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.56 by root, Tue Apr 24 12:32:15 2007 UTC vs.
Revision 1.61 by root, Tue May 1 05:48:20 2007 UTC

1/* 1/*
2 * CrossFire, A Multiplayer game for X-windows 2 * CrossFire, A Multiplayer game
3 * 3 *
4 * Copyright (C) 2005, 2006, 2007 Marc Lehmann & Crossfire+ Development Team 4 * Copyright (C) 2005, 2006, 2007 Marc Lehmann & Crossfire+ Development Team
5 * Copyright (C) 2002 Mark Wedel & Crossfire Development Team 5 * Copyright (C) 2002 Mark Wedel & Crossfire Development Team
6 * Copyright (C) 1992 Frank Tore Johansen 6 * Copyright (C) 1992 Frank Tore Johansen
7 * 7 *
267 * op is going in direction 'dir' 267 * op is going in direction 'dir'
268 * type is the attacktype of the object. 268 * type is the attacktype of the object.
269 * full_hit is set if monster area does not matter. 269 * full_hit is set if monster area does not matter.
270 * returns 1 if it hits something, 0 otherwise. 270 * returns 1 if it hits something, 0 otherwise.
271 */ 271 */
272
273int 272int
274hit_map (object *op, int dir, int type, int full_hit) 273hit_map (object *op, int dir, int type, int full_hit)
275{ 274{
276 maptile *map; 275 maptile *map;
277 sint16 x, y; 276 sint16 x, y;
310 mapspace &ms = map->at (x, y); 309 mapspace &ms = map->at (x, y);
311 310
312 if (ms.flags () & P_SAFE) 311 if (ms.flags () & P_SAFE)
313 return 0; 312 return 0;
314 313
315 /* peterm: a few special cases for special attacktypes --counterspell 314 /* peterm: a few special cases for special attacktypes --counterspell
316 * must be out here because it strikes things which are not alive 315 * must be out here because it strikes things which are not alive
317 */ 316 */
318 if (type & (AT_COUNTERSPELL | AT_CHAOS)) 317 if (type & (AT_COUNTERSPELL | AT_CHAOS))
319 { 318 {
320 if (type & AT_COUNTERSPELL) 319 if (type & AT_COUNTERSPELL)
774 { 773 {
775 int hitdam = base_dam; 774 int hitdam = base_dam;
776 775
777 if (settings.casting_time == TRUE) 776 if (settings.casting_time == TRUE)
778 { 777 {
779 if ((hitter->type == PLAYER) && (hitter->casting_time > -1)) 778 if (hitter->type == PLAYER && hitter->casting_time > -1)
780 { 779 {
781 hitter->casting_time = -1; 780 hitter->casting_time = -1;
782 new_draw_info (NDI_UNIQUE, 0, hitter, "You attacked and lost your spell!"); 781 new_draw_info (NDI_UNIQUE, 0, hitter, "You attacked and lost your spell!");
783 } 782 }
783
784 if ((op->casting_time > -1) && (hitdam > 0)) 784 if (op->casting_time > -1 && hitdam > 0)
785 { 785 {
786 op->casting_time = -1; 786 op->casting_time = -1;
787 if (op->type == PLAYER) 787 if (op->type == PLAYER)
788 { 788 {
789 new_draw_info (NDI_UNIQUE, 0, op, "You were hit and lost your spell!"); 789 new_draw_info (NDI_UNIQUE, 0, op, "You were hit and lost your spell!");
790 new_draw_info_format (NDI_ALL | NDI_UNIQUE, 5, NULL, "%s was hit by %s and lost a spell.", &op_name, &hitter->name); 790 new_draw_info_format (NDI_ALL | NDI_UNIQUE, 5, NULL, "%s was hit by %s and lost a spell.", &op_name, &hitter->name);
791 } 791 }
792 } 792 }
793 } 793 }
794
794 if (!simple_attack) 795 if (!simple_attack)
795 { 796 {
796 /* If you hit something, the victim should *always* wake up. 797 /* If you hit something, the victim should *always* wake up.
797 * Before, invisible hitters could avoid doing this. 798 * Before, invisible hitters could avoid doing this.
798 * -b.t. */ 799 * -b.t. */
806 807
807 /* if you were hidden and hit by a creature, you are discovered */ 808 /* if you were hidden and hit by a creature, you are discovered */
808 if (op->hide && QUERY_FLAG (hitter, FLAG_ALIVE)) 809 if (op->hide && QUERY_FLAG (hitter, FLAG_ALIVE))
809 { 810 {
810 make_visible (op); 811 make_visible (op);
812
811 if (op->type == PLAYER) 813 if (op->type == PLAYER)
812 new_draw_info (NDI_UNIQUE, 0, op, "You were hit by a wild attack. " "You are no longer hidden!"); 814 new_draw_info (NDI_UNIQUE, 0, op, "You were hit by a wild attack. " "You are no longer hidden!");
813 } 815 }
814 816
815 /* thrown items (hitter) will have various effects 817 /* thrown items (hitter) will have various effects
869} 871}
870 872
871int 873int
872attack_ob (object *op, object *hitter) 874attack_ob (object *op, object *hitter)
873{ 875{
874
875 if (hitter->head)
876 hitter = hitter->head; 876 hitter = hitter->head_ ();
877
877 return attack_ob_simple (op, hitter, hitter->stats.dam, hitter->stats.wc); 878 return attack_ob_simple (op, hitter, hitter->stats.dam, hitter->stats.wc);
878} 879}
879 880
880/* op is the arrow, tmp is what is stopping the arrow. 881/* op is the arrow, tmp is what is stopping the arrow.
881 * 882 *
890 * debate - 5000 is 5 kg, so arrows, knives, and other light weapons 891 * debate - 5000 is 5 kg, so arrows, knives, and other light weapons
891 * stick around. 892 * stick around.
892 */ 893 */
893 if (op->weight <= 5000 && tmp->stats.hp >= 0) 894 if (op->weight <= 5000 && tmp->stats.hp >= 0)
894 { 895 {
895 if (tmp->head != NULL)
896 tmp = tmp->head; 896 tmp = tmp->head_ ();
897 897
898 op->remove (); 898 op->remove ();
899 op = insert_ob_in_ob (op, tmp); 899 op = insert_ob_in_ob (op, tmp);
900 900
901 if (tmp->type == PLAYER) 901 if (tmp->type == PLAYER)
1008 insert_ob_in_ob (hitter, container); 1008 insert_ob_in_ob (hitter, container);
1009 } 1009 }
1010 1010
1011 return op; 1011 return op;
1012} 1012}
1013
1014 1013
1015void 1014void
1016tear_down_wall (object *op) 1015tear_down_wall (object *op)
1017{ 1016{
1018 int perc = 0; 1017 int perc = 0;
1067 SET_FLAG (target, FLAG_SCARED); 1066 SET_FLAG (target, FLAG_SCARED);
1068 if (!target->enemy) 1067 if (!target->enemy)
1069 target->enemy = owner; 1068 target->enemy = owner;
1070} 1069}
1071 1070
1072
1073/* This returns the amount of damage hitter does to op with the 1071/* This returns the amount of damage hitter does to op with the
1074 * appropriate attacktype. Only 1 attacktype should be set at a time. 1072 * appropriate attacktype. Only 1 attacktype should be set at a time.
1075 * This doesn't damage the player, but returns how much it should 1073 * This doesn't damage the player, but returns how much it should
1076 * take. However, it will do other effects (paralyzation, slow, etc.) 1074 * take. However, it will do other effects (paralyzation, slow, etc.)
1077 * Note - changed for PR code - we now pass the attack number and not 1075 * Note - changed for PR code - we now pass the attack number and not
1088 return 0; 1086 return 0;
1089 } 1087 }
1090 1088
1091 if (dam < 0) 1089 if (dam < 0)
1092 { 1090 {
1093 LOG (llevError, "hit_player_attacktype called with negative damage %d (hitter %s, target %s)\n", dam, hitter->debug_desc (), op->debug_desc2 ()); 1091 LOG (llevError, "hit_player_attacktype called with negative damage %d (hitter %s, target %s)\n",
1092 dam, hitter->debug_desc (), op->debug_desc ());
1094 return 0; 1093 return 0;
1095 } 1094 }
1096 1095
1097 /* AT_INTERNAL is supposed to do exactly dam. Put a case here so 1096 /* AT_INTERNAL is supposed to do exactly dam. Put a case here so
1098 * people can't mess with that or it otherwise get confused. */ 1097 * people can't mess with that or it otherwise get confused. */
1099 if (attacknum == ATNR_INTERNAL) 1098 if (attacknum == ATNR_INTERNAL)
1100 return dam; 1099 return dam;
1101 1100
1102 if (hitter->slaying) 1101 if (hitter->slaying)
1103 { 1102 {
1104 if (((op->race != NULL) && strstr (hitter->slaying, op->race)) || 1103 if ((op->race && strstr (hitter->slaying, op->race))
1105 (op->arch && (op->arch->name != NULL) && strstr (op->arch->name, hitter->slaying))) 1104 || (op->arch && op->arch->name && strstr (op->arch->name, hitter->slaying)))
1106 { 1105 {
1107 doesnt_slay = 0; 1106 doesnt_slay = 0;
1108 dam *= 3; 1107 dam *= 3;
1109 } 1108 }
1110 } 1109 }
1124 /* Special hack. By default, if immune to something, you 1123 /* Special hack. By default, if immune to something, you
1125 * shouldn't need to worry. However, acid is an exception, since 1124 * shouldn't need to worry. However, acid is an exception, since
1126 * it can still damage your items. Only include attacktypes if 1125 * it can still damage your items. Only include attacktypes if
1127 * special processing is needed */ 1126 * special processing is needed */
1128 1127
1129 if ((op->resist[attacknum] >= 100) && doesnt_slay && (attacknum != ATNR_ACID)) 1128 if (op->resist[attacknum] >= 100
1129 && doesnt_slay
1130 && attacknum != ATNR_ACID)
1130 return 0; 1131 return 0;
1131 1132
1132 /* Keep this in order - makes things easier to find */ 1133 /* Keep this in order - makes things easier to find */
1133 1134
1134 switch (attacknum) 1135 switch (attacknum)
1184 else if (attacknum == ATNR_DEPLETE) 1185 else if (attacknum == ATNR_DEPLETE)
1185 op->drain_stat (); 1186 op->drain_stat ();
1186 else if (attacknum == ATNR_BLIND && !QUERY_FLAG (op, FLAG_UNDEAD) && !QUERY_FLAG (op, FLAG_GENERATOR)) 1187 else if (attacknum == ATNR_BLIND && !QUERY_FLAG (op, FLAG_UNDEAD) && !QUERY_FLAG (op, FLAG_GENERATOR))
1187 blind_player (op, hitter, dam); 1188 blind_player (op, hitter, dam);
1188 } 1189 }
1190
1189 dam = 0; /* These are all effects and don't do real damage */ 1191 dam = 0; /* These are all effects and don't do real damage */
1190 } 1192 }
1191 break; 1193 break;
1192 1194
1193 case ATNR_ACID: 1195 case ATNR_ACID:
1282 if (op->type != PLAYER || owner->type != PLAYER) 1284 if (op->type != PLAYER || owner->type != PLAYER)
1283 change_exp (owner, op->stats.exp / (rate * 2), 1285 change_exp (owner, op->stats.exp / (rate * 2),
1284 hitter->chosen_skill ? hitter->chosen_skill->skill : (const char *) 0, SK_EXP_TOTAL); 1286 hitter->chosen_skill ? hitter->chosen_skill->skill : (const char *) 0, SK_EXP_TOTAL);
1285 } 1287 }
1286 else if (op->type != PLAYER || hitter->type != PLAYER) 1288 else if (op->type != PLAYER || hitter->type != PLAYER)
1287 {
1288 change_exp (hitter, op->stats.exp / (rate * 2), 1289 change_exp (hitter, op->stats.exp / (rate * 2),
1289 hitter->chosen_skill ? hitter->chosen_skill->skill : (const char *) 0, 0); 1290 hitter->chosen_skill ? hitter->chosen_skill->skill : (const char *) 0, 0);
1290 } 1291
1291 change_exp (op, -op->stats.exp / rate, NULL, 0); 1292 change_exp (op, -op->stats.exp / rate, NULL, 0);
1292 } 1293 }
1293 1294
1294 dam = 1; /* Drain is an effect. Still return 1 - otherwise, if you have pure 1295 dam = 1; /* Drain is an effect. Still return 1 - otherwise, if you have pure
1295 * drain attack, you won't know that you are actually sucking out EXP, 1296 * drain attack, you won't know that you are actually sucking out EXP,
1309 1310
1310 /* if undead are not an enemy of your god, you turn them 1311 /* if undead are not an enemy of your god, you turn them
1311 * at half strength */ 1312 * at half strength */
1312 if (!god || !god->slaying || strstr (god->slaying, undead_name) == NULL) 1313 if (!god || !god->slaying || strstr (god->slaying, undead_name) == NULL)
1313 div = 2; 1314 div = 2;
1315
1314 /* Give a bonus if you resist turn undead */ 1316 /* Give a bonus if you resist turn undead */
1315 if (op->level * div < (turn_bonus[owner->stats.Wis] + owner->level + (op->resist[ATNR_TURN_UNDEAD] / 100))) 1317 if (op->level * div < (turn_bonus[owner->stats.Wis] + owner->level + (op->resist[ATNR_TURN_UNDEAD] / 100)))
1316 scare_creature (op, owner); 1318 scare_creature (op, owner);
1317 } 1319 }
1318 else 1320 else
1324 case ATNR_DEATH: 1326 case ATNR_DEATH:
1325 deathstrike_player (op, hitter, &dam); 1327 deathstrike_player (op, hitter, &dam);
1326 break; 1328 break;
1327 1329
1328 case ATNR_CHAOS: 1330 case ATNR_CHAOS:
1329 LOG (llevError, "%s was hit by %s with non-specific chaos.\n", op->debug_desc (), hitter->debug_desc2 ()); 1331 LOG (llevError, "%s was hit by %s with non-specific chaos.\n", op->debug_desc (), hitter->debug_desc ());
1330 dam = 0; 1332 dam = 0;
1331 break; 1333 break;
1332 1334
1333 case ATNR_COUNTERSPELL: 1335 case ATNR_COUNTERSPELL:
1334 LOG (llevError, "%s was hit by %s with counterspell attack.\n", op->debug_desc (), hitter->debug_desc2 ()); 1336 LOG (llevError, "%s was hit by %s with counterspell attack.\n", op->debug_desc (), hitter->debug_desc ());
1335 dam = 0; 1337 dam = 0;
1336 /* This should never happen. Counterspell is handled 1338 /* This should never happen. Counterspell is handled
1337 * seperately and filtered out. If this does happen, 1339 * seperately and filtered out. If this does happen,
1338 * Counterspell has no effect on anything but spells, so it 1340 * Counterspell has no effect on anything but spells, so it
1339 * does no damage. */ 1341 * does no damage. */
1411 char buf[MAX_BUF]; 1413 char buf[MAX_BUF];
1412 const char *skill; 1414 const char *skill;
1413 int maxdam = 0; 1415 int maxdam = 0;
1414 int battleg = 0; /* true if op standing on battleground */ 1416 int battleg = 0; /* true if op standing on battleground */
1415 int pk = 0; /* true if op and what controls hitter are both players */ 1417 int pk = 0; /* true if op and what controls hitter are both players */
1416 object *owner = NULL; 1418 object *owner = 0;
1417 object *skop = NULL; 1419 object *skop = 0;
1418 1420
1419 if (op->stats.hp >= 0) 1421 if (op->stats.hp >= 0)
1420 return -1; 1422 return -1;
1421 1423
1422 if (INVOKE_OBJECT (KILL, op, ARG_OBJECT (hitter))) 1424 if (INVOKE_OBJECT (KILL, op, ARG_OBJECT (hitter)))
1506 */ 1508 */
1507 if (op->type == PLAYER && owner != op && !battleg) 1509 if (op->type == PLAYER && owner != op && !battleg)
1508 owner->change_luck (-settings.pk_luck_penalty); 1510 owner->change_luck (-settings.pk_luck_penalty);
1509 1511
1510 /* This code below deals with finding the appropriate skill 1512 /* This code below deals with finding the appropriate skill
1511 * to credit exp to. This is a bit problematic - we should 1513 * to credit exp to. This is a bit problematic - we should
1512 * probably never really have to look at current_weapon->skill 1514 * probably never really have to look at current_weapon->skill
1513 */ 1515 */
1514 skill = 0; 1516 skill = 0;
1515 1517
1516 if (hitter->skill && hitter->type != PLAYER) 1518 if (hitter->skill && hitter->type != PLAYER)
1517 skill = hitter->skill; 1519 skill = hitter->skill;
1518 else if (owner->chosen_skill) 1520 else if (owner->chosen_skill)
1519 { 1521 {
1520 skill = owner->chosen_skill->skill;
1521 skop = owner->chosen_skill; 1522 skop = owner->chosen_skill;
1523 skill = skop->skill;
1522 } 1524 }
1523 else if (QUERY_FLAG (owner, FLAG_READY_WEAPON)) 1525 else if (QUERY_FLAG (owner, FLAG_READY_WEAPON))
1524 skill = owner->current_weapon->skill; 1526 skill = owner->current_weapon->skill;
1525 else 1527 else
1526 LOG (llevError, "kill_object - unable to find skill that killed monster\n"); 1528 LOG (llevError, "kill_object - unable to find skill that killed monster\n");
1901 1903
1902#ifdef ATTACK_DEBUG 1904#ifdef ATTACK_DEBUG
1903 LOG (llevDebug, "Attacktype %d did %d damage\n", type, maxdam); 1905 LOG (llevDebug, "Attacktype %d did %d damage\n", type, maxdam);
1904#endif 1906#endif
1905 1907
1908 // for now, only do this for active objects, otherwise they
1909 // keep a refcount for a long time and I see no usefulness
1910 // for an non-active objetc to know its enemy.
1911 if (op->active)
1906 if (hitter->owner) 1912 if (hitter->owner)
1907 op->enemy = hitter->owner; 1913 op->enemy = hitter->owner;
1908 else if (QUERY_FLAG (hitter, FLAG_ALIVE)) 1914 else if (QUERY_FLAG (hitter, FLAG_ALIVE))
1909 op->enemy = hitter; 1915 op->enemy = hitter;
1910 1916
1911 if (QUERY_FLAG (op, FLAG_UNAGGRESSIVE) && op->type != PLAYER) 1917 if (QUERY_FLAG (op, FLAG_UNAGGRESSIVE) && op->type != PLAYER)
1912 { 1918 {
1913 /* The unaggressives look after themselves 8) */ 1919 /* The unaggressives look after themselves 8) */
1914 CLEAR_FLAG (op, FLAG_UNAGGRESSIVE); 1920 CLEAR_FLAG (op, FLAG_UNAGGRESSIVE);

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines