Crossfire Server, Trunk  1.75.0
time.cpp
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;
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  }
183  if (i == -1)
184  return FALSE;
185 
186  op = object_create_clone(&gen->other_arch->clone);
187  if (rndm(0, 9))
188  generate_artifact(op, gen->map->difficulty);
189  object *ins = object_insert_in_map_at(op, gen->map, gen, 0, nx, ny);
190  /* Object insert in map at can return NULL when failing to place something
191  * because the tile is blocked or because the monster was immediately killed
192  * by a spell effect on the space they were trying to be added to.
193  * Banishment in particular is guilty of causing the latter.
194  *
195  * Regardless, it appears to be intended behavior, but wasn't accounted for here.
196  *
197  * Ensure we actually got op back before continuing to process.
198  */
199  if (ins == NULL)
200  return FALSE;
201  op = ins; // Make sure we look at the object we got back. I *think* the pointer should be the same, but to be safe...
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  code = object_get_value(gen, "generator_code");
211  if (code) {
212  object_set_value(op, "generator_code", code, 1);
213  }
214 
215  return TRUE;
216 }
217 
224 static void generate_monster(object *gen) {
225  int8_t children, max_children;
226  int8_t x, y;
227  const char *code, *value;
228  int did_gen = 0;
229 
230  if (GENERATE_SPEED(gen) && rndm(0, GENERATE_SPEED(gen)-1))
231  return;
232 
233  value = object_get_value(gen, "generator_max_map");
234  if (value) {
235  max_children = (int8_t)strtol(value, NULL, 10);
236  if (max_children < 1)
237  return;
238  code = object_get_value(gen, "generator_code");
239  if (code) {
240  /* Generator has a limit and has created some,
241  * so count how many already exist
242  */
243  children = 0;
244  for (x = 0; x < MAP_WIDTH(gen->map); x++) {
245  for (y = 0; y < MAP_HEIGHT(gen->map); y++) {
246  FOR_MAP_PREPARE(gen->map, x, y, tmp) {
247  value = object_get_value(tmp, "generator_code");
248  if (value && value == code) {
249  children++;
250  }
251  } FOR_MAP_FINISH();
252  }
253  }
254  /* and return without generating if there are already enough */
255  if (children >= max_children+1)
256  return;
257  } else {
258  /* Generator has a limit, but hasn't created anything yet,
259  * so no need to count, just set code and go
260  */
261  value = object_get_value(gen, "generator_name");
262  if (value) {
263  object_set_value(gen, "generator_code", value, 1);
264  } else if (gen->name) {
265  object_set_value(gen, "generator_code", gen->name, 1);
266  } else {
267  object_set_value(gen, "generator_code", "generator", 1);
268  }
269  }
270  } /* If this has a max map generator limit */
271 
273  did_gen = generate_monster_inv(gen);
274  else
275  did_gen = generate_monster_arch(gen);
276 
277  /* See if generator has a generator_limit limit set */
278  if (object_value_set(gen, "generator_limit")) {
279  value = object_get_value(gen, "generator_limit");
280 
281  /* Only do this if we actually made a monster. If the generator
282  * was unable to create a monster (no space for example),
283  * we don't want to prematurely remove the generator.
284  */
285  if (value && did_gen) {
286  int limit = atoi(value), num_generated = 0;
287 
288  value = object_get_value(gen, "generator_generated");
289  if (value)
290  num_generated = atoi(value);
291 
292  if (num_generated++ >= limit) {
294  object_remove(gen);
296  } else {
297  char buf[50];
298 
299  snprintf(buf, sizeof(buf), "%d", num_generated);
300  object_set_value(gen, "generator_generated", buf, 1);
301  }
302  }
303  }
304 }
305 
313 static void remove_force(object *op) {
314  if (--op->duration > 0) {
315  check_spell_expiry(op);
316  return;
317  }
318 
319  switch (op->subtype) {
320  case FORCE_CONFUSION:
321  if (op->env != NULL) {
323  draw_ext_info(NDI_UNIQUE, 0, op->env,
325  "You regain your senses.");
326  }
327  break;
328 
330  /* The force is into the item that was created */
331  if (op->env != NULL && op->inv != NULL) {
332  object *inv = op->inv;
333  object *pl = object_get_player_container(op);
334 
335  object_remove(inv);
336 
337  // FIXME: For whatever reason, leaving an item transformed this way somewhere that it gets saved
338  // propagates the NO_PICK flag from the force down to the item. Clearing that here
339  // fixes the symptom, but not the underlying logic that causes the problem to occur.
340  CLEAR_FLAG(inv, FLAG_NO_PICK);
341 
342  inv->weight = (inv->nrof ? (int32_t)(op->env->weight/inv->nrof) : op->env->weight);
343  if (op->env->env) {
344  object_insert_in_ob(inv, op->env->env);
345  if (pl) {
346  char name[HUGE_BUF];
347 
350  "Your %s recovers its original form.",
351  name);
352  }
353  } else {
354  /* Object on map */
355  object_insert_in_map_at(inv, op->env->map, NULL, 0, op->env->x, op->env->y);
356  }
357  inv = op->env;
358  object_remove(op);
360  object_remove(inv);
361  }
362  return;
363 
364  default:
365  break;
366  }
367 
368  if (op->env != NULL) {
370  change_abil(op->env, op);
371  fix_object(op->env);
372  }
373  object_remove(op);
375 }
376 
383 static void animate_trigger(object *op) {
384  if ((unsigned char)++op->stats.wc >= NUM_ANIMATIONS(op)) {
385  op->stats.wc = 0;
386  check_trigger(op, NULL);
387  } else {
388  SET_ANIMATION(op, op->stats.wc);
390  }
391 }
392 
399 static void move_hole(object *op) { /* 1 = opening, 0 = closing */
400  if (op->value) { /* We're opening */
401  if (--op->stats.wc <= 0) { /* Opened, let's stop */
402  op->stats.wc = 0;
403  op->speed = 0;
405 
406  /* Hard coding this makes sense for holes I suppose */
407  op->move_on = MOVE_WALK;
408  FOR_ABOVE_PREPARE(op, tmp)
409  ob_move_on(op, tmp, tmp);
411  }
412 
413  op->state = op->stats.wc;
414  animate_object(op, 0);
416  return;
417  }
418  /* We're closing */
419  op->move_on = 0;
420 
421  op->stats.wc++;
422  if ((int)op->stats.wc >= NUM_ANIMATIONS(op))
423  op->stats.wc = NUM_ANIMATIONS(op)-1;
424 
425  op->state = op->stats.wc;
426  animate_object(op, 0);
428  if ((unsigned char)op->stats.wc == (NUM_ANIMATIONS(op)-1)) {
429  op->speed = 0;
430  object_update_speed(op); /* closed, let's stop */
431  return;
432  }
433 }
434 
455 object *stop_item(object *op) {
456  if (free_no_drop(op))
457  return NULL;
458 
459  if (op->map == NULL)
460  return op;
461 
462  switch (op->type) {
463  case THROWN_OBJ: {
464  object *payload = op->inv;
465 
466  if (payload == NULL)
467  return NULL;
468  object_remove(payload);
469  object_remove(op);
471  return payload;
472  }
473 
474  case ARROW:
475  if (op->speed >= MIN_ACTIVE_SPEED)
476  op = fix_stopped_arrow(op);
477  return op;
478 
479  default:
480  return op;
481  }
482 }
483 
495 void fix_stopped_item(object *op, mapstruct *map, object *originator) {
496  if (map == NULL)
497  return;
498  if (QUERY_FLAG(op, FLAG_REMOVED))
499  object_insert_in_map(op, map, originator, 0);
500  else if (op->type == ARROW)
501  object_merge(op, NULL); /* only some arrows actually need this */
502 }
503 
512 object *fix_stopped_arrow(object *op) {
513  if (free_no_drop(op))
514  return NULL;
515 
516  if (rndm(0, 99) < op->stats.food) {
517  /* Small chance of breaking */
518  object_remove(op);
520  return NULL;
521  }
522 
523  op->direction = 0;
524  op->move_on = 0;
525  op->move_type = 0;
526  op->speed = 0;
528  op->stats.wc = op->stats.sp;
529  op->stats.dam = op->stats.hp;
530  op->attacktype = op->stats.grace;
531  if (op->slaying != NULL)
533 
534  if (op->skill != NULL)
536 
537  if (op->spellarg != NULL) {
538  op->slaying = add_string(op->spellarg);
539  free(op->spellarg);
540  op->spellarg = NULL;
541  } else
542  op->slaying = NULL;
543 
544  /* Reset these to zero, so that object_can_merge will work properly */
545  op->spellarg = NULL;
546  op->stats.sp = 0;
547  op->stats.hp = 0;
548  op->stats.grace = 0;
549  op->level = 0;
550  animate_object(op, 0);
551  object_clear_owner(op); /* So that stopped arrows will be saved */
553  return op;
554 }
555 
565 int free_no_drop(object *op) {
566  if (!QUERY_FLAG(op, FLAG_NO_DROP)) {
567  return 0;
568  }
569 
570  if (!QUERY_FLAG(op, FLAG_REMOVED)) {
571  object_remove(op);
572  }
573 
575  return 1;
576 }
577 
592 void change_object(object *op) {
593  object *env;
594  int i;
595  int friendly;
596  int unaggressive;
597  object *owner;
598 
599  if (op->other_arch == NULL) {
600  LOG(llevError, "Change object (%s) without other_arch error.\n", op->name);
601  return;
602  }
603 
604  /* In non-living items only change when food value is 0 */
605  if (!QUERY_FLAG(op, FLAG_ALIVE)) {
606  if (op->stats.food-- > 0)
607  return;
608  else
609  op->stats.food = 1; /* so 1 other_arch is made */
610  }
611 
612  env = op->env;
613  object_remove(op);
615  unaggressive = QUERY_FLAG(op, FLAG_UNAGGRESSIVE);
616  owner = object_get_owner(op);
617  for (i = 0; i < op->stats.food; i++) {
618  object *tmp;
619 
620  tmp = arch_to_object(op->other_arch);
621  if (op->type == LAMP)
622  tmp->stats.food = op->stats.food-1;
623  tmp->stats.hp = op->stats.hp;
624  if (friendly) {
625  SET_FLAG(tmp, FLAG_FRIENDLY);
626  add_friendly_object(tmp);
627  tmp->attack_movement = PETMOVE;
628  if (owner != NULL)
629  object_set_owner(tmp, owner);
630  }
631  if (unaggressive)
633  if (env) {
634  tmp->x = env->x,
635  tmp->y = env->y;
636  tmp = object_insert_in_ob(tmp, env);
637  }
638  // If there is more to the object, put in the map,
639  // then initiate the process of setting up multipartdom.
640  else if (tmp->arch->more)
641  {
642  tmp->map = op->map;
643  // Get the best free spot for the object
644  // Using the clone of the arch because I do not think that the actual object is ready yet.
645  if (object_find_multi_free_spot_around(&tmp->arch->clone, op, &tmp->x, &tmp->y) != 0)
646  {
647  LOG(llevInfo, "change_object: Failed to find a spot to put changing multipart object\n");
648  // Put the orignal object back.
650  // Free the failed object
652  // Bail out so we don't break things.
653  return;
654  }
657  }
658  else{
659  // Single-size objects work here.
660  object_insert_to_free_spot_or_free(tmp, op->map, op->x, op->y, 1, SIZEOFFREE1+1, op);
661  }
662  }
663  if (friendly)
666 }
667 
678 void move_firewall(object *op) {
679  object *spell;
680 
681  if (!op->map)
682  return; /* dm has created a firewall in his inventory */
683 
684  spell = op->inv;
685  if (!spell) {
686  LOG(llevError, "firewall '%s' in (%s, %d, %d) has no spell\n", op->name, op->map->path, op->x, op->y);
687  return;
688  }
689 
690  cast_spell(op, op, op->direction ? op->direction : get_random_dir(), spell, NULL);
691 }
692 
693 
707 void move_player_mover(object *op) {
708  int dir = op->stats.sp;
709  int16_t nx, ny;
710  mapstruct *m;
711 
712  if (!op->map) {
713  if (op->env && op->env->map)
714  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);
715  else
716  LOG(llevError, "move_player_mover: mover not in a map at undefinite location!");
717  op->speed = 0;
719  return;
720  }
721 
722  /* Determine direction now for random movers so we do the right thing */
723  if (!dir)
724  dir = get_random_dir();
725 
726  FOR_MAP_PREPARE(op->map, op->x, op->y, victim) {
727  if (QUERY_FLAG(victim, FLAG_ALIVE)
728  && !QUERY_FLAG(victim, FLAG_WIZPASS)
729  && (victim->move_type&op->move_type || !victim->move_type)) {
730  victim = HEAD(victim);
731 
732  if (QUERY_FLAG(op, FLAG_LIFESAVE) && op->stats.hp-- < 0) {
733  object_remove(op);
735  return;
736  }
737  nx = op->x+freearr_x[dir];
738  ny = op->y+freearr_y[dir];
739  m = op->map;
740  if (get_map_flags(m, &m, nx, ny, &nx, &ny)&P_OUT_OF_MAP) {
741  LOG(llevError, "move_player_mover: Trying to push player off the map! map=%s (%d, %d)\n", m->path, op->x, op->y);
742  return;
743  }
744 
745  if (should_director_abort(op, victim))
746  return;
747 
748  FOR_MAP_PREPARE(m, nx, ny, nextmover) {
749  if (nextmover->type == PLAYERMOVER)
750  nextmover->speed_left = -.99;
751  if (QUERY_FLAG(nextmover, FLAG_ALIVE)) {
752  op->speed_left = -1.1; /* wait until the next thing gets out of the way */
753  }
754  } FOR_MAP_FINISH();
755 
756  if (victim->type == PLAYER) {
757  /* only level >= 1 movers move people */
758  if (op->level) {
759  /* Following is a bit of hack. We need to make sure it
760  * is cleared, otherwise the player will get stuck in
761  * place. This can happen if the player used a spell to
762  * get to this space.
763  */
764  victim->contr->fire_on = 0;
765  victim->speed_left = -FABS(victim->speed);
766  move_player(victim, dir);
767  } else
768  return;
769  } else
770  move_object(victim, dir);
771 
772  if (!op->stats.maxsp && op->attacktype)
773  op->stats.maxsp = 2.0;
774 
775  if (op->attacktype) { /* flag to paralyze the player */
776  victim->speed_left = -FABS(op->stats.maxsp*victim->speed/op->speed);
777  /* Not sure why, but for some chars on metalforge, they
778  * would sometimes get -inf speed_left, and from the
779  * description, it could only happen here, so just put
780  * a lower sanity limit. My only guess is that the
781  * mover has 0 speed.
782  */
783  if (victim->speed_left < -5.0)
784  victim->speed_left = -5.0;
785  }
786  }
787  } FOR_MAP_FINISH();
788 }
789 
796 void process_object(object *op) {
797  if (getenv("CF_DEBUG_PROCESS")) {
798  LOG(llevDebug, "processing %s (%d), speed %.3f\n", op->name, op->count, op->speed);
799  }
801  return;
802 
803  if (events_execute_object_event(op, EVENT_TIME, NULL, NULL, NULL, SCRIPT_FIX_NOTHING) != 0)
804  return;
805 
806  if (QUERY_FLAG(op, FLAG_REMOVED)) {
807  return;
808  }
809 
810  if (QUERY_FLAG(op, FLAG_MONSTER))
811  if (monster_move(op) || QUERY_FLAG(op, FLAG_FREED))
812  return;
813 
814  if ((QUERY_FLAG(op, FLAG_ANIMATE) && op->anim_speed == 0)
815  || (op->temp_animation && op->temp_anim_speed == 0)) {
816  op->state++;
817  if (op->type == PLAYER)
818  animate_object(op, op->facing);
819  else
820  animate_object(op, op->direction);
821 
822  if (QUERY_FLAG(op, FLAG_SEE_ANYWHERE))
823  make_sure_seen(op);
824  }
825  if (QUERY_FLAG(op, FLAG_CHANGING) && !op->state) {
826  change_object(op);
827  return;
828  }
830  generate_monster(op);
831 
832  /* If object can be used up, decrement 'food' and eventually remove it.
833  * Well, unless the object has a duration, in which case that should
834  * dictate how long it lasts and not food.
835  * Otherwise, you end up with artifact foods creating forces
836  * that ultimately starve the player to death.
837  */
838  if (QUERY_FLAG(op, FLAG_IS_USED_UP) && (op->duration > 0 || (--op->stats.food) <= 0)) {
839  if (QUERY_FLAG(op, FLAG_APPLIED)) {
840  remove_force(op);
841  } else {
842  if (op->env != NULL && op->env->type == PLAYER) {
843  sstring key;
844  key_value *used_up_message;
845 
846  key = add_string("used_up_message");
847  used_up_message = object_get_key_value(op, key);
848  free_string(key);
849 
850  if (used_up_message != NULL) {
853  "The %s %s.", op->name, used_up_message->value);
854  }
855  }
856 
857  object_remove(op);
858  if (QUERY_FLAG(op, FLAG_SEE_ANYWHERE))
859  make_sure_not_seen(op);
861  }
862  return;
863  }
864  ob_process(op);
865 }
866 
867 void legacy_remove_force(object *op) {
868  remove_force(op);
869 }
870 
871 void legacy_animate_trigger(object *op) {
872  animate_trigger(op);
873 }
874 
875 void legacy_move_hole(object *op) {
876  move_hole(op);
877 }
remove_door
void remove_door(object *op)
Remove non locked doors.
Definition: time.cpp:38
object_value_set
bool object_value_set(const object *op, const char *const key)
Determine if an extra value is set.
Definition: object.cpp:4376
HAS_RANDOM_ITEMS
#define HAS_RANDOM_ITEMS(op)
This return TRUE if object has still randomitems which could be expanded.
Definition: define.h:184
UP_OBJ_FACE
#define UP_OBJ_FACE
Only thing that changed was the face.
Definition: object.h:533
make_sure_not_seen
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.cpp:718
PLAYER
@ PLAYER
Definition: object.h:112
object_get_owner
object * object_get_owner(object *op)
Returns the object which this object marks as being the owner.
Definition: object.cpp:804
free_no_drop
int free_no_drop(object *op)
Check whether the given object is FLAG_NO_DROP.
Definition: time.cpp:565
global.h
object_clear_owner
void object_clear_owner(object *op)
Clears the owner of specified object.
Definition: object.cpp:823
INS_NO_WALK_ON
#define INS_NO_WALK_ON
Don't call check_walk_on against the originator.
Definition: object.h:582
friendly
TIPS on SURVIVING Crossfire is populated with a wealth of different monsters These monsters can have varying immunities and attack types In some of them can be quite a bit smarter than others It will be important for new players to learn the abilities of different monsters and learn just how much it will take to kill them This section discusses how monsters can interact with players Most monsters in the game are out to mindlessly kill and destroy the players These monsters will help boost a player s after he kills them When fighting a large amount of monsters in a single attempt to find a narrower hallway so that you are not being attacked from all sides Charging into a room full of Beholders for instance would not be open the door and fight them one at a time For there are several maps designed for them Find these areas and clear them out All throughout these a player can find signs and books which they can read by stepping onto them and hitting A to apply the book sign These messages will help the player to learn the system One more always keep an eye on your food If your food drops to your character will soon so BE CAREFUL ! NPCs Non Player Character are special monsters which have intelligence Players may be able to interact with these monsters to help solve puzzles and find items of interest To speak with a monster you suspect to be a simply move to an adjacent square to them and push the double ie Enter your and press< Return > You can also use say if you feel like typing a little extra Other NPCs may not speak to but display intelligence with their movement Some monsters can be friendly
Definition: survival-guide.txt:38
FOR_MAP_FINISH
#define FOR_MAP_FINISH()
Finishes FOR_MAP_PREPARE().
Definition: define.h:724
remove_friendly_object
void remove_friendly_object(object *op)
Removes the specified object from the linked list of friendly objects.
Definition: friend.cpp:52
FLAG_CONFUSED
#define FLAG_CONFUSED
Will also be unable to cast spells.
Definition: define.h:311
FORCE_CONFUSION
#define FORCE_CONFUSION
Definition: spells.h:144
llevError
@ llevError
Error, serious thing.
Definition: logger.h:11
FABS
#define FABS(x)
Decstations have trouble with fabs()...
Definition: define.h:22
mapstruct::difficulty
uint16_t difficulty
What level the player should be to play here.
Definition: map.h:333
LOG
void LOG(LogLevel logLevel, const char *format,...)
Logs a message to stderr, or to file.
Definition: logger.cpp:58
SET_FLAG
#define SET_FLAG(xyz, p)
Definition: define.h:224
archetype::more
archetype * more
Next part of a linked object.
Definition: object.h:486
FLAG_GENERATOR
#define FLAG_GENERATOR
Will generate type ob->stats.food.
Definition: define.h:248
object::inv
object * inv
Pointer to the first object in the inventory.
Definition: object.h:298
SIZEOFFREE1
#define SIZEOFFREE1
Definition: define.h:153
QUERY_FLAG
#define QUERY_FLAG(xyz, p)
Definition: define.h:226
get_random_dir
int get_random_dir(void)
Returns a random direction (1..8).
Definition: utils.cpp:400
FLAG_CONTENT_ON_GEN
#define FLAG_CONTENT_ON_GEN
Definition: define.h:365
object_merge
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.cpp:2051
FALSE
#define FALSE
Definition: compat.h:14
object::arch
struct archetype * arch
Pointer to archetype.
Definition: object.h:424
cast_spell
int cast_spell(object *op, object *caster, int dir, object *spell_ob, char *stringarg)
Main dispatch when someone casts a spell.
Definition: spell_util.cpp:1424
object::attack_movement
uint16_t attack_movement
What kind of attack movement.
Definition: object.h:401
object::speed
float speed
Frequency of object 'moves' relative to server tick rate.
Definition: object.h:337
object_insert_to_free_spot_or_free
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.cpp:4791
object::x
int16_t x
Definition: object.h:335
object::speed_left
float speed_left
How much speed is left to spend this round.
Definition: object.h:338
object::map
struct mapstruct * map
Pointer to the map in which this object is present.
Definition: object.h:305
move_firewall
void move_firewall(object *op)
Move for FIREWALL.
Definition: time.cpp:678
key_value
Each object (this also means archetypes!) could have a few of these "dangling" from it; this could al...
Definition: object.h:42
object_set_owner
void object_set_owner(object *op, object *owner)
Sets the owner and sets the skill and exp pointers to owner's current skill and experience objects.
Definition: object.cpp:840
object_handle_death_animation
void object_handle_death_animation(object *op)
Definition: object.cpp:5410
MSG_TYPE_ATTRIBUTE
#define MSG_TYPE_ATTRIBUTE
Changes to attributes (stats, resistances, etc)
Definition: newclient.h:408
SET_ANIMATION
#define SET_ANIMATION(ob, newanim)
Definition: global.h:164
draw_ext_info_format
void draw_ext_info_format(int flags, int pri, const object *pl, uint8_t type, uint8_t subtype, const char *format,...) PRINTF_ARGS(6
move_player
int move_player(object *op, int dir)
Move player in the given direction.
Definition: player.cpp:2965
object::direction
int8_t direction
Means the object is moving that way.
Definition: object.h:344
object::count
tag_t count
Unique object number for this object.
Definition: object.h:307
fix_object
void fix_object(object *op)
Updates all abilities given by applied objects in the inventory of the given object.
Definition: living.cpp:1132
object_find_multi_free_spot_within_radius
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.cpp:3412
move_hole
static void move_hole(object *op)
Move a HOLE.
Definition: time.cpp:399
FOR_ABOVE_PREPARE
#define FOR_ABOVE_PREPARE(op_, it_)
Constructs a loop iterating over all objects above an object.
Definition: define.h:681
rndm
int rndm(int min, int max)
Returns a number between min and max.
Definition: utils.cpp:162
fix_stopped_item
void fix_stopped_item(object *op, mapstruct *map, object *originator)
Put stopped item where stop_item() had found it.
Definition: time.cpp:495
generate_monster
static void generate_monster(object *gen)
Main generator function.
Definition: time.cpp:224
mapstruct::path
char path[HUGE_BUF]
Filename of the map.
Definition: map.h:355
object_get_value
const char * object_get_value(const object *op, const char *const key)
Get an extra value by key.
Definition: object.cpp:4346
FLAG_APPLIED
#define FLAG_APPLIED
Object is ready for use by living.
Definition: define.h:235
object::level
int16_t level
Level of creature or object.
Definition: object.h:361
events_execute_object_event
int events_execute_object_event(object *op, int eventcode, object *activator, object *third, const char *message, int fix)
Execute an event on the specified object.
Definition: events.cpp:308
generate_monster_arch
static int generate_monster_arch(object *gen)
Generate a monster from the other_arch field.
Definition: time.cpp:164
stop_item
object * stop_item(object *op)
An item (ARROW or such) stops moving.
Definition: time.cpp:455
buf
StringBuffer * buf
Definition: readable.cpp:1565
object_insert_in_ob
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.cpp:2857
HUGE_BUF
#define HUGE_BUF
Used for messages - some can be quite long.
Definition: define.h:37
ob_move_on
method_ret ob_move_on(object *op, object *victim, object *originator)
Makes an object move on top of another one.
Definition: ob_methods.cpp:111
FLAG_NO_PICK
#define FLAG_NO_PICK
Object can't be picked up.
Definition: define.h:239
name
Plugin animator file specs[Config] name
Definition: animfiles.txt:4
draw_ext_info
vs only yadda is in because all tags get reset on the next draw_ext_info In the second since it is all in one draw_ext_info
Definition: media-tags.txt:61
FLAG_ALIVE
#define FLAG_ALIVE
Object can fight (or be fought)
Definition: define.h:230
INS_ABOVE_FLOOR_ONLY
#define INS_ABOVE_FLOOR_ONLY
Put object immediatly above the floor.
Definition: object.h:581
key_value::value
const char * value
Key's value.
Definition: object.h:44
FLAG_IS_A_TEMPLATE
#define FLAG_IS_A_TEMPLATE
Object has no ingame life until instantiated.
Definition: define.h:366
object::y
int16_t y
Position in the map for this object.
Definition: object.h:335
m
static event_registration m
Definition: citylife.cpp:422
object_free_drop_inventory
void object_free_drop_inventory(object *ob)
Frees everything allocated by an object, removes it from the list of used objects,...
Definition: object.cpp:1560
object_update
void object_update(object *op, int action)
object_update() updates the array which represents the map.
Definition: object.cpp:1434
object::temp_anim_speed
uint8_t temp_anim_speed
Ticks between temporary animation-frames.
Definition: object.h:432
object_get_key_value
key_value * object_get_key_value(const object *ob, const char *key)
Search for a field by key.
Definition: object.cpp:4321
object::subtype
uint8_t subtype
Subtype of object.
Definition: object.h:349
move_player_mover
void move_player_mover(object *op)
This function takes a PLAYERMOVER as an argument, and performs the function of a player mover,...
Definition: time.cpp:707
freearr_y
short freearr_y[SIZEOFFREE]
Y offset when searching around a spot.
Definition: object.cpp:305
object::anim_speed
uint8_t anim_speed
Ticks between animation-frames.
Definition: object.h:429
map_find_by_type
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.cpp:3145
MOVE_WALK
#define MOVE_WALK
Object walks.
Definition: define.h:392
FOR_ABOVE_FINISH
#define FOR_ABOVE_FINISH()
Finishes FOR_ABOVE_PREPARE().
Definition: define.h:688
archetype::clone
object clone
An object from which to do object_copy()
Definition: object.h:487
add_string
sstring add_string(const char *str)
This will add 'str' to the hash table.
Definition: shstr.cpp:124
HEAD
#define HEAD(op)
Returns the head part of an object.
Definition: object.h:607
object::move_type
MoveType move_type
Type of movement this object uses.
Definition: object.h:436
query_short_name
void query_short_name(const object *op, char *buf, size_t size)
query_short_name(object) is similar to query_name(), but doesn't contain any information about object...
Definition: item.cpp:513
FLAG_FREED
#define FLAG_FREED
Object is in the list of free objects.
Definition: define.h:233
LOCKED_DOOR
@ LOCKED_DOOR
Definition: object.h:128
MSG_TYPE_ITEM
#define MSG_TYPE_ITEM
Item related information.
Definition: newclient.h:415
PLAYERMOVER
@ PLAYERMOVER
Definition: object.h:145
should_director_abort
int should_director_abort(const object *op, const object *victim)
Check if op should abort moving victim because of it's race or slaying.
Definition: apply.cpp:68
object::value
int32_t value
How much money it is worth (or contains)
Definition: object.h:360
object_update_speed
void object_update_speed(object *op)
Updates the speed of an object.
Definition: object.cpp:1349
legacy_remove_force
void legacy_remove_force(object *op)
Definition: time.cpp:867
legacy_animate_trigger
void legacy_animate_trigger(object *op)
Definition: time.cpp:871
object::type
uint8_t type
PLAYER, BULLET, etc.
Definition: object.h:348
INS_NO_MERGE
#define INS_NO_MERGE
Don't try to merge with other items.
Definition: object.h:580
living::dam
int16_t dam
How much damage this object does when hitting.
Definition: living.h:46
FORCE_TRANSFORMED_ITEM
#define FORCE_TRANSFORMED_ITEM
Definition: spells.h:146
spell
with a maximum of six This is not so if you are wearing plate you receive no benefit Armour is additive with all the supplementry forms of which means that it lasts until the next semi permanent spell effect is cast upon the character spell
Definition: tome-of-magic.txt:44
FLAG_WIZPASS
#define FLAG_WIZPASS
The wizard can go through walls.
Definition: define.h:314
object_free
void object_free(object *ob, int flags)
Frees everything allocated by an object, removes it from the list of used objects,...
Definition: object.cpp:1592
LAMP
@ LAMP
Lamp.
Definition: object.h:206
FOR_INV_FINISH
#define FOR_INV_FINISH()
Finishes FOR_INV_PREPARE().
Definition: define.h:671
object::move_on
MoveType move_on
Move types affected moving on to this space.
Definition: object.h:439
living::food
int32_t food
How much food in stomach.
Definition: living.h:48
FLAG_UNAGGRESSIVE
#define FLAG_UNAGGRESSIVE
Monster doesn't attack players.
Definition: define.h:272
process_object
void process_object(object *op)
Main object move function.
Definition: time.cpp:796
legacy_move_hole
void legacy_move_hole(object *op)
Definition: time.cpp:875
object_find_multi_free_spot_around
int object_find_multi_free_spot_around(const object *ob, const object *gen, int16_t *hx, int16_t *hy)
Sets hx and hy to the coords to insert a possibly multi-tile ob at, around gen.
Definition: object.cpp:3296
sproto.h
ARROW
@ ARROW
Definition: object.h:122
FLAG_NO_DROP
#define FLAG_NO_DROP
Object can't be dropped.
Definition: define.h:288
living::sp
int16_t sp
Spell points.
Definition: living.h:42
object::facing
int8_t facing
Object is oriented/facing that way.
Definition: object.h:345
FREE_OBJ_DROP_ABOVE_FLOOR
#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:546
NDI_BLACK
#define NDI_BLACK
Definition: newclient.h:245
object_insert_in_map_at
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.cpp:2100
object::other_arch
struct archetype * other_arch
Pointer used for various things - mostly used for what this objects turns into or what this object cr...
Definition: object.h:425
object_create_clone
object * object_create_clone(object *asrc)
Create clone from object to another.
Definition: object.cpp:3909
FLAG_MONSTER
#define FLAG_MONSTER
Will attack players.
Definition: define.h:245
MAP_WIDTH
#define MAP_WIDTH(m)
Map width.
Definition: map.h:73
P_OUT_OF_MAP
#define P_OUT_OF_MAP
This space is outside the map.
Definition: map.h:249
env
static std::shared_ptr< inja::Environment > env
Rendering environment.
Definition: mapper.cpp:2222
object_insert_in_map
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.cpp:2361
object::weight
int32_t weight
Attributes of the object.
Definition: object.h:375
free_string
void free_string(sstring str)
This will reduce the refcount, and if it has reached 0, str will be freed.
Definition: shstr.cpp:280
monster_check_apply_all
void monster_check_apply_all(object *monster)
Calls monster_check_apply() for all inventory objects.
Definition: monster.cpp:1999
living::wc
int8_t wc
Weapon Class, lower WC increases probability of hitting.
Definition: living.h:37
move_object
int move_object(object *op, int dir)
Try to move op in the direction "dir".
Definition: move.cpp:39
FREE_AND_CLEAR_STR
#define FREE_AND_CLEAR_STR(xyz)
Release the shared string, and set it to NULL.
Definition: global.h:200
animate_trigger
static void animate_trigger(object *op)
Animate a TRIGGER.
Definition: time.cpp:383
FOR_MAP_PREPARE
#define FOR_MAP_PREPARE(map_, mx_, my_, it_)
Constructs a loop iterating over all objects of a map tile.
Definition: define.h:717
change_abil
int change_abil(object *op, object *tmp)
Permanently alters an object's stats/flags based on another object.
Definition: living.cpp:394
FLAG_REMOVED
#define FLAG_REMOVED
Object is not in any map or invenory.
Definition: define.h:232
check_trigger
int check_trigger(object *op, object *cause)
Definition: button.cpp:518
fix_stopped_arrow
object * fix_stopped_arrow(object *op)
An ARROW stops moving.
Definition: time.cpp:512
llevInfo
@ llevInfo
Information.
Definition: logger.h:12
NDI_UNIQUE
#define NDI_UNIQUE
Print immediately, don't buffer.
Definition: newclient.h:265
object::slaying
sstring slaying
Which race to do double damage to.
Definition: object.h:327
FLAG_FRIENDLY
#define FLAG_FRIENDLY
Will help players.
Definition: define.h:246
spells.h
change_object
void change_object(object *op)
Replaces op with its other_arch if it has reached its end of life.
Definition: time.cpp:592
object::name
sstring name
The name of the object, obviously...
Definition: object.h:319
ob_process
method_ret ob_process(object *op)
Processes an object, giving it the opportunity to move or react.
Definition: ob_methods.cpp:67
SCRIPT_FIX_NOTHING
#define SCRIPT_FIX_NOTHING
Definition: global.h:388
add_friendly_object
void add_friendly_object(object *op)
Add a new friendly object to the list of friendly objects.
Definition: friend.cpp:32
get_map_flags
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.cpp:300
MSG_TYPE_ITEM_REMOVE
#define MSG_TYPE_ITEM_REMOVE
Item removed from inv.
Definition: newclient.h:645
living::maxsp
int16_t maxsp
Max spell points.
Definition: living.h:43
mapstruct
This is a game-map.
Definition: map.h:315
object::env
object * env
Pointer to the object which is the environment.
Definition: object.h:301
sstring
const typedef char * sstring
Definition: sstring.h:2
generate_monster_inv
static int generate_monster_inv(object *gen)
Will generate a monster according to parameters of generator.
Definition: time.cpp:97
remove_locked_door
void remove_locked_door(object *op)
Same as remove_door() but for locked doors.
Definition: time.cpp:64
object::skill
sstring skill
Name of the skill this object uses/grants.
Definition: object.h:329
animate_object
void animate_object(object *op, int dir)
Updates the face-variable of an object.
Definition: anim.cpp:44
EVENT_TIME
#define EVENT_TIME
Triggered each time the object can react/move.
Definition: events.h:32
GENERATE_SPEED
#define GENERATE_SPEED(xyz)
Definition: define.h:431
remove_force
static void remove_force(object *op)
Move for FORCE objects.
Definition: time.cpp:313
object_unset_flag_inv
void object_unset_flag_inv(object *op, int flag)
Desactivate recursively a flag on an object inventory.
Definition: object.cpp:3256
CLEAR_FLAG
#define CLEAR_FLAG(xyz, p)
Definition: define.h:225
MAP_HEIGHT
#define MAP_HEIGHT(m)
Map height.
Definition: map.h:75
NUM_ANIMATIONS
#define NUM_ANIMATIONS(ob)
Definition: global.h:173
object::duration
int16_t duration
Number of moves (see 'speed') spell lasts.
Definition: object.h:415
check_spell_expiry
void check_spell_expiry(object *spell)
Checks if player should be warned of soon expiring spell.
Definition: spell_util.cpp:2006
arch_to_object
object * arch_to_object(archetype *at)
Creates and returns a new object which is a copy of the given archetype.
Definition: arch.cpp:227
MIN_ACTIVE_SPEED
#define MIN_ACTIVE_SPEED
Cut off point of when an object is put on the active list or not.
Definition: define.h:633
FLAG_IS_USED_UP
#define FLAG_IS_USED_UP
When (–food<0) the object will exit.
Definition: define.h:260
FLAG_ANIMATE
#define FLAG_ANIMATE
The object looks at archetype for faces.
Definition: define.h:242
MSG_TYPE_ATTRIBUTE_BAD_EFFECT_END
#define MSG_TYPE_ATTRIBUTE_BAD_EFFECT_END
End of a bad effect.
Definition: newclient.h:570
object_fix_multipart
void object_fix_multipart(object *tmp)
Ensures specified object has its more parts correctly inserted in map.
Definition: object.cpp:4685
object::randomitems
struct treasurelist * randomitems
Items to be generated.
Definition: object.h:395
FLAG_SEE_ANYWHERE
#define FLAG_SEE_ANYWHERE
The object will be visible behind walls.
Definition: define.h:318
monster_move
int monster_move(object *op)
Main monster processing routine.
Definition: monster.cpp:854
object_remove
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.cpp:1833
DOOR
@ DOOR
Definition: object.h:131
MSG_TYPE_ITEM_CHANGE
#define MSG_TYPE_ITEM_CHANGE
Item has changed in some way.
Definition: newclient.h:647
object::spellarg
char * spellarg
Optional argument when casting obj::spell.
Definition: object.h:421
FREE_OBJ_FREE_INVENTORY
#define FREE_OBJ_FREE_INVENTORY
Free inventory objects; if not set, drop inventory.
Definition: object.h:544
code
Crossfire Architecture the general intention is to enhance the enjoyability and playability of CF In this code
Definition: arch-handbook.txt:14
object::state
uint8_t state
How the object was last drawn (animation)
Definition: object.h:359
object::nrof
uint32_t nrof
Number of objects.
Definition: object.h:342
PETMOVE
#define PETMOVE
If the upper four bits of attack_movement are set to this number, the monster follows a player until ...
Definition: define.h:495
living::grace
int16_t grace
Grace.
Definition: living.h:44
object::stats
living stats
Str, Con, Dex, etc.
Definition: object.h:378
object_set_value
int object_set_value(object *op, const char *key, const char *value, int add_key)
Updates the key in op to value.
Definition: object.cpp:4499
freearr_x
short freearr_x[SIZEOFFREE]
X offset when searching around a spot.
Definition: object.cpp:299
TRUE
#define TRUE
Definition: compat.h:11
FLAG_CHANGING
#define FLAG_CHANGING
Changes to other_arch when anim is done.
Definition: define.h:263
object::attacktype
uint32_t attacktype
Bitmask of attacks this object does.
Definition: object.h:352
object_get_player_container
object * object_get_player_container(object *op)
Finds the player carrying an object.
Definition: object.cpp:607
object::temp_animation
const Animations * temp_animation
A temporary animation.
Definition: object.h:431
generate_artifact
void generate_artifact(object *op, int difficulty)
Decides randomly which artifact the object should be turned into.
Definition: artifact.cpp:177
THROWN_OBJ
@ THROWN_OBJ
Definition: object.h:151
FOR_INV_PREPARE
#define FOR_INV_PREPARE(op_, it_)
Constructs a loop iterating over the inventory of an object.
Definition: define.h:664
living::hp
int16_t hp
Hit Points.
Definition: living.h:40
create_treasure
void create_treasure(treasurelist *t, object *op, int flag, int difficulty, int tries)
This calls the appropriate treasure creation function.
Definition: treasure.cpp:263
object.h
make_sure_seen
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.cpp:695
llevDebug
@ llevDebug
Only for debugging purposes.
Definition: logger.h:13
FLAG_LIFESAVE
#define FLAG_LIFESAVE
Saves a players' life once, then destr.
Definition: define.h:305