Crossfire Server, Trunk  R22047
time.c
Go to the documentation of this file.
1 /*
2  * Crossfire -- cooperative multi-player graphical RPG and adventure game
3  *
4  * Copyright (c) 1999-2014 Mark Wedel and the Crossfire Development Team
5  * Copyright (c) 1992 Frank Tore Johansen
6  *
7  * Crossfire is free software and comes with ABSOLUTELY NO WARRANTY. You are
8  * welcome to redistribute it under certain conditions. For details, please
9  * see COPYING and LICENSE.
10  *
11  * The authors can be reached via e-mail at <crossfire@metalforge.org>.
12  */
13 
20 #include "global.h"
21 
22 #include <stdlib.h>
23 
24 #include "spells.h"
25 #include "sproto.h"
26 #include "object.h"
27 
38 void remove_door(object *op) {
39  int i;
40  object *tmp;
41 
42  for (i = 1; i < 9; i += 2)
43  if ((tmp = map_find_by_type(op->map, op->x+freearr_x[i], op->y+freearr_y[i], DOOR)) != NULL) {
44  tmp->speed = 0.1;
46  tmp->speed_left = -0.2;
47  }
48 
49  if (op->other_arch) {
50  tmp = arch_to_object(op->other_arch);
51  tmp->level = op->level;
52  object_insert_in_map_at(tmp, op->map, op, 0, op->x, op->y);
53  }
54  object_remove(op);
56 }
57 
64 void remove_locked_door(object *op) {
65  int i;
66  object *tmp;
67 
68  for (i = 1; i < 9; i += 2) {
69  tmp = map_find_by_type(op->map, op->x+freearr_x[i], op->y+freearr_y[i], LOCKED_DOOR);
70  if (tmp && tmp->slaying == op->slaying) {/* same key both doors */
71  tmp->speed = 0.1;
73  tmp->speed_left = -0.2;
74  }
75  }
76  if (op->other_arch) {
77  tmp = arch_to_object(op->other_arch);
78  tmp->level = op->level;
79  object_insert_in_map_at(tmp, op->map, op, 0, op->x, op->y);
80  }
81  object_remove(op);
83 }
84 
97 static int generate_monster_inv(object *gen) {
98  int i;
99  int nx, ny;
100  object *op, *head = NULL;
101  const char *code;
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  LOG(llevError, "Generator (%s) not on a map?\n", gen->name);
110  return FALSE;
111  }
112 
113  /*First count number of objects in inv*/
114  FOR_INV_PREPARE(gen, op)
115  qty++;
116  FOR_INV_FINISH();
117  if (!qty) {
118  LOG(llevError, "Generator (%s) has no inventory in generate_monster_inv?\n", gen->name);
119  return FALSE;/*No inventory*/
120  }
121  qty = rndm(0, qty-1);
122  op = NULL;
123  FOR_INV_PREPARE(gen, tmp) {
124  op = tmp;
125  if (qty == 0)
126  break;
127  qty--;
128  } FOR_INV_FINISH();
129  i = object_find_multi_free_spot_within_radius(op, gen, &nx, &ny);
130  if (i == -1)
131  return FALSE;
132  head = object_create_clone(op);
135  if (rndm(0, 9))
136  generate_artifact(head, gen->map->difficulty);
137  code = object_get_value(gen, "generator_code");
138  if (code) {
139  object_set_value(head, "generator_code", code, 1);
140  }
141  object_insert_in_map_at(head, gen->map, gen, 0, nx, ny);
142  if (QUERY_FLAG(head, FLAG_FREED))
143  return TRUE;
144  object_fix_multipart(head);
145  if (HAS_RANDOM_ITEMS(head)) {
146  create_treasure(head->randomitems, head, 0, gen->map->difficulty, 0);
147  if (QUERY_FLAG(head, FLAG_MONSTER)) {
149  }
150  }
151  return TRUE;
152 }
153 
164 static int generate_monster_arch(object *gen) {
165  int i;
166  int nx, ny;
167  object *op, *head = NULL, *prev = NULL;
168  archetype *at = gen->other_arch;
169  const char *code;
170 
171  if (gen->other_arch == NULL) {
172  LOG(llevError, "Generator without other_arch: %s\n", gen->name);
173  return FALSE;
174  }
175  /* Code below assumes the generator is on a map, as it tries
176  * to place the monster on the map. So if the generator
177  * isn't on a map, complain and exit.
178  */
179  if (gen->map == NULL) {
180  LOG(llevError, "Generator (%s) not on a map?\n", gen->name);
181  return FALSE;
182  }
183  i = object_find_multi_free_spot_within_radius(&at->clone, gen, &nx, &ny);
184  if (i == -1)
185  return FALSE;
186  while (at != NULL) {
187  op = arch_to_object(at);
188  op->x = nx+at->clone.x;
189  op->y = ny+at->clone.y;
190 
191  if (head != NULL) {
192  op->head = head;
193  prev->more = op;
194  }
195 
196  if (rndm(0, 9))
197  generate_artifact(op, gen->map->difficulty);
198 
199  code = object_get_value(gen, "generator_code");
200 
201  object_insert_in_map(op, gen->map, gen, 0);
202  /* Did generate a monster, just didn't live very long */
203  if (QUERY_FLAG(op, FLAG_FREED))
204  return TRUE;
205  if (HAS_RANDOM_ITEMS(op)) {
206  create_treasure(op->randomitems, op, 0, gen->map->difficulty, 0);
207  if (QUERY_FLAG(op, FLAG_MONSTER)) {
209  }
210  }
211  if (head == NULL) {
212  head = op;
213  if (code) {
214  object_set_value(head, "generator_code", code, 1);
215  }
216  }
217  prev = op;
218  at = at->more;
219  }
220  return TRUE;
221 }
222 
229 static void generate_monster(object *gen) {
230  int8_t children, max_children;
231  int8_t x, y;
232  const char *code, *value;
233  int did_gen = 0;
234 
235  if (GENERATE_SPEED(gen) && rndm(0, GENERATE_SPEED(gen)-1))
236  return;
237 
238  value = object_get_value(gen, "generator_max_map");
239  if (value) {
240  max_children = (int8_t)strtol(value, NULL, 10);
241  if (max_children < 1)
242  return;
243  code = object_get_value(gen, "generator_code");
244  if (code) {
245  /* Generator has a limit and has created some,
246  * so count how many already exist
247  */
248  children = 0;
249  for (x = 0; x < MAP_WIDTH(gen->map); x++) {
250  for (y = 0; y < MAP_HEIGHT(gen->map); y++) {
251  FOR_MAP_PREPARE(gen->map, x, y, tmp) {
252  value = object_get_value(tmp, "generator_code");
253  if (value && value == code) {
254  children++;
255  }
256  } FOR_MAP_FINISH();
257  }
258  }
259  /* and return without generating if there are already enough */
260  if (children >= max_children+1)
261  return;
262  } else {
263  /* Generator has a limit, but hasn't created anything yet,
264  * so no need to count, just set code and go
265  */
266  value = object_get_value(gen, "generator_name");
267  if (value) {
268  object_set_value(gen, "generator_code", value, 1);
269  } else if (gen->name) {
270  object_set_value(gen, "generator_code", gen->name, 1);
271  } else {
272  object_set_value(gen, "generator_code", "generator", 1);
273  }
274  }
275  } /* If this has a max map generator limit */
276 
278  did_gen = generate_monster_inv(gen);
279  else
280  did_gen = generate_monster_arch(gen);
281 
282  /* See if generator has a generator_limit limit set */
283  value = object_get_value(gen, "generator_limit");
284 
285  /* Only do this if we actually made a monster. If the generator
286  * was unable to create a monster (no space for example),
287  * we don't want to prematurely remove the generator.
288  */
289  if (value && did_gen) {
290  int limit = atoi(value), num_generated = 0;
291 
292  value = object_get_value(gen, "generator_generated");
293  if (value)
294  num_generated = atoi(value);
295 
296  if (num_generated++ >= limit) {
298  object_remove(gen);
300  } else {
301  char buf[50];
302 
303  snprintf(buf, sizeof(buf), "%d", num_generated);
304  object_set_value(gen, "generator_generated", buf, 1);
305  }
306  }
307 }
308 
316 static void remove_force(object *op) {
317  if (--op->duration > 0) {
318  check_spell_expiry(op);
319  return;
320  }
321 
322  switch (op->subtype) {
323  case FORCE_CONFUSION:
324  if (op->env != NULL) {
325  CLEAR_FLAG(op->env, FLAG_CONFUSED);
326  draw_ext_info(NDI_UNIQUE, 0, op->env,
328  "You regain your senses.");
329  }
330  break;
331 
333  /* The force is into the item that was created */
334  if (op->env != NULL && op->inv != NULL) {
335  object *inv = op->inv;
336  object *pl = object_get_player_container(op);
337 
338  object_remove(inv);
339  inv->weight = (inv->nrof ? (int32_t)(op->env->weight/inv->nrof) : op->env->weight);
340  if (op->env->env) {
341  object_insert_in_ob(inv, op->env->env);
342  if (pl) {
343  char name[HUGE_BUF];
344 
345  query_short_name(inv, name, HUGE_BUF);
347  "Your %s recovers its original form.",
348  name);
349  }
350  } else {
351  /* Object on map */
352  object_insert_in_map_at(inv, op->env->map, NULL, 0, op->env->x, op->env->y);
353  }
354  inv = op->env;
355  object_remove(op);
357  object_remove(inv);
358  }
359  return;
360 
361  default:
362  break;
363  }
364 
365  if (op->env != NULL) {
367  change_abil(op->env, op);
368  fix_object(op->env);
369  }
370  object_remove(op);
372 }
373 
380 static void animate_trigger(object *op) {
381  if ((unsigned char)++op->stats.wc >= NUM_ANIMATIONS(op)) {
382  op->stats.wc = 0;
383  check_trigger(op, NULL);
384  } else {
385  SET_ANIMATION(op, op->stats.wc);
386  object_update(op, UP_OBJ_FACE);
387  }
388 }
389 
396 static void move_hole(object *op) { /* 1 = opening, 0 = closing */
397  if (op->value) { /* We're opening */
398  if (--op->stats.wc <= 0) { /* Opened, let's stop */
399  op->stats.wc = 0;
400  op->speed = 0;
402 
403  /* Hard coding this makes sense for holes I suppose */
404  op->move_on = MOVE_WALK;
405  FOR_ABOVE_PREPARE(op, tmp)
406  ob_move_on(op, tmp, tmp);
408  }
409 
410  op->state = op->stats.wc;
411  animate_object(op, 0);
412  object_update(op, UP_OBJ_FACE);
413  return;
414  }
415  /* We're closing */
416  op->move_on = 0;
417 
418  op->stats.wc++;
419  if ((int)op->stats.wc >= NUM_ANIMATIONS(op))
420  op->stats.wc = NUM_ANIMATIONS(op)-1;
421 
422  op->state = op->stats.wc;
423  animate_object(op, 0);
424  object_update(op, UP_OBJ_FACE);
425  if ((unsigned char)op->stats.wc == (NUM_ANIMATIONS(op)-1)) {
426  op->speed = 0;
427  object_update_speed(op); /* closed, let's stop */
428  return;
429  }
430 }
431 
452 object *stop_item(object *op) {
453  if (free_no_drop(op))
454  return NULL;
455 
456  if (op->map == NULL)
457  return op;
458 
459  switch (op->type) {
460  case THROWN_OBJ: {
461  object *payload = op->inv;
462 
463  if (payload == NULL)
464  return NULL;
465  object_remove(payload);
466  object_remove(op);
468  return payload;
469  }
470 
471  case ARROW:
472  if (op->speed >= MIN_ACTIVE_SPEED)
473  op = fix_stopped_arrow(op);
474  return op;
475 
476  default:
477  return op;
478  }
479 }
480 
492 void fix_stopped_item(object *op, mapstruct *map, object *originator) {
493  if (map == NULL)
494  return;
495  if (QUERY_FLAG(op, FLAG_REMOVED))
496  object_insert_in_map(op, map, originator, 0);
497  else if (op->type == ARROW)
498  object_merge(op, NULL); /* only some arrows actually need this */
499 }
500 
509 object *fix_stopped_arrow(object *op) {
510  if (free_no_drop(op))
511  return NULL;
512 
513  if (rndm(0, 99) < op->stats.food) {
514  /* Small chance of breaking */
515  object_remove(op);
517  return NULL;
518  }
519 
520  op->direction = 0;
521  op->move_on = 0;
522  op->move_type = 0;
523  op->speed = 0;
525  op->stats.wc = op->stats.sp;
526  op->stats.dam = op->stats.hp;
527  op->attacktype = op->stats.grace;
528  if (op->slaying != NULL)
529  FREE_AND_CLEAR_STR(op->slaying);
530 
531  if (op->skill != NULL)
532  FREE_AND_CLEAR_STR(op->skill);
533 
534  if (op->spellarg != NULL) {
535  op->slaying = add_string(op->spellarg);
536  free(op->spellarg);
537  op->spellarg = NULL;
538  } else
539  op->slaying = NULL;
540 
541  /* Reset these to zero, so that object_can_merge will work properly */
542  op->spellarg = NULL;
543  op->stats.sp = 0;
544  op->stats.hp = 0;
545  op->stats.grace = 0;
546  op->level = 0;
547  animate_object(op, 0);
548  object_clear_owner(op); /* So that stopped arrows will be saved */
549  object_update(op, UP_OBJ_FACE);
550  return op;
551 }
552 
562 int free_no_drop(object *op) {
563  if (!QUERY_FLAG(op, FLAG_NO_DROP)) {
564  return 0;
565  }
566 
567  if (!QUERY_FLAG(op, FLAG_REMOVED)) {
568  object_remove(op);
569  }
570 
571  object_free(op, FREE_OBJ_FREE_INVENTORY);
572  return 1;
573 }
574 
589 void change_object(object *op) {
590  object *env;
591  int i;
592  int friendly;
593  int unaggressive;
594  object *owner;
595 
596  if (op->other_arch == NULL) {
597  LOG(llevError, "Change object (%s) without other_arch error.\n", op->name);
598  return;
599  }
600 
601  /* In non-living items only change when food value is 0 */
602  if (!QUERY_FLAG(op, FLAG_ALIVE)) {
603  if (op->stats.food-- > 0)
604  return;
605  else
606  op->stats.food = 1; /* so 1 other_arch is made */
607  }
608 
609  env = op->env;
610  object_remove(op);
611  friendly = QUERY_FLAG(op, FLAG_FRIENDLY);
612  unaggressive = QUERY_FLAG(op, FLAG_UNAGGRESSIVE);
613  owner = object_get_owner(op);
614  for (i = 0; i < op->stats.food; i++) {
615  object *tmp;
616 
617  tmp = arch_to_object(op->other_arch);
618  if (op->type == LAMP)
619  tmp->stats.food = op->stats.food-1;
620  tmp->stats.hp = op->stats.hp;
621  if (friendly) {
622  SET_FLAG(tmp, FLAG_FRIENDLY);
623  add_friendly_object(tmp);
624  tmp->attack_movement = PETMOVE;
625  if (owner != NULL)
626  object_set_owner(tmp, owner);
627  }
628  if (unaggressive)
630  if (env) {
631  tmp->x = env->x,
632  tmp->y = env->y;
633  tmp = object_insert_in_ob(tmp, env);
634  }
635  // If there is more to the object, put in the map,
636  // then initiate the process of setting up multipartdom.
637  else if (tmp->arch->more)
638  {
639  tmp->map = op->map;
640  // Get the best free spot for the object
641  // Using the clone of the arch because I do not think that the actual object is ready yet.
642  if (object_find_multi_free_spot_around(&tmp->arch->clone, op, &tmp->x, &tmp->y) != 0)
643  {
644  LOG(llevInfo, "change_object: Failed to find a spot to put changing multipart object\n");
645  // Put the orignal object back.
646  object_insert_in_map(op, op->map, NULL, INS_NO_MERGE|INS_ABOVE_FLOOR_ONLY|INS_NO_WALK_ON);
647  // Free the failed object
649  // Bail out so we don't break things.
650  return;
651  }
652  object_insert_in_map(tmp, op->map, op, INS_NO_MERGE|INS_ABOVE_FLOOR_ONLY|INS_NO_WALK_ON);
654  }
655  else{
656  // Single-size objects work here.
657  object_insert_to_free_spot_or_free(tmp, op->map, op->x, op->y, 1, SIZEOFFREE1+1, op);
658  }
659  }
660  if (friendly)
663 }
664 
675 void move_firewall(object *op) {
676  object *spell;
677 
678  if (!op->map)
679  return; /* dm has created a firewall in his inventory */
680 
681  spell = op->inv;
682  if (!spell) {
683  LOG(llevError, "firewall '%s' in (%s, %d, %d) has no spell\n", op->name, op->map->path, op->x, op->y);
684  return;
685  }
686 
687  cast_spell(op, op, op->direction ? op->direction : get_random_dir(), spell, NULL);
688 }
689 
690 
704 void move_player_mover(object *op) {
705  int dir = op->stats.sp;
706  int16_t nx, ny;
707  mapstruct *m;
708 
709  if (!op->map) {
710  if (op->env && op->env->map)
711  LOG(llevError, "move_player_mover: mover not in a map at %s %d %d!\n", op->env->map->path, op->env->x, op->env->y);
712  else
713  LOG(llevError, "move_player_mover: mover not in a map at undefinite location!");
714  op->speed = 0;
716  return;
717  }
718 
719  /* Determine direction now for random movers so we do the right thing */
720  if (!dir)
721  dir = get_random_dir();
722 
723  FOR_MAP_PREPARE(op->map, op->x, op->y, victim) {
724  if (QUERY_FLAG(victim, FLAG_ALIVE)
725  && !QUERY_FLAG(victim, FLAG_WIZPASS)
726  && (victim->move_type&op->move_type || !victim->move_type)) {
727  victim = HEAD(victim);
728 
729  if (QUERY_FLAG(op, FLAG_LIFESAVE) && op->stats.hp-- < 0) {
730  object_remove(op);
732  return;
733  }
734  nx = op->x+freearr_x[dir];
735  ny = op->y+freearr_y[dir];
736  m = op->map;
737  if (get_map_flags(m, &m, nx, ny, &nx, &ny)&P_OUT_OF_MAP) {
738  LOG(llevError, "move_player_mover: Trying to push player off the map! map=%s (%d, %d)\n", m->path, op->x, op->y);
739  return;
740  }
741 
742  if (should_director_abort(op, victim))
743  return;
744 
745  FOR_MAP_PREPARE(m, nx, ny, nextmover) {
746  if (nextmover->type == PLAYERMOVER)
747  nextmover->speed_left = -.99;
748  if (QUERY_FLAG(nextmover, FLAG_ALIVE)) {
749  op->speed_left = -1.1; /* wait until the next thing gets out of the way */
750  }
751  } FOR_MAP_FINISH();
752 
753  if (victim->type == PLAYER) {
754  /* only level >= 1 movers move people */
755  if (op->level) {
756  /* Following is a bit of hack. We need to make sure it
757  * is cleared, otherwise the player will get stuck in
758  * place. This can happen if the player used a spell to
759  * get to this space.
760  */
761  victim->contr->fire_on = 0;
762  victim->speed_left = -FABS(victim->speed);
763  move_player(victim, dir);
764  } else
765  return;
766  } else
767  move_object(victim, dir);
768 
769  if (!op->stats.maxsp && op->attacktype)
770  op->stats.maxsp = 2.0;
771 
772  if (op->attacktype) { /* flag to paralyze the player */
773  victim->speed_left = -FABS(op->stats.maxsp*victim->speed/op->speed);
774  /* Not sure why, but for some chars on metalforge, they
775  * would sometimes get -inf speed_left, and from the
776  * description, it could only happen here, so just put
777  * a lower sanity limit. My only guess is that the
778  * mover has 0 speed.
779  */
780  if (victim->speed_left < -5.0)
781  victim->speed_left = -5.0;
782  }
783  }
784  } FOR_MAP_FINISH();
785 }
786 
796 int process_object(object *op) {
798  return 0;
799 
800  if (events_execute_object_event(op, EVENT_TIME, NULL, NULL, NULL, SCRIPT_FIX_NOTHING) != 0)
801  return 0;
802 
803  if (QUERY_FLAG(op, FLAG_MONSTER))
804  if (monster_move(op) || QUERY_FLAG(op, FLAG_FREED))
805  return 1;
806 
807  if ((QUERY_FLAG(op, FLAG_ANIMATE) && op->anim_speed == 0)
808  || (op->temp_animation && op->temp_anim_speed == 0)) {
809  op->state++;
810  if (op->type == PLAYER)
811  animate_object(op, op->facing);
812  else
813  animate_object(op, op->direction);
814 
815  if (QUERY_FLAG(op, FLAG_SEE_ANYWHERE))
816  make_sure_seen(op);
817  }
818  if (QUERY_FLAG(op, FLAG_CHANGING) && !op->state) {
819  change_object(op);
820  return 1;
821  }
823  generate_monster(op);
824 
825  /* If object can be used up, decrement 'food' and eventually remove it. */
826  if (QUERY_FLAG(op, FLAG_IS_USED_UP) && op->stats.food-- <= 0) {
827  if (QUERY_FLAG(op, FLAG_APPLIED)) {
828  remove_force(op);
829  } else {
830  if (op->env != NULL && op->env->type == PLAYER) {
831  sstring key;
832  key_value *used_up_message;
833 
834  key = add_string("used_up_message");
835  used_up_message = object_get_key_value(op, key);
836  free_string(key);
837 
838  if (used_up_message != NULL) {
841  "The %s %s.", op->name, used_up_message->value);
842  }
843  }
844 
845  object_remove(op);
846  if (QUERY_FLAG(op, FLAG_SEE_ANYWHERE))
847  make_sure_not_seen(op);
848  object_free(op, FREE_OBJ_DROP_ABOVE_FLOOR);
849  }
850  return 1;
851  }
852  return (ob_process(op) == METHOD_OK ? 1 : 0);
853 }
854 
855 void legacy_remove_force(object *op) {
856  remove_force(op);
857 }
858 
859 void legacy_animate_trigger(object *op) {
860  animate_trigger(op);
861 }
862 
863 void legacy_move_hole(object *op) {
864  move_hole(op);
865 }
void draw_ext_info_format(int flags, int pri, const object *pl, uint8_t type, uint8_t subtype, const char *format,...)
Definition: main.c:313
char path[HUGE_BUF]
Definition: map.h:366
#define FLAG_NO_DROP
Definition: define.h:289
Definition: player.h:92
#define MSG_TYPE_ITEM_CHANGE
Definition: newclient.h:640
#define MOVE_WALK
Definition: define.h:407
#define MSG_TYPE_ITEM
Definition: newclient.h:388
void object_free(object *ob, int flags)
Definition: object.c:1348
int move_player(object *op, int dir)
Definition: player.c:2913
int free_no_drop(object *op)
Definition: time.c:562
#define SET_FLAG(xyz, p)
Definition: define.h:223
void object_clear_owner(object *op)
Definition: object.c:587
#define FABS(x)
Definition: define.h:22
StringBuffer * buf
Definition: readable.c:1591
#define FLAG_FRIENDLY
Definition: define.h:246
static void generate_monster(object *gen)
Definition: time.c:229
static int generate_monster_inv(object *gen)
Definition: time.c:97
void free_string(sstring str)
Definition: shstr.c:280
#define HUGE_BUF
Definition: define.h:37
#define SET_ANIMATION(ob, newanim)
Definition: global.h:160
void object_fix_multipart(object *tmp)
Definition: object.c:4442
const char * object_get_value(const object *op, const char *const key)
Definition: object.c:4136
#define MAP_HEIGHT(m)
Definition: map.h:80
short freearr_x[SIZEOFFREE]
Definition: object.c:65
int object_find_multi_free_spot_within_radius(const object *ob, const object *gen, int *hx, int *hy)
Definition: object.c:3144
static int generate_monster_arch(object *gen)
Definition: time.c:164
#define FLAG_CONFUSED
Definition: define.h:312
void check_spell_expiry(object *spell)
Definition: spell_util.c:2042
method_ret ob_process(object *op)
Definition: ob_methods.c:67
void fix_stopped_item(object *op, mapstruct *map, object *originator)
Definition: time.c:492
#define FLAG_SEE_ANYWHERE
Definition: define.h:319
#define TRUE
Definition: compat.h:10
int monster_move(object *op)
Definition: monster.c:699
#define FALSE
Definition: compat.h:11
void remove_friendly_object(object *op)
Definition: friend.c:56
void change_object(object *op)
Definition: time.c:589
void object_update(object *op, int action)
Definition: object.c:1190
#define MSG_TYPE_ITEM_REMOVE
Definition: newclient.h:638
void make_sure_seen(const object *op)
Definition: los.c:636
#define NDI_BLACK
Definition: newclient.h:221
static void animate_trigger(object *op)
Definition: time.c:380
#define PETMOVE
Definition: define.h:518
void draw_ext_info(int flags, int pri, const object *pl, uint8_t type, uint8_t subtype, const char *message)
Definition: main.c:308
#define FLAG_REMOVED
Definition: define.h:232
void remove_locked_door(object *op)
Definition: time.c:64
short freearr_y[SIZEOFFREE]
Definition: object.c:71
static void remove_force(object *op)
Definition: time.c:316
void create_treasure(treasurelist *t, object *op, int flag, int difficulty, int tries)
Definition: treasure.c:252
#define FLAG_IS_USED_UP
Definition: define.h:260
int object_find_multi_free_spot_around(const object *ob, const object *gen, int16_t *hx, int16_t *hy)
Definition: object.c:3028
int rndm(int min, int max)
Definition: utils.c:162
void object_set_owner(object *op, object *owner)
Definition: object.c:604
int object_set_value(object *op, const char *key, const char *value, int add_key)
Definition: object.c:4259
object * stop_item(object *op)
Definition: time.c:452
void object_free_drop_inventory(object *ob)
Definition: object.c:1316
int change_abil(object *op, object *tmp)
Definition: living.c:395
key_value * object_get_key_value(const object *ob, const char *key)
Definition: object.c:4111
object * object_insert_in_map_at(object *op, mapstruct *m, object *originator, int flag, int x, int y)
Definition: object.c:1849
#define MSG_TYPE_ATTRIBUTE_BAD_EFFECT_END
Definition: newclient.h:561
#define FLAG_ALIVE
Definition: define.h:230
static void move_hole(object *op)
Definition: time.c:396
object * object_insert_in_ob(object *op, object *where)
Definition: object.c:2602
signed short int16_t
Definition: win32.h:160
object * arch_to_object(archetype *at)
Definition: arch.cpp:232
#define FOR_ABOVE_FINISH()
Definition: define.h:731
#define METHOD_OK
Definition: ob_methods.h:15
#define EVENT_TIME
Definition: events.h:31
#define FLAG_UNAGGRESSIVE
Definition: define.h:272
void monster_check_apply_all(object *monster)
Definition: monster.c:1827
#define snprintf
Definition: win32.h:46
#define MSG_TYPE_ATTRIBUTE
Definition: newclient.h:380
#define FOR_INV_FINISH()
Definition: define.h:714
void add_friendly_object(object *op)
Definition: friend.c:30
#define FLAG_CHANGING
Definition: define.h:263
#define FOR_ABOVE_PREPARE(op_, it_)
Definition: define.h:724
object * fix_stopped_arrow(object *op)
Definition: time.c:509
#define FLAG_IS_A_TEMPLATE
Definition: define.h:375
object * object_create_clone(object *asrc)
Definition: object.c:3699
#define P_OUT_OF_MAP
Definition: map.h:252
object * object_insert_in_map(object *op, mapstruct *m, object *originator, int flag)
Definition: object.c:2110
#define FORCE_CONFUSION
Definition: spells.h:144
int get_random_dir(void)
Definition: utils.c:427
#define FREE_AND_CLEAR_STR(xyz)
Definition: global.h:198
#define QUERY_FLAG(xyz, p)
Definition: define.h:225
#define CLEAR_FLAG(xyz, p)
Definition: define.h:224
void legacy_remove_force(object *op)
Definition: time.c:855
#define GENERATE_SPEED(xyz)
Definition: define.h:452
void generate_artifact(object *op, int difficulty)
Definition: artifact.c:155
method_ret ob_move_on(object *op, object *victim, object *originator)
Definition: ob_methods.c:111
void move_firewall(object *op)
Definition: time.c:675
void object_insert_to_free_spot_or_free(object *op, mapstruct *map, int x, int y, int start, int stop, object *originator)
Definition: object.c:4550
#define FOR_MAP_FINISH()
Definition: define.h:767
void animate_object(object *op, int dir)
Definition: anim.c:43
const char * sstring
Definition: global.h:40
void legacy_animate_trigger(object *op)
Definition: time.c:859
#define FLAG_ANIMATE
Definition: define.h:242
void move_player_mover(object *op)
Definition: time.c:704
#define FLAG_GENERATOR
Definition: define.h:248
signed char int8_t
Definition: win32.h:158
#define NUM_ANIMATIONS(ob)
Definition: global.h:169
#define MAP_WIDTH(m)
Definition: map.h:78
#define FLAG_APPLIED
Definition: define.h:235
int move_object(object *op, int dir)
Definition: move.c:39
object * object_merge(object *op, object *top)
Definition: object.c:1800
void query_short_name(const object *op, char *buf, size_t size)
Definition: item.c:508
object * object_get_player_container(object *op)
Definition: object.c:377
#define FLAG_LIFESAVE
Definition: define.h:306
signed int int32_t
Definition: win32.h:159
void object_handle_death_animation(object *op)
Definition: object.c:5142
void object_unset_flag_inv(object *op, int flag)
Definition: object.c:2988
sstring add_string(const char *str)
Definition: shstr.c:124
#define MIN_ACTIVE_SPEED
Definition: define.h:676
#define FORCE_TRANSFORMED_ITEM
Definition: spells.h:146
#define FLAG_MONSTER
Definition: define.h:245
int events_execute_object_event(object *op, int eventcode, object *activator, object *third, const char *message, int fix)
Definition: events.cpp:259
int get_map_flags(mapstruct *oldmap, mapstruct **newmap, int16_t x, int16_t y, int16_t *nx, int16_t *ny)
Definition: map.c:311
#define NDI_UNIQUE
Definition: newclient.h:245
#define SIZEOFFREE1
Definition: define.h:152
void LOG(LogLevel logLevel, const char *format,...)
Definition: logger.c:51
#define FOR_MAP_PREPARE(map_, mx_, my_, it_)
Definition: define.h:760
int check_trigger(object *op, object *cause)
Definition: button.c:518
Definition: map.h:326
int should_director_abort(const object *op, const object *victim)
Definition: apply.c:68
#define FLAG_WIZPASS
Definition: define.h:315
void make_sure_not_seen(const object *op)
Definition: los.c:659
void fix_object(object *op)
Definition: living.c:1124
void legacy_move_hole(object *op)
Definition: time.c:863
#define FLAG_CONTENT_ON_GEN
Definition: define.h:374
void object_update_speed(object *op)
Definition: object.c:1086
#define SCRIPT_FIX_NOTHING
Definition: global.h:371
object * object_get_owner(object *op)
Definition: object.c:568
#define HAS_RANDOM_ITEMS(op)
Definition: define.h:183
#define FOR_INV_PREPARE(op_, it_)
Definition: define.h:707
int cast_spell(object *op, object *caster, int dir, object *spell_ob, char *stringarg)
Definition: spell_util.c:1459
void object_remove(object *op)
Definition: object.c:1588
object * map_find_by_type(mapstruct *m, int x, int y, uint8_t type)
Definition: object.c:2877
int process_object(object *op)
Definition: time.c:796
#define FLAG_FREED
Definition: define.h:233
void remove_door(object *op)
Definition: time.c:38