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.31 by root, Tue Jan 2 11:08:36 2007 UTC vs.
Revision 1.52 by root, Tue May 22 10:50:01 2007 UTC

1/* 1/*
2 CrossFire, A Multiplayer game for X-windows 2 * CrossFire, A Multiplayer game
3 3 *
4 * Copyright (C) 2005, 2006, 2007 Marc Lehmann & Crossfire+ Development Team
4 Copyright (C) 2002 Mark Wedel & Crossfire Development Team 5 * Copyright (C) 2002 Mark Wedel & Crossfire Development Team
5 Copyright (C) 1992 Frank Tore Johansen 6 * Copyright (C) 1992 Frank Tore Johansen
6 7 *
7 This program is free software; you can redistribute it and/or modify 8 * This program is free software; you can redistribute it and/or modify
8 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
9 the Free Software Foundation; either version 2 of the License, or 10 * the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version. 11 * (at your option) any later version.
11 12 *
12 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,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details. 16 * GNU General Public License for more details.
16 17 *
17 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
18 along with this program; if not, write to the Free Software 19 * along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 21 *
21 The authors can be reached via e-mail at <crossfire@schmorp.de> 22 * The authors can be reached via e-mail at <crossfire@schmorp.de>
22*/ 23 */
23 24
24/* 25/*
25 * Routines that is executed from objects based on their speed have been 26 * Routines that is executed from objects based on their speed have been
26 * collected in this file. 27 * collected in this file.
27 */ 28 */
28
29#include <global.h> 29#include <global.h>
30#include <spells.h> 30#include <spells.h>
31#include <sproto.h> 31#include <sproto.h>
32 32
33/* The following removes doors. The functions check to see if similar 33/* 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 34 * 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.) 35 * so those will be removed shortly (in a cascade like fashion.)
36 */ 36 */
37
38void 37void
39remove_door (object *op) 38remove_door (object *op)
40{ 39{
41 int i; 40 int i;
42 object *tmp; 41 object *tmp;
43 42
44 for (i = 1; i < 9; i += 2) 43 for (i = 1; i < 9; i += 2)
45 if ((tmp = present (DOOR, op->map, op->x + freearr_x[i], op->y + freearr_y[i])) != NULL) 44 if ((tmp = present (DOOR, op->map, op->x + freearr_x[i], op->y + freearr_y[i])) != NULL)
46 { 45 {
47 tmp->set_speed (0.1); 46 tmp->set_speed (0.1f);
48 tmp->speed_left = -0.2; 47 tmp->speed_left = -0.2f;
49 } 48 }
50 49
51 if (op->other_arch) 50 if (op->other_arch)
52 { 51 {
53 tmp = arch_to_object (op->other_arch); 52 tmp = arch_to_object (op->other_arch);
70 for (i = 1; i < 9; i += 2) 69 for (i = 1; i < 9; i += 2)
71 { 70 {
72 tmp = present (LOCKED_DOOR, op->map, op->x + freearr_x[i], op->y + freearr_y[i]); 71 tmp = present (LOCKED_DOOR, op->map, op->x + freearr_x[i], op->y + freearr_y[i]);
73 if (tmp && tmp->slaying == op->slaying) 72 if (tmp && tmp->slaying == op->slaying)
74 { /* same key both doors */ 73 { /* same key both doors */
75 tmp->set_speed (0.1); 74 tmp->set_speed (0.1f);
76 tmp->speed_left = -0.2; 75 tmp->speed_left = -0.2f;
77 } 76 }
78 } 77 }
79 78
80 if (op->other_arch) 79 if (op->other_arch)
81 { 80 {
88 } 87 }
89 88
90 op->destroy (); 89 op->destroy ();
91} 90}
92 91
93/* Will generate a monster according to content
94 * of generator.
95 */
96void 92void
97generate_monster_inv (object *gen) 93generate_monster (object *gen)
98{ 94{
99 int i;
100 object *op, *head = NULL;
101
102 int qty = 0;
103
104 /* Code below assumes the generator is on a map, as it tries
105 * to place the monster on the map. So if the generator
106 * isn't on a map, complain and exit.
107 */
108 if (gen->map == NULL)
109 {
110 //LOG(llevError,"Generator (%s) not on a map?\n", gen->name);
111 return;
112 }
113 /*First count numer of objects in inv */
114 for (op = gen->inv; op; op = op->below)
115 qty++;
116 if (!qty)
117 {
118 LOG (llevError, "Generator (%s) has no inventory in generate_monster_inv?\n", &gen->name);
119 return; /*No inventory */
120 }
121 qty = rndm (0, qty - 1);
122 for (op = gen->inv; qty; qty--)
123 op = op->below;
124 i = find_free_spot (op, gen->map, gen->x, gen->y, 1, 9);
125 if (i == -1)
126 return;
127 head = object_create_clone (op);
128 CLEAR_FLAG (head, FLAG_IS_A_TEMPLATE);
129 unflag_inv (head, FLAG_IS_A_TEMPLATE);
130 if (rndm (0, 9))
131 generate_artifact (head, gen->map->difficulty);
132 insert_ob_in_map_at (head, gen->map, gen, 0, gen->x + freearr_x[i], gen->y + freearr_y[i]);
133 if (QUERY_FLAG (head, FLAG_FREED))
134 return;
135 if (head->has_random_items ())
136 create_treasure (head->randomitems, head, GT_APPLY, gen->map->difficulty, 0);
137}
138
139void
140generate_monster_arch (object *gen)
141{
142 int i;
143 object *op, *head = NULL, *prev = NULL;
144 archetype *at = gen->other_arch;
145
146 if (!gen->other_arch)
147 return;
148
149 /* Code below assumes the generator is on a map, as it tries
150 * to place the monster on the map. So if the generator
151 * isn't on a map, complain and exit.
152 */
153 if (!gen->map) 95 if (!gen->map)
154 return; 96 return;
155 97
156 i = find_free_spot (&at->clone, gen->map, gen->x, gen->y, 1, 9);
157 if (i == -1)
158 return;
159
160 while (at)
161 {
162 op = arch_to_object (at);
163 op->x = gen->x + freearr_x[i] + at->clone.x;
164 op->y = gen->y + freearr_y[i] + at->clone.y;
165
166 if (head)
167 op->head = head, prev->more = op;
168
169 if (rndm (0, 9))
170 generate_artifact (op, gen->map->difficulty);
171
172 insert_ob_in_map (op, gen->map, gen, 0);
173 if (QUERY_FLAG (op, FLAG_FREED))
174 return;
175
176 if (op->has_random_items ())
177 create_treasure (op->randomitems, op, GT_APPLY, gen->map->difficulty, 0);
178
179 if (head == NULL)
180 head = op;
181
182 prev = op;
183 at = at->more;
184 }
185}
186
187void
188generate_monster (object *gen)
189{
190
191 if (GENERATE_SPEED (gen) && rndm (0, GENERATE_SPEED (gen) - 1)) 98 if (GENERATE_SPEED (gen) && rndm (0, GENERATE_SPEED (gen) - 1))
192 return; 99 return;
193 100
101 object *op;
102
194 if (QUERY_FLAG (gen, FLAG_CONTENT_ON_GEN)) 103 if (QUERY_FLAG (gen, FLAG_CONTENT_ON_GEN))
195 generate_monster_inv (gen); 104 {
105 // either copy one item form the inventory...
106 if (!gen->inv)
107 return;
108
109 // first select one item from the inventory
110 int index = 0;
111 for (object *tmp = gen->inv; tmp; tmp = tmp->below)
112 if (!rndm (++index))
113 op = tmp;
114
115 op = object_create_clone (op);
116
117 CLEAR_FLAG (op, FLAG_IS_A_TEMPLATE);
118 unflag_inv (op, FLAG_IS_A_TEMPLATE);
119 }
196 else 120 else
197 generate_monster_arch (gen); 121 {
122 // ...or use other_arch
123 if (archetype *at = gen->other_arch)
124 op = arch_to_object (at);
125 else
126 return;
127 }
198 128
129 op->expand_tail ();
130
131 int i = find_free_spot (op, gen->map, gen->x, gen->y, 1, 9);
132 if (i >= 0)
133 {
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))
137 generate_artifact (op, gen->map->difficulty);
138
139 if (op->has_random_items ())
140 create_treasure (op->randomitems, op, GT_APPLY, gen->map->difficulty);
141
142 return;
143 }
144 }
145
146 op->destroy ();
199} 147}
200 148
201void 149void
202remove_force (object *op) 150remove_force (object *op)
203{ 151{
246 return; 194 return;
247 } 195 }
248 196
249 if (op->stats.food == 1) 197 if (op->stats.food == 1)
250 { 198 {
251 /* need to remove the object before fix_player is called, else fix_player 199 /* need to unapply the object before update_stats is called, else fix_player
252 * will not do anything. 200 * will not do anything.
253 */ 201 */
254 if (op->env->type == PLAYER) 202 if (op->env->type == PLAYER)
255 { 203 {
256 CLEAR_FLAG (op, FLAG_APPLIED); 204 CLEAR_FLAG (op, FLAG_APPLIED);
265 if (op->env->type == PLAYER) 213 if (op->env->type == PLAYER)
266 { 214 {
267 op->env->stats.food--; 215 op->env->stats.food--;
268 new_draw_info (NDI_UNIQUE, 0, op->env, "You feel very sick..."); 216 new_draw_info (NDI_UNIQUE, 0, op->env, "You feel very sick...");
269 } 217 }
218
270 (void) hit_player (op->env, op->stats.dam, op, AT_INTERNAL, 1); 219 hit_player (op->env, op->stats.dam, op, AT_INTERNAL, 1);
271} 220}
272 221
273 222
274void 223void
275move_gate (object *op) 224move_gate (object *op)
276{ /* 1 = going down, 0 = goind up */ 225{ /* 1 = going down, 0 = going up */
277 object *tmp; 226 object *tmp;
278 227
279 if (op->stats.wc < 0 || (int) op->stats.wc >= NUM_ANIMATIONS (op)) 228 if (op->stats.wc < 0 || (int) op->stats.wc >= NUM_ANIMATIONS (op))
280 { 229 {
281 LOG (llevError, "Gate error: animation was %d, max=%d\n", op->stats.wc, NUM_ANIMATIONS (op)); 230 LOG (llevError, "Gate error: animation was %d, max=%d\n", op->stats.wc, NUM_ANIMATIONS (op));
353 */ 302 */
354 if ((int) op->stats.wc >= NUM_ANIMATIONS (op) / 2) 303 if ((int) op->stats.wc >= NUM_ANIMATIONS (op) / 2)
355 { 304 {
356 /* Halfway or further, check blocks */ 305 /* Halfway or further, check blocks */
357 /* First, get the top object on the square. */ 306 /* First, get the top object on the square. */
358 for (tmp = op->above; tmp != NULL && tmp->above != NULL; tmp = tmp->above); 307 for (tmp = op->above; tmp && tmp->above; tmp = tmp->above)
308 ;
359 309
360 if (tmp != NULL) 310 if (tmp)
361 { 311 {
362 if (QUERY_FLAG (tmp, FLAG_ALIVE)) 312 if (QUERY_FLAG (tmp, FLAG_ALIVE))
363 { 313 {
364 hit_player (tmp, random_roll (1, op->stats.dam, tmp, PREFER_LOW), op, AT_PHYSICAL, 1); 314 hit_player (tmp, random_roll (0, op->stats.dam, tmp, PREFER_LOW), op, AT_PHYSICAL, 1);
315
365 if (tmp->type == PLAYER) 316 if (tmp->type == PLAYER)
366 new_draw_info_format (NDI_UNIQUE, 0, tmp, "You are crushed by the %s!", &op->name); 317 new_draw_info_format (NDI_UNIQUE, 0, tmp, "You are crushed by the %s!", &op->name);
367 } 318 }
368 else 319 else
369 /* If the object is not alive, and the object either can 320 /* If the object is not alive, and the object either can
455 406
456 if (op->stats.hp) 407 if (op->stats.hp)
457 { 408 {
458 for (tmp2 = tmp->inv; tmp2; tmp2 = tmp2->below) 409 for (tmp2 = tmp->inv; tmp2; tmp2 = tmp2->below)
459 { 410 {
460 if (op->slaying && !strcmp (op->slaying, tmp->name)) 411 if (op->slaying && op->slaying == tmp->name)
461 detected = 1; 412 detected = 1;
413
462 if (tmp2->type == FORCE && tmp2->slaying && !strcmp (tmp2->slaying, op->slaying)) 414 if (tmp2->type == FORCE && tmp2->slaying && tmp2->slaying == op->slaying)
463 detected = 1; 415 detected = 1;
464 } 416 }
465 } 417 }
418
466 if (op->slaying && !strcmp (op->slaying, tmp->name)) 419 if (op->slaying && op->slaying == tmp->name)
467 {
468 detected = 1; 420 detected = 1;
469 }
470 else if (tmp->type == SPECIAL_KEY && tmp->slaying == op->slaying) 421 else if (tmp->type == SPECIAL_KEY && tmp->slaying == op->slaying)
471 detected = 1; 422 detected = 1;
472 } 423 }
473 424
474 /* the detector sets the button if detection is found */ 425 /* the detector sets the button if detection is found */
604void 555void
605fix_stopped_item (object *op, maptile *map, object *originator) 556fix_stopped_item (object *op, maptile *map, object *originator)
606{ 557{
607 if (map == NULL) 558 if (map == NULL)
608 return; 559 return;
560
609 if (QUERY_FLAG (op, FLAG_REMOVED)) 561 if (QUERY_FLAG (op, FLAG_REMOVED))
610 insert_ob_in_map (op, map, originator, 0); 562 insert_ob_in_map (op, map, originator, 0);
611 else if (op->type == ARROW) 563 else if (op->type == ARROW)
612 merge_ob (op, NULL); /* only some arrows actually need this */ 564 merge_ob (op, NULL); /* only some arrows actually need this */
613} 565}
614 566
615
616object * 567object *
617fix_stopped_arrow (object *op) 568fix_stopped_arrow (object *op)
618{ 569{
619 if (rndm (0, 99) < op->stats.food) 570 if (rndm (0, 99) < op->stats.food)
620 { 571 {
623 return NULL; 574 return NULL;
624 } 575 }
625 576
626 op->set_speed (0); 577 op->set_speed (0);
627 op->direction = 0; 578 op->direction = 0;
628 op->move_on = 0; 579 op->move_on = 0;
629 op->move_type = 0; 580 op->move_type = 0;
581 op->skill = 0; // really?
582
583 // restore original wc, dam, attacktype and slaying
630 op->stats.wc = op->stats.sp; 584 op->stats.wc = op->stats.sp;
631 op->stats.dam = op->stats.hp; 585 op->stats.dam = op->stats.hp;
632 op->attacktype = op->stats.grace; 586 op->attacktype = op->stats.grace;
633 op->slaying = 0;
634 op->skill = 0;
635 587
636 if (op->spellarg != NULL) 588 if (op->spellarg)
637 { 589 {
638 op->slaying = op->spellarg; 590 op->slaying = op->spellarg;
639 free (op->spellarg); 591 free (op->spellarg);
640 op->spellarg = NULL; 592 op->spellarg = 0;
641 } 593 }
642 else 594 else
643 op->slaying = NULL; 595 op->slaying = 0;
644 596
645 /* Reset these to zero, so that object::can_merge will work properly */ 597 /* Reset these to zero, so that object::can_merge will work properly */
646 op->spellarg = NULL; 598 op->spellarg = NULL;
647 op->stats.sp = 0; 599 op->stats.sp = 0;
648 op->stats.hp = 0; 600 op->stats.hp = 0;
649 op->stats.grace = 0; 601 op->stats.grace = 0;
650 op->level = 0; 602 op->level = 0;
651 op->face = op->arch->clone.face; 603 op->face = op->arch->clone.face;
652 op->owner = NULL; /* So that stopped arrows will be saved */ 604 op->owner = NULL; /* So that stopped arrows will be saved */
653 update_object (op, UP_OBJ_FACE); 605 update_object (op, UP_OBJ_CHANGE);
654 return op; 606 return op;
655} 607}
656 608
657/* stop_arrow() - what to do when a non-living flying object 609/* stop_arrow() - what to do when a non-living flying object
658 * has to stop. Sept 96 - I added in thrown object code in 610 * has to stop. Sept 96 - I added in thrown object code in
677 op->destroy (); 629 op->destroy ();
678 } 630 }
679 else 631 else
680 { 632 {
681 op = fix_stopped_arrow (op); 633 op = fix_stopped_arrow (op);
634
682 if (op) 635 if (op)
683 merge_ob (op, NULL); 636 merge_ob (op, 0);
684 } 637 }
685} 638}
686 639
687/* Move an arrow along its course. op is the arrow or thrown object. 640/* Move an arrow along its course. op is the arrow or thrown object.
688 */ 641 */
689
690void 642void
691move_arrow (object *op) 643move_arrow (object *op)
692{ 644{
693 object *tmp; 645 object *tmp;
694 sint16 new_x, new_y; 646 sint16 new_x, new_y;
765 * as below. (Note that for living creatures there is a small 717 * as below. (Note that for living creatures there is a small
766 * chance that reflect_missile fails.) 718 * chance that reflect_missile fails.)
767 */ 719 */
768 if (QUERY_FLAG (tmp, FLAG_REFL_MISSILE) && (rndm (0, 99)) < (90 - op->level / 10)) 720 if (QUERY_FLAG (tmp, FLAG_REFL_MISSILE) && (rndm (0, 99)) < (90 - op->level / 10))
769 { 721 {
770 int number = op->face->number; 722 int number = op->face;
771 723
772 op->direction = absdir (op->direction + 4); 724 op->direction = absdir (op->direction + 4);
773 op->state = 0; 725 update_turn_face (op);
774
775 if (GET_ANIM_ID (op))
776 {
777 number += 4;
778
779 if (number > GET_ANIMATION (op, 8))
780 number -= 8;
781
782 op->face = &new_faces[number];
783 }
784
785 was_reflected = 1; /* skip normal movement calculations */ 726 was_reflected = 1; /* skip normal movement calculations */
786 } 727 }
787 else 728 else
788 { 729 {
789 /* Attack the object. */ 730 /* Attack the object. */
1013 return; 954 return;
1014 teleport (head, TELEPORTER, tmp); 955 teleport (head, TELEPORTER, tmp);
1015 } 956 }
1016} 957}
1017 958
1018
1019/* This object will teleport someone to a different map 959/* This object will teleport someone to a different map
1020 and will also apply changes to the player from its inventory. 960 and will also apply changes to the player from its inventory.
1021 This was invented for giving classes, but there's no reason it 961 This was invented for giving classes, but there's no reason it
1022 can't be generalized. 962 can't be generalized.
1023*/ 963*/
1024void 964void
1025move_player_changer (object *op) 965move_player_changer (object *op)
1026{ 966{
1027 object *player; 967 object *player;
1028 object *walk; 968 object *walk;
1029 char c;
1030 969
1031 if (!op->above || !EXIT_PATH (op)) 970 if (!op->above || !EXIT_PATH (op))
1032 return; 971 return;
1033 972
1034 /* This isn't all that great - means that the player_mover 973 /* This isn't all that great - means that the player_mover
1035 * needs to be on top. 974 * needs to be on top.
1036 */ 975 */
1037 if (op->above->type == PLAYER) 976 if (op->above->type == PLAYER)
1038 { 977 {
1039 if (INVOKE_OBJECT (TRIGGER, op, ARG_OBJECT (player))) 978 if (INVOKE_OBJECT (TRIGGER, op, ARG_OBJECT (player)))
1040 return; 979 return;
980
1041 player = op->above; 981 player = op->above;
1042 982
1043 for (walk = op->inv; walk != NULL; walk = walk->below) 983 for (walk = op->inv; walk; walk = walk->below)
1044 apply_changes_to_player (player, walk); 984 apply_changes_to_player (player, walk);
1045 985
1046 player->update_stats (); 986 player->update_stats ();
1047 987
1048 esrv_send_inventory (op->above, op->above); 988 esrv_send_inventory (op->above, op->above);
1049 esrv_update_item (UPD_FACE, op->above, op->above); 989 esrv_update_item (UPD_FACE, op->above, op->above);
1050 990
1051 /* update players death & WoR home-position */ 991 /* update players death & WoR home-position */
1052 sscanf (EXIT_PATH (op), "%c", &c); 992 if (*EXIT_PATH (op) == '/')
1053 if (c == '/')
1054 { 993 {
1055 player->contr->savebed_map = EXIT_PATH (op); 994 player->contr->savebed_map = EXIT_PATH (op);
1056 player->contr->bed_x = EXIT_X (op); 995 player->contr->bed_x = EXIT_X (op);
1057 player->contr->bed_y = EXIT_Y (op); 996 player->contr->bed_y = EXIT_Y (op);
1058 } 997 }
1059 else 998 else
1060 LOG (llevDebug, "WARNING: destination '%s' in player_changer must be an absolute path!\n", &EXIT_PATH (op)); 999 LOG (llevDebug, "WARNING: destination '%s' in player_changer must be an absolute path!\n", &EXIT_PATH (op));
1061 1000
1062 op->above->enter_exit (op); 1001 op->above->enter_exit (op);
1063 player->contr->save ();
1064 } 1002 }
1065} 1003}
1066 1004
1067/* firewalls fire other spells. 1005/* firewalls fire other spells.
1068 * The direction of the wall is stored in op->stats.sp. 1006 * The direction of the wall is stored in op->stats.sp.
1100 * it'll paralyze the victim for hp*his speed/op->speed 1038 * it'll paralyze the victim for hp*his speed/op->speed
1101 */ 1039 */
1102void 1040void
1103move_player_mover (object *op) 1041move_player_mover (object *op)
1104{ 1042{
1105 object *victim, *nextmover;
1106 int dir = op->stats.sp; 1043 int dir = op->stats.sp;
1107 sint16 nx, ny; 1044 sint16 nx, ny;
1108 maptile *m; 1045 maptile *m;
1109 1046
1110 /* Determine direction now for random movers so we do the right thing */ 1047 /* Determine direction now for random movers so we do the right thing */
1111 if (!dir) 1048 if (!dir)
1112 dir = rndm (1, 8); 1049 dir = rndm (1, 8);
1113 1050
1114 for (victim = GET_MAP_OB (op->map, op->x, op->y); victim != NULL; victim = victim->above) 1051 for (object *victim = op->ms ().bot; victim; victim = victim->above)
1115 { 1052 {
1116 if (QUERY_FLAG (victim, FLAG_ALIVE) && !QUERY_FLAG (victim, FLAG_WIZPASS) && 1053 if (QUERY_FLAG (victim, FLAG_ALIVE) && !QUERY_FLAG (victim, FLAG_WIZPASS) &&
1117 (victim->move_type & op->move_type || !victim->move_type)) 1054 (victim->move_type & op->move_type || !victim->move_type))
1118 { 1055 {
1119 1056
1136 } 1073 }
1137 1074
1138 if (should_director_abort (op, victim)) 1075 if (should_director_abort (op, victim))
1139 return; 1076 return;
1140 1077
1141 for (nextmover = GET_MAP_OB (m, nx, ny); nextmover != NULL; nextmover = nextmover->above) 1078 for (object *nextmover = m->at (nx, ny).bot; nextmover; nextmover = nextmover->above)
1142 { 1079 {
1143 if (nextmover->type == PLAYERMOVER) 1080 if (nextmover->type == PLAYERMOVER)
1144 nextmover->speed_left = -.99; 1081 nextmover->speed_left = -.99f;
1082
1145 if (QUERY_FLAG (nextmover, FLAG_ALIVE)) 1083 if (QUERY_FLAG (nextmover, FLAG_ALIVE))
1146 {
1147 op->speed_left = -1.1; /* wait until the next thing gets out of the way */ 1084 op->speed_left = -1.1f; /* wait until the next thing gets out of the way */
1148 }
1149 } 1085 }
1150 1086
1151 if (victim->type == PLAYER) 1087 if (victim->type == PLAYER)
1152 { 1088 {
1153 /* only level >=1 movers move people */ 1089 /* only level >=1 movers move people */
1157 * is cleared, otherwise the player will get stuck in 1093 * is cleared, otherwise the player will get stuck in
1158 * place. This can happen if the player used a spell to 1094 * place. This can happen if the player used a spell to
1159 * get to this space. 1095 * get to this space.
1160 */ 1096 */
1161 victim->contr->fire_on = 0; 1097 victim->contr->fire_on = 0;
1162 victim->speed_left = -FABS (victim->speed); 1098 victim->speed_left = 1.f;
1163 move_player (victim, dir); 1099 move_player (victim, dir);
1164 } 1100 }
1165 else 1101 else
1166 return; 1102 return;
1167 } 1103 }
1171 if (!op->stats.maxsp && op->attacktype) 1107 if (!op->stats.maxsp && op->attacktype)
1172 op->stats.maxsp = 2; 1108 op->stats.maxsp = 2;
1173 1109
1174 if (op->attacktype) 1110 if (op->attacktype)
1175 { /* flag to paralyze the player */ 1111 { /* flag to paralyze the player */
1176
1177 victim->speed_left = -FABS (op->stats.maxsp * victim->speed / op->speed); 1112 victim->speed_left = max (-5.f, -FABS (op->stats.maxsp * victim->speed / op->speed));
1178 /* Not sure why, but for some chars on metalforge, they
1179 * would sometimes get -inf speed_left, and from the
1180 * description, it could only happen here, so just put
1181 * a lower sanity limit. My only guess is that the
1182 * mover has 0 speed.
1183 */
1184 if (victim->speed_left < -5.0)
1185 victim->speed_left = -5.0;
1186 } 1113 }
1187 } 1114 }
1188 } 1115 }
1189} 1116}
1190 1117
1206 return; 1133 return;
1207 } 1134 }
1208 1135
1209 if (op->above == NULL) 1136 if (op->above == NULL)
1210 return; 1137 return;
1138
1211 for (tmp = op->above; tmp != NULL; tmp = tmp->above) 1139 for (tmp = op->above; tmp; tmp = tmp->above)
1212 { 1140 {
1213 if (strcmp (op->other_arch->name, tmp->arch->name) == 0) 1141 if (op->other_arch->name == tmp->arch->name)
1214 { 1142 {
1215 if (op->level <= 0) 1143 if (op->level <= 0)
1216 tmp->destroy (); 1144 tmp->destroy ();
1217 else 1145 else
1218 { 1146 {
1309 with a specific code as the slaying field. 1237 with a specific code as the slaying field.
1310 At that time, it writes the contents of its own message 1238 At that time, it writes the contents of its own message
1311 field to the player. The marker will decrement hp to 1239 field to the player. The marker will decrement hp to
1312 0 and then delete itself every time it grants a mark. 1240 0 and then delete itself every time it grants a mark.
1313 unless hp was zero to start with, in which case it is infinite.*/ 1241 unless hp was zero to start with, in which case it is infinite.*/
1314
1315void 1242void
1316move_marker (object *op) 1243move_marker (object *op)
1317{ 1244{
1318 if (object *tmp = op->ms ().player ()) 1245 if (object *tmp = op->ms ().player ())
1319 { 1246 {
1320 object *tmp2; 1247 object *tmp2;
1321 1248
1322 /* remove an old force with a slaying field == op->name */ 1249 /* remove an old force with a slaying field == op->name */
1323 for (tmp2 = tmp->inv; tmp2; tmp2 = tmp2->below) 1250 for (tmp2 = tmp->inv; tmp2; tmp2 = tmp2->below)
1324 if (tmp2->type == FORCE && tmp2->slaying && !strcmp (tmp2->slaying, op->name)) 1251 if (tmp2->type == FORCE && tmp2->slaying && tmp2->slaying == op->name)
1325 { 1252 {
1326 tmp2->destroy (); 1253 tmp2->destroy ();
1327 break; 1254 break;
1328 } 1255 }
1329 1256
1330 /* cycle through his inventory to look for the MARK we want to 1257 /* cycle through his inventory to look for the MARK we want to
1331 * place 1258 * place
1332 */ 1259 */
1333 for (tmp2 = tmp->inv; tmp2; tmp2 = tmp2->below) 1260 for (tmp2 = tmp->inv; tmp2; tmp2 = tmp2->below)
1334 if (tmp2->type == FORCE && tmp2->slaying && !strcmp (tmp2->slaying, op->slaying)) 1261 if (tmp2->type == FORCE && tmp2->slaying && tmp2->slaying == op->slaying)
1335 break; 1262 break;
1336 1263
1337 /* if we didn't find our own MARK */ 1264 /* if we didn't find our own MARK */
1338 if (tmp2 == NULL) 1265 if (!tmp2)
1339 { 1266 {
1340 object *force = get_archetype (FORCE_NAME); 1267 object *force = get_archetype (FORCE_NAME);
1341 1268
1342 if (op->stats.food) 1269 if (op->stats.food)
1343 { 1270 {
1369 } 1296 }
1370 } 1297 }
1371 } 1298 }
1372} 1299}
1373 1300
1374int 1301void
1375process_object (object *op) 1302process_object (object *op)
1376{ 1303{
1377 if (QUERY_FLAG (op, FLAG_IS_A_TEMPLATE)) 1304 if (QUERY_FLAG (op, FLAG_IS_A_TEMPLATE))
1378 return 0; 1305 return;
1379 1306
1380 if (INVOKE_OBJECT (TICK, op)) 1307 if (INVOKE_OBJECT (TICK, op))
1381 return 0; 1308 return;
1382 1309
1383 if (QUERY_FLAG (op, FLAG_MONSTER)) 1310 if (QUERY_FLAG (op, FLAG_MONSTER))
1384 if (move_monster (op) || QUERY_FLAG (op, FLAG_FREED)) 1311 if (move_monster (op) || QUERY_FLAG (op, FLAG_FREED))
1385 return 1; 1312 return;
1386 1313
1387 if (QUERY_FLAG (op, FLAG_ANIMATE) && op->anim_speed == 0) 1314 if (QUERY_FLAG (op, FLAG_ANIMATE) && op->anim_speed == 0)
1388 { 1315 {
1389 if (op->type == PLAYER)
1390 animate_object (op, op->facing);
1391 else
1392 animate_object (op, op->direction); 1316 animate_object (op, op->contr ? op->facing : op->direction);
1393 1317
1394 if (QUERY_FLAG (op, FLAG_SEE_ANYWHERE)) 1318 if (QUERY_FLAG (op, FLAG_SEE_ANYWHERE))
1395 make_sure_seen (op); 1319 make_sure_seen (op);
1396 } 1320 }
1397 1321
1322 if (op->flag [FLAG_GENERATOR]
1323 || op->flag [FLAG_CHANGING]
1324 || op->flag [FLAG_IS_USED_UP])
1325 {
1398 if (QUERY_FLAG (op, FLAG_CHANGING) && !op->state) 1326 if (QUERY_FLAG (op, FLAG_CHANGING) && !op->state)
1399 { 1327 {
1400 change_object (op); 1328 change_object (op);
1401 return 1; 1329 return;
1402 } 1330 }
1403 1331
1404 if (QUERY_FLAG (op, FLAG_GENERATOR) && !QUERY_FLAG (op, FLAG_FRIENDLY)) 1332 if (QUERY_FLAG (op, FLAG_GENERATOR) && !QUERY_FLAG (op, FLAG_FRIENDLY))
1405 generate_monster (op); 1333 generate_monster (op);
1406 1334
1407 if (QUERY_FLAG (op, FLAG_IS_USED_UP) && --op->stats.food <= 0) 1335 if (QUERY_FLAG (op, FLAG_IS_USED_UP) && --op->stats.food <= 0)
1408 { 1336 {
1409 if (QUERY_FLAG (op, FLAG_APPLIED)) 1337 if (QUERY_FLAG (op, FLAG_APPLIED))
1410 remove_force (op); 1338 remove_force (op);
1411 else 1339 else
1412 { 1340 {
1413 /* IF necessary, delete the item from the players inventory */ 1341 /* If necessary, delete the item from the players inventory */
1414 object *pl = op->in_player (); 1342 object *pl = op->in_player ();
1415 1343
1416 if (pl) 1344 if (pl)
1417 esrv_del_item (pl->contr, op->count); 1345 esrv_del_item (pl->contr, op->count);
1418 1346
1419 op->remove (); 1347 op->remove ();
1420 1348
1421 if (QUERY_FLAG (op, FLAG_SEE_ANYWHERE)) 1349 if (QUERY_FLAG (op, FLAG_SEE_ANYWHERE))
1422 make_sure_not_seen (op); 1350 make_sure_not_seen (op);
1423 1351
1424 op->destroy (); 1352 op->destroy ();
1425 } 1353 }
1426 1354
1427 return 1; 1355 return;
1356 }
1428 } 1357 }
1429 1358
1430 switch (op->type) 1359 switch (op->type)
1431 { 1360 {
1432 case SPELL_EFFECT: 1361 case SPELL_EFFECT:
1433 move_spell_effect (op); 1362 move_spell_effect (op);
1434 return 1; 1363 break;
1435 1364
1436 case ROD: 1365 case ROD:
1437 case HORN: 1366 case HORN:
1438 regenerate_rod (op); 1367 regenerate_rod (op);
1439 return 1; 1368 break;
1440 1369
1441 case FORCE: 1370 case FORCE:
1442 case POTION_EFFECT: 1371 case POTION_EFFECT:
1443 remove_force (op); 1372 remove_force (op);
1444 return 1; 1373 break;
1445 1374
1446 case BLINDNESS: 1375 case BLINDNESS:
1447 remove_blindness (op); 1376 remove_blindness (op);
1448 return 0; 1377 break;
1449 1378
1450 case POISONING: 1379 case POISONING:
1451 poison_more (op); 1380 poison_more (op);
1452 return 0; 1381 break;
1453 1382
1454 case DISEASE: 1383 case DISEASE:
1455 move_disease (op); 1384 move_disease (op);
1456 return 0; 1385 break;
1457 1386
1458 case SYMPTOM: 1387 case SYMPTOM:
1459 move_symptom (op); 1388 move_symptom (op);
1460 return 0; 1389 break;
1461 1390
1462 case THROWN_OBJ: 1391 case THROWN_OBJ:
1463 case ARROW: 1392 case ARROW:
1464 move_arrow (op); 1393 move_arrow (op);
1465 return 0; 1394 break;
1466 1395
1467 case DOOR: 1396 case DOOR:
1468 remove_door (op); 1397 remove_door (op);
1469 return 0; 1398 break;
1470 1399
1471 case LOCKED_DOOR: 1400 case LOCKED_DOOR:
1472 remove_door2 (op); 1401 remove_door2 (op);
1473 return 0; 1402 break;
1474 1403
1475 case TELEPORTER: 1404 case TELEPORTER:
1476 move_teleporter (op); 1405 move_teleporter (op);
1477 return 0; 1406 break;
1478 1407
1479 case GOLEM: 1408 case GOLEM:
1480 move_golem (op); 1409 move_golem (op);
1481 return 0; 1410 break;
1482 1411
1483 case EARTHWALL: 1412 case EARTHWALL:
1484 hit_player (op, 2, op, AT_PHYSICAL, 1); 1413 hit_player (op, 2, op, AT_PHYSICAL, 1);
1485 return 0; 1414 break;
1486 1415
1487 case FIREWALL: 1416 case FIREWALL:
1488 move_firewall (op); 1417 move_firewall (op);
1489 if (op->stats.maxsp) 1418 if (op->stats.maxsp)
1490 animate_turning (op); 1419 animate_turning (op);
1491 return 0; 1420 break;
1492 1421
1493 case MOOD_FLOOR: 1422 case MOOD_FLOOR:
1494 do_mood_floor (op); 1423 do_mood_floor (op);
1495 return 0; 1424 break;
1496 1425
1497 case GATE: 1426 case GATE:
1498 move_gate (op); 1427 move_gate (op);
1499 return 0; 1428 break;
1500 1429
1501 case TIMED_GATE: 1430 case TIMED_GATE:
1502 move_timed_gate (op); 1431 move_timed_gate (op);
1503 return 0; 1432 break;
1504 1433
1505 case TRIGGER: 1434 case TRIGGER:
1506 case TRIGGER_BUTTON: 1435 case TRIGGER_BUTTON:
1507 case TRIGGER_PEDESTAL: 1436 case TRIGGER_PEDESTAL:
1508 case TRIGGER_ALTAR: 1437 case TRIGGER_ALTAR:
1509 animate_trigger (op); 1438 animate_trigger (op);
1510 return 0; 1439 break;
1511 1440
1512 case DETECTOR: 1441 case DETECTOR:
1513 move_detector (op); 1442 move_detector (op);
1514 1443
1515 case DIRECTOR: 1444 case DIRECTOR:
1516 if (op->stats.maxsp) 1445 if (op->stats.maxsp)
1517 animate_turning (op); 1446 animate_turning (op);
1518 return 0; 1447 break;
1519 1448
1520 case HOLE: 1449 case HOLE:
1521 move_hole (op); 1450 move_hole (op);
1522 return 0; 1451 break;
1523 1452
1524 case DEEP_SWAMP: 1453 case DEEP_SWAMP:
1525 move_deep_swamp (op); 1454 move_deep_swamp (op);
1526 return 0; 1455 break;
1527 1456
1528 case RUNE: 1457 case RUNE:
1529 case TRAP: 1458 case TRAP:
1530 move_rune (op); 1459 move_rune (op);
1531 return 0; 1460 break;
1532 1461
1533 case PLAYERMOVER: 1462 case PLAYERMOVER:
1534 move_player_mover (op); 1463 move_player_mover (op);
1535 return 0; 1464 break;
1536 1465
1537 case CREATOR: 1466 case CREATOR:
1538 move_creator (op); 1467 move_creator (op);
1539 return 0; 1468 break;
1540 1469
1541 case MARKER: 1470 case MARKER:
1542 move_marker (op); 1471 move_marker (op);
1543 return 0; 1472 break;
1544 1473
1545 case PLAYER_CHANGER: 1474 case PLAYER_CHANGER:
1546 move_player_changer (op); 1475 move_player_changer (op);
1547 return 0; 1476 break;
1548 1477
1549 case PEACEMAKER: 1478 case PEACEMAKER:
1550 move_peacemaker (op); 1479 move_peacemaker (op);
1551 return 0; 1480 break;
1552 }
1553 1481
1554 return 0; 1482 case PLAYER:
1483 // players have their own speed-management, so undo the --speed_left
1484 ++op->speed_left;
1485 break;
1486 }
1555} 1487}
1488

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines