Crossfire Server, Trunk  R20513
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 
37 void remove_door(object *op) {
38  int i;
39  object *tmp;
40 
41  for (i = 1; i < 9; i += 2)
42  if ((tmp = map_find_by_type(op->map, op->x+freearr_x[i], op->y+freearr_y[i], DOOR)) != NULL) {
43  tmp->speed = 0.1;
45  tmp->speed_left = -0.2;
46  }
47 
48  if (op->other_arch) {
49  tmp = arch_to_object(op->other_arch);
50  tmp->level = op->level;
51  object_insert_in_map_at(tmp, op->map, op, 0, op->x, op->y);
52  }
53  object_remove(op);
55 }
56 
63 void remove_locked_door(object *op) {
64  int i;
65  object *tmp;
66 
67  for (i = 1; i < 9; i += 2) {
68  tmp = map_find_by_type(op->map, op->x+freearr_x[i], op->y+freearr_y[i], LOCKED_DOOR);
69  if (tmp && tmp->slaying == op->slaying) {/* same key both doors */
70  tmp->speed = 0.1;
72  tmp->speed_left = -0.2;
73  }
74  }
75  if (op->other_arch) {
76  tmp = arch_to_object(op->other_arch);
77  tmp->level = op->level;
78  object_insert_in_map_at(tmp, op->map, op, 0, op->x, op->y);
79  }
80  object_remove(op);
82 }
83 
96 static int generate_monster_inv(object *gen) {
97  int i;
98  int nx, ny;
99  object *op, *head = NULL;
100  const char *code;
101  int qty = 0;
102 
103  /* Code below assumes the generator is on a map, as it tries
104  * to place the monster on the map. So if the generator
105  * isn't on a map, complain and exit.
106  */
107  if (gen->map == NULL) {
108  LOG(llevError, "Generator (%s) not on a map?\n", gen->name);
109  return FALSE;
110  }
111 
112  /*First count number of objects in inv*/
113  FOR_INV_PREPARE(gen, op)
114  qty++;
115  FOR_INV_FINISH();
116  if (!qty) {
117  LOG(llevError, "Generator (%s) has no inventory in generate_monster_inv?\n", gen->name);
118  return FALSE;/*No inventory*/
119  }
120  qty = rndm(0, qty-1);
121  op = NULL;
122  FOR_INV_PREPARE(gen, tmp) {
123  op = tmp;
124  if (qty == 0)
125  break;
126  qty--;
127  } FOR_INV_FINISH();
128  i = object_find_multi_free_spot_within_radius(op, gen, &nx, &ny);
129  if (i == -1)
130  return FALSE;
131  head = object_create_clone(op);
134  if (rndm(0, 9))
135  generate_artifact(head, gen->map->difficulty);
136  code = object_get_value(gen, "generator_code");
137  if (code) {
138  object_set_value(head, "generator_code", code, 1);
139  }
140  object_insert_in_map_at(head, gen->map, gen, 0, nx, ny);
141  if (QUERY_FLAG(head, FLAG_FREED))
142  return TRUE;
143  object_fix_multipart(head);
144  if (HAS_RANDOM_ITEMS(head)) {
145  create_treasure(head->randomitems, head, 0, gen->map->difficulty, 0);
146  if (QUERY_FLAG(head, FLAG_MONSTER)) {
148  }
149  }
150  return TRUE;
151 }
152 
163 static int generate_monster_arch(object *gen) {
164  int i;
165  int nx, ny;
166  object *op, *head = NULL, *prev = NULL;
167  archetype *at = gen->other_arch;
168  const char *code;
169 
170  if (gen->other_arch == NULL) {
171  LOG(llevError, "Generator without other_arch: %s\n", gen->name);
172  return FALSE;
173  }
174  /* Code below assumes the generator is on a map, as it tries
175  * to place the monster on the map. So if the generator
176  * isn't on a map, complain and exit.
177  */
178  if (gen->map == NULL) {
179  LOG(llevError, "Generator (%s) not on a map?\n", gen->name);
180  return FALSE;
181  }
182  i = object_find_multi_free_spot_within_radius(&at->clone, gen, &nx, &ny);
183  if (i == -1)
184  return FALSE;
185  while (at != NULL) {
186  op = arch_to_object(at);
187  op->x = nx+at->clone.x;
188  op->y = ny+at->clone.y;
189 
190  if (head != NULL) {
191  op->head = head;
192  prev->more = op;
193  }
194 
195  if (rndm(0, 9))
196  generate_artifact(op, gen->map->difficulty);
197 
198  code = object_get_value(gen, "generator_code");
199 
200  object_insert_in_map(op, gen->map, gen, 0);
201  /* Did generate a monster, just didn't live very long */
202  if (QUERY_FLAG(op, FLAG_FREED))
203  return TRUE;
204  if (HAS_RANDOM_ITEMS(op)) {
205  create_treasure(op->randomitems, op, 0, gen->map->difficulty, 0);
206  if (QUERY_FLAG(op, FLAG_MONSTER)) {
208  }
209  }
210  if (head == NULL) {
211  head = op;
212  if (code) {
213  object_set_value(head, "generator_code", code, 1);
214  }
215  }
216  prev = op;
217  at = at->more;
218  }
219  return TRUE;
220 }
221 
228 static void generate_monster(object *gen) {
229  int8_t children, max_children;
230  int8_t x, y;
231  const char *code, *value;
232  int did_gen = 0;
233 
234  if (GENERATE_SPEED(gen) && rndm(0, GENERATE_SPEED(gen)-1))
235  return;
236 
237  value = object_get_value(gen, "generator_max_map");
238  if (value) {
239  max_children = (int8_t)strtol(value, NULL, 10);
240  if (max_children < 1)
241  return;
242  code = object_get_value(gen, "generator_code");
243  if (code) {
244  /* Generator has a limit and has created some,
245  * so count how many already exist
246  */
247  children = 0;
248  for (x = 0; x < MAP_WIDTH(gen->map); x++) {
249  for (y = 0; y < MAP_HEIGHT(gen->map); y++) {
250  FOR_MAP_PREPARE(gen->map, x, y, tmp) {
251  value = object_get_value(tmp, "generator_code");
252  if (value && value == code) {
253  children++;
254  }
255  } FOR_MAP_FINISH();
256  }
257  }
258  /* and return without generating if there are already enough */
259  if (children >= max_children+1)
260  return;
261  } else {
262  /* Generator has a limit, but hasn't created anything yet,
263  * so no need to count, just set code and go
264  */
265  value = object_get_value(gen, "generator_name");
266  if (value) {
267  object_set_value(gen, "generator_code", value, 1);
268  } else if (gen->name) {
269  object_set_value(gen, "generator_code", gen->name, 1);
270  } else {
271  object_set_value(gen, "generator_code", "generator", 1);
272  }
273  }
274  } /* If this has a max map generator limit */
275 
277  did_gen = generate_monster_inv(gen);
278  else
279  did_gen = generate_monster_arch(gen);
280 
281  /* See if generator has a generator_limit limit set */
282  value = object_get_value(gen, "generator_limit");
283 
284  /* Only do this if we actually made a monster. If the generator
285  * was unable to create a monster (no space for example),
286  * we don't want to prematurely remove the generator.
287  */
288  if (value && did_gen) {
289  int limit = atoi(value), num_generated = 0;
290 
291  value = object_get_value(gen, "generator_generated");
292  if (value)
293  num_generated = atoi(value);
294 
295  if (num_generated++ >= limit) {
296  object_remove(gen);
298  } else {
299  char buf[50];
300 
301  snprintf(buf, sizeof(buf), "%d", num_generated);
302  object_set_value(gen, "generator_generated", buf, 1);
303  }
304  }
305 }
306 
314 static void remove_force(object *op) {
315  if (--op->duration > 0) {
316  check_spell_expiry(op);
317  return;
318  }
319 
320  switch (op->subtype) {
321  case FORCE_CONFUSION:
322  if (op->env != NULL) {
324  draw_ext_info(NDI_UNIQUE, 0, op->env,
326  "You regain your senses.");
327  }
328  break;
329 
331  /* The force is into the item that was created */
332  if (op->env != NULL && op->inv != NULL) {
333  object *inv = op->inv;
334  object *pl = object_get_player_container(op);
335 
336  object_remove(inv);
337  inv->weight = (inv->nrof ? (int32_t)(op->env->weight/inv->nrof) : op->env->weight);
338  if (op->env->env) {
339  object_insert_in_ob(inv, op->env->env);
340  if (pl) {
341  char name[HUGE_BUF];
342 
343  query_short_name(inv, name, HUGE_BUF);
345  "Your %s recovers its original form.",
346  name);
347  }
348  } else {
349  /* Object on map */
350  object_insert_in_map_at(inv, op->env->map, NULL, 0, op->env->x, op->env->y);
351  }
352  inv = op->env;
353  object_remove(op);
355  object_remove(inv);
356  }
357  return;
358 
359  default:
360  break;
361  }
362 
363  if (op->env != NULL) {
365  change_abil(op->env, op);
366  fix_object(op->env);
367  }
368  object_remove(op);
370 }
371 
378 static void animate_trigger(object *op) {
379  if ((unsigned char)++op->stats.wc >= NUM_ANIMATIONS(op)) {
380  op->stats.wc = 0;
381  check_trigger(op, NULL);
382  } else {
383  SET_ANIMATION(op, op->stats.wc);
385  }
386 }
387 
394 static void move_hole(object *op) { /* 1 = opening, 0 = closing */
395  if (op->value) { /* We're opening */
396  if (--op->stats.wc <= 0) { /* Opened, let's stop */
397  op->stats.wc = 0;
398  op->speed = 0;
400 
401  /* Hard coding this makes sense for holes I suppose */
402  op->move_on = MOVE_WALK;
403  FOR_ABOVE_PREPARE(op, tmp)
404  ob_move_on(op, tmp, tmp);
406  }
407 
408  op->state = op->stats.wc;
409  animate_object(op, 0);
411  return;
412  }
413  /* We're closing */
414  op->move_on = 0;
415 
416  op->stats.wc++;
417  if ((int)op->stats.wc >= NUM_ANIMATIONS(op))
418  op->stats.wc = NUM_ANIMATIONS(op)-1;
419 
420  op->state = op->stats.wc;
421  animate_object(op, 0);
423  if ((unsigned char)op->stats.wc == (NUM_ANIMATIONS(op)-1)) {
424  op->speed = 0;
425  object_update_speed(op); /* closed, let's stop */
426  return;
427  }
428 }
429 
450 object *stop_item(object *op) {
451  if (free_no_drop(op))
452  return NULL;
453 
454  if (op->map == NULL)
455  return op;
456 
457  switch (op->type) {
458  case THROWN_OBJ: {
459  object *payload = op->inv;
460 
461  if (payload == NULL)
462  return NULL;
463  object_remove(payload);
464  object_remove(op);
466  return payload;
467  }
468 
469  case ARROW:
470  if (op->speed >= MIN_ACTIVE_SPEED)
471  op = fix_stopped_arrow(op);
472  return op;
473 
474  default:
475  return op;
476  }
477 }
478 
490 void fix_stopped_item(object *op, mapstruct *map, object *originator) {
491  if (map == NULL)
492  return;
493  if (QUERY_FLAG(op, FLAG_REMOVED))
494  object_insert_in_map(op, map, originator, 0);
495  else if (op->type == ARROW)
496  object_merge(op, NULL); /* only some arrows actually need this */
497 }
498 
507 object *fix_stopped_arrow(object *op) {
508  if (free_no_drop(op))
509  return NULL;
510 
511  if (rndm(0, 99) < op->stats.food) {
512  /* Small chance of breaking */
513  object_remove(op);
515  return NULL;
516  }
517 
518  op->direction = 0;
519  op->move_on = 0;
520  op->move_type = 0;
521  op->speed = 0;
523  op->stats.wc = op->stats.sp;
524  op->stats.dam = op->stats.hp;
525  op->attacktype = op->stats.grace;
526  if (op->slaying != NULL)
528 
529  if (op->skill != NULL)
531 
532  if (op->spellarg != NULL) {
533  op->slaying = add_string(op->spellarg);
534  free(op->spellarg);
535  op->spellarg = NULL;
536  } else
537  op->slaying = NULL;
538 
539  /* Reset these to zero, so that object_can_merge will work properly */
540  op->spellarg = NULL;
541  op->stats.sp = 0;
542  op->stats.hp = 0;
543  op->stats.grace = 0;
544  op->level = 0;
545  animate_object(op, 0);
546  object_clear_owner(op); /* So that stopped arrows will be saved */
548  return op;
549 }
550 
560 int free_no_drop(object *op) {
561  if (!QUERY_FLAG(op, FLAG_NO_DROP)) {
562  return 0;
563  }
564 
565  if (!QUERY_FLAG(op, FLAG_REMOVED)) {
566  object_remove(op);
567  }
568 
570  return 1;
571 }
572 
583 void change_object(object *op) { /* Doesn`t handle linked objs yet */
584  object *env;
585  int i;
586  int friendly;
587  int unaggressive;
588  object *owner;
589 
590  if (op->other_arch == NULL) {
591  LOG(llevError, "Change object (%s) without other_arch error.\n", op->name);
592  return;
593  }
594 
595  /* In non-living items only change when food value is 0 */
596  if (!QUERY_FLAG(op, FLAG_ALIVE)) {
597  if (op->stats.food-- > 0)
598  return;
599  else
600  op->stats.food = 1; /* so 1 other_arch is made */
601  }
602 
603  env = op->env;
604  object_remove(op);
605  friendly = QUERY_FLAG(op, FLAG_FRIENDLY);
606  unaggressive = QUERY_FLAG(op, FLAG_UNAGGRESSIVE);
607  owner = object_get_owner(op);
608  for (i = 0; i < op->stats.food; i++) { /* This doesn't handle op->more yet */
609  object *tmp;
610 
611  tmp = arch_to_object(op->other_arch);
612  if (op->type == LAMP)
613  tmp->stats.food = op->stats.food-1;
614  tmp->stats.hp = op->stats.hp;
615  if (friendly) {
616  SET_FLAG(tmp, FLAG_FRIENDLY);
617  add_friendly_object(tmp);
618  tmp->attack_movement = PETMOVE;
619  if (owner != NULL)
620  object_set_owner(tmp, owner);
621  }
622  if (unaggressive)
624  if (env) {
625  tmp->x = env->x,
626  tmp->y = env->y;
627  tmp = object_insert_in_ob(tmp, env);
628  } else
629  object_insert_to_free_spot_or_free(tmp, op->map, op->x, op->y, 1, SIZEOFFREE1+1, op);
630  }
631  if (friendly)
634 }
635 
646 void move_firewall(object *op) {
647  object *spell;
648 
649  if (!op->map)
650  return; /* dm has created a firewall in his inventory */
651 
652  spell = op->inv;
653  if (!spell) {
654  LOG(llevError, "move_firewall: no spell specified (%s, %s, %d, %d)\n", op->name, op->map->name, op->x, op->y);
655  return;
656  }
657 
658  cast_spell(op, op, op->direction ? op->direction : get_random_dir(), spell, NULL);
659 }
660 
661 
675 void move_player_mover(object *op) {
676  int dir = op->stats.sp;
677  int16_t nx, ny;
678  mapstruct *m;
679 
680  if (!op->map) {
681  if (op->env && op->env->map)
682  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);
683  else
684  LOG(llevError, "move_player_mover: mover not in a map at undefinite location!");
685  op->speed = 0;
687  return;
688  }
689 
690  /* Determine direction now for random movers so we do the right thing */
691  if (!dir)
692  dir = get_random_dir();
693 
694  FOR_MAP_PREPARE(op->map, op->x, op->y, victim) {
695  if (QUERY_FLAG(victim, FLAG_ALIVE)
696  && !QUERY_FLAG(victim, FLAG_WIZPASS)
697  && (victim->move_type&op->move_type || !victim->move_type)) {
698  victim = HEAD(victim);
699 
700  if (QUERY_FLAG(op, FLAG_LIFESAVE) && op->stats.hp-- < 0) {
701  object_remove(op);
703  return;
704  }
705  nx = op->x+freearr_x[dir];
706  ny = op->y+freearr_y[dir];
707  m = op->map;
708  if (get_map_flags(m, &m, nx, ny, &nx, &ny)&P_OUT_OF_MAP) {
709  LOG(llevError, "move_player_mover: Trying to push player off the map! map=%s (%d, %d)\n", m->path, op->x, op->y);
710  return;
711  }
712 
713  if (should_director_abort(op, victim))
714  return;
715 
716  FOR_MAP_PREPARE(m, nx, ny, nextmover) {
717  if (nextmover->type == PLAYERMOVER)
718  nextmover->speed_left = -.99;
719  if (QUERY_FLAG(nextmover, FLAG_ALIVE)) {
720  op->speed_left = -1.1; /* wait until the next thing gets out of the way */
721  }
722  } FOR_MAP_FINISH();
723 
724  if (victim->type == PLAYER) {
725  /* only level >= 1 movers move people */
726  if (op->level) {
727  /* Following is a bit of hack. We need to make sure it
728  * is cleared, otherwise the player will get stuck in
729  * place. This can happen if the player used a spell to
730  * get to this space.
731  */
732  victim->contr->fire_on = 0;
733  victim->speed_left = -FABS(victim->speed);
734  move_player(victim, dir);
735  } else
736  return;
737  } else
738  move_object(victim, dir);
739 
740  if (!op->stats.maxsp && op->attacktype)
741  op->stats.maxsp = 2.0;
742 
743  if (op->attacktype) { /* flag to paralyze the player */
744  victim->speed_left = -FABS(op->stats.maxsp*victim->speed/op->speed);
745  /* Not sure why, but for some chars on metalforge, they
746  * would sometimes get -inf speed_left, and from the
747  * description, it could only happen here, so just put
748  * a lower sanity limit. My only guess is that the
749  * mover has 0 speed.
750  */
751  if (victim->speed_left < -5.0)
752  victim->speed_left = -5.0;
753  }
754  }
755  } FOR_MAP_FINISH();
756 }
757 
767 int process_object(object *op) {
769  return 0;
770 
771  /* Lauwenmark: Handle for plugin time event */
772  if (execute_event(op, EVENT_TIME, NULL, NULL, NULL, SCRIPT_FIX_NOTHING) != 0)
773  return 0;
774 
775  if (QUERY_FLAG(op, FLAG_MONSTER))
776  if (monster_move(op) || QUERY_FLAG(op, FLAG_FREED))
777  return 1;
778 
779  if ((QUERY_FLAG(op, FLAG_ANIMATE) && op->anim_speed == 0)
780  || (op->temp_animation_id && op->temp_anim_speed == 0)) {
781  op->state++;
782  if (op->type == PLAYER)
783  animate_object(op, op->facing);
784  else
785  animate_object(op, op->direction);
786 
787  if (QUERY_FLAG(op, FLAG_SEE_ANYWHERE))
788  make_sure_seen(op);
789  }
790  if (QUERY_FLAG(op, FLAG_CHANGING) && !op->state) {
791  change_object(op);
792  return 1;
793  }
795  generate_monster(op);
796 
797  /* If object can be used up, decrement 'food' and eventually remove it. */
798  if (QUERY_FLAG(op, FLAG_IS_USED_UP) && --op->stats.food <= 0) {
799  if (QUERY_FLAG(op, FLAG_APPLIED)) {
800  remove_force(op);
801  } else {
802  if (op->env != NULL && op->env->type == PLAYER) {
803  sstring key;
804  key_value *used_up_message;
805 
806  key = add_string("used_up_message");
807  used_up_message = object_get_key_value(op, key);
808  free_string(key);
809 
810  if (used_up_message != NULL) {
813  "The %s %s.", op->name, used_up_message->value);
814  }
815  }
816 
817  object_remove(op);
818  if (QUERY_FLAG(op, FLAG_SEE_ANYWHERE))
819  make_sure_not_seen(op);
821  }
822  return 1;
823  }
824  return (ob_process(op) == METHOD_OK ? 1 : 0);
825 }
826 
827 void legacy_remove_force(object *op) {
828  remove_force(op);
829 }
830 
831 void legacy_animate_trigger(object *op) {
832  animate_trigger(op);
833 }
834 
835 void legacy_move_hole(object *op) {
836  move_hole(op);
837 }
void draw_ext_info_format(int flags, int pri, const object *pl, uint8_t type, uint8_t subtype, const char *format,...)
Sends message to player(s).
Definition: main.c:315
Error, serious thing.
Definition: logger.h:11
char path[HUGE_BUF]
Filename of the map.
Definition: map.h:365
#define FLAG_NO_DROP
Object can&#39;t be dropped.
Definition: define.h:289
One player.
Definition: player.h:92
#define MSG_TYPE_ITEM_CHANGE
Item has changed in some way.
Definition: newclient.h:640
#define MOVE_WALK
Object walks.
Definition: define.h:407
#define UP_OBJ_FACE
Only thing that changed was the face.
Definition: object.h:519
MoveType move_type
Type of movement this object uses.
Definition: object.h:424
#define MSG_TYPE_ITEM
Item related information.
Definition: newclient.h:388
Spell-related defines: spellpath, subtypes, ...
int move_player(object *op, int dir)
Player gave us a direction, check whether to move or fire.
Definition: player.c:3007
MoveType move_on
Move types affected moving on to this space.
Definition: object.h:427
int free_no_drop(object *op)
Check whether the given object is FLAG_NO_DROP.
Definition: time.c:560
uint16_t attack_movement
What kind of attack movement.
Definition: object.h:391
#define SET_FLAG(xyz, p)
Definition: define.h:223
void object_clear_owner(object *op)
Clears the owner of specified object.
Definition: object.c:581
#define FABS(x)
Decstations have trouble with fabs()...
Definition: define.h:22
uint8_t anim_speed
Ticks between animation-frames.
Definition: object.h:417
#define FLAG_IS_USED_UP
When (–food<0) the object will exit.
Definition: define.h:260
See Projectile.
Definition: object.h:117
#define FLAG_FRIENDLY
Will help players.
Definition: define.h:246
static void generate_monster(object *gen)
Main generator function.
Definition: time.c:228
static int generate_monster_inv(object *gen)
Will generate a monster according to parameters of generator.
Definition: time.c:96
void free_string(sstring str)
This will reduce the refcount, and if it has reached 0, str will be freed.
Definition: shstr.c:280
#define HUGE_BUF
Used for messages - some can be quite long.
Definition: define.h:37
#define SET_ANIMATION(ob, newanim)
Definition: global.h:171
void object_fix_multipart(object *tmp)
Ensures specified object has its more parts correctly inserted in map.
Definition: object.c:4564
const char * object_get_value(const object *op, const char *const key)
Get an extra value by key.
Definition: object.c:4246
struct treasureliststruct * randomitems
Items to be generated.
Definition: object.h:385
#define MAP_HEIGHT(m)
Map height.
Definition: map.h:80
object clone
An object from which to do object_copy()
Definition: object.h:470
int16_t duration
How long the spell lasts.
Definition: object.h:403
short freearr_x[SIZEOFFREE]
X offset when searching around a spot.
Definition: object.c:65
int object_find_multi_free_spot_within_radius(const object *ob, const object *gen, int *hx, int *hy)
Sets hx and hy to the coords to insert a possibly multi-tile ob at, within radius of generator...
Definition: object.c:3266
static int generate_monster_arch(object *gen)
Generate a monster from the other_arch field.
Definition: time.c:163
const char * slaying
Which race to do double damage to.
Definition: object.h:319
#define FLAG_CONFUSED
Will also be unable to cast spells.
Definition: define.h:312
uint8_t subtype
Subtype of object.
Definition: object.h:339
void check_spell_expiry(object *spell)
Checks if player should be warned of soon expiring spell.
Definition: spell_util.c:2031
method_ret ob_process(object *op)
Processes an object, giving it the opportunity to move or react.
Definition: ob_methods.c:62
void fix_stopped_item(object *op, mapstruct *map, object *originator)
Put stopped item where stop_item() had found it.
Definition: time.c:490
#define FLAG_SEE_ANYWHERE
The object will be visible behind walls.
Definition: define.h:319
#define TRUE
Definition: compat.h:10
int monster_move(object *op)
Main monster processing routine.
Definition: monster.c:635
#define FALSE
Definition: compat.h:11
void remove_friendly_object(object *op)
Removes the specified object from the linked list of friendly objects.
Definition: friend.c:56
void change_object(object *op)
Replaces op with its other_arch if it has reached its end of life.
Definition: time.c:583
void object_update(object *op, int action)
object_update() updates the array which represents the map.
Definition: object.c:1239
#define MSG_TYPE_ITEM_REMOVE
Item removed from inv.
Definition: newclient.h:638
uint8_t temp_anim_speed
Ticks between temporary animation-frames.
Definition: object.h:420
void make_sure_seen(const object *op)
The object is supposed to be visible through walls, thus check if any players are nearby...
Definition: los.c:632
int16_t sp
Spell points.
Definition: living.h:41
#define NDI_BLACK
Definition: newclient.h:221
static void animate_trigger(object *op)
Animate a TRIGGER.
Definition: time.c:378
Global type definitions and header inclusions.
#define PETMOVE
If the upper four bits of attack_movement are set to this number, the monster follows a player until ...
Definition: define.h:517
struct archt * other_arch
Pointer used for various things - mostly used for what this objects turns into or what this object cr...
Definition: object.h:413
void draw_ext_info(int flags, int pri, const object *pl, uint8_t type, uint8_t subtype, const char *message)
Sends message to player(s).
Definition: main.c:310
The archetype structure is a set of rules on how to generate and manipulate objects which point to ar...
Definition: object.h:465
See Mover.
Definition: object.h:140
uint16_t temp_animation_id
An index into the temporary animation array.
Definition: object.h:419
int16_t maxsp
Max spell points.
Definition: living.h:42
#define FLAG_REMOVED
Object is not in any map or invenory.
Definition: define.h:232
int16_t hp
Hit Points.
Definition: living.h:39
void remove_locked_door(object *op)
Same as remove_door() but for locked doors.
Definition: time.c:63
short freearr_y[SIZEOFFREE]
Y offset when searching around a spot.
Definition: object.c:71
static void remove_force(object *op)
Move for FORCE objects.
Definition: time.c:314
void create_treasure(treasurelist *t, object *op, int flag, int difficulty, int tries)
This calls the appropriate treasure creation function.
Definition: treasure.c:490
int rndm(int min, int max)
Returns a number between min and max.
Definition: utils.c:161
void object_set_owner(object *op, object *owner)
Sets the owner and sets the skill and exp pointers to owner&#39;s current skill and experience objects...
Definition: object.c:601
char * name
Name of map as given by its creator.
Definition: map.h:328
int object_set_value(object *op, const char *key, const char *value, int add_key)
Updates the key in op to value.
Definition: object.c:4375
object * stop_item(object *op)
An item (ARROW or such) stops moving.
Definition: time.c:450
void object_free_drop_inventory(object *ob)
Frees everything allocated by an object, removes it from the list of used objects, and puts it on the list of free objects.
Definition: object.c:1368
int change_abil(object *op, object *tmp)
Permanently alters an object&#39;s stats/flags based on another object.
Definition: living.c:394
int16_t y
Position in the map for this object.
Definition: object.h:326
key_value * object_get_key_value(const object *ob, const char *key)
Search for a field by key.
Definition: object.c:4218
object * object_insert_in_map_at(object *op, mapstruct *m, object *originator, int flag, int x, int y)
Same as object_insert_in_map() except it handle separate coordinates and do a clean job preparing mul...
Definition: object.c:1921
#define MSG_TYPE_ATTRIBUTE_BAD_EFFECT_END
End of a bad effect.
Definition: newclient.h:561
#define FREE_OBJ_FREE_INVENTORY
Free inventory objects; if not set, drop inventory.
Definition: object.h:532
#define FLAG_ALIVE
Object can fight (or be fought)
Definition: define.h:230
static void move_hole(object *op)
Move a HOLE.
Definition: time.c:394
object * object_insert_in_ob(object *op, object *where)
This function inserts the object op in the linked list inside the object environment.
Definition: object.c:2690
float speed_left
How much speed is left to spend this round.
Definition: object.h:329
signed short int16_t
Definition: win32.h:160
int32_t weight
Attributes of the object.
Definition: object.h:365
#define FOR_ABOVE_FINISH()
Finishes FOR_ABOVE_PREPARE().
Definition: define.h:729
#define METHOD_OK
Definition: ob_methods.h:15
#define FLAG_UNAGGRESSIVE
Monster doesn&#39;t attack players.
Definition: define.h:272
struct mapdef * map
Pointer to the map in which this object is present.
Definition: object.h:297
void monster_check_apply_all(object *monster)
Calls monster_check_apply() for all inventory objects.
Definition: monster.c:1757
#define snprintf
Definition: win32.h:46
#define MSG_TYPE_ATTRIBUTE
Changes to attributes (stats, resistances, etc)
Definition: newclient.h:380
#define FOR_INV_FINISH()
Finishes FOR_INV_PREPARE().
Definition: define.h:712
int16_t dam
How much damage this object does when hitting.
Definition: living.h:45
void add_friendly_object(object *op)
Add a new friendly object to the linked list of friendly objects.
Definition: friend.c:30
const char * name
The name of the object, obviously...
Definition: object.h:311
#define FLAG_CHANGING
Changes to other_arch when anim is done.
Definition: define.h:263
struct obj * env
Pointer to the object which is the environment.
Definition: object.h:293
#define FOR_ABOVE_PREPARE(op_, it_)
Constructs a loop iterating over all objects above an object.
Definition: define.h:722
object * fix_stopped_arrow(object *op)
An ARROW stops moving.
Definition: time.c:507
uint8_t state
How the object was last drawn (animation)
Definition: object.h:349
struct archt * more
Next part of a linked object.
Definition: object.h:469
#define FLAG_IS_A_TEMPLATE
Object has no ingame life until instantiated.
Definition: define.h:375
int8_t direction
Means the object is moving that way.
Definition: object.h:334
object * object_create_clone(object *asrc)
Create clone from object to another.
Definition: object.c:3832
uint32_t nrof
How many of the objects.
Definition: object.h:333
Each object (this also means archetypes!) could have a few of these "dangling" from it; this could al...
Definition: object.h:40
#define P_OUT_OF_MAP
This space is outside the map.
Definition: map.h:251
object * object_insert_in_map(object *op, mapstruct *m, object *originator, int flag)
This function inserts the object in the two-way linked list which represents what is on a map...
Definition: object.c:2152
#define FORCE_CONFUSION
Definition: spells.h:144
int get_random_dir(void)
Returns a random direction (1..8).
Definition: utils.c:426
#define FREE_AND_CLEAR_STR(xyz)
Release the shared string, and set it to NULL.
Definition: global.h:208
char * spellarg
Optional argument when casting obj::spell.
Definition: object.h:409
float speed
The overall speed of this object.
Definition: object.h:328
#define QUERY_FLAG(xyz, p)
Definition: define.h:225
#define CLEAR_FLAG(xyz, p)
Definition: define.h:224
#define HEAD(op)
Returns the head part of an object.
Definition: object.h:594
See Locked Door.
Definition: object.h:123
void legacy_remove_force(object *op)
Definition: time.c:827
#define GENERATE_SPEED(xyz)
Definition: define.h:453
void generate_artifact(object *op, int difficulty)
Decides randomly which artifact the object should be turned into.
Definition: artifact.c:155
See Door.
Definition: object.h:126
method_ret ob_move_on(object *op, object *victim, object *originator)
Makes an object move on top of another one.
Definition: ob_methods.c:105
int16_t x
Definition: object.h:326
const char * skill
Name of the skill this object uses/grants.
Definition: object.h:321
Lamp.
Definition: object.h:201
int8_t wc
Weapon Class, how skilled, the lower the better.
Definition: living.h:36
uint16_t difficulty
What level the player should be to play here.
Definition: map.h:343
void move_firewall(object *op)
Move for FIREWALL.
Definition: time.c:646
void object_insert_to_free_spot_or_free(object *op, mapstruct *map, int x, int y, int start, int stop, object *originator)
Inserts an object into its map.
Definition: object.c:4675
#define FOR_MAP_FINISH()
Finishes FOR_MAP_PREPARE().
Definition: define.h:765
#define EVENT_TIME
Triggered each time the object can react/move.
Definition: plugin.h:72
void animate_object(object *op, int dir)
Updates the face-variable of an object.
Definition: anim.c:186
const char * sstring
Strings that should be manipulated through add_string() and free_string().
Definition: global.h:40
See Player.
Definition: object.h:107
void legacy_animate_trigger(object *op)
Definition: time.c:831
#define FLAG_ANIMATE
The object looks at archetype for faces.
Definition: define.h:242
void move_player_mover(object *op)
This function takes a PLAYERMOVER as an argument, and performs the function of a player mover...
Definition: time.c:675
uint32_t attacktype
Bitmask of attacks this object does.
Definition: object.h:342
#define FLAG_GENERATOR
Will generate type ob->stats.food.
Definition: define.h:248
int16_t grace
Grace.
Definition: living.h:43
signed char int8_t
Type definitions for fixed-size integer types.
Definition: win32.h:158
#define NUM_ANIMATIONS(ob)
Definition: global.h:179
living stats
Str, Con, Dex, etc.
Definition: object.h:368
#define MAP_WIDTH(m)
Map width.
Definition: map.h:78
uint8_t type
PLAYER, BULLET, etc.
Definition: object.h:338
void object_free2(object *ob, int flags)
Frees everything allocated by an object, removes it from the list of used objects, and puts it on the list of free objects.
Definition: object.c:1391
#define FLAG_APPLIED
Object is ready for use by living.
Definition: define.h:235
int move_object(object *op, int dir)
Try to move op in the direction "dir".
Definition: move.c:39
object * object_merge(object *op, object *top)
This function goes through all objects below and including top, and merges op to the first matching o...
Definition: object.c:1869
void query_short_name(const object *op, char *buf, size_t size)
query_short_name(object) is similar to query_name(), but doesn&#39;t contain any information about object...
Definition: item.c:547
object * object_get_player_container(object *op)
Finds the player carrying an object.
Definition: object.c:353
int execute_event(object *op, int eventcode, object *activator, object *third, const char *message, int fix)
Definition: main.c:364
#define FLAG_LIFESAVE
Saves a players&#39; life once, then destr.
Definition: define.h:306
signed int int32_t
Definition: win32.h:159
const char * value
Key&#39;s value.
Definition: object.h:42
void object_unset_flag_inv(object *op, int flag)
Desactivate recursively a flag on an object inventory.
Definition: object.c:3101
sstring add_string(const char *str)
This will add &#39;str&#39; to the hash table.
Definition: shstr.c:124
#define MIN_ACTIVE_SPEED
Cut off point of when an object is put on the active list or not.
Definition: define.h:674
#define FORCE_TRANSFORMED_ITEM
Definition: spells.h:146
#define FLAG_MONSTER
Will attack players.
Definition: define.h:245
int get_map_flags(mapstruct *oldmap, mapstruct **newmap, int16_t x, int16_t y, int16_t *nx, int16_t *ny)
This rolls up wall, blocks_magic, blocks_view, etc, all into one function that just returns a P_...
Definition: map.c:302
struct obj * inv
Pointer to the first object in the inventory.
Definition: object.h:290
#define NDI_UNIQUE
Print immediately, don&#39;t buffer.
Definition: newclient.h:245
#define SIZEOFFREE1
Definition: define.h:152
struct obj * head
Points to the main object of a large body.
Definition: object.h:296
void LOG(LogLevel logLevel, const char *format,...)
Logs a message to stderr, or to file.
Definition: logger.c:51
#define FOR_MAP_PREPARE(map_, mx_, my_, it_)
Constructs a loop iterating over all objects of a map tile.
Definition: define.h:758
#define FREE_OBJ_DROP_ABOVE_FLOOR
If FREE_OBJ_FREE_INVENTORY is not set, drop inventory just above ground instead on top...
Definition: object.h:534
int check_trigger(object *op, object *cause)
Definition: button.c:523
This is a game-map.
Definition: map.h:325
int should_director_abort(const object *op, const object *victim)
Check if op should abort moving victim because of it&#39;s race or slaying.
Definition: apply.c:68
#define FLAG_WIZPASS
The wizard can go through walls.
Definition: define.h:315
void make_sure_not_seen(const object *op)
The object which is supposed to be visible through walls has just been removed from the map...
Definition: los.c:655
int16_t level
Level of creature or object.
Definition: object.h:351
int8_t facing
Object is oriented/facing that way.
Definition: object.h:335
void fix_object(object *op)
Updates all abilities given by applied objects in the inventory of the given object.
Definition: living.c:1120
void legacy_move_hole(object *op)
Definition: time.c:835
struct obj * more
Pointer to the rest of a large body of objects.
Definition: object.h:295
object * arch_to_object(archetype *at)
Creates and returns a new object which is a copy of the given archetype.
Definition: arch.c:571
#define FLAG_CONTENT_ON_GEN
Definition: define.h:374
void object_update_speed(object *op)
Updates the speed of an object.
Definition: object.c:1129
#define SCRIPT_FIX_NOTHING
Definition: global.h:362
int32_t value
How much money it is worth (or contains)
Definition: object.h:350
object * object_get_owner(object *op)
Returns the object which this object marks as being the owner.
Definition: object.c:559
#define HAS_RANDOM_ITEMS(op)
This return TRUE if object has still randomitems which could be expanded.
Definition: define.h:183
#define FOR_INV_PREPARE(op_, it_)
Constructs a loop iterating over the inventory of an object.
Definition: define.h:705
int cast_spell(object *op, object *caster, int dir, object *spell_ob, char *stringarg)
Main dispatch when someone casts a spell.
Definition: spell_util.c:1471
void object_remove(object *op)
This function removes the object op from the linked list of objects which it is currently tied to...
Definition: object.c:1654
object * map_find_by_type(mapstruct *m, int x, int y, uint8_t type)
Searches for any objects with a matching type variable at the given map and coordinates.
Definition: object.c:2974
int process_object(object *op)
Main object move function.
Definition: time.c:767
int32_t food
How much food in stomach.
Definition: living.h:47
#define FLAG_FREED
Object is in the list of free objects.
Definition: define.h:233
void remove_door(object *op)
Remove non locked doors.
Definition: time.c:37