ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/server/attack.C
(Generate patch)

Comparing deliantra/server/server/attack.C (file contents):
Revision 1.101 by root, Fri Dec 26 13:33:22 2008 UTC vs.
Revision 1.109 by elmex, Fri Aug 28 22:40:41 2009 UTC

79 int i, roll, saves = 0, attacks = 0, number; 79 int i, roll, saves = 0, attacks = 0, number;
80 materialtype_t *mt; 80 materialtype_t *mt;
81 81
82 if (!op->materialname) 82 if (!op->materialname)
83 { 83 {
84 for (mt = materialt; mt && mt->next; mt = mt->next) 84 for (mt = materialt; mt; mt = mt->next)
85 if (op->materials & mt->material) 85 if (op->materials & mt->material)
86 break; 86 break;
87 } 87 }
88 else 88 else
89 mt = name_to_material (op->materialname); 89 mt = name_to_material (op->materialname);
159 * object with +/- glow_radius and an "other_arch" to change to. 159 * object with +/- glow_radius and an "other_arch" to change to.
160 * (and please note that we cant fail our save and reach this 160 * (and please note that we cant fail our save and reach this
161 * function if the object doesnt contain a material that can burn. 161 * function if the object doesnt contain a material that can burn.
162 * So forget lighting magical swords on fire with this!) -b.t. 162 * So forget lighting magical swords on fire with this!) -b.t.
163 */ 163 */
164 if (type & (AT_FIRE | AT_ELECTRICITY) && op->other_arch && QUERY_FLAG (op, FLAG_IS_LIGHTABLE)) 164 if (type & (AT_FIRE | AT_ELECTRICITY)
165 && (QUERY_FLAG (op, FLAG_IS_LIGHTABLE)
166 || op->type == LAMP
167 || op->type == TORCH
165 { 168 ))
166 const char *arch = op->other_arch->archname; 169 {
167 170 switch (op->type)
168 if (op->decrease ())
169 fix_stopped_item (op, m, originator);
170
171 if ((op = archetype::get (arch)))
172 { 171 {
172 case LAMP:
173 // turn on a lamp
174 apply_lamp (op, true);
175 break;
176
177 default:
178 // for instance icecubes:
179 if (op->other_arch)
180 {
181 const char *arch = op->other_arch->archname;
182
183 if (op->decrease ())
184 fix_stopped_item (op, m, originator);
185
186 if ((op = archetype::get (arch)))
187 {
173 if (env) 188 if (env)
174 env->insert (op); 189 env->insert (op);
175 else 190 else
176 m->insert (op, x, y, originator); 191 m->insert (op, x, y, originator);
192 }
193 }
177 } 194 }
178
179 return; 195 return;
180 } 196 }
181 197
182 if (type & AT_CANCELLATION) 198 if (type & AT_CANCELLATION)
183 { /* Cancellation. */ 199 { /* Cancellation. */
807 if (hitdam <= 0) 823 if (hitdam <= 0)
808 hitdam = 1; 824 hitdam = 1;
809 825
810 type = hitter->attacktype; 826 type = hitter->attacktype;
811 827
828 /* Ok, because some of the brainfucks of the good *sigh* old *sigh*
829 * Crossfire we have to default the attacktype here to AT_PHYSICAL.
830 * This check is important for the most simple monsters out there in the
831 * game content (maps, archs). For example orcs: They would have
832 * no attacktype at all.
833 *
834 * Some time in the future someone should just go into the game data
835 * and fix every monster out there ;-/ Until then we will kill some
836 * more trees in the african rain forests with this check.
837 */
812 if (!type) 838 if (!type)
813 type = AT_PHYSICAL; 839 type = AT_PHYSICAL;
814 840
815 /* Handle monsters that hit back */ 841 /* Handle monsters that hit back */
816 if (!simple_attack && QUERY_FLAG (op, FLAG_HITBACK) && QUERY_FLAG (hitter, FLAG_ALIVE)) 842 if (!simple_attack && QUERY_FLAG (op, FLAG_HITBACK) && QUERY_FLAG (hitter, FLAG_ALIVE))
982} 1008}
983 1009
984void 1010void
985tear_down_wall (object *op) 1011tear_down_wall (object *op)
986{ 1012{
987 int perc = 0;
988
989 if (!op->stats.maxhp) 1013 if (!op->stats.maxhp)
990 {
991 LOG (llevError, "TEAR_DOWN wall %s had no maxhp.\n", &op->name); 1014 LOG (llevError, "TEAR_DOWN wall %s had no maxhp.\n", &op->name);
992 perc = 1; 1015 else if (!op->has_anim ())
993 }
994 else if (!GET_ANIM_ID (op))
995 { 1016 {
996 /* Object has been called - no animations, so remove it */ 1017 /* Object has been called - no animations, so remove it */
997 if (op->stats.hp < 0) 1018 if (op->stats.hp < 0)
998 op->destroy (); 1019 op->destroy ();
999 1020
1000 return; /* no animations, so nothing more to do */ 1021 return; /* no animations, so nothing more to do */
1001 } 1022 }
1002 1023
1003 perc = NUM_ANIMATIONS (op) - ((int) NUM_ANIMATIONS (op) * op->stats.hp) / op->stats.maxhp; 1024 // we use frames 1..num-2 as intermediate frames, so
1025 // the last frame is used only when hp < 0.
1026 int perc = clamp (
1027 lerp_ru<int> (op->stats.hp, 0, op->stats.maxhp, op->anim_frames () - 2, 0),
1028 0, op->anim_frames () - 1
1029 );
1004 1030
1005 if (perc >= (int) NUM_ANIMATIONS (op)) 1031 op->set_anim_frame (perc);
1006 perc = NUM_ANIMATIONS (op) - 1;
1007 else if (perc < 1)
1008 perc = 1;
1009
1010 SET_ANIMATION (op, perc);
1011 update_object (op, UP_OBJ_FACE); 1032 update_object (op, UP_OBJ_FACE);
1012 1033
1013 if (perc == NUM_ANIMATIONS (op) - 1) 1034 if (op->stats.hp < 0)
1014 { /* Reached the last animation */ 1035 { /* Reached the last animation */
1015 if (op->face == blank_face) 1036 if (op->face == blank_face)
1016 /* If the last face is blank, remove the ob */ 1037 /* If the last face is blank, remove the ob */
1017 op->destroy (); 1038 op->destroy ();
1018 else 1039 else
1019 { /* The last face was not blank, leave an image */ 1040 { /* The last face was not blank, leave an image */
1020 CLEAR_FLAG (op, FLAG_BLOCKSVIEW); 1041 op->flag [FLAG_BLOCKSVIEW] = false;
1021 update_all_los (op->map, op->x, op->y); 1042 update_all_los (op->map, op->x, op->y);
1022 op->move_block = 0; 1043 op->move_block = 0;
1023 CLEAR_FLAG (op, FLAG_ALIVE); 1044 op->flag [FLAG_ALIVE] = false;
1024 } 1045 }
1025 } 1046 }
1026} 1047}
1027 1048
1028void 1049void
1029scare_creature (object *target, object *hitter) 1050scare_creature (object *target, object *hitter)
1030{ 1051{
1031 object *owner = hitter->owner; 1052 target->flag [FLAG_SCARED] = true;
1032 1053
1033 if (!owner)
1034 owner = hitter;
1035
1036 SET_FLAG (target, FLAG_SCARED);
1037 if (!target->enemy) 1054 if (!target->enemy)
1038 target->enemy = owner; 1055 target->enemy = hitter->outer_owner ();
1039} 1056}
1040 1057
1041/* This returns the amount of damage hitter does to op with the 1058/* This returns the amount of damage hitter does to op with the
1042 * appropriate attacktype. Only 1 attacktype should be set at a time. 1059 * appropriate attacktype. Only 1 attacktype should be set at a time.
1043 * This doesn't damage the player, but returns how much it should 1060 * This doesn't damage the player, but returns how much it should
1068 if (attacknum == ATNR_INTERNAL) 1085 if (attacknum == ATNR_INTERNAL)
1069 return dam; 1086 return dam;
1070 1087
1071 if (hitter->slaying) 1088 if (hitter->slaying)
1072 { 1089 {
1073 if ((op->race && strstr (hitter->slaying, op->race)) 1090 if ((op->race && hitter->slaying.contains (op->race))
1074 || (op->arch && op->arch->archname && strstr (op->arch->archname, hitter->slaying))) 1091 || (op->arch && op->arch->archname.contains (hitter->slaying)))
1075 { 1092 {
1076 doesnt_slay = 0; 1093 doesnt_slay = 0;
1077 dam *= 3; 1094 dam *= 3;
1078 } 1095 }
1079 } 1096 }
1281 object *god = find_god (determine_god (owner)); 1298 object *god = find_god (determine_god (owner));
1282 int div = 1; 1299 int div = 1;
1283 1300
1284 /* if undead are not an enemy of your god, you turn them 1301 /* if undead are not an enemy of your god, you turn them
1285 * at half strength */ 1302 * at half strength */
1286 if (!god || !god->slaying || strstr (god->slaying, shstr_undead) == NULL) 1303 if (!god || !god->slaying.contains (shstr_undead))
1287 div = 2; 1304 div = 2;
1288 1305
1289 /* Give a bonus if you resist turn undead */ 1306 /* Give a bonus if you resist turn undead */
1290 if (op->level * div < (turn_bonus[owner->stats.Wis] + owner->level + (op->resist[ATNR_TURN_UNDEAD] / 100))) 1307 if (op->level * div < (turn_bonus[owner->stats.Wis] + owner->level + (op->resist[ATNR_TURN_UNDEAD] / 100)))
1291 scare_creature (op, owner); 1308 scare_creature (op, owner);
1769 */ 1786 */
1770 if (type & AT_HOLYWORD) 1787 if (type & AT_HOLYWORD)
1771 { 1788 {
1772 object *god; 1789 object *god;
1773 1790
1774 if ((!hitter->slaying || 1791 if ((!hitter->slaying
1775 (!(op->race && strstr (hitter->slaying, op->race)) && 1792 || (!(op->race && hitter->slaying.contains (op->race))
1776 !(op->name && strstr (hitter->slaying, op->name)))) && 1793 && !(op->name && hitter->slaying.contains (op->name))))
1777 (!QUERY_FLAG (op, FLAG_UNDEAD) || 1794 && (!QUERY_FLAG (op, FLAG_UNDEAD)
1778 (hitter->title != NULL 1795 || (hitter->title
1779 && (god = find_god (determine_god (hitter))) != NULL && god->race != NULL && strstr (god->race, shstr_undead) != NULL))) 1796 && (god = find_god (determine_god (hitter))) != NULL
1797 && god->race.contains (shstr_undead))))
1780 return 0; 1798 return 0;
1781 } 1799 }
1782 1800
1783 maxattacktype = type; /* initialise this to something */ 1801 maxattacktype = type; /* initialise this to something */
1784 for (attacknum = 0; attacknum < NROFATTACKS; attacknum++, attacktype = 1 << attacknum) 1802 for (attacknum = 0; attacknum < NROFATTACKS; attacknum++, attacktype = 1 << attacknum)
2157 ** field of the deathstriking object */ 2175 ** field of the deathstriking object */
2158 2176
2159 int atk_lev, def_lev, kill_lev; 2177 int atk_lev, def_lev, kill_lev;
2160 2178
2161 if (hitter->slaying) 2179 if (hitter->slaying)
2162 if (!((QUERY_FLAG (op, FLAG_UNDEAD) && strstr (hitter->slaying, shstr_undead)) || (op->race && strstr (hitter->slaying, op->race)))) 2180 if (!((QUERY_FLAG (op, FLAG_UNDEAD) && hitter->slaying.contains (shstr_undead))
2181 || (op->race && hitter->slaying.contains (op->race))))
2163 return; 2182 return;
2164 2183
2165 def_lev = op->level; 2184 def_lev = op->level;
2166 if (def_lev < 1) 2185 if (def_lev < 1)
2167 { 2186 {
2266 { 2285 {
2267 /* target is unseen */ 2286 /* target is unseen */
2268 if (target->invisible || QUERY_FLAG (attacker, FLAG_BLIND)) 2287 if (target->invisible || QUERY_FLAG (attacker, FLAG_BLIND))
2269 adjust -= 10; 2288 adjust -= 10;
2270 /* dark map penalty for the hitter (lacks infravision if we got here). */ 2289 /* dark map penalty for the hitter (lacks infravision if we got here). */
2271 else if (target->map && target->map->darklevel () > 0 && !stand_in_light (target)) 2290 else if (!stand_in_light (target))
2272 adjust -= target->map->darklevel (); 2291 adjust -= target->map->darklevel ();
2273 } 2292 }
2274 2293
2275 if (QUERY_FLAG (attacker, FLAG_SCARED)) 2294 if (QUERY_FLAG (attacker, FLAG_SCARED))
2276 adjust -= 3; 2295 adjust -= 3;

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines