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.111 by elmex, Thu Sep 3 21:55:39 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 case TORCH:
174 // turn on a lamp
175 apply_lamp (op, true);
176 break;
177
178 default:
179 // for instance icecubes:
180 if (op->other_arch)
181 {
182 const char *arch = op->other_arch->archname;
183
184 if (op->decrease ())
185 fix_stopped_item (op, m, originator);
186
187 if ((op = archetype::get (arch)))
188 {
173 if (env) 189 if (env)
174 env->insert (op); 190 env->insert (op);
175 else 191 else
176 m->insert (op, x, y, originator); 192 m->insert (op, x, y, originator);
193 }
194 }
177 } 195 }
178
179 return; 196 return;
180 } 197 }
181 198
182 if (type & AT_CANCELLATION) 199 if (type & AT_CANCELLATION)
183 { /* Cancellation. */ 200 { /* Cancellation. */
785 if (op->flag [FLAG_HIDDEN] && hitter->flag [FLAG_ALIVE]) 802 if (op->flag [FLAG_HIDDEN] && hitter->flag [FLAG_ALIVE])
786 { 803 {
787 make_visible (op); 804 make_visible (op);
788 805
789 if (op->type == PLAYER) 806 if (op->type == PLAYER)
790 new_draw_info (NDI_UNIQUE, 0, op, "You were hit by a wild attack. " "You are no longer hidden!"); 807 new_draw_info (NDI_UNIQUE, 0, op, "You were hit by a wild attack. You are no longer hidden!");
791 } 808 }
792 809
793 /* thrown items (hitter) will have various effects 810 /* thrown items (hitter) will have various effects
794 * when they hit the victim. For things like thrown daggers, 811 * when they hit the victim. For things like thrown daggers,
795 * this sets 'hitter' to the actual dagger, and not the 812 * this sets 'hitter' to the actual dagger, and not the
807 if (hitdam <= 0) 824 if (hitdam <= 0)
808 hitdam = 1; 825 hitdam = 1;
809 826
810 type = hitter->attacktype; 827 type = hitter->attacktype;
811 828
829 /* Ok, because some of the brainfucks of the good *sigh* old *sigh*
830 * Crossfire we have to default the attacktype here to AT_PHYSICAL.
831 * This check is important for the most simple monsters out there in the
832 * game content (maps, archs). For example orcs: They would have
833 * no attacktype at all.
834 *
835 * Some time in the future someone should just go into the game data
836 * and fix every monster out there ;-/ Until then we will kill some
837 * more trees in the african rain forests with this check.
838 */
812 if (!type) 839 if (!type)
813 type = AT_PHYSICAL; 840 type = AT_PHYSICAL;
814 841
815 /* Handle monsters that hit back */ 842 /* Handle monsters that hit back */
816 if (!simple_attack && QUERY_FLAG (op, FLAG_HITBACK) && QUERY_FLAG (hitter, FLAG_ALIVE)) 843 if (!simple_attack && QUERY_FLAG (op, FLAG_HITBACK) && QUERY_FLAG (hitter, FLAG_ALIVE))
982} 1009}
983 1010
984void 1011void
985tear_down_wall (object *op) 1012tear_down_wall (object *op)
986{ 1013{
987 int perc = 0;
988
989 if (!op->stats.maxhp) 1014 if (!op->stats.maxhp)
990 {
991 LOG (llevError, "TEAR_DOWN wall %s had no maxhp.\n", &op->name); 1015 LOG (llevError, "TEAR_DOWN wall %s had no maxhp.\n", &op->name);
992 perc = 1; 1016 else if (!op->has_anim ())
993 }
994 else if (!GET_ANIM_ID (op))
995 { 1017 {
996 /* Object has been called - no animations, so remove it */ 1018 /* Object has been called - no animations, so remove it */
997 if (op->stats.hp < 0) 1019 if (op->stats.hp < 0)
998 op->destroy (); 1020 op->destroy ();
999 1021
1000 return; /* no animations, so nothing more to do */ 1022 return; /* no animations, so nothing more to do */
1001 } 1023 }
1002 1024
1003 perc = NUM_ANIMATIONS (op) - ((int) NUM_ANIMATIONS (op) * op->stats.hp) / op->stats.maxhp; 1025 // we use frames 1..num-2 as intermediate frames, so
1026 // the last frame is used only when hp < 0.
1027 int perc = clamp (
1028 lerp_ru<int> (op->stats.hp, 0, op->stats.maxhp, op->anim_frames () - 2, 0),
1029 0, op->anim_frames () - 1
1030 );
1004 1031
1005 if (perc >= (int) NUM_ANIMATIONS (op)) 1032 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); 1033 update_object (op, UP_OBJ_FACE);
1012 1034
1013 if (perc == NUM_ANIMATIONS (op) - 1) 1035 if (op->stats.hp < 0)
1014 { /* Reached the last animation */ 1036 { /* Reached the last animation */
1015 if (op->face == blank_face) 1037 if (op->face == blank_face)
1016 /* If the last face is blank, remove the ob */ 1038 /* If the last face is blank, remove the ob */
1017 op->destroy (); 1039 op->destroy ();
1018 else 1040 else
1019 { /* The last face was not blank, leave an image */ 1041 { /* The last face was not blank, leave an image */
1020 CLEAR_FLAG (op, FLAG_BLOCKSVIEW); 1042 op->flag [FLAG_BLOCKSVIEW] = false;
1021 update_all_los (op->map, op->x, op->y); 1043 update_all_los (op->map, op->x, op->y);
1022 op->move_block = 0; 1044 op->move_block = 0;
1023 CLEAR_FLAG (op, FLAG_ALIVE); 1045 op->flag [FLAG_ALIVE] = false;
1024 } 1046 }
1025 } 1047 }
1026} 1048}
1027 1049
1028void 1050void
1029scare_creature (object *target, object *hitter) 1051scare_creature (object *target, object *hitter)
1030{ 1052{
1031 object *owner = hitter->owner; 1053 target->flag [FLAG_SCARED] = true;
1032 1054
1033 if (!owner)
1034 owner = hitter;
1035
1036 SET_FLAG (target, FLAG_SCARED);
1037 if (!target->enemy) 1055 if (!target->enemy)
1038 target->enemy = owner; 1056 target->enemy = hitter->outer_owner ();
1039} 1057}
1040 1058
1041/* This returns the amount of damage hitter does to op with the 1059/* This returns the amount of damage hitter does to op with the
1042 * appropriate attacktype. Only 1 attacktype should be set at a time. 1060 * appropriate attacktype. Only 1 attacktype should be set at a time.
1043 * This doesn't damage the player, but returns how much it should 1061 * This doesn't damage the player, but returns how much it should
1068 if (attacknum == ATNR_INTERNAL) 1086 if (attacknum == ATNR_INTERNAL)
1069 return dam; 1087 return dam;
1070 1088
1071 if (hitter->slaying) 1089 if (hitter->slaying)
1072 { 1090 {
1073 if ((op->race && strstr (hitter->slaying, op->race)) 1091 if ((op->race && hitter->slaying.contains (op->race))
1074 || (op->arch && op->arch->archname && strstr (op->arch->archname, hitter->slaying))) 1092 || (op->arch && op->arch->archname.contains (hitter->slaying)))
1075 { 1093 {
1076 doesnt_slay = 0; 1094 doesnt_slay = 0;
1077 dam *= 3; 1095 dam *= 3;
1078 } 1096 }
1079 } 1097 }
1281 object *god = find_god (determine_god (owner)); 1299 object *god = find_god (determine_god (owner));
1282 int div = 1; 1300 int div = 1;
1283 1301
1284 /* if undead are not an enemy of your god, you turn them 1302 /* if undead are not an enemy of your god, you turn them
1285 * at half strength */ 1303 * at half strength */
1286 if (!god || !god->slaying || strstr (god->slaying, shstr_undead) == NULL) 1304 if (!god || !god->slaying.contains (shstr_undead))
1287 div = 2; 1305 div = 2;
1288 1306
1289 /* Give a bonus if you resist turn undead */ 1307 /* 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))) 1308 if (op->level * div < (turn_bonus[owner->stats.Wis] + owner->level + (op->resist[ATNR_TURN_UNDEAD] / 100)))
1291 scare_creature (op, owner); 1309 scare_creature (op, owner);
1769 */ 1787 */
1770 if (type & AT_HOLYWORD) 1788 if (type & AT_HOLYWORD)
1771 { 1789 {
1772 object *god; 1790 object *god;
1773 1791
1774 if ((!hitter->slaying || 1792 if ((!hitter->slaying
1775 (!(op->race && strstr (hitter->slaying, op->race)) && 1793 || (!(op->race && hitter->slaying.contains (op->race))
1776 !(op->name && strstr (hitter->slaying, op->name)))) && 1794 && !(op->name && hitter->slaying.contains (op->name))))
1777 (!QUERY_FLAG (op, FLAG_UNDEAD) || 1795 && (!QUERY_FLAG (op, FLAG_UNDEAD)
1778 (hitter->title != NULL 1796 || (hitter->title
1779 && (god = find_god (determine_god (hitter))) != NULL && god->race != NULL && strstr (god->race, shstr_undead) != NULL))) 1797 && (god = find_god (determine_god (hitter))) != NULL
1798 && god->race.contains (shstr_undead))))
1780 return 0; 1799 return 0;
1781 } 1800 }
1782 1801
1783 maxattacktype = type; /* initialise this to something */ 1802 maxattacktype = type; /* initialise this to something */
1784 for (attacknum = 0; attacknum < NROFATTACKS; attacknum++, attacktype = 1 << attacknum) 1803 for (attacknum = 0; attacknum < NROFATTACKS; attacknum++, attacktype = 1 << attacknum)
2157 ** field of the deathstriking object */ 2176 ** field of the deathstriking object */
2158 2177
2159 int atk_lev, def_lev, kill_lev; 2178 int atk_lev, def_lev, kill_lev;
2160 2179
2161 if (hitter->slaying) 2180 if (hitter->slaying)
2162 if (!((QUERY_FLAG (op, FLAG_UNDEAD) && strstr (hitter->slaying, shstr_undead)) || (op->race && strstr (hitter->slaying, op->race)))) 2181 if (!((QUERY_FLAG (op, FLAG_UNDEAD) && hitter->slaying.contains (shstr_undead))
2182 || (op->race && hitter->slaying.contains (op->race))))
2163 return; 2183 return;
2164 2184
2165 def_lev = op->level; 2185 def_lev = op->level;
2166 if (def_lev < 1) 2186 if (def_lev < 1)
2167 { 2187 {
2266 { 2286 {
2267 /* target is unseen */ 2287 /* target is unseen */
2268 if (target->invisible || QUERY_FLAG (attacker, FLAG_BLIND)) 2288 if (target->invisible || QUERY_FLAG (attacker, FLAG_BLIND))
2269 adjust -= 10; 2289 adjust -= 10;
2270 /* dark map penalty for the hitter (lacks infravision if we got here). */ 2290 /* 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)) 2291 else if (!stand_in_light (target))
2272 adjust -= target->map->darklevel (); 2292 adjust -= target->map->darklevel ();
2273 } 2293 }
2274 2294
2275 if (QUERY_FLAG (attacker, FLAG_SCARED)) 2295 if (QUERY_FLAG (attacker, FLAG_SCARED))
2276 adjust -= 3; 2296 adjust -= 3;

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines