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.36 by pippijn, Wed Jan 3 00:21:36 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
10 Copyright (C) 2002 Mark Wedel & Crossfire Development Team 4 Copyright (C) 2002 Mark Wedel & Crossfire Development Team
11 Copyright (C) 1992 Frank Tore Johansen 5 Copyright (C) 1992 Frank Tore Johansen
22 16
23 You should have received a copy of the GNU General Public License 17 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software 18 along with this program; if not, write to the Free Software
25 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 20
27 The authors can be reached via e-mail to crossfire-devel@real-time.com 21 The authors can be reached via e-mail to <crossfire@schmorp.de>
28*/ 22*/
29#include <assert.h> 23#include <assert.h>
30#include <global.h> 24#include <global.h>
31#include <living.h> 25#include <living.h>
32#include <material.h> 26#include <material.h>
78 esrv_send_item (op->env, op); 72 esrv_send_item (op->env, op);
79 } 73 }
80 } 74 }
81} 75}
82 76
83
84
85/* did_make_save_item just checks to make sure the item actually 77/* 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 78 * made its saving throw based on the tables. It does not take
87 * any further action (like destroying the item). 79 * any further action (like destroying the item).
88 */ 80 */
89
90int 81int
91did_make_save_item (object *op, int type, object *originator) 82did_make_save_item (object *op, int type, object *originator)
92{ 83{
93 int i, roll, saves = 0, attacks = 0, number; 84 int i, roll, saves = 0, attacks = 0, number;
94 materialtype_t *mt; 85 materialtype_t *mt;
95 86
96 if (op->materialname == NULL) 87 if (op->materialname == NULL)
97 { 88 {
98 for (mt = materialt; mt != NULL && mt->next != NULL; mt = mt->next) 89 for (mt = materialt; mt != NULL && mt->next != NULL; mt = mt->next)
99 {
100 if (op->material & mt->material) 90 if (op->material & mt->material)
101 break; 91 break;
102 }
103 } 92 }
104 else 93 else
105 mt = name_to_material (op->materialname); 94 mt = name_to_material (op->materialname);
106 if (mt == NULL) 95 if (mt == NULL)
107 return TRUE; 96 return TRUE;
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.
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; 278 object *tmp, *next;
284 mapstruct *map; 279 maptile *map;
285 sint16 x, y; 280 sint16 x, y;
286 int retflag = 0; /* added this flag.. will return 1 if it hits a monster */ 281 int retflag = 0; /* added this flag.. will return 1 if it hits a monster */
287 282
288 tag_t op_tag, next_tag = 0;
289
290 if (QUERY_FLAG (op, FLAG_FREED)) 283 if (QUERY_FLAG (op, FLAG_FREED))
291 { 284 {
292 LOG (llevError, "BUG: hit_map(): free object\n"); 285 LOG (llevError, "BUG: hit_map(): free object\n");
293 return 0; 286 return 0;
294 } 287 }
305 return 0; 298 return 0;
306 } 299 }
307 300
308 if (op->head) 301 if (op->head)
309 op = op->head; 302 op = op->head;
310
311 op_tag = op->count;
312 303
313 map = op->map; 304 map = op->map;
314 x = op->x + freearr_x[dir]; 305 x = op->x + freearr_x[dir];
315 y = op->y + freearr_y[dir]; 306 y = op->y + freearr_y[dir];
316 307
317 int mflags = get_map_flags (map, &map, x, y, &x, &y); 308 int mflags = get_map_flags (map, &map, x, y, &x, &y);
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 if (mflags & (P_OUT_OF_MAP | P_SAFE))
322 return 0; 313 return 0;
323 314
324 /* peterm: a few special cases for special attacktypes --counterspell 315 /* peterm: a few special cases for special attacktypes --counterspell
325 * must be out here because it strikes things which are not alive 316 * must be out here because it strikes things which are not alive
326 */ 317 */
331 322
332 /* If the only attacktype is counterspell or magic, don't need 323 /* If the only attacktype is counterspell or magic, don't need
333 * to do any further processing. 324 * to do any further processing.
334 */ 325 */
335 if (!(type & ~(AT_COUNTERSPELL | AT_MAGIC))) 326 if (!(type & ~(AT_COUNTERSPELL | AT_MAGIC)))
336 {
337 return 0; 327 return 0;
338 } 328
339 type &= ~AT_COUNTERSPELL; 329 type &= ~AT_COUNTERSPELL;
340 } 330 }
341 331
342 if (type & AT_CHAOS) 332 if (type & AT_CHAOS)
343 { 333 {
344 shuffle_attack (op, 1); /*1 flag tells it to change the face */ 334 shuffle_attack (op, 1); /*1 flag tells it to change the face */
345 update_object (op, UP_OBJ_FACE); 335 update_object (op, UP_OBJ_FACE);
346 type &= ~AT_CHAOS; 336 type &= ~AT_CHAOS;
347 } 337 }
348 338
349 next = get_map_ob (map, x, y); 339 next = GET_MAP_OB (map, x, y);
350 if (next)
351 next_tag = next->count;
352 340
353 while (next) 341 while (next)
354 { 342 {
355 if (was_destroyed (next, next_tag)) 343 if (next->destroyed ())
356 { 344 {
357 /* There may still be objects that were above 'next', but there is no 345 /* 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 346 * simple way to find out short of copying all object references and
359 * tags into a temporary array before we start processing the first 347 * tags into a temporary array before we start processing the first
360 * object. That's why we just abort. 348 * object. That's why we just abort.
364 * below was spamming the logs for absolutely no reason. 352 * below was spamming the logs for absolutely no reason.
365 */ 353 */
366 /* LOG (llevDebug, "hit_map(): next object destroyed\n"); */ 354 /* LOG (llevDebug, "hit_map(): next object destroyed\n"); */
367 break; 355 break;
368 } 356 }
357
369 tmp = next; 358 tmp = next;
370 next = tmp->above; 359 next = tmp->above;
371 if (next)
372 next_tag = next->count;
373 360
374 if (QUERY_FLAG (tmp, FLAG_FREED)) 361 if (tmp->destroyed ())
375 { 362 {
376 LOG (llevError, "BUG: hit_map(): found freed object\n"); 363 LOG (llevError, "BUG: hit_map(): found freed object\n");
377 break; 364 break;
378 } 365 }
379 366
386 373
387 if (QUERY_FLAG (tmp, FLAG_ALIVE)) 374 if (QUERY_FLAG (tmp, FLAG_ALIVE))
388 { 375 {
389 hit_player (tmp, op->stats.dam, op, type, full_hit); 376 hit_player (tmp, op->stats.dam, op, type, full_hit);
390 retflag |= 1; 377 retflag |= 1;
391 if (was_destroyed (op, op_tag)) 378 if (op->destroyed ())
392 break; 379 break;
393 } 380 }
381
394 /* Here we are potentially destroying an object. If the object has 382 /* 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 383 * 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 384 * that weak walls have is_alive set, which prevent objects from
397 * passing over/through them. We don't care what type of movement 385 * passing over/through them. We don't care what type of movement
398 * the wall blocks - if it blocks any type of movement, can't be 386 * the wall blocks - if it blocks any type of movement, can't be
399 * destroyed right now. 387 * destroyed right now.
400 */ 388 */
401 else if ((tmp->material || tmp->materialname) && op->stats.dam > 0 && !tmp->move_block) 389 else if ((tmp->material || tmp->materialname) && op->stats.dam > 0 && !tmp->move_block)
402 { 390 {
403 save_throw_object (tmp, type, op); 391 save_throw_object (tmp, type, op);
404 if (was_destroyed (op, op_tag)) 392 if (op->destroyed ())
405 break; 393 break;
406 } 394 }
407 } 395 }
396
408 return 0; 397 return 0;
409} 398}
410 399
411void 400void
412attack_message (int dam, int type, object *op, object *hitter) 401attack_message (int dam, int type, object *op, object *hitter)
413{ 402{
414 char buf[MAX_BUF], buf1[MAX_BUF], buf2[MAX_BUF]; 403 char buf[MAX_BUF], buf1[MAX_BUF], buf2[MAX_BUF];
415 int i, found = 0; 404 int i, found = 0;
416 mapstruct *map; 405 maptile *map;
417 object *next, *tmp; 406 object *next, *tmp;
418 407
419 /* put in a few special messages for some of the common attacktypes 408 /* put in a few special messages for some of the common attacktypes
420 * a player might have. For example, fire, electric, cold, etc 409 * a player might have. For example, fire, electric, cold, etc
421 * [garbled 20010919] 410 * [garbled 20010919]
438 sprintf (buf1, "missed %s", &op->name); 427 sprintf (buf1, "missed %s", &op->name);
439 sprintf (buf2, " misses"); 428 sprintf (buf2, " misses");
440 found++; 429 found++;
441 } 430 }
442 else if ((hitter->type == DISEASE || hitter->type == SYMPTOM || 431 else if ((hitter->type == DISEASE || hitter->type == SYMPTOM ||
443 hitter->type == POISONING || (type & AT_POISON && IS_LIVE (op))) && !found) 432 hitter->type == POISONING || (type & AT_POISON && op->is_alive ())) && !found)
444 { 433 {
445 for (i = 0; i < MAXATTACKMESS && attack_mess[ATM_SUFFER][i].level != -1; i++) 434 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) 435 if (dam < attack_mess[ATM_SUFFER][i].level || attack_mess[ATM_SUFFER][i + 1].level == -1)
447 { 436 {
448 sprintf (buf1, "%s %s%s", attack_mess[ATM_SUFFER][i].buf1, &op->name, attack_mess[ATM_SUFFER][i].buf2); 437 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); 449 strcpy (buf2, attack_mess[ATM_DOOR][i].buf3);
461 found++; 450 found++;
462 break; 451 break;
463 } 452 }
464 } 453 }
465 else if (hitter->type == PLAYER && IS_LIVE (op)) 454 else if (hitter->type == PLAYER && op->is_alive ())
466 { 455 {
467 if (USING_SKILL (hitter, SK_KARATE)) 456 if (USING_SKILL (hitter, SK_KARATE))
468 { 457 {
469 for (i = 0; i < MAXATTACKMESS && attack_mess[ATM_KARATE][i].level != -1; i++) 458 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) 459 if (dam < attack_mess[ATM_KARATE][i].level || attack_mess[ATM_KARATE][i + 1].level == -1)
496 found++; 485 found++;
497 break; 486 break;
498 } 487 }
499 } 488 }
500 } 489 }
490
501 if (found) 491 if (found)
502 { 492 {
503 /* done */ 493 /* done */
504 } 494 }
505 else if (IS_ARROW (hitter) && (type == AT_PHYSICAL || type == AT_MAGIC)) 495 else if (hitter->is_arrow () && (type == AT_PHYSICAL || type == AT_MAGIC))
506 { 496 {
507 sprintf (buf1, "hit"); /* just in case */ 497 sprintf (buf1, "hit"); /* just in case */
508 for (i = 0; i < MAXATTACKMESS; i++) 498 for (i = 0; i < MAXATTACKMESS; i++)
509 if (dam < attack_mess[ATM_ARROW][i].level || attack_mess[ATM_ARROW][i + 1].level == -1) 499 if (dam < attack_mess[ATM_ARROW][i].level || attack_mess[ATM_ARROW][i + 1].level == -1)
510 { 500 {
511 strcpy (buf2, attack_mess[ATM_ARROW][i].buf3); 501 strcpy (buf2, attack_mess[ATM_ARROW][i].buf3);
512 found++; 502 found++;
513 break; 503 break;
514 } 504 }
515 } 505 }
516 else if (type & AT_DRAIN && IS_LIVE (op)) 506 else if (type & AT_DRAIN && op->is_alive ())
517 { 507 {
518 /* drain is first, because some items have multiple attypes */ 508 /* drain is first, because some items have multiple attypes */
519 for (i = 0; i < MAXATTACKMESS && attack_mess[ATM_DRAIN][i].level != -1; i++) 509 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) 510 if (dam < attack_mess[ATM_DRAIN][i].level || attack_mess[ATM_DRAIN][i + 1].level == -1)
521 { 511 {
523 strcpy (buf2, attack_mess[ATM_DRAIN][i].buf3); 513 strcpy (buf2, attack_mess[ATM_DRAIN][i].buf3);
524 found++; 514 found++;
525 break; 515 break;
526 } 516 }
527 } 517 }
528 else if (type & AT_ELECTRICITY && IS_LIVE (op)) 518 else if (type & AT_ELECTRICITY && op->is_alive ())
529 { 519 {
530 for (i = 0; i < MAXATTACKMESS && attack_mess[ATM_ELEC][i].level != -1; i++) 520 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) 521 if (dam < attack_mess[ATM_ELEC][i].level || attack_mess[ATM_ELEC][i + 1].level == -1)
532 { 522 {
533 sprintf (buf1, "%s %s%s", attack_mess[ATM_ELEC][i].buf1, &op->name, attack_mess[ATM_ELEC][i].buf2); 523 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); 524 strcpy (buf2, attack_mess[ATM_ELEC][i].buf3);
535 found++; 525 found++;
536 break; 526 break;
537 } 527 }
538 } 528 }
539 else if (type & AT_COLD && IS_LIVE (op)) 529 else if (type & AT_COLD && op->is_alive ())
540 { 530 {
541 for (i = 0; i < MAXATTACKMESS && attack_mess[ATM_COLD][i].level != -1; i++) 531 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) 532 if (dam < attack_mess[ATM_COLD][i].level || attack_mess[ATM_COLD][i + 1].level == -1)
543 { 533 {
544 sprintf (buf1, "%s %s%s", attack_mess[ATM_COLD][i].buf1, &op->name, attack_mess[ATM_COLD][i].buf2); 534 sprintf (buf1, "%s %s%s", attack_mess[ATM_COLD][i].buf1, &op->name, attack_mess[ATM_COLD][i].buf2);
621 strcpy (buf1, "hit"); 611 strcpy (buf1, "hit");
622 strcpy (buf2, " hits"); 612 strcpy (buf2, " hits");
623 } 613 }
624 614
625 /* bail out if a monster is casting spells */ 615 /* bail out if a monster is casting spells */
626 if (!(hitter->type == PLAYER || (get_owner (hitter) != NULL && hitter->owner->type == PLAYER))) 616 if (!(hitter->type == PLAYER || (hitter->owner != NULL && hitter->owner->type == PLAYER)))
627 return; 617 return;
628 618
629 /* scale down magic considerably. */ 619 /* scale down magic considerably. */
630 if (type & AT_MAGIC && rndm (0, 5)) 620 if (type & AT_MAGIC && rndm (0, 5))
631 return; 621 return;
632 622
633 /* Did a player hurt another player? Inform both! */ 623 /* Did a player hurt another player? Inform both! */
634 if (op->type == PLAYER && (get_owner (hitter) == NULL ? hitter->type : hitter->owner->type) == PLAYER) 624 if (op->type == PLAYER && (hitter->owner == NULL ? hitter->type : hitter->owner->type) == PLAYER)
635 { 625 {
636 if (get_owner (hitter) != NULL) 626 if (hitter->owner != NULL)
637 sprintf (buf, "%s's %s%s you.", &hitter->owner->name, &hitter->name, buf2); 627 sprintf (buf, "%s's %s%s you.", &hitter->owner->name, &hitter->name, buf2);
638 else 628 else
639 { 629 {
640 sprintf (buf, "%s%s you.", &hitter->name, buf2); 630 sprintf (buf, "%s%s you.", &hitter->name, buf2);
641 if (dam != 0) 631 if (dam != 0)
663 else 653 else
664 play_sound_player_only (hitter->contr, SOUND_PLAYER_HITS3, 0, 0); 654 play_sound_player_only (hitter->contr, SOUND_PLAYER_HITS3, 0, 0);
665 } 655 }
666 new_draw_info (NDI_BLACK, 0, hitter, buf); 656 new_draw_info (NDI_BLACK, 0, hitter, buf);
667 } 657 }
668 else if (get_owner (hitter) != NULL && hitter->owner->type == PLAYER) 658 else if (hitter->owner != NULL && hitter->owner->type == PLAYER)
669 { 659 {
670 /* look for stacked spells and start reducing the message chances */ 660 /* 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)) 661 if (hitter->type == SPELL_EFFECT && (hitter->subtype == SP_EXPLOSION || hitter->subtype == SP_BULLET || hitter->subtype == SP_CONE))
672 { 662 {
673 i = 4; 663 i = 4;
674 map = hitter->map; 664 map = hitter->map;
675 if (out_of_map (map, hitter->x, hitter->y)) 665 if (out_of_map (map, hitter->x, hitter->y))
676 return; 666 return;
677 next = get_map_ob (map, hitter->x, hitter->y); 667 next = GET_MAP_OB (map, hitter->x, hitter->y);
678 if (next) 668 if (next)
679 while (next) 669 while (next)
680 { 670 {
681 if (next->type == SPELL_EFFECT && (next->subtype == SP_EXPLOSION || next->subtype == SP_BULLET || next->subtype == SP_CONE)) 671 if (next->type == SPELL_EFFECT && (next->subtype == SP_EXPLOSION || next->subtype == SP_BULLET || next->subtype == SP_CONE))
682 i *= 3; 672 i *= 3;
748attack_ob_simple (object *op, object *hitter, int base_dam, int base_wc) 738attack_ob_simple (object *op, object *hitter, int base_dam, int base_wc)
749{ 739{
750 int simple_attack, roll, dam = 0; 740 int simple_attack, roll, dam = 0;
751 uint32 type; 741 uint32 type;
752 shstr op_name; 742 shstr op_name;
753 tag_t op_tag, hitter_tag;
754 743
755 if (get_attack_mode (&op, &hitter, &simple_attack)) 744 if (get_attack_mode (&op, &hitter, &simple_attack))
756 goto error; 745 goto error;
757 746
758 if (hitter->current_weapon) 747 if (hitter->current_weapon)
759 if (INVOKE_OBJECT (WEAPON_ATTACK, hitter->current_weapon, ARG_OBJECT (hitter), ARG_OBJECT (op))) 748 if (INVOKE_OBJECT (WEAPON_ATTACK, hitter->current_weapon, ARG_OBJECT (hitter), ARG_OBJECT (op)))
760 return RESULT_INT (0); 749 return RESULT_INT (0);
761 750
762 if (INVOKE_OBJECT (ATTACK, op, ARG_OBJECT (hitter))) 751 if (INVOKE_OBJECT (ATTACK, op, ARG_OBJECT (hitter)))
763 return RESULT_INT (0); 752 return RESULT_INT (0);
764
765 op_tag = op->count;
766 hitter_tag = hitter->count;
767 753
768 /* 754 /*
769 * A little check to make it more difficult to dance forward and back 755 * A little check to make it more difficult to dance forward and back
770 * to avoid ever being hit by monsters. 756 * to avoid ever being hit by monsters.
771 */ 757 */
776 * which then gets here again. By decreasing the speed before 762 * which then gets here again. By decreasing the speed before
777 * we call process_object, the 'if' statement above will fail. 763 * we call process_object, the 'if' statement above will fail.
778 */ 764 */
779 op->speed_left--; 765 op->speed_left--;
780 process_object (op); 766 process_object (op);
767
781 if (was_destroyed (op, op_tag) || was_destroyed (hitter, hitter_tag) || abort_attack (op, hitter, simple_attack)) 768 if (op->destroyed () || hitter->destroyed () || abort_attack (op, hitter, simple_attack))
782 goto error; 769 goto error;
783 } 770 }
784 771
785 op_name = op->name; 772 op_name = op->name;
786 773
820 if (QUERY_FLAG (op, FLAG_SLEEP)) 807 if (QUERY_FLAG (op, FLAG_SLEEP))
821 CLEAR_FLAG (op, FLAG_SLEEP); 808 CLEAR_FLAG (op, FLAG_SLEEP);
822 809
823 /* If the victim can't see the attacker, it may alert others 810 /* If the victim can't see the attacker, it may alert others
824 * for help. */ 811 * for help. */
825 if (op->type != PLAYER && !can_see_enemy (op, hitter) && !get_owner (op) && rndm (0, op->stats.Int)) 812 if (op->type != PLAYER && !can_see_enemy (op, hitter) && !op->owner && rndm (0, op->stats.Int))
826 npc_call_help (op); 813 npc_call_help (op);
827 814
828 /* if you were hidden and hit by a creature, you are discovered */ 815 /* if you were hidden and hit by a creature, you are discovered */
829 if (op->hide && QUERY_FLAG (hitter, FLAG_ALIVE)) 816 if (op->hide && QUERY_FLAG (hitter, FLAG_ALIVE))
830 { 817 {
837 * when they hit the victim. For things like thrown daggers, 824 * when they hit the victim. For things like thrown daggers,
838 * this sets 'hitter' to the actual dagger, and not the 825 * this sets 'hitter' to the actual dagger, and not the
839 * wrapper object. 826 * wrapper object.
840 */ 827 */
841 thrown_item_effect (hitter, op); 828 thrown_item_effect (hitter, op);
829
842 if (was_destroyed (hitter, hitter_tag) || was_destroyed (op, op_tag) || abort_attack (op, hitter, simple_attack)) 830 if (hitter->destroyed () || op->destroyed () || abort_attack (op, hitter, simple_attack))
843 goto leave; 831 goto leave;
844 } 832 }
845 833
846 /* Need to do at least 1 damage, otherwise there is no point 834 /* Need to do at least 1 damage, otherwise there is no point
847 * to go further and it will cause FPE's below. 835 * to go further and it will cause FPE's below.
848 */ 836 */
849 if (hitdam <= 0) 837 if (hitdam <= 0)
850 hitdam = 1; 838 hitdam = 1;
851 839
852 type = hitter->attacktype; 840 type = hitter->attacktype;
841
853 if (!type) 842 if (!type)
854 type = AT_PHYSICAL; 843 type = AT_PHYSICAL;
844
855 /* Handle monsters that hit back */ 845 /* Handle monsters that hit back */
856 if (!simple_attack && QUERY_FLAG (op, FLAG_HITBACK) && QUERY_FLAG (hitter, FLAG_ALIVE)) 846 if (!simple_attack && QUERY_FLAG (op, FLAG_HITBACK) && QUERY_FLAG (hitter, FLAG_ALIVE))
857 { 847 {
858 if (op->attacktype & AT_ACID && hitter->type == PLAYER) 848 if (op->attacktype & AT_ACID && hitter->type == PLAYER)
859 new_draw_info (NDI_UNIQUE, 0, hitter, "You are splashed by acid!\n"); 849 new_draw_info (NDI_UNIQUE, 0, hitter, "You are splashed by acid!\n");
850
860 hit_player (hitter, random_roll (0, (op->stats.dam), hitter, PREFER_LOW), op, op->attacktype, 1); 851 hit_player (hitter, random_roll (0, (op->stats.dam), hitter, PREFER_LOW), op, op->attacktype, 1);
852
861 if (was_destroyed (op, op_tag) || was_destroyed (hitter, hitter_tag) || abort_attack (op, hitter, simple_attack)) 853 if (op->destroyed () || hitter->destroyed () || abort_attack (op, hitter, simple_attack))
862 goto leave; 854 goto leave;
863 } 855 }
864 856
865 /* In the new attack code, it should handle multiple attack 857 /* In the new attack code, it should handle multiple attack
866 * types in its area, so remove it from here. 858 * types in its area, so remove it from here.
867 */ 859 */
868 dam = hit_player (op, random_roll (1, hitdam, hitter, PREFER_HIGH), hitter, type, 1); 860 dam = hit_player (op, random_roll (1, hitdam, hitter, PREFER_HIGH), hitter, type, 1);
861
869 if (was_destroyed (op, op_tag) || was_destroyed (hitter, hitter_tag) || abort_attack (op, hitter, simple_attack)) 862 if (op->destroyed () || hitter->destroyed () || abort_attack (op, hitter, simple_attack))
870 goto leave; 863 goto leave;
871 } /* end of if hitter hit op */ 864 } /* end of if hitter hit op */
872 /* if we missed, dam=0 */ 865 /* if we missed, dam=0 */
873 866
874 /*attack_message(dam, type, op, hitter); */ 867 /*attack_message(dam, type, op, hitter); */
908 if (op->weight <= 5000 && tmp->stats.hp >= 0) 901 if (op->weight <= 5000 && tmp->stats.hp >= 0)
909 { 902 {
910 if (tmp->head != NULL) 903 if (tmp->head != NULL)
911 tmp = tmp->head; 904 tmp = tmp->head;
912 905
913 remove_ob (op); 906 op->remove ();
914 op = insert_ob_in_ob (op, tmp); 907 op = insert_ob_in_ob (op, tmp);
915 908
916 if (tmp->type == PLAYER) 909 if (tmp->type == PLAYER)
917 esrv_send_item (tmp, op); 910 esrv_send_item (tmp, op);
918 911
931object * 924object *
932hit_with_arrow (object *op, object *victim) 925hit_with_arrow (object *op, object *victim)
933{ 926{
934 object *container, *hitter; 927 object *container, *hitter;
935 int hit_something = 0; 928 int hit_something = 0;
936 tag_t victim_tag, hitter_tag;
937 sint16 victim_x, victim_y;
938 929
939 /* Disassemble missile */ 930 /* Disassemble missile */
940 if (op->inv) 931 if (op->inv)
941 { 932 {
942 container = op; 933 container = op;
943 hitter = op->inv; 934 hitter = op->inv;
944 remove_ob (hitter); 935 hitter->remove ();
945 insert_ob_in_map (hitter, container->map, hitter, INS_NO_MERGE | INS_NO_WALK_ON); 936 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 937 /* 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 938 * 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 939 * removed at the end of this function must be able to deal with empty
949 * THROWN_OBJs. */ 940 * THROWN_OBJs. */
950 } 941 }
951 else 942 else
952 { 943 {
953 container = NULL; 944 container = 0;
954 hitter = op; 945 hitter = op;
955 } 946 }
956 947
957 /* Try to hit victim */ 948 /* 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); 949 hit_something = attack_ob_simple (victim, hitter, op->stats.dam, op->stats.wc);
964 950
965 /* Arrow attacks door, rune of summoning is triggered, demon is put on 951 /* Arrow attacks door, rune of summoning is triggered, demon is put on
966 * arrow, move_apply() calls this function, arrow sticks in demon, 952 * arrow, move_apply() calls this function, arrow sticks in demon,
967 * attack_ob_simple() returns, and we've got an arrow that still exists 953 * 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 954 * but is no longer on the map. Ugh. (Beware: Such things can happen at
969 * other places as well!) 955 * other places as well!)
970 */ 956 */
971 if (was_destroyed (hitter, hitter_tag) || hitter->env != NULL) 957 if (hitter->destroyed () || hitter->env != NULL)
972 { 958 {
973 if (container) 959 if (container)
974 { 960 {
975 remove_ob (container); 961 container->remove ();
976 free_object (container); 962 container->destroy ();
977 } 963 }
964
978 return NULL; 965 return 0;
979 } 966 }
980 967
981 /* Missile hit victim */ 968 /* Missile hit victim */
982 /* if the speed is > 10, then this is a fast moving arrow, we go straight 969 /* if the speed is > 10, then this is a fast moving arrow, we go straight
983 * through the target 970 * through the target
984 */ 971 */
985 if (hit_something && op->speed <= 10.0) 972 if (hit_something && op->speed <= 10.0)
986 { 973 {
987 /* Stop arrow */ 974 /* Stop arrow */
988 if (container == NULL) 975 if (!container)
989 { 976 {
990 hitter = fix_stopped_arrow (hitter); 977 hitter = fix_stopped_arrow (hitter);
991 if (hitter == NULL) 978 if (!hitter)
992 return NULL; 979 return 0;
993 } 980 }
994 else 981 else
995 { 982 container->destroy ();
996 remove_ob (container);
997 free_object (container);
998 }
999 983
1000 /* Try to stick arrow into victim */ 984 /* Try to stick arrow into victim */
1001 if (!was_destroyed (victim, victim_tag) && stick_arrow (hitter, victim)) 985 if (!victim->destroyed () && stick_arrow (hitter, victim))
1002 return NULL; 986 return 0;
1003 987
1004 /* Else try to put arrow on victim's map square 988 /* Else try to put arrow on victim's map square
1005 * remove check for P_WALL here. If the arrow got to this 989 * remove check for P_WALL here. If the arrow got to this
1006 * space, that is good enough - with the new movement code, 990 * space, that is good enough - with the new movement code,
1007 * there is now the potential for lots of spaces where something 991 * there is now the potential for lots of spaces where something
1008 * can fly over but not otherwise move over. What is the correct 992 * can fly over but not otherwise move over. What is the correct
1009 * way to handle those otherwise? 993 * way to handle those otherwise?
1010 */ 994 */
1011 if (victim_x != hitter->x || victim_y != hitter->y) 995 if (victim->x != hitter->x || victim->y != hitter->y)
1012 { 996 {
1013 remove_ob (hitter); 997 hitter->remove ();
1014 hitter->x = victim_x; 998 hitter->x = victim->x;
1015 hitter->y = victim_y; 999 hitter->y = victim->y;
1016 insert_ob_in_map (hitter, victim->map, hitter, 0); 1000 insert_ob_in_map (hitter, victim->map, hitter, 0);
1017 } 1001 }
1018 else 1002 else
1019 {
1020 /* Else leave arrow where it is */ 1003 /* Else leave arrow where it is */
1021 merge_ob (hitter, NULL); 1004 merge_ob (hitter, NULL);
1022 } 1005
1023 return NULL; 1006 return 0;
1024 } 1007 }
1025 1008
1026 if (hit_something && op->speed >= 10.0) 1009 if (hit_something && op->speed >= 10.0)
1027 op->speed -= 1.0; 1010 op->speed -= 1.0;
1028 1011
1029 /* Missile missed victim - reassemble missile */ 1012 /* Missile missed victim - reassemble missile */
1030 if (container) 1013 if (container)
1031 { 1014 {
1032 remove_ob (hitter); 1015 hitter->remove ();
1033 insert_ob_in_ob (hitter, container); 1016 insert_ob_in_ob (hitter, container);
1034 } 1017 }
1018
1035 return op; 1019 return op;
1036} 1020}
1037 1021
1038 1022
1039void 1023void
1048 } 1032 }
1049 else if (!GET_ANIM_ID (op)) 1033 else if (!GET_ANIM_ID (op))
1050 { 1034 {
1051 /* Object has been called - no animations, so remove it */ 1035 /* Object has been called - no animations, so remove it */
1052 if (op->stats.hp < 0) 1036 if (op->stats.hp < 0)
1037 op->destroy ();
1053 { 1038
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 */ 1039 return; /* no animations, so nothing more to do */
1060 } 1040 }
1041
1061 perc = NUM_ANIMATIONS (op) - ((int) NUM_ANIMATIONS (op) * op->stats.hp) / op->stats.maxhp; 1042 perc = NUM_ANIMATIONS (op) - ((int) NUM_ANIMATIONS (op) * op->stats.hp) / op->stats.maxhp;
1043
1062 if (perc >= (int) NUM_ANIMATIONS (op)) 1044 if (perc >= (int) NUM_ANIMATIONS (op))
1063 perc = NUM_ANIMATIONS (op) - 1; 1045 perc = NUM_ANIMATIONS (op) - 1;
1064 else if (perc < 1) 1046 else if (perc < 1)
1065 perc = 1; 1047 perc = 1;
1048
1066 SET_ANIMATION (op, perc); 1049 SET_ANIMATION (op, perc);
1067 update_object (op, UP_OBJ_FACE); 1050 update_object (op, UP_OBJ_FACE);
1051
1068 if (perc == NUM_ANIMATIONS (op) - 1) 1052 if (perc == NUM_ANIMATIONS (op) - 1)
1069 { /* Reached the last animation */ 1053 { /* Reached the last animation */
1070 if (op->face == blank_face) 1054 if (op->face == blank_face)
1071 {
1072 /* If the last face is blank, remove the ob */ 1055 /* If the last face is blank, remove the ob */
1073 remove_ob (op); /* Should update LOS */ 1056 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 1057 else
1081 { /* The last face was not blank, leave an image */ 1058 { /* The last face was not blank, leave an image */
1082 CLEAR_FLAG (op, FLAG_BLOCKSVIEW); 1059 CLEAR_FLAG (op, FLAG_BLOCKSVIEW);
1083 update_all_los (op->map, op->x, op->y); 1060 update_all_los (op->map, op->x, op->y);
1084 op->move_block = 0; 1061 op->move_block = 0;
1088} 1065}
1089 1066
1090void 1067void
1091scare_creature (object *target, object *hitter) 1068scare_creature (object *target, object *hitter)
1092{ 1069{
1093 object *owner = get_owner (hitter); 1070 object *owner = hitter->owner;
1094 1071
1095 if (!owner) 1072 if (!owner)
1096 owner = hitter; 1073 owner = hitter;
1097 1074
1098 SET_FLAG (target, FLAG_SCARED); 1075 SET_FLAG (target, FLAG_SCARED);
1213 else if (attacknum == ATNR_FEAR) 1190 else if (attacknum == ATNR_FEAR)
1214 scare_creature (op, hitter); 1191 scare_creature (op, hitter);
1215 else if (attacknum == ATNR_CANCELLATION) 1192 else if (attacknum == ATNR_CANCELLATION)
1216 cancellation (op); 1193 cancellation (op);
1217 else if (attacknum == ATNR_DEPLETE) 1194 else if (attacknum == ATNR_DEPLETE)
1218 drain_stat (op); 1195 op->drain_stat ();
1219 else if (attacknum == ATNR_BLIND && !QUERY_FLAG (op, FLAG_UNDEAD) && !QUERY_FLAG (op, FLAG_GENERATOR)) 1196 else if (attacknum == ATNR_BLIND && !QUERY_FLAG (op, FLAG_UNDEAD) && !QUERY_FLAG (op, FLAG_GENERATOR))
1220 blind_player (op, hitter, dam); 1197 blind_player (op, hitter, dam);
1221 } 1198 }
1222 dam = 0; /* These are all effects and don't do real damage */ 1199 dam = 0; /* These are all effects and don't do real damage */
1223 } 1200 }
1262 if (op->type == PLAYER) 1239 if (op->type == PLAYER)
1263 esrv_send_item (op, tmp); 1240 esrv_send_item (op, tmp);
1264 } 1241 }
1265 } 1242 }
1266 if (flag) 1243 if (flag)
1267 fix_player (op); /* Something was corroded */ 1244 op->update_stats (); /* Something was corroded */
1268 } 1245 }
1269 } 1246 }
1270 break; 1247 break;
1271 case ATNR_DRAIN: 1248 case ATNR_DRAIN:
1272 { 1249 {
1302 * Try to credit the owner. We try to display player -> player drain 1279 * Try to credit the owner. We try to display player -> player drain
1303 * attacks, hence all the != PLAYER checks. 1280 * attacks, hence all the != PLAYER checks.
1304 */ 1281 */
1305 if (!op_on_battleground (hitter, NULL, NULL) && !QUERY_FLAG (op, FLAG_WAS_WIZ)) 1282 if (!op_on_battleground (hitter, NULL, NULL) && !QUERY_FLAG (op, FLAG_WAS_WIZ))
1306 { 1283 {
1307 object *owner = get_owner (hitter); 1284 object *owner = hitter->owner;
1308 1285
1309 if (owner && owner != hitter) 1286 if (owner && owner != hitter)
1310 { 1287 {
1311 if (op->type != PLAYER || owner->type != PLAYER) 1288 if (op->type != PLAYER || owner->type != PLAYER)
1312 change_exp (owner, op->stats.exp / (rate * 2), 1289 change_exp (owner, op->stats.exp / (rate * 2),
1328 break; 1305 break;
1329 case ATNR_TURN_UNDEAD: 1306 case ATNR_TURN_UNDEAD:
1330 { 1307 {
1331 if (QUERY_FLAG (op, FLAG_UNDEAD)) 1308 if (QUERY_FLAG (op, FLAG_UNDEAD))
1332 { 1309 {
1333 object *owner = get_owner (hitter) == NULL ? hitter : get_owner (hitter); 1310 object *owner = hitter->owner ? (object *)hitter->owner : hitter;
1334 object *god = find_god (determine_god (owner)); 1311 object *god = find_god (determine_god (owner));
1335 int div = 1; 1312 int div = 1;
1336 1313
1337 /* if undead are not an enemy of your god, you turn them 1314 /* if undead are not an enemy of your god, you turn them
1338 * at half strength */ 1315 * at half strength */
1364 break; 1341 break;
1365 case ATNR_HOLYWORD: 1342 case ATNR_HOLYWORD:
1366 { 1343 {
1367 /* This has already been handled by hit_player, 1344 /* This has already been handled by hit_player,
1368 * no need to check twice -- DAMN */ 1345 * no need to check twice -- DAMN */
1369 1346 object *owner = hitter->owner ? (object *)hitter->owner : hitter;
1370 object *owner = get_owner (hitter) == NULL ? hitter : get_owner (hitter);
1371 1347
1372 /* As with turn undead above, give a bonus on the saving throw */ 1348 /* 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]) 1349 if ((op->level + (op->resist[ATNR_HOLYWORD] / 100)) < owner->level + turn_bonus[owner->stats.Wis])
1374 scare_creature (op, owner); 1350 scare_creature (op, owner);
1375 } 1351 }
1450 if (QUERY_FLAG (op, FLAG_BLOCKSVIEW)) 1426 if (QUERY_FLAG (op, FLAG_BLOCKSVIEW))
1451 update_all_los (op->map, op->x, op->y); /* makes sure los will be recalculated */ 1427 update_all_los (op->map, op->x, op->y); /* makes sure los will be recalculated */
1452 1428
1453 if (op->type == DOOR) 1429 if (op->type == DOOR)
1454 { 1430 {
1455 op->speed = 0.1; 1431 op->set_speed (0.1);
1456 update_ob_speed (op);
1457 op->speed_left = -0.05; 1432 op->speed_left = -0.05;
1458 return maxdam; 1433 return maxdam;
1459 } 1434 }
1435
1460 if (QUERY_FLAG (op, FLAG_FRIENDLY) && op->type != PLAYER) 1436 if (QUERY_FLAG (op, FLAG_FRIENDLY) && op->type != PLAYER)
1461 { 1437 {
1462 remove_friendly_object (op); 1438 remove_friendly_object (op);
1439
1463 if (get_owner (op) != NULL && op->owner->type == PLAYER && op->owner->contr->ranges[range_golem] == op) 1440 if (op->owner && op->owner->type == PLAYER && op->owner->contr->ranges[range_golem] == op)
1464 {
1465 op->owner->contr->ranges[range_golem] = NULL; 1441 op->owner->contr->ranges[range_golem] = 0;
1466 op->owner->contr->golem_count = 0;
1467 }
1468 1442
1469 remove_ob (op); 1443 op->destroy ();
1470 free_object (op);
1471 return maxdam; 1444 return maxdam;
1472 } 1445 }
1473 1446
1474 /* Now lets start dealing with experience we get for killing something */ 1447 /* Now lets start dealing with experience we get for killing something */
1475 1448
1476 owner = get_owner (hitter); 1449 owner = hitter->owner;
1477 if (owner == NULL) 1450 if (!owner)
1478 owner = hitter; 1451 owner = hitter;
1479 1452
1480 /* is the victim (op) standing on battleground? */ 1453 /* is the victim (op) standing on battleground? */
1481 if (op_on_battleground (op, NULL, NULL)) 1454 if (op_on_battleground (op, NULL, NULL))
1482 battleg = 1; 1455 battleg = 1;
1502 char buf[256]; 1475 char buf[256];
1503 1476
1504 tmv = localtime (&t); 1477 tmv = localtime (&t);
1505 strftime (buf, 256, "%a %b %d %H:%M:%S %Y", tmv); 1478 strftime (buf, 256, "%a %b %d %H:%M:%S %Y", tmv);
1506 1479
1507 LOG (llevInfo, "%s PLAYER_KILL_PLAYER: %s (%s) killed %s\n", buf, &owner->name, owner->contr->socket.host, query_name (op)); 1480 LOG (llevInfo, "%s PLAYER_KILL_PLAYER: %s (%s) killed %s\n", buf, &owner->name, owner->contr->ns->host, query_name (op));
1508 } 1481 }
1509 1482
1510 /* try to filter some things out - basically, if you are 1483 /* try to filter some things out - basically, if you are
1511 * killing a level 1 creature and your level 20, you 1484 * killing a level 1 creature and your level 20, you
1512 * probably don't want to see that. 1485 * probably don't want to see that.
1513 */ 1486 */
1514 if (owner->level < op->level * 2 || op->stats.exp > 1000) 1487 if (owner->level < op->level * 2 || op->stats.exp > 1000)
1515 { 1488 {
1516 if (owner != hitter) 1489 if (owner != hitter)
1517 {
1518 new_draw_info_format (NDI_BLACK, 0, owner, "You killed %s with %s.", query_name (op), query_name (hitter)); 1490 new_draw_info_format (NDI_BLACK, 0, owner, "You killed %s with %s.", query_name (op), query_name (hitter));
1519 }
1520 else 1491 else
1521 {
1522 new_draw_info_format (NDI_BLACK, 0, owner, "You killed %s.", query_name (op)); 1492 new_draw_info_format (NDI_BLACK, 0, owner, "You killed %s.", query_name (op));
1523 } 1493
1524 /* Only play sounds for melee kills */ 1494 /* Only play sounds for melee kills */
1525 if (hitter->type == PLAYER) 1495 if (hitter->type == PLAYER)
1526 play_sound_map (owner->map, owner->x, owner->y, SOUND_PLAYER_KILLS); 1496 play_sound_map (owner->map, owner->x, owner->y, SOUND_PLAYER_KILLS);
1527 } 1497 }
1528 1498
1533 * player that the object belonged to - so if you killed another player 1503 * player that the object belonged to - so if you killed another player
1534 * with spells, pets, whatever, there was no penalty. 1504 * with spells, pets, whatever, there was no penalty.
1535 * Changed to make luck penalty configurable in settings. 1505 * Changed to make luck penalty configurable in settings.
1536 */ 1506 */
1537 if (op->type == PLAYER && owner != op && !battleg) 1507 if (op->type == PLAYER && owner != op && !battleg)
1538 change_luck (owner, -settings.pk_luck_penalty); 1508 owner->change_luck (-settings.pk_luck_penalty);
1539 1509
1540 /* This code below deals with finding the appropriate skill 1510 /* This code below deals with finding the appropriate skill
1541 * to credit exp to. This is a bit problematic - we should 1511 * to credit exp to. This is a bit problematic - we should
1542 * probably never really have to look at current_weapon->skill 1512 * probably never really have to look at current_weapon->skill
1543 */ 1513 */
1544 skill = NULL; 1514 skill = 0;
1515
1545 if (hitter->skill && hitter->type != PLAYER) 1516 if (hitter->skill && hitter->type != PLAYER)
1546 skill = hitter->skill; 1517 skill = hitter->skill;
1547 else if (owner->chosen_skill) 1518 else if (owner->chosen_skill)
1548 { 1519 {
1549 skill = owner->chosen_skill->skill; 1520 skill = owner->chosen_skill->skill;
1568 break; 1539 break;
1569 } 1540 }
1570 } 1541 }
1571 } /* Was it a player that hit somethign */ 1542 } /* Was it a player that hit somethign */
1572 else 1543 else
1573 {
1574 skill = NULL; 1544 skill = 0;
1575 }
1576 1545
1577 /* Pet (or spell) killed something. */ 1546 /* Pet (or spell) killed something. */
1578 if (owner != hitter) 1547 if (owner != hitter)
1579 {
1580 (void) sprintf (buf, "%s killed %s with %s%s%s.", &owner->name, 1548 sprintf (buf, "%s killed %s with %s%s%s.", &owner->name,
1581 query_name (op), query_name (hitter), battleg ? " (duel)" : "", pk ? " (pk)" : ""); 1549 query_name (op), query_name (hitter), battleg ? " (duel)" : "", pk ? " (pk)" : "");
1582 }
1583 else 1550 else
1584 {
1585 (void) sprintf (buf, "%s killed %s%s%s%s.", &hitter->name, &op->name, 1551 sprintf (buf, "%s killed %s%s%s%s.", &hitter->name, &op->name,
1586 (QUERY_FLAG (hitter, FLAG_MONSTER)) || hitter->type == PLAYER ? 1552 (QUERY_FLAG (hitter, FLAG_MONSTER)) || hitter->type == PLAYER ?
1587 " in hand to hand combat" : "", battleg ? " (duel)" : "", pk ? " (pk)" : ""); 1553 " in hand to hand combat" : "", battleg ? " (duel)" : "", pk ? " (pk)" : "");
1588 } 1554
1589 /* These may have been set in the player code section above */ 1555 /* These may have been set in the player code section above */
1590 if (!skop) 1556 if (!skop)
1591 skop = hitter->chosen_skill; 1557 skop = hitter->chosen_skill;
1558
1592 if (!skill && skop) 1559 if (!skill && skop)
1593 skill = skop->skill; 1560 skill = skop->skill;
1594 1561
1595 new_draw_info (NDI_ALL, op->type == PLAYER ? 1 : 10, NULL, buf); 1562 new_draw_info (NDI_ALL, op->type == PLAYER ? 1 : 10, NULL, buf);
1596 1563
1597
1598 /* If you didn't kill yourself, and your not the wizard */ 1564 /* If you didn't kill yourself, and your not the wizard */
1599 if (owner != op && !QUERY_FLAG (op, FLAG_WAS_WIZ)) 1565 if (owner != op && !QUERY_FLAG (op, FLAG_WAS_WIZ))
1600 { 1566 {
1601 int exp; 1567 int exp;
1602 1568
1603 /* Really don't give much experience for killing other players */ 1569 /* Really don't give much experience for killing other players */
1604 // schmorp: temporary? reduce the amount of exp gained for pking enourmously 1570 // schmorp: temporarily? reduce the amount of exp gained for pking enourmously
1605 if (op->type == PLAYER) 1571 if (op->type == PLAYER)
1606 { 1572 {
1607 if (battleg) 1573 if (battleg)
1608 { 1574 {
1609 new_draw_info (NDI_UNIQUE, 0, owner, "Your foe has fallen!"); 1575 new_draw_info (NDI_UNIQUE, 0, owner, "Your foe has fallen!");
1627 1593
1628 if (!settings.simple_exp) 1594 if (!settings.simple_exp)
1629 exp = exp / 2; 1595 exp = exp / 2;
1630 1596
1631 if (owner->type != PLAYER || owner->contr->party == NULL) 1597 if (owner->type != PLAYER || owner->contr->party == NULL)
1632 {
1633 change_exp (owner, exp, skill, 0); 1598 change_exp (owner, exp, skill, 0);
1634 }
1635 else 1599 else
1636 { 1600 {
1637 int shares = 0, count = 0; 1601 int shares = 0, count = 0;
1638
1639 player *pl; 1602 player *pl;
1640
1641 partylist *party = owner->contr->party; 1603 partylist *party = owner->contr->party;
1642 1604
1643#ifdef PARTY_KILL_LOG
1644 add_kill_to_party (party, query_name (owner), query_name (op), exp); 1605 add_kill_to_party (party, query_name (owner), query_name (op), exp);
1645#endif 1606
1646 for (pl = first_player; pl != NULL; pl = pl->next) 1607 for_all_players (pl)
1647 {
1648 if (party && pl->ob->contr->party == party && on_same_map (pl->ob, owner)) 1608 if (party && pl->ob->contr->party == party && on_same_map (pl->ob, owner))
1649 { 1609 {
1650 count++; 1610 count++;
1651 shares += (pl->ob->level + 4); 1611 shares += (pl->ob->level + 4);
1652 } 1612 }
1653 } 1613
1654 if (count == 1 || shares > exp) 1614 if (count == 1 || shares > exp || !shares)
1655 change_exp (owner, exp, skill, SK_EXP_TOTAL); 1615 change_exp (owner, exp, skill, SK_EXP_TOTAL);
1656 else 1616 else
1657 { 1617 {
1658 int share = exp / shares, given = 0, nexp; 1618 int share = exp / shares, given = 0, nexp;
1659 1619
1660 for (pl = first_player; pl != NULL; pl = pl->next) 1620 for_all_players (pl)
1661 {
1662 if (party && pl->ob->contr->party == party && on_same_map (pl->ob, owner)) 1621 if (party && pl->ob->contr->party == party && on_same_map (pl->ob, owner))
1663 { 1622 {
1664 nexp = (pl->ob->level + 4) * share; 1623 nexp = (pl->ob->level + 4) * share;
1665 change_exp (pl->ob, nexp, skill, SK_EXP_TOTAL); 1624 change_exp (pl->ob, nexp, skill, SK_EXP_TOTAL);
1666 given += nexp; 1625 given += nexp;
1667 } 1626 }
1668 } 1627
1669 exp -= given; 1628 exp -= given;
1670 /* give any remainder to the player */ 1629 /* give any remainder to the player */
1671 change_exp (owner, exp, skill, SK_EXP_ADD_SKILL); 1630 change_exp (owner, exp, skill, SK_EXP_ADD_SKILL);
1672 } 1631 }
1673 } /* else part of a party */ 1632 } /* else part of a party */
1674
1675 } /* end if person didn't kill himself */ 1633 } /* end if person didn't kill himself */
1676 1634
1677 if (op->type != PLAYER) 1635 if (op->type != PLAYER)
1678 { 1636 {
1679 if (QUERY_FLAG (op, FLAG_FRIENDLY)) 1637 if (QUERY_FLAG (op, FLAG_FRIENDLY))
1680 { 1638 {
1681 object *owner1 = get_owner (op); 1639 object *owner1 = op->owner;
1682 1640
1683 if (owner1 != NULL && owner1->type == PLAYER) 1641 if (owner1 && owner1->type == PLAYER)
1684 { 1642 {
1685 play_sound_player_only (owner1->contr, SOUND_PET_IS_KILLED, 0, 0); 1643 play_sound_player_only (owner1->contr, SOUND_PET_IS_KILLED, 0, 0);
1686 /* Maybe we should include the owner that killed this, maybe not */ 1644 /* 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); 1645 new_draw_info_format (NDI_UNIQUE, 0, owner1, "Your pet, the %s, is killed by %s.", &op->name, &hitter->name);
1688 } 1646 }
1647
1689 remove_friendly_object (op); 1648 remove_friendly_object (op);
1690 } 1649 }
1691 remove_ob (op); 1650
1692 free_object (op); 1651 op->destroy ();
1693 } 1652 }
1694 /* Player has been killed! */
1695 else 1653 else
1696 { 1654 {
1655 /* Player has been killed! */
1697 if (owner->type == PLAYER) 1656 if (owner->type == PLAYER)
1698 {
1699 snprintf (op->contr->killer, BIG_NAME, "%s the %s", &owner->name, owner->contr->title); 1657 snprintf (op->contr->killer, sizeof (op->contr->killer), "%s the %s", &owner->name, owner->contr->title);
1700 }
1701 else 1658 else
1702 {
1703 strncpy (op->contr->killer, hitter->name, BIG_NAME); 1659 assign (op->contr->killer, hitter->name);
1704 op->contr->killer[BIG_NAME - 1] = '\0';
1705 }
1706 } 1660 }
1661
1707 /* This was return -1 - that doesn't seem correct - if we return -1, process 1662 /* This was return -1 - that doesn't seem correct - if we return -1, process
1708 * continues in the calling function. 1663 * continues in the calling function.
1709 */ 1664 */
1710 return maxdam; 1665 return maxdam;
1711} 1666}
1731 return 0; 1686 return 0;
1732 1687
1733 if (hitter->type == PLAYER && hitter->contr->peaceful == 1) 1688 if (hitter->type == PLAYER && hitter->contr->peaceful == 1)
1734 return 1; 1689 return 1;
1735 1690
1736 if ((owner = get_owner (hitter)) != NULL) 1691 if ((owner = hitter->owner) != NULL)
1737 { 1692 {
1738 if (owner->type == PLAYER && owner->contr->peaceful == 1) 1693 if (owner->type == PLAYER && owner->contr->peaceful == 1)
1739 friendlyfire = 2; 1694 friendlyfire = 2;
1740 } 1695 }
1741 1696
1762{ 1717{
1763 int maxdam = 0, ndam = 0, attacktype = 1, magic = (type & AT_MAGIC); 1718 int maxdam = 0, ndam = 0, attacktype = 1, magic = (type & AT_MAGIC);
1764 int maxattacktype, attacknum; 1719 int maxattacktype, attacknum;
1765 int body_attack = op && op->head; /* Did we hit op's head? */ 1720 int body_attack = op && op->head; /* Did we hit op's head? */
1766 int simple_attack; 1721 int simple_attack;
1767 tag_t op_tag, hitter_tag;
1768 int rtn_kill = 0; 1722 int rtn_kill = 0;
1769 int friendlyfire; 1723 int friendlyfire;
1770 1724
1771 if (get_attack_mode (&op, &hitter, &simple_attack)) 1725 if (get_attack_mode (&op, &hitter, &simple_attack))
1772 return 0; 1726 return 0;
1776 return 0; 1730 return 0;
1777 1731
1778#ifdef PROHIBIT_PLAYERKILL 1732#ifdef PROHIBIT_PLAYERKILL
1779 if (op->type == PLAYER) 1733 if (op->type == PLAYER)
1780 { 1734 {
1781 object *owner = get_owner (hitter); 1735 object *owner = hitter->owner;
1782 1736
1783 if (!owner) 1737 if (!owner)
1784 owner = hitter; 1738 owner = hitter;
1739
1785 if (owner->type == PLAYER && (!op_on_battleground (op, 0, 0) && (op->contr->peaceful || owner->contr->peaceful)) && op != owner) 1740 if (owner->type == PLAYER && (!op_on_battleground (op, 0, 0) && (op->contr->peaceful || owner->contr->peaceful)) && op != owner)
1786 {
1787 return 0; 1741 return 0;
1788 }
1789 } 1742 }
1790#endif 1743#endif
1791
1792 op_tag = op->count;
1793 hitter_tag = hitter->count;
1794 1744
1795 if (body_attack) 1745 if (body_attack)
1796 { 1746 {
1797 /* slow and paralyze must hit the head. But we don't want to just 1747 /* 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 1748 * return - we still need to process other attacks the spell still
1804 * attack so we don't cancel out things like magic bullet. 1754 * attack so we don't cancel out things like magic bullet.
1805 */ 1755 */
1806 if (type & (AT_PARALYZE | AT_SLOW)) 1756 if (type & (AT_PARALYZE | AT_SLOW))
1807 { 1757 {
1808 type &= ~(AT_PARALYZE | AT_SLOW); 1758 type &= ~(AT_PARALYZE | AT_SLOW);
1759
1809 if (!type || type == AT_MAGIC) 1760 if (!type || type == AT_MAGIC)
1810 return 0; 1761 return 0;
1811 } 1762 }
1812 } 1763 }
1813 1764
1817 1768
1818 for (tmp = op->inv; tmp != NULL; tmp = tmp->below) 1769 for (tmp = op->inv; tmp != NULL; tmp = tmp->below)
1819 if (tmp->type == RUNE || tmp->type == TRAP) 1770 if (tmp->type == RUNE || tmp->type == TRAP)
1820 { 1771 {
1821 spring_trap (tmp, hitter); 1772 spring_trap (tmp, hitter);
1773
1822 if (was_destroyed (hitter, hitter_tag) || was_destroyed (op, op_tag) || abort_attack (op, hitter, simple_attack)) 1774 if (hitter->destroyed () || op->destroyed () || abort_attack (op, hitter, simple_attack))
1823 return 0; 1775 return 0;
1776
1824 break; 1777 break;
1825 } 1778 }
1826 } 1779 }
1827 1780
1828 if (!QUERY_FLAG (op, FLAG_ALIVE) || op->stats.hp < 0) 1781 if (!QUERY_FLAG (op, FLAG_ALIVE) || op->stats.hp < 0)
1829 { 1782 {
1830 /* FIXME: If a player is killed by a rune in a door, the 1783 /* 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. 1784 * destroyed() check above doesn't return, and might get here.
1832 */ 1785 */
1833 LOG (llevDebug, "victim (arch %s, name %s) already dead in " "hit_player()\n", &op->arch->name, &op->name); 1786 LOG (llevDebug, "victim (arch %s, name %s) already dead in " "hit_player()\n", &op->arch->name, &op->name);
1834 return 0; 1787 return 0;
1835 } 1788 }
1836 1789
1874 (hitter->title != NULL 1827 (hitter->title != NULL
1875 && (god = find_god (determine_god (hitter))) != NULL && god->race != NULL && strstr (god->race, undead_name) != NULL))) 1828 && (god = find_god (determine_god (hitter))) != NULL && god->race != NULL && strstr (god->race, undead_name) != NULL)))
1876 return 0; 1829 return 0;
1877 } 1830 }
1878 1831
1879 maxattacktype = type; /* initialize this to something */ 1832 maxattacktype = type; /* initialise this to something */
1880 for (attacknum = 0; attacknum < NROFATTACKS; attacknum++, attacktype = 1 << attacknum) 1833 for (attacknum = 0; attacknum < NROFATTACKS; attacknum++, attacktype = 1 << attacknum)
1881 { 1834 {
1882 /* Magic isn't really a true attack type - it gets combined with other 1835 /* 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 1836 * attack types. As such, skip it over. However, if magic is
1884 * the only attacktype in the group, then still attack with it 1837 * the only attacktype in the group, then still attack with it
1945 1898
1946#ifdef ATTACK_DEBUG 1899#ifdef ATTACK_DEBUG
1947 LOG (llevDebug, "Attacktype %d did %d damage\n", type, maxdam); 1900 LOG (llevDebug, "Attacktype %d did %d damage\n", type, maxdam);
1948#endif 1901#endif
1949 1902
1950 if (get_owner (hitter)) 1903 if (hitter->owner)
1951 op->enemy = hitter->owner; 1904 op->enemy = hitter->owner;
1952 else if (QUERY_FLAG (hitter, FLAG_ALIVE)) 1905 else if (QUERY_FLAG (hitter, FLAG_ALIVE))
1953 op->enemy = hitter; 1906 op->enemy = hitter;
1954 1907
1955 if (QUERY_FLAG (op, FLAG_UNAGGRESSIVE) && op->type != PLAYER) 1908 if (QUERY_FLAG (op, FLAG_UNAGGRESSIVE) && op->type != PLAYER)
1980 1933
1981 if (QUERY_FLAG (op, FLAG_TEAR_DOWN)) 1934 if (QUERY_FLAG (op, FLAG_TEAR_DOWN))
1982 { 1935 {
1983 if (maxdam) 1936 if (maxdam)
1984 tear_down_wall (op); 1937 tear_down_wall (op);
1938
1985 return maxdam; /* nothing more to do for wall */ 1939 return maxdam; /* nothing more to do for wall */
1986 } 1940 }
1987 1941
1988 /* See if the creature has been killed */ 1942 /* See if the creature has been killed */
1989 rtn_kill = kill_object (op, maxdam, hitter, type); 1943 rtn_kill = kill_object (op, maxdam, hitter, type);
1997 */ 1951 */
1998 if (QUERY_FLAG (hitter, FLAG_ONE_HIT)) 1952 if (QUERY_FLAG (hitter, FLAG_ONE_HIT))
1999 { 1953 {
2000 if (QUERY_FLAG (hitter, FLAG_FRIENDLY)) 1954 if (QUERY_FLAG (hitter, FLAG_FRIENDLY))
2001 remove_friendly_object (hitter); 1955 remove_friendly_object (hitter);
2002 remove_ob (hitter); 1956
2003 free_object (hitter); 1957 hitter->destroy ();
2004 } 1958 }
2005 /* Lets handle creatures that are splitting now */ 1959 /* Lets handle creatures that are splitting now */
2006 else if (type & AT_PHYSICAL && !QUERY_FLAG (op, FLAG_FREED) && QUERY_FLAG (op, FLAG_SPLITTING)) 1960 else if (type & AT_PHYSICAL && !QUERY_FLAG (op, FLAG_FREED) && QUERY_FLAG (op, FLAG_SPLITTING))
2007 { 1961 {
2008 int i; 1962 int i;
2009 int friendly = QUERY_FLAG (op, FLAG_FRIENDLY); 1963 int friendly = QUERY_FLAG (op, FLAG_FRIENDLY);
2010 int unaggressive = QUERY_FLAG (op, FLAG_UNAGGRESSIVE); 1964 int unaggressive = QUERY_FLAG (op, FLAG_UNAGGRESSIVE);
2011 object *owner = get_owner (op); 1965 object *owner = op->owner;
2012 1966
2013 if (!op->other_arch) 1967 if (!op->other_arch)
2014 { 1968 {
2015 LOG (llevError, "SPLITTING without other_arch error.\n"); 1969 LOG (llevError, "SPLITTING without other_arch error.\n");
2016 return maxdam; 1970 return maxdam;
2017 } 1971 }
1972
2018 remove_ob (op); 1973 op->remove ();
1974
2019 for (i = 0; i < NROFNEWOBJS (op); i++) 1975 for (i = 0; i < NROFNEWOBJS (op); i++)
2020 { /* This doesn't handle op->more yet */ 1976 { /* This doesn't handle op->more yet */
2021 object *tmp = arch_to_object (op->other_arch); 1977 object *tmp = arch_to_object (op->other_arch);
2022 int j; 1978 int j;
2023 1979
2024 tmp->stats.hp = op->stats.hp; 1980 tmp->stats.hp = op->stats.hp;
1981
2025 if (friendly) 1982 if (friendly)
2026 { 1983 {
2027 SET_FLAG (tmp, FLAG_FRIENDLY); 1984 SET_FLAG (tmp, FLAG_FRIENDLY);
2028 add_friendly_object (tmp); 1985 add_friendly_object (tmp);
2029 tmp->attack_movement = PETMOVE; 1986 tmp->attack_movement = PETMOVE;
2030 if (owner != NULL) 1987 if (owner != NULL)
2031 set_owner (tmp, owner); 1988 tmp->set_owner (owner);
2032 } 1989 }
1990
2033 if (unaggressive) 1991 if (unaggressive)
2034 SET_FLAG (tmp, FLAG_UNAGGRESSIVE); 1992 SET_FLAG (tmp, FLAG_UNAGGRESSIVE);
1993
2035 j = find_first_free_spot (tmp, op->map, op->x, op->y); 1994 j = find_first_free_spot (tmp, op->map, op->x, op->y);
1995
2036 if (j == -1) /* No spot to put this monster */ 1996 if (j == -1) /* No spot to put this monster */
2037 free_object (tmp); 1997 tmp->destroy ();
2038 else 1998 else
2039 { 1999 {
2040 tmp->x = op->x + freearr_x[j], tmp->y = op->y + freearr_y[j]; 2000 tmp->x = op->x + freearr_x[j], tmp->y = op->y + freearr_y[j];
2041 insert_ob_in_map (tmp, op->map, NULL, 0); 2001 insert_ob_in_map (tmp, op->map, NULL, 0);
2042 } 2002 }
2043 } 2003 }
2044 if (friendly) 2004
2045 remove_friendly_object (op); 2005 op->destroy ();
2046 free_object (op);
2047 } 2006 }
2048 else if (type & AT_DRAIN && hitter->type == GRIMREAPER && hitter->value++ > 10) 2007 else if (type & AT_DRAIN && hitter->type == GRIMREAPER && hitter->value++ > 10)
2049 { 2008 hitter->destroy ();
2050 remove_ob (hitter); 2009
2051 free_object (hitter);
2052 }
2053 return maxdam; 2010 return maxdam;
2054} 2011}
2055 2012
2056 2013
2057void 2014void
2058poison_player (object *op, object *hitter, int dam) 2015poison_player (object *op, object *hitter, int dam)
2059{ 2016{
2060 archetype *at = find_archetype ("poisoning"); 2017 archetype *at = archetype::find ("poisoning");
2061 object *tmp = present_arch_in_ob (at, op); 2018 object *tmp = present_arch_in_ob (at, op);
2062 2019
2063 if (tmp == NULL) 2020 if (tmp == NULL)
2064 { 2021 {
2065 if ((tmp = arch_to_object (at)) == NULL) 2022 if ((tmp = arch_to_object (at)) == NULL)
2078 if (QUERY_FLAG (hitter, FLAG_ALIVE)) 2035 if (QUERY_FLAG (hitter, FLAG_ALIVE))
2079 tmp->stats.dam += hitter->level / 2; 2036 tmp->stats.dam += hitter->level / 2;
2080 else 2037 else
2081 tmp->stats.dam = dam; 2038 tmp->stats.dam = dam;
2082 2039
2083 copy_owner (tmp, hitter); /* so we get credit for poisoning kills */ 2040 tmp->set_owner (hitter); /* so we get credit for poisoning kills */
2084 if (hitter->skill && hitter->skill != tmp->skill) 2041 if (hitter->skill && hitter->skill != tmp->skill)
2085 { 2042 {
2086 tmp->skill = hitter->skill; 2043 tmp->skill = hitter->skill;
2087 } 2044 }
2088 2045
2094 tmp->stats.Con = MAX (-(dam / 4 + 1), -10); 2051 tmp->stats.Con = MAX (-(dam / 4 + 1), -10);
2095 tmp->stats.Str = MAX (-(dam / 3 + 2), -10); 2052 tmp->stats.Str = MAX (-(dam / 3 + 2), -10);
2096 tmp->stats.Dex = MAX (-(dam / 6 + 1), -10); 2053 tmp->stats.Dex = MAX (-(dam / 6 + 1), -10);
2097 tmp->stats.Int = MAX (-dam / 7, -10); 2054 tmp->stats.Int = MAX (-dam / 7, -10);
2098 SET_FLAG (tmp, FLAG_APPLIED); 2055 SET_FLAG (tmp, FLAG_APPLIED);
2099 fix_player (op); 2056 op->update_stats ();
2100 new_draw_info (NDI_UNIQUE, 0, op, "You suddenly feel very ill."); 2057 new_draw_info (NDI_UNIQUE, 0, op, "You suddenly feel very ill.");
2101 } 2058 }
2102 if (hitter->type == PLAYER) 2059 if (hitter->type == PLAYER)
2103 new_draw_info_format (NDI_UNIQUE, 0, hitter, "You poison %s.", &op->name); 2060 new_draw_info_format (NDI_UNIQUE, 0, hitter, "You poison %s.", &op->name);
2104 else if (get_owner (hitter) != NULL && hitter->owner->type == PLAYER) 2061 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); 2062 new_draw_info_format (NDI_UNIQUE, 0, hitter->owner, "Your %s poisons %s.", &hitter->name, &op->name);
2106 } 2063 }
2107 tmp->speed_left = 0; 2064 tmp->speed_left = 0;
2108 } 2065 }
2109 else 2066 else
2111} 2068}
2112 2069
2113void 2070void
2114slow_player (object *op, object *hitter, int dam) 2071slow_player (object *op, object *hitter, int dam)
2115{ 2072{
2116 archetype *at = find_archetype ("slowness"); 2073 archetype *at = archetype::find ("slowness");
2117 object *tmp; 2074 object *tmp;
2118 2075
2119 if (at == NULL) 2076 if (at == NULL)
2120 { 2077 {
2121 LOG (llevError, "Can't find slowness archetype.\n"); 2078 LOG (llevError, "Can't find slowness archetype.\n");
2128 } 2085 }
2129 else 2086 else
2130 tmp->stats.food++; 2087 tmp->stats.food++;
2131 SET_FLAG (tmp, FLAG_APPLIED); 2088 SET_FLAG (tmp, FLAG_APPLIED);
2132 tmp->speed_left = 0; 2089 tmp->speed_left = 0;
2133 fix_player (op); 2090 op->update_stats ();
2134} 2091}
2135 2092
2136void 2093void
2137confuse_player (object *op, object *hitter, int dam) 2094confuse_player (object *op, object *hitter, int dam)
2138{ 2095{
2182 */ 2139 */
2183 tmp->speed = tmp->speed * (100.0 - (float) op->resist[ATNR_BLIND]) / 100; 2140 tmp->speed = tmp->speed * (100.0 - (float) op->resist[ATNR_BLIND]) / 100;
2184 2141
2185 tmp = insert_ob_in_ob (tmp, op); 2142 tmp = insert_ob_in_ob (tmp, op);
2186 change_abil (op, tmp); /* Mostly to display any messages */ 2143 change_abil (op, tmp); /* Mostly to display any messages */
2187 fix_player (op); /* This takes care of some other stuff */ 2144 op->update_stats (); /* This takes care of some other stuff */
2188 2145
2189 if (hitter->owner) 2146 if (hitter->owner)
2190 owner = get_owner (hitter); 2147 owner = hitter->owner;
2191 else 2148 else
2192 owner = hitter; 2149 owner = hitter;
2193 2150
2194 new_draw_info_format (NDI_UNIQUE, 0, owner, "Your attack blinds %s!", query_name (op)); 2151 new_draw_info_format (NDI_UNIQUE, 0, owner, "Your attack blinds %s!", query_name (op));
2195 } 2152 }
2341 } 2298 }
2342 2299
2343 /* aimed missiles use the owning object's sight */ 2300 /* aimed missiles use the owning object's sight */
2344 if (is_aimed_missile (hitter)) 2301 if (is_aimed_missile (hitter))
2345 { 2302 {
2346 if ((attacker = get_owner (hitter)) == NULL) 2303 if ((attacker = hitter->owner) == NULL)
2347 attacker = hitter; 2304 attacker = hitter;
2348 /* A player who saves but hasn't quit still could have objects 2305 /* A player who saves but hasn't quit still could have objects
2349 * owned by him - need to handle that case to avoid crashes. 2306 * owned by him - need to handle that case to avoid crashes.
2350 */ 2307 */
2351 if (QUERY_FLAG (attacker, FLAG_REMOVED)) 2308 if (QUERY_FLAG (attacker, FLAG_REMOVED))

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines