ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/server/time.C
(Generate patch)

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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines