ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/server/time.C
(Generate patch)

Comparing deliantra/server/server/time.C (file contents):
Revision 1.10 by root, Mon Sep 11 20:26:41 2006 UTC vs.
Revision 1.35 by root, Tue Jan 9 01:28:32 2007 UTC

1
2/* 1/*
3 * static char *rcsid_time_c = 2 * CrossFire, A Multiplayer game
4 * "$Id: time.C,v 1.10 2006/09/11 20:26:41 root Exp $"; 3 *
4 * Copyright (C) 2005, 2006, 2007 Marc Lehmann & Crossfire+ Development Team
5 * Copyright (C) 2002 Mark Wedel & Crossfire Development Team
6 * Copyright (C) 1992 Frank Tore Johansen
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 *
22 * The authors can be reached via e-mail at <crossfire@schmorp.de>
5 */ 23 */
6
7/*
8 CrossFire, A Multiplayer game for X-windows
9
10 Copyright (C) 2002 Mark Wedel & Crossfire Development Team
11 Copyright (C) 1992 Frank Tore Johansen
12
13 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
15 the Free Software Foundation; either version 2 of the License, or
16 (at your option) any later version.
17
18 This program is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 GNU General Public License for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software
25 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26
27 The authors can be reached via e-mail at crossfire-devel@real-time.com
28*/
29 24
30/* 25/*
31 * Routines that is executed from objects based on their speed have been 26 * Routines that is executed from objects based on their speed have been
32 * collected in this file. 27 * collected in this file.
33 */ 28 */
34
35#include <global.h> 29#include <global.h>
36#include <spells.h> 30#include <spells.h>
37#ifndef __CEXTRACT__
38# include <sproto.h> 31#include <sproto.h>
39#endif
40 32
41/* The following removes doors. The functions check to see if similar 33/* The following removes doors. The functions check to see if similar
42 * doors are next to the one that is being removed, and if so, set it 34 * doors are next to the one that is being removed, and if so, set it
43 * so those will be removed shortly (in a cascade like fashion.) 35 * so those will be removed shortly (in a cascade like fashion.)
44 */ 36 */
45
46void 37void
47remove_door (object *op) 38remove_door (object *op)
48{ 39{
49 int i; 40 int i;
50 object *tmp; 41 object *tmp;
51 42
52 for (i = 1; i < 9; i += 2) 43 for (i = 1; i < 9; i += 2)
53 if ((tmp = present (DOOR, op->map, op->x + freearr_x[i], op->y + freearr_y[i])) != NULL) 44 if ((tmp = present (DOOR, op->map, op->x + freearr_x[i], op->y + freearr_y[i])) != NULL)
54 { 45 {
55 tmp->speed = 0.1; 46 tmp->set_speed (0.1);
56 update_ob_speed (tmp);
57 tmp->speed_left = -0.2; 47 tmp->speed_left = -0.2;
58 } 48 }
59 49
60 if (op->other_arch) 50 if (op->other_arch)
61 { 51 {
64 tmp->y = op->y; 54 tmp->y = op->y;
65 tmp->map = op->map; 55 tmp->map = op->map;
66 tmp->level = op->level; 56 tmp->level = op->level;
67 insert_ob_in_map (tmp, op->map, op, 0); 57 insert_ob_in_map (tmp, op->map, op, 0);
68 } 58 }
69 remove_ob (op); 59
70 free_object (op); 60 op->destroy ();
71} 61}
72 62
73void 63void
74remove_door2 (object *op) 64remove_door2 (object *op)
75{ 65{
79 for (i = 1; i < 9; i += 2) 69 for (i = 1; i < 9; i += 2)
80 { 70 {
81 tmp = present (LOCKED_DOOR, op->map, op->x + freearr_x[i], op->y + freearr_y[i]); 71 tmp = present (LOCKED_DOOR, op->map, op->x + freearr_x[i], op->y + freearr_y[i]);
82 if (tmp && tmp->slaying == op->slaying) 72 if (tmp && tmp->slaying == op->slaying)
83 { /* same key both doors */ 73 { /* same key both doors */
84 tmp->speed = 0.1; 74 tmp->set_speed (0.1);
85 update_ob_speed (tmp);
86 tmp->speed_left = -0.2; 75 tmp->speed_left = -0.2;
87 } 76 }
88 } 77 }
78
89 if (op->other_arch) 79 if (op->other_arch)
90 { 80 {
91 tmp = arch_to_object (op->other_arch); 81 tmp = arch_to_object (op->other_arch);
92 tmp->x = op->x; 82 tmp->x = op->x;
93 tmp->y = op->y; 83 tmp->y = op->y;
94 tmp->map = op->map; 84 tmp->map = op->map;
95 tmp->level = op->level; 85 tmp->level = op->level;
96 insert_ob_in_map (tmp, op->map, op, 0); 86 insert_ob_in_map (tmp, op->map, op, 0);
97 } 87 }
98 remove_ob (op); 88
99 free_object (op); 89 op->destroy ();
100} 90}
101 91
102/* Will generate a monster according to content 92/* Will generate a monster according to content
103 * of generator. 93 * of generator.
104 */ 94 */
139 if (rndm (0, 9)) 129 if (rndm (0, 9))
140 generate_artifact (head, gen->map->difficulty); 130 generate_artifact (head, gen->map->difficulty);
141 insert_ob_in_map_at (head, gen->map, gen, 0, gen->x + freearr_x[i], gen->y + freearr_y[i]); 131 insert_ob_in_map_at (head, gen->map, gen, 0, gen->x + freearr_x[i], gen->y + freearr_y[i]);
142 if (QUERY_FLAG (head, FLAG_FREED)) 132 if (QUERY_FLAG (head, FLAG_FREED))
143 return; 133 return;
144 if (HAS_RANDOM_ITEMS (head)) 134 if (head->has_random_items ())
145 create_treasure (head->randomitems, head, GT_APPLY, gen->map->difficulty, 0); 135 create_treasure (head->randomitems, head, GT_APPLY, gen->map->difficulty, 0);
146} 136}
147 137
148void 138void
149generate_monster_arch (object *gen) 139generate_monster_arch (object *gen)
150{ 140{
151 int i; 141 int i;
152 object *op, *head = NULL, *prev = NULL; 142 object *op, *head = NULL, *prev = NULL;
153 archetype *at = gen->other_arch; 143 archetype *at = gen->other_arch;
154 144
155 if (gen->other_arch == NULL) 145 if (!gen->other_arch)
156 {
157 //LOG(llevError,"Generator without other_arch: %s\n",gen->name);
158 return; 146 return;
159 } 147
160 /* Code below assumes the generator is on a map, as it tries 148 /* Code below assumes the generator is on a map, as it tries
161 * to place the monster on the map. So if the generator 149 * to place the monster on the map. So if the generator
162 * isn't on a map, complain and exit. 150 * isn't on a map, complain and exit.
163 */ 151 */
164 if (gen->map == NULL) 152 if (!gen->map)
165 {
166 //LOG(llevError,"Generator (%s) not on a map?\n", gen->name);
167 return; 153 return;
168 } 154
169 i = find_free_spot (&at->clone, gen->map, gen->x, gen->y, 1, 9); 155 i = find_free_spot (&at->clone, gen->map, gen->x, gen->y, 1, 9);
170 if (i == -1) 156 if (i == -1)
171 return; 157 return;
158
172 while (at != NULL) 159 while (at)
173 { 160 {
174 op = arch_to_object (at); 161 op = arch_to_object (at);
175 op->x = gen->x + freearr_x[i] + at->clone.x; 162 op->x = gen->x + freearr_x[i] + at->clone.x;
176 op->y = gen->y + freearr_y[i] + at->clone.y; 163 op->y = gen->y + freearr_y[i] + at->clone.y;
177 164
178 if (head != NULL) 165 if (head)
179 op->head = head, prev->more = op; 166 op->head = head, prev->more = op;
180 167
181 if (rndm (0, 9)) 168 if (rndm (0, 9))
182 generate_artifact (op, gen->map->difficulty); 169 generate_artifact (op, gen->map->difficulty);
170
183 insert_ob_in_map (op, gen->map, gen, 0); 171 insert_ob_in_map (op, gen->map, gen, 0);
184 if (QUERY_FLAG (op, FLAG_FREED)) 172 if (QUERY_FLAG (op, FLAG_FREED))
185 return; 173 return;
186 if (HAS_RANDOM_ITEMS (op)) 174
175 if (op->has_random_items ())
187 create_treasure (op->randomitems, op, GT_APPLY, gen->map->difficulty, 0); 176 create_treasure (op->randomitems, op, GT_APPLY, gen->map->difficulty, 0);
177
188 if (head == NULL) 178 if (head == NULL)
189 head = op; 179 head = op;
180
190 prev = op; 181 prev = op;
191 at = at->more; 182 at = at->more;
192 } 183 }
193} 184}
194 185
196generate_monster (object *gen) 187generate_monster (object *gen)
197{ 188{
198 189
199 if (GENERATE_SPEED (gen) && rndm (0, GENERATE_SPEED (gen) - 1)) 190 if (GENERATE_SPEED (gen) && rndm (0, GENERATE_SPEED (gen) - 1))
200 return; 191 return;
192
201 if (QUERY_FLAG (gen, FLAG_CONTENT_ON_GEN)) 193 if (QUERY_FLAG (gen, FLAG_CONTENT_ON_GEN))
202 generate_monster_inv (gen); 194 generate_monster_inv (gen);
203 else 195 else
204 generate_monster_arch (gen); 196 generate_monster_arch (gen);
205 197
209remove_force (object *op) 201remove_force (object *op)
210{ 202{
211 if (--op->duration > 0) 203 if (--op->duration > 0)
212 return; 204 return;
213 205
206 if (op->env)
214 switch (op->subtype) 207 switch (op->subtype)
215 { 208 {
216 case FORCE_CONFUSION: 209 case FORCE_CONFUSION:
217 if (op->env != NULL)
218 {
219 CLEAR_FLAG (op->env, FLAG_CONFUSED); 210 CLEAR_FLAG (op->env, FLAG_CONFUSED);
220 new_draw_info (NDI_UNIQUE, 0, op->env, "You regain your senses.\n"); 211 new_draw_info (NDI_UNIQUE, 0, op->env, "You regain your senses.\n");
221 }
222 212
223 default: 213 default:
224 if (op->env != NULL)
225 {
226 CLEAR_FLAG (op, FLAG_APPLIED); 214 CLEAR_FLAG (op, FLAG_APPLIED);
227 change_abil (op->env, op); 215 change_abil (op->env, op);
228 fix_player (op->env); 216 op->env->update_stats ();
229 }
230 } 217 }
231 remove_ob (op); 218
232 free_object (op); 219 op->destroy ();
233} 220}
234 221
235void 222void
236remove_blindness (object *op) 223remove_blindness (object *op)
237{ 224{
238 if (--op->stats.food > 0) 225 if (--op->stats.food > 0)
239 return; 226 return;
227
240 CLEAR_FLAG (op, FLAG_APPLIED); 228 CLEAR_FLAG (op, FLAG_APPLIED);
229
241 if (op->env != NULL) 230 if (op->env)
242 { 231 {
243 change_abil (op->env, op); 232 change_abil (op->env, op);
244 fix_player (op->env); 233 op->env->update_stats ();
245 } 234 }
246 remove_ob (op); 235
247 free_object (op); 236 op->destroy ();
248} 237}
249 238
250void 239void
251poison_more (object *op) 240poison_more (object *op)
252{ 241{
253 if (op->env == NULL || !QUERY_FLAG (op->env, FLAG_ALIVE) || op->env->stats.hp < 0) 242 if (op->env == NULL || !QUERY_FLAG (op->env, FLAG_ALIVE) || op->env->stats.hp < 0)
254 { 243 {
255 remove_ob (op); 244 op->destroy ();
256 free_object (op);
257 return; 245 return;
258 } 246 }
247
259 if (op->stats.food == 1) 248 if (op->stats.food == 1)
260 { 249 {
261 /* need to remove the object before fix_player is called, else fix_player 250 /* need to remove the object before fix_player is called, else fix_player
262 * will not do anything. 251 * will not do anything.
263 */ 252 */
264 if (op->env->type == PLAYER) 253 if (op->env->type == PLAYER)
265 { 254 {
266 CLEAR_FLAG (op, FLAG_APPLIED); 255 CLEAR_FLAG (op, FLAG_APPLIED);
267 fix_player (op->env); 256 op->env->update_stats ();
268 new_draw_info (NDI_UNIQUE, 0, op->env, "You feel much better now."); 257 new_draw_info (NDI_UNIQUE, 0, op->env, "You feel much better now.");
269 } 258 }
270 remove_ob (op); 259
271 free_object (op); 260 op->destroy ();
272 return; 261 return;
273 } 262 }
263
274 if (op->env->type == PLAYER) 264 if (op->env->type == PLAYER)
275 { 265 {
276 op->env->stats.food--; 266 op->env->stats.food--;
277 new_draw_info (NDI_UNIQUE, 0, op->env, "You feel very sick..."); 267 new_draw_info (NDI_UNIQUE, 0, op->env, "You feel very sick...");
278 } 268 }
269
279 (void) hit_player (op->env, op->stats.dam, op, AT_INTERNAL, 1); 270 hit_player (op->env, op->stats.dam, op, AT_INTERNAL, 1);
280} 271}
281 272
282 273
283void 274void
284move_gate (object *op) 275move_gate (object *op)
286 object *tmp; 277 object *tmp;
287 278
288 if (op->stats.wc < 0 || (int) op->stats.wc >= NUM_ANIMATIONS (op)) 279 if (op->stats.wc < 0 || (int) op->stats.wc >= NUM_ANIMATIONS (op))
289 { 280 {
290 LOG (llevError, "Gate error: animation was %d, max=%d\n", op->stats.wc, NUM_ANIMATIONS (op)); 281 LOG (llevError, "Gate error: animation was %d, max=%d\n", op->stats.wc, NUM_ANIMATIONS (op));
291 dump_object (op);
292 LOG (llevError, "%s\n", errmsg);
293 op->stats.wc = 0; 282 op->stats.wc = 0;
294 } 283 }
295 284
296 /* We're going down */ 285 /* We're going down */
297 if (op->value) 286 if (op->value)
300 { /* Reached bottom, let's stop */ 289 { /* Reached bottom, let's stop */
301 op->stats.wc = 0; 290 op->stats.wc = 0;
302 if (op->arch->clone.speed) 291 if (op->arch->clone.speed)
303 op->value = 0; 292 op->value = 0;
304 else 293 else
305 {
306 op->speed = 0; 294 op->set_speed (0);
307 update_ob_speed (op);
308 } 295 }
309 } 296
310 if ((int) op->stats.wc < (NUM_ANIMATIONS (op) / 2 + 1)) 297 if ((int) op->stats.wc < (NUM_ANIMATIONS (op) / 2 + 1))
311 { 298 {
312 op->move_block = 0; 299 op->move_block = 0;
313 CLEAR_FLAG (op, FLAG_BLOCKSVIEW); 300 CLEAR_FLAG (op, FLAG_BLOCKSVIEW);
314 update_all_los (op->map, op->x, op->y); 301 update_all_los (op->map, op->x, op->y);
315 } 302 }
303
316 SET_ANIMATION (op, op->stats.wc); 304 SET_ANIMATION (op, op->stats.wc);
317 update_object (op, UP_OBJ_CHANGE); 305 update_object (op, UP_OBJ_CHANGE);
318 return; 306 return;
319 } 307 }
320 308
337 if (tmp == NULL) 325 if (tmp == NULL)
338 { 326 {
339 if (op->arch->clone.speed) 327 if (op->arch->clone.speed)
340 op->value = 1; 328 op->value = 1;
341 else 329 else
342 {
343 op->speed = 0; 330 op->set_speed (0);
344 update_ob_speed (op); /* Reached top, let's stop */ 331
345 }
346 return; 332 return;
347 } 333 }
348 } 334 }
349 335
350 if (op->stats.food) 336 if (op->stats.food)
390 int i = find_free_spot (tmp, op->map, op->x, op->y, 1, 9); 376 int i = find_free_spot (tmp, op->map, op->x, op->y, 1, 9);
391 377
392 /* If there is a free spot, move the object someplace */ 378 /* If there is a free spot, move the object someplace */
393 if (i != -1) 379 if (i != -1)
394 { 380 {
395 remove_ob (tmp); 381 tmp->remove ();
396 tmp->x += freearr_x[i], tmp->y += freearr_y[i]; 382 tmp->x += freearr_x[i], tmp->y += freearr_y[i];
397 insert_ob_in_map (tmp, op->map, op, 0); 383 insert_ob_in_map (tmp, op->map, op, 0);
398 } 384 }
399 } 385 }
400 } 386 }
441 } 427 }
442 if (--op->stats.hp <= 0) 428 if (--op->stats.hp <= 0)
443 { /* keep gate down */ 429 { /* keep gate down */
444 move_gate (op); 430 move_gate (op);
445 if (op->value != v) 431 if (op->value != v)
446 { /* ready ? */
447 op->speed = 0; 432 op->set_speed (0);
448 update_ob_speed (op);
449 }
450 } 433 }
451} 434}
452 435
453/* slaying: name of the thing the detector is to look for 436/* slaying: name of the thing the detector is to look for
454 * speed: frequency of 'glances' 437 * speed: frequency of 'glances'
464 int last = op->value; 447 int last = op->value;
465 int detected; 448 int detected;
466 449
467 detected = 0; 450 detected = 0;
468 451
469 for (tmp = get_map_ob (op->map, op->x, op->y); tmp != NULL && !detected; tmp = tmp->above) 452 for (tmp = GET_MAP_OB (op->map, op->x, op->y); tmp != NULL && !detected; tmp = tmp->above)
470 { 453 {
471 object *tmp2; 454 object *tmp2;
472 455
473 if (op->stats.hp) 456 if (op->stats.hp)
474 { 457 {
541 if (op->value) 524 if (op->value)
542 { /* We're opening */ 525 { /* We're opening */
543 if (--op->stats.wc <= 0) 526 if (--op->stats.wc <= 0)
544 { /* Opened, let's stop */ 527 { /* Opened, let's stop */
545 op->stats.wc = 0; 528 op->stats.wc = 0;
546 op->speed = 0; 529 op->set_speed (0);
547 update_ob_speed (op);
548 530
549 /* Hard coding this makes sense for holes I suppose */ 531 /* Hard coding this makes sense for holes I suppose */
550 op->move_on = MOVE_WALK; 532 op->move_on = MOVE_WALK;
551 for (tmp = op->above; tmp != NULL; tmp = next) 533 for (tmp = op->above; tmp != NULL; tmp = next)
552 { 534 {
553 next = tmp->above; 535 next = tmp->above;
554 move_apply (op, tmp, tmp); 536 move_apply (op, tmp, tmp);
555 } 537 }
556 } 538 }
539
557 SET_ANIMATION (op, op->stats.wc); 540 SET_ANIMATION (op, op->stats.wc);
558 update_object (op, UP_OBJ_FACE); 541 update_object (op, UP_OBJ_FACE);
559 return; 542 return;
560 } 543 }
561 /* We're closing */ 544 /* We're closing */
562 op->move_on = 0; 545 op->move_on = 0;
563 546
564 op->stats.wc++; 547 op->stats.wc++;
565 if ((int) op->stats.wc >= NUM_ANIMATIONS (op)) 548 if ((int) op->stats.wc >= NUM_ANIMATIONS (op))
566 op->stats.wc = NUM_ANIMATIONS (op) - 1; 549 op->stats.wc = NUM_ANIMATIONS (op) - 1;
550
567 SET_ANIMATION (op, op->stats.wc); 551 SET_ANIMATION (op, op->stats.wc);
568 update_object (op, UP_OBJ_FACE); 552 update_object (op, UP_OBJ_FACE);
569 if ((unsigned char) op->stats.wc == (NUM_ANIMATIONS (op) - 1)) 553 if ((unsigned char) op->stats.wc == (NUM_ANIMATIONS (op) - 1))
570 {
571 op->speed = 0;
572 update_ob_speed (op); /* closed, let's stop */ 554 op->set_speed (0); /* closed, let's stop */
573 return;
574 }
575} 555}
576 556
577 557
578/* stop_item() returns a pointer to the stopped object. The stopped object 558/* stop_item() returns a pointer to the stopped object. The stopped object
579 * may or may not have been removed from maps or inventories. It will not 559 * may or may not have been removed from maps or inventories. It will not
599 { 579 {
600 object *payload = op->inv; 580 object *payload = op->inv;
601 581
602 if (payload == NULL) 582 if (payload == NULL)
603 return NULL; 583 return NULL;
604 remove_ob (payload); 584 payload->remove ();
605 remove_ob (op); 585 op->destroy ();
606 free_object (op);
607 return payload; 586 return payload;
608 } 587 }
609 588
610 case ARROW: 589 case ARROW:
611 if (op->speed >= MIN_ACTIVE_SPEED) 590 if (op->has_active_speed ())
612 op = fix_stopped_arrow (op); 591 op = fix_stopped_arrow (op);
613 return op; 592 return op;
614 593
615 default: 594 default:
616 return op; 595 return op;
621 * Inserts item into the old map, or merges it if it already is on the map. 600 * Inserts item into the old map, or merges it if it already is on the map.
622 * 601 *
623 * 'map' must be the value of op->map before stop_item() was called. 602 * 'map' must be the value of op->map before stop_item() was called.
624 */ 603 */
625void 604void
626fix_stopped_item (object *op, mapstruct *map, object *originator) 605fix_stopped_item (object *op, maptile *map, object *originator)
627{ 606{
628 if (map == NULL) 607 if (map == NULL)
629 return; 608 return;
630 if (QUERY_FLAG (op, FLAG_REMOVED)) 609 if (QUERY_FLAG (op, FLAG_REMOVED))
631 insert_ob_in_map (op, map, originator, 0); 610 insert_ob_in_map (op, map, originator, 0);
638fix_stopped_arrow (object *op) 617fix_stopped_arrow (object *op)
639{ 618{
640 if (rndm (0, 99) < op->stats.food) 619 if (rndm (0, 99) < op->stats.food)
641 { 620 {
642 /* Small chance of breaking */ 621 /* Small chance of breaking */
643 remove_ob (op); 622 op->destroy ();
644 free_object (op);
645 return NULL; 623 return NULL;
646 } 624 }
647 625
626 op->set_speed (0);
648 op->direction = 0; 627 op->direction = 0;
649 op->move_on = 0; 628 op->move_on = 0;
650 op->move_type = 0; 629 op->move_type = 0;
651 op->speed = 0;
652 update_ob_speed (op);
653 op->stats.wc = op->stats.sp; 630 op->stats.wc = op->stats.sp;
654 op->stats.dam = op->stats.hp; 631 op->stats.dam = op->stats.hp;
655 op->attacktype = op->stats.grace; 632 op->attacktype = op->stats.grace;
656 op->slaying = 0; 633 op->slaying = 0;
657 op->skill = 0; 634 op->skill = 0;
663 op->spellarg = NULL; 640 op->spellarg = NULL;
664 } 641 }
665 else 642 else
666 op->slaying = NULL; 643 op->slaying = NULL;
667 644
668 /* Reset these to zero, so that CAN_MERGE will work properly */ 645 /* Reset these to zero, so that object::can_merge will work properly */
669 op->spellarg = NULL; 646 op->spellarg = NULL;
670 op->stats.sp = 0; 647 op->stats.sp = 0;
671 op->stats.hp = 0; 648 op->stats.hp = 0;
672 op->stats.grace = 0; 649 op->stats.grace = 0;
673 op->level = 0; 650 op->level = 0;
682 * here too. -b.t. 659 * here too. -b.t.
683 * 660 *
684 * Returns a pointer to the stopped object (which will have been removed 661 * Returns a pointer to the stopped object (which will have been removed
685 * from maps or inventories), or NULL if was destroyed. 662 * from maps or inventories), or NULL if was destroyed.
686 */ 663 */
687
688static void 664static void
689stop_arrow (object *op) 665stop_arrow (object *op)
690{ 666{
691 if (INVOKE_OBJECT (STOP, op)) 667 if (INVOKE_OBJECT (STOP, op))
692 return; 668 return;
693 669
694 if (op->inv) 670 if (op->inv)
695 { 671 {
696 object *payload = op->inv; 672 object *payload = op->inv;
697 673
698 remove_ob (payload); 674 payload->remove ();
699 clear_owner (payload); 675 payload->owner = 0;
700 insert_ob_in_map (payload, op->map, payload, 0); 676 insert_ob_in_map (payload, op->map, payload, 0);
701 remove_ob (op); 677 op->destroy ();
702 free_object (op);
703 } 678 }
704 else 679 else
705 { 680 {
706 op = fix_stopped_arrow (op); 681 op = fix_stopped_arrow (op);
707 if (op) 682 if (op)
716move_arrow (object *op) 691move_arrow (object *op)
717{ 692{
718 object *tmp; 693 object *tmp;
719 sint16 new_x, new_y; 694 sint16 new_x, new_y;
720 int was_reflected, mflags; 695 int was_reflected, mflags;
721 mapstruct *m; 696 maptile *m;
722 697
723 if (op->map == NULL) 698 if (op->map == NULL)
724 { 699 {
725 LOG (llevError, "BUG: Arrow had no map.\n"); 700 LOG (llevError, "BUG: Arrow had no map.\n");
726 remove_ob (op); 701 op->destroy ();
727 free_object (op);
728 return; 702 return;
729 } 703 }
730 704
731 /* we need to stop thrown objects at some point. Like here. */ 705 /* we need to stop thrown objects at some point. Like here. */
732 if (op->type == THROWN_OBJ) 706 if (op->type == THROWN_OBJ)
739 * bomb code, but there are potential other cases where that could happen, 713 * bomb code, but there are potential other cases where that could happen,
740 * and it is easy enough to clean it up here. 714 * and it is easy enough to clean it up here.
741 */ 715 */
742 if (op->inv == NULL) 716 if (op->inv == NULL)
743 { 717 {
744 remove_ob (op); 718 op->destroy ();
745 free_object (op);
746 return; 719 return;
747 } 720 }
721
748 if (op->last_sp-- < 0) 722 if (op->last_sp-- < 0)
749 { 723 {
750 stop_arrow (op); 724 stop_arrow (op);
751 return; 725 return;
752 } 726 }
775 } 749 }
776 750
777 /* only need to look for living creatures if this flag is set */ 751 /* only need to look for living creatures if this flag is set */
778 if (mflags & P_IS_ALIVE) 752 if (mflags & P_IS_ALIVE)
779 { 753 {
780 for (tmp = get_map_ob (m, new_x, new_y); tmp != NULL; tmp = tmp->above) 754 for (tmp = GET_MAP_OB (m, new_x, new_y); tmp != NULL; tmp = tmp->above)
781 if (QUERY_FLAG (tmp, FLAG_ALIVE)) 755 if (QUERY_FLAG (tmp, FLAG_ALIVE))
782 break; 756 break;
783
784 757
785 /* Not really fair, but don't let monsters hit themselves with 758 /* Not really fair, but don't let monsters hit themselves with
786 * their own arrow - this can be because they fire it then 759 * their own arrow - this can be because they fire it then
787 * move into it. 760 * move into it.
788 */ 761 */
789
790 if (tmp != NULL && tmp != op->owner) 762 if (tmp && tmp != op->owner)
791 { 763 {
792 /* Found living object, but it is reflecting the missile. Update 764 /* Found living object, but it is reflecting the missile. Update
793 * as below. (Note that for living creatures there is a small 765 * as below. (Note that for living creatures there is a small
794 * chance that reflect_missile fails.) 766 * chance that reflect_missile fails.)
795 */ 767 */
796
797 if (QUERY_FLAG (tmp, FLAG_REFL_MISSILE) && (rndm (0, 99)) < (90 - op->level / 10)) 768 if (QUERY_FLAG (tmp, FLAG_REFL_MISSILE) && (rndm (0, 99)) < (90 - op->level / 10))
798 { 769 {
799
800 int number = op->face->number; 770 int number = op->face->number;
801 771
802 op->direction = absdir (op->direction + 4); 772 op->direction = absdir (op->direction + 4);
803 op->state = 0; 773 op->state = 0;
774
804 if (GET_ANIM_ID (op)) 775 if (GET_ANIM_ID (op))
805 { 776 {
806 number += 4; 777 number += 4;
778
807 if (number > GET_ANIMATION (op, 8)) 779 if (number > GET_ANIMATION (op, 8))
808 number -= 8; 780 number -= 8;
781
809 op->face = &new_faces[number]; 782 op->face = &new_faces[number];
810 } 783 }
784
811 was_reflected = 1; /* skip normal movement calculations */ 785 was_reflected = 1; /* skip normal movement calculations */
812 } 786 }
813 else 787 else
814 { 788 {
815 /* Attack the object. */ 789 /* Attack the object. */
816 op = hit_with_arrow (op, tmp); 790 op = hit_with_arrow (op, tmp);
791
817 if (op == NULL) 792 if (!op)
818 return; 793 return;
819 } 794 }
820 } /* if this is not hitting its owner */ 795 } /* if this is not hitting its owner */
821 } /* if there is something alive on this space */ 796 } /* if there is something alive on this space */
822
823 797
824 if (OB_TYPE_MOVE_BLOCK (op, GET_MAP_MOVE_BLOCK (m, new_x, new_y))) 798 if (OB_TYPE_MOVE_BLOCK (op, GET_MAP_MOVE_BLOCK (m, new_x, new_y)))
825 { 799 {
826 int retry = 0; 800 int retry = 0;
827 801
849 * that did the same thing. 823 * that did the same thing.
850 */ 824 */
851 while (retry < 2) 825 while (retry < 2)
852 { 826 {
853 int left, right, mflags; 827 int left, right, mflags;
854 mapstruct *m1; 828 maptile *m1;
855 sint16 x1, y1; 829 sint16 x1, y1;
856 830
857 retry++; 831 retry++;
858 832
859 /* Need to check for P_OUT_OF_MAP: if the arrow is tavelling 833 /* Need to check for P_OUT_OF_MAP: if the arrow is tavelling
899 SET_ANIMATION (op, op->direction); 873 SET_ANIMATION (op, op->direction);
900 } /* object is reflected */ 874 } /* object is reflected */
901 } /* object ran into a wall */ 875 } /* object ran into a wall */
902 876
903 /* Move the arrow. */ 877 /* Move the arrow. */
904 remove_ob (op); 878 op->remove ();
905 op->x = new_x; 879 op->x = new_x;
906 op->y = new_y; 880 op->y = new_y;
907 881
908 /* decrease the speed as it flies. 0.05 means a standard bow will shoot 882 /* decrease the speed as it flies. 0.05 means a standard bow will shoot
909 * about 17 squares. Tune as needed. 883 * about 17 squares. Tune as needed.
917 * Modified this routine to allow held objects. b.t. */ 891 * Modified this routine to allow held objects. b.t. */
918 892
919void 893void
920change_object (object *op) 894change_object (object *op)
921{ /* Doesn`t handle linked objs yet */ 895{ /* Doesn`t handle linked objs yet */
922 object *tmp, *env, *pl;
923 int i, j; 896 int i, j;
924 897
925 if (op->other_arch == NULL) 898 if (op->other_arch == NULL)
926 { 899 {
927 LOG (llevError, "Change object (%s) without other_arch error.\n", &op->name); 900 LOG (llevError, "Change object (%s) without other_arch error.\n", &op->name);
934 if (op->stats.food-- > 0) 907 if (op->stats.food-- > 0)
935 return; 908 return;
936 else 909 else
937 op->stats.food = 1; /* so 1 other_arch is made */ 910 op->stats.food = 1; /* so 1 other_arch is made */
938 } 911 }
912
913 object *pl = op->in_player ();
939 env = op->env; 914 object *env = op->env;
940 remove_ob (op); 915
916 op->remove ();
941 for (i = 0; i < NROFNEWOBJS (op); i++) 917 for (i = 0; i < NROFNEWOBJS (op); i++)
942 { 918 {
943 tmp = arch_to_object (op->other_arch); 919 object *tmp = arch_to_object (op->other_arch);
920
944 if (op->type == LAMP) 921 if (op->type == LAMP)
945 tmp->stats.food = op->stats.food - 1; 922 tmp->stats.food = op->stats.food - 1;
923
946 tmp->stats.hp = op->stats.hp; /* The only variable it keeps. */ 924 tmp->stats.hp = op->stats.hp; /* The only variable it keeps. */
947 if (env) 925 if (env)
948 { 926 {
949 tmp->x = env->x, tmp->y = env->y; 927 tmp->x = env->x, tmp->y = env->y;
950 tmp = insert_ob_in_ob (tmp, env); 928 tmp = insert_ob_in_ob (tmp, env);
929
951 /* If this object is the players inventory, we need to tell the 930 /* If this object is the players inventory, we need to tell the
952 * client of the change. Insert_ob_in_map takes care of the 931 * client of the change. Insert_ob_in_map takes care of the
953 * updating the client, so we don't need to do that below. 932 * updating the client, so we don't need to do that below.
954 */ 933 */
955 if ((pl = is_player_inv (env)) != NULL) 934 if (pl)
956 { 935 {
957 esrv_del_item (pl->contr, op->count); 936 esrv_del_item (pl->contr, op->count);
958 esrv_send_item (pl, tmp); 937 esrv_send_item (pl, tmp);
959 } 938 }
960 } 939 }
961 else 940 else
962 { 941 {
963 j = find_first_free_spot (tmp, op->map, op->x, op->y); 942 j = find_first_free_spot (tmp, op->map, op->x, op->y);
964 if (j == -1) /* No free spot */ 943 if (j == -1) /* No free spot */
965 free_object (tmp); 944 tmp->destroy ();
966 else 945 else
967 { 946 {
968 tmp->x = op->x + freearr_x[j], tmp->y = op->y + freearr_y[j]; 947 tmp->x = op->x + freearr_x[j], tmp->y = op->y + freearr_y[j];
969 insert_ob_in_map (tmp, op->map, op, 0); 948 insert_ob_in_map (tmp, op->map, op, 0);
970 } 949 }
971 } 950 }
972 } 951 }
973 free_object (op); 952
953 op->destroy ();
974} 954}
975 955
976void 956void
977move_teleporter (object *op) 957move_teleporter (object *op)
978{ 958{
983 * there is an old multipart teleporter in which the other parts 963 * there is an old multipart teleporter in which the other parts
984 * have speed, we don't really want to call it twice for the same 964 * have speed, we don't really want to call it twice for the same
985 * function - in fact, as written below, part N would get called 965 * function - in fact, as written below, part N would get called
986 * N times without the speed check. 966 * N times without the speed check.
987 */ 967 */
988 if (op->more && FABS (op->more->speed) < MIN_ACTIVE_SPEED) 968 if (op->more && !op->more->has_active_speed ())
989 move_teleporter (op->more); 969 move_teleporter (op->more);
990 970
991 if (op->head) 971 if (op->head)
992 head = op->head; 972 head = op->head;
993 973
1004 if (tmp->type == PLAYER) 984 if (tmp->type == PLAYER)
1005 { 985 {
1006 if (INVOKE_OBJECT (TRIGGER, op, ARG_OBJECT (tmp))) 986 if (INVOKE_OBJECT (TRIGGER, op, ARG_OBJECT (tmp)))
1007 return; 987 return;
1008 988
1009 enter_exit (tmp, head); 989 tmp->enter_exit (head);
1010 } 990 }
1011 else 991 else
1012 /* Currently only players can transfer maps */ 992 /* Currently only players can transfer maps */
1013 return; 993 return;
1014 } 994 }
1015 else if (EXIT_X (head) || EXIT_Y (head)) 995 else if (EXIT_X (head) || EXIT_Y (head))
1016 { 996 {
1017 if (out_of_map (head->map, EXIT_X (head), EXIT_Y (head))) 997 if (out_of_map (head->map, EXIT_X (head), EXIT_Y (head)))
1018 { 998 {
1019 LOG (llevError, "Removed illegal teleporter.\n"); 999 LOG (llevError, "Removed illegal teleporter.\n");
1020 remove_ob (head); 1000 head->destroy ();
1021 free_object (head);
1022 return; 1001 return;
1023 } 1002 }
1003
1024 if (INVOKE_OBJECT (TRIGGER, op, ARG_OBJECT (tmp))) 1004 if (INVOKE_OBJECT (TRIGGER, op, ARG_OBJECT (tmp)))
1025 return; 1005 return;
1006
1026 transfer_ob (tmp, EXIT_X (head), EXIT_Y (head), 0, head); 1007 transfer_ob (tmp, EXIT_X (head), EXIT_Y (head), 0, head);
1027 } 1008 }
1028 else 1009 else
1029 { 1010 {
1030 /* Random teleporter */ 1011 /* Random teleporter */
1038/* This object will teleport someone to a different map 1019/* This object will teleport someone to a different map
1039 and will also apply changes to the player from its inventory. 1020 and will also apply changes to the player from its inventory.
1040 This was invented for giving classes, but there's no reason it 1021 This was invented for giving classes, but there's no reason it
1041 can't be generalized. 1022 can't be generalized.
1042*/ 1023*/
1043
1044void 1024void
1045move_player_changer (object *op) 1025move_player_changer (object *op)
1046{ 1026{
1047 object *player; 1027 object *player;
1048 object *walk; 1028 object *walk;
1049 char c;
1050 1029
1051 if (!op->above || !EXIT_PATH (op)) 1030 if (!op->above || !EXIT_PATH (op))
1052 return; 1031 return;
1053 1032
1054 /* This isn't all that great - means that the player_mover 1033 /* This isn't all that great - means that the player_mover
1055 * needs to be on top. 1034 * needs to be on top.
1056 */ 1035 */
1057 if (op->above->type == PLAYER) 1036 if (op->above->type == PLAYER)
1058 { 1037 {
1059 if (INVOKE_OBJECT (TRIGGER, op, ARG_OBJECT (player))) 1038 if (INVOKE_OBJECT (TRIGGER, op, ARG_OBJECT (player)))
1060 return; 1039 return;
1040
1061 player = op->above; 1041 player = op->above;
1062 1042
1063 for (walk = op->inv; walk != NULL; walk = walk->below) 1043 for (walk = op->inv; walk; walk = walk->below)
1064 apply_changes_to_player (player, walk); 1044 apply_changes_to_player (player, walk);
1065 1045
1066 fix_player (player); 1046 player->update_stats ();
1067 1047
1068 esrv_send_inventory (op->above, op->above); 1048 esrv_send_inventory (op->above, op->above);
1069 esrv_update_item (UPD_FACE, op->above, op->above); 1049 esrv_update_item (UPD_FACE, op->above, op->above);
1070 1050
1071 /* update players death & WoR home-position */ 1051 /* update players death & WoR home-position */
1072 sscanf (EXIT_PATH (op), "%c", &c); 1052 if (*EXIT_PATH (op) == '/')
1073 if (c == '/')
1074 { 1053 {
1075 strcpy (player->contr->savebed_map, EXIT_PATH (op)); 1054 player->contr->savebed_map = EXIT_PATH (op);
1076 player->contr->bed_x = EXIT_X (op); 1055 player->contr->bed_x = EXIT_X (op);
1077 player->contr->bed_y = EXIT_Y (op); 1056 player->contr->bed_y = EXIT_Y (op);
1078 } 1057 }
1079 else 1058 else
1080 LOG (llevDebug, "WARNING: destination '%s' in player_changer must be an absolute path!\n", &EXIT_PATH (op)); 1059 LOG (llevDebug, "WARNING: destination '%s' in player_changer must be an absolute path!\n", &EXIT_PATH (op));
1081 1060
1082 enter_exit (op->above, op); 1061 op->above->enter_exit (op);
1083 save_player (player, 1);
1084 } 1062 }
1085} 1063}
1086 1064
1087/* firewalls fire other spells. 1065/* firewalls fire other spells.
1088 * The direction of the wall is stored in op->stats.sp. 1066 * The direction of the wall is stored in op->stats.sp.
1095 1073
1096 if (!op->map) 1074 if (!op->map)
1097 return; /* dm has created a firewall in his inventory */ 1075 return; /* dm has created a firewall in his inventory */
1098 1076
1099 spell = op->inv; 1077 spell = op->inv;
1078
1100 if (!spell || spell->type != SPELL) 1079 if (!spell || spell->type != SPELL)
1101 spell = &op->other_arch->clone; 1080 spell = &op->other_arch->clone;
1081
1102 if (!spell) 1082 if (!spell)
1103 { 1083 {
1104 LOG (llevError, "move_firewall: no spell specified (%s, %s, %d, %d)\n", &op->name, op->map->name, op->x, op->y); 1084 LOG (llevError, "move_firewall: no spell specified (%s, %s, %d, %d)\n", &op->name, &op->map->name, op->x, op->y);
1105 return; 1085 return;
1106 } 1086 }
1107 1087
1108 cast_spell (op, op, op->stats.sp ? op->stats.sp : rndm (1, 8), spell, NULL); 1088 cast_spell (op, op, op->stats.sp ? op->stats.sp : rndm (1, 8), spell, NULL);
1109} 1089}
1110
1111 1090
1112/* move_player_mover: this function takes a "player mover" as an 1091/* move_player_mover: this function takes a "player mover" as an
1113 * argument, and performs the function of a player mover, which is: 1092 * argument, and performs the function of a player mover, which is:
1114 * 1093 *
1115 * a player mover finds any players that are sitting on it. It 1094 * a player mover finds any players that are sitting on it. It
1122move_player_mover (object *op) 1101move_player_mover (object *op)
1123{ 1102{
1124 object *victim, *nextmover; 1103 object *victim, *nextmover;
1125 int dir = op->stats.sp; 1104 int dir = op->stats.sp;
1126 sint16 nx, ny; 1105 sint16 nx, ny;
1127 mapstruct *m; 1106 maptile *m;
1128 1107
1129 /* Determine direction now for random movers so we do the right thing */ 1108 /* Determine direction now for random movers so we do the right thing */
1130 if (!dir) 1109 if (!dir)
1131 dir = rndm (1, 8); 1110 dir = rndm (1, 8);
1132 1111
1133 for (victim = get_map_ob (op->map, op->x, op->y); victim != NULL; victim = victim->above) 1112 for (victim = GET_MAP_OB (op->map, op->x, op->y); victim != NULL; victim = victim->above)
1134 { 1113 {
1135 if (QUERY_FLAG (victim, FLAG_ALIVE) && !QUERY_FLAG (victim, FLAG_WIZPASS) && 1114 if (QUERY_FLAG (victim, FLAG_ALIVE) && !QUERY_FLAG (victim, FLAG_WIZPASS) &&
1136 (victim->move_type & op->move_type || !victim->move_type)) 1115 (victim->move_type & op->move_type || !victim->move_type))
1137 { 1116 {
1138 1117
1139 if (victim->head) 1118 if (victim->head)
1140 victim = victim->head; 1119 victim = victim->head;
1141 1120
1142 if (QUERY_FLAG (op, FLAG_LIFESAVE) && op->stats.hp-- < 0) 1121 if (QUERY_FLAG (op, FLAG_LIFESAVE) && op->stats.hp-- < 0)
1143 { 1122 {
1144 remove_ob (op); 1123 op->remove ();
1145 free_object (op);
1146 return; 1124 return;
1147 } 1125 }
1126
1148 nx = op->x + freearr_x[dir]; 1127 nx = op->x + freearr_x[dir];
1149 ny = op->y + freearr_y[dir]; 1128 ny = op->y + freearr_y[dir];
1150 m = op->map; 1129 m = op->map;
1151 if (get_map_flags (m, &m, nx, ny, &nx, &ny) & P_OUT_OF_MAP) 1130 if (get_map_flags (m, &m, nx, ny, &nx, &ny) & P_OUT_OF_MAP)
1152 { 1131 {
1153 LOG (llevError, "move_player_mover: Trying to push player off the map! map=%s (%d, %d)\n", m->path, op->x, op->y); 1132 LOG (llevError, "move_player_mover: Trying to push player off the map! map=%s (%d, %d)\n", &m->path, op->x, op->y);
1154 return; 1133 return;
1155 } 1134 }
1156 1135
1157 if (should_director_abort (op, victim)) 1136 if (should_director_abort (op, victim))
1158 return; 1137 return;
1159 1138
1160 for (nextmover = get_map_ob (m, nx, ny); nextmover != NULL; nextmover = nextmover->above) 1139 for (nextmover = GET_MAP_OB (m, nx, ny); nextmover != NULL; nextmover = nextmover->above)
1161 { 1140 {
1162 if (nextmover->type == PLAYERMOVER) 1141 if (nextmover->type == PLAYERMOVER)
1163 nextmover->speed_left = -.99; 1142 nextmover->speed_left = -.99;
1164 if (QUERY_FLAG (nextmover, FLAG_ALIVE)) 1143 if (QUERY_FLAG (nextmover, FLAG_ALIVE))
1165 { 1144 {
1219{ 1198{
1220 object *tmp; 1199 object *tmp;
1221 1200
1222 if (!op->other_arch) 1201 if (!op->other_arch)
1223 { 1202 {
1224 LOG (llevInfo, "Duplicator with no other_arch! %d %d %s\n", op->x, op->y, op->map ? op->map->path : "nullmap"); 1203 LOG (llevInfo, "Duplicator with no other_arch! %d %d %s\n", op->x, op->y, op->map ? &op->map->path : "nullmap");
1225 return; 1204 return;
1226 } 1205 }
1227 1206
1228 if (op->above == NULL) 1207 if (op->above == NULL)
1229 return; 1208 return;
1230 for (tmp = op->above; tmp != NULL; tmp = tmp->above) 1209 for (tmp = op->above; tmp != NULL; tmp = tmp->above)
1231 { 1210 {
1232 if (strcmp (op->other_arch->name, tmp->arch->name) == 0) 1211 if (strcmp (op->other_arch->name, tmp->arch->name) == 0)
1233 { 1212 {
1234 if (op->level <= 0) 1213 if (op->level <= 0)
1235 { 1214 tmp->destroy ();
1236 remove_ob (tmp);
1237 free_object (tmp);
1238 }
1239 else 1215 else
1240 { 1216 {
1241 uint64 new_nrof = (uint64) tmp->nrof * op->level; 1217 uint64 new_nrof = (uint64) tmp->nrof * op->level;
1242 1218
1243 if (new_nrof >= 1UL << 31) 1219 if (new_nrof >= 1UL << 31)
1244 new_nrof = 1UL << 31; 1220 new_nrof = 1UL << 31;
1221
1245 tmp->nrof = new_nrof; 1222 tmp->nrof = new_nrof;
1246 } 1223 }
1224
1247 break; 1225 break;
1248 } 1226 }
1249 } 1227 }
1250} 1228}
1251 1229
1295 } 1273 }
1296 else 1274 else
1297 { 1275 {
1298 if (creator->other_arch == NULL) 1276 if (creator->other_arch == NULL)
1299 { 1277 {
1300 LOG (llevError, "move_creator: Creator doesn't have other arch set: %s (%s, %d, %d)\n", &creator->name, creator->map->path, 1278 LOG (llevError, "move_creator: Creator doesn't have other arch set: %s (%s, %d, %d)\n",
1301 creator->x, creator->y); 1279 &creator->name, &creator->map->path, creator->x, creator->y);
1302 return; 1280 return;
1303 } 1281 }
1304 1282
1305 new_ob = object_create_arch (creator->other_arch); 1283 new_ob = object_create_arch (creator->other_arch);
1306 fix_generated_item (new_ob, creator, 0, 0, GT_MINIMAL); 1284 fix_generated_item (new_ob, creator, 0, 0, GT_MINIMAL);
1307 } 1285 }
1308 1286
1309 /* Make sure this multipart object fits */ 1287 /* Make sure this multipart object fits */
1310 if (new_ob->arch->more && ob_blocked (new_ob, creator->map, creator->x, creator->y)) 1288 if (new_ob->arch->more && ob_blocked (new_ob, creator->map, creator->x, creator->y))
1311 { 1289 {
1312 free_object (new_ob); 1290 new_ob->destroy ();
1313 return; 1291 return;
1314 } 1292 }
1315 1293
1316 insert_ob_in_map_at (new_ob, creator->map, creator, 0, creator->x, creator->y); 1294 insert_ob_in_map_at (new_ob, creator->map, creator, 0, creator->x, creator->y);
1317 if (QUERY_FLAG (new_ob, FLAG_FREED)) 1295 if (QUERY_FLAG (new_ob, FLAG_FREED))
1333 unless hp was zero to start with, in which case it is infinite.*/ 1311 unless hp was zero to start with, in which case it is infinite.*/
1334 1312
1335void 1313void
1336move_marker (object *op) 1314move_marker (object *op)
1337{ 1315{
1316 if (object *tmp = op->ms ().player ())
1317 {
1338 object *tmp, *tmp2; 1318 object *tmp2;
1339 1319
1340 for (tmp = get_map_ob (op->map, op->x, op->y); tmp != NULL; tmp = tmp->above)
1341 {
1342 if (tmp->type == PLAYER)
1343 { /* we've got someone to MARK */
1344
1345 /* remove an old force with a slaying field == op->name */ 1320 /* remove an old force with a slaying field == op->name */
1346 for (tmp2 = tmp->inv; tmp2 != NULL; tmp2 = tmp2->below) 1321 for (tmp2 = tmp->inv; tmp2; tmp2 = tmp2->below)
1347 {
1348 if (tmp2->type == FORCE && tmp2->slaying && !strcmp (tmp2->slaying, op->name)) 1322 if (tmp2->type == FORCE && tmp2->slaying && !strcmp (tmp2->slaying, op->name))
1349 break;
1350 }
1351
1352 if (tmp2)
1353 { 1323 {
1354 remove_ob (tmp2); 1324 tmp2->destroy ();
1355 free_object (tmp2); 1325 break;
1356 } 1326 }
1357 1327
1358 /* cycle through his inventory to look for the MARK we want to 1328 /* cycle through his inventory to look for the MARK we want to
1359 * place 1329 * place
1360 */ 1330 */
1361 for (tmp2 = tmp->inv; tmp2 != NULL; tmp2 = tmp2->below) 1331 for (tmp2 = tmp->inv; tmp2; tmp2 = tmp2->below)
1362 {
1363 if (tmp2->type == FORCE && tmp2->slaying && !strcmp (tmp2->slaying, op->slaying)) 1332 if (tmp2->type == FORCE && tmp2->slaying && !strcmp (tmp2->slaying, op->slaying))
1364 break; 1333 break;
1365 }
1366 1334
1367 /* if we didn't find our own MARK */ 1335 /* if we didn't find our own MARK */
1368 if (tmp2 == NULL) 1336 if (tmp2 == NULL)
1369 { 1337 {
1370 object *force = get_archetype (FORCE_NAME); 1338 object *force = get_archetype (FORCE_NAME);
1371 1339
1372 force->speed = 0;
1373 if (op->stats.food) 1340 if (op->stats.food)
1341 {
1342 force->set_speed (0.01);
1343 force->speed_left = -op->stats.food;
1344 }
1345 else
1346 force->set_speed (0);
1347
1348 /* put in the lock code */
1349 force->slaying = op->slaying;
1350
1351 if (op->lore)
1352 force->lore = op->lore;
1353
1354 insert_ob_in_ob (force, tmp);
1355 if (op->msg)
1356 new_draw_info (NDI_UNIQUE | NDI_NAVY, 0, tmp, op->msg);
1357
1358 if (op->stats.hp > 0)
1359 {
1360 op->stats.hp--;
1361 if (op->stats.hp == 0)
1374 { 1362 {
1375 force->speed = 0.01; 1363 /* marker expires--granted mark number limit */
1376 force->speed_left = -op->stats.food; 1364 op->destroy ();
1365 return;
1377 } 1366 }
1378 update_ob_speed (force);
1379 /* put in the lock code */
1380 force->slaying = op->slaying;
1381
1382 if (op->lore)
1383 force->lore = op->lore;
1384
1385 insert_ob_in_ob (force, tmp);
1386 if (op->msg)
1387 new_draw_info (NDI_UNIQUE | NDI_NAVY, 0, tmp, op->msg);
1388
1389 if (op->stats.hp > 0)
1390 {
1391 op->stats.hp--;
1392 if (op->stats.hp == 0)
1393 {
1394 /* marker expires--granted mark number limit */
1395 remove_ob (op);
1396 free_object (op);
1397 return;
1398 }
1399 } 1367 }
1400 } /* if tmp2 == NULL */ 1368 }
1401 } /* if tmp->type == PLAYER */ 1369 }
1402 } /* For all objects on this space */
1403} 1370}
1404 1371
1405int 1372int
1406process_object (object *op) 1373process_object (object *op)
1407{ 1374{
1440 if (QUERY_FLAG (op, FLAG_APPLIED)) 1407 if (QUERY_FLAG (op, FLAG_APPLIED))
1441 remove_force (op); 1408 remove_force (op);
1442 else 1409 else
1443 { 1410 {
1444 /* IF necessary, delete the item from the players inventory */ 1411 /* IF necessary, delete the item from the players inventory */
1445 object *pl = is_player_inv (op); 1412 object *pl = op->in_player ();
1446 1413
1447 if (pl) 1414 if (pl)
1448 esrv_del_item (pl->contr, op->count); 1415 esrv_del_item (pl->contr, op->count);
1449 1416
1450 remove_ob (op); 1417 op->remove ();
1451 1418
1452 if (QUERY_FLAG (op, FLAG_SEE_ANYWHERE)) 1419 if (QUERY_FLAG (op, FLAG_SEE_ANYWHERE))
1453 make_sure_not_seen (op); 1420 make_sure_not_seen (op);
1454 1421
1455 free_object (op); 1422 op->destroy ();
1456 } 1423 }
1457 1424
1458 return 1; 1425 return 1;
1459 } 1426 }
1427
1460 switch (op->type) 1428 switch (op->type)
1461 { 1429 {
1462 case SPELL_EFFECT: 1430 case SPELL_EFFECT:
1463 move_spell_effect (op); 1431 move_spell_effect (op);
1464 return 1; 1432 return 1;
1490 return 0; 1458 return 0;
1491 1459
1492 case THROWN_OBJ: 1460 case THROWN_OBJ:
1493 case ARROW: 1461 case ARROW:
1494 move_arrow (op); 1462 move_arrow (op);
1495 return 0;
1496
1497 case LIGHTNING: /* It now moves twice as fast */
1498 move_bolt (op);
1499 return 0; 1463 return 0;
1500 1464
1501 case DOOR: 1465 case DOOR:
1502 remove_door (op); 1466 remove_door (op);
1503 return 0; 1467 return 0;

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines