Crossfire Server, Trunk  1.75.0
apply.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 
19 #include "global.h"
20 
21 /* need math lib for double-precision and pow() in dragon_eat_flesh() */
22 #include <math.h>
23 #include <stdlib.h>
24 #include <string.h>
25 
26 #include "living.h"
27 #include "skills.h"
28 #include "sounds.h"
29 #include "spells.h"
30 #include "sproto.h"
31 #include "tod.h"
32 
33 static int apply_check_apply_restrictions(object *who, object *op, int aflags);
34 static int apply_check_personalized_blessings(object *who, const object *op);
35 static int apply_check_item_power(const object *who, const object *op, int aflags);
36 static int apply_check_owner(const object *who, const object *op, int aflags);
37 static void apply_update_ranged_skill(const object *who, object *op, int aflags);
38 
54 int transport_can_hold(const object *transport, const object *op, int nrof) {
55  return op->weight*nrof+transport->carrying <= transport->weight_limit;
56 }
57 
68 int should_director_abort(const object *op, const object *victim) {
69  int arch_flag, name_flag, race_flag;
70 
71  /* Never move doors, it messes things. */
72  if (victim->type == DOOR)
73  return 1;
74 
75  /* Get flags to determine what of arch, name, and race should be
76  * checked. This is stored in subtype, and is a bitmask, the LSB
77  * is the arch flag, the next is the name flag, and the last is
78  * the race flag. Also note, if subtype is set to zero, that also
79  * goes to defaults of all affecting it. Examples:
80  * subtype 1: only arch
81  * subtype 3: arch or name
82  * subtype 5: arch or race
83  * subtype 7: all three
84  */
85  if (op->subtype) {
86  arch_flag = op->subtype&1;
87  name_flag = op->subtype&2;
88  race_flag = op->subtype&4;
89  } else {
90  arch_flag = 1;
91  name_flag = 1;
92  race_flag = 1;
93  }
94  /* If the director has race set, only affect objects with a arch,
95  * name or race that matches.
96  */
97  if (op->race
98  && (!(victim->arch && arch_flag && victim->arch->name) || strcmp(op->race, victim->arch->name))
99  && (!(victim->name && name_flag) || strcmp(op->race, victim->name))
100  && (!(victim->race && race_flag) || strcmp(op->race, victim->race)))
101  return 1;
102 
103  /* If the director has slaying set, only affect objects where none
104  * of arch, name, or race match.
105  */
106  if (op->slaying
107  && ((victim->arch && arch_flag && victim->arch->name && !strcmp(op->slaying, victim->arch->name))
108  || (victim->name && name_flag && !strcmp(op->slaying, victim->name))
109  || (victim->race && race_flag && !strcmp(op->slaying, victim->race))))
110  return 1;
111 
112  return 0;
113 }
114 
122 void apply_handle_yield(object *tmp) {
123  const char *yield;
124 
125  yield = object_get_value(tmp, "on_use_yield");
126  if (yield != NULL) {
127  object *drop = create_archetype(yield);
128  if (tmp->env)
129  drop = object_insert_in_ob(drop, tmp->env);
130  else
131  object_insert_in_map_at(drop, tmp->map, tmp, INS_BELOW_ORIGINATOR, tmp->x, tmp->y);
132  }
133 }
134 
146 void do_learn_spell(object *op, object *spell, int special_prayer) {
147  object *tmp;
148 
149  if (op->type != PLAYER) {
150  LOG(llevError, "BUG: do_learn_spell(): not a player\n");
151  return;
152  }
153 
154  /* Upgrade special prayers to normal prayers */
155  tmp = check_spell_known(op, spell->name);
156  if (tmp != NULL) {
157  if (special_prayer && !QUERY_FLAG(tmp, FLAG_STARTEQUIP)) {
158  LOG(llevError, "BUG: do_learn_spell(): spell already known, but not marked as startequip\n");
159  return;
160  }
161  return;
162  }
163 
165  tmp = object_new();
166  object_copy(spell, tmp);
167  object_insert_in_ob(tmp, op);
168 
169  if (special_prayer)
171 
173  "Type 'bind cast %s to store the spell in a key.",
174  spell->name);
175 
176  esrv_add_spells(op->contr, tmp);
177 }
178 
187 void do_forget_spell(object *op, const char *spell) {
188  object *spob;
189 
190  if (op->type != PLAYER) {
191  LOG(llevError, "BUG: do_forget_spell(): not a player\n");
192  return;
193  }
194  spob = check_spell_known(op, spell);
195  if (spob == NULL) {
196  LOG(llevError, "BUG: do_forget_spell(): spell not known\n");
197  return;
198  }
199 
201  "You lose knowledge of %s.",
202  spell);
203  player_unready_range_ob(op->contr, spob);
204  esrv_remove_spell(op->contr, spob);
205  object_remove(spob);
206  object_free(spob, 0);
207 }
208 
219 static int apply_check_race_restrictions(object *who, object *item) {
220  char buf[MAX_BUF];
221  sstring restriction;
222 
223  if (who->type != PLAYER || QUERY_FLAG(who, FLAG_WIZ))
224  return 1;
225 
226  restriction = object_get_value(item, "race_restriction");
227  if (!restriction)
228  return 1;
229 
230  snprintf(buf, sizeof(buf), ":%s:", who->race);
231  buf[sizeof(buf)-1] = '\0';
232 
233  if (strstr(restriction, buf) != NULL)
234  return 1;
235 
236  query_name(item, buf, sizeof(buf));
237  draw_ext_info_format(NDI_UNIQUE, 0, who, MSG_TYPE_APPLY, MSG_TYPE_APPLY_PROHIBITION, "Somehow you can't seem to use the %s.", buf);
238 
239  return 0;
240 }
241 
259 int apply_manual(object *op, object *tmp, int aflag) {
260  tmp = HEAD(tmp);
261 
262  if (QUERY_FLAG(tmp, FLAG_UNPAID) && !QUERY_FLAG(tmp, FLAG_APPLIED)) {
263  if (op->type == PLAYER) {
265  "You should pay for it first.");
266  return METHOD_SILENT_ERROR;
267  }
268  return 0; /* monsters just skip unpaid items */
269  }
270 
271  if (!apply_check_race_restrictions(op, tmp))
272  return METHOD_SILENT_ERROR;
273 
274  if (op->contr)
275  play_sound_player_only(op->contr, SOUND_TYPE_ITEM, tmp, 0, "apply");
276 
277  return ob_apply(tmp, op, aflag);
278 }
279 
299 int apply_by_living(object *pl, object *op, int aflag, int quiet) {
300  int tmp;
301 
302  if (op->env == NULL && (pl->move_type&MOVE_FLYING)) {
303  /* player is flying and applying object not in inventory */
304  if (!QUERY_FLAG(pl, FLAG_WIZ) && !(op->move_type&MOVE_FLYING)) {
306  "But you are floating high above the ground!");
307  return 0;
308  }
309  }
310 
311  /* Check for PLAYER to avoid a DM to disappear in a puff of smoke if
312  * applied.
313  */
314  if (op->type != PLAYER
315  && QUERY_FLAG(op, FLAG_WAS_WIZ)
316  && !QUERY_FLAG(pl, FLAG_WAS_WIZ)) {
317  play_sound_map(SOUND_TYPE_ITEM, op, 0, "evaporate");
319  "The object disappears in a puff of smoke!");
321  "It must have been an illusion.");
322  object_remove(op);
323  object_free(op, 0);
324  return 1;
325  }
326 
327  tmp = apply_manual(pl, op, aflag);
328  if (!quiet) {
329  if (tmp == METHOD_UNHANDLED) {
330  char name[MAX_BUF];
331 
332  query_name(op, name, MAX_BUF);
334  "I don't know how to apply the %s.",
335  name);
336  } else if (tmp == METHOD_ERROR)
338  "You must get it first!\n");
339  else if (tmp == METHOD_SILENT_ERROR)
340  return tmp;
341  }
342  if (tmp == METHOD_OK) {
343  if (op->anim_suffix != NULL)
345  }
346  return tmp;
347 }
348 
357 void apply_by_living_below(object *pl) {
358  object *tmp;
359  int floors;
360 
361  if (pl->contr->transport && pl->contr->transport->type == TRANSPORT) {
362  ob_apply(pl->contr->transport, pl, 0);
363  return;
364  }
365 
366  /* If using a container, set the starting item to be the top
367  * item in the container. Otherwise, use the map.
368  */
369  tmp = pl->container != NULL ? pl->container->inv : pl->below;
370 
371  /* This is perhaps more complicated. However, I want to make sure that
372  * we don't use a corrupt pointer for the next object, so we get the
373  * next object in the stack before applying. This is can only be a
374  * problem if apply_by_living() has a bug in that it uses the object but
375  * does not return a proper value.
376  */
377  floors = 0;
379  if (QUERY_FLAG(tmp, FLAG_IS_FLOOR))
380  floors++;
381  else if (floors > 0)
382  return; /* process only floor objects after first floor object */
383 
384  /* If it is visible, player can apply it. If it is applied by
385  * person moving on it, also activate. Added code to make it
386  * so that at least one of players movement types be that which
387  * the item needs.
388  */
389  if (!tmp->invisible || (tmp->move_on&pl->move_type)) {
390  if (apply_by_living(pl, tmp, 0, 1) == METHOD_OK)
391  return;
392  }
393  if (floors >= 2)
394  return; /* process at most two floor objects */
396 }
397 
413 static int unapply_special(object *who, object *op, int aflags) {
414  char name[MAX_BUF];
415 
416  if (op->type != LAMP)
418  query_name(op, name, MAX_BUF);
419  switch (op->type) {
420  case WEAPON:
421  if (!(aflags&AP_NOPRINT))
423  "You unwield %s.",
424  name);
425  (void)change_abil(who, op);
427  who->current_weapon = NULL;
428  clear_skill(who);
429  break;
430 
431  case SKILL: /* allows objects to impart skills */
432  case SKILL_TOOL:
433  if (op != who->chosen_skill)
434  LOG(llevError, "BUG: unapply_special(): applied skill is not a chosen skill\n");
435  if (who->type == PLAYER) {
436  if (who->contr->shoottype == range_skill)
437  who->contr->shoottype = range_none;
438  if (!op->invisible) {
439  if (!(aflags&AP_NOPRINT))
441  "You stop using the %s.",
442  name);
443  } else {
444  if (!(aflags&AP_NOPRINT))
446  "You can no longer use the skill: %s.",
447  op->skill);
448  }
449  }
450  (void)change_abil(who, op);
451  who->chosen_skill = NULL;
453  break;
454 
455  case ARMOUR:
456  case HELMET:
457  case SHIELD:
458  case RING:
459  case BOOTS:
460  case GLOVES:
461  case AMULET:
462  case GIRDLE:
463  case BRACERS:
464  case CLOAK:
465  if (!(aflags&AP_NOPRINT))
467  "You unwear %s.",
468  name);
469  (void)change_abil(who, op);
470  break;
471 
472  case BOW:
473  case WAND:
474  case ROD:
475  clear_skill(who);
476  if (!(aflags&AP_NOPRINT))
478  "You unready %s.",
479  name);
480  if (who->type == PLAYER)
481  who->contr->shoottype = range_none;
482  else if (op->type == BOW)
484  else
486  break;
487 
488  case BUILDER:
489  if (!(aflags&AP_NOPRINT))
491  "You unready %s.",
492  name);
493  who->contr->shoottype = range_none;
494  who->contr->ranges[range_builder] = NULL;
495  break;
496 
497  default:
498  if (!(aflags&AP_NOPRINT))
500  "You unapply %s.",
501  name);
502  break;
503  }
504 
505  fix_object(who);
506 
507  if (!(aflags&AP_NO_MERGE)) {
508  object *tmp;
509 
510  tmp = object_merge(op, NULL);
511  if (who->type == PLAYER) {
512  if (tmp) { /* it was merged */
513  op = tmp;
514  }
515  esrv_update_item(UPD_FLAGS, who, op);
516  }
517  }
518  return 0;
519 }
520 
540 static object *get_item_from_body_location(object *start, int loc) {
541  object *tmp;
542 
543  if (!start)
544  return NULL;
545 
546  tmp = start;
548  if (QUERY_FLAG(tmp, FLAG_APPLIED)
549  && tmp->body_info[loc]
550  && (!tmp->invisible || tmp->type == SKILL))
551  return tmp;
553  return NULL;
554 }
555 
577 static int unapply_for_ob(object *who, object *op, int aflags) {
578  int i;
579  object *tmp = NULL, *last;
580  char name[MAX_BUF];
581 
582  /* If we are applying a shield or weapon, unapply any equipped shield
583  * or weapons first - only allowed to use one weapon/shield at a time.
584  */
585  if (op->type == WEAPON || op->type == SHIELD) {
586  FOR_INV_PREPARE(who, tmp) {
587  if (QUERY_FLAG(tmp, FLAG_APPLIED) && tmp->type == op->type) {
588  if (!(aflags&AP_IGNORE_CURSE)
589  && !(aflags&AP_PRINT)
590  && (QUERY_FLAG(tmp, FLAG_CURSED) || QUERY_FLAG(tmp, FLAG_DAMNED))) {
591  /* In this case, we want to try and remove a
592  * cursed item. While we know it won't work, we
593  * want unapply_special to at least generate the
594  * message.
595  */
596  if (!(aflags&AP_NOPRINT)) {
597  query_name(tmp, name, MAX_BUF);
599  "No matter how hard you try, you just can't remove %s.",
600  name);
601  }
602  return 1;
603  }
604 
605  if (aflags&AP_PRINT) {
606  query_name(tmp, name, MAX_BUF);
608  name);
609  } else
610  unapply_special(who, tmp, aflags);
611  }
612  } FOR_INV_FINISH();
613  }
614 
615  for (i = 0; i < NUM_BODY_LOCATIONS; i++) {
616  /* this used up a slot that we need to free */
617  if (op->body_info[i]) {
618  last = who->inv;
619 
620  /* We do a while loop - may need to remove several items
621  * in order to free up enough slots.
622  */
623  while (who->body_used[i]+op->body_info[i] < 0) {
624  tmp = get_item_from_body_location(last, i);
625  if (!tmp)
626  return 1;
627 
628  /* If just printing, we don't care about cursed status */
629  if ((aflags&AP_IGNORE_CURSE)
630  || (aflags&AP_PRINT)
631  || (!(QUERY_FLAG(tmp, FLAG_CURSED) || QUERY_FLAG(tmp, FLAG_DAMNED)))) {
632  if (aflags&AP_PRINT) {
633  query_name(tmp, name, MAX_BUF);
635  name);
636  } else
637  unapply_special(who, tmp, aflags);
638  } else {
639  /* Cursed item that we can't unequip - tell the player.
640  * Note this could be annoying if this is just one of a
641  * few, so it may not be critical (eg, putting on a
642  * ring and you have one cursed ring.)
643  */
644  if (!(aflags&AP_NOPRINT)) {
645  query_name(tmp, name, MAX_BUF);
647  "The %s just won't come off",
648  name);
649  }
650  }
651  last = tmp->below;
652  }
653  /* if we got here, this slot is freed up - otherwise, if it
654  * wasn't freed up, the return in the !tmp would have
655  * kicked in.
656  */
657  } /* if op is using this body location */
658  } /* for body locations */
659  return 0;
660 }
661 
678 int apply_can_apply_object(const object *who, const object *op) {
679  int i, retval = 0;
680  object *tmp = NULL, *ws = NULL;
681 
682  /* Players have 2 'arm's, so they could in theory equip 2 shields or
683  * 2 weapons, but we don't want to let them do that. So if they are
684  * trying to equip a weapon or shield, see if they already have one
685  * in place and store that way.
686  */
687  if (op->type == WEAPON || op->type == SHIELD) {
688  tmp = object_find_by_type_applied(who, op->type);
689  if (tmp != NULL) {
690  retval = CAN_APPLY_UNAPPLY;
691  ws = tmp;
692  }
693  }
694 
695  for (i = 0; i < NUM_BODY_LOCATIONS; i++) {
696  if (op->body_info[i]) {
697  /* Item uses more slots than we have */
698  if (FABS(op->body_info[i]) > who->body_info[i]) {
699  /* Could return now for efficiently - rest of info
700  * below isn't really needed.
701  */
702  retval |= CAN_APPLY_NEVER;
703  } else if (who->body_used[i]+op->body_info[i] < 0) {
704  /* in this case, equipping this would use more free
705  * spots than we have.
706  */
707  object *tmp1;
708 
709  /* if we have an applied weapon/shield, and unapply
710  * it would free enough slots to equip the new item,
711  * then just set this can continue. We don't care
712  * about the logic below - if you have shield equipped
713  * and try to equip another shield, there is only one
714  * choice. However, the check for the number of body
715  * locations does take into the account cases where what
716  * is being applied may be two handed for example.
717  */
718  if (ws) {
719  if (who->body_used[i]-ws->body_info[i]+op->body_info[i] >= 0) {
720  retval |= CAN_APPLY_UNAPPLY;
721  continue;
722  }
723  }
724 
725  tmp1 = get_item_from_body_location(who->inv, i);
726  if (!tmp1)
727  retval |= CAN_APPLY_NEVER;
728  else {
729  /* need to unapply something. However, if this
730  * something is different than we had found before,
731  * it means they need to apply multiple objects
732  */
733  retval |= CAN_APPLY_UNAPPLY;
734  if (!tmp)
735  tmp = tmp1;
736  else if (tmp != tmp1)
737  retval |= CAN_APPLY_UNAPPLY_MULT;
738  /* This object isn't using up all the slots, so
739  * there must be another. If so, and if the new
740  * item doesn't need all the slots, the player
741  * then has a choice.
742  */
743  if (who->body_used[i]-tmp1->body_info[i] != who->body_info[i]
744  && FABS(op->body_info[i]) < who->body_info[i])
745  retval |= CAN_APPLY_UNAPPLY_CHOICE;
746 
747  /* Does unequipping 'tmp1' free up enough slots
748  * for this to be equipped? If not, there must
749  * be something else to unapply.
750  */
751  if (who->body_used[i]+op->body_info[i]-tmp1->body_info[i] < 0)
752  retval |= CAN_APPLY_UNAPPLY_MULT;
753  }
754  } /* if not enough free slots */
755  } /* if this object uses location i */
756  } /* for i -> num_body_locations loop */
757 
758  /* Do checks for can_use_weapon/shield/armour. */
759  if (IS_WEAPON(op) && !QUERY_FLAG(who, FLAG_USE_WEAPON))
760  retval |= CAN_APPLY_RESTRICTION;
761  if (IS_SHIELD(op) && !QUERY_FLAG(who, FLAG_USE_SHIELD))
762  retval |= CAN_APPLY_RESTRICTION;
763  if (IS_ARMOR(op) && !QUERY_FLAG(who, FLAG_USE_ARMOUR))
764  retval |= CAN_APPLY_RESTRICTION;
765 
766  if (who->type != PLAYER) {
767  if ((op->type == WAND || op->type == ROD)
768  && !QUERY_FLAG(who, FLAG_USE_RANGE))
769  retval |= CAN_APPLY_RESTRICTION;
770  if (op->type == BOW && !QUERY_FLAG(who, FLAG_USE_BOW))
771  retval |= CAN_APPLY_RESTRICTION;
772  if (op->type == RING && !QUERY_FLAG(who, FLAG_USE_RING))
773  retval |= CAN_APPLY_RESTRICTION;
774  }
775  return retval;
776 }
777 
793 int apply_check_weapon_power(const object *who, int improves) {
794  return (who->level/5)+5 >= improves;
795 }
796 
818 int apply_special(object *who, object *op, int aflags) {
819  int basic_flag = aflags&AP_BASIC_FLAGS;
820  object *tmp, *skop;
821  char name_op[MAX_BUF];
822 
823  if (who == NULL) {
824  LOG(llevError, "apply_special() from object without environment.\n");
825  return 1;
826  }
827 
828  if (op->env != who)
829  return 1; /* op is not in inventory */
830 
831  /* trying to unequip op */
832  if (QUERY_FLAG(op, FLAG_APPLIED)) {
833  /* always apply, so no reason to unapply */
834  if (basic_flag == AP_APPLY)
835  return 0;
836 
837  if (!(aflags&AP_IGNORE_CURSE)
838  && (QUERY_FLAG(op, FLAG_CURSED) || QUERY_FLAG(op, FLAG_DAMNED))) {
839  if (!(aflags&AP_NOPRINT)) {
840  query_name(op, name_op, MAX_BUF);
842  "No matter how hard you try, you just can't remove %s.",
843  name_op);
844  }
845  return 1;
846  }
847  return unapply_special(who, op, aflags);
848  }
849 
850  if (basic_flag == AP_UNAPPLY)
851  return 0;
852 
853  if (!apply_check_apply_restrictions(who, op, aflags))
854  return 1;
855 
856  if (op->skill && op->type != SKILL && op->type != SKILL_TOOL) {
857  skop = find_skill_by_name(who, op->skill);
858  if (!skop) {
859  if (!(aflags&AP_NOPRINT))
861  "You need the %s skill to use this item!",
862  op->skill);
863  if (who->type == PLAYER)
864  return 1;
865 
866  /* monsters do not care about missing skills */
867  } else
868  /* While experience will be credited properly, we want to
869  * change the skill so that the dam and wc get updated
870  */
871  change_skill(who, skop, (aflags&AP_NOPRINT));
872  } else
873  skop = NULL;
874 
875  if (!apply_check_item_power(who, op, aflags))
876  return 1;
877 
879  return 1;
880 
881  /* Ok. We are now at the state where we can apply the new object.
882  * Note that we don't have the checks for can_use_...
883  * below - that is already taken care of by apply_can_apply_object().
884  */
885 
886  tmp = op->nrof <= 1 ? NULL : object_split(op, op->nrof-1, NULL, 0);
887 
888  switch (op->type) {
889  case WEAPON:
890  if (!apply_check_weapon_power(who, op->last_eat)) {
891  if (!(aflags&AP_NOPRINT))
893  "That weapon is too powerful for you to use. It would consume your soul!");
894  if (tmp != NULL)
895  (void)object_insert_in_ob(tmp, who);
896  return 1;
897  }
898 
899  if (!apply_check_owner(who, op, aflags)) {
900  if (tmp != NULL)
901  (void)object_insert_in_ob(tmp, who);
902  return 1;
903  }
904 
905  SET_FLAG(op, FLAG_APPLIED);
906 
907  if (skop)
908  change_skill(who, skop, 1);
910 
911  if (!(aflags&AP_NOPRINT)) {
912  query_name(op, name_op, MAX_BUF);
914  "You wield %s.",
915  name_op);
916  }
917 
918  (void)change_abil(who, op);
919  break;
920 
921  case ARMOUR:
922  case HELMET:
923  case SHIELD:
924  case BOOTS:
925  case GLOVES:
926  case GIRDLE:
927  case BRACERS:
928  case CLOAK:
929  case RING:
930  case AMULET:
931  SET_FLAG(op, FLAG_APPLIED);
932  if (!(aflags&AP_NOPRINT)) {
933  query_name(op, name_op, MAX_BUF);
935  "You wear %s.",
936  name_op);
937  }
938  (void)change_abil(who, op);
939  break;
940 
941  /* this part is needed for skill-tools */
942  case SKILL:
943  case SKILL_TOOL:
944  if (who->chosen_skill) {
945  LOG(llevError, "BUG: apply_special(): can't apply two skills\n");
946  return 1;
947  }
948 
949  apply_update_ranged_skill(who, op, aflags);
950  SET_FLAG(op, FLAG_APPLIED);
951  (void)change_abil(who, op);
952  who->chosen_skill = op;
954  break;
955 
956  case BOW:
957  if (!apply_check_weapon_power(who, op->last_eat)) {
958  if (!(aflags&AP_NOPRINT))
960  "That weapon is too powerful for you to use. It would consume your soul!");
961  if (tmp != NULL)
962  (void)object_insert_in_ob(tmp, who);
963  return 1;
964  }
965 
966  if (!apply_check_owner(who, op, aflags)) {
967  if (tmp != NULL)
968  (void)object_insert_in_ob(tmp, who);
969  return 1;
970  }
971  /*FALLTHROUGH*/
972  case WAND:
973  case ROD:
974  /* check for skill, alter player status */
975  SET_FLAG(op, FLAG_APPLIED);
976  if (skop)
977  change_skill(who, skop, 0);
978  if (!(aflags&AP_NOPRINT)) {
979  query_name(op, name_op, MAX_BUF);
981  "You ready %s.",
982  name_op);
983  }
984  if (who->type == PLAYER) {
985  if (op->type == BOW) {
986  (void)change_abil(who, op);
987  if (!(aflags&AP_NOPRINT)) {
988  query_name(op, name_op, MAX_BUF);
990  "You will now fire %s with %s.",
991  op->race ? op->race : "nothing",
992  name_op);
993  }
994  who->contr->shoottype = range_bow;
995  } else
996  who->contr->shoottype = range_misc;
997  } else {
998  if (op->type == BOW)
999  SET_FLAG(who, FLAG_READY_BOW);
1000  else
1001  SET_FLAG(who, FLAG_READY_RANGE);
1002  }
1003  break;
1004 
1005  case BUILDER:
1006  if (who->contr->ranges[range_builder])
1007  unapply_special(who, who->contr->ranges[range_builder], 0);
1008  who->contr->shoottype = range_builder;
1009  who->contr->ranges[range_builder] = op;
1010  if (!(aflags&AP_NOPRINT)) {
1011  query_name(op, name_op, MAX_BUF);
1013  "You ready your %s.",
1014  name_op);
1015  }
1016  break;
1017 
1018  default:
1019  query_name(op, name_op, MAX_BUF);
1021  "You apply %s.",
1022  name_op);
1023  break;
1024  } /* end of switch op->type */
1025 
1026  SET_FLAG(op, FLAG_APPLIED);
1027 
1028  if (tmp != NULL)
1029  tmp = object_insert_in_ob(tmp, who);
1030 
1031  fix_object(who);
1032 
1033  /* We exclude spell casting objects. The fire code will set the
1034  * been applied flag when they are used - until that point,
1035  * you don't know anything about them.
1036  */
1037  if (who->type == PLAYER && op->type != WAND && op->type != ROD)
1039 
1040  if (QUERY_FLAG(op, FLAG_CURSED) || QUERY_FLAG(op, FLAG_DAMNED)) {
1041  if (who->type == PLAYER) {
1043  "Oops, it feels deadly cold!");
1045  }
1046  }
1047  if (who->type == PLAYER)
1049  return 0;
1050 }
1051 
1062 int apply_auto(object *op) {
1063  switch (op->type) {
1064  case SHOP_FLOOR:
1065  if (!HAS_RANDOM_ITEMS(op))
1066  return 0;
1067  {
1068  int difficulty = op->stats.exp ? (int)op->stats.exp : MAX(op->map->difficulty, 5);
1069  // create all treasures, inserting it into the shop floor
1070  create_treasure(op->randomitems, op, GT_ONLY_GOOD, difficulty, 0);
1071  }
1072  FOR_INV_PREPARE(op, tmp) {
1073  SET_FLAG(tmp, FLAG_UNPAID);
1074  identify(tmp);
1075  // then drop it on the floor
1076  object_remove(tmp);
1077  object_insert_in_map_at(tmp, op->map, op, INS_NO_WALK_ON, op->x, op->y);
1078  } FOR_INV_FINISH();
1079  op->randomitems = NULL;
1081  return 1;
1082  break;
1083 
1084  case TREASURE:
1085  if (QUERY_FLAG(op, FLAG_IS_A_TEMPLATE))
1086  return 0;
1087  while (op->stats.hp-- > 0)
1088  create_treasure(op->randomitems, op, (op->map ? GT_ENVIRONMENT : 0) | (QUERY_FLAG(op, FLAG_BLESSED) ? GT_ONLY_GOOD : 0), op->stats.exp ? (int)op->stats.exp : op->map == NULL ? 14 : op->map->difficulty, 0);
1089 
1090  /* If we generated an object and put it in this object's
1091  * inventory, move it to the parent object as the current
1092  * object is about to disappear. An example of this item
1093  * is the random_ *stuff that is put inside other objects.
1094  */
1095  FOR_INV_PREPARE(op, tmp) {
1096  object_remove(tmp);
1097  if (op->env)
1098  object_insert_in_ob(tmp, op->env);
1099  else
1101  } FOR_INV_FINISH();
1102  object_remove(op);
1104  break;
1105  }
1106  return 0;
1107 }
1108 
1121 static void auto_apply_fix_inventory(mapstruct *m, object *tmp)
1122 {
1123  if (!tmp->inv)
1124  return;
1125  FOR_INV_PREPARE(tmp, invtmp) {
1126  if (invtmp->inv)
1127  auto_apply_fix_inventory(m,invtmp); // Recurse for containers in objects
1128  if (QUERY_FLAG(invtmp, FLAG_AUTO_APPLY))
1129  apply_auto(invtmp);
1130  else if (invtmp->type == TREASURE && HAS_RANDOM_ITEMS(invtmp)) {
1131  while (invtmp->stats.hp-- > 0)
1132  create_treasure(invtmp->randomitems, invtmp, 0, m->difficulty, 0);
1133  invtmp->randomitems = NULL;
1134  } else if (invtmp && invtmp->arch
1135  && invtmp->type != TREASURE
1136  && invtmp->type != SPELL
1137  && invtmp->type != CLASS
1138  && HAS_RANDOM_ITEMS(invtmp)) {
1139  create_treasure(invtmp->randomitems, invtmp, 0, m->difficulty, 0);
1140  /* Need to clear this so that we never try to
1141  * create treasure again for this object
1142  */
1143  invtmp->randomitems = NULL;
1144  }
1145  } FOR_INV_FINISH();
1146  /* This is really temporary - the code at the
1147  * bottom will also set randomitems to null.
1148  * The problem is there are bunches of maps/players
1149  * already out there with items that have spells
1150  * which haven't had the randomitems set
1151  * to null yet.
1152  * MSW 2004-05-13
1153  *
1154  * And if it's a spellbook, it's better to set
1155  * randomitems to NULL too, else you get two spells
1156  * in the book ^_-
1157  * Ryo 2004-08-16
1158  */
1159  if (tmp->type == WAND
1160  || tmp->type == ROD
1161  || tmp->type == SCROLL
1162  || tmp->type == FIREWALL
1163  || tmp->type == POTION
1164  || tmp->type == ALTAR
1165  || tmp->type == SPELLBOOK)
1166  tmp->randomitems = NULL;
1167 }
1168 
1180  int x, y;
1181 
1182  if (m == NULL)
1183  return;
1184 
1185  for (x = 0; x < MAP_WIDTH(m); x++)
1186  for (y = 0; y < MAP_HEIGHT(m); y++)
1187  FOR_MAP_PREPARE(m, x, y, tmp) {
1188  if (tmp->inv) {
1190  }
1191 
1192  if (QUERY_FLAG(tmp, FLAG_AUTO_APPLY))
1193  apply_auto(tmp);
1194  else if ((tmp->type == TREASURE || tmp->type == CONTAINER)
1195  && HAS_RANDOM_ITEMS(tmp)) {
1196  while (tmp->stats.hp-- > 0)
1197  create_treasure(tmp->randomitems, tmp, 0, m->difficulty, 0);
1198  tmp->randomitems = NULL;
1199  } else if (tmp->type == TIMED_GATE) {
1200  object *head = HEAD(tmp);
1201 
1202  if (QUERY_FLAG(head, FLAG_IS_LINKED)) {
1203  tmp->speed = 0;
1204  object_update_speed(tmp);
1205  }
1206  }
1207  /* This function can be called every time a map is loaded,
1208  * even when swapping back in. As such, we don't want to
1209  * create the treasure over and over again, so after we
1210  * generate the treasure, blank out randomitems so if it
1211  * is swapped in again, it won't make anything. This is a
1212  * problem for the above objects, because they have
1213  * counters which say how many times to make the treasure.
1214  */
1215  else if (tmp
1216  && tmp->arch
1217  && tmp->type != PLAYER
1218  && tmp->type != TREASURE
1219  && tmp->type != SPELL
1220  && tmp->type != PLAYER_CHANGER
1221  && tmp->type != CLASS
1222  && HAS_RANDOM_ITEMS(tmp)) {
1223  create_treasure(tmp->randomitems, tmp, 0, m->difficulty, 0);
1224  tmp->randomitems = NULL;
1225  }
1226 
1227  if (QUERY_FLAG(tmp, FLAG_MONSTER))
1229  } FOR_MAP_FINISH();
1230 
1231  for (x = 0; x < MAP_WIDTH(m); x++)
1232  for (y = 0; y < MAP_HEIGHT(m); y++)
1233  FOR_MAP_PREPARE(m, x, y, tmp) {
1234  if (tmp->above
1235  && (tmp->type == TRIGGER_BUTTON || tmp->type == TRIGGER_PEDESTAL))
1236  check_trigger(tmp, tmp->above);
1237  } FOR_MAP_FINISH();
1238 }
1239 
1254 void scroll_failure(object *op, int failure, int power) {
1255  if (abs(failure/4) > power)
1256  power = abs(failure/4); /* set minimum effect */
1257 
1258  if (failure <= -1 && failure > -15) {/* wonder */
1259  object *tmp;
1260 
1262  "Your spell warps!");
1264  cast_wonder(op, op, 0, tmp);
1265  if (op->stats.sp < 0)
1266  /* For some reason the sp can become negative here. */
1267  op->stats.sp = 0;
1269  return;
1270  }
1271 
1273  if (failure <= -35 && failure > -60) { /* confusion */
1275  "The magic recoils on you!");
1276  confuse_living(op, op, power);
1277  return;
1278  }
1279 
1280  if (failure <= -60 && failure > -70) {/* paralysis */
1282  "The magic recoils and paralyzes you!");
1283  paralyze_living(op, power);
1284  return;
1285  }
1286 
1287  if (failure <= -70 && failure > -80) {/* blind */
1289  "The magic recoils on you!");
1290  blind_living(op, op, power);
1291  return;
1292  }
1293 
1294  if (failure <= -80) {/* blast the immediate area */
1295  object *tmp;
1296 
1298  cast_magic_storm(op, tmp, power);
1300  "You unleash uncontrolled mana!");
1301  return;
1302  }
1303  }
1304  /* Either no spell failure on this server, or wrong values,
1305  * in any case let's punish.
1306  */
1308  "Your mana is drained!");
1309  op->stats.sp -= random_roll(0, power-1, op, PREFER_LOW);
1310  if (op->stats.sp < 0)
1311  op->stats.sp = 0;
1312 }
1313 
1325 void apply_changes_to_player(object *pl, object *change, int limit_stats) {
1326  int i, j;
1327  int excess_stat = 0; /* if the stat goes over the maximum
1328  * for the race, put the excess stat some
1329  * where else.
1330  */
1331 
1332  if (change->type != CLASS) return;
1333 
1334  /* the following code assigns stats up to the stat max
1335  * for the race, and if the stat max is exceeded,
1336  * tries to randomly reassign the excess stat
1337  */
1338  if (! (limit_stats & AC_PLAYER_STAT_NO_CHANGE)) {
1339  for (i = 0; i < NUM_STATS; i++) {
1340  int8_t stat = get_attr_value(&pl->contr->orig_stats, i);
1341  int race_bonus = get_attr_value(&pl->arch->clone.stats, i);
1342 
1343  stat += get_attr_value(&change->stats, i);
1344  if (limit_stats & AC_PLAYER_STAT_LIMIT) {
1345  if (stat > 20+race_bonus) {
1346  excess_stat++;
1347  stat = 20+race_bonus;
1348  } else if (stat < 1) {
1349  /* I didn't see any code here before to make sure minimum
1350  * stats were enforced - maybe it was just dumb
1351  * luck that one would not have a stat low enough that then
1352  * has a stat penalty for class that would bring it negative?
1353  * I imagine a negative stat would crash the server pretty
1354  * quickly - MSW, Sept 2010
1355  */
1356  excess_stat += stat;
1357  stat = 1;
1358  }
1359  }
1360  set_attr_value(&pl->contr->orig_stats, i, stat);
1361  }
1362 
1363  /* Maybe we should randomly deduct stats in this case?
1364  * It's will go away sometime soon in any case.
1365  */
1366  if (excess_stat < 0) excess_stat = 0;
1367 
1368  /* We don't put an explicit check for limit_stats here -
1369  * excess stat will never be 0 if limit_stats is not
1370  * true.
1371  */
1372  for (j = 0; excess_stat > 0 && j < 100; j++) {
1373  /* try 100 times to assign excess stats */
1374  int i = rndm(0, NUM_STATS-1);
1375  int stat = get_attr_value(&pl->contr->orig_stats, i);
1376  int race_bonus = get_attr_value(&pl->arch->clone.stats, i);
1377 
1378  if (i == CHARISMA) {
1379  continue; /* exclude cha from this */
1380  }
1381 
1382  if (stat < 20+race_bonus) {
1383  change_attr_value(&pl->contr->orig_stats, i, 1);
1384  excess_stat--;
1385  }
1386  }
1387  }
1388  /* Done with stat processing */
1389 
1390  /* insert the randomitems from the change's treasurelist into
1391  * the player ref: player.c
1392  */
1393  if (change->randomitems != NULL)
1394  give_initial_items(pl, change->randomitems);
1395 
1396 
1397  /* set up the face, for some races. */
1398 
1399  /* first, look for the force object banning changing the
1400  * face. Certain races never change face with class.
1401  */
1402  int has_noclassfacechange = (object_find_by_name(pl, "NOCLASSFACECHANGE") != NULL);
1403  const Animations *anim = NULL;
1404 
1405  if (change->anim_suffix) {
1406  char buf[MAX_BUF];
1407 
1408  snprintf(buf, MAX_BUF, "%s_%s", pl->animation->name, change->anim_suffix);
1409  anim = try_find_animation(buf);
1410  if (anim) {
1411  pl->animation = anim;
1412  pl->anim_speed = -1;
1413  CLEAR_FLAG(pl, FLAG_ANIMATE);
1414  animate_object(pl, pl->facing);
1415  }
1416  }
1417  /* Check for anim == -1 so that we can override specific class faces for races.
1418  * This allows us to have custom class faces on the races that lack noclassfacechange
1419  *
1420  * Neila Hawkins 2020-09-08
1421  */
1422  if ((!has_noclassfacechange) && anim == 0) {
1423  pl->animation = GET_ANIM(change);
1424  pl->face = change->face;
1425 
1426  if (QUERY_FLAG(change, FLAG_ANIMATE))
1427  SET_FLAG(pl, FLAG_ANIMATE);
1428  else
1429  CLEAR_FLAG(pl, FLAG_ANIMATE);
1430  }
1431 
1432  /* Hard coding in class name is a horrible idea - lets
1433  * use the supported mechanism for this
1434  */
1435  if (object_present_in_ob_by_name(FORCE, "no weapon force", pl))
1437 
1438 }
1439 
1453 static int apply_check_apply_restrictions(object *who, object *op, int aflags) {
1454  int i;
1455 
1456  i = apply_can_apply_object(who, op);
1457  if (i == 0)
1458  return 1;
1459 
1460  /* Can't just apply this object. Lets see why not and what to do */
1461 
1462  if (i&CAN_APPLY_NEVER) {
1463  if (!(aflags&AP_NOPRINT)) {
1464  char name_op[MAX_BUF];
1465 
1466  query_name(op, name_op, MAX_BUF);
1468  "You don't have the body to use a %s",
1469  name_op);
1470  }
1471  return 0;
1472  }
1473 
1474  if (i&CAN_APPLY_RESTRICTION) {
1475  if (!(aflags&AP_NOPRINT)) {
1476  char name_op[MAX_BUF];
1477 
1478  query_name(op, name_op, MAX_BUF);
1480  "You have a prohibition against using a %s",
1481  name_op);
1482  }
1483  return 0;
1484  }
1485 
1486  if (who->type != PLAYER) {
1487  /* Some error, so don't try to equip something more */
1488  return !unapply_for_ob(who, op, aflags);
1489  }
1490 
1491  if (who->contr->unapply == unapply_never
1493  if (!(aflags&AP_NOPRINT))
1495  "You need to unapply some item(s):");
1496  unapply_for_ob(who, op, AP_PRINT);
1497  return 0;
1498  }
1499 
1500  if (who->contr->unapply == unapply_always
1501  || !(i&CAN_APPLY_UNAPPLY_CHOICE)) {
1502  return !unapply_for_ob(who, op, aflags);
1503  }
1504 
1505  return 1;
1506 }
1507 
1520 static int apply_check_item_power(const object *who, const object *op, int aflags) {
1521  if (who->type != PLAYER)
1522  return 1;
1523 
1524  if (op->item_power == 0
1526  return 1;
1527 
1528  if (!(aflags&AP_NOPRINT))
1530  "Equipping that combined with other items would consume your soul!");
1531  return 0;
1532 }
1533 
1548 static int apply_check_personalized_blessings(object *who, const object *op) {
1549  const char *owner;
1550  const char *will;
1551  long item_will;
1552  long margin;
1553  const char *msg;
1554  int random_effect;
1555  int damage_percentile;
1556 
1558  return 1;
1559  }
1560 
1561  owner = object_get_value(op, "item_owner");
1562  if (owner == NULL || strcmp(owner, who->name) == 0)
1563  return 1;
1564 
1565  will = object_get_value(op, "item_willpower");
1566  item_will = will != NULL ? atol(will) : 0;
1567  if (item_will > who->stats.exp) {
1569  "This %s refuses to serve you - it keeps evading your hand !",
1570  op->name);
1571  return 0;
1572  }
1573 
1574  margin = item_will != 0 ? who->stats.exp/item_will : who->stats.exp;
1575  random_effect = random_roll(0, 100, who, 1)-margin*20;
1576  if (random_effect > 80) {
1577  msg = "You don't know why, but you have the feeling that the %s is angry at you !";
1578  damage_percentile = 60;
1579  } else if (random_effect > 60) {
1580  msg = "The %s seems to look at you nastily !";
1581  damage_percentile = 45;
1582  } else if (random_effect > 40) {
1583  msg = "You have the strange feeling that the %s is annoyed...";
1584  damage_percentile = 30;
1585  } else if (random_effect > 20) {
1586  msg = "The %s seems tired, or bored, in a way. Very strange !";
1587  damage_percentile = 15;
1588  } else if (random_effect > 0) {
1589  msg = "You hear the %s sighing !";
1590  damage_percentile = 0;
1591  } else {
1592  msg = NULL;
1593  damage_percentile = 0;
1594  }
1595  if (msg != NULL)
1597  msg, op->name);
1598  if (damage_percentile > 0) {
1599  int weapon_bite = (who->stats.hp*damage_percentile)/100;
1600  if (weapon_bite < 1)
1601  weapon_bite = 1;
1602  who->stats.hp -= weapon_bite;
1604  "You get a nasty bite in the hand !");
1605  }
1606 
1607  return 1;
1608 }
1609 
1624 static int apply_check_owner(const object *who, const object *op, int aflags) {
1625  const char *quotepos;
1626 
1627  if (op->level == 0)
1628  return 1;
1629 
1630  quotepos = strstr(op->name, "'");
1631  if (quotepos == NULL || strncmp(op->name, who->name, quotepos-op->name) == 0)
1632  return 1;
1633 
1634  if (!(aflags&AP_NOPRINT))
1636  "The weapon does not recognize you as its owner.");
1637  return 0;
1638 }
1639 
1650 static void apply_update_ranged_skill(const object *who, object *op, int aflags) {
1651  if (who->type != PLAYER) {
1652  return;
1653  }
1654 
1655  who->contr->shoottype = range_skill;
1656  who->contr->ranges[range_skill] = op;
1657  if (op->invisible) {
1658  if (!(aflags&AP_NOPRINT))
1660  "Readied skill: %s.",
1661  op->skill ? op->skill : op->name);
1662  } else {
1663  if (!(aflags&AP_NOPRINT)) {
1664  char name_op[MAX_BUF];
1665 
1666  query_name(op, name_op, MAX_BUF);
1668  "You ready %s.",
1669  name_op);
1671  "You can now use the skill: %s.",
1672  op->skill);
1673  }
1674  }
1675 }
paralyze_living
void paralyze_living(object *op, int dam)
Paralyze a living thing.
Definition: attack.cpp:2402
CLASS
@ CLASS
Object for applying character class modifications to someone.
Definition: object.h:143
FLAG_USE_BOW
#define FLAG_USE_BOW
(Monster) can apply and fire bows
Definition: define.h:280
living::exp
int64_t exp
Experience.
Definition: living.h:47
HAS_RANDOM_ITEMS
#define HAS_RANDOM_ITEMS(op)
This return TRUE if object has still randomitems which could be expanded.
Definition: define.h:184
unapply_special
static int unapply_special(object *who, object *op, int aflags)
Unapplies specified item.
Definition: apply.cpp:413
PLAYER
@ PLAYER
Definition: object.h:112
global.h
settings
struct Settings settings
Global settings.
Definition: init.cpp:139
SOUND_TYPE_ITEM
#define SOUND_TYPE_ITEM
Definition: newclient.h:339
FOR_MAP_FINISH
#define FOR_MAP_FINISH()
Finishes FOR_MAP_PREPARE().
Definition: define.h:714
FLAG_USE_RANGE
#define FLAG_USE_RANGE
(Monster) can apply and use range items
Definition: define.h:279
object_find_by_type_applied
object * object_find_by_type_applied(const object *who, int type)
Find applied object in inventory.
Definition: object.cpp:4068
NUM_BODY_LOCATIONS
#define NUM_BODY_LOCATIONS
Number of body locations.
Definition: object.h:15
BOW
@ BOW
Definition: object.h:123
BRACERS
@ BRACERS
Definition: object.h:222
llevError
@ llevError
Error, serious thing.
Definition: logger.h:11
FABS
#define FABS(x)
Decstations have trouble with fabs()...
Definition: define.h:22
FLAG_ANIMATE
#define FLAG_ANIMATE
The object looks at archetype for faces.
Definition: define.h:229
mapstruct::difficulty
uint16_t difficulty
What level the player should be to play here.
Definition: map.h:336
MOVE_FLYING
#define MOVE_FLYING
Combo of fly_low and fly_high.
Definition: define.h:386
WAND
@ WAND
Definition: object.h:225
range_bow
@ range_bow
Bow.
Definition: player.h:31
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:369
GLOVES
@ GLOVES
Definition: object.h:218
FLAG_IS_LINKED
#define FLAG_IS_LINKED
The object is linked with other objects.
Definition: define.h:302
object::inv
object * inv
Pointer to the first object in the inventory.
Definition: object.h:298
GIRDLE
@ GIRDLE
Definition: object.h:228
QUERY_FLAG
#define QUERY_FLAG(xyz, p)
Definition: define.h:371
TRIGGER_PEDESTAL
@ TRIGGER_PEDESTAL
Definition: object.h:139
apply_special
int apply_special(object *who, object *op, int aflags)
Apply an object.
Definition: apply.cpp:818
confuse_living
void confuse_living(object *op, object *hitter, int dam)
Confuse a living thing.
Definition: attack.cpp:2315
clear_skill
void clear_skill(object *who)
This function just clears the chosen_skill and range_skill values in the player.
Definition: skill_util.cpp:396
apply_check_apply_restrictions
static int apply_check_apply_restrictions(object *who, object *op, int aflags)
Checks for general apply restrictions (no body, prohibited by god, conflicts with other items,...
Definition: apply.cpp:1453
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:2036
AP_APPLY
#define AP_APPLY
Item is to be applied.
Definition: define.h:558
object::item_power
int8_t item_power
Power rating of the object.
Definition: object.h:372
apply_check_owner
static int apply_check_owner(const object *who, const object *op, int aflags)
Checks that the item's owner matches the applier.
Definition: apply.cpp:1624
apply_check_race_restrictions
static int apply_check_race_restrictions(object *who, object *item)
Checks if an item is restricted to a race.
Definition: apply.cpp:219
object::arch
struct archetype * arch
Pointer to archetype.
Definition: object.h:424
IS_WEAPON
#define IS_WEAPON(op)
Definition: define.h:163
UPD_WEIGHT
#define UPD_WEIGHT
Definition: newclient.h:320
SHOP_FLOOR
@ SHOP_FLOOR
Definition: object.h:188
METHOD_OK
#define METHOD_OK
Definition: ob_methods.h:15
object::invisible
int16_t invisible
How much longer the object will be invis.
Definition: object.h:370
CAN_APPLY_UNAPPLY_MULT
#define CAN_APPLY_UNAPPLY_MULT
Definition: define.h:618
object::x
int16_t x
Definition: object.h:335
CAN_APPLY_RESTRICTION
#define CAN_APPLY_RESTRICTION
Definition: define.h:615
ARMOUR
@ ARMOUR
Definition: object.h:125
player::transport
object * transport
Transport the player is in.
Definition: player.h:216
FLAG_USE_ARMOUR
#define FLAG_USE_ARMOUR
(Monster) can wear armour/shield/helmet
Definition: define.h:282
PREFER_LOW
#define PREFER_LOW
Definition: define.h:548
object::map
struct mapstruct * map
Pointer to the map in which this object is present.
Definition: object.h:305
object::anim_suffix
sstring anim_suffix
Used to determine combined animations.
Definition: object.h:324
WEAPON
@ WEAPON
Definition: object.h:124
AP_UNAPPLY
#define AP_UNAPPLY
Item is to be remvoed.
Definition: define.h:559
TIMED_GATE
@ TIMED_GATE
Definition: object.h:133
MSG_TYPE_APPLY_CURSED
#define MSG_TYPE_APPLY_CURSED
Applied a cursed object (BAD)
Definition: newclient.h:609
apply_by_living
int apply_by_living(object *pl, object *op, int aflag, int quiet)
Living thing is applying an object.
Definition: apply.cpp:299
LOOSE_MANA
#define LOOSE_MANA
Definition: spells.h:162
GT_ONLY_GOOD
@ GT_ONLY_GOOD
Don't generate bad/cursed items.
Definition: treasure.h:34
range_none
@ range_none
No range selected.
Definition: player.h:30
apply_changes_to_player
void apply_changes_to_player(object *pl, object *change, int limit_stats)
Applies (race) changes to a player.
Definition: apply.cpp:1325
unapply_for_ob
static int unapply_for_ob(object *who, object *op, int aflags)
Remove equipment so an object can be applied.
Definition: apply.cpp:577
CHARISMA
@ CHARISMA
Definition: living.h:15
AMULET
@ AMULET
Definition: object.h:144
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
FLAG_WIZ
#define FLAG_WIZ
Object has special privilegies.
Definition: define.h:218
FLAG_BEEN_APPLIED
#define FLAG_BEEN_APPLIED
Object was ever applied, for identification purposes.
Definition: define.h:310
play_sound_player_only
void play_sound_player_only(player *pl, int8_t sound_type, object *emitter, int dir, const char *action)
Plays a sound for specified player only.
Definition: sounds.cpp:51
TREASURE
@ TREASURE
Definition: object.h:115
SKILL
@ SKILL
Also see SKILL_TOOL (74) below.
Definition: object.h:148
FLAG_READY_RANGE
#define FLAG_READY_RANGE
(Monster) has a range attack readied...
Definition: define.h:285
play_sound_map
void play_sound_map(int8_t sound_type, object *emitter, int dir, const char *action)
Plays a sound on a map.
Definition: sounds.cpp:113
change_skill
int change_skill(object *who, object *new_skill, int flag)
This changes the object's skill to new_skill.
Definition: skill_util.cpp:357
object_copy
void object_copy(const object *src_ob, object *dest_ob)
Copy object first frees everything allocated by the second object, and then copies the contents of th...
Definition: object.cpp:1177
AP_IGNORE_CURSE
#define AP_IGNORE_CURSE
Apply/unapply regardless of cursed/damned status.
Definition: define.h:566
GET_ANIM
#define GET_ANIM(ob)
Definition: global.h:166
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
NDI_NAVY
#define NDI_NAVY
Definition: newclient.h:248
TRANSPORT
@ TRANSPORT
see doc/Developers/objects
Definition: object.h:113
UPD_NROF
#define UPD_NROF
Definition: newclient.h:325
unapply_always
@ unapply_always
Will unapply whatever is necessary - this goes beyond no choice - if there are multiple ojbect of the...
Definition: player.h:78
scroll_failure
void scroll_failure(object *op, int failure, int power)
op made some mistake with a scroll, this takes care of punishment.
Definition: apply.cpp:1254
rndm
int rndm(int min, int max)
Returns a number between min and max.
Definition: utils.cpp:162
skills.h
TRIGGER_BUTTON
@ TRIGGER_BUTTON
Definition: object.h:137
FLAG_READY_BOW
#define FLAG_READY_BOW
not implemented yet
Definition: define.h:286
esrv_add_spells
void esrv_add_spells(player *pl, object *spell)
This tells the client to add the spell *spell, if spell is NULL, then add all spells in the player's ...
Definition: request.cpp:1994
FLAG_CURSED
#define FLAG_CURSED
The object is cursed.
Definition: define.h:303
FLAG_BLESSED
#define FLAG_BLESSED
Item has a blessing, opposite of cursed/damned.
Definition: define.h:356
object::level
int16_t level
Level of creature or object.
Definition: object.h:361
apply_check_personalized_blessings
static int apply_check_personalized_blessings(object *who, const object *op)
If personalized blessings are activated, the weapon can bite the wielder if he/she is not the one who...
Definition: apply.cpp:1548
auto_apply_fix_inventory
static void auto_apply_fix_inventory(mapstruct *m, object *tmp)
Go through one object on a map and process any special treasure creation or such for anything in it's...
Definition: apply.cpp:1121
buf
StringBuffer * buf
Definition: readable.cpp:1565
do_learn_spell
void do_learn_spell(object *op, object *spell, int special_prayer)
Actually makes op learn spell.
Definition: apply.cpp:146
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:2842
MSG_TYPE_VICTIM
#define MSG_TYPE_VICTIM
Something bad is happening to the player.
Definition: newclient.h:419
MAX
#define MAX(x, y)
Definition: compat.h:24
name
Plugin animator file specs[Config] name
Definition: animfiles.txt:4
cast_magic_storm
void cast_magic_storm(object *op, object *tmp, int lvl)
This is really used mostly for spell fumbles and the like.
Definition: spell_effect.cpp:49
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_KNOWN_CURSED
#define FLAG_KNOWN_CURSED
The object is known to be cursed.
Definition: define.h:307
range_builder
@ range_builder
Map builder.
Definition: player.h:36
METHOD_UNHANDLED
#define METHOD_UNHANDLED
Definition: ob_methods.h:16
object::carrying
int32_t carrying
How much weight this object contains.
Definition: object.h:377
object::y
int16_t y
Position in the map for this object.
Definition: object.h:335
m
static event_registration m
Definition: citylife.cpp:424
CLOAK
@ CLOAK
Definition: object.h:209
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:1545
give_initial_items
void give_initial_items(object *pl, treasurelist *items)
Gives a new player her initial items.
Definition: player.cpp:792
object::contr
struct player * contr
Pointer to the player which control this object.
Definition: object.h:284
object_find_by_name
object * object_find_by_name(const object *who, const char *name)
Finds an object in inventory name.
Definition: object.cpp:3941
esrv_remove_spell
void esrv_remove_spell(player *pl, object *spell)
Definition: request.cpp:1857
apply_handle_yield
void apply_handle_yield(object *tmp)
This checks whether the object has a "on_use_yield" field, and if so generated and drops matching ite...
Definition: apply.cpp:122
HELMET
@ HELMET
Definition: object.h:141
FLAG_READY_SKILL
#define FLAG_READY_SKILL
(Monster or Player) has a skill readied
Definition: define.h:320
object::chosen_skill
object * chosen_skill
The skill chosen to use.
Definition: object.h:396
object::subtype
uint8_t subtype
Subtype of object.
Definition: object.h:349
drop
void drop(object *op, object *tmp)
Drop an item, either on the floor or in a container.
Definition: c_object.cpp:1120
AP_PRINT
#define AP_PRINT
Print what to do, don't actually do it Note this is supported in all the functions.
Definition: define.h:567
object::anim_speed
uint8_t anim_speed
Ticks between animation-frames.
Definition: object.h:429
FLAG_UNPAID
#define FLAG_UNPAID
Object hasn't been paid for yet.
Definition: define.h:223
blind_living
void blind_living(object *op, object *hitter, int dam)
Blind a living thing.
Definition: attack.cpp:2358
object_present_in_ob_by_name
object * object_present_in_ob_by_name(int type, const char *str, const object *op)
Searches for any objects with a matching type & name variable in the inventory of the given object.
Definition: object.cpp:3188
MSG_TYPE_APPLY_SUCCESS
#define MSG_TYPE_APPLY_SUCCESS
Was able to apply object.
Definition: newclient.h:607
SPELL_WONDER
#define SPELL_WONDER
Definition: spells.h:163
query_name
void query_name(const object *op, char *buf, size_t size)
Describes an item.
Definition: item.cpp:594
FREE_OBJ_NO_DESTROY_CALLBACK
#define FREE_OBJ_NO_DESTROY_CALLBACK
Do not run the destroy callback.
Definition: object.h:545
POTION
@ POTION
Definition: object.h:116
BUILDER
@ BUILDER
Generic item builder, see subtypes below.
Definition: object.h:251
player::ranges
object * ranges[range_size]
Object for each range.
Definition: player.h:118
archetype::clone
object clone
An object from which to do object_copy()
Definition: object.h:487
AC_PLAYER_STAT_NO_CHANGE
#define AC_PLAYER_STAT_NO_CHANGE
Do not make any stat adjustments.
Definition: define.h:581
apply_by_living_below
void apply_by_living_below(object *pl)
Attempt to apply the object 'below' the player.
Definition: apply.cpp:357
object::weight_limit
int32_t weight_limit
Weight-limit of object.
Definition: object.h:376
apply_anim_suffix
void apply_anim_suffix(object *who, const char *suffix)
Applies a compound animation to an object.
Definition: anim.cpp:150
FLAG_MONSTER
#define FLAG_MONSTER
Will attack players.
Definition: define.h:232
FOR_OB_AND_BELOW_FINISH
#define FOR_OB_AND_BELOW_FINISH()
Finishes FOR_OB_AND_BELOW_PREPARE().
Definition: define.h:738
HEAD
#define HEAD(op)
Returns the head part of an object.
Definition: object.h:607
ROD
@ ROD
Definition: object.h:114
CONTAINER
@ CONTAINER
Definition: object.h:236
object::below
object * below
Pointer to the object stacked below this one.
Definition: object.h:295
object::move_type
MoveType move_type
Type of movement this object uses.
Definition: object.h:436
set_attr_value
void set_attr_value(living *stats, int attr, int8_t value)
Sets Str/Dex/con/Wis/Cha/Int/Pow in stats to value, depending on what attr is (STR to POW).
Definition: living.cpp:218
object::face
const Face * face
Face with colors.
Definition: object.h:341
apply_check_item_power
static int apply_check_item_power(const object *who, const object *op, int aflags)
Checks for item power restrictions when applying an item.
Definition: apply.cpp:1520
object::last_eat
int32_t last_eat
How long since we last ate.
Definition: object.h:366
object_update_speed
void object_update_speed(object *op)
Updates the speed of an object.
Definition: object.cpp:1334
object::type
uint8_t type
PLAYER, BULLET, etc.
Definition: object.h:348
apply_manual
int apply_manual(object *op, object *tmp, int aflag)
Main apply handler.
Definition: apply.cpp:259
UPD_FLAGS
#define UPD_FLAGS
Definition: newclient.h:319
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
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:1577
do_forget_spell
void do_forget_spell(object *op, const char *spell)
Erases spell from player's inventory.
Definition: apply.cpp:187
LAMP
@ LAMP
Lamp.
Definition: object.h:206
Settings::item_power_factor
float item_power_factor
See note in setings file.
Definition: global.h:304
FOR_INV_FINISH
#define FOR_INV_FINISH()
Finishes FOR_INV_PREPARE().
Definition: define.h:661
player::item_power
int16_t item_power
Total item power of objects equipped.
Definition: player.h:132
object::move_on
MoveType move_on
Move types affected moving on to this space.
Definition: object.h:439
FLAG_IS_A_TEMPLATE
#define FLAG_IS_A_TEMPLATE
Object has no ingame life until instantiated.
Definition: define.h:353
player::shoottype
rangetype shoottype
Which range-attack is being used by player.
Definition: player.h:114
sproto.h
living::sp
int16_t sp
Spell points.
Definition: living.h:42
MSG_TYPE_VICTIM_WAS_HIT
#define MSG_TYPE_VICTIM_WAS_HIT
Player was hit by something.
Definition: newclient.h:655
FLAG_IS_FLOOR
#define FLAG_IS_FLOOR
Can't see what's underneath this object.
Definition: define.h:289
FOR_OB_AND_BELOW_PREPARE
#define FOR_OB_AND_BELOW_PREPARE(op_)
Constructs a loop iterating over an object and all objects below it in the same pile.
Definition: define.h:734
GT_ENVIRONMENT
@ GT_ENVIRONMENT
?
Definition: treasure.h:31
random_roll
int random_roll(int min, int max, const object *op, int goodbad)
Roll a random number between min and max.
Definition: utils.cpp:42
SOUND_TYPE_SPELL
#define SOUND_TYPE_SPELL
Definition: newclient.h:338
object::race
sstring race
Human, goblin, dragon, etc.
Definition: object.h:326
object::facing
int8_t facing
Object is oriented/facing that way.
Definition: object.h:345
object::animation
const Animations * animation
Animation of this item, NULL if not animated.
Definition: object.h:428
RING
@ RING
Definition: object.h:190
INS_NO_WALK_ON
#define INS_NO_WALK_ON
Don't call check_walk_on against the originator.
Definition: object.h:582
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:2085
find_skill_by_name
object * find_skill_by_name(object *who, const char *name)
This returns the skill pointer of the given name (the one that accumulates exp, has the level,...
Definition: skill_util.cpp:209
MAP_WIDTH
#define MAP_WIDTH(m)
Map width.
Definition: map.h:76
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
FLAG_USE_WEAPON
#define FLAG_USE_WEAPON
(Monster) can wield weapons
Definition: define.h:283
MAX_BUF
#define MAX_BUF
Used for all kinds of things.
Definition: define.h:35
object_new
object * object_new(void)
Grabs an object from the list of unused objects, makes sure it is initialised, and returns it.
Definition: object.cpp:1258
create_archetype
object * create_archetype(const char *name)
Finds which archetype matches the given name, and returns a new object containing a copy of the arche...
Definition: arch.cpp:276
player::orig_stats
living orig_stats
Permanent real stats of player.
Definition: player.h:169
object::current_weapon
object * current_weapon
Pointer to the weapon currently used.
Definition: object.h:380
object::weight
int32_t weight
Attributes of the object.
Definition: object.h:375
monster_check_apply_all
void monster_check_apply_all(object *monster)
Calls monster_check_apply() for all inventory objects.
Definition: monster.cpp:2001
apply_check_weapon_power
int apply_check_weapon_power(const object *who, int improves)
This checks to see of the player (who) is sufficient level to use a weapon with improves improvements...
Definition: apply.cpp:793
AP_BASIC_FLAGS
#define AP_BASIC_FLAGS
Definition: define.h:562
player::unapply
unapplymode unapply
Method for auto unapply.
Definition: player.h:123
try_find_animation
Animations * try_find_animation(const char *name)
Definition: assets.cpp:282
apply_auto
int apply_auto(object *op)
Map was just loaded, handle op's initialization.
Definition: apply.cpp:1062
FLAG_DAMNED
#define FLAG_DAMNED
The object is very cursed.
Definition: define.h:304
Settings::spell_failure_effects
uint8_t spell_failure_effects
Nasty backlash to spell failures.
Definition: global.h:270
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:707
change_abil
int change_abil(object *op, object *tmp)
Permanently alters an object's stats/flags based on another object.
Definition: living.cpp:394
MSG_TYPE_APPLY_BADBODY
#define MSG_TYPE_APPLY_BADBODY
Don't have body to use object.
Definition: newclient.h:611
CAN_APPLY_NEVER
#define CAN_APPLY_NEVER
Definition: define.h:614
range_misc
@ range_misc
Misc items.
Definition: player.h:33
sounds.h
check_trigger
int check_trigger(object *op, object *cause)
Definition: button.cpp:518
NDI_UNIQUE
#define NDI_UNIQUE
Print immediately, don't buffer.
Definition: newclient.h:266
object::slaying
sstring slaying
Which race to do double damage to.
Definition: object.h:327
spells.h
FLAG_READY_WEAPON
#define FLAG_READY_WEAPON
(Monster or Player) has a weapon readied
Definition: define.h:321
object::name
sstring name
The name of the object, obviously...
Definition: object.h:319
unapply_nochoice
@ unapply_nochoice
Will unapply objects when there no choice to unapply.
Definition: player.h:76
IS_SHIELD
#define IS_SHIELD(op)
Definition: define.h:170
apply_can_apply_object
int apply_can_apply_object(const object *who, const object *op)
Checks to see if 'who' can apply object 'op'.
Definition: apply.cpp:678
FIREWALL
@ FIREWALL
Definition: object.h:173
PLAYER_CHANGER
@ PLAYER_CHANGER
Definition: object.h:167
change_attr_value
void change_attr_value(living *stats, int attr, int8_t value)
Like set_attr_value(), but instead the value (which can be negative) is added to the specified stat.
Definition: living.cpp:264
mapstruct
This is a game-map.
Definition: map.h:318
object::env
object * env
Pointer to the object which is the environment.
Definition: object.h:301
check_spell_known
object * check_spell_known(object *op, const char *name)
Checks to see if player knows the spell.
Definition: spell_util.cpp:394
FLAG_AUTO_APPLY
#define FLAG_AUTO_APPLY
Will be applied when created.
Definition: define.h:237
AP_NOPRINT
#define AP_NOPRINT
Don't print messages - caller will do that may be some that still print.
Definition: define.h:569
sstring
const typedef char * sstring
Definition: sstring.h:2
Animations
This represents one animation.
Definition: face.h:25
Settings::personalized_blessings
uint8_t personalized_blessings
If 1, blessed weapons get an owner and a willpower value.
Definition: global.h:313
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
object_split
object * object_split(object *orig_ob, uint32_t nr, char *err, size_t size)
object_split(ob,nr) splits up ob into two parts.
Definition: object.cpp:2622
FLAG_APPLIED
#define FLAG_APPLIED
Object is ready for use by living.
Definition: define.h:222
esrv_update_item
void esrv_update_item(int flags, object *pl, object *op)
Updates object *op for player *pl.
Definition: main.cpp:359
SKILL_TOOL
@ SKILL_TOOL
Allows the use of a skill.
Definition: object.h:194
object_get_value
sstring object_get_value(const object *op, const char *const key)
Get an extra value by key.
Definition: object.cpp:4331
AP_NO_MERGE
#define AP_NO_MERGE
Don't try to merge object after (un)applying it.
Definition: define.h:565
get_item_from_body_location
static object * get_item_from_body_location(object *start, int loc)
Returns the object that is using body location 'loc'.
Definition: apply.cpp:540
CLEAR_FLAG
#define CLEAR_FLAG(xyz, p)
Definition: define.h:370
ob_apply
method_ret ob_apply(object *op, object *applier, int aflags)
Apply an object by running an event hook or an object method.
Definition: ob_methods.cpp:44
FLAG_STARTEQUIP
#define FLAG_STARTEQUIP
Object was given to player at start.
Definition: define.h:255
MAP_HEIGHT
#define MAP_HEIGHT(m)
Map height.
Definition: map.h:78
cast_wonder
int cast_wonder(object *op, object *caster, int dir, object *spell_ob)
wonder is really just a spell that will likely cast another spell.
Definition: spell_effect.cpp:968
CAN_APPLY_UNAPPLY
#define CAN_APPLY_UNAPPLY
Definition: define.h:617
MSG_TYPE_APPLY_FAILURE
#define MSG_TYPE_APPLY_FAILURE
Apply OK, but no/bad result.
Definition: newclient.h:608
apply_auto_fix
void apply_auto_fix(mapstruct *m)
Go through the entire map (only the first time when an original map is loaded) and performs special a...
Definition: apply.cpp:1179
object::body_info
int8_t body_info[NUM_BODY_LOCATIONS]
Body info as loaded from the file.
Definition: object.h:382
UPD_NAME
#define UPD_NAME
Definition: newclient.h:322
object::randomitems
struct treasurelist * randomitems
Items to be generated.
Definition: object.h:395
IS_ARMOR
#define IS_ARMOR(op)
Definition: define.h:166
object::container
object * container
Current container being used.
Definition: object.h:299
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:1818
ALTAR
@ ALTAR
Definition: object.h:127
DOOR
@ DOOR
Definition: object.h:131
transport_can_hold
int transport_can_hold(const object *transport, const object *op, int nrof)
Can transport hold object op? This is a pretty trivial function, but in the future,...
Definition: apply.cpp:54
METHOD_ERROR
#define METHOD_ERROR
Definition: ob_methods.h:17
FLAG_USE_SHIELD
#define FLAG_USE_SHIELD
Can this creature use a shield?
Definition: define.h:224
SCROLL
@ SCROLL
Definition: object.h:226
archetype::name
sstring name
More definite name, like "generate_kobold".
Definition: object.h:484
object::nrof
uint32_t nrof
Number of objects.
Definition: object.h:342
FLAG_WAS_WIZ
#define FLAG_WAS_WIZ
Player was once a wiz.
Definition: define.h:221
object::body_used
int8_t body_used[NUM_BODY_LOCATIONS]
Calculated value based on items equipped.
Definition: object.h:383
MSG_TYPE_APPLY_PROHIBITION
#define MSG_TYPE_APPLY_PROHIBITION
Class/god prohibiiton on obj.
Definition: newclient.h:612
object::stats
living stats
Str, Con, Dex, etc.
Definition: object.h:378
unapply_never
@ unapply_never
Will not unapply objects automatically.
Definition: player.h:77
get_attr_value
int8_t get_attr_value(const living *stats, int attr)
Gets the value of a stat.
Definition: living.cpp:313
FLAG_USE_RING
#define FLAG_USE_RING
(Monster) can use rings, boots, gauntlets, etc
Definition: define.h:284
range_skill
@ range_skill
Use skill.
Definition: player.h:35
apply_update_ranged_skill
static void apply_update_ranged_skill(const object *who, object *op, int aflags)
Updates ranged skill information.
Definition: apply.cpp:1650
tod.h
BOOTS
@ BOOTS
Definition: object.h:217
TRUE
#define TRUE
Definition: compat.h:11
SPELL
@ SPELL
Definition: object.h:219
player_unready_range_ob
void player_unready_range_ob(player *pl, object *ob)
Unready an object for a player.
Definition: player.cpp:4475
SHIELD
@ SHIELD
Definition: object.h:140
MSG_TYPE_APPLY
#define MSG_TYPE_APPLY
Applying objects.
Definition: newclient.h:412
MSG_TYPE_APPLY_ERROR
#define MSG_TYPE_APPLY_ERROR
Definition: newclient.h:605
living.h
SPELLBOOK
@ SPELLBOOK
Definition: object.h:208
NUM_STATS
@ NUM_STATS
Number of statistics.
Definition: living.h:18
FOR_INV_PREPARE
#define FOR_INV_PREPARE(op_, it_)
Constructs a loop iterating over the inventory of an object.
Definition: define.h:654
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:287
FORCE
@ FORCE
Definition: object.h:229
AC_PLAYER_STAT_LIMIT
#define AC_PLAYER_STAT_LIMIT
Limit stats to racial maximum.
Definition: define.h:580
CAN_APPLY_UNAPPLY_CHOICE
#define CAN_APPLY_UNAPPLY_CHOICE
Definition: define.h:619
METHOD_SILENT_ERROR
#define METHOD_SILENT_ERROR
Player was warned she can't use the item for now.
Definition: ob_methods.h:18
Animations::name
sstring name
Name of the animation sequence.
Definition: face.h:26
INS_BELOW_ORIGINATOR
#define INS_BELOW_ORIGINATOR
Insert new object immediately below originator.
Definition: object.h:584
identify
object * identify(object *op)
Identifies an item.
Definition: item.cpp:1446
MSG_TYPE_APPLY_UNAPPLY
#define MSG_TYPE_APPLY_UNAPPLY
Unapply an object.
Definition: newclient.h:606