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.10 by root, Mon Sep 11 11:46:52 2006 UTC vs.
Revision 1.44 by root, Mon Jan 15 15:41:09 2007 UTC

1
2/*
3 * static char *rcsid_attack_c =
4 * "$Id: attack.C,v 1.10 2006/09/11 11:46:52 root Exp $";
5 */
6
7/* 1/*
8 CrossFire, A Multiplayer game for X-windows 2 CrossFire, A Multiplayer game for X-windows
9 3
4 Copyright (C) 2005, 2006, 2007 Marc Lehmann & Crossfire+ Development Team
10 Copyright (C) 2002 Mark Wedel & Crossfire Development Team 5 Copyright (C) 2002 Mark Wedel & Crossfire Development Team
11 Copyright (C) 1992 Frank Tore Johansen 6 Copyright (C) 1992 Frank Tore Johansen
12 7
13 This program is free software; you can redistribute it and/or modify 8 This program is free software; you can redistribute it and/or modify
14 it under the terms of the GNU General Public License as published by 9 it under the terms of the GNU General Public License as published by
22 17
23 You should have received a copy of the GNU General Public License 18 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software 19 along with this program; if not, write to the Free Software
25 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 21
27 The authors can be reached via e-mail to crossfire-devel@real-time.com 22 The authors can be reached via e-mail to <crossfire@schmorp.de>
28*/ 23*/
29#include <assert.h> 24#include <assert.h>
30#include <global.h> 25#include <global.h>
31#include <living.h> 26#include <living.h>
32#include <material.h> 27#include <material.h>
50 * its magical benefits. 45 * its magical benefits.
51 */ 46 */
52void 47void
53cancellation (object *op) 48cancellation (object *op)
54{ 49{
55 object *tmp;
56
57 if (op->invisible) 50 if (op->invisible)
58 return; 51 return;
59 52
60 if (QUERY_FLAG (op, FLAG_ALIVE) || op->type == CONTAINER || op->type == THROWN_OBJ) 53 if (QUERY_FLAG (op, FLAG_ALIVE) || op->type == CONTAINER || op->type == THROWN_OBJ)
61 { 54 {
62 /* Recur through the inventory */ 55 /* Recurse through the inventory */
63 for (tmp = op->inv; tmp != NULL; tmp = tmp->below) 56 for (object *tmp = op->inv; tmp; tmp = tmp->below)
64 if (!did_make_save_item (tmp, AT_CANCELLATION, op)) 57 if (!did_make_save_item (tmp, AT_CANCELLATION, op))
65 cancellation (tmp); 58 cancellation (tmp);
66 } 59 }
67 else if (FABS (op->magic) <= (rndm (0, 5))) 60 else if (FABS (op->magic) <= rndm (0, 5))
68 { 61 {
69 /* Nullify this object. This code could probably be more complete */ 62 /* Nullify this object. This code could probably be more complete */
70 /* in what abilities it should cancel */ 63 /* in what abilities it should cancel */
71 op->magic = 0; 64 op->magic = 0;
65
72 CLEAR_FLAG (op, FLAG_DAMNED); 66 CLEAR_FLAG (op, FLAG_DAMNED);
73 CLEAR_FLAG (op, FLAG_CURSED); 67 CLEAR_FLAG (op, FLAG_CURSED);
74 CLEAR_FLAG (op, FLAG_KNOWN_MAGICAL); 68 CLEAR_FLAG (op, FLAG_KNOWN_MAGICAL);
75 CLEAR_FLAG (op, FLAG_KNOWN_CURSED); 69 CLEAR_FLAG (op, FLAG_KNOWN_CURSED);
70
76 if (op->env && op->env->type == PLAYER) 71 if (op->env && op->env->type == PLAYER)
77 {
78 esrv_send_item (op->env, op); 72 esrv_send_item (op->env, op);
79 }
80 } 73 }
81} 74}
82
83
84 75
85/* did_make_save_item just checks to make sure the item actually 76/* did_make_save_item just checks to make sure the item actually
86 * made its saving throw based on the tables. It does not take 77 * made its saving throw based on the tables. It does not take
87 * any further action (like destroying the item). 78 * any further action (like destroying the item).
88 */ 79 */
89
90int 80int
91did_make_save_item (object *op, int type, object *originator) 81did_make_save_item (object *op, int type, object *originator)
92{ 82{
93 int i, roll, saves = 0, attacks = 0, number; 83 int i, roll, saves = 0, attacks = 0, number;
94 materialtype_t *mt; 84 materialtype_t *mt;
95 85
96 if (op->materialname == NULL) 86 if (op->materialname == NULL)
97 { 87 {
98 for (mt = materialt; mt != NULL && mt->next != NULL; mt = mt->next) 88 for (mt = materialt; mt != NULL && mt->next != NULL; mt = mt->next)
99 {
100 if (op->material & mt->material) 89 if (op->material & mt->material)
101 break; 90 break;
102 }
103 } 91 }
104 else 92 else
105 mt = name_to_material (op->materialname); 93 mt = name_to_material (op->materialname);
94
106 if (mt == NULL) 95 if (mt == NULL)
107 return TRUE; 96 return TRUE;
97
108 roll = rndm (1, 20); 98 roll = rndm (1, 20);
109 99
110 /* the attacktypes have no meaning for object saves 100 /* the attacktypes have no meaning for object saves
111 * If the type is only magic, don't adjust type - basically, if 101 * If the type is only magic, don't adjust type - basically, if
112 * pure magic is hitting an object, it should save. However, if it 102 * pure magic is hitting an object, it should save. However, if it
150 140
151/* This function calls did_make_save_item. It then performs the 141/* This function calls did_make_save_item. It then performs the
152 * appropriate actions to the item (such as burning the item up, 142 * appropriate actions to the item (such as burning the item up,
153 * calling cancellation, etc.) 143 * calling cancellation, etc.)
154 */ 144 */
155
156void 145void
157save_throw_object (object *op, int type, object *originator) 146save_throw_object (object *op, int type, object *originator)
158{ 147{
159 if (!did_make_save_item (op, type, originator)) 148 if (!did_make_save_item (op, type, originator))
160 { 149 {
161 object *env = op->env; 150 object *env = op->env;
162 int x = op->x, y = op->y; 151 int x = op->x, y = op->y;
163 mapstruct *m = op->map; 152 maptile *m = op->map;
164 153
165 op = stop_item (op); 154 op = stop_item (op);
166 if (op == NULL) 155 if (op == NULL)
167 return; 156 return;
168 157
177 if (type & (AT_FIRE | AT_ELECTRICITY) && op->other_arch && QUERY_FLAG (op, FLAG_IS_LIGHTABLE)) 166 if (type & (AT_FIRE | AT_ELECTRICITY) && op->other_arch && QUERY_FLAG (op, FLAG_IS_LIGHTABLE))
178 { 167 {
179 const char *arch = op->other_arch->name; 168 const char *arch = op->other_arch->name;
180 169
181 op = decrease_ob_nr (op, 1); 170 op = decrease_ob_nr (op, 1);
171
182 if (op) 172 if (op)
183 fix_stopped_item (op, m, originator); 173 fix_stopped_item (op, m, originator);
174
184 if ((op = get_archetype (arch)) != NULL) 175 if ((op = get_archetype (arch)) != NULL)
185 { 176 {
186 if (env) 177 if (env)
187 { 178 {
188 op->x = env->x, op->y = env->y; 179 op->x = env->x, op->y = env->y;
194 { 185 {
195 op->x = x, op->y = y; 186 op->x = x, op->y = y;
196 insert_ob_in_map (op, m, originator, 0); 187 insert_ob_in_map (op, m, originator, 0);
197 } 188 }
198 } 189 }
190
199 return; 191 return;
200 } 192 }
193
201 if (type & AT_CANCELLATION) 194 if (type & AT_CANCELLATION)
202 { /* Cancellation. */ 195 { /* Cancellation. */
203 cancellation (op); 196 cancellation (op);
204 fix_stopped_item (op, m, originator); 197 fix_stopped_item (op, m, originator);
205 return; 198 return;
206 } 199 }
200
207 if (op->nrof > 1) 201 if (op->nrof > 1)
208 { 202 {
209 op = decrease_ob_nr (op, rndm (0, op->nrof - 1)); 203 op = decrease_ob_nr (op, rndm (0, op->nrof - 1));
204
210 if (op) 205 if (op)
211 fix_stopped_item (op, m, originator); 206 fix_stopped_item (op, m, originator);
212 } 207 }
213 else 208 else
214 { 209 {
215 if (op->env) 210 if (op->env)
216 { 211 {
217 object *tmp = is_player_inv (op->env); 212 object *tmp = op->in_player ();
218 213
219 if (tmp) 214 if (tmp)
220 {
221 esrv_del_item (tmp->contr, op->count); 215 esrv_del_item (tmp->contr, op->count);
222 }
223 } 216 }
224 if (!QUERY_FLAG (op, FLAG_REMOVED)) 217
225 remove_ob (op); 218 op->destroy ();
226 free_object (op);
227 } 219 }
220
228 if (type & (AT_FIRE | AT_ELECTRICITY)) 221 if (type & (AT_FIRE | AT_ELECTRICITY))
229 {
230 if (env) 222 if (env)
231 { 223 {
232 op = get_archetype ("burnout"); 224 op = get_archetype ("burnout");
233 op->x = env->x, op->y = env->y; 225 op->x = env->x, op->y = env->y;
234 insert_ob_in_ob (op, env); 226 insert_ob_in_ob (op, env);
235 } 227 }
236 else 228 else
237 {
238 replace_insert_ob_in_map ("burnout", originator); 229 replace_insert_ob_in_map ("burnout", originator);
239 } 230
240 }
241 return; 231 return;
242 } 232 }
233
243 /* The value of 50 is arbitrary. */ 234 /* The value of 50 is arbitrary. */
244 if (type & AT_COLD && (op->resist[ATNR_COLD] < 50) && !QUERY_FLAG (op, FLAG_NO_PICK) && (RANDOM () & 2)) 235 if (type & AT_COLD && (op->resist[ATNR_COLD] < 50) && !QUERY_FLAG (op, FLAG_NO_PICK) && (RANDOM () & 2))
245 { 236 {
246 object *tmp; 237 object *tmp;
247 archetype *at = find_archetype ("icecube"); 238 archetype *at = archetype::find ("icecube");
248 239
249 if (at == NULL) 240 if (at == NULL)
250 return; 241 return;
242
251 op = stop_item (op); 243 op = stop_item (op);
252 if (op == NULL) 244 if (op == NULL)
253 return; 245 return;
246
254 if ((tmp = present_arch (at, op->map, op->x, op->y)) == NULL) 247 if ((tmp = present_arch (at, op->map, op->x, op->y)) == NULL)
255 { 248 {
256 tmp = arch_to_object (at); 249 tmp = arch_to_object (at);
257 tmp->x = op->x, tmp->y = op->y; 250 tmp->x = op->x, tmp->y = op->y;
258 /* This was in the old (pre new movement code) - 251 /* This was in the old (pre new movement code) -
261 */ 254 */
262 tmp->move_slow_penalty = 0; 255 tmp->move_slow_penalty = 0;
263 tmp->move_slow = 0; 256 tmp->move_slow = 0;
264 insert_ob_in_map (tmp, op->map, originator, 0); 257 insert_ob_in_map (tmp, op->map, originator, 0);
265 } 258 }
259
266 if (!QUERY_FLAG (op, FLAG_REMOVED)) 260 if (!QUERY_FLAG (op, FLAG_REMOVED))
267 remove_ob (op); 261 op->remove ();
262
268 (void) insert_ob_in_ob (op, tmp); 263 insert_ob_in_ob (op, tmp);
269 return; 264 return;
270 } 265 }
271} 266}
272 267
273/* Object op is hitting the map. 268/* Object op is hitting the map.
278 */ 273 */
279 274
280int 275int
281hit_map (object *op, int dir, int type, int full_hit) 276hit_map (object *op, int dir, int type, int full_hit)
282{ 277{
283 object *tmp, *next;
284 mapstruct *map; 278 maptile *map;
285 sint16 x, y; 279 sint16 x, y;
286 int retflag = 0; /* added this flag.. will return 1 if it hits a monster */ 280 int retflag = 0; /* added this flag.. will return 1 if it hits a monster */
287 281
288 tag_t op_tag, next_tag = 0;
289
290 if (QUERY_FLAG (op, FLAG_FREED)) 282 if (QUERY_FLAG (op, FLAG_FREED))
291 { 283 {
292 LOG (llevError, "BUG: hit_map(): free object\n"); 284 LOG (llevError, "BUG: hit_map(): free object\n");
293 return 0; 285 return 0;
294 } 286 }
305 return 0; 297 return 0;
306 } 298 }
307 299
308 if (op->head) 300 if (op->head)
309 op = op->head; 301 op = op->head;
310
311 op_tag = op->count;
312 302
313 map = op->map; 303 map = op->map;
314 x = op->x + freearr_x[dir]; 304 x = op->x + freearr_x[dir];
315 y = op->y + freearr_y[dir]; 305 y = op->y + freearr_y[dir];
316 306
317 int mflags = get_map_flags (map, &map, x, y, &x, &y); 307 if (!xy_normalise (map, x, y))
308 return 0;
318 309
319 // elmex: a safe map tile can't be hit! 310 // elmex: a safe map tile can't be hit!
320 // this should prevent most harmful effects on items and players there. 311 // this should prevent most harmful effects on items and players there.
321 if ((mflags & P_OUT_OF_MAP) || (mflags & P_SAFE)) 312 mapspace &ms = map->at (x, y);
313
314 if (ms.flags () & P_SAFE)
322 return 0; 315 return 0;
323 316
324 /* peterm: a few special cases for special attacktypes --counterspell 317 /* peterm: a few special cases for special attacktypes --counterspell
325 * must be out here because it strikes things which are not alive 318 * must be out here because it strikes things which are not alive
326 */ 319 */
327 320 if (type & (AT_COUNTERSPELL | AT_CHAOS))
321 {
328 if (type & AT_COUNTERSPELL) 322 if (type & AT_COUNTERSPELL)
329 { 323 {
330 counterspell (op, dir); /* see spell_effect.c */ 324 counterspell (op, dir); /* see spell_effect.c */
331 325
332 /* If the only attacktype is counterspell or magic, don't need 326 /* If the only attacktype is counterspell or magic, don't need
333 * to do any further processing. 327 * to do any further processing.
334 */
335 if (!(type & ~(AT_COUNTERSPELL | AT_MAGIC)))
336 {
337 return 0;
338 }
339 type &= ~AT_COUNTERSPELL;
340 }
341
342 if (type & AT_CHAOS)
343 {
344 shuffle_attack (op, 1); /*1 flag tells it to change the face */
345 update_object (op, UP_OBJ_FACE);
346 type &= ~AT_CHAOS;
347 }
348
349 next = get_map_ob (map, x, y);
350 if (next)
351 next_tag = next->count;
352
353 while (next)
354 {
355 if (was_destroyed (next, next_tag))
356 {
357 /* There may still be objects that were above 'next', but there is no
358 * simple way to find out short of copying all object references and
359 * tags into a temporary array before we start processing the first
360 * object. That's why we just abort.
361 *
362 * This happens whenever attack spells (like fire) hit a pile
363 * of objects. This is not a bug - nor an error. The errormessage
364 * below was spamming the logs for absolutely no reason.
365 */ 328 */
366 /* LOG (llevDebug, "hit_map(): next object destroyed\n"); */ 329 if (!(type & ~(AT_COUNTERSPELL | AT_MAGIC)))
367 break; 330 return 0;
331
332 type &= ~AT_COUNTERSPELL;
333 }
334
335 if (type & AT_CHAOS)
368 } 336 {
337 shuffle_attack (op, 1); /* flag tells it to change the face */
338 update_object (op, UP_OBJ_FACE);
339 type &= ~AT_CHAOS;
340 }
341 }
342
343 /* There may still be objects that were above 'next', but there is no
344 * simple way to find out short of copying all object references and
345 * tags into a temporary array before we start processing the first
346 * object. That's why we just abort on destroy.
347 *
348 * This happens whenever attack spells (like fire) hit a pile
349 * of objects. This is not a bug - nor an error.
350 */
351 for (object *next = ms.bot; next && !next->destroyed (); )
352 {
369 tmp = next; 353 object *tmp = next;
370 next = tmp->above; 354 next = tmp->above;
371 if (next)
372 next_tag = next->count;
373
374 if (QUERY_FLAG (tmp, FLAG_FREED))
375 {
376 LOG (llevError, "BUG: hit_map(): found freed object\n");
377 break;
378 }
379 355
380 /* Something could have happened to 'tmp' while 'tmp->below' was processed. 356 /* Something could have happened to 'tmp' while 'tmp->below' was processed.
381 * For example, 'tmp' was put in an icecube. 357 * For example, 'tmp' was put in an icecube.
382 * This is one of the few cases where on_same_map should not be used. 358 * This is one of the few cases where on_same_map should not be used.
383 */ 359 */
386 362
387 if (QUERY_FLAG (tmp, FLAG_ALIVE)) 363 if (QUERY_FLAG (tmp, FLAG_ALIVE))
388 { 364 {
389 hit_player (tmp, op->stats.dam, op, type, full_hit); 365 hit_player (tmp, op->stats.dam, op, type, full_hit);
390 retflag |= 1; 366 retflag |= 1;
367
391 if (was_destroyed (op, op_tag)) 368 if (op->destroyed ())
392 break; 369 break;
393 } 370 }
394 /* Here we are potentially destroying an object. If the object has 371 /* Here we are potentially destroying an object. If the object has
395 * NO_PASS set, it is also immune - you can't destroy walls. Note 372 * NO_PASS set, it is also immune - you can't destroy walls. Note
396 * that weak walls have is_alive set, which prevent objects from 373 * that weak walls have is_alive set, which prevent objects from
399 * destroyed right now. 376 * destroyed right now.
400 */ 377 */
401 else if ((tmp->material || tmp->materialname) && op->stats.dam > 0 && !tmp->move_block) 378 else if ((tmp->material || tmp->materialname) && op->stats.dam > 0 && !tmp->move_block)
402 { 379 {
403 save_throw_object (tmp, type, op); 380 save_throw_object (tmp, type, op);
381
404 if (was_destroyed (op, op_tag)) 382 if (op->destroyed ())
405 break; 383 break;
406 } 384 }
407 } 385 }
386
408 return 0; 387 return 0;
409} 388}
410 389
411void 390void
412attack_message (int dam, int type, object *op, object *hitter) 391attack_message (int dam, int type, object *op, object *hitter)
413{ 392{
414 char buf[MAX_BUF], buf1[MAX_BUF], buf2[MAX_BUF]; 393 char buf[MAX_BUF], buf1[MAX_BUF], buf2[MAX_BUF];
415 int i, found = 0; 394 int i, found = 0;
416 mapstruct *map; 395 maptile *map;
417 object *next, *tmp; 396 object *next, *tmp;
418 397
419 /* put in a few special messages for some of the common attacktypes 398 /* put in a few special messages for some of the common attacktypes
420 * a player might have. For example, fire, electric, cold, etc 399 * a player might have. For example, fire, electric, cold, etc
421 * [garbled 20010919] 400 * [garbled 20010919]
438 sprintf (buf1, "missed %s", &op->name); 417 sprintf (buf1, "missed %s", &op->name);
439 sprintf (buf2, " misses"); 418 sprintf (buf2, " misses");
440 found++; 419 found++;
441 } 420 }
442 else if ((hitter->type == DISEASE || hitter->type == SYMPTOM || 421 else if ((hitter->type == DISEASE || hitter->type == SYMPTOM ||
443 hitter->type == POISONING || (type & AT_POISON && IS_LIVE (op))) && !found) 422 hitter->type == POISONING || (type & AT_POISON && op->is_alive ())) && !found)
444 { 423 {
445 for (i = 0; i < MAXATTACKMESS && attack_mess[ATM_SUFFER][i].level != -1; i++) 424 for (i = 0; i < MAXATTACKMESS && attack_mess[ATM_SUFFER][i].level != -1; i++)
446 if (dam < attack_mess[ATM_SUFFER][i].level || attack_mess[ATM_SUFFER][i + 1].level == -1) 425 if (dam < attack_mess[ATM_SUFFER][i].level || attack_mess[ATM_SUFFER][i + 1].level == -1)
447 { 426 {
448 sprintf (buf1, "%s %s%s", attack_mess[ATM_SUFFER][i].buf1, &op->name, attack_mess[ATM_SUFFER][i].buf2); 427 sprintf (buf1, "%s %s%s", attack_mess[ATM_SUFFER][i].buf1, &op->name, attack_mess[ATM_SUFFER][i].buf2);
460 strcpy (buf2, attack_mess[ATM_DOOR][i].buf3); 439 strcpy (buf2, attack_mess[ATM_DOOR][i].buf3);
461 found++; 440 found++;
462 break; 441 break;
463 } 442 }
464 } 443 }
465 else if (hitter->type == PLAYER && IS_LIVE (op)) 444 else if (hitter->type == PLAYER && op->is_alive ())
466 { 445 {
467 if (USING_SKILL (hitter, SK_KARATE)) 446 if (USING_SKILL (hitter, SK_KARATE))
468 { 447 {
469 for (i = 0; i < MAXATTACKMESS && attack_mess[ATM_KARATE][i].level != -1; i++) 448 for (i = 0; i < MAXATTACKMESS && attack_mess[ATM_KARATE][i].level != -1; i++)
470 if (dam < attack_mess[ATM_KARATE][i].level || attack_mess[ATM_KARATE][i + 1].level == -1) 449 if (dam < attack_mess[ATM_KARATE][i].level || attack_mess[ATM_KARATE][i + 1].level == -1)
496 found++; 475 found++;
497 break; 476 break;
498 } 477 }
499 } 478 }
500 } 479 }
480
501 if (found) 481 if (found)
502 { 482 {
503 /* done */ 483 /* done */
504 } 484 }
505 else if (IS_ARROW (hitter) && (type == AT_PHYSICAL || type == AT_MAGIC)) 485 else if (hitter->is_arrow () && (type == AT_PHYSICAL || type == AT_MAGIC))
506 { 486 {
507 sprintf (buf1, "hit"); /* just in case */ 487 sprintf (buf1, "hit"); /* just in case */
508 for (i = 0; i < MAXATTACKMESS; i++) 488 for (i = 0; i < MAXATTACKMESS; i++)
509 if (dam < attack_mess[ATM_ARROW][i].level || attack_mess[ATM_ARROW][i + 1].level == -1) 489 if (dam < attack_mess[ATM_ARROW][i].level || attack_mess[ATM_ARROW][i + 1].level == -1)
510 { 490 {
511 strcpy (buf2, attack_mess[ATM_ARROW][i].buf3); 491 strcpy (buf2, attack_mess[ATM_ARROW][i].buf3);
512 found++; 492 found++;
513 break; 493 break;
514 } 494 }
515 } 495 }
516 else if (type & AT_DRAIN && IS_LIVE (op)) 496 else if (type & AT_DRAIN && op->is_alive ())
517 { 497 {
518 /* drain is first, because some items have multiple attypes */ 498 /* drain is first, because some items have multiple attypes */
519 for (i = 0; i < MAXATTACKMESS && attack_mess[ATM_DRAIN][i].level != -1; i++) 499 for (i = 0; i < MAXATTACKMESS && attack_mess[ATM_DRAIN][i].level != -1; i++)
520 if (dam < attack_mess[ATM_DRAIN][i].level || attack_mess[ATM_DRAIN][i + 1].level == -1) 500 if (dam < attack_mess[ATM_DRAIN][i].level || attack_mess[ATM_DRAIN][i + 1].level == -1)
521 { 501 {
523 strcpy (buf2, attack_mess[ATM_DRAIN][i].buf3); 503 strcpy (buf2, attack_mess[ATM_DRAIN][i].buf3);
524 found++; 504 found++;
525 break; 505 break;
526 } 506 }
527 } 507 }
528 else if (type & AT_ELECTRICITY && IS_LIVE (op)) 508 else if (type & AT_ELECTRICITY && op->is_alive ())
529 { 509 {
530 for (i = 0; i < MAXATTACKMESS && attack_mess[ATM_ELEC][i].level != -1; i++) 510 for (i = 0; i < MAXATTACKMESS && attack_mess[ATM_ELEC][i].level != -1; i++)
531 if (dam < attack_mess[ATM_ELEC][i].level || attack_mess[ATM_ELEC][i + 1].level == -1) 511 if (dam < attack_mess[ATM_ELEC][i].level || attack_mess[ATM_ELEC][i + 1].level == -1)
532 { 512 {
533 sprintf (buf1, "%s %s%s", attack_mess[ATM_ELEC][i].buf1, &op->name, attack_mess[ATM_ELEC][i].buf2); 513 sprintf (buf1, "%s %s%s", attack_mess[ATM_ELEC][i].buf1, &op->name, attack_mess[ATM_ELEC][i].buf2);
534 strcpy (buf2, attack_mess[ATM_ELEC][i].buf3); 514 strcpy (buf2, attack_mess[ATM_ELEC][i].buf3);
535 found++; 515 found++;
536 break; 516 break;
537 } 517 }
538 } 518 }
539 else if (type & AT_COLD && IS_LIVE (op)) 519 else if (type & AT_COLD && op->is_alive ())
540 { 520 {
541 for (i = 0; i < MAXATTACKMESS && attack_mess[ATM_COLD][i].level != -1; i++) 521 for (i = 0; i < MAXATTACKMESS && attack_mess[ATM_COLD][i].level != -1; i++)
542 if (dam < attack_mess[ATM_COLD][i].level || attack_mess[ATM_COLD][i + 1].level == -1) 522 if (dam < attack_mess[ATM_COLD][i].level || attack_mess[ATM_COLD][i + 1].level == -1)
543 { 523 {
544 sprintf (buf1, "%s %s%s", attack_mess[ATM_COLD][i].buf1, &op->name, attack_mess[ATM_COLD][i].buf2); 524 sprintf (buf1, "%s %s%s", attack_mess[ATM_COLD][i].buf1, &op->name, attack_mess[ATM_COLD][i].buf2);
621 strcpy (buf1, "hit"); 601 strcpy (buf1, "hit");
622 strcpy (buf2, " hits"); 602 strcpy (buf2, " hits");
623 } 603 }
624 604
625 /* bail out if a monster is casting spells */ 605 /* bail out if a monster is casting spells */
626 if (!(hitter->type == PLAYER || (get_owner (hitter) != NULL && hitter->owner->type == PLAYER))) 606 if (!(hitter->type == PLAYER || (hitter->owner != NULL && hitter->owner->type == PLAYER)))
627 return; 607 return;
628 608
629 /* scale down magic considerably. */ 609 /* scale down magic considerably. */
630 if (type & AT_MAGIC && rndm (0, 5)) 610 if (type & AT_MAGIC && rndm (0, 5))
631 return; 611 return;
632 612
633 /* Did a player hurt another player? Inform both! */ 613 /* Did a player hurt another player? Inform both! */
634 if (op->type == PLAYER && (get_owner (hitter) == NULL ? hitter->type : hitter->owner->type) == PLAYER) 614 if (op->type == PLAYER && (hitter->owner == NULL ? hitter->type : hitter->owner->type) == PLAYER)
635 { 615 {
636 if (get_owner (hitter) != NULL) 616 if (hitter->owner != NULL)
637 sprintf (buf, "%s's %s%s you.", &hitter->owner->name, &hitter->name, buf2); 617 sprintf (buf, "%s's %s%s you.", &hitter->owner->name, &hitter->name, buf2);
638 else 618 else
639 { 619 {
640 sprintf (buf, "%s%s you.", &hitter->name, buf2); 620 sprintf (buf, "%s%s you.", &hitter->name, buf2);
641 if (dam != 0) 621 if (dam != 0)
663 else 643 else
664 play_sound_player_only (hitter->contr, SOUND_PLAYER_HITS3, 0, 0); 644 play_sound_player_only (hitter->contr, SOUND_PLAYER_HITS3, 0, 0);
665 } 645 }
666 new_draw_info (NDI_BLACK, 0, hitter, buf); 646 new_draw_info (NDI_BLACK, 0, hitter, buf);
667 } 647 }
668 else if (get_owner (hitter) != NULL && hitter->owner->type == PLAYER) 648 else if (hitter->owner != NULL && hitter->owner->type == PLAYER)
669 { 649 {
670 /* look for stacked spells and start reducing the message chances */ 650 /* look for stacked spells and start reducing the message chances */
671 if (hitter->type == SPELL_EFFECT && (hitter->subtype == SP_EXPLOSION || hitter->subtype == SP_BULLET || hitter->subtype == SP_CONE)) 651 if (hitter->type == SPELL_EFFECT && (hitter->subtype == SP_EXPLOSION || hitter->subtype == SP_BULLET || hitter->subtype == SP_CONE))
672 { 652 {
673 i = 4; 653 i = 4;
674 map = hitter->map; 654 map = hitter->map;
675 if (out_of_map (map, hitter->x, hitter->y)) 655 if (out_of_map (map, hitter->x, hitter->y))
676 return; 656 return;
677 next = get_map_ob (map, hitter->x, hitter->y); 657 next = GET_MAP_OB (map, hitter->x, hitter->y);
678 if (next) 658 if (next)
679 while (next) 659 while (next)
680 { 660 {
681 if (next->type == SPELL_EFFECT && (next->subtype == SP_EXPLOSION || next->subtype == SP_BULLET || next->subtype == SP_CONE)) 661 if (next->type == SPELL_EFFECT && (next->subtype == SP_EXPLOSION || next->subtype == SP_BULLET || next->subtype == SP_CONE))
682 i *= 3; 662 i *= 3;
748attack_ob_simple (object *op, object *hitter, int base_dam, int base_wc) 728attack_ob_simple (object *op, object *hitter, int base_dam, int base_wc)
749{ 729{
750 int simple_attack, roll, dam = 0; 730 int simple_attack, roll, dam = 0;
751 uint32 type; 731 uint32 type;
752 shstr op_name; 732 shstr op_name;
753 tag_t op_tag, hitter_tag;
754 733
755 if (get_attack_mode (&op, &hitter, &simple_attack)) 734 if (get_attack_mode (&op, &hitter, &simple_attack))
756 goto error; 735 goto error;
757 736
758 if (hitter->current_weapon) 737 if (hitter->current_weapon)
759 if (INVOKE_OBJECT (WEAPON_ATTACK, hitter->current_weapon, ARG_OBJECT (hitter), ARG_OBJECT (op))) 738 if (INVOKE_OBJECT (WEAPON_ATTACK, hitter->current_weapon, ARG_OBJECT (hitter), ARG_OBJECT (op)))
760 return RESULT_INT (0); 739 return RESULT_INT (0);
761 740
762 if (INVOKE_OBJECT (ATTACK, op, ARG_OBJECT (hitter))) 741 if (INVOKE_OBJECT (ATTACK, op, ARG_OBJECT (hitter)))
763 return RESULT_INT (0); 742 return RESULT_INT (0);
764
765 op_tag = op->count;
766 hitter_tag = hitter->count;
767 743
768 /* 744 /*
769 * A little check to make it more difficult to dance forward and back 745 * A little check to make it more difficult to dance forward and back
770 * to avoid ever being hit by monsters. 746 * to avoid ever being hit by monsters.
771 */ 747 */
776 * which then gets here again. By decreasing the speed before 752 * which then gets here again. By decreasing the speed before
777 * we call process_object, the 'if' statement above will fail. 753 * we call process_object, the 'if' statement above will fail.
778 */ 754 */
779 op->speed_left--; 755 op->speed_left--;
780 process_object (op); 756 process_object (op);
757
781 if (was_destroyed (op, op_tag) || was_destroyed (hitter, hitter_tag) || abort_attack (op, hitter, simple_attack)) 758 if (op->destroyed () || hitter->destroyed () || abort_attack (op, hitter, simple_attack))
782 goto error; 759 goto error;
783 } 760 }
784 761
785 op_name = op->name; 762 op_name = op->name;
786 763
798 if (settings.casting_time == TRUE) 775 if (settings.casting_time == TRUE)
799 { 776 {
800 if ((hitter->type == PLAYER) && (hitter->casting_time > -1)) 777 if ((hitter->type == PLAYER) && (hitter->casting_time > -1))
801 { 778 {
802 hitter->casting_time = -1; 779 hitter->casting_time = -1;
803 new_draw_info (NDI_UNIQUE, 0, hitter, "You attacked and lost " "your spell!"); 780 new_draw_info (NDI_UNIQUE, 0, hitter, "You attacked and lost your spell!");
804 } 781 }
805 if ((op->casting_time > -1) && (hitdam > 0)) 782 if ((op->casting_time > -1) && (hitdam > 0))
806 { 783 {
807 op->casting_time = -1; 784 op->casting_time = -1;
808 if (op->type == PLAYER) 785 if (op->type == PLAYER)
809 { 786 {
810 new_draw_info (NDI_UNIQUE, 0, op, "You were hit and lost " "your spell!"); 787 new_draw_info (NDI_UNIQUE, 0, op, "You were hit and lost your spell!");
811 new_draw_info_format (NDI_ALL | NDI_UNIQUE, 5, NULL, "%s was hit by %s and lost a spell.", &op_name, &hitter->name); 788 new_draw_info_format (NDI_ALL | NDI_UNIQUE, 5, NULL, "%s was hit by %s and lost a spell.", &op_name, &hitter->name);
812 } 789 }
813 } 790 }
814 } 791 }
815 if (!simple_attack) 792 if (!simple_attack)
820 if (QUERY_FLAG (op, FLAG_SLEEP)) 797 if (QUERY_FLAG (op, FLAG_SLEEP))
821 CLEAR_FLAG (op, FLAG_SLEEP); 798 CLEAR_FLAG (op, FLAG_SLEEP);
822 799
823 /* If the victim can't see the attacker, it may alert others 800 /* If the victim can't see the attacker, it may alert others
824 * for help. */ 801 * for help. */
825 if (op->type != PLAYER && !can_see_enemy (op, hitter) && !get_owner (op) && rndm (0, op->stats.Int)) 802 if (op->type != PLAYER && !can_see_enemy (op, hitter) && !op->owner && rndm (0, op->stats.Int))
826 npc_call_help (op); 803 npc_call_help (op);
827 804
828 /* if you were hidden and hit by a creature, you are discovered */ 805 /* if you were hidden and hit by a creature, you are discovered */
829 if (op->hide && QUERY_FLAG (hitter, FLAG_ALIVE)) 806 if (op->hide && QUERY_FLAG (hitter, FLAG_ALIVE))
830 { 807 {
837 * when they hit the victim. For things like thrown daggers, 814 * when they hit the victim. For things like thrown daggers,
838 * this sets 'hitter' to the actual dagger, and not the 815 * this sets 'hitter' to the actual dagger, and not the
839 * wrapper object. 816 * wrapper object.
840 */ 817 */
841 thrown_item_effect (hitter, op); 818 thrown_item_effect (hitter, op);
819
842 if (was_destroyed (hitter, hitter_tag) || was_destroyed (op, op_tag) || abort_attack (op, hitter, simple_attack)) 820 if (hitter->destroyed () || op->destroyed () || abort_attack (op, hitter, simple_attack))
843 goto leave; 821 goto leave;
844 } 822 }
845 823
846 /* Need to do at least 1 damage, otherwise there is no point 824 /* Need to do at least 1 damage, otherwise there is no point
847 * to go further and it will cause FPE's below. 825 * to go further and it will cause FPE's below.
848 */ 826 */
849 if (hitdam <= 0) 827 if (hitdam <= 0)
850 hitdam = 1; 828 hitdam = 1;
851 829
852 type = hitter->attacktype; 830 type = hitter->attacktype;
831
853 if (!type) 832 if (!type)
854 type = AT_PHYSICAL; 833 type = AT_PHYSICAL;
834
855 /* Handle monsters that hit back */ 835 /* Handle monsters that hit back */
856 if (!simple_attack && QUERY_FLAG (op, FLAG_HITBACK) && QUERY_FLAG (hitter, FLAG_ALIVE)) 836 if (!simple_attack && QUERY_FLAG (op, FLAG_HITBACK) && QUERY_FLAG (hitter, FLAG_ALIVE))
857 { 837 {
858 if (op->attacktype & AT_ACID && hitter->type == PLAYER) 838 if (op->attacktype & AT_ACID && hitter->type == PLAYER)
859 new_draw_info (NDI_UNIQUE, 0, hitter, "You are splashed by acid!\n"); 839 new_draw_info (NDI_UNIQUE, 0, hitter, "You are splashed by acid!\n");
840
860 hit_player (hitter, random_roll (0, (op->stats.dam), hitter, PREFER_LOW), op, op->attacktype, 1); 841 hit_player (hitter, random_roll (0, (op->stats.dam), hitter, PREFER_LOW), op, op->attacktype, 1);
842
861 if (was_destroyed (op, op_tag) || was_destroyed (hitter, hitter_tag) || abort_attack (op, hitter, simple_attack)) 843 if (op->destroyed () || hitter->destroyed () || abort_attack (op, hitter, simple_attack))
862 goto leave; 844 goto leave;
863 } 845 }
864 846
865 /* In the new attack code, it should handle multiple attack 847 /* In the new attack code, it should handle multiple attack
866 * types in its area, so remove it from here. 848 * types in its area, so remove it from here.
867 */ 849 */
868 dam = hit_player (op, random_roll (1, hitdam, hitter, PREFER_HIGH), hitter, type, 1); 850 dam = hit_player (op, random_roll (1, hitdam, hitter, PREFER_HIGH), hitter, type, 1);
851
869 if (was_destroyed (op, op_tag) || was_destroyed (hitter, hitter_tag) || abort_attack (op, hitter, simple_attack)) 852 if (op->destroyed () || hitter->destroyed () || abort_attack (op, hitter, simple_attack))
870 goto leave; 853 goto leave;
871 } /* end of if hitter hit op */ 854 } /* end of if hitter hit op */
872 /* if we missed, dam=0 */ 855 /* if we missed, dam=0 */
873 856
874 /*attack_message(dam, type, op, hitter); */ 857 /*attack_message(dam, type, op, hitter); */
908 if (op->weight <= 5000 && tmp->stats.hp >= 0) 891 if (op->weight <= 5000 && tmp->stats.hp >= 0)
909 { 892 {
910 if (tmp->head != NULL) 893 if (tmp->head != NULL)
911 tmp = tmp->head; 894 tmp = tmp->head;
912 895
913 remove_ob (op); 896 op->remove ();
914 op = insert_ob_in_ob (op, tmp); 897 op = insert_ob_in_ob (op, tmp);
915 898
916 if (tmp->type == PLAYER) 899 if (tmp->type == PLAYER)
917 esrv_send_item (tmp, op); 900 esrv_send_item (tmp, op);
918 901
931object * 914object *
932hit_with_arrow (object *op, object *victim) 915hit_with_arrow (object *op, object *victim)
933{ 916{
934 object *container, *hitter; 917 object *container, *hitter;
935 int hit_something = 0; 918 int hit_something = 0;
936 tag_t victim_tag, hitter_tag;
937 sint16 victim_x, victim_y;
938 919
939 /* Disassemble missile */ 920 /* Disassemble missile */
940 if (op->inv) 921 if (op->inv)
941 { 922 {
942 container = op; 923 container = op;
943 hitter = op->inv; 924 hitter = op->inv;
944 remove_ob (hitter); 925 hitter->remove ();
945 insert_ob_in_map (hitter, container->map, hitter, INS_NO_MERGE | INS_NO_WALK_ON); 926 insert_ob_in_map (hitter, container->map, hitter, INS_NO_MERGE | INS_NO_WALK_ON);
946 /* Note that we now have an empty THROWN_OBJ on the map. Code that 927 /* Note that we now have an empty THROWN_OBJ on the map. Code that
947 * might be called until this THROWN_OBJ is either reassembled or 928 * might be called until this THROWN_OBJ is either reassembled or
948 * removed at the end of this function must be able to deal with empty 929 * removed at the end of this function must be able to deal with empty
949 * THROWN_OBJs. */ 930 * THROWN_OBJs. */
950 } 931 }
951 else 932 else
952 { 933 {
953 container = NULL; 934 container = 0;
954 hitter = op; 935 hitter = op;
955 } 936 }
956 937
957 /* Try to hit victim */ 938 /* Try to hit victim */
958 victim_x = victim->x;
959 victim_y = victim->y;
960 victim_tag = victim->count;
961 hitter_tag = hitter->count;
962
963 hit_something = attack_ob_simple (victim, hitter, op->stats.dam, op->stats.wc); 939 hit_something = attack_ob_simple (victim, hitter, op->stats.dam, op->stats.wc);
964 940
965 /* Arrow attacks door, rune of summoning is triggered, demon is put on 941 /* Arrow attacks door, rune of summoning is triggered, demon is put on
966 * arrow, move_apply() calls this function, arrow sticks in demon, 942 * arrow, move_apply() calls this function, arrow sticks in demon,
967 * attack_ob_simple() returns, and we've got an arrow that still exists 943 * attack_ob_simple() returns, and we've got an arrow that still exists
968 * but is no longer on the map. Ugh. (Beware: Such things can happen at 944 * but is no longer on the map. Ugh. (Beware: Such things can happen at
969 * other places as well!) 945 * other places as well!)
970 */ 946 */
971 if (was_destroyed (hitter, hitter_tag) || hitter->env != NULL) 947 if (hitter->destroyed () || hitter->env != NULL)
972 { 948 {
973 if (container) 949 if (container)
974 { 950 {
975 remove_ob (container); 951 container->remove ();
976 free_object (container); 952 container->destroy ();
977 } 953 }
954
978 return NULL; 955 return 0;
979 } 956 }
980 957
981 /* Missile hit victim */ 958 /* Missile hit victim */
982 /* if the speed is > 10, then this is a fast moving arrow, we go straight 959 /* if the speed is > 10, then this is a fast moving arrow, we go straight
983 * through the target 960 * through the target
984 */ 961 */
985 if (hit_something && op->speed <= 10.0) 962 if (hit_something && op->speed <= 10.0)
986 { 963 {
987 /* Stop arrow */ 964 /* Stop arrow */
988 if (container == NULL) 965 if (!container)
989 { 966 {
990 hitter = fix_stopped_arrow (hitter); 967 hitter = fix_stopped_arrow (hitter);
991 if (hitter == NULL) 968 if (!hitter)
992 return NULL; 969 return 0;
993 } 970 }
994 else 971 else
995 { 972 container->destroy ();
996 remove_ob (container);
997 free_object (container);
998 }
999 973
1000 /* Try to stick arrow into victim */ 974 /* Try to stick arrow into victim */
1001 if (!was_destroyed (victim, victim_tag) && stick_arrow (hitter, victim)) 975 if (!victim->destroyed () && stick_arrow (hitter, victim))
1002 return NULL; 976 return 0;
1003 977
1004 /* Else try to put arrow on victim's map square 978 /* Else try to put arrow on victim's map square
1005 * remove check for P_WALL here. If the arrow got to this 979 * remove check for P_WALL here. If the arrow got to this
1006 * space, that is good enough - with the new movement code, 980 * space, that is good enough - with the new movement code,
1007 * there is now the potential for lots of spaces where something 981 * there is now the potential for lots of spaces where something
1008 * can fly over but not otherwise move over. What is the correct 982 * can fly over but not otherwise move over. What is the correct
1009 * way to handle those otherwise? 983 * way to handle those otherwise?
1010 */ 984 */
1011 if (victim_x != hitter->x || victim_y != hitter->y) 985 if (victim->x != hitter->x || victim->y != hitter->y)
1012 { 986 {
1013 remove_ob (hitter); 987 hitter->remove ();
1014 hitter->x = victim_x; 988 hitter->x = victim->x;
1015 hitter->y = victim_y; 989 hitter->y = victim->y;
1016 insert_ob_in_map (hitter, victim->map, hitter, 0); 990 insert_ob_in_map (hitter, victim->map, hitter, 0);
1017 } 991 }
1018 else 992 else
1019 {
1020 /* Else leave arrow where it is */ 993 /* Else leave arrow where it is */
1021 merge_ob (hitter, NULL); 994 merge_ob (hitter, NULL);
1022 } 995
1023 return NULL; 996 return 0;
1024 } 997 }
1025 998
1026 if (hit_something && op->speed >= 10.0) 999 if (hit_something && op->speed >= 10.0)
1027 op->speed -= 1.0; 1000 op->speed -= 1.0;
1028 1001
1029 /* Missile missed victim - reassemble missile */ 1002 /* Missile missed victim - reassemble missile */
1030 if (container) 1003 if (container)
1031 { 1004 {
1032 remove_ob (hitter); 1005 hitter->remove ();
1033 insert_ob_in_ob (hitter, container); 1006 insert_ob_in_ob (hitter, container);
1034 } 1007 }
1008
1035 return op; 1009 return op;
1036} 1010}
1037 1011
1038 1012
1039void 1013void
1048 } 1022 }
1049 else if (!GET_ANIM_ID (op)) 1023 else if (!GET_ANIM_ID (op))
1050 { 1024 {
1051 /* Object has been called - no animations, so remove it */ 1025 /* Object has been called - no animations, so remove it */
1052 if (op->stats.hp < 0) 1026 if (op->stats.hp < 0)
1027 op->destroy ();
1053 { 1028
1054 remove_ob (op); /* Should update LOS */
1055 free_object (op);
1056 /* Don't know why this is here - remove_ob should do it for us */
1057 /*update_position(m, x, y); */
1058 }
1059 return; /* no animations, so nothing more to do */ 1029 return; /* no animations, so nothing more to do */
1060 } 1030 }
1031
1061 perc = NUM_ANIMATIONS (op) - ((int) NUM_ANIMATIONS (op) * op->stats.hp) / op->stats.maxhp; 1032 perc = NUM_ANIMATIONS (op) - ((int) NUM_ANIMATIONS (op) * op->stats.hp) / op->stats.maxhp;
1033
1062 if (perc >= (int) NUM_ANIMATIONS (op)) 1034 if (perc >= (int) NUM_ANIMATIONS (op))
1063 perc = NUM_ANIMATIONS (op) - 1; 1035 perc = NUM_ANIMATIONS (op) - 1;
1064 else if (perc < 1) 1036 else if (perc < 1)
1065 perc = 1; 1037 perc = 1;
1038
1066 SET_ANIMATION (op, perc); 1039 SET_ANIMATION (op, perc);
1067 update_object (op, UP_OBJ_FACE); 1040 update_object (op, UP_OBJ_FACE);
1041
1068 if (perc == NUM_ANIMATIONS (op) - 1) 1042 if (perc == NUM_ANIMATIONS (op) - 1)
1069 { /* Reached the last animation */ 1043 { /* Reached the last animation */
1070 if (op->face == blank_face) 1044 if (op->face == blank_face)
1071 {
1072 /* If the last face is blank, remove the ob */ 1045 /* If the last face is blank, remove the ob */
1073 remove_ob (op); /* Should update LOS */ 1046 op->destroy ();
1074 free_object (op);
1075
1076 /* remove_ob should call update_position for us */
1077 /*update_position(m, x, y); */
1078
1079 }
1080 else 1047 else
1081 { /* The last face was not blank, leave an image */ 1048 { /* The last face was not blank, leave an image */
1082 CLEAR_FLAG (op, FLAG_BLOCKSVIEW); 1049 CLEAR_FLAG (op, FLAG_BLOCKSVIEW);
1083 update_all_los (op->map, op->x, op->y); 1050 update_all_los (op->map, op->x, op->y);
1084 op->move_block = 0; 1051 op->move_block = 0;
1088} 1055}
1089 1056
1090void 1057void
1091scare_creature (object *target, object *hitter) 1058scare_creature (object *target, object *hitter)
1092{ 1059{
1093 object *owner = get_owner (hitter); 1060 object *owner = hitter->owner;
1094 1061
1095 if (!owner) 1062 if (!owner)
1096 owner = hitter; 1063 owner = hitter;
1097 1064
1098 SET_FLAG (target, FLAG_SCARED); 1065 SET_FLAG (target, FLAG_SCARED);
1105 * appropriate attacktype. Only 1 attacktype should be set at a time. 1072 * appropriate attacktype. Only 1 attacktype should be set at a time.
1106 * 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
1107 * take. However, it will do other effects (paralyzation, slow, etc.) 1074 * take. However, it will do other effects (paralyzation, slow, etc.)
1108 * 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
1109 * the attacktype. Makes it easier for the PR code. */ 1076 * the attacktype. Makes it easier for the PR code. */
1110
1111int 1077int
1112hit_player_attacktype (object *op, object *hitter, int dam, uint32 attacknum, int magic) 1078hit_player_attacktype (object *op, object *hitter, int dam, uint32 attacknum, int magic)
1113{ 1079{
1114
1115 int doesnt_slay = 1; 1080 int doesnt_slay = 1;
1116 1081
1117 /* Catch anyone that may be trying to send us a bitmask instead of the number */ 1082 /* Catch anyone that may be trying to send us a bitmask instead of the number */
1118 if (attacknum >= NROFATTACKS) 1083 if (attacknum >= NROFATTACKS)
1119 { 1084 {
1164 1129
1165 /* Keep this in order - makes things easier to find */ 1130 /* Keep this in order - makes things easier to find */
1166 1131
1167 switch (attacknum) 1132 switch (attacknum)
1168 { 1133 {
1169 case ATNR_PHYSICAL: 1134 case ATNR_PHYSICAL:
1170 /* here also check for diseases */ 1135 /* here also check for diseases */
1171 check_physically_infect (op, hitter); 1136 check_physically_infect (op, hitter);
1172 break; 1137 break;
1173 1138
1174 /* Don't need to do anything for: 1139 /* Don't need to do anything for:
1175 magic, 1140 magic,
1176 fire, 1141 fire,
1177 electricity, 1142 electricity,
1178 cold */ 1143 cold */
1179 1144
1180 case ATNR_CONFUSION: 1145 case ATNR_CONFUSION:
1181 case ATNR_POISON: 1146 case ATNR_POISON:
1182 case ATNR_SLOW: 1147 case ATNR_SLOW:
1183 case ATNR_PARALYZE: 1148 case ATNR_PARALYZE:
1184 case ATNR_FEAR: 1149 case ATNR_FEAR:
1185 case ATNR_CANCELLATION: 1150 case ATNR_CANCELLATION:
1186 case ATNR_DEPLETE: 1151 case ATNR_DEPLETE:
1187 case ATNR_BLIND: 1152 case ATNR_BLIND:
1188 { 1153 {
1189 /* chance for inflicting a special attack depends on the 1154 /* chance for inflicting a special attack depends on the
1190 * difference between attacker's and defender's level 1155 * difference between attacker's and defender's level
1191 */ 1156 */
1192 int level_diff = MIN (110, MAX (0, op->level - hitter->level)); 1157 int level_diff = MIN (110, MAX (0, op->level - hitter->level));
1193 1158
1194 /* First, only creatures/players with speed can be affected. 1159 /* First, only creatures/players with speed can be affected.
1195 * Second, just getting hit doesn't mean it always affects 1160 * Second, just getting hit doesn't mean it always affects
1196 * you. Third, you still get a saving through against the 1161 * you. Third, you still get a saving through against the
1197 * effect. 1162 * effect.
1198 */ 1163 */
1199 if (op->speed && 1164 if (op->speed &&
1200 (QUERY_FLAG (op, FLAG_MONSTER) || op->type == PLAYER) && 1165 (QUERY_FLAG (op, FLAG_MONSTER) || op->type == PLAYER) &&
1201 !(rndm (0, (attacknum == ATNR_SLOW ? 6 : 3) - 1)) && !did_make_save (op, level_diff, op->resist[attacknum] / 10)) 1166 !(rndm (0, (attacknum == ATNR_SLOW ? 6 : 3) - 1)) && !did_make_save (op, level_diff, op->resist[attacknum] / 10))
1202 { 1167 {
1203 1168
1204 /* Player has been hit by something */ 1169 /* Player has been hit by something */
1205 if (attacknum == ATNR_CONFUSION) 1170 if (attacknum == ATNR_CONFUSION)
1206 confuse_player (op, hitter, dam); 1171 confuse_player (op, hitter, dam);
1207 else if (attacknum == ATNR_POISON) 1172 else if (attacknum == ATNR_POISON)
1208 poison_player (op, hitter, dam); 1173 poison_player (op, hitter, dam);
1209 else if (attacknum == ATNR_SLOW) 1174 else if (attacknum == ATNR_SLOW)
1210 slow_player (op, hitter, dam); 1175 slow_player (op, hitter, dam);
1211 else if (attacknum == ATNR_PARALYZE) 1176 else if (attacknum == ATNR_PARALYZE)
1212 paralyze_player (op, hitter, dam); 1177 paralyze_player (op, hitter, dam);
1213 else if (attacknum == ATNR_FEAR) 1178 else if (attacknum == ATNR_FEAR)
1214 scare_creature (op, hitter); 1179 scare_creature (op, hitter);
1215 else if (attacknum == ATNR_CANCELLATION) 1180 else if (attacknum == ATNR_CANCELLATION)
1216 cancellation (op); 1181 cancellation (op);
1217 else if (attacknum == ATNR_DEPLETE) 1182 else if (attacknum == ATNR_DEPLETE)
1218 drain_stat (op); 1183 op->drain_stat ();
1219 else if (attacknum == ATNR_BLIND && !QUERY_FLAG (op, FLAG_UNDEAD) && !QUERY_FLAG (op, FLAG_GENERATOR)) 1184 else if (attacknum == ATNR_BLIND && !QUERY_FLAG (op, FLAG_UNDEAD) && !QUERY_FLAG (op, FLAG_GENERATOR))
1220 blind_player (op, hitter, dam); 1185 blind_player (op, hitter, dam);
1221 } 1186 }
1222 dam = 0; /* These are all effects and don't do real damage */ 1187 dam = 0; /* These are all effects and don't do real damage */
1223 } 1188 }
1224 break; 1189 break;
1190
1225 case ATNR_ACID: 1191 case ATNR_ACID:
1226 { 1192 {
1227 int flag = 0; 1193 int flag = 0;
1228 1194
1229 /* Items only get corroded if you're not on a battleground and 1195 /* Items only get corroded if you're not on a battleground and
1230 * if your acid resistance is below 50%. */ 1196 * if your acid resistance is below 50%. */
1231 if (!op_on_battleground (op, NULL, NULL) && (op->resist[ATNR_ACID] < 50)) 1197 if (!op_on_battleground (op, NULL, NULL) && (op->resist[ATNR_ACID] < 50))
1232 { 1198 {
1233 object *tmp;
1234
1235 for (tmp = op->inv; tmp != NULL; tmp = tmp->below) 1199 for (object *tmp = op->inv; tmp; tmp = tmp->below)
1236 { 1200 {
1237 if (tmp->invisible) 1201 if (tmp->invisible)
1238 continue; 1202 continue;
1239 if (!QUERY_FLAG (tmp, FLAG_APPLIED) || (tmp->resist[ATNR_ACID] >= 10)) 1203 if (!QUERY_FLAG (tmp, FLAG_APPLIED) || (tmp->resist[ATNR_ACID] >= 10))
1240 /* >= 10% acid res. on itmes will protect these */ 1204 /* >= 10% acid res. on items will protect these */
1241 continue; 1205 continue;
1242 if (!(tmp->material & M_IRON)) 1206 if (!(tmp->material & M_IRON))
1243 continue; 1207 continue;
1244 if (tmp->magic < -4) /* Let's stop at -5 */ 1208 if (tmp->magic < -4) /* Let's stop at -5 */
1245 continue; 1209 continue;
1246 if (tmp->type == RING || 1210 if (tmp->type == RING
1247 /* removed boots and gloves from exclusion list in 1211 /* removed boots and gloves from exclusion list in PR */
1248 PR */ 1212 || tmp->type == GIRDLE
1249 tmp->type == GIRDLE || tmp->type == AMULET || tmp->type == WAND || tmp->type == ROD || tmp->type == HORN) 1213 || tmp->type == AMULET
1214 || tmp->type == WAND
1215 || tmp->type == ROD
1216 || tmp->type == HORN)
1250 continue; /* To avoid some strange effects */ 1217 continue; /* To avoid some strange effects */
1251 1218
1252 /* High damage acid has better chance of corroding 1219 /* High damage acid has better chance of corroding
1253 objects */ 1220 objects */
1254 if (rndm (0, dam + 4) > random_roll (0, 39, op, PREFER_HIGH) + 2 * tmp->magic) 1221 if (rndm (0, dam + 4) > random_roll (0, 39, op, PREFER_HIGH) + 2 * tmp->magic)
1255 { 1222 {
1256 if (op->type == PLAYER) 1223 if (op->type == PLAYER)
1257 /* Make this more visible */ 1224 /* Make this more visible */
1258 new_draw_info_format (NDI_UNIQUE | NDI_RED, 0, op, 1225 new_draw_info_format (NDI_UNIQUE | NDI_RED, 0, op,
1259 "The %s's acid corrodes your %s!", query_name (hitter), query_name (tmp)); 1226 "The %s's acid corrodes your %s!", query_name (hitter), query_name (tmp));
1260 flag = 1; 1227 flag = 1;
1261 tmp->magic--; 1228 tmp->magic--;
1262 if (op->type == PLAYER) 1229 if (op->type == PLAYER)
1263 esrv_send_item (op, tmp); 1230 esrv_send_item (op, tmp);
1264 } 1231 }
1265 } 1232 }
1266 if (flag)
1267 fix_player (op); /* Something was corroded */
1268 } 1233
1234 if (flag)
1235 op->update_stats (); /* Something was corroded */
1269 } 1236 }
1237 }
1270 break; 1238 break;
1239
1271 case ATNR_DRAIN: 1240 case ATNR_DRAIN:
1272 { 1241 {
1273 /* rate is the proportion of exp drained. High rate means 1242 /* rate is the proportion of exp drained. High rate means
1274 * not much is drained, low rate means a lot is drained. 1243 * not much is drained, low rate means a lot is drained.
1275 */ 1244 */
1276 int rate; 1245 int rate;
1277 1246
1278 if (op->resist[ATNR_DRAIN] >= 0) 1247 if (op->resist[ATNR_DRAIN] >= 0)
1279 rate = 400 + op->resist[ATNR_DRAIN] * 3; 1248 rate = 400 + op->resist[ATNR_DRAIN] * 3;
1280 else 1249 else
1281 rate = 400 * 100 / (100 - op->resist[ATNR_DRAIN]); 1250 rate = 400 * 100 / (100 - op->resist[ATNR_DRAIN]);
1282 1251
1283 if (op->stats.exp <= rate) 1252 if (op->stats.exp <= rate)
1284 { 1253 {
1285 if (op->type == GOLEM) 1254 if (op->type == GOLEM)
1286 dam = 999; /* Its force is "sucked" away. 8) */ 1255 dam = 999; /* Its force is "sucked" away. 8) */
1287 else 1256 else
1288 /* If we can't drain, lets try to do physical damage */ 1257 /* If we can't drain, lets try to do physical damage */
1289 dam = hit_player_attacktype (op, hitter, dam, ATNR_PHYSICAL, magic); 1258 dam = hit_player_attacktype (op, hitter, dam, ATNR_PHYSICAL, magic);
1290 } 1259 }
1291 else 1260 else
1292 { 1261 {
1293 /* Randomly give the hitter some hp */ 1262 /* Randomly give the hitter some hp */
1294 if (hitter->stats.hp < hitter->stats.maxhp && 1263 if (hitter->stats.hp < hitter->stats.maxhp &&
1295 (op->level > hitter->level) && random_roll (0, (op->level - hitter->level + 2), hitter, PREFER_HIGH) > 3) 1264 (op->level > hitter->level) && random_roll (0, (op->level - hitter->level + 2), hitter, PREFER_HIGH) > 3)
1296 hitter->stats.hp++; 1265 hitter->stats.hp++;
1297 1266
1298 /* Can't do drains on battleground spaces. 1267 /* Can't do drains on battleground spaces.
1299 * Move the wiz check up here - before, the hitter wouldn't gain exp 1268 * Move the wiz check up here - before, the hitter wouldn't gain exp
1300 * exp, but the wiz would still lose exp! If drainee is a wiz, 1269 * exp, but the wiz would still lose exp! If drainee is a wiz,
1301 * nothing happens. 1270 * nothing happens.
1302 * Try to credit the owner. We try to display player -> player drain 1271 * Try to credit the owner. We try to display player -> player drain
1303 * attacks, hence all the != PLAYER checks. 1272 * attacks, hence all the != PLAYER checks.
1304 */ 1273 */
1305 if (!op_on_battleground (hitter, NULL, NULL) && !QUERY_FLAG (op, FLAG_WAS_WIZ)) 1274 if (!op_on_battleground (hitter, NULL, NULL) && !QUERY_FLAG (op, FLAG_WAS_WIZ))
1306 { 1275 {
1307 object *owner = get_owner (hitter); 1276 object *owner = hitter->owner;
1308 1277
1309 if (owner && owner != hitter) 1278 if (owner && owner != hitter)
1310 { 1279 {
1311 if (op->type != PLAYER || owner->type != PLAYER) 1280 if (op->type != PLAYER || owner->type != PLAYER)
1312 change_exp (owner, op->stats.exp / (rate * 2), 1281 change_exp (owner, op->stats.exp / (rate * 2),
1313 hitter->chosen_skill ? hitter->chosen_skill->skill : (const char *) 0, SK_EXP_TOTAL); 1282 hitter->chosen_skill ? hitter->chosen_skill->skill : (const char *) 0, SK_EXP_TOTAL);
1314 } 1283 }
1315 else if (op->type != PLAYER || hitter->type != PLAYER) 1284 else if (op->type != PLAYER || hitter->type != PLAYER)
1316 { 1285 {
1317 change_exp (hitter, op->stats.exp / (rate * 2), 1286 change_exp (hitter, op->stats.exp / (rate * 2),
1318 hitter->chosen_skill ? hitter->chosen_skill->skill : (const char *) 0, 0); 1287 hitter->chosen_skill ? hitter->chosen_skill->skill : (const char *) 0, 0);
1319 } 1288 }
1320 change_exp (op, -op->stats.exp / rate, NULL, 0); 1289 change_exp (op, -op->stats.exp / rate, NULL, 0);
1321 } 1290 }
1291
1322 dam = 1; /* Drain is an effect. Still return 1 - otherwise, if you have pure 1292 dam = 1; /* Drain is an effect. Still return 1 - otherwise, if you have pure
1323 * drain attack, you won't know that you are actually sucking out EXP, 1293 * drain attack, you won't know that you are actually sucking out EXP,
1324 * as the messages will say you missed 1294 * as the messages will say you missed
1325 */ 1295 */
1326 } 1296 }
1327 } 1297 }
1328 break; 1298 break;
1299
1329 case ATNR_TURN_UNDEAD: 1300 case ATNR_TURN_UNDEAD:
1330 { 1301 {
1331 if (QUERY_FLAG (op, FLAG_UNDEAD)) 1302 if (QUERY_FLAG (op, FLAG_UNDEAD))
1332 { 1303 {
1333 object *owner = get_owner (hitter) == NULL ? hitter : get_owner (hitter); 1304 object *owner = hitter->owner ? (object *)hitter->owner : hitter;
1334 object *god = find_god (determine_god (owner)); 1305 object *god = find_god (determine_god (owner));
1335 int div = 1; 1306 int div = 1;
1336 1307
1337 /* if undead are not an enemy of your god, you turn them 1308 /* if undead are not an enemy of your god, you turn them
1338 * at half strength */ 1309 * at half strength */
1339 if (!god || !god->slaying || strstr (god->slaying, undead_name) == NULL) 1310 if (!god || !god->slaying || strstr (god->slaying, undead_name) == NULL)
1340 div = 2; 1311 div = 2;
1341 /* Give a bonus if you resist turn undead */ 1312 /* Give a bonus if you resist turn undead */
1342 if (op->level * div < (turn_bonus[owner->stats.Wis] + owner->level + (op->resist[ATNR_TURN_UNDEAD] / 100))) 1313 if (op->level * div < (turn_bonus[owner->stats.Wis] + owner->level + (op->resist[ATNR_TURN_UNDEAD] / 100)))
1343 scare_creature (op, owner); 1314 scare_creature (op, owner);
1344 } 1315 }
1345 else 1316 else
1346 dam = 0; /* don't damage non undead - should we damage 1317 dam = 0; /* don't damage non undead - should we damage
1347 undead? */ 1318 undead? */
1348 } 1319 }
1349 break; 1320 break;
1321
1350 case ATNR_DEATH: 1322 case ATNR_DEATH:
1351 deathstrike_player (op, hitter, &dam); 1323 deathstrike_player (op, hitter, &dam);
1352 break; 1324 break;
1325
1353 case ATNR_CHAOS: 1326 case ATNR_CHAOS:
1354 LOG (llevError, "%s was hit by %s with non-specific chaos.\n", query_name (op), query_name (hitter)); 1327 LOG (llevError, "%s was hit by %s with non-specific chaos.\n", op->debug_desc (), hitter->debug_desc2 ());
1355 dam = 0; 1328 dam = 0;
1356 break; 1329 break;
1330
1357 case ATNR_COUNTERSPELL: 1331 case ATNR_COUNTERSPELL:
1358 LOG (llevError, "%s was hit by %s with counterspell attack.\n", query_name (op), query_name (hitter)); 1332 LOG (llevError, "%s was hit by %s with counterspell attack.\n", op->debug_desc (), hitter->debug_desc2 ());
1359 dam = 0; 1333 dam = 0;
1360 /* This should never happen. Counterspell is handled 1334 /* This should never happen. Counterspell is handled
1361 * seperately and filtered out. If this does happen, 1335 * seperately and filtered out. If this does happen,
1362 * Counterspell has no effect on anything but spells, so it 1336 * Counterspell has no effect on anything but spells, so it
1363 * does no damage. */ 1337 * does no damage. */
1364 break; 1338 break;
1339
1365 case ATNR_HOLYWORD: 1340 case ATNR_HOLYWORD:
1366 { 1341 {
1367 /* This has already been handled by hit_player, 1342 /* This has already been handled by hit_player,
1368 * no need to check twice -- DAMN */ 1343 * no need to check twice -- DAMN */
1344 object *owner = hitter->owner ? (object *)hitter->owner : hitter;
1369 1345
1370 object *owner = get_owner (hitter) == NULL ? hitter : get_owner (hitter);
1371
1372 /* As with turn undead above, give a bonus on the saving throw */ 1346 /* As with turn undead above, give a bonus on the saving throw */
1373 if ((op->level + (op->resist[ATNR_HOLYWORD] / 100)) < owner->level + turn_bonus[owner->stats.Wis]) 1347 if ((op->level + (op->resist[ATNR_HOLYWORD] / 100)) < owner->level + turn_bonus[owner->stats.Wis])
1374 scare_creature (op, owner); 1348 scare_creature (op, owner);
1375 } 1349 }
1376 break; 1350 break;
1351
1377 case ATNR_LIFE_STEALING: 1352 case ATNR_LIFE_STEALING:
1378 { 1353 {
1379 int new_hp; 1354 int new_hp;
1380 1355
1381 /* this is replacement to drain for players, instead of taking 1356 /* this is replacement to drain for players, instead of taking
1382 * exp it takes hp. It is geared for players, probably not 1357 * exp it takes hp. It is geared for players, probably not
1383 * much use giving it to monsters 1358 * much use giving it to monsters
1384 * 1359 *
1385 * life stealing doesn't do a lot of damage, but it gives the 1360 * life stealing doesn't do a lot of damage, but it gives the
1386 * damage it does do to the player. Given that, 1361 * damage it does do to the player. Given that,
1387 * it only does 1/10'th normal damage (hence the divide by 1362 * it only does 1/10'th normal damage (hence the divide by
1388 * 1000). 1363 * 1000).
1389 */ 1364 */
1390 /* You can't steal life from something undead */ 1365 /* You can't steal life from something undead */
1391 if ((op->type == GOLEM) || (QUERY_FLAG (op, FLAG_UNDEAD))) 1366 if ((op->type == GOLEM) || (QUERY_FLAG (op, FLAG_UNDEAD)))
1392 return 0; 1367 return 0;
1368
1393 /* If drain protection is higher than life stealing, use that */ 1369 /* If drain protection is higher than life stealing, use that */
1394 if (op->resist[ATNR_DRAIN] >= op->resist[ATNR_LIFE_STEALING]) 1370 if (op->resist[ATNR_DRAIN] >= op->resist[ATNR_LIFE_STEALING])
1395 dam = (dam * (100 - op->resist[ATNR_DRAIN])) / 3000; 1371 dam = (dam * (100 - op->resist[ATNR_DRAIN])) / 3000;
1396 else 1372 else
1397 dam = (dam * (100 - op->resist[ATNR_LIFE_STEALING])) / 3000; 1373 dam = (dam * (100 - op->resist[ATNR_LIFE_STEALING])) / 3000;
1374
1398 /* You die at -1 hp, not zero. */ 1375 /* You die at -1 hp, not zero. */
1399 if (dam > (op->stats.hp + 1)) 1376 if (dam > (op->stats.hp + 1))
1400 dam = op->stats.hp + 1; 1377 dam = op->stats.hp + 1;
1378
1401 new_hp = hitter->stats.hp + dam; 1379 new_hp = hitter->stats.hp + dam;
1402 if (new_hp > hitter->stats.maxhp) 1380 if (new_hp > hitter->stats.maxhp)
1403 new_hp = hitter->stats.maxhp; 1381 new_hp = hitter->stats.maxhp;
1382
1404 if (new_hp > hitter->stats.hp) 1383 if (new_hp > hitter->stats.hp)
1405 hitter->stats.hp = new_hp; 1384 hitter->stats.hp = new_hp;
1406 } 1385 }
1407 } 1386 }
1387
1408 return dam; 1388 return dam;
1409} 1389}
1410
1411 1390
1412/* GROS: This code comes from hit_player. It has been made external to 1391/* GROS: This code comes from hit_player. It has been made external to
1413 * allow script procedures to "kill" objects in a combat-like fashion. 1392 * allow script procedures to "kill" objects in a combat-like fashion.
1414 * It was initially used by (kill-object) developed for the Collector's 1393 * It was initially used by (kill-object) developed for the Collector's
1415 * Sword. Note that nothing has been changed from the original version 1394 * Sword. Note that nothing has been changed from the original version
1450 if (QUERY_FLAG (op, FLAG_BLOCKSVIEW)) 1429 if (QUERY_FLAG (op, FLAG_BLOCKSVIEW))
1451 update_all_los (op->map, op->x, op->y); /* makes sure los will be recalculated */ 1430 update_all_los (op->map, op->x, op->y); /* makes sure los will be recalculated */
1452 1431
1453 if (op->type == DOOR) 1432 if (op->type == DOOR)
1454 { 1433 {
1455 op->speed = 0.1; 1434 op->set_speed (0.1);
1456 update_ob_speed (op);
1457 op->speed_left = -0.05; 1435 op->speed_left = -0.05;
1458 return maxdam; 1436 return maxdam;
1459 } 1437 }
1438
1460 if (QUERY_FLAG (op, FLAG_FRIENDLY) && op->type != PLAYER) 1439 if (QUERY_FLAG (op, FLAG_FRIENDLY) && op->type != PLAYER)
1461 { 1440 {
1462 remove_friendly_object (op); 1441 remove_friendly_object (op);
1442
1463 if (get_owner (op) != NULL && op->owner->type == PLAYER && op->owner->contr->ranges[range_golem] == op) 1443 if (op->owner && op->owner->type == PLAYER && op->owner->contr->ranges[range_golem] == op)
1464 {
1465 op->owner->contr->ranges[range_golem] = NULL; 1444 op->owner->contr->ranges[range_golem] = 0;
1466 op->owner->contr->golem_count = 0;
1467 }
1468 1445
1469 remove_ob (op); 1446 op->destroy ();
1470 free_object (op);
1471 return maxdam; 1447 return maxdam;
1472 } 1448 }
1473 1449
1474 /* Now lets start dealing with experience we get for killing something */ 1450 /* Now lets start dealing with experience we get for killing something */
1475 1451
1476 owner = get_owner (hitter); 1452 owner = hitter->owner;
1477 if (owner == NULL) 1453 if (!owner)
1478 owner = hitter; 1454 owner = hitter;
1479 1455
1480 /* is the victim (op) standing on battleground? */ 1456 /* is the victim (op) standing on battleground? */
1481 if (op_on_battleground (op, NULL, NULL)) 1457 if (op_on_battleground (op, NULL, NULL))
1482 battleg = 1; 1458 battleg = 1;
1502 char buf[256]; 1478 char buf[256];
1503 1479
1504 tmv = localtime (&t); 1480 tmv = localtime (&t);
1505 strftime (buf, 256, "%a %b %d %H:%M:%S %Y", tmv); 1481 strftime (buf, 256, "%a %b %d %H:%M:%S %Y", tmv);
1506 1482
1507 LOG (llevInfo, "%s PLAYER_KILL_PLAYER: %s (%s) killed %s\n", buf, &owner->name, owner->contr->socket.host, query_name (op)); 1483 LOG (llevInfo, "%s PLAYER_KILL_PLAYER: %s (%s) killed %s\n", buf, &owner->name, owner->contr->ns->host, query_name (op));
1508 } 1484 }
1509 1485
1510 /* try to filter some things out - basically, if you are 1486 /* try to filter some things out - basically, if you are
1511 * killing a level 1 creature and your level 20, you 1487 * killing a level 1 creature and your level 20, you
1512 * probably don't want to see that. 1488 * probably don't want to see that.
1513 */ 1489 */
1514 if (owner->level < op->level * 2 || op->stats.exp > 1000) 1490 if (owner->level < op->level * 2 || op->stats.exp > 1000)
1515 { 1491 {
1516 if (owner != hitter) 1492 if (owner != hitter)
1517 {
1518 new_draw_info_format (NDI_BLACK, 0, owner, "You killed %s with %s.", query_name (op), query_name (hitter)); 1493 new_draw_info_format (NDI_BLACK, 0, owner, "You killed %s with %s.", query_name (op), query_name (hitter));
1519 }
1520 else 1494 else
1521 {
1522 new_draw_info_format (NDI_BLACK, 0, owner, "You killed %s.", query_name (op)); 1495 new_draw_info_format (NDI_BLACK, 0, owner, "You killed %s.", query_name (op));
1523 } 1496
1524 /* Only play sounds for melee kills */ 1497 /* Only play sounds for melee kills */
1525 if (hitter->type == PLAYER) 1498 if (hitter->type == PLAYER)
1526 play_sound_map (owner->map, owner->x, owner->y, SOUND_PLAYER_KILLS); 1499 play_sound_map (owner->map, owner->x, owner->y, SOUND_PLAYER_KILLS);
1527 } 1500 }
1528 1501
1533 * player that the object belonged to - so if you killed another player 1506 * player that the object belonged to - so if you killed another player
1534 * with spells, pets, whatever, there was no penalty. 1507 * with spells, pets, whatever, there was no penalty.
1535 * Changed to make luck penalty configurable in settings. 1508 * Changed to make luck penalty configurable in settings.
1536 */ 1509 */
1537 if (op->type == PLAYER && owner != op && !battleg) 1510 if (op->type == PLAYER && owner != op && !battleg)
1538 change_luck (owner, -settings.pk_luck_penalty); 1511 owner->change_luck (-settings.pk_luck_penalty);
1539 1512
1540 /* This code below deals with finding the appropriate skill 1513 /* This code below deals with finding the appropriate skill
1541 * to credit exp to. This is a bit problematic - we should 1514 * to credit exp to. This is a bit problematic - we should
1542 * probably never really have to look at current_weapon->skill 1515 * probably never really have to look at current_weapon->skill
1543 */ 1516 */
1544 skill = NULL; 1517 skill = 0;
1518
1545 if (hitter->skill && hitter->type != PLAYER) 1519 if (hitter->skill && hitter->type != PLAYER)
1546 skill = hitter->skill; 1520 skill = hitter->skill;
1547 else if (owner->chosen_skill) 1521 else if (owner->chosen_skill)
1548 { 1522 {
1549 skill = owner->chosen_skill->skill; 1523 skill = owner->chosen_skill->skill;
1568 break; 1542 break;
1569 } 1543 }
1570 } 1544 }
1571 } /* Was it a player that hit somethign */ 1545 } /* Was it a player that hit somethign */
1572 else 1546 else
1573 {
1574 skill = NULL; 1547 skill = 0;
1575 }
1576 1548
1577 /* Pet (or spell) killed something. */ 1549 /* Pet (or spell) killed something. */
1578 if (owner != hitter) 1550 if (owner != hitter)
1579 {
1580 (void) sprintf (buf, "%s killed %s with %s%s%s.", &owner->name, 1551 sprintf (buf, "%s killed %s with %s%s%s.", &owner->name,
1581 query_name (op), query_name (hitter), battleg ? " (duel)" : "", pk ? " (pk)" : ""); 1552 query_name (op), query_name (hitter), battleg ? " (duel)" : "", pk ? " (pk)" : "");
1582 }
1583 else 1553 else
1584 {
1585 (void) sprintf (buf, "%s killed %s%s%s%s.", &hitter->name, &op->name, 1554 sprintf (buf, "%s killed %s%s%s%s.", &hitter->name, &op->name,
1586 (QUERY_FLAG (hitter, FLAG_MONSTER)) || hitter->type == PLAYER ? 1555 (QUERY_FLAG (hitter, FLAG_MONSTER)) || hitter->type == PLAYER ?
1587 " in hand to hand combat" : "", battleg ? " (duel)" : "", pk ? " (pk)" : ""); 1556 " in hand to hand combat" : "", battleg ? " (duel)" : "", pk ? " (pk)" : "");
1588 } 1557
1589 /* These may have been set in the player code section above */ 1558 /* These may have been set in the player code section above */
1590 if (!skop) 1559 if (!skop)
1591 skop = hitter->chosen_skill; 1560 skop = hitter->chosen_skill;
1561
1592 if (!skill && skop) 1562 if (!skill && skop)
1593 skill = skop->skill; 1563 skill = skop->skill;
1594 1564
1595 new_draw_info (NDI_ALL, op->type == PLAYER ? 1 : 10, NULL, buf); 1565 new_draw_info (NDI_ALL, op->type == PLAYER ? 1 : 10, NULL, buf);
1596 1566
1597
1598 /* If you didn't kill yourself, and your not the wizard */ 1567 /* If you didn't kill yourself, and your not the wizard */
1599 if (owner != op && !QUERY_FLAG (op, FLAG_WAS_WIZ)) 1568 if (owner != op && !QUERY_FLAG (op, FLAG_WAS_WIZ))
1600 { 1569 {
1601 int exp; 1570 int exp;
1602 1571
1603 /* Really don't give much experience for killing other players */ 1572 /* Really don't give much experience for killing other players */
1604 // schmorp: temporary? reduce the amount of exp gained for pking enourmously 1573 // schmorp: temporarily? reduce the amount of exp gained for pking enourmously
1605 if (op->type == PLAYER) 1574 if (op->type == PLAYER)
1606 { 1575 {
1607 if (battleg) 1576 if (battleg)
1608 { 1577 {
1609 new_draw_info (NDI_UNIQUE, 0, owner, "Your foe has fallen!"); 1578 new_draw_info (NDI_UNIQUE, 0, owner, "Your foe has fallen!");
1627 1596
1628 if (!settings.simple_exp) 1597 if (!settings.simple_exp)
1629 exp = exp / 2; 1598 exp = exp / 2;
1630 1599
1631 if (owner->type != PLAYER || owner->contr->party == NULL) 1600 if (owner->type != PLAYER || owner->contr->party == NULL)
1632 {
1633 change_exp (owner, exp, skill, 0); 1601 change_exp (owner, exp, skill, 0);
1634 }
1635 else 1602 else
1636 { 1603 {
1637 int shares = 0, count = 0; 1604 int shares = 0, count = 0;
1638
1639 player *pl; 1605 player *pl;
1640
1641 partylist *party = owner->contr->party; 1606 partylist *party = owner->contr->party;
1642 1607
1643#ifdef PARTY_KILL_LOG
1644 add_kill_to_party (party, query_name (owner), query_name (op), exp); 1608 add_kill_to_party (party, query_name (owner), query_name (op), exp);
1645#endif 1609
1646 for (pl = first_player; pl != NULL; pl = pl->next) 1610 for_all_players (pl)
1647 {
1648 if (party && pl->ob->contr->party == party && on_same_map (pl->ob, owner)) 1611 if (party && pl->ob->contr->party == party && on_same_map (pl->ob, owner))
1649 { 1612 {
1650 count++; 1613 count++;
1651 shares += (pl->ob->level + 4); 1614 shares += (pl->ob->level + 4);
1652 } 1615 }
1653 } 1616
1654 if (count == 1 || shares > exp) 1617 if (count == 1 || shares > exp || !shares)
1655 change_exp (owner, exp, skill, SK_EXP_TOTAL); 1618 change_exp (owner, exp, skill, SK_EXP_TOTAL);
1656 else 1619 else
1657 { 1620 {
1658 int share = exp / shares, given = 0, nexp; 1621 int share = exp / shares, given = 0, nexp;
1659 1622
1660 for (pl = first_player; pl != NULL; pl = pl->next) 1623 for_all_players (pl)
1661 {
1662 if (party && pl->ob->contr->party == party && on_same_map (pl->ob, owner)) 1624 if (party && pl->ob->contr->party == party && on_same_map (pl->ob, owner))
1663 { 1625 {
1664 nexp = (pl->ob->level + 4) * share; 1626 nexp = (pl->ob->level + 4) * share;
1665 change_exp (pl->ob, nexp, skill, SK_EXP_TOTAL); 1627 change_exp (pl->ob, nexp, skill, SK_EXP_TOTAL);
1666 given += nexp; 1628 given += nexp;
1667 } 1629 }
1668 } 1630
1669 exp -= given; 1631 exp -= given;
1670 /* give any remainder to the player */ 1632 /* give any remainder to the player */
1671 change_exp (owner, exp, skill, SK_EXP_ADD_SKILL); 1633 change_exp (owner, exp, skill, SK_EXP_ADD_SKILL);
1672 } 1634 }
1673 } /* else part of a party */ 1635 } /* else part of a party */
1674
1675 } /* end if person didn't kill himself */ 1636 } /* end if person didn't kill himself */
1676 1637
1677 if (op->type != PLAYER) 1638 if (op->type != PLAYER)
1678 { 1639 {
1679 if (QUERY_FLAG (op, FLAG_FRIENDLY)) 1640 if (QUERY_FLAG (op, FLAG_FRIENDLY))
1680 { 1641 {
1681 object *owner1 = get_owner (op); 1642 object *owner1 = op->owner;
1682 1643
1683 if (owner1 != NULL && owner1->type == PLAYER) 1644 if (owner1 && owner1->type == PLAYER)
1684 { 1645 {
1685 play_sound_player_only (owner1->contr, SOUND_PET_IS_KILLED, 0, 0); 1646 play_sound_player_only (owner1->contr, SOUND_PET_IS_KILLED, 0, 0);
1686 /* Maybe we should include the owner that killed this, maybe not */ 1647 /* Maybe we should include the owner that killed this, maybe not */
1687 new_draw_info_format (NDI_UNIQUE, 0, owner1, "Your pet, the %s, is killed by %s.", &op->name, &hitter->name); 1648 new_draw_info_format (NDI_UNIQUE, 0, owner1, "Your pet, the %s, is killed by %s.", &op->name, &hitter->name);
1688 } 1649 }
1650
1689 remove_friendly_object (op); 1651 remove_friendly_object (op);
1690 } 1652 }
1691 remove_ob (op); 1653
1692 free_object (op); 1654 op->destroy ();
1693 } 1655 }
1694 /* Player has been killed! */
1695 else 1656 else
1696 { 1657 {
1658 /* Player has been killed! */
1697 if (owner->type == PLAYER) 1659 if (owner->type == PLAYER)
1698 {
1699 snprintf (op->contr->killer, BIG_NAME, "%s the %s", &owner->name, owner->contr->title); 1660 snprintf (op->contr->killer, sizeof (op->contr->killer), "%s the %s", &owner->name, owner->contr->title);
1700 }
1701 else 1661 else
1702 {
1703 strncpy (op->contr->killer, hitter->name, BIG_NAME); 1662 assign (op->contr->killer, hitter->name);
1704 op->contr->killer[BIG_NAME - 1] = '\0';
1705 }
1706 } 1663 }
1664
1707 /* This was return -1 - that doesn't seem correct - if we return -1, process 1665 /* This was return -1 - that doesn't seem correct - if we return -1, process
1708 * continues in the calling function. 1666 * continues in the calling function.
1709 */ 1667 */
1710 return maxdam; 1668 return maxdam;
1711} 1669}
1731 return 0; 1689 return 0;
1732 1690
1733 if (hitter->type == PLAYER && hitter->contr->peaceful == 1) 1691 if (hitter->type == PLAYER && hitter->contr->peaceful == 1)
1734 return 1; 1692 return 1;
1735 1693
1736 if ((owner = get_owner (hitter)) != NULL) 1694 if ((owner = hitter->owner) != NULL)
1737 { 1695 {
1738 if (owner->type == PLAYER && owner->contr->peaceful == 1) 1696 if (owner->type == PLAYER && owner->contr->peaceful == 1)
1739 friendlyfire = 2; 1697 friendlyfire = 2;
1740 } 1698 }
1741 1699
1751 * is what is hitting the object, type is the attacktype, and 1709 * is what is hitting the object, type is the attacktype, and
1752 * full_hit is set if monster area does not matter. 1710 * full_hit is set if monster area does not matter.
1753 * dam is base damage - protections/vulnerabilities/slaying matches can 1711 * dam is base damage - protections/vulnerabilities/slaying matches can
1754 * modify it. 1712 * modify it.
1755 */ 1713 */
1756
1757 /* Oct 95 - altered the following slightly for MULTIPLE_GODS hack 1714/* Oct 95 - altered the following slightly for MULTIPLE_GODS hack
1758 * which needs new attacktype AT_HOLYWORD to work . b.t. */ 1715 * which needs new attacktype AT_HOLYWORD to work . b.t. */
1759
1760int 1716int
1761hit_player (object *op, int dam, object *hitter, int type, int full_hit) 1717hit_player (object *op, int dam, object *hitter, int type, int full_hit)
1762{ 1718{
1763 int maxdam = 0, ndam = 0, attacktype = 1, magic = (type & AT_MAGIC); 1719 int maxdam = 0, ndam = 0, attacktype = 1, magic = (type & AT_MAGIC);
1764 int maxattacktype, attacknum; 1720 int maxattacktype, attacknum;
1765 int body_attack = op && op->head; /* Did we hit op's head? */ 1721 int body_attack = op && op->head; /* Did we hit op's head? */
1766 int simple_attack; 1722 int simple_attack;
1767 tag_t op_tag, hitter_tag;
1768 int rtn_kill = 0; 1723 int rtn_kill = 0;
1769 int friendlyfire; 1724 int friendlyfire;
1770 1725
1771 if (get_attack_mode (&op, &hitter, &simple_attack)) 1726 if (get_attack_mode (&op, &hitter, &simple_attack))
1772 return 0; 1727 return 0;
1776 return 0; 1731 return 0;
1777 1732
1778#ifdef PROHIBIT_PLAYERKILL 1733#ifdef PROHIBIT_PLAYERKILL
1779 if (op->type == PLAYER) 1734 if (op->type == PLAYER)
1780 { 1735 {
1781 object *owner = get_owner (hitter); 1736 object *owner = hitter->owner;
1782 1737
1783 if (!owner) 1738 if (!owner)
1784 owner = hitter; 1739 owner = hitter;
1740
1785 if (owner->type == PLAYER && (!op_on_battleground (op, 0, 0) && (op->contr->peaceful || owner->contr->peaceful)) && op != owner) 1741 if (owner->type == PLAYER && (!op_on_battleground (op, 0, 0) && (op->contr->peaceful || owner->contr->peaceful)) && op != owner)
1786 {
1787 return 0; 1742 return 0;
1788 }
1789 } 1743 }
1790#endif 1744#endif
1791
1792 op_tag = op->count;
1793 hitter_tag = hitter->count;
1794 1745
1795 if (body_attack) 1746 if (body_attack)
1796 { 1747 {
1797 /* slow and paralyze must hit the head. But we don't want to just 1748 /* slow and paralyze must hit the head. But we don't want to just
1798 * return - we still need to process other attacks the spell still 1749 * return - we still need to process other attacks the spell still
1804 * attack so we don't cancel out things like magic bullet. 1755 * attack so we don't cancel out things like magic bullet.
1805 */ 1756 */
1806 if (type & (AT_PARALYZE | AT_SLOW)) 1757 if (type & (AT_PARALYZE | AT_SLOW))
1807 { 1758 {
1808 type &= ~(AT_PARALYZE | AT_SLOW); 1759 type &= ~(AT_PARALYZE | AT_SLOW);
1760
1809 if (!type || type == AT_MAGIC) 1761 if (!type || type == AT_MAGIC)
1810 return 0; 1762 return 0;
1811 } 1763 }
1812 } 1764 }
1813 1765
1814 if (!simple_attack && op->type == DOOR) 1766 if (!simple_attack && op->type == DOOR)
1815 { 1767 {
1816 object *tmp;
1817
1818 for (tmp = op->inv; tmp != NULL; tmp = tmp->below) 1768 for (object *tmp = op->inv; tmp; tmp = tmp->below)
1819 if (tmp->type == RUNE || tmp->type == TRAP) 1769 if (tmp->type == RUNE || tmp->type == TRAP)
1820 { 1770 {
1821 spring_trap (tmp, hitter); 1771 spring_trap (tmp, hitter);
1772
1822 if (was_destroyed (hitter, hitter_tag) || was_destroyed (op, op_tag) || abort_attack (op, hitter, simple_attack)) 1773 if (hitter->destroyed () || op->destroyed () || abort_attack (op, hitter, simple_attack))
1823 return 0; 1774 return 0;
1775
1824 break; 1776 break;
1825 } 1777 }
1826 } 1778 }
1827 1779
1828 if (!QUERY_FLAG (op, FLAG_ALIVE) || op->stats.hp < 0) 1780 if (!QUERY_FLAG (op, FLAG_ALIVE) || op->stats.hp < 0)
1829 { 1781 {
1830 /* FIXME: If a player is killed by a rune in a door, the 1782 /* FIXME: If a player is killed by a rune in a door, the
1831 * was_destroyed() check above doesn't return, and might get here. 1783 * destroyed() check above doesn't return, and might get here.
1832 */ 1784 */
1833 LOG (llevDebug, "victim (arch %s, name %s) already dead in " "hit_player()\n", &op->arch->name, &op->name); 1785 LOG (llevDebug, "victim %s already dead in hit_player()\n", op->debug_desc ());
1834 return 0; 1786 return 0;
1835 } 1787 }
1836 1788
1837#ifdef ATTACK_DEBUG 1789#ifdef ATTACK_DEBUG
1838 LOG (llevDebug, "hit player: attacktype %d, dam %d\n", type, dam); 1790 LOG (llevDebug, "hit player: attacktype %d, dam %d\n", type, dam);
1874 (hitter->title != NULL 1826 (hitter->title != NULL
1875 && (god = find_god (determine_god (hitter))) != NULL && god->race != NULL && strstr (god->race, undead_name) != NULL))) 1827 && (god = find_god (determine_god (hitter))) != NULL && god->race != NULL && strstr (god->race, undead_name) != NULL)))
1876 return 0; 1828 return 0;
1877 } 1829 }
1878 1830
1879 maxattacktype = type; /* initialize this to something */ 1831 maxattacktype = type; /* initialise this to something */
1880 for (attacknum = 0; attacknum < NROFATTACKS; attacknum++, attacktype = 1 << attacknum) 1832 for (attacknum = 0; attacknum < NROFATTACKS; attacknum++, attacktype = 1 << attacknum)
1881 { 1833 {
1882 /* Magic isn't really a true attack type - it gets combined with other 1834 /* Magic isn't really a true attack type - it gets combined with other
1883 * attack types. As such, skip it over. However, if magic is 1835 * attack types. As such, skip it over. However, if magic is
1884 * the only attacktype in the group, then still attack with it 1836 * the only attacktype in the group, then still attack with it
1945 1897
1946#ifdef ATTACK_DEBUG 1898#ifdef ATTACK_DEBUG
1947 LOG (llevDebug, "Attacktype %d did %d damage\n", type, maxdam); 1899 LOG (llevDebug, "Attacktype %d did %d damage\n", type, maxdam);
1948#endif 1900#endif
1949 1901
1950 if (get_owner (hitter)) 1902 if (hitter->owner)
1951 op->enemy = hitter->owner; 1903 op->enemy = hitter->owner;
1952 else if (QUERY_FLAG (hitter, FLAG_ALIVE)) 1904 else if (QUERY_FLAG (hitter, FLAG_ALIVE))
1953 op->enemy = hitter; 1905 op->enemy = hitter;
1954 1906
1955 if (QUERY_FLAG (op, FLAG_UNAGGRESSIVE) && op->type != PLAYER) 1907 if (QUERY_FLAG (op, FLAG_UNAGGRESSIVE) && op->type != PLAYER)
1980 1932
1981 if (QUERY_FLAG (op, FLAG_TEAR_DOWN)) 1933 if (QUERY_FLAG (op, FLAG_TEAR_DOWN))
1982 { 1934 {
1983 if (maxdam) 1935 if (maxdam)
1984 tear_down_wall (op); 1936 tear_down_wall (op);
1937
1985 return maxdam; /* nothing more to do for wall */ 1938 return maxdam; /* nothing more to do for wall */
1986 } 1939 }
1987 1940
1988 /* See if the creature has been killed */ 1941 /* See if the creature has been killed */
1989 rtn_kill = kill_object (op, maxdam, hitter, type); 1942 rtn_kill = kill_object (op, maxdam, hitter, type);
1997 */ 1950 */
1998 if (QUERY_FLAG (hitter, FLAG_ONE_HIT)) 1951 if (QUERY_FLAG (hitter, FLAG_ONE_HIT))
1999 { 1952 {
2000 if (QUERY_FLAG (hitter, FLAG_FRIENDLY)) 1953 if (QUERY_FLAG (hitter, FLAG_FRIENDLY))
2001 remove_friendly_object (hitter); 1954 remove_friendly_object (hitter);
2002 remove_ob (hitter); 1955
2003 free_object (hitter); 1956 hitter->destroy ();
2004 } 1957 }
2005 /* Lets handle creatures that are splitting now */ 1958 /* Lets handle creatures that are splitting now */
2006 else if (type & AT_PHYSICAL && !QUERY_FLAG (op, FLAG_FREED) && QUERY_FLAG (op, FLAG_SPLITTING)) 1959 else if (type & AT_PHYSICAL && !QUERY_FLAG (op, FLAG_FREED) && QUERY_FLAG (op, FLAG_SPLITTING))
2007 { 1960 {
2008 int i; 1961 int i;
2009 int friendly = QUERY_FLAG (op, FLAG_FRIENDLY); 1962 int friendly = QUERY_FLAG (op, FLAG_FRIENDLY);
2010 int unaggressive = QUERY_FLAG (op, FLAG_UNAGGRESSIVE); 1963 int unaggressive = QUERY_FLAG (op, FLAG_UNAGGRESSIVE);
2011 object *owner = get_owner (op); 1964 object *owner = op->owner;
2012 1965
2013 if (!op->other_arch) 1966 if (!op->other_arch)
2014 { 1967 {
2015 LOG (llevError, "SPLITTING without other_arch error.\n"); 1968 LOG (llevError, "SPLITTING without other_arch error.\n");
2016 return maxdam; 1969 return maxdam;
2017 } 1970 }
1971
2018 remove_ob (op); 1972 op->remove ();
1973
2019 for (i = 0; i < NROFNEWOBJS (op); i++) 1974 for (i = 0; i < NROFNEWOBJS (op); i++)
2020 { /* This doesn't handle op->more yet */ 1975 { /* This doesn't handle op->more yet */
2021 object *tmp = arch_to_object (op->other_arch); 1976 object *tmp = arch_to_object (op->other_arch);
2022 int j; 1977 int j;
2023 1978
2024 tmp->stats.hp = op->stats.hp; 1979 tmp->stats.hp = op->stats.hp;
1980
2025 if (friendly) 1981 if (friendly)
2026 { 1982 {
2027 SET_FLAG (tmp, FLAG_FRIENDLY);
2028 add_friendly_object (tmp); 1983 add_friendly_object (tmp);
2029 tmp->attack_movement = PETMOVE; 1984 tmp->attack_movement = PETMOVE;
1985
2030 if (owner != NULL) 1986 if (owner)
2031 set_owner (tmp, owner); 1987 tmp->set_owner (owner);
2032 } 1988 }
1989
2033 if (unaggressive) 1990 if (unaggressive)
2034 SET_FLAG (tmp, FLAG_UNAGGRESSIVE); 1991 SET_FLAG (tmp, FLAG_UNAGGRESSIVE);
1992
2035 j = find_first_free_spot (tmp, op->map, op->x, op->y); 1993 j = find_first_free_spot (tmp, op->map, op->x, op->y);
1994
2036 if (j == -1) /* No spot to put this monster */ 1995 if (j == -1) /* No spot to put this monster */
2037 free_object (tmp); 1996 tmp->destroy ();
2038 else 1997 else
2039 { 1998 {
2040 tmp->x = op->x + freearr_x[j], tmp->y = op->y + freearr_y[j]; 1999 tmp->x = op->x + freearr_x[j], tmp->y = op->y + freearr_y[j];
2041 insert_ob_in_map (tmp, op->map, NULL, 0); 2000 insert_ob_in_map (tmp, op->map, NULL, 0);
2042 } 2001 }
2043 } 2002 }
2044 if (friendly) 2003
2045 remove_friendly_object (op); 2004 op->destroy ();
2046 free_object (op);
2047 } 2005 }
2048 else if (type & AT_DRAIN && hitter->type == GRIMREAPER && hitter->value++ > 10) 2006 else if (type & AT_DRAIN && hitter->type == GRIMREAPER && hitter->value++ > 10)
2049 { 2007 hitter->destroy ();
2050 remove_ob (hitter); 2008
2051 free_object (hitter);
2052 }
2053 return maxdam; 2009 return maxdam;
2054} 2010}
2055 2011
2056 2012
2057void 2013void
2058poison_player (object *op, object *hitter, int dam) 2014poison_player (object *op, object *hitter, int dam)
2059{ 2015{
2060 archetype *at = find_archetype ("poisoning"); 2016 archetype *at = archetype::find ("poisoning");
2061 object *tmp = present_arch_in_ob (at, op); 2017 object *tmp = present_arch_in_ob (at, op);
2062 2018
2063 if (tmp == NULL) 2019 if (tmp == NULL)
2064 { 2020 {
2065 if ((tmp = arch_to_object (at)) == NULL) 2021 if ((tmp = arch_to_object (at)) == NULL)
2078 if (QUERY_FLAG (hitter, FLAG_ALIVE)) 2034 if (QUERY_FLAG (hitter, FLAG_ALIVE))
2079 tmp->stats.dam += hitter->level / 2; 2035 tmp->stats.dam += hitter->level / 2;
2080 else 2036 else
2081 tmp->stats.dam = dam; 2037 tmp->stats.dam = dam;
2082 2038
2083 copy_owner (tmp, hitter); /* so we get credit for poisoning kills */ 2039 tmp->set_owner (hitter); /* so we get credit for poisoning kills */
2084 if (hitter->skill && hitter->skill != tmp->skill) 2040 if (hitter->skill && hitter->skill != tmp->skill)
2085 { 2041 {
2086 tmp->skill = hitter->skill; 2042 tmp->skill = hitter->skill;
2087 } 2043 }
2088 2044
2094 tmp->stats.Con = MAX (-(dam / 4 + 1), -10); 2050 tmp->stats.Con = MAX (-(dam / 4 + 1), -10);
2095 tmp->stats.Str = MAX (-(dam / 3 + 2), -10); 2051 tmp->stats.Str = MAX (-(dam / 3 + 2), -10);
2096 tmp->stats.Dex = MAX (-(dam / 6 + 1), -10); 2052 tmp->stats.Dex = MAX (-(dam / 6 + 1), -10);
2097 tmp->stats.Int = MAX (-dam / 7, -10); 2053 tmp->stats.Int = MAX (-dam / 7, -10);
2098 SET_FLAG (tmp, FLAG_APPLIED); 2054 SET_FLAG (tmp, FLAG_APPLIED);
2099 fix_player (op); 2055 op->update_stats ();
2100 new_draw_info (NDI_UNIQUE, 0, op, "You suddenly feel very ill."); 2056 new_draw_info (NDI_UNIQUE, 0, op, "You suddenly feel very ill.");
2101 } 2057 }
2102 if (hitter->type == PLAYER) 2058 if (hitter->type == PLAYER)
2103 new_draw_info_format (NDI_UNIQUE, 0, hitter, "You poison %s.", &op->name); 2059 new_draw_info_format (NDI_UNIQUE, 0, hitter, "You poison %s.", &op->name);
2104 else if (get_owner (hitter) != NULL && hitter->owner->type == PLAYER) 2060 else if (hitter->owner != NULL && hitter->owner->type == PLAYER)
2105 new_draw_info_format (NDI_UNIQUE, 0, hitter->owner, "Your %s poisons %s.", &hitter->name, &op->name); 2061 new_draw_info_format (NDI_UNIQUE, 0, hitter->owner, "Your %s poisons %s.", &hitter->name, &op->name);
2106 } 2062 }
2107 tmp->speed_left = 0; 2063 tmp->speed_left = 0;
2108 } 2064 }
2109 else 2065 else
2111} 2067}
2112 2068
2113void 2069void
2114slow_player (object *op, object *hitter, int dam) 2070slow_player (object *op, object *hitter, int dam)
2115{ 2071{
2116 archetype *at = find_archetype ("slowness"); 2072 archetype *at = archetype::find ("slowness");
2117 object *tmp; 2073 object *tmp;
2118 2074
2119 if (at == NULL) 2075 if (at == NULL)
2120 { 2076 {
2121 LOG (llevError, "Can't find slowness archetype.\n"); 2077 LOG (llevError, "Can't find slowness archetype.\n");
2128 } 2084 }
2129 else 2085 else
2130 tmp->stats.food++; 2086 tmp->stats.food++;
2131 SET_FLAG (tmp, FLAG_APPLIED); 2087 SET_FLAG (tmp, FLAG_APPLIED);
2132 tmp->speed_left = 0; 2088 tmp->speed_left = 0;
2133 fix_player (op); 2089 op->update_stats ();
2134} 2090}
2135 2091
2136void 2092void
2137confuse_player (object *op, object *hitter, int dam) 2093confuse_player (object *op, object *hitter, int dam)
2138{ 2094{
2182 */ 2138 */
2183 tmp->speed = tmp->speed * (100.0 - (float) op->resist[ATNR_BLIND]) / 100; 2139 tmp->speed = tmp->speed * (100.0 - (float) op->resist[ATNR_BLIND]) / 100;
2184 2140
2185 tmp = insert_ob_in_ob (tmp, op); 2141 tmp = insert_ob_in_ob (tmp, op);
2186 change_abil (op, tmp); /* Mostly to display any messages */ 2142 change_abil (op, tmp); /* Mostly to display any messages */
2187 fix_player (op); /* This takes care of some other stuff */ 2143 op->update_stats (); /* This takes care of some other stuff */
2188 2144
2189 if (hitter->owner) 2145 if (hitter->owner)
2190 owner = get_owner (hitter); 2146 owner = hitter->owner;
2191 else 2147 else
2192 owner = hitter; 2148 owner = hitter;
2193 2149
2194 new_draw_info_format (NDI_UNIQUE, 0, owner, "Your attack blinds %s!", query_name (op)); 2150 new_draw_info_format (NDI_UNIQUE, 0, owner, "Your attack blinds %s!", query_name (op));
2195 } 2151 }
2341 } 2297 }
2342 2298
2343 /* aimed missiles use the owning object's sight */ 2299 /* aimed missiles use the owning object's sight */
2344 if (is_aimed_missile (hitter)) 2300 if (is_aimed_missile (hitter))
2345 { 2301 {
2346 if ((attacker = get_owner (hitter)) == NULL) 2302 if ((attacker = hitter->owner) == NULL)
2347 attacker = hitter; 2303 attacker = hitter;
2348 /* A player who saves but hasn't quit still could have objects 2304 /* A player who saves but hasn't quit still could have objects
2349 * owned by him - need to handle that case to avoid crashes. 2305 * owned by him - need to handle that case to avoid crashes.
2350 */ 2306 */
2351 if (QUERY_FLAG (attacker, FLAG_REMOVED)) 2307 if (QUERY_FLAG (attacker, FLAG_REMOVED))

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines