… | |
… | |
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 | |
984 | void |
1010 | void |
985 | tear_down_wall (object *op) |
1011 | tear_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 | |
1028 | void |
1049 | void |
1029 | scare_creature (object *target, object *hitter) |
1050 | scare_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; |