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.118 by root, Tue Nov 10 04:38:45 2009 UTC vs.
Revision 1.125 by root, Sun Nov 29 09:41:28 2009 UTC

41/* did_make_save_item just checks to make sure the item actually 41/* did_make_save_item just checks to make sure the item actually
42 * made its saving throw based on the tables. It does not take 42 * made its saving throw based on the tables. It does not take
43 * any further action (like destroying the item). 43 * any further action (like destroying the item).
44 */ 44 */
45static int 45static int
46did_make_save_item (object *op, int type, object *originator) 46did_make_save_item (object *op, uint32_t type, object *originator)
47{ 47{
48 int i, roll, saves = 0, attacks = 0, number; 48 int saves = 0, attacks = 0;
49 materialtype_t *mt = op->material; 49 materialtype_t *mt = op->material;
50 50
51 // destroying objects without material has many bad effects
52 if (mt == MATERIAL_NULL)
53 return 1;
54
51 roll = rndm (1, 20); 55 int roll = rndm (1, 20);
52 56
53 /* the attacktypes have no meaning for object saves 57 /* the attacktypes have no meaning for object saves
54 * If the type is only magic, don't adjust type - basically, if 58 * If the type is only magic, don't adjust type - basically, if
55 * pure magic is hitting an object, it should save. However, if it 59 * pure magic is hitting an object, it should save. However, if it
56 * is magic teamed with something else, then strip out the 60 * is magic teamed with something else, then strip out the
57 * magic type, and instead let the fire, cold, or whatever component 61 * magic type, and instead let the fire, cold, or whatever component
58 * destroy the item. Otherwise, you get the case of poisoncloud 62 * destroy the item. Otherwise, you get the case of poisoncloud
59 * destroying objects because it has magic attacktype. 63 * destroying objects because it has magic attacktype.
60 */ 64 */
61 if (type != AT_MAGIC) 65 if (type != AT_MAGIC)
62 type &= ~(AT_CONFUSION | AT_DRAIN | AT_GHOSTHIT | AT_POISON | AT_SLOW | 66 type &= ~(AT_CONFUSION | AT_DRAIN | AT_GHOSTHIT | AT_POISON | AT_SLOW |
63 AT_PARALYZE | AT_TURN_UNDEAD | AT_FEAR | AT_DEPLETE | AT_DEATH | 67 AT_PARALYZE | AT_TURN_UNDEAD | AT_FEAR | AT_DEPLETE | AT_DEATH |
64 AT_COUNTERSPELL | AT_HOLYWORD | AT_BLIND | AT_LIFE_STEALING | AT_MAGIC); 68 AT_COUNTERSPELL | AT_HOLYWORD | AT_BLIND | AT_LIFE_STEALING | AT_MAGIC);
65 69
70
66 if (type == 0) return TRUE; 71 if (type == 0) return TRUE;
67 72
68 if (roll == 20) return TRUE; 73 if (roll == 20) return TRUE;
69 if (roll == 1) return FALSE; 74 if (roll == 1) return FALSE;
70 75
71 for (number = 0; number < NROFATTACKS; number++) 76 for_all_bits_sparse_32 (type, number)
72 { 77 {
73 i = 1 << number;
74
75 if (!(i & type))
76 continue;
77
78 attacks++; 78 attacks++;
79
79 if (op->resist[number] == 100) 80 if (op->resist[number] == 100)
80 saves++; 81 saves++;
81 else if (roll >= mt->save[number] - op->magic - op->resist[number] / 100) 82 else if (roll >= mt->save[number] - op->magic - op->resist[number] / 100)
82 saves++; 83 saves++;
83 else if ((20 - mt->save[number]) / 3 > originator->stats.dam) 84 else if ((20 - mt->save[number]) / 3 > originator->stats.dam)
148 * object with +/- glow_radius and an "other_arch" to change to. 149 * object with +/- glow_radius and an "other_arch" to change to.
149 * (and please note that we cant fail our save and reach this 150 * (and please note that we cant fail our save and reach this
150 * function if the object doesnt contain a material that can burn. 151 * function if the object doesnt contain a material that can burn.
151 * So forget lighting magical swords on fire with this!) -b.t. 152 * So forget lighting magical swords on fire with this!) -b.t.
152 */ 153 */
153 if (type & (AT_FIRE | AT_ELECTRICITY) 154 if (type & (AT_FIRE | AT_ELECTRICITY))
154 && (QUERY_FLAG (op, FLAG_IS_LIGHTABLE)
155 || op->type == LAMP
156 || op->type == TORCH
157 )) 155 {
158 { 156 // seems LAMPs and TORCHes are always IS_LIGHTABLE?
159 switch (op->type) 157 if (op->type == LAMP || op->type == TORCH)
160 { 158 {
161 case LAMP:
162 case TORCH:
163 // turn on a lamp
164 apply_lamp (op, true); 159 apply_lamp (op, true); // turn on a lamp
165 break; 160 return;
166
167 default:
168 // for instance icecubes:
169 if (op->other_arch)
170 {
171 const char *arch = op->other_arch->archname;
172
173 if (op->decrease ())
174 fix_stopped_item (op, m, originator);
175
176 if ((op = archetype::get (arch)))
177 {
178 if (env)
179 env->insert (op);
180 else
181 m->insert (op, x, y, originator);
182 }
183 }
184 } 161 }
162 else if (op->flag [FLAG_IS_LIGHTABLE])
163 {
164 if (op->other_arch)
165 {
166 const char *arch = op->other_arch->archname;
167
168 if (op->decrease ())
169 fix_stopped_item (op, m, originator);
170
171 if ((op = archetype::get (arch)))
172 {
173 if (env)
174 env->insert (op);
175 else
176 m->insert (op, x, y, originator);
177 }
178 }
179
185 return; 180 return;
181 }
186 } 182 }
187 183
188 if (type & AT_CANCELLATION) 184 if (type & AT_CANCELLATION)
189 { /* Cancellation. */ 185 { /* Cancellation. */
190 cancellation (op); 186 cancellation (op);
191 fix_stopped_item (op, m, originator); 187 fix_stopped_item (op, m, originator);
188
192 return; 189 return;
193 }
194
195 if (op->nrof > 1)
196 {
197 if (op->decrease (rndm (0, op->nrof - 1)))
198 fix_stopped_item (op, m, originator);
199 }
200 else
201 {
202 // drop everything to the ground, if possible
203 op->insert_at (originator);
204 op->drop_and_destroy ();
205 } 190 }
206 191
207 if (type & (AT_FIRE | AT_ELECTRICITY)) 192 if (type & (AT_FIRE | AT_ELECTRICITY))
208 if (env) 193 if (env)
209 { 194 {
210 op = archetype::get (shstr_burnout); 195 object *op = archetype::get (shstr_burnout);
211 op->x = env->x, op->y = env->y; 196 op->x = env->x, op->y = env->y;
212 env->insert (op); 197 env->insert (op);
213 } 198 }
214 else 199 else
215 replace_insert_ob_in_map (shstr_burnout, originator); 200 replace_insert_ob_in_map (shstr_burnout, originator);
201
202 if (op->nrof > 1)
203 {
204 if (op->decrease (rndm (0, op->nrof - 1)))
205 fix_stopped_item (op, m, originator);
206 }
207 else
208 {
209 // drop everything to the ground, if possible
210 op->insert_at (originator);
211 op->drop_and_destroy ();
212 }
216 213
217 return; 214 return;
218 } 215 }
219 216
220 /* The value of 50 is arbitrary. */ 217 /* The value of 50 is arbitrary. */
253 * type is the attacktype of the object. 250 * type is the attacktype of the object.
254 * full_hit is set if monster area does not matter. 251 * full_hit is set if monster area does not matter.
255 * returns 1 if it hits something, 0 otherwise. 252 * returns 1 if it hits something, 0 otherwise.
256 */ 253 */
257int 254int
258hit_map (object *op, int dir, int type, int full_hit) 255hit_map (object *op, int dir, uint32_t type, int full_hit)
259{ 256{
260 maptile *map; 257 maptile *map;
261 sint16 x, y; 258 sint16 x, y;
262 int retflag = 0; /* added this flag.. will return 1 if it hits a monster */ 259 int retflag = 0; /* added this flag.. will return 1 if it hits a monster */
263 260
353 * NO_PASS set, it is also immune - you can't destroy walls. Note 350 * NO_PASS set, it is also immune - you can't destroy walls. Note
354 * that weak walls have is_alive set, which prevent objects from 351 * that weak walls have is_alive set, which prevent objects from
355 * passing over/through them. We don't care what type of movement 352 * passing over/through them. We don't care what type of movement
356 * the wall blocks - if it blocks any type of movement, can't be 353 * the wall blocks - if it blocks any type of movement, can't be
357 * destroyed right now. 354 * destroyed right now.
355 * Without the material check the server completely fails to work,
356 * objects detsroy themselves, floors get destroyed etc. etc.
358 */ 357 */
359 else if (op->stats.dam > 0 && !tmp->move_block) 358 else if (op->stats.dam > 0 && !tmp->move_block && tmp->material != MATERIAL_NULL)
360 { 359 {
361 save_throw_object (tmp, type, op); 360 save_throw_object (tmp, type, op);
362 361
363 if (op->destroyed ()) 362 if (op->destroyed ())
364 break; 363 break;
865 864
866 /* 865 /*
867 * A little check to make it more difficult to dance forward and back 866 * A little check to make it more difficult to dance forward and back
868 * to avoid ever being hit by monsters. 867 * to avoid ever being hit by monsters.
869 */ 868 */
870 if (!simple_attack && QUERY_FLAG (op, FLAG_MONSTER) && op->speed_left > abs (op->speed) * -0.3f) 869 if (!simple_attack && QUERY_FLAG (op, FLAG_MONSTER) && op->speed_left > op->speed * -0.3f)
871 { 870 {
872 /* Decrease speed BEFORE calling process_object. Otherwise, an 871 /* Decrease speed BEFORE calling process_object. Otherwise, an
873 * infinite loop occurs, with process_object calling move_monster, 872 * infinite loop occurs, with process_object calling move_monster,
874 * which then gets here again. By decreasing the speed before 873 * which then gets here again. By decreasing the speed before
875 * we call process_object, the 'if' statement above will fail. 874 * we call process_object, the 'if' statement above will fail.
1452 * modify it. 1451 * modify it.
1453 */ 1452 */
1454/* Oct 95 - altered the following slightly for MULTIPLE_GODS hack 1453/* Oct 95 - altered the following slightly for MULTIPLE_GODS hack
1455 * which needs new attacktype AT_HOLYWORD to work . b.t. */ 1454 * which needs new attacktype AT_HOLYWORD to work . b.t. */
1456int 1455int
1457hit_player (object *op, int dam, object *hitter, int type, int full_hit) 1456hit_player (object *op, int dam, object *hitter, uint32_t type, int full_hit)
1458{ 1457{
1459 int maxdam = 0, ndam = 0, attacktype = 1, magic = (type & AT_MAGIC); 1458 int magic = type & AT_MAGIC;
1460 int maxattacktype, attacknum;
1461 int body_attack = op && op->head; /* Did we hit op's head? */ 1459 int body_attack = op && op->head; /* Did we hit op's head? */
1460 int maxdam = 0, ndam = 0, attacktype = 1;
1461 int maxattacktype;
1462 int simple_attack; 1462 int simple_attack;
1463 int rtn_kill = 0; 1463 int rtn_kill = 0;
1464 int friendlyfire; 1464 int friendlyfire;
1465 1465
1466 if (get_attack_mode (&op, &hitter, &simple_attack)) 1466 if (get_attack_mode (&op, &hitter, &simple_attack))
1576 && god->race.contains (shstr_undead)))) 1576 && god->race.contains (shstr_undead))))
1577 return 0; 1577 return 0;
1578 } 1578 }
1579 1579
1580 maxattacktype = type; /* initialise this to something */ 1580 maxattacktype = type; /* initialise this to something */
1581 for (attacknum = 0; attacknum < NROFATTACKS; attacknum++, attacktype = 1 << attacknum) 1581 for_all_bits_sparse_32 (type, attacknum)
1582 { 1582 {
1583 uint32_t attacktype = 1 << attacknum;
1584
1583 /* Magic isn't really a true attack type - it gets combined with other 1585 /* Magic isn't really a true attack type - it gets combined with other
1584 * attack types. As such, skip it over. However, if magic is 1586 * attack types. As such, skip it over. However, if magic is
1585 * the only attacktype in the group, then still attack with it 1587 * the only attacktype in the group, then still attack with it
1586 */ 1588 */
1587 if ((attacktype == AT_MAGIC) && (type & ~AT_MAGIC)) 1589 if ((attacktype == AT_MAGIC) && (type & ~AT_MAGIC))
1590 /* Go through and hit the player with each attacktype, one by one. 1592 /* Go through and hit the player with each attacktype, one by one.
1591 * hit_player_attacktype only figures out the damage, doesn't inflict 1593 * hit_player_attacktype only figures out the damage, doesn't inflict
1592 * it. It will do the appropriate action for attacktypes with 1594 * it. It will do the appropriate action for attacktypes with
1593 * effects (slow, paralization, etc. 1595 * effects (slow, paralization, etc.
1594 */ 1596 */
1595 if (type & attacktype)
1596 {
1597 ndam = hit_player_attacktype (op, hitter, dam, attacknum, magic); 1597 ndam = hit_player_attacktype (op, hitter, dam, attacknum, magic);
1598
1598 /* the >= causes us to prefer messages from special attacks, if 1599 /* the >= causes us to prefer messages from special attacks, if
1599 * the damage is equal. 1600 * the damage is equal.
1600 */ 1601 */
1601 if (ndam >= maxdam) 1602 if (ndam >= maxdam)
1602 { 1603 {
1603 maxdam = ndam; 1604 maxdam = ndam;
1604 maxattacktype = 1 << attacknum; 1605 maxattacktype = 1 << attacknum;
1605 }
1606 } 1606 }
1607 } 1607 }
1608 1608
1609 /* if this is friendly fire then do a set % of damage only 1609 /* if this is friendly fire then do a set % of damage only
1610 * Note - put a check in to make sure this attack is actually 1610 * Note - put a check in to make sure this attack is actually
1668 attack_message (maxdam, maxattacktype, op, hitter); 1668 attack_message (maxdam, maxattacktype, op, hitter);
1669 1669
1670 op->stats.hp -= maxdam; 1670 op->stats.hp -= maxdam;
1671 1671
1672 /* Eneq(@csd.uu.se): Check to see if monster runs away. */ 1672 /* Eneq(@csd.uu.se): Check to see if monster runs away. */
1673 if ((op->stats.hp >= 0) && 1673 if (op->stats.hp >= 0
1674 (QUERY_FLAG (op, FLAG_MONSTER) || op->type == PLAYER) && 1674 && (QUERY_FLAG (op, FLAG_MONSTER) || op->type == PLAYER)
1675 op->stats.hp < (signed short) (((float) op->run_away / (float) 100) * (float) op->stats.maxhp)) 1675 && op->stats.hp * 100 < op->stats.maxhp * op->run_away)
1676 { 1676 {
1677 1677
1678 if (QUERY_FLAG (op, FLAG_MONSTER)) 1678 if (QUERY_FLAG (op, FLAG_MONSTER))
1679 SET_FLAG (op, FLAG_RUN_AWAY); 1679 SET_FLAG (op, FLAG_RUN_AWAY);
1680 else 1680 else
1701 if (QUERY_FLAG (hitter, FLAG_ONE_HIT)) 1701 if (QUERY_FLAG (hitter, FLAG_ONE_HIT))
1702 hitter->drop_and_destroy (); 1702 hitter->drop_and_destroy ();
1703 /* Lets handle creatures that are splitting now */ 1703 /* Lets handle creatures that are splitting now */
1704 else if (type & AT_PHYSICAL && !QUERY_FLAG (op, FLAG_FREED) && QUERY_FLAG (op, FLAG_SPLITTING)) 1704 else if (type & AT_PHYSICAL && !QUERY_FLAG (op, FLAG_FREED) && QUERY_FLAG (op, FLAG_SPLITTING))
1705 { 1705 {
1706 int i;
1707 int friendly = QUERY_FLAG (op, FLAG_FRIENDLY); 1706 int friendly = QUERY_FLAG (op, FLAG_FRIENDLY);
1708 int unaggressive = QUERY_FLAG (op, FLAG_UNAGGRESSIVE); 1707 int unaggressive = QUERY_FLAG (op, FLAG_UNAGGRESSIVE);
1709 object *owner = op->owner; 1708 object *owner = op->owner;
1710 1709
1711 if (!op->other_arch) 1710 if (!op->other_arch)
1714 return maxdam; 1713 return maxdam;
1715 } 1714 }
1716 1715
1717 op->remove (); 1716 op->remove ();
1718 1717
1719 for (i = 0; i < op->stats.food; i++) 1718 for (int i = 0; i < op->stats.food; i++)
1720 { /* This doesn't handle op->more yet */ 1719 { /* This doesn't handle op->more yet */
1721 object *tmp = arch_to_object (op->other_arch); 1720 object *tmp = arch_to_object (op->other_arch);
1722 int j;
1723 1721
1724 tmp->stats.hp = op->stats.hp; 1722 tmp->stats.hp = op->stats.hp;
1725 1723
1726 if (friendly) 1724 if (friendly)
1727 { 1725 {
1733 } 1731 }
1734 1732
1735 if (unaggressive) 1733 if (unaggressive)
1736 SET_FLAG (tmp, FLAG_UNAGGRESSIVE); 1734 SET_FLAG (tmp, FLAG_UNAGGRESSIVE);
1737 1735
1738 j = find_first_free_spot (tmp, op->map, op->x, op->y); 1736 int j = find_first_free_spot (tmp, op->map, op->x, op->y);
1739 1737
1740 if (j == -1) /* No spot to put this monster */ 1738 if (j == -1) /* No spot to put this monster */
1741 tmp->destroy (); 1739 tmp->destroy ();
1742 else 1740 else
1743 { 1741 {
1919 */ 1917 */
1920 1918
1921 /* Do this as a float - otherwise, rounding might very well reduce this to 0 */ 1919 /* Do this as a float - otherwise, rounding might very well reduce this to 0 */
1922 float effect = dam * 3.f * (100.f - op->resist[ATNR_PARALYZE]) / 100.f; 1920 float effect = dam * 3.f * (100.f - op->resist[ATNR_PARALYZE]) / 100.f;
1923 1921
1924 op->speed_left -= fabs (op->speed) * effect; 1922 op->speed_left -= op->speed * effect;
1925 /* tmp->stats.food+=(signed short) effect/op->speed; */ 1923 /* tmp->stats.food+=(signed short) effect/op->speed; */
1926 1924
1927 /* max number of ticks to be affected for. */ 1925 /* max number of ticks to be affected for. */
1928 float max = (100 - op->resist[ATNR_PARALYZE]) / 2; 1926 float max = (100 - op->resist[ATNR_PARALYZE]) / 2;
1929 1927
1930 if (op->speed_left < -(fabs (op->speed) * max)) 1928 max_it (op->speed_left, -op->speed * max);
1931 op->speed_left = -(fabs (op->speed) * max);
1932 1929
1933/* tmp->stats.food = (signed short) (max / fabs (op->speed)); */ 1930/* tmp->stats.food = (signed short) (max / op->speed); */
1934} 1931}
1935 1932
1936/* Attempts to kill 'op'. hitter is the attack object, dam is 1933/* Attempts to kill 'op'. hitter is the attack object, dam is
1937 * the computed damaged. 1934 * the computed damaged.
1938 */ 1935 */

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines