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.52 by root, Tue May 22 10:50:01 2007 UTC vs.
Revision 1.67 by root, Tue Sep 4 08:42:58 2007 UTC

1/* 1/*
2 * CrossFire, A Multiplayer game 2 * This file is part of Crossfire TRT, the Roguelike Realtime MORPG.
3 * 3 *
4 * Copyright (C) 2005, 2006, 2007 Marc Lehmann & Crossfire+ Development Team 4 * Copyright (©) 2005,2006,2007 Marc Alexander Lehmann / Robin Redeker / the Crossfire TRT team
5 * Copyright (C) 2002 Mark Wedel & Crossfire Development Team 5 * Copyright (©) 2002,2007 Mark Wedel & Crossfire Development Team
6 * Copyright (C) 1992 Frank Tore Johansen 6 * Copyright (©) 1992,2007 Frank Tore Johansen
7 * 7 *
8 * This program is free software; you can redistribute it and/or modify 8 * Crossfire TRT is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by 9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or 10 * the Free Software Foundation, either version 3 of the License, or
11 * (at your option) any later version. 11 * (at your option) any later version.
12 * 12 *
13 * This program is distributed in the hope that it will be useful, 13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details. 16 * GNU General Public License for more details.
17 * 17 *
18 * You should have received a copy of the GNU General Public License 18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software 19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 * 20 *
22 * The authors can be reached via e-mail at <crossfire@schmorp.de> 21 * The authors can be reached via e-mail to <crossfire@schmorp.de>
23 */ 22 */
24 23
25/* 24/*
26 * Routines that is executed from objects based on their speed have been 25 * Routines that is executed from objects based on their speed have been
27 * collected in this file. 26 * collected in this file.
97 96
98 if (GENERATE_SPEED (gen) && rndm (0, GENERATE_SPEED (gen) - 1)) 97 if (GENERATE_SPEED (gen) && rndm (0, GENERATE_SPEED (gen) - 1))
99 return; 98 return;
100 99
101 object *op; 100 object *op;
101 int dir;
102 102
103 if (QUERY_FLAG (gen, FLAG_CONTENT_ON_GEN)) 103 if (QUERY_FLAG (gen, FLAG_CONTENT_ON_GEN))
104 { 104 {
105 // either copy one item form the inventory... 105 // either copy one item from the inventory...
106 if (!gen->inv) 106 if (!gen->inv)
107 return; 107 return;
108 108
109 // first select one item from the inventory 109 // first select one item from the inventory
110 int index = 0; 110 int index = 0;
111 for (object *tmp = gen->inv; tmp; tmp = tmp->below) 111 for (object *tmp = gen->inv; tmp; tmp = tmp->below)
112 if (!rndm (++index)) 112 if (!rndm (++index))
113 op = tmp; 113 op = tmp;
114 114
115 dir = find_free_spot (op, gen->map, gen->x, gen->y, 1, SIZEOFFREE1 + 1);
116 if (dir < 0)
117 return;
118
115 op = object_create_clone (op); 119 op = object_create_clone (op);
116 120
117 CLEAR_FLAG (op, FLAG_IS_A_TEMPLATE); 121 CLEAR_FLAG (op, FLAG_IS_A_TEMPLATE);
118 unflag_inv (op, FLAG_IS_A_TEMPLATE); 122 unflag_inv (op, FLAG_IS_A_TEMPLATE);
119 } 123 }
124 else if (gen->other_arch)
125 {
126 // ...or use other_arch
127 dir = find_free_spot (gen->other_arch, gen->map, gen->x, gen->y, 1, SIZEOFFREE1 + 1);
128 if (dir < 0)
129 return;
130
131 op = arch_to_object (gen->other_arch);
132 }
120 else 133 else
121 {
122 // ...or use other_arch
123 if (archetype *at = gen->other_arch)
124 op = arch_to_object (at);
125 else
126 return; 134 return;
127 }
128 135
129 op->expand_tail (); 136 op->expand_tail ();
130 137
131 int i = find_free_spot (op, gen->map, gen->x, gen->y, 1, 9); 138 mapxy pos (gen); pos.move (dir);
132 if (i >= 0) 139
140 if (pos.insert (op, gen))
133 { 141 {
134 if (insert_ob_in_map_at (op, gen->map, gen, 0, gen->x + freearr_x[i], gen->y + freearr_y[i]))
135 {
136 if (rndm (0, 9)) 142 if (rndm (0, 9))
137 generate_artifact (op, gen->map->difficulty); 143 generate_artifact (op, gen->map->difficulty);
138 144
139 if (op->has_random_items ()) 145 if (op->has_random_items ())
140 create_treasure (op->randomitems, op, GT_APPLY, gen->map->difficulty); 146 create_treasure (op->randomitems, op, GT_APPLY, gen->map->difficulty);
141 147
142 return; 148 return;
143 }
144 } 149 }
145 150
146 op->destroy (); 151 op->destroy ();
147} 152}
148 153
235 if (op->value) 240 if (op->value)
236 { 241 {
237 if (--op->stats.wc <= 0) 242 if (--op->stats.wc <= 0)
238 { /* Reached bottom, let's stop */ 243 { /* Reached bottom, let's stop */
239 op->stats.wc = 0; 244 op->stats.wc = 0;
240 if (op->arch->clone.speed) 245 if (op->arch->speed)
241 op->value = 0; 246 op->value = 0;
242 else 247 else
243 op->set_speed (0); 248 op->set_speed (0);
244 } 249 }
245 250
265 * objects are above the gate. If so, we finish closing the gate, 270 * objects are above the gate. If so, we finish closing the gate,
266 * otherwise, we fall through to the code below which should lower 271 * otherwise, we fall through to the code below which should lower
267 * the gate slightly. 272 * the gate slightly.
268 */ 273 */
269 274
270 for (tmp = op->above; tmp != NULL; tmp = tmp->above) 275 for (tmp = op->above; tmp; tmp = tmp->above)
271 if (!QUERY_FLAG (tmp, FLAG_NO_PICK) || QUERY_FLAG (tmp, FLAG_CAN_ROLL) || QUERY_FLAG (tmp, FLAG_ALIVE)) 276 if (!QUERY_FLAG (tmp, FLAG_NO_PICK) || QUERY_FLAG (tmp, FLAG_CAN_ROLL) || QUERY_FLAG (tmp, FLAG_ALIVE))
272 break; 277 break;
273 278
274 if (tmp == NULL) 279 if (!tmp)
275 { 280 {
276 if (op->arch->clone.speed) 281 if (op->arch->speed)
277 op->value = 1; 282 op->value = 1;
278 else 283 else
279 op->set_speed (0); 284 op->set_speed (0);
280 285
281 return; 286 return;
310 if (tmp) 315 if (tmp)
311 { 316 {
312 if (QUERY_FLAG (tmp, FLAG_ALIVE)) 317 if (QUERY_FLAG (tmp, FLAG_ALIVE))
313 { 318 {
314 hit_player (tmp, random_roll (0, op->stats.dam, tmp, PREFER_LOW), op, AT_PHYSICAL, 1); 319 hit_player (tmp, random_roll (0, op->stats.dam, tmp, PREFER_LOW), op, AT_PHYSICAL, 1);
320 op->play_sound (sound_find ("blocked_gate"));
315 321
316 if (tmp->type == PLAYER) 322 if (tmp->type == PLAYER)
317 new_draw_info_format (NDI_UNIQUE, 0, tmp, "You are crushed by the %s!", &op->name); 323 new_draw_info_format (NDI_UNIQUE, 0, tmp, "You are crushed by the %s!", &op->name);
318 } 324 }
319 else
320 /* If the object is not alive, and the object either can 325 /* If the object is not alive, and the object either can
321 * be picked up or the object rolls, move the object 326 * be picked up or the object rolls, move the object
322 * off the gate. 327 * off the gate.
323 */ 328 */
324 if (!QUERY_FLAG (tmp, FLAG_ALIVE) && (!QUERY_FLAG (tmp, FLAG_NO_PICK) || QUERY_FLAG (tmp, FLAG_CAN_ROLL))) 329 else if (!QUERY_FLAG (tmp, FLAG_ALIVE) && (!QUERY_FLAG (tmp, FLAG_NO_PICK) || QUERY_FLAG (tmp, FLAG_CAN_ROLL)))
325 { 330 {
326 /* If it has speed, it should move itself, otherwise: */ 331 /* If it has speed, it should move itself, otherwise: */
327 int i = find_free_spot (tmp, op->map, op->x, op->y, 1, 9); 332 int i = find_free_spot (tmp, op->map, op->x, op->y, 1, 9);
328 333
329 /* If there is a free spot, move the object someplace */ 334 /* If there is a free spot, move the object someplace */
335 } 340 }
336 } 341 }
337 } 342 }
338 343
339 /* See if there is still anything blocking the gate */ 344 /* See if there is still anything blocking the gate */
340 for (tmp = op->above; tmp != NULL; tmp = tmp->above) 345 for (tmp = op->above; tmp; tmp = tmp->above)
341 if (!QUERY_FLAG (tmp, FLAG_NO_PICK) || QUERY_FLAG (tmp, FLAG_CAN_ROLL) || QUERY_FLAG (tmp, FLAG_ALIVE)) 346 if (!QUERY_FLAG (tmp, FLAG_NO_PICK) || QUERY_FLAG (tmp, FLAG_CAN_ROLL) || QUERY_FLAG (tmp, FLAG_ALIVE))
342 break; 347 break;
343 348
344 /* IF there is, start putting the gate down */ 349 /* IF there is, start putting the gate down */
345 if (tmp) 350 if (tmp)
346 {
347 op->stats.food = 1; 351 op->stats.food = 1;
348 }
349 else 352 else
350 { 353 {
351 op->move_block = MOVE_ALL; 354 op->move_block = MOVE_ALL;
355
352 if (!op->arch->clone.stats.ac) 356 if (!op->arch->stats.ac)
353 SET_FLAG (op, FLAG_BLOCKSVIEW); 357 SET_FLAG (op, FLAG_BLOCKSVIEW);
354 update_all_los (op->map, op->x, op->y); 358 update_all_los (op->map, op->x, op->y);
355 } 359 }
356 } /* gate is halfway up */ 360 } /* gate is halfway up */
357 361
370 int v = op->value; 374 int v = op->value;
371 375
372 if (op->stats.sp) 376 if (op->stats.sp)
373 { 377 {
374 move_gate (op); 378 move_gate (op);
379
375 if (op->value != v) /* change direction ? */ 380 if (op->value != v) /* change direction ? */
376 op->stats.sp = 0; 381 op->stats.sp = 0;
377 return; 382 return;
378 } 383 }
384
379 if (--op->stats.hp <= 0) 385 if (--op->stats.hp <= 0)
380 { /* keep gate down */ 386 { /* keep gate down */
381 move_gate (op); 387 move_gate (op);
388
382 if (op->value != v) 389 if (op->value != v)
383 op->set_speed (0); 390 op->set_speed (0);
384 } 391 }
385} 392}
386 393
398 int last = op->value; 405 int last = op->value;
399 int detected; 406 int detected;
400 407
401 detected = 0; 408 detected = 0;
402 409
403 for (tmp = GET_MAP_OB (op->map, op->x, op->y); tmp != NULL && !detected; tmp = tmp->above) 410 for (tmp = op->ms ().bot; tmp && !detected; tmp = tmp->above)
404 { 411 {
405 object *tmp2; 412 object *tmp2;
406 413
407 if (op->stats.hp) 414 if (op->stats.hp)
408 { 415 {
428 if (detected && last == 0) 435 if (detected && last == 0)
429 { 436 {
430 op->value = 1; 437 op->value = 1;
431 push_button (op); 438 push_button (op);
432 } 439 }
440
433 if (!detected && last == 1) 441 if (!detected && last == 1)
434 { 442 {
435 op->value = 0; 443 op->value = 0;
436 push_button (op); 444 push_button (op);
437 } 445 }
441 if (detected && last == 1) 449 if (detected && last == 1)
442 { 450 {
443 op->value = 0; 451 op->value = 0;
444 push_button (op); 452 push_button (op);
445 } 453 }
454
446 if (!detected && last == 0) 455 if (!detected && last == 0)
447 { 456 {
448 op->value = 1; 457 op->value = 1;
449 push_button (op); 458 push_button (op);
450 } 459 }
451 } 460 }
452} 461}
453
454 462
455void 463void
456animate_trigger (object *op) 464animate_trigger (object *op)
457{ 465{
458 if ((unsigned char) ++op->stats.wc >= NUM_ANIMATIONS (op)) 466 if ((unsigned char) ++op->stats.wc >= NUM_ANIMATIONS (op))
490 498
491 SET_ANIMATION (op, op->stats.wc); 499 SET_ANIMATION (op, op->stats.wc);
492 update_object (op, UP_OBJ_FACE); 500 update_object (op, UP_OBJ_FACE);
493 return; 501 return;
494 } 502 }
503
495 /* We're closing */ 504 /* We're closing */
496 op->move_on = 0; 505 op->move_on = 0;
497 506
498 op->stats.wc++; 507 op->stats.wc++;
499 if ((int) op->stats.wc >= NUM_ANIMATIONS (op)) 508 if ((int) op->stats.wc >= NUM_ANIMATIONS (op))
598 op->spellarg = NULL; 607 op->spellarg = NULL;
599 op->stats.sp = 0; 608 op->stats.sp = 0;
600 op->stats.hp = 0; 609 op->stats.hp = 0;
601 op->stats.grace = 0; 610 op->stats.grace = 0;
602 op->level = 0; 611 op->level = 0;
603 op->face = op->arch->clone.face; 612 op->face = op->arch->face;
604 op->owner = NULL; /* So that stopped arrows will be saved */ 613 op->owner = NULL; /* So that stopped arrows will be saved */
605 update_object (op, UP_OBJ_CHANGE); 614 update_object (op, UP_OBJ_CHANGE);
606 return op; 615 return op;
607} 616}
608 617
640/* Move an arrow along its course. op is the arrow or thrown object. 649/* Move an arrow along its course. op is the arrow or thrown object.
641 */ 650 */
642void 651void
643move_arrow (object *op) 652move_arrow (object *op)
644{ 653{
645 object *tmp;
646 sint16 new_x, new_y;
647 int was_reflected, mflags; 654 int was_reflected;
648 maptile *m;
649 655
650 if (op->map == NULL) 656 if (!op->map)
651 { 657 {
652 LOG (llevError, "BUG: Arrow had no map.\n"); 658 LOG (llevError, "BUG: Arrow had no map.\n");
653 op->destroy (); 659 op->destroy ();
654 return; 660 return;
655 } 661 }
685 stop_arrow (op); 691 stop_arrow (op);
686 return; 692 return;
687 } 693 }
688 694
689 /* Calculate target map square */ 695 /* Calculate target map square */
690 new_x = op->x + DIRX (op);
691 new_y = op->y + DIRY (op);
692 was_reflected = 0; 696 was_reflected = 0;
693 697
694 m = op->map; 698 mapxy pos (op); pos.move (op->direction);
695 mflags = get_map_flags (m, &m, new_x, new_y, &new_x, &new_y);
696 699
697 if (mflags & P_OUT_OF_MAP) 700 if (!pos.normalise ())
698 { 701 {
699 stop_arrow (op); 702 stop_arrow (op);
700 return; 703 return;
701 } 704 }
702 705
703 /* only need to look for living creatures if this flag is set */ 706 /* only need to look for living creatures if this flag is set */
704 if (mflags & P_IS_ALIVE) 707 if (pos->flags () & P_IS_ALIVE)
705 { 708 {
706 for (tmp = GET_MAP_OB (m, new_x, new_y); tmp != NULL; tmp = tmp->above) 709 object *tmp;
710
711 for (tmp = pos->bot; tmp; tmp = tmp->above)
707 if (QUERY_FLAG (tmp, FLAG_ALIVE)) 712 if (QUERY_FLAG (tmp, FLAG_ALIVE))
708 break; 713 break;
709 714
710 /* Not really fair, but don't let monsters hit themselves with 715 /* Not really fair, but don't let monsters hit themselves with
711 * their own arrow - this can be because they fire it then 716 * their own arrow - this can be because they fire it then
734 return; 739 return;
735 } 740 }
736 } /* if this is not hitting its owner */ 741 } /* if this is not hitting its owner */
737 } /* if there is something alive on this space */ 742 } /* if there is something alive on this space */
738 743
739 if (OB_TYPE_MOVE_BLOCK (op, GET_MAP_MOVE_BLOCK (m, new_x, new_y))) 744 if (OB_TYPE_MOVE_BLOCK (op, pos->move_block))
740 { 745 {
741 int retry = 0; 746 int retry = 0;
742 747
743 /* if the object doesn't reflect, stop the arrow from moving 748 /* if the object doesn't reflect, stop the arrow from moving
744 * note that this code will now catch cases where a monster is 749 * note that this code will now catch cases where a monster is
757 if (op->direction & 1) 762 if (op->direction & 1)
758 { 763 {
759 op->direction = absdir (op->direction + 4); 764 op->direction = absdir (op->direction + 4);
760 retry = 1; 765 retry = 1;
761 } 766 }
767
762 /* There were two blocks with identical code - 768 /* There were two blocks with identical code -
763 * use this retry here to make this one block 769 * use this retry here to make this one block
764 * that did the same thing. 770 * that did the same thing.
765 */ 771 */
766 while (retry < 2) 772 while (retry < 2)
767 { 773 {
768 int left, right, mflags;
769 maptile *m1;
770 sint16 x1, y1;
771
772 retry++; 774 retry++;
773 775
774 /* Need to check for P_OUT_OF_MAP: if the arrow is tavelling 776 /* Need to check for P_OUT_OF_MAP: if the arrow is travelling
775 * over a corner in a tiled map, it is possible that 777 * over a corner in a tiled map, it is possible that
776 * op->direction is within an adjacent map but either 778 * op->direction is within an adjacent map but either
777 * op->direction-1 or op->direction+1 does not exist. 779 * op->direction-1 or op->direction+1 does not exist.
778 */ 780 */
779 mflags = get_map_flags (op->map, &m1, op->x + freearr_x[absdir (op->direction - 1)], 781 mapxy pos1 (pos); pos1.move (absdir (op->direction - 1));
780 op->y + freearr_y[absdir (op->direction - 1)], &x1, &y1); 782 bool left = pos1.normalise () && OB_TYPE_MOVE_BLOCK (op, pos1->move_block);
781 left = (mflags & P_OUT_OF_MAP) ? 0 : OB_TYPE_MOVE_BLOCK (op, (GET_MAP_MOVE_BLOCK (m1, x1, y1)));
782 783
783 mflags = get_map_flags (op->map, &m1, op->x + freearr_x[absdir (op->direction + 1)], 784 mapxy pos2 (pos); pos2.move (absdir (op->direction + 1));
784 op->y + freearr_y[absdir (op->direction + 1)], &x1, &y1); 785 bool right = pos2.normalise () && OB_TYPE_MOVE_BLOCK (op, pos2->move_block);
785 right = (mflags & P_OUT_OF_MAP) ? 0 : OB_TYPE_MOVE_BLOCK (op, (GET_MAP_MOVE_BLOCK (m1, x1, y1)));
786 786
787 if (left == right) 787 if (left == right)
788 op->direction = absdir (op->direction + 4); 788 op->direction = absdir (op->direction + 4);
789 else if (left) 789 else if (left)
790 op->direction = absdir (op->direction + 2); 790 op->direction = absdir (op->direction + 2);
791 else if (right) 791 else if (right)
792 op->direction = absdir (op->direction - 2); 792 op->direction = absdir (op->direction - 2);
793 793
794 mflags = get_map_flags (op->map, &m1, op->x + DIRX (op), op->y + DIRY (op), &x1, &y1);
795
796 /* If this space is not out of the map and not blocked, valid space - 794 /* If this space is not out of the map and not blocked, valid space -
797 * don't need to retry again. 795 * don't need to retry again.
798 */ 796 */
799 if (!(mflags & P_OUT_OF_MAP) && !OB_TYPE_MOVE_BLOCK (op, GET_MAP_MOVE_BLOCK (m1, x1, y1))) 797 mapxy pos3 (pos); pos3.move (op->direction);
798 if (pos3.normalise () && !OB_TYPE_MOVE_BLOCK (op, pos3->move_block))
800 break; 799 break;
801
802 } 800 }
801
803 /* Couldn't find a direction to move the arrow to - just 802 /* Couldn't find a direction to move the arrow to - just
804 * top it from moving. 803 * stop it from moving.
805 */ 804 */
806 if (retry == 2) 805 if (retry == 2)
807 { 806 {
808 stop_arrow (op); 807 stop_arrow (op);
809 return; 808 return;
810 } 809 }
810
811 /* update object image for new facing */ 811 /* update object image for new facing */
812 /* many thrown objects *don't* have more than one face */ 812 /* many thrown objects *don't* have more than one face */
813 if (GET_ANIM_ID (op)) 813 if (GET_ANIM_ID (op))
814 SET_ANIMATION (op, op->direction); 814 SET_ANIMATION (op, op->direction);
815 } /* object is reflected */ 815 } /* object is reflected */
816 } /* object ran into a wall */ 816 } /* object ran into a wall */
817 817
818 /* Move the arrow. */
819 op->remove ();
820 op->x = new_x;
821 op->y = new_y;
822
823 /* decrease the speed as it flies. 0.05 means a standard bow will shoot 818 /* decrease the speed as it flies. 0.05 means a standard bow will shoot
824 * about 17 squares. Tune as needed. 819 * about 17 squares. Tune as needed.
825 */ 820 */
826 op->speed -= 0.05; 821 op->speed -= 0.05;
827 insert_ob_in_map (op, m, op, 0);
828}
829 822
830/* This routine doesnt seem to work for "inanimate" objects that 823 /* Move the arrow. */
831 * are being carried, ie a held torch leaps from your hands!. 824 op->move_to (pos);
832 * Modified this routine to allow held objects. b.t. */ 825}
833 826
834void 827void
835change_object (object *op) 828change_object (object *op)
836{ /* Doesn`t handle linked objs yet */ 829{ /* Doesn`t handle linked objs yet */
837 int i, j; 830 int i, j;
838 831
839 if (op->other_arch == NULL) 832 if (!op->other_arch)
840 { 833 {
841 LOG (llevError, "Change object (%s) without other_arch error.\n", &op->name); 834 LOG (llevError, "Change object (%s) without other_arch error.\n", op->debug_desc ());
842 return; 835 return;
843 } 836 }
844 837
845 /* In non-living items only change when food value is 0 */ 838 /* In non-living items only change when food value is 0 */
846 if (!QUERY_FLAG (op, FLAG_ALIVE)) 839 if (!QUERY_FLAG (op, FLAG_ALIVE))
847 { 840 {
848 if (op->stats.food-- > 0) 841 if (op->stats.food-- > 0)
849 return; 842 return;
850 else 843
851 op->stats.food = 1; /* so 1 other_arch is made */ 844 op->stats.food = 1; /* so 1 other_arch is made */
852 } 845 }
853 846
854 object *pl = op->in_player ();
855 object *env = op->env; 847 object *env = op->env;
856 848
857 op->remove (); 849 op->remove ();
858 for (i = 0; i < NROFNEWOBJS (op); i++) 850 for (i = 0; i < op->stats.food; i++)
859 { 851 {
860 object *tmp = arch_to_object (op->other_arch); 852 object *tmp = arch_to_object (op->other_arch);
861 853
862 if (op->type == LAMP) 854 if (op->type == LAMP)
863 tmp->stats.food = op->stats.food - 1; 855 tmp->stats.food = op->stats.food - 1;
864 856
865 tmp->stats.hp = op->stats.hp; /* The only variable it keeps. */ 857 tmp->stats.hp = op->stats.hp; /* The only variable it keeps. */
866 if (env) 858 if (env)
867 { 859 {
868 tmp->x = env->x, tmp->y = env->y;
869 tmp = insert_ob_in_ob (tmp, env); 860 tmp = env->insert (tmp);
870 861
871 /* If this object is the players inventory, we need to tell the 862 /* If this object is the players inventory, we need to tell the
872 * client of the change. Insert_ob_in_map takes care of the 863 * client of the change. Insert_ob_in_map takes care of the
873 * updating the client, so we don't need to do that below. 864 * updating the client, so we don't need to do that below.
874 */ 865 */
875 if (pl) 866 if (object *pl = op->in_player ())
876 { 867 {
877 esrv_del_item (pl->contr, op->count); 868 esrv_del_item (pl->contr, op->count);
878 esrv_send_item (pl, tmp); 869 esrv_send_item (pl, tmp);
879 } 870 }
880 } 871 }
881 else 872 else
882 { 873 {
883 j = find_first_free_spot (tmp, op->map, op->x, op->y); 874 j = find_first_free_spot (tmp, op->map, op->x, op->y);
884 if (j == -1) /* No free spot */ 875 if (j < 0) /* No free spot */
885 tmp->destroy (); 876 tmp->destroy ();
886 else 877 else
887 { 878 {
888 tmp->x = op->x + freearr_x[j], tmp->y = op->y + freearr_y[j]; 879 mapxy pos (op); pos.move (j);
889 insert_ob_in_map (tmp, op->map, op, 0); 880
881 if (pos.normalise ())
882 pos.insert (tmp, op);
890 } 883 }
891 } 884 }
892 } 885 }
893 886
894 op->destroy (); 887 op->destroy ();
910 move_teleporter (op->more); 903 move_teleporter (op->more);
911 904
912 if (op->head) 905 if (op->head)
913 head = op->head; 906 head = op->head;
914 907
915 for (tmp = op->above; tmp != NULL; tmp = tmp->above) 908 for (tmp = op->above; tmp; tmp = tmp->above)
916 if (!QUERY_FLAG (tmp, FLAG_IS_FLOOR)) 909 if (!QUERY_FLAG (tmp, FLAG_IS_FLOOR))
917 break; 910 break;
918 911
919 /* If nothing above us to move, nothing to do */ 912 /* If nothing above us to move, nothing to do */
920 if (!tmp || QUERY_FLAG (tmp, FLAG_WIZPASS)) 913 if (!tmp || QUERY_FLAG (tmp, FLAG_WIZPASS))
1015 return; /* dm has created a firewall in his inventory */ 1008 return; /* dm has created a firewall in his inventory */
1016 1009
1017 spell = op->inv; 1010 spell = op->inv;
1018 1011
1019 if (!spell || spell->type != SPELL) 1012 if (!spell || spell->type != SPELL)
1020 spell = &op->other_arch->clone; 1013 spell = op->other_arch;
1021 1014
1022 if (!spell) 1015 if (!spell)
1023 { 1016 {
1024 LOG (llevError, "move_firewall: no spell specified (%s, %s, %d, %d)\n", &op->name, &op->map->name, op->x, op->y); 1017 LOG (llevError, "move_firewall: no spell specified (%s, %s, %d, %d)\n", &op->name, &op->map->name, op->x, op->y);
1025 return; 1018 return;
1136 if (op->above == NULL) 1129 if (op->above == NULL)
1137 return; 1130 return;
1138 1131
1139 for (tmp = op->above; tmp; tmp = tmp->above) 1132 for (tmp = op->above; tmp; tmp = tmp->above)
1140 { 1133 {
1141 if (op->other_arch->name == tmp->arch->name) 1134 if (op->other_arch->archname == tmp->arch->archname)
1142 { 1135 {
1143 if (op->level <= 0) 1136 if (op->level <= 0)
1144 tmp->destroy (); 1137 tmp->destroy ();
1145 else 1138 else
1146 { 1139 {
1168 * has to make sure that there is in fact space for the object. 1161 * has to make sure that there is in fact space for the object.
1169 * It should really do this for small objects also, but there is 1162 * It should really do this for small objects also, but there is
1170 * more concern with large objects, most notably a part being placed 1163 * more concern with large objects, most notably a part being placed
1171 * outside of the map which would cause the server to crash 1164 * outside of the map which would cause the server to crash
1172*/ 1165*/
1173
1174void 1166void
1175move_creator (object *creator) 1167move_creator (object *creator)
1176{ 1168{
1177 object *new_ob; 1169 object *new_ob;
1178 1170
1218 if (new_ob->arch->more && ob_blocked (new_ob, creator->map, creator->x, creator->y)) 1210 if (new_ob->arch->more && ob_blocked (new_ob, creator->map, creator->x, creator->y))
1219 { 1211 {
1220 new_ob->destroy (); 1212 new_ob->destroy ();
1221 return; 1213 return;
1222 } 1214 }
1215
1216 // for now lets try to identify everything generated here, it mostly
1217 // happens automated, so this will at least fix many identify-experience holes
1218 SET_FLAG (new_ob, FLAG_IDENTIFIED);
1223 1219
1224 insert_ob_in_map_at (new_ob, creator->map, creator, 0, creator->x, creator->y); 1220 insert_ob_in_map_at (new_ob, creator->map, creator, 0, creator->x, creator->y);
1225 if (QUERY_FLAG (new_ob, FLAG_FREED)) 1221 if (QUERY_FLAG (new_ob, FLAG_FREED))
1226 return; 1222 return;
1227 1223
1242void 1238void
1243move_marker (object *op) 1239move_marker (object *op)
1244{ 1240{
1245 if (object *tmp = op->ms ().player ()) 1241 if (object *tmp = op->ms ().player ())
1246 { 1242 {
1247 object *tmp2;
1248
1249 /* remove an old force with a slaying field == op->name */ 1243 /* remove an old force with a slaying field == op->name */
1250 for (tmp2 = tmp->inv; tmp2; tmp2 = tmp2->below) 1244 if (object *force = tmp->force_find (op->name))
1251 if (tmp2->type == FORCE && tmp2->slaying && tmp2->slaying == op->name) 1245 force->destroy ();
1246
1247 if (!tmp->force_find (op->slaying))
1252 { 1248 {
1253 tmp2->destroy (); 1249 tmp->force_add (op->slaying, op->stats.food);
1254 break;
1255 }
1256 1250
1257 /* cycle through his inventory to look for the MARK we want to
1258 * place
1259 */
1260 for (tmp2 = tmp->inv; tmp2; tmp2 = tmp2->below)
1261 if (tmp2->type == FORCE && tmp2->slaying && tmp2->slaying == op->slaying)
1262 break;
1263
1264 /* if we didn't find our own MARK */
1265 if (!tmp2)
1266 {
1267 object *force = get_archetype (FORCE_NAME);
1268
1269 if (op->stats.food)
1270 {
1271 force->set_speed (0.01);
1272 force->speed_left = -op->stats.food;
1273 }
1274 else
1275 force->set_speed (0);
1276
1277 /* put in the lock code */
1278 force->slaying = op->slaying;
1279
1280 if (op->lore)
1281 force->lore = op->lore;
1282
1283 insert_ob_in_ob (force, tmp);
1284 if (op->msg) 1251 if (op->msg)
1285 new_draw_info (NDI_UNIQUE | NDI_NAVY, 0, tmp, op->msg); 1252 new_draw_info (NDI_UNIQUE | NDI_NAVY, 0, tmp, op->msg);
1286 1253
1287 if (op->stats.hp > 0) 1254 if (op->stats.hp > 0)
1288 { 1255 {
1289 op->stats.hp--; 1256 op->stats.hp--;
1257
1290 if (op->stats.hp == 0) 1258 if (op->stats.hp == 0)
1291 { 1259 {
1292 /* marker expires--granted mark number limit */ 1260 /* marker expires--granted mark number limit */
1293 op->destroy (); 1261 op->destroy ();
1294 return; 1262 return;
1299} 1267}
1300 1268
1301void 1269void
1302process_object (object *op) 1270process_object (object *op)
1303{ 1271{
1304 if (QUERY_FLAG (op, FLAG_IS_A_TEMPLATE)) 1272 if (expect_false (QUERY_FLAG (op, FLAG_IS_A_TEMPLATE)))
1305 return; 1273 return;
1306 1274
1307 if (INVOKE_OBJECT (TICK, op)) 1275 if (expect_false (INVOKE_OBJECT (TICK, op)))
1308 return; 1276 return;
1309 1277
1310 if (QUERY_FLAG (op, FLAG_MONSTER)) 1278 if (QUERY_FLAG (op, FLAG_MONSTER))
1311 if (move_monster (op) || QUERY_FLAG (op, FLAG_FREED)) 1279 if (move_monster (op) || QUERY_FLAG (op, FLAG_FREED))
1312 return; 1280 return;
1317 1285
1318 if (QUERY_FLAG (op, FLAG_SEE_ANYWHERE)) 1286 if (QUERY_FLAG (op, FLAG_SEE_ANYWHERE))
1319 make_sure_seen (op); 1287 make_sure_seen (op);
1320 } 1288 }
1321 1289
1290 if (expect_false (
1322 if (op->flag [FLAG_GENERATOR] 1291 op->flag [FLAG_GENERATOR]
1323 || op->flag [FLAG_CHANGING] 1292 || op->flag [FLAG_CHANGING]
1324 || op->flag [FLAG_IS_USED_UP]) 1293 || op->flag [FLAG_IS_USED_UP]
1294 ))
1325 { 1295 {
1326 if (QUERY_FLAG (op, FLAG_CHANGING) && !op->state) 1296 if (QUERY_FLAG (op, FLAG_CHANGING) && !op->state)
1327 { 1297 {
1328 change_object (op); 1298 change_object (op);
1329 return; 1299 return;
1337 if (QUERY_FLAG (op, FLAG_APPLIED)) 1307 if (QUERY_FLAG (op, FLAG_APPLIED))
1338 remove_force (op); 1308 remove_force (op);
1339 else 1309 else
1340 { 1310 {
1341 /* If necessary, delete the item from the players inventory */ 1311 /* If necessary, delete the item from the players inventory */
1342 object *pl = op->in_player (); 1312 if (object *pl = op->in_player ())
1343
1344 if (pl)
1345 esrv_del_item (pl->contr, op->count); 1313 esrv_del_item (pl->contr, op->count);
1346 1314
1347 op->remove (); 1315 op->remove ();
1348 1316
1349 if (QUERY_FLAG (op, FLAG_SEE_ANYWHERE)) 1317 if (QUERY_FLAG (op, FLAG_SEE_ANYWHERE))

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines