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.13 by root, Sat Sep 16 22:24:13 2006 UTC vs.
Revision 1.30 by root, Sun Dec 31 21:02:05 2006 UTC

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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines