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.80 by root, Mon Sep 29 10:20:49 2008 UTC vs.
Revision 1.103 by root, Fri Mar 26 00:53:26 2010 UTC

3 * 3 *
4 * Copyright (©) 2005,2006,2007,2008 Marc Alexander Lehmann / Robin Redeker / the Deliantra team 4 * Copyright (©) 2005,2006,2007,2008 Marc Alexander Lehmann / Robin Redeker / the Deliantra team
5 * Copyright (©) 2002,2007 Mark Wedel & Crossfire Development Team 5 * Copyright (©) 2002,2007 Mark Wedel & Crossfire Development Team
6 * Copyright (©) 1992,2007 Frank Tore Johansen 6 * Copyright (©) 1992,2007 Frank Tore Johansen
7 * 7 *
8 * Deliantra is free software: you can redistribute it and/or modify 8 * Deliantra is free software: you can redistribute it and/or modify it under
9 * it under the terms of the GNU General Public License as published by 9 * the terms of the Affero GNU General Public License as published by the
10 * the Free Software Foundation, either version 3 of the License, or 10 * Free Software Foundation, either version 3 of the License, or (at your
11 * (at your option) any later version. 11 * 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 Affero GNU General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>. 19 * and the GNU General Public License along with this program. If not, see
20 * <http://www.gnu.org/licenses/>.
20 * 21 *
21 * The authors can be reached via e-mail to <support@deliantra.net> 22 * The authors can be reached via e-mail to <support@deliantra.net>
22 */ 23 */
23 24
24/* 25/*
49 } 50 }
50 } 51 }
51 52
52 if (op->other_arch) 53 if (op->other_arch)
53 { 54 {
54 object *tmp = arch_to_object (op->other_arch); 55 object *tmp = op->other_arch->instance ();
55 tmp->x = op->x; 56 tmp->x = op->x;
56 tmp->y = op->y; 57 tmp->y = op->y;
57 tmp->map = op->map; 58 tmp->map = op->map;
58 tmp->level = op->level; 59 tmp->level = op->level;
59 insert_ob_in_map (tmp, op->map, op, 0); 60 insert_ob_in_map (tmp, op->map, op, 0);
60 } 61 }
61 62
62 op->destroy_inv (true); // be explicit about dropping 63 op->drop_and_destroy ();
63 op->destroy (true);
64} 64}
65 65
66void 66void
67remove_door2 (object *op) 67remove_door2 (object *op)
68{ 68{
79 } 79 }
80 } 80 }
81 81
82 if (op->other_arch) 82 if (op->other_arch)
83 { 83 {
84 tmp = arch_to_object (op->other_arch); 84 tmp = op->other_arch->instance ();
85 tmp->x = op->x; 85 tmp->x = op->x;
86 tmp->y = op->y; 86 tmp->y = op->y;
87 tmp->map = op->map; 87 tmp->map = op->map;
88 tmp->level = op->level; 88 tmp->level = op->level;
89 insert_ob_in_map (tmp, op->map, op, 0); 89 insert_ob_in_map (tmp, op->map, op, 0);
90 } 90 }
91 91
92 op->destroy_inv (true); // be explicit about dropping 92 op->drop_and_destroy ();
93 op->destroy (true);
94} 93}
95 94
96void 95static void
97generate_monster (object *gen) 96generate_monster (object *gen)
98{ 97{
99 if (!gen->map) 98 if (!gen->map)
100 return; 99 return;
101 100
102 if (GENERATE_SPEED (gen) && rndm (0, GENERATE_SPEED (gen) - 1)) 101 if (GENERATE_SPEED (gen) && rndm (0, GENERATE_SPEED (gen) - 1))
102 return;
103
104 // sleeping generators won't generate, this will make monsters like
105 // centipedes not generate more centipedes when being asleep.
106 if (gen->flag [FLAG_SLEEP])
103 return; 107 return;
104 108
105 object *op; 109 object *op;
106 int dir; 110 int dir;
107 111
131 // ...or use other_arch 135 // ...or use other_arch
132 dir = find_free_spot (gen->other_arch, gen->map, gen->x, gen->y, 1, SIZEOFFREE1 + 1); 136 dir = find_free_spot (gen->other_arch, gen->map, gen->x, gen->y, 1, SIZEOFFREE1 + 1);
133 if (dir < 0) 137 if (dir < 0)
134 return; 138 return;
135 139
136 op = arch_to_object (gen->other_arch); 140 op = gen->other_arch->instance ();
137 } 141 }
138 else 142 else
139 return; 143 return;
140 144
141 op->expand_tail (); 145 op->expand_tail ();
151 create_treasure (op->randomitems, op, GT_APPLY, gen->map->difficulty); 155 create_treasure (op->randomitems, op, GT_APPLY, gen->map->difficulty);
152 156
153 return; 157 return;
154 } 158 }
155 159
156 op->destroy (true); 160 op->destroy ();
157} 161}
158 162
159void 163static void
160remove_force (object *op) 164remove_force (object *op)
161{ 165{
162 if (--op->duration > 0) 166 if (--op->duration > 0)
163 return; 167 return;
164 168
173 CLEAR_FLAG (op, FLAG_APPLIED); 177 CLEAR_FLAG (op, FLAG_APPLIED);
174 change_abil (op->env, op); 178 change_abil (op->env, op);
175 op->env->update_stats (); 179 op->env->update_stats ();
176 } 180 }
177 181
178 op->destroy (true); 182 op->destroy ();
179} 183}
180 184
181void 185static void
182remove_blindness (object *op) 186remove_blindness (object *op)
183{ 187{
184 if (--op->stats.food > 0) 188 if (--op->stats.food > 0)
185 return; 189 return;
186 190
190 { 194 {
191 change_abil (op->env, op); 195 change_abil (op->env, op);
192 op->env->update_stats (); 196 op->env->update_stats ();
193 } 197 }
194 198
195 op->destroy (true); 199 op->destroy ();
196} 200}
197 201
198void 202static void
199poison_more (object *op) 203poison_more (object *op)
200{ 204{
201 if (op->env == NULL || !QUERY_FLAG (op->env, FLAG_ALIVE) || op->env->stats.hp < 0) 205 if (op->env == NULL || !QUERY_FLAG (op->env, FLAG_ALIVE) || op->env->stats.hp < 0)
202 { 206 {
203 op->destroy (true); 207 op->destroy ();
204 return; 208 return;
205 } 209 }
206 210
207 if (op->stats.food == 1) 211 if (op->stats.food == 1)
208 { 212 {
214 CLEAR_FLAG (op, FLAG_APPLIED); 218 CLEAR_FLAG (op, FLAG_APPLIED);
215 op->env->update_stats (); 219 op->env->update_stats ();
216 new_draw_info (NDI_UNIQUE, 0, op->env, "You feel much better now."); 220 new_draw_info (NDI_UNIQUE, 0, op->env, "You feel much better now.");
217 } 221 }
218 222
219 op->destroy (true); 223 op->destroy ();
220 return; 224 return;
221 } 225 }
222 226
223 if (op->env->type == PLAYER) 227 if (op->env->type == PLAYER)
224 { 228 {
228 232
229 hit_player (op->env, op->stats.dam, op, AT_INTERNAL, 1); 233 hit_player (op->env, op->stats.dam, op, AT_INTERNAL, 1);
230} 234}
231 235
232 236
233void 237static void
234move_gate (object *op) 238move_gate (object *op)
235{ /* 1 = going down, 0 = going up */ 239{ /* 1 = going down, 0 = going up */
236 object *tmp; 240 object *tmp;
237 241
238 if (op->stats.wc < 0 || (int) op->stats.wc >= NUM_ANIMATIONS (op)) 242 if (op->stats.wc < 0 || (int) op->stats.wc >= NUM_ANIMATIONS (op))
245 if (op->value) 249 if (op->value)
246 { 250 {
247 if (--op->stats.wc <= 0) 251 if (--op->stats.wc <= 0)
248 { /* Reached bottom, let's stop */ 252 { /* Reached bottom, let's stop */
249 op->stats.wc = 0; 253 op->stats.wc = 0;
250 if (op->arch->speed) 254 if (op->arch->has_active_speed ())
251 op->value = 0; 255 op->value = 0;
252 else 256 else
253 op->set_speed (0); 257 op->set_speed (0);
254 } 258 }
255 259
281 if (!QUERY_FLAG (tmp, FLAG_NO_PICK) || QUERY_FLAG (tmp, FLAG_CAN_ROLL) || QUERY_FLAG (tmp, FLAG_ALIVE)) 285 if (!QUERY_FLAG (tmp, FLAG_NO_PICK) || QUERY_FLAG (tmp, FLAG_CAN_ROLL) || QUERY_FLAG (tmp, FLAG_ALIVE))
282 break; 286 break;
283 287
284 if (!tmp) 288 if (!tmp)
285 { 289 {
286 if (op->arch->speed) 290 if (op->arch->has_active_speed ())
287 op->value = 1; 291 op->value = 1;
288 else 292 else
289 op->set_speed (0); 293 op->set_speed (0);
290 294
291 return; 295 return;
372 376
373/* hp : how long door is open/closed 377/* hp : how long door is open/closed
374 * maxhp : initial value for hp 378 * maxhp : initial value for hp
375 * sp : 1 = open, 0 = close 379 * sp : 1 = open, 0 = close
376 */ 380 */
377void 381static void
378move_timed_gate (object *op) 382move_timed_gate (object *op)
379{ 383{
380 int v = op->value; 384 int v = op->value;
381 385
382 if (op->stats.sp) 386 if (op->stats.sp)
401 * speed: frequency of 'glances' 405 * speed: frequency of 'glances'
402 * connected: connected value of detector 406 * connected: connected value of detector
403 * sp: 1 if detection sets buttons 407 * sp: 1 if detection sets buttons
404 * -1 if detection unsets buttons 408 * -1 if detection unsets buttons
405 */ 409 */
406 410static void
407void
408move_detector (object *op) 411move_detector (object *op)
409{ 412{
410 object *tmp; 413 object *tmp;
411 int last = op->value; 414 int last = op->value;
412 int detected; 415 int detected;
439 if (op->stats.sp == 1) 442 if (op->stats.sp == 1)
440 { 443 {
441 if (detected && last == 0) 444 if (detected && last == 0)
442 { 445 {
443 op->value = 1; 446 op->value = 1;
444 push_button (op); 447 push_button (op, tmp);
445 } 448 }
446 449
447 if (!detected && last == 1) 450 if (!detected && last == 1)
448 { 451 {
449 op->value = 0; 452 op->value = 0;
450 push_button (op); 453 push_button (op, tmp);
451 } 454 }
452 } 455 }
453 else 456 else
454 { /* in this case, we unset buttons */ 457 { /* in this case, we unset buttons */
455 if (detected && last == 1) 458 if (detected && last == 1)
456 { 459 {
457 op->value = 0; 460 op->value = 0;
458 push_button (op); 461 push_button (op, tmp);
459 } 462 }
460 463
461 if (!detected && last == 0) 464 if (!detected && last == 0)
462 { 465 {
463 op->value = 1; 466 op->value = 1;
464 push_button (op); 467 push_button (op, tmp);
465 } 468 }
466 } 469 }
467} 470}
468 471
469void 472void
479 SET_ANIMATION (op, op->stats.wc); 482 SET_ANIMATION (op, op->stats.wc);
480 update_object (op, UP_OBJ_FACE); 483 update_object (op, UP_OBJ_FACE);
481 } 484 }
482} 485}
483 486
484void 487static void
485move_hole (object *op) 488move_hole (object *op)
486{ /* 1 = opening, 0 = closing */ 489{ /* 1 = opening, 0 = closing */
487 if (op->value) 490 if (op->value)
488 { /* We're opening */ 491 { /* We're opening */
489 if (--op->stats.wc <= 0) 492 if (--op->stats.wc <= 0)
545 548
546 if (payload == NULL) 549 if (payload == NULL)
547 return NULL; 550 return NULL;
548 551
549 payload->remove (); 552 payload->remove ();
550 op->destroy (true); 553 op->destroy ();
551 return payload; 554 return payload;
552 } 555 }
553 556
554 case ARROW: 557 case ARROW:
555 if (op->has_active_speed ()) 558 if (op->has_active_speed ())
582fix_stopped_arrow (object *op) 585fix_stopped_arrow (object *op)
583{ 586{
584 if (rndm (0, 99) < op->stats.food) 587 if (rndm (0, 99) < op->stats.food)
585 { 588 {
586 /* Small chance of breaking */ 589 /* Small chance of breaking */
587 op->destroy (true); 590 op->destroy ();
588 return NULL; 591 return NULL;
589 } 592 }
590 593
591 op->set_speed (0); 594 op->set_speed (0);
592 op->direction = 0; 595 op->direction = 0;
596 599
597 // restore original wc, dam, attacktype and slaying 600 // restore original wc, dam, attacktype and slaying
598 op->stats.wc = op->stats.sp; 601 op->stats.wc = op->stats.sp;
599 op->stats.dam = op->stats.hp; 602 op->stats.dam = op->stats.hp;
600 op->attacktype = op->stats.grace; 603 op->attacktype = op->stats.grace;
604 op->slaying = op->custom_name;
601 605
602 if (op->spellarg)
603 {
604 op->slaying = op->spellarg;
605 free (op->spellarg);
606 op->spellarg = 0;
607 }
608 else
609 op->slaying = 0;
610
611 /* Reset these to zero, so that object::can_merge will work properly */ 606 /* Reset these to defaults, so that object::can_merge will work properly */
612 op->spellarg = NULL; 607 op->custom_name = 0;
613 op->stats.sp = 0; 608 op->stats.sp = 0;
614 op->stats.hp = 0; 609 op->stats.hp = 0;
615 op->stats.grace = 0; 610 op->stats.grace = 0;
616 op->level = 0; 611 op->level = 0;
617 op->face = op->arch->face; 612 op->face = op->arch->face;
618 op->owner = NULL; /* So that stopped arrows will be saved */ 613 op->owner = 0;
614
619 update_object (op, UP_OBJ_CHANGE); 615 update_object (op, UP_OBJ_CHANGE);
616
620 return op; 617 return op;
621} 618}
622 619
623/* stop_arrow() - what to do when a non-living flying object 620/* stop_arrow() - what to do when a non-living flying object
624 * has to stop. Sept 96 - I added in thrown object code in 621 * has to stop. Sept 96 - I added in thrown object code in
638 // replace this by straightforward drop to ground? 635 // replace this by straightforward drop to ground?
639 object *payload = op->inv; 636 object *payload = op->inv;
640 637
641 payload->owner = 0; 638 payload->owner = 0;
642 insert_ob_in_map (payload, op->map, payload, 0); 639 insert_ob_in_map (payload, op->map, payload, 0);
643 op->destroy (true); 640 op->destroy ();
644 } 641 }
645 else 642 else
646 { 643 {
647 op = fix_stopped_arrow (op); 644 op = fix_stopped_arrow (op);
648 645
659 int was_reflected; 656 int was_reflected;
660 657
661 if (!op->map) 658 if (!op->map)
662 { 659 {
663 LOG (llevError, "BUG: Arrow had no map.\n"); 660 LOG (llevError, "BUG: Arrow had no map.\n");
664 op->destroy (true); 661 op->destroy ();
665 return; 662 return;
666 } 663 }
667 664
668 /* we need to stop thrown objects at some point. Like here. */ 665 /* we need to stop thrown objects at some point. Like here. */
669 if (op->type == THROWN_OBJ) 666 if (op->type == THROWN_OBJ)
676 * bomb code, but there are potential other cases where that could happen, 673 * bomb code, but there are potential other cases where that could happen,
677 * and it is easy enough to clean it up here. 674 * and it is easy enough to clean it up here.
678 */ 675 */
679 if (!op->inv) 676 if (!op->inv)
680 { 677 {
681 op->destroy (true); 678 op->destroy ();
682 return; 679 return;
683 } 680 }
684 681
685 if (op->last_sp-- < 0) 682 if (op->last_sp-- < 0)
686 { 683 {
813 return; 810 return;
814 } 811 }
815 812
816 /* update object image for new facing */ 813 /* update object image for new facing */
817 /* many thrown objects *don't* have more than one face */ 814 /* many thrown objects *don't* have more than one face */
818 if (GET_ANIM_ID (op)) 815 if (op->has_anim ())
819 SET_ANIMATION (op, op->direction); 816 op->set_anim_frame (op->direction);
820 } /* object is reflected */ 817 } /* object is reflected */
821 } /* object ran into a wall */ 818 } /* object ran into a wall */
822 819
823 /* decrease the speed as it flies. 0.05 means a standard bow will shoot 820 /* decrease the speed as it flies. 0.05 means a standard bow will shoot
824 * about 17 squares. Tune as needed. 821 * about 17 squares. Tune as needed.
827 824
828 /* Move the arrow. */ 825 /* Move the arrow. */
829 op->move_to (pos); 826 op->move_to (pos);
830} 827}
831 828
832void 829static void
833change_object (object *op) 830change_object (object *op)
834{ /* Doesn`t handle linked objs yet */ 831{ /* Doesn`t handle linked objs yet */
835 int i, j;
836
837 if (!op->other_arch) 832 if (!op->other_arch)
838 { 833 {
839 LOG (llevError, "Change object (%s) without other_arch error.\n", op->debug_desc ()); 834 LOG (llevError, "Change object (%s) without other_arch error.\n", op->debug_desc ());
840 return; 835 return;
841 } 836 }
850 } 845 }
851 846
852 object *env = op->env; 847 object *env = op->env;
853 848
854 op->remove (); 849 op->remove ();
855 for (i = 0; i < op->stats.food; i++) 850 for (int i = 0; i < op->stats.food; i++)
856 { 851 {
857 object *tmp = arch_to_object (op->other_arch); 852 object *tmp = op->other_arch->instance ();
858
859 if (op->type == LAMP)
860 tmp->stats.food = op->stats.food - 1;
861 853
862 tmp->stats.hp = op->stats.hp; /* The only variable it keeps. */ 854 tmp->stats.hp = op->stats.hp; /* The only variable it keeps. */
863 855
864 if (env) 856 if (env)
865 env->insert (tmp); 857 env->insert (tmp);
866 else 858 else
867 { 859 {
868 j = find_first_free_spot (tmp, op->map, op->x, op->y); 860 int j = find_first_free_spot (tmp, op->map, op->x, op->y);
861
869 if (j < 0) /* No free spot */ 862 if (j < 0) /* No free spot */
870 tmp->destroy (true); 863 tmp->destroy ();
871 else 864 else
872 { 865 {
873 mapxy pos (op); pos.move (j); 866 mapxy pos (op); pos.move (j);
874 867
875 if (pos.normalise ()) 868 if (pos.normalise ())
876 pos.insert (tmp, op); 869 pos.insert (tmp, op);
877 } 870 }
878 } 871 }
879 } 872 }
880 873
881 op->destroy (true); 874 op->destroy ();
882} 875}
883 876
884void 877void
885move_teleporter (object *op) 878move_teleporter (object *op)
886{ 879{
923 else if (EXIT_X (head) || EXIT_Y (head)) 916 else if (EXIT_X (head) || EXIT_Y (head))
924 { 917 {
925 if (out_of_map (head->map, EXIT_X (head), EXIT_Y (head))) 918 if (out_of_map (head->map, EXIT_X (head), EXIT_Y (head)))
926 { 919 {
927 LOG (llevError, "Removed illegal teleporter.\n"); 920 LOG (llevError, "Removed illegal teleporter.\n");
928 head->destroy (true); 921 head->destroy ();
929 return; 922 return;
930 } 923 }
931 924
932 if (INVOKE_OBJECT (TRIGGER, op, ARG_OBJECT (tmp))) 925 if (INVOKE_OBJECT (TRIGGER, op, ARG_OBJECT (tmp)))
933 return; 926 return;
947/* This object will teleport someone to a different map 940/* This object will teleport someone to a different map
948 and will also apply changes to the player from its inventory. 941 and will also apply changes to the player from its inventory.
949 This was invented for giving classes, but there's no reason it 942 This was invented for giving classes, but there's no reason it
950 can't be generalized. 943 can't be generalized.
951*/ 944*/
952void 945static void
953move_player_changer (object *op) 946move_player_changer (object *op)
954{ 947{
955 object *player;
956 object *walk;
957
958 if (!op->above || !EXIT_PATH (op)) 948 if (!op->above || !EXIT_PATH (op))
959 return; 949 return;
960 950
961 /* This isn't all that great - means that the player_mover 951 /* This isn't all that great - means that the player_mover
962 * needs to be on top. 952 * needs to be on top.
963 */ 953 */
964 if (op->above->type == PLAYER) 954 if (op->above->type == PLAYER)
965 { 955 {
956 object *player = op->above;
957
966 if (INVOKE_OBJECT (TRIGGER, op, ARG_OBJECT (player))) 958 if (INVOKE_OBJECT (TRIGGER, op, ARG_OBJECT (player)))
967 return; 959 return;
968 960
969 player = op->above;
970
971 for (walk = op->inv; walk; walk = walk->below) 961 for (object *walk = op->inv; walk; walk = walk->below)
972 apply_changes_to_player (player, walk); 962 apply_changes_to_player (player, walk);
973 963
974 player->update_stats (); 964 player->update_stats ();
975 965
976 esrv_send_inventory (op->above, op->above); 966 esrv_send_inventory (op->above, op->above);
1023 * moves them in the op->stats.sp direction. speed is how often it'll move. 1013 * moves them in the op->stats.sp direction. speed is how often it'll move.
1024 * If attacktype is nonzero it will paralyze the player. If lifesave is set, 1014 * If attacktype is nonzero it will paralyze the player. If lifesave is set,
1025 * it'll dissapear after hp+1 moves. If hp is set and attacktype is set, 1015 * it'll dissapear after hp+1 moves. If hp is set and attacktype is set,
1026 * it'll paralyze the victim for hp*his speed/op->speed 1016 * it'll paralyze the victim for hp*his speed/op->speed
1027 */ 1017 */
1028void 1018static void
1029move_player_mover (object *op) 1019move_player_mover (object *op)
1030{ 1020{
1031 int dir = op->stats.sp; 1021 int dir = op->stats.sp;
1032 sint16 nx, ny; 1022 sint16 nx, ny;
1033 maptile *m; 1023 maptile *m;
1077 /* only level >=1 movers move people */ 1067 /* only level >=1 movers move people */
1078 if (op->level) 1068 if (op->level)
1079 { 1069 {
1080 /* Following is a bit of hack. We need to make sure it 1070 /* Following is a bit of hack. We need to make sure it
1081 * is cleared, otherwise the player will get stuck in 1071 * is cleared, otherwise the player will get stuck in
1082 * place. This can happen if the player used a spell to 1072 * place. This can happen if the player used a spell to
1083 * get to this space. 1073 * get to this space.
1084 */ 1074 */
1085 victim->contr->fire_on = 0; 1075 victim->contr->fire_on = 0;
1086 victim->speed_left = 1.f; 1076 victim->speed_left = 1.f;
1087 move_player (victim, dir); 1077 move_player (victim, dir);
1088 } 1078 }
1089 else 1079 else
1090 return; 1080 return;
1091 } 1081 }
1092 else 1082 else
1093 move_object (victim, dir); 1083 victim->move (dir);
1094 1084
1095 if (!op->stats.maxsp && op->attacktype) 1085 if (!op->stats.maxsp && op->attacktype)
1096 op->stats.maxsp = 2; 1086 op->stats.maxsp = 2;
1097 1087
1098 if (op->attacktype) 1088 if (op->attacktype)
1099 { /* flag to paralyze the player */ 1089 { /* flag to paralyze the player */
1100 victim->speed_left = max (-5.f, -FABS (op->stats.maxsp * victim->speed / op->speed)); 1090 victim->speed_left = max (-5.f, -op->stats.maxsp * victim->speed / op->speed);
1101 } 1091 }
1102 } 1092 }
1103 } 1093 }
1104} 1094}
1105 1095
1127 for (tmp = op->above; tmp; tmp = tmp->above) 1117 for (tmp = op->above; tmp; tmp = tmp->above)
1128 { 1118 {
1129 if (op->other_arch->archname == tmp->arch->archname) 1119 if (op->other_arch->archname == tmp->arch->archname)
1130 { 1120 {
1131 if (op->level <= 0) 1121 if (op->level <= 0)
1132 tmp->destroy (true); 1122 tmp->destroy ();
1133 else 1123 else
1134 { 1124 {
1135 uint64 new_nrof = (uint64) tmp->nrof * op->level; 1125 uint64 new_nrof = (uint64) tmp->nrof * op->level;
1136 1126
1137 if (new_nrof >= 1UL << 31) 1127 if (new_nrof >= 1UL << 31)
1167 { 1157 {
1168 creator->stats.hp = -1; 1158 creator->stats.hp = -1;
1169 return; 1159 return;
1170 } 1160 }
1171 1161
1172 if (creator->inv != NULL) 1162 if (creator->inv)
1173 { 1163 {
1174 object *ob; 1164 object *ob;
1175 int i; 1165 int i;
1176 object *ob_to_copy; 1166 object *ob_to_copy;
1177 1167
1202 } 1192 }
1203 1193
1204 /* Make sure this multipart object fits */ 1194 /* Make sure this multipart object fits */
1205 if (new_ob->arch->more && new_ob->blocked (creator->map, creator->x, creator->y)) 1195 if (new_ob->arch->more && new_ob->blocked (creator->map, creator->x, creator->y))
1206 { 1196 {
1207 op->destroy_inv (false); // remove when desttroy does this
1208 new_ob->destroy (true); 1197 new_ob->destroy ();
1209 return; 1198 return;
1210 } 1199 }
1211 1200
1212 // for now lets try to identify everything generated here, it mostly 1201 // for now lets try to identify everything generated here, it mostly
1213 // happens automated, so this will at least fix many identify-experience holes 1202 // happens automated, so this will at least fix many identify-experience holes
1234{ 1223{
1235 if (object *tmp = op->ms ().player ()) 1224 if (object *tmp = op->ms ().player ())
1236 { 1225 {
1237 /* remove an old force with a slaying field == op->name */ 1226 /* remove an old force with a slaying field == op->name */
1238 if (object *force = tmp->force_find (op->name)) 1227 if (object *force = tmp->force_find (op->name))
1239 force->destroy (true); 1228 force->destroy ();
1240 1229
1241 if (!tmp->force_find (op->slaying)) 1230 if (op->slaying && !tmp->force_find (op->slaying))
1242 { 1231 {
1243 tmp->force_add (op->slaying, op->stats.food); 1232 tmp->force_add (op->slaying, op->stats.food);
1244 1233
1245 if (op->msg) 1234 if (op->msg)
1246 new_draw_info (NDI_UNIQUE | NDI_NAVY, 0, tmp, op->msg); 1235 new_draw_info (NDI_UNIQUE | NDI_NAVY, 0, tmp, op->msg);
1250 op->stats.hp--; 1239 op->stats.hp--;
1251 1240
1252 if (op->stats.hp == 0) 1241 if (op->stats.hp == 0)
1253 { 1242 {
1254 /* marker expires--granted mark number limit */ 1243 /* marker expires--granted mark number limit */
1255 op->destroy (true); 1244 op->destroy ();
1256 return; 1245 return;
1257 } 1246 }
1258 } 1247 }
1259 } 1248 }
1260 } 1249 }
1250}
1251
1252// mapscript objects activate themselves (only) then their timer fires
1253// TODO: maybe they should simply trigger the link like any other object?
1254static void
1255move_mapscript (object *op)
1256{
1257 op->set_speed (0);
1258 cfperl_mapscript_activate (op, true, op, 0);
1259}
1260
1261static void
1262move_lamp (object *op)
1263{
1264 // if the lamp/torch is off, we should disable it.
1265 if (!op->glow_radius)
1266 {
1267 op->set_speed (0);
1268 return;
1269 }
1270 else
1271 {
1272 // check whether the face might need to be updated
1273 // (currently this is needed to have already switched on torches
1274 // on maps, as they just set the glow_radius in the archetype)
1275 if (op->other_arch
1276 && (
1277 (op->flag [FLAG_ANIMATE] != op->other_arch->flag [FLAG_ANIMATE])
1278 || (op->flag [FLAG_ANIMATE]
1279 ? (op->animation_id != op->other_arch->animation_id)
1280 : (op->face != op->other_arch->face))
1281 ))
1282 get_animation_from_arch (op, op->other_arch);
1283 }
1284
1285 // lamps and torches on maps don't use up their fuel
1286 if (op->is_on_map ())
1287 return;
1288
1289 if (op->stats.food > 0)
1290 {
1291 op->stats.food--;
1292 return;
1293 }
1294
1295 apply_lamp (op, false);
1261} 1296}
1262 1297
1263void 1298void
1264process_object (object *op) 1299process_object (object *op)
1265{ 1300{
1305 op->remove (); // TODO: really necessary? 1340 op->remove (); // TODO: really necessary?
1306 1341
1307 if (QUERY_FLAG (op, FLAG_SEE_ANYWHERE)) 1342 if (QUERY_FLAG (op, FLAG_SEE_ANYWHERE))
1308 make_sure_not_seen (op); 1343 make_sure_not_seen (op);
1309 1344
1310 op->destroy_inv (false); // be explicit about dropping
1311 op->destroy (true); 1345 op->drop_and_destroy ();
1312 } 1346 }
1313 1347
1314 return; 1348 return;
1315 } 1349 }
1316 } 1350 }
1440 1474
1441 case PLAYER: 1475 case PLAYER:
1442 // players have their own speed-management, so undo the --speed_left 1476 // players have their own speed-management, so undo the --speed_left
1443 ++op->speed_left; 1477 ++op->speed_left;
1444 break; 1478 break;
1445 }
1446}
1447 1479
1480 case MAPSCRIPT:
1481 move_mapscript (op);
1482 break;
1483
1484 case LAMP:
1485 case TORCH:
1486 move_lamp (op);
1487 break;
1488 }
1489}
1490

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines