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.105 by root, Fri Mar 26 01:04:45 2010 UTC vs.
Revision 1.126 by root, Sat Nov 17 23:40:05 2018 UTC

1/* 1/*
2 * This file is part of Deliantra, the Roguelike Realtime MMORPG. 2 * This file is part of Deliantra, the Roguelike Realtime MMORPG.
3 * 3 *
4 * Copyright (©) 2017,2018 Marc Alexander Lehmann / the Deliantra team
4 * Copyright (©) 2005,2006,2007,2008,2009,2010 Marc Alexander Lehmann / Robin Redeker / the Deliantra team 5 * Copyright (©) 2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015,2016 Marc Alexander Lehmann / Robin Redeker / the Deliantra team
5 * Copyright (©) 2002 Mark Wedel & Crossfire Development Team 6 * Copyright (©) 2002 Mark Wedel & Crossfire Development Team
6 * Copyright (©) 1992 Frank Tore Johansen 7 * Copyright (©) 1992 Frank Tore Johansen
7 * 8 *
8 * Deliantra is free software: you can redistribute it and/or modify it under 9 * Deliantra is free software: you can redistribute it and/or modify it under
9 * the terms of the Affero GNU General Public License as published by the 10 * the terms of the Affero GNU General Public License as published by the
10 * Free Software Foundation, either version 3 of the License, or (at your 11 * Free Software Foundation, either version 3 of the License, or (at your
11 * option) any later version. 12 * option) any later version.
12 * 13 *
13 * This program is distributed in the hope that it will be useful, 14 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details. 17 * GNU General Public License for more details.
17 * 18 *
18 * You should have received a copy of the Affero GNU General Public License 19 * You should have received a copy of the Affero GNU General Public License
19 * and the GNU General Public License along with this program. If not, see 20 * and the GNU General Public License along with this program. If not, see
20 * <http://www.gnu.org/licenses/>. 21 * <http://www.gnu.org/licenses/>.
21 * 22 *
22 * The authors can be reached via e-mail to <support@deliantra.net> 23 * The authors can be reached via e-mail to <support@deliantra.net>
23 */ 24 */
24 25
25/* 26/*
26 * Routines that is executed from objects based on their speed have been 27 * Routines that is executed from objects based on their speed have been
28 */ 29 */
29#include <global.h> 30#include <global.h>
30#include <spells.h> 31#include <spells.h>
31#include <sproto.h> 32#include <sproto.h>
32 33
33/* The following removes doors. The functions check to see if similar 34/* The following removes doors. The functions check to see if similar
34 * doors are next to the one that is being removed, and if so, set it 35 * doors are next to the one that is being removed, and if so, set it
35 * so those will be removed shortly (in a cascade like fashion.) 36 * so those will be removed shortly (in a cascade like fashion.)
36 */ 37 */
37void 38void
38remove_door (object *op) 39remove_door (object *op)
69 int i; 70 int i;
70 object *tmp; 71 object *tmp;
71 72
72 for (i = 1; i < 9; i += 2) 73 for (i = 1; i < 9; i += 2)
73 { 74 {
74 tmp = present (LOCKED_DOOR, op->map, op->x + freearr_x[i], op->y + freearr_y[i]); 75 tmp = present (LOCKED_DOOR, op->map, op->x + DIRX (i), op->y + DIRY (i));
75 if (tmp && tmp->slaying == op->slaying) 76 if (tmp && tmp->slaying == op->slaying)
76 { /* same key both doors */ 77 { /* same key both doors */
77 tmp->set_speed (0.1f); 78 tmp->set_speed (0.1f);
78 tmp->speed_left = -0.2f; 79 tmp->speed_left = -0.2f;
79 } 80 }
107 return; 108 return;
108 109
109 object *op; 110 object *op;
110 int dir; 111 int dir;
111 112
112 if (QUERY_FLAG (gen, FLAG_CONTENT_ON_GEN)) 113 if (gen->flag [FLAG_CONTENT_ON_GEN])
113 { 114 {
114 // either copy one item from the inventory... 115 // either copy one item from the inventory...
115 if (!gen->inv) 116 if (!gen->inv)
116 return; 117 return;
117 118
125 if (dir < 0) 126 if (dir < 0)
126 return; 127 return;
127 128
128 op = op->deep_clone (); 129 op = op->deep_clone ();
129 130
130 CLEAR_FLAG (op, FLAG_IS_A_TEMPLATE); 131 op->clr_flag (FLAG_IS_A_TEMPLATE);
131 unflag_inv (op, FLAG_IS_A_TEMPLATE); 132 unflag_inv (op, FLAG_IS_A_TEMPLATE);
132 } 133 }
133 else if (gen->other_arch) 134 else if (gen->other_arch)
134 { 135 {
135 // ...or use other_arch 136 // ...or use other_arch
168 169
169 if (op->env) 170 if (op->env)
170 switch (op->subtype) 171 switch (op->subtype)
171 { 172 {
172 case FORCE_CONFUSION: 173 case FORCE_CONFUSION:
173 CLEAR_FLAG (op->env, FLAG_CONFUSED); 174 op->env->clr_flag (FLAG_CONFUSED);
174 new_draw_info (NDI_UNIQUE, 0, op->env, "You regain your senses.\n"); 175 new_draw_info (NDI_UNIQUE, 0, op->env, "You regain your senses.\n");
175 176
176 default: 177 default:
177 CLEAR_FLAG (op, FLAG_APPLIED); 178 op->clr_flag (FLAG_APPLIED);
178 change_abil (op->env, op); 179 change_abil (op->env, op);
179 op->env->update_stats (); 180 op->env->update_stats ();
180 } 181 }
181 182
182 op->destroy (); 183 op->destroy ();
186remove_blindness (object *op) 187remove_blindness (object *op)
187{ 188{
188 if (--op->stats.food > 0) 189 if (--op->stats.food > 0)
189 return; 190 return;
190 191
191 CLEAR_FLAG (op, FLAG_APPLIED); 192 op->clr_flag (FLAG_APPLIED);
192 193
193 if (op->env) 194 if (op->env)
194 { 195 {
195 change_abil (op->env, op); 196 change_abil (op->env, op);
196 op->env->update_stats (); 197 op->env->update_stats ();
200} 201}
201 202
202static void 203static void
203poison_more (object *op) 204poison_more (object *op)
204{ 205{
205 if (op->env == NULL || !QUERY_FLAG (op->env, FLAG_ALIVE) || op->env->stats.hp < 0) 206 if (op->env == NULL || !op->env->flag [FLAG_ALIVE] || op->env->stats.hp < 0)
206 { 207 {
207 op->destroy (); 208 op->destroy ();
208 return; 209 return;
209 } 210 }
210 211
213 /* need to unapply the object before update_stats is called, else fix_player 214 /* need to unapply the object before update_stats is called, else fix_player
214 * will not do anything. 215 * will not do anything.
215 */ 216 */
216 if (op->env->type == PLAYER) 217 if (op->env->type == PLAYER)
217 { 218 {
218 CLEAR_FLAG (op, FLAG_APPLIED); 219 op->clr_flag (FLAG_APPLIED);
219 op->env->update_stats (); 220 op->env->update_stats ();
220 new_draw_info (NDI_UNIQUE, 0, op->env, "You feel much better now."); 221 new_draw_info (NDI_UNIQUE, 0, op->env, "You feel much better now.");
221 } 222 }
222 223
223 op->destroy (); 224 op->destroy ();
239{ /* 1 = going down, 0 = going up */ 240{ /* 1 = going down, 0 = going up */
240 object *tmp; 241 object *tmp;
241 242
242 if (op->stats.wc < 0 || (int) op->stats.wc >= NUM_ANIMATIONS (op)) 243 if (op->stats.wc < 0 || (int) op->stats.wc >= NUM_ANIMATIONS (op))
243 { 244 {
244 LOG (llevError, "Gate error: animation was %d, max=%d\n", op->stats.wc, NUM_ANIMATIONS (op)); 245 LOG (llevError, "%s: gate error: animation was %d, max=%d\n", op->debug_desc (), op->stats.wc, NUM_ANIMATIONS (op));
245 op->stats.wc = 0; 246 op->stats.wc = 0;
246 } 247 }
247 248
248 /* We're going down */ 249 /* We're going down */
249 if (op->value) 250 if (op->value)
258 } 259 }
259 260
260 if ((int) op->stats.wc < (NUM_ANIMATIONS (op) / 2 + 1)) 261 if ((int) op->stats.wc < (NUM_ANIMATIONS (op) / 2 + 1))
261 { 262 {
262 op->move_block = 0; 263 op->move_block = 0;
263 CLEAR_FLAG (op, FLAG_BLOCKSVIEW); 264 op->clr_flag (FLAG_BLOCKSVIEW);
264 update_all_los (op->map, op->x, op->y); 265 update_all_los (op->map, op->x, op->y);
265 } 266 }
266 267
267 SET_ANIMATION (op, op->stats.wc); 268 SET_ANIMATION (op, op->stats.wc);
268 update_object (op, UP_OBJ_CHANGE); 269 update_object (op, UP_OBJ_CHANGE);
272 /* We're going up */ 273 /* We're going up */
273 274
274 /* First, lets see if we are already at the top */ 275 /* First, lets see if we are already at the top */
275 if ((unsigned char) op->stats.wc == (NUM_ANIMATIONS (op) - 1)) 276 if ((unsigned char) op->stats.wc == (NUM_ANIMATIONS (op) - 1))
276 { 277 {
277
278 /* Check to make sure that only non pickable and non rollable 278 /* Check to make sure that only non pickable and non rollable
279 * objects are above the gate. If so, we finish closing the gate, 279 * objects are above the gate. If so, we finish closing the gate,
280 * otherwise, we fall through to the code below which should lower 280 * otherwise, we fall through to the code below which should lower
281 * the gate slightly. 281 * the gate slightly.
282 */ 282 */
283 283
284 for (tmp = op->above; tmp; tmp = tmp->above) 284 for (tmp = op->above; tmp; tmp = tmp->above)
285 if (!QUERY_FLAG (tmp, FLAG_NO_PICK) || QUERY_FLAG (tmp, FLAG_CAN_ROLL) || QUERY_FLAG (tmp, FLAG_ALIVE)) 285 if (!tmp->flag [FLAG_NO_PICK] || tmp->flag [FLAG_CAN_ROLL] || tmp->flag [FLAG_ALIVE])
286 break; 286 break;
287 287
288 if (!tmp) 288 if (!tmp)
289 { 289 {
290 if (op->arch->has_active_speed ()) 290 if (op->arch->has_active_speed ())
321 for (tmp = op->above; tmp && tmp->above; tmp = tmp->above) 321 for (tmp = op->above; tmp && tmp->above; tmp = tmp->above)
322 ; 322 ;
323 323
324 if (tmp) 324 if (tmp)
325 { 325 {
326 if (QUERY_FLAG (tmp, FLAG_ALIVE)) 326 if (tmp->flag [FLAG_ALIVE])
327 { 327 {
328 hit_player (tmp, random_roll (0, op->stats.dam, tmp, PREFER_LOW), op, AT_PHYSICAL, 1); 328 hit_player (tmp, random_roll (0, op->stats.dam, tmp, PREFER_LOW), op, AT_PHYSICAL, 1);
329 op->play_sound (sound_find ("blocked_gate")); 329 op->play_sound (sound_find ("blocked_gate"));
330 330
331 if (tmp->type == PLAYER) 331 if (tmp->type == PLAYER)
333 } 333 }
334 /* If the object is not alive, and the object either can 334 /* If the object is not alive, and the object either can
335 * be picked up or the object rolls, move the object 335 * be picked up or the object rolls, move the object
336 * off the gate. 336 * off the gate.
337 */ 337 */
338 else if (!QUERY_FLAG (tmp, FLAG_ALIVE) && (!QUERY_FLAG (tmp, FLAG_NO_PICK) || QUERY_FLAG (tmp, FLAG_CAN_ROLL))) 338 else if (!tmp->flag [FLAG_ALIVE] && (!tmp->flag [FLAG_NO_PICK] || tmp->flag [FLAG_CAN_ROLL]))
339 { 339 {
340 /* If it has speed, it should move itself, otherwise: */ 340 /* If it has speed, it should move itself, otherwise: */
341 int i = find_free_spot (tmp, op->map, op->x, op->y, 1, SIZEOFFREE1 + 1); 341 int i = find_free_spot (tmp, op->map, op->x, op->y, 1, SIZEOFFREE1 + 1);
342 342
343 /* If there is a free spot, move the object someplace */ 343 /* If there is a free spot, move the object someplace */
351 } 351 }
352 } 352 }
353 353
354 /* See if there is still anything blocking the gate */ 354 /* See if there is still anything blocking the gate */
355 for (tmp = op->above; tmp; tmp = tmp->above) 355 for (tmp = op->above; tmp; tmp = tmp->above)
356 if (!QUERY_FLAG (tmp, FLAG_NO_PICK) || QUERY_FLAG (tmp, FLAG_CAN_ROLL) || QUERY_FLAG (tmp, FLAG_ALIVE)) 356 if (!tmp->flag [FLAG_NO_PICK] || tmp->flag [FLAG_CAN_ROLL] || tmp->flag [FLAG_ALIVE])
357 break; 357 break;
358 358
359 /* IF there is, start putting the gate down */ 359 /* IF there is, start putting the gate down */
360 if (tmp) 360 if (tmp)
361 op->stats.food = 1; 361 op->stats.food = 1;
362 else 362 else
363 { 363 {
364 op->move_block = MOVE_ALL; 364 op->move_block = MOVE_ALL;
365 365
366 if (!op->arch->stats.ac) 366 if (!op->arch->stats.ac)
367 SET_FLAG (op, FLAG_BLOCKSVIEW); 367 op->set_flag (FLAG_BLOCKSVIEW);
368 update_all_los (op->map, op->x, op->y); 368 update_all_los (op->map, op->x, op->y);
369 } 369 }
370 } /* gate is halfway up */ 370 } /* gate is halfway up */
371 371
372 SET_ANIMATION (op, op->stats.wc); 372 SET_ANIMATION (op, op->stats.wc);
502 move_apply (op, tmp, tmp); 502 move_apply (op, tmp, tmp);
503 } 503 }
504 } 504 }
505 505
506 SET_ANIMATION (op, op->stats.wc); 506 SET_ANIMATION (op, op->stats.wc);
507 update_object (op, UP_OBJ_FACE); 507 update_object (op, UP_OBJ_CHANGE);
508 return; 508 return;
509 } 509 }
510 510
511 /* We're closing */ 511 /* We're closing */
512 op->move_on = 0; 512 op->move_on = 0;
513 513
514 op->stats.wc++; 514 op->stats.wc++;
515 if ((int) op->stats.wc >= NUM_ANIMATIONS (op)) 515 if (op->stats.wc >= NUM_ANIMATIONS (op))
516 op->stats.wc = NUM_ANIMATIONS (op) - 1; 516 op->stats.wc = NUM_ANIMATIONS (op) - 1;
517 517
518 SET_ANIMATION (op, op->stats.wc); 518 SET_ANIMATION (op, op->stats.wc);
519 update_object (op, UP_OBJ_FACE); 519 update_object (op, UP_OBJ_CHANGE);
520 if ((unsigned char) op->stats.wc == (NUM_ANIMATIONS (op) - 1)) 520 if (op->stats.wc == (NUM_ANIMATIONS (op) - 1))
521 op->set_speed (0); /* closed, let's stop */ 521 op->set_speed (0); /* closed, let's stop */
522} 522}
523 523
524 524
525/* stop_item() returns a pointer to the stopped object. The stopped object 525/* stop_item() returns a pointer to the stopped object. The stopped object
573fix_stopped_item (object *op, maptile *map, object *originator) 573fix_stopped_item (object *op, maptile *map, object *originator)
574{ 574{
575 if (map == NULL) 575 if (map == NULL)
576 return; 576 return;
577 577
578 if (QUERY_FLAG (op, FLAG_REMOVED)) 578 if (op->flag [FLAG_REMOVED])
579 insert_ob_in_map (op, map, originator, 0); 579 insert_ob_in_map (op, map, originator, 0);
580 else if (op->type == ARROW) 580 else if (op->type == ARROW)
581 merge_ob (op, NULL); /* only some arrows actually need this */ 581 merge_ob (op, NULL); /* only some arrows actually need this */
582} 582}
583 583
609 op->stats.hp = 0; 609 op->stats.hp = 0;
610 op->stats.grace = 0; 610 op->stats.grace = 0;
611 op->level = 0; 611 op->level = 0;
612 op->face = op->arch->face; 612 op->face = op->arch->face;
613 op->owner = 0; 613 op->owner = 0;
614
615 op->clr_flag (FLAG_NO_PICK); /* fire_bow makes arrows NO_PICK so monsters (or anything else) don't pick them mid-flight */
614 616
615 update_object (op, UP_OBJ_CHANGE); 617 update_object (op, UP_OBJ_CHANGE);
616 618
617 return op; 619 return op;
618} 620}
646 if (op) 648 if (op)
647 merge_ob (op, 0); 649 merge_ob (op, 0);
648 } 650 }
649} 651}
650 652
651/* Move an arrow along its course. op is the arrow or thrown object. 653/* Move an arrow or throwen_obj along its course. op is the arrow or thrown object.
652 */ 654 */
653void 655void
654move_arrow (object *op) 656move_arrow (object *op)
655{ 657{
656 int was_reflected; 658 int was_reflected;
657 659
658 if (!op->map) 660 if (!op->map)
659 { 661 {
660 LOG (llevError, "BUG: Arrow had no map.\n"); 662 LOG (llevError | logBacktrace, "BUG: Arrow %s had no map.\n", op->debug_desc ());
661 op->destroy (); 663 op->destroy ();
662 return; 664 return;
663 } 665 }
664 666
665 /* we need to stop thrown objects at some point. Like here. */ 667 /* we need to stop thrown objects at some point. Like here. */
684 stop_arrow (op); 686 stop_arrow (op);
685 return; 687 return;
686 } 688 }
687 } 689 }
688 690
691 /* decrease the speed as it flies. 0.05 means a standard bow will shoot
692 * about 17 squares. Tune as needed.
693 */
694 op->set_speed (op->speed - 0.05);
695
689 /* if the arrow is moving too slow.. stop it. 0.5 was chosen as lower 696 /* if the arrow is moving too slow.. stop it. 0.5 was chosen as lower
690 values look rediculous. */ 697 values look ridiculous. */
691 if (op->speed < 0.5 && op->type == ARROW) 698 if (op->speed < (op->type == ARROW ? 0.5 : MIN_ACTIVE_SPEED))
692 { 699 {
693 stop_arrow (op); 700 stop_arrow (op);
694 return; 701 return;
695 } 702 }
696 703
709 if (pos->flags () & P_IS_ALIVE) 716 if (pos->flags () & P_IS_ALIVE)
710 { 717 {
711 object *tmp; 718 object *tmp;
712 719
713 for (tmp = pos->bot; tmp; tmp = tmp->above) 720 for (tmp = pos->bot; tmp; tmp = tmp->above)
714 if (QUERY_FLAG (tmp, FLAG_ALIVE)) 721 if (tmp->flag [FLAG_ALIVE] && tmp != op->owner)
715 break; 722 {
716
717 /* Not really fair, but don't let monsters hit themselves with 723 /* Not really fair, but don't let monsters hit themselves with
718 * their own arrow - this can be because they fire it then 724 * their own arrow - this can be because they fire it then
719 * move into it. 725 * move into it.
720 */ 726 */
721 if (tmp && tmp != op->owner) 727
722 {
723 /* Found living object, but it is reflecting the missile. Update 728 /* Found living object, but it is reflecting the missile. Update
724 * as below. (Note that for living creatures there is a small 729 * as below. (Note that for living creatures there is a small
725 * chance that reflect_missile fails.) 730 * chance that reflect_missile fails.)
726 */ 731 */
727 if (QUERY_FLAG (tmp, FLAG_REFL_MISSILE) && (rndm (0, 99)) < (90 - op->level / 10)) 732 if (tmp->flag [FLAG_REFL_MISSILE] && (rndm (0, 99)) < (90 - op->level / 10))
728 { 733 {
729 int number = op->face;
730
731 op->direction = absdir (op->direction + 4); 734 op->direction = absdir (op->direction + 4);
732 update_turn_face (op); 735 update_turn_face (op);
733 was_reflected = 1; /* skip normal movement calculations */ 736 was_reflected = 1; /* skip normal movement calculations */
734 } 737 }
735 else 738 else
736 { 739 {
737 /* Attack the object. */ 740 /* Attack the object. */
738 op = hit_with_arrow (op, tmp); 741 op = hit_with_arrow (op, tmp);
739 742
740 if (!op) 743 if (!op)
741 return; 744 return;
742 } 745 }
743 } /* if this is not hitting its owner */ 746
744 } /* if there is something alive on this space */ 747 break;
748 }
749 }
745 750
746 if (OB_TYPE_MOVE_BLOCK (op, pos->move_block)) 751 if (OB_TYPE_MOVE_BLOCK (op, pos->move_block))
747 { 752 {
748 int retry = 0; 753 int retry = 0;
749 754
751 * note that this code will now catch cases where a monster is 756 * note that this code will now catch cases where a monster is
752 * on a wall but has reflecting - the arrow won't reflect. 757 * on a wall but has reflecting - the arrow won't reflect.
753 * Mapmakers shouldn't put monsters on top of wall in the first 758 * Mapmakers shouldn't put monsters on top of wall in the first
754 * place, so I don't consider that a problem. 759 * place, so I don't consider that a problem.
755 */ 760 */
756 if (!QUERY_FLAG (op, FLAG_REFLECTING) || !(rndm (0, 19))) 761 if (!op->flag [FLAG_REFLECTING] || !rndm (0, 19))
757 { 762 {
758 stop_arrow (op); 763 stop_arrow (op);
759 return; 764 return;
760 } 765 }
761 else 766 else
815 if (op->has_anim ()) 820 if (op->has_anim ())
816 op->set_anim_frame (op->direction); 821 op->set_anim_frame (op->direction);
817 } /* object is reflected */ 822 } /* object is reflected */
818 } /* object ran into a wall */ 823 } /* object ran into a wall */
819 824
820 /* decrease the speed as it flies. 0.05 means a standard bow will shoot
821 * about 17 squares. Tune as needed.
822 */
823 op->speed -= 0.05;
824
825 /* Move the arrow. */ 825 /* Move the arrow. */
826 op->move_to (pos); 826 op->move_to (pos);
827} 827}
828 828
829static void 829static void
834 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 ());
835 return; 835 return;
836 } 836 }
837 837
838 /* In non-living items only change when food value is 0 */ 838 /* In non-living items only change when food value is 0 */
839 if (!QUERY_FLAG (op, FLAG_ALIVE)) 839 if (!op->flag [FLAG_ALIVE])
840 { 840 {
841 if (op->stats.food-- > 0) 841 if (op->stats.food-- > 0)
842 return; 842 return;
843 843
844 op->stats.food = 1; /* so 1 other_arch is made */ 844 op->stats.food = 1; /* so 1 other_arch is made */
891 891
892 if (op->head) 892 if (op->head)
893 head = op->head; 893 head = op->head;
894 894
895 for (tmp = op->above; tmp; tmp = tmp->above) 895 for (tmp = op->above; tmp; tmp = tmp->above)
896 if (!QUERY_FLAG (tmp, FLAG_IS_FLOOR)) 896 if (!tmp->flag [FLAG_IS_FLOOR])
897 break; 897 break;
898 898
899 /* If nothing above us to move, nothing to do */ 899 /* If nothing above us to move, nothing to do */
900 if (!tmp || QUERY_FLAG (tmp, FLAG_WIZPASS)) 900 if (!tmp || tmp->flag [FLAG_WIZPASS])
901 return; 901 return;
902 902
903 if (EXIT_PATH (head)) 903 if (EXIT_PATH (head))
904 { 904 {
905 if (tmp->type == PLAYER) 905 if (tmp->type == PLAYER)
1004 } 1004 }
1005 1005
1006 cast_spell (op, op, op->stats.sp ? op->stats.sp : rndm (1, 8), spell, NULL); 1006 cast_spell (op, op, op->stats.sp ? op->stats.sp : rndm (1, 8), spell, NULL);
1007} 1007}
1008 1008
1009/* move_player_mover: this function takes a "player mover" as an 1009/* move_player_mover: this function takes a "player mover" as an
1010 * argument, and performs the function of a player mover, which is: 1010 * argument, and performs the function of a player mover, which is:
1011 * 1011 *
1012 * a player mover finds any players that are sitting on it. It 1012 * a player mover finds any players that are sitting on it. It
1013 * 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.
1014 * 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,
1016 * it'll paralyze the victim for hp*his speed/op->speed 1016 * it'll paralyze the victim for hp*his speed/op->speed
1017 */ 1017 */
1018static void 1018static void
1019move_player_mover (object *op) 1019move_player_mover (object *op)
1020{ 1020{
1021 int dir = op->stats.sp; 1021 int dir = 0;
1022 sint16 nx, ny;
1023 maptile *m;
1024
1025 /* Determine direction now for random movers so we do the right thing */
1026 if (!dir)
1027 dir = rndm (1, 8);
1028 1022
1029 for (object *victim = op->ms ().bot; victim; victim = victim->above) 1023 for (object *victim = op->ms ().bot; victim; victim = victim->above)
1030 { 1024 {
1031 if (QUERY_FLAG (victim, FLAG_ALIVE) && !QUERY_FLAG (victim, FLAG_WIZPASS) && 1025 if (victim->flag [FLAG_ALIVE]
1026 && !victim->flag [FLAG_WIZPASS]
1032 (victim->move_type & op->move_type || !victim->move_type)) 1027 && (victim->move_type & op->move_type || !victim->move_type))
1028 {
1029 if (op->flag [FLAG_LIFESAVE] && op->stats.hp-- < 0)
1033 { 1030 {
1031 op->destroy ();
1032 return;
1033 }
1034
1035 /* Determine direction only once so we do the right thing */
1036 // why is it the right thing, though?
1037 if (!dir)
1038 dir = op->stats.sp ? op->stats.sp : rndm (1, 8);
1039
1040 sint16 nx = op->x + DIRX (dir);
1041 sint16 ny = op->y + DIRY (dir);
1042 maptile *m = op->map;
1043 if (get_map_flags (m, &m, nx, ny, &nx, &ny) & P_OUT_OF_MAP)
1044 {
1045 LOG (llevError, "move_player_mover: Trying to push player off the map! map=%s (%d, %d)\n", &m->path, op->x, op->y);
1046 return;
1047 }
1034 1048
1035 if (victim->head) 1049 if (victim->head)
1036 victim = victim->head; 1050 victim = victim->head;
1037 1051
1038 if (QUERY_FLAG (op, FLAG_LIFESAVE) && op->stats.hp-- < 0)
1039 {
1040 op->remove ();
1041 return;
1042 }
1043
1044 nx = op->x + freearr_x[dir];
1045 ny = op->y + freearr_y[dir];
1046 m = op->map;
1047 if (get_map_flags (m, &m, nx, ny, &nx, &ny) & P_OUT_OF_MAP)
1048 {
1049 LOG (llevError, "move_player_mover: Trying to push player off the map! map=%s (%d, %d)\n", &m->path, op->x, op->y);
1050 return;
1051 }
1052
1053 if (should_director_abort (op, victim)) 1052 if (should_director_abort (op, victim))
1054 return; 1053 return;
1055 1054
1056 for (object *nextmover = m->at (nx, ny).bot; nextmover; nextmover = nextmover->above) 1055 for (object *nextmover = m->at (nx, ny).bot; nextmover; nextmover = nextmover->above)
1057 { 1056 {
1058 if (nextmover->type == PLAYERMOVER) 1057 if (nextmover->type == PLAYERMOVER)
1059 nextmover->speed_left = -.99f; 1058 nextmover->speed_left = -.99f;
1060 1059
1061 if (QUERY_FLAG (nextmover, FLAG_ALIVE)) 1060 if (nextmover->flag [FLAG_ALIVE])
1062 op->speed_left = -1.1f; /* wait until the next thing gets out of the way */ 1061 op->speed_left = -1.1f; /* wait until the next thing gets out of the way */
1063 } 1062 }
1064 1063
1065 if (victim->type == PLAYER) 1064 if (victim->type == PLAYER)
1066 { 1065 {
1133 break; 1132 break;
1134 } 1133 }
1135 } 1134 }
1136} 1135}
1137 1136
1138/* move_creator (by peterm) 1137/* move_creator (by peterm)
1139 * it has the creator object create it's other_arch right on top of it. 1138 * it has the creator object create it's other_arch right on top of it.
1140 * connected: what will trigger it 1139 * connected: what will trigger it
1141 * hp: how many times it may create before stopping 1140 * hp: how many times it may create before stopping
1142 * lifesave: if set, it'll never disappear but will go on creating 1141 * lifesave: if set, it'll never disappear but will go on creating
1143 * everytime it's triggered 1142 * everytime it's triggered
1151void 1150void
1152move_creator (object *creator) 1151move_creator (object *creator)
1153{ 1152{
1154 object *new_ob; 1153 object *new_ob;
1155 1154
1156 if (!QUERY_FLAG (creator, FLAG_LIFESAVE) && --creator->stats.hp < 0) 1155 if (!creator->flag [FLAG_LIFESAVE] && --creator->stats.hp < 0)
1157 { 1156 {
1158 creator->stats.hp = -1; 1157 creator->stats.hp = -1;
1159 return; 1158 return;
1160 } 1159 }
1161 1160
1165 int i; 1164 int i;
1166 object *ob_to_copy; 1165 object *ob_to_copy;
1167 1166
1168 /* select random object from inventory to copy */ 1167 /* select random object from inventory to copy */
1169 ob_to_copy = creator->inv; 1168 ob_to_copy = creator->inv;
1170 for (ob = creator->inv->below, i = 1; ob != NULL; ob = ob->below, i++) 1169 for (ob = creator->inv->below, i = 1; ob; ob = ob->below, i++)
1171 { 1170 {
1172 if (rndm (0, i) == 0) 1171 if (rndm (0, i) == 0)
1173 { 1172 {
1174 ob_to_copy = ob; 1173 ob_to_copy = ob;
1175 } 1174 }
1176 } 1175 }
1176
1177 new_ob = ob_to_copy->deep_clone (); 1177 new_ob = ob_to_copy->deep_clone ();
1178 CLEAR_FLAG (new_ob, FLAG_IS_A_TEMPLATE); 1178 new_ob->clr_flag (FLAG_IS_A_TEMPLATE);
1179 unflag_inv (new_ob, FLAG_IS_A_TEMPLATE); 1179 unflag_inv (new_ob, FLAG_IS_A_TEMPLATE);
1180 } 1180 }
1181 else 1181 else
1182 { 1182 {
1183 if (!creator->other_arch) 1183 if (!creator->other_arch)
1198 return; 1198 return;
1199 } 1199 }
1200 1200
1201 // for now lets try to identify everything generated here, it mostly 1201 // for now lets try to identify everything generated here, it mostly
1202 // 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
1203 SET_FLAG (new_ob, FLAG_IDENTIFIED); 1203 if (new_ob->need_identify ())
1204 new_ob->set_flag (FLAG_IDENTIFIED);
1204 1205
1205 insert_ob_in_map_at (new_ob, creator->map, creator, 0, creator->x, creator->y); 1206 insert_ob_in_map_at (new_ob, creator->map, creator, 0, creator->x, creator->y);
1206 if (QUERY_FLAG (new_ob, FLAG_FREED)) 1207 if (new_ob->flag [FLAG_FREED])
1207 return; 1208 return;
1208 1209
1209 if (creator->slaying) 1210 if (creator->slaying)
1210 new_ob->name = new_ob->title = creator->slaying; 1211 new_ob->name = new_ob->title = creator->slaying;
1211} 1212}
1296} 1297}
1297 1298
1298void 1299void
1299process_object (object *op) 1300process_object (object *op)
1300{ 1301{
1301 if (expect_false (QUERY_FLAG (op, FLAG_IS_A_TEMPLATE))) 1302 if (expect_false (op->flag [FLAG_IS_A_TEMPLATE]))
1302 return; 1303 return;
1303 1304
1304 if (expect_false (INVOKE_OBJECT (TICK, op))) 1305 if (expect_false (INVOKE_OBJECT (TICK, op)))
1305 return; 1306 return;
1306 1307
1307 if (QUERY_FLAG (op, FLAG_MONSTER)) 1308 if (op->flag [FLAG_MONSTER])
1308 if (move_monster (op) || QUERY_FLAG (op, FLAG_FREED)) 1309 if (move_monster (op) || op->flag [FLAG_FREED])
1309 return; 1310 return;
1310 1311
1311 if (QUERY_FLAG (op, FLAG_ANIMATE) && op->anim_speed == 0) 1312 if (op->flag [FLAG_ANIMATE] && op->anim_speed == 0)
1312 { 1313 {
1313 animate_object (op, op->contr ? op->facing : op->direction); 1314 animate_object (op, op->contr ? op->facing : op->direction);
1314 1315
1315 if (QUERY_FLAG (op, FLAG_SEE_ANYWHERE)) 1316 if (op->flag [FLAG_SEE_ANYWHERE])
1316 make_sure_seen (op); 1317 make_sure_seen (op);
1317 } 1318 }
1318 1319
1319 if (expect_false ( 1320 if (expect_false (
1320 op->flag [FLAG_GENERATOR] 1321 op->flag [FLAG_GENERATOR]
1321 || op->flag [FLAG_CHANGING] 1322 || op->flag [FLAG_CHANGING]
1322 || op->flag [FLAG_IS_USED_UP] 1323 || op->flag [FLAG_IS_USED_UP]
1323 )) 1324 ))
1324 { 1325 {
1325 if (QUERY_FLAG (op, FLAG_CHANGING) && !op->state) 1326 if (op->flag [FLAG_CHANGING] && !op->state)
1326 { 1327 {
1327 change_object (op); 1328 change_object (op);
1328 return; 1329 return;
1329 } 1330 }
1330 1331
1331 if (QUERY_FLAG (op, FLAG_GENERATOR) && !QUERY_FLAG (op, FLAG_FRIENDLY)) 1332 if (op->flag [FLAG_GENERATOR] && !op->flag [FLAG_FRIENDLY])
1332 generate_monster (op); 1333 generate_monster (op);
1333 1334
1334 if (QUERY_FLAG (op, FLAG_IS_USED_UP) && --op->stats.food <= 0) 1335 if (op->flag [FLAG_IS_USED_UP] && --op->stats.food <= 0)
1335 { 1336 {
1336 if (QUERY_FLAG (op, FLAG_APPLIED)) 1337 if (op->flag [FLAG_APPLIED])
1337 remove_force (op); 1338 remove_force (op);
1338 else 1339 else
1339 { 1340 {
1340 op->remove (); // TODO: really necessary? 1341 op->remove (); // TODO: really necessary?
1341 1342
1342 if (QUERY_FLAG (op, FLAG_SEE_ANYWHERE)) 1343 if (op->flag [FLAG_SEE_ANYWHERE])
1343 make_sure_not_seen (op); 1344 make_sure_not_seen (op);
1344 1345
1345 op->drop_and_destroy (); 1346 op->drop_and_destroy ();
1346 } 1347 }
1347 1348
1483 1484
1484 case LAMP: 1485 case LAMP:
1485 case TORCH: 1486 case TORCH:
1486 move_lamp (op); 1487 move_lamp (op);
1487 break; 1488 break;
1488 }
1489}
1490 1489
1490 case PHYSICS: // hmm, bad naming
1491 move_physics (op);
1492 break;
1493 }
1494}
1495

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines