Crossfire Server, Trunk
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
132  }
133 }
134 
146 int set_object_face_main(object *op) {
147  const Face *newface = op->arch->clone.face;
148  sstring saved = object_get_value(op, "face_closed");
149 
150  if (op->more)
151  set_object_face_main(op->more);
152 
153  if (saved)
154  newface = try_find_face(saved, newface);
155  if (newface && op->face != newface) {
156  op->face = newface;
157  return TRUE;
158  }
159  return FALSE;
160 }
161 
173 static int set_object_face_other(object *op) {
174  sstring custom;
175  const Face *newface = NULL;
176  object *head = op->head ? op->head : op;
177 
178  if (op->more)
179  set_object_face_other(op->more);
180 
181  if (head->face && head->other_arch && head->other_arch->clone.face)
182  newface = head->other_arch->clone.face;
183 
184  if (op->face != op->arch->clone.face) {
185  /* object has a custom face, save it so it gets correctly restored later. */
186  object_set_value(op, "face_closed", op->face->name, 1);
187  }
188 
189  custom = object_get_value(head, "face_opened");
190  if (custom)
191  newface = try_find_face(custom, newface);
192  if (newface && op->face != newface) {
193  op->face = newface;
194  return TRUE;
195  }
196  return FALSE;
197 }
198 
222 int apply_container(object *op, object *sack, int aflags) {
223  char name_sack[MAX_BUF], name_tmp[MAX_BUF];
224  object *tmp = op->container;
225 
226  if (op->type != PLAYER)
227  return 0; /* This might change */
228 
229  if (sack == NULL || sack->type != CONTAINER) {
230  LOG(llevError, "apply_container: '%s' tried to apply %s, which is not a container\n", op->name, sack ? sack->name : "(null)");
231  return 0;
232  }
233 
234  if (sack->head)
235  sack = sack->head;
236 
237  query_name(sack, name_sack, MAX_BUF);
238 
239  if ( aflags == AP_APPLY || aflags == AP_UNAPPLY || aflags == AP_OPEN ) {
240  // What if the container isn't in the player's inventory?
241  if ( sack->env != op ) {
243  "Not in your inventory: %s",
244  name_sack);
245  return 0;
246  }
247  }
248  if ( aflags == AP_APPLY ) {
249  // What if the container is open? Make it just ready!
250  if ( op->container == sack ) {
251  op->container = NULL;
252  if (op->contr != NULL)
253  op->contr->socket->container_position = 0;
254  CLEAR_FLAG(sack, FLAG_APPLIED);
256  "You readied %s.",
257  name_sack);
258  SET_FLAG(sack, FLAG_APPLIED);
259  // FIXME: This is not flipping the face!
260  if (set_object_face_main(sack)) // change image to closed
262  else
263  esrv_update_item(UPD_FLAGS, op, sack);
264  return 0;
265  }
266  // What if the container is already applied? Do nothing!
267  if (QUERY_FLAG(sack, FLAG_APPLIED)) {
269  "Already readied %s.",
270  name_sack);
271  return 0;
272  }
273  // What if the container is closed? Same as no aflags.
274  aflags = AP_NULL;
275  }
276 
277  if ( aflags == AP_OPEN ) {
278  // What if the container is already open?
279  if ( op->container == sack ) {
281  "Already opened %s.",
282  name_sack);
283  return 0;
284  }
285  // Set the container as applied and then proceed as if no special flags
286  SET_FLAG(sack, FLAG_APPLIED);
287  aflags = AP_NULL;
288  }
289 
290  if ( aflags == AP_UNAPPLY ) {
291  // If not open, two cases:
292  if ( op->container != sack ) {
293  if (QUERY_FLAG(sack, FLAG_APPLIED)) {
294  CLEAR_FLAG(sack, FLAG_APPLIED);
296  "You closed %s.",
297  name_sack);
298  esrv_update_item(UPD_FLAGS, op, sack);
299  return 0;
300  }
301  else {
303  "Already closed %s.",
304  name_sack);
305  return 0;
306  }
307  }
308  // open; same as no special flags
309  aflags = AP_NULL;
310  }
311 
312  /* If we have a currently open container, then it needs
313  * to be closed in all cases if we are opening this one up.
314  * We then fall through if appropriate for opening the new
315  * container.
316  */
317  if (op->container && QUERY_FLAG(op->container, FLAG_APPLIED) &&
318  (QUERY_FLAG(sack, FLAG_APPLIED) || sack->env != op) )
319  {
320  tag_t tmp_tag = op->container->count;
321 
322  if (op->container->env != op) { /* if container is on the ground */
323  object *part = op->container->head ? op->container->head : op->container;
324  while (part) {
325  part->move_off = 0;
326  part = part->more;
327  }
328  }
329 
330  /* Query name before the close event, as the container could be destroyed. */
331  query_name(op->container, name_tmp, MAX_BUF);
332 
334  return 1;
335 
338  "You close %s.",
339  name_tmp);
340 
341  op->container = NULL;
342  if (op->contr != NULL)
343  op->contr->socket->container_position = 0;
344 
345  /* The container may have been destroyed by the event handler. */
346  if (!object_was_destroyed(tmp, tmp_tag)) {
350  else
352  }
353  if (tmp == sack)
354  return 1;
355  }
356 
357  /* If the player is trying to open it (which he must be doing
358  * if we got here), and it is locked, check to see if player
359  * has the equipment to open it.
360  */
361 
362  if (sack->slaying) { /* it's locked */
363  tmp = find_key(op, op, sack);
364  if (tmp) {
365  query_name(tmp, name_tmp, MAX_BUF);
368  "You unlock %s with %s.",
369  name_sack, name_tmp);
370  } else {
373  "You don't have the key to unlock %s.",
374  name_sack);
375  return 0;
376  }
377  }
378 
379  /* By the time we get here, we have made sure any other container
380  * has been closed and if this is a locked container, the player
381  * has the key to open it.
382  */
383 
384  /* There are really two cases - the sack is either on the ground,
385  * or the sack is part of the player's inventory. If on the ground,
386  * we assume that the player is opening it, since if it was being
387  * closed, that would have been taken care of above.
388  */
389 
390 
391  if (sack->env != op) {
392  /* Hypothetical case - the player is trying to open a sack
393  * that belongs to someone else. This normally should not
394  * happen, but a misbehaving client/player could
395  * try to do it, so let's handle it gracefully.
396  */
397  if (sack->env) {
399  "You can't open %s",
400  name_sack);
401  return 0;
402  }
403 
404  if (sack->nrof > 1) {
405  object *left = object_split(sack, sack->nrof-1, NULL, 0);
406 
407  object_insert_in_map_at(left, sack->map, NULL, INS_NO_MERGE, sack->x, sack->y);
408  /* recompute the name so it's nice */
409  query_name(sack, name_sack, MAX_BUF);
410  }
411 
412  /* set it so when the player walks off, we can unapply the sack */
413  {
414  object *part = sack->head ? sack->head : sack;
415  while (part) {
416  part->move_off = MOVE_ALL;
417  part = part->more;
418  }
419  }
420 
421  CLEAR_FLAG(sack, FLAG_APPLIED);
423  "You open %s.",
424  name_sack);
425  SET_FLAG(sack, FLAG_APPLIED);
426  op->container = sack;
427  if (op->contr != NULL)
428  op->contr->socket->container_position = 0;
429 
430  if (set_object_face_other(sack))
432  else
433  esrv_update_item(UPD_FLAGS, op, sack);
434  esrv_send_inventory(op, sack);
435  } else { /* sack is in players inventory */
436  if (QUERY_FLAG(sack, FLAG_APPLIED)) { /* readied sack becoming open */
437  CLEAR_FLAG(sack, FLAG_APPLIED);
439  "You open %s.",
440  name_sack);
441  SET_FLAG(sack, FLAG_APPLIED);
442  op->container = sack;
443  if (op->contr != NULL)
444  op->contr->socket->container_position = 0;
445 
446  if (set_object_face_other(sack))
448  else
449  esrv_update_item(UPD_FLAGS, op, sack);
450  esrv_send_inventory(op, sack);
451  } else {
452  object *left = NULL;
453 
454  if (sack->nrof > 1)
455  left = object_split(sack, sack->nrof-1, NULL, 1);
456 
457  CLEAR_FLAG(sack, FLAG_APPLIED);
459  "You readied %s.",
460  name_sack);
461  SET_FLAG(sack, FLAG_APPLIED);
462  esrv_update_item(UPD_FLAGS, op, sack);
463 
464  if (left) {
465  object_insert_in_ob(left, sack->env);
466  esrv_send_item(op, left);
467  }
468  }
469  }
470  return 1;
471 }
472 
484 void do_learn_spell(object *op, object *spell, int special_prayer) {
485  object *tmp;
486 
487  if (op->type != PLAYER) {
488  LOG(llevError, "BUG: do_learn_spell(): not a player\n");
489  return;
490  }
491 
492  /* Upgrade special prayers to normal prayers */
493  tmp = check_spell_known(op, spell->name);
494  if (tmp != NULL) {
495  if (special_prayer && !QUERY_FLAG(tmp, FLAG_STARTEQUIP)) {
496  LOG(llevError, "BUG: do_learn_spell(): spell already known, but not marked as startequip\n");
497  return;
498  }
499  return;
500  }
501 
502  play_sound_player_only(op->contr, SOUND_TYPE_SPELL, spell, 0, "learn");
503  tmp = object_new();
504  object_copy(spell, tmp);
506 
507  if (special_prayer)
509 
511  "Type 'bind cast %s to store the spell in a key.",
512  spell->name);
513 
514  esrv_add_spells(op->contr, tmp);
515 }
516 
525 void do_forget_spell(object *op, const char *spell) {
526  object *spob;
527 
528  if (op->type != PLAYER) {
529  LOG(llevError, "BUG: do_forget_spell(): not a player\n");
530  return;
531  }
532  spob = check_spell_known(op, spell);
533  if (spob == NULL) {
534  LOG(llevError, "BUG: do_forget_spell(): spell not known\n");
535  return;
536  }
537 
539  "You lose knowledge of %s.",
540  spell);
541  player_unready_range_ob(op->contr, spob);
542  esrv_remove_spell(op->contr, spob);
543  object_remove(spob);
544  object_free(spob, 0);
545 }
546 
557 static int apply_check_race_restrictions(object *who, object *item) {
558  char buf[MAX_BUF];
559  sstring restriction;
560 
561  if (who->type != PLAYER || QUERY_FLAG(who, FLAG_WIZ))
562  return 1;
563 
564  restriction = object_get_value(item, "race_restriction");
565  if (!restriction)
566  return 1;
567 
568  snprintf(buf, sizeof(buf), ":%s:", who->race);
569  buf[sizeof(buf)-1] = '\0';
570 
571  if (strstr(restriction, buf) != NULL)
572  return 1;
573 
574  query_name(item, buf, sizeof(buf));
575  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);
576 
577  return 0;
578 }
579 
597 int apply_manual(object *op, object *tmp, int aflag) {
598  tmp = HEAD(tmp);
599 
601  if (op->type == PLAYER) {
603  "You should pay for it first.");
604  return METHOD_SILENT_ERROR;
605  }
606  return 0; /* monsters just skip unpaid items */
607  }
608 
610  return METHOD_SILENT_ERROR;
611 
612  if (op->contr)
613  play_sound_player_only(op->contr, SOUND_TYPE_ITEM, tmp, 0, "apply");
614 
615  return ob_apply(tmp, op, aflag);
616 }
617 
637 int apply_by_living(object *pl, object *op, int aflag, int quiet) {
638  int tmp;
639 
640  if (op->env == NULL && (pl->move_type&MOVE_FLYING)) {
641  /* player is flying and applying object not in inventory */
642  if (!QUERY_FLAG(pl, FLAG_WIZ) && !(op->move_type&MOVE_FLYING)) {
644  "But you are floating high above the ground!");
645  return 0;
646  }
647  }
648 
649  /* Check for PLAYER to avoid a DM to disappear in a puff of smoke if
650  * applied.
651  */
652  if (op->type != PLAYER
654  && !QUERY_FLAG(pl, FLAG_WAS_WIZ)) {
655  play_sound_map(SOUND_TYPE_ITEM, op, 0, "evaporate");
657  "The object disappears in a puff of smoke!");
659  "It must have been an illusion.");
660  object_remove(op);
661  object_free(op, 0);
662  return 1;
663  }
664 
665  tmp = apply_manual(pl, op, aflag);
666  if (!quiet) {
667  if (tmp == METHOD_UNHANDLED) {
668  char name[MAX_BUF];
669 
672  "I don't know how to apply the %s.",
673  name);
674  } else if (tmp == METHOD_ERROR)
676  "You must get it first!\n");
677  else if (tmp == METHOD_SILENT_ERROR)
678  return tmp;
679  }
680  if (tmp == METHOD_OK) {
681  if (op->anim_suffix != NULL)
682  apply_anim_suffix(pl, op->anim_suffix);
683  }
684  return tmp;
685 }
686 
695 void apply_by_living_below(object *pl) {
696  object *tmp;
697  int floors;
698 
699  if (pl->contr->transport && pl->contr->transport->type == TRANSPORT) {
700  ob_apply(pl->contr->transport, pl, 0);
701  return;
702  }
703 
704  /* If using a container, set the starting item to be the top
705  * item in the container. Otherwise, use the map.
706  */
707  tmp = pl->container != NULL ? pl->container->inv : pl->below;
708 
709  /* This is perhaps more complicated. However, I want to make sure that
710  * we don't use a corrupt pointer for the next object, so we get the
711  * next object in the stack before applying. This is can only be a
712  * problem if apply_by_living() has a bug in that it uses the object but
713  * does not return a proper value.
714  */
715  floors = 0;
718  floors++;
719  else if (floors > 0)
720  return; /* process only floor objects after first floor object */
721 
722  /* If it is visible, player can apply it. If it is applied by
723  * person moving on it, also activate. Added code to make it
724  * so that at least one of players movement types be that which
725  * the item needs.
726  */
727  if (!tmp->invisible || (tmp->move_on&pl->move_type)) {
728  if (apply_by_living(pl, tmp, 0, 1) == METHOD_OK)
729  return;
730  }
731  if (floors >= 2)
732  return; /* process at most two floor objects */
734 }
735 
751 static int unapply_special(object *who, object *op, int aflags) {
752  char name[MAX_BUF];
753 
754  if (op->type != LAMP)
757  switch (op->type) {
758  case WEAPON:
759  if (!(aflags&AP_NOPRINT))
761  "You unwield %s.",
762  name);
763  (void)change_abil(who, op);
765  who->current_weapon = NULL;
766  clear_skill(who);
767  break;
768 
769  case SKILL: /* allows objects to impart skills */
770  case SKILL_TOOL:
771  if (op != who->chosen_skill)
772  LOG(llevError, "BUG: unapply_special(): applied skill is not a chosen skill\n");
773  if (who->type == PLAYER) {
774  if (who->contr->shoottype == range_skill)
775  who->contr->shoottype = range_none;
776  if (!op->invisible) {
777  if (!(aflags&AP_NOPRINT))
779  "You stop using the %s.",
780  name);
781  } else {
782  if (!(aflags&AP_NOPRINT))
784  "You can no longer use the skill: %s.",
785  op->skill);
786  }
787  }
788  (void)change_abil(who, op);
789  who->chosen_skill = NULL;
791  break;
792 
793  case ARMOUR:
794  case HELMET:
795  case SHIELD:
796  case RING:
797  case BOOTS:
798  case GLOVES:
799  case AMULET:
800  case GIRDLE:
801  case BRACERS:
802  case CLOAK:
803  if (!(aflags&AP_NOPRINT))
805  "You unwear %s.",
806  name);
807  (void)change_abil(who, op);
808  break;
809 
810  case BOW:
811  case WAND:
812  case ROD:
813  clear_skill(who);
814  if (!(aflags&AP_NOPRINT))
816  "You unready %s.",
817  name);
818  if (who->type == PLAYER)
819  who->contr->shoottype = range_none;
820  else if (op->type == BOW)
822  else
824  break;
825 
826  case BUILDER:
827  if (!(aflags&AP_NOPRINT))
829  "You unready %s.",
830  name);
831  who->contr->shoottype = range_none;
832  who->contr->ranges[range_builder] = NULL;
833  break;
834 
835  default:
836  if (!(aflags&AP_NOPRINT))
838  "You unapply %s.",
839  name);
840  break;
841  }
842 
843  fix_object(who);
844 
845  if (!(aflags&AP_NO_MERGE)) {
846  object *tmp;
847 
848  tmp = object_merge(op, NULL);
849  if (who->type == PLAYER) {
850  if (tmp) { /* it was merged */
851  op = tmp;
852  }
854  }
855  }
856  return 0;
857 }
858 
878 static object *get_item_from_body_location(object *start, int loc) {
879  object *tmp;
880 
881  if (!start)
882  return NULL;
883 
884  tmp = start;
887  && tmp->body_info[loc]
888  && (!tmp->invisible || tmp->type == SKILL))
889  return tmp;
891  return NULL;
892 }
893 
915 static int unapply_for_ob(object *who, object *op, int aflags) {
916  int i;
917  object *tmp = NULL, *last;
918  char name[MAX_BUF];
919 
920  /* If we are applying a shield or weapon, unapply any equipped shield
921  * or weapons first - only allowed to use one weapon/shield at a time.
922  */
923  if (op->type == WEAPON || op->type == SHIELD) {
925  if (QUERY_FLAG(tmp, FLAG_APPLIED) && tmp->type == op->type) {
926  if (!(aflags&AP_IGNORE_CURSE)
927  && !(aflags&AP_PRINT)
929  /* In this case, we want to try and remove a
930  * cursed item. While we know it won't work, we
931  * want unapply_special to at least generate the
932  * message.
933  */
934  if (!(aflags&AP_NOPRINT)) {
937  "No matter how hard you try, you just can't remove %s.",
938  name);
939  }
940  return 1;
941  }
942 
943  if (aflags&AP_PRINT) {
946  name);
947  } else
948  unapply_special(who, tmp, aflags);
949  }
950  } FOR_INV_FINISH();
951  }
952 
953  for (i = 0; i < NUM_BODY_LOCATIONS; i++) {
954  /* this used up a slot that we need to free */
955  if (op->body_info[i]) {
956  last = who->inv;
957 
958  /* We do a while loop - may need to remove several items
959  * in order to free up enough slots.
960  */
961  while (who->body_used[i]+op->body_info[i] < 0) {
962  tmp = get_item_from_body_location(last, i);
963  if (!tmp)
964  return 1;
965 
966  /* If just printing, we don't care about cursed status */
967  if ((aflags&AP_IGNORE_CURSE)
968  || (aflags&AP_PRINT)
970  if (aflags&AP_PRINT) {
973  name);
974  } else
975  unapply_special(who, tmp, aflags);
976  } else {
977  /* Cursed item that we can't unequip - tell the player.
978  * Note this could be annoying if this is just one of a
979  * few, so it may not be critical (eg, putting on a
980  * ring and you have one cursed ring.)
981  */
982  if (!(aflags&AP_NOPRINT)) {
985  "The %s just won't come off",
986  name);
987  }
988  }
989  last = tmp->below;
990  }
991  /* if we got here, this slot is freed up - otherwise, if it
992  * wasn't freed up, the return in the !tmp would have
993  * kicked in.
994  */
995  } /* if op is using this body location */
996  } /* for body locations */
997  return 0;
998 }
999 
1016 int apply_can_apply_object(const object *who, const object *op) {
1017  int i, retval = 0;
1018  object *tmp = NULL, *ws = NULL;
1019 
1020  /* Players have 2 'arm's, so they could in theory equip 2 shields or
1021  * 2 weapons, but we don't want to let them do that. So if they are
1022  * trying to equip a weapon or shield, see if they already have one
1023  * in place and store that way.
1024  */
1025  if (op->type == WEAPON || op->type == SHIELD) {
1027  if (tmp != NULL) {
1028  retval = CAN_APPLY_UNAPPLY;
1029  ws = tmp;
1030  }
1031  }
1032 
1033  for (i = 0; i < NUM_BODY_LOCATIONS; i++) {
1034  if (op->body_info[i]) {
1035  /* Item uses more slots than we have */
1036  if (FABS(op->body_info[i]) > who->body_info[i]) {
1037  /* Could return now for efficiently - rest of info
1038  * below isn't really needed.
1039  */
1040  retval |= CAN_APPLY_NEVER;
1041  } else if (who->body_used[i]+op->body_info[i] < 0) {
1042  /* in this case, equipping this would use more free
1043  * spots than we have.
1044  */
1045  object *tmp1;
1046 
1047  /* if we have an applied weapon/shield, and unapply
1048  * it would free enough slots to equip the new item,
1049  * then just set this can continue. We don't care
1050  * about the logic below - if you have shield equipped
1051  * and try to equip another shield, there is only one
1052  * choice. However, the check for the number of body
1053  * locations does take into the account cases where what
1054  * is being applied may be two handed for example.
1055  */
1056  if (ws) {
1057  if (who->body_used[i]-ws->body_info[i]+op->body_info[i] >= 0) {
1058  retval |= CAN_APPLY_UNAPPLY;
1059  continue;
1060  }
1061  }
1062 
1063  tmp1 = get_item_from_body_location(who->inv, i);
1064  if (!tmp1)
1065  retval |= CAN_APPLY_NEVER;
1066  else {
1067  /* need to unapply something. However, if this
1068  * something is different than we had found before,
1069  * it means they need to apply multiple objects
1070  */
1071  retval |= CAN_APPLY_UNAPPLY;
1072  if (!tmp)
1073  tmp = tmp1;
1074  else if (tmp != tmp1)
1075  retval |= CAN_APPLY_UNAPPLY_MULT;
1076  /* This object isn't using up all the slots, so
1077  * there must be another. If so, and if the new
1078  * item doesn't need all the slots, the player
1079  * then has a choice.
1080  */
1081  if (who->body_used[i]-tmp1->body_info[i] != who->body_info[i]
1082  && FABS(op->body_info[i]) < who->body_info[i])
1083  retval |= CAN_APPLY_UNAPPLY_CHOICE;
1084 
1085  /* Does unequipping 'tmp1' free up enough slots
1086  * for this to be equipped? If not, there must
1087  * be something else to unapply.
1088  */
1089  if (who->body_used[i]+op->body_info[i]-tmp1->body_info[i] < 0)
1090  retval |= CAN_APPLY_UNAPPLY_MULT;
1091  }
1092  } /* if not enough free slots */
1093  } /* if this object uses location i */
1094  } /* for i -> num_body_locations loop */
1095 
1096  /* Do checks for can_use_weapon/shield/armour. */
1098  retval |= CAN_APPLY_RESTRICTION;
1100  retval |= CAN_APPLY_RESTRICTION;
1102  retval |= CAN_APPLY_RESTRICTION;
1103 
1104  if (who->type != PLAYER) {
1105  if ((op->type == WAND || op->type == ROD)
1107  retval |= CAN_APPLY_RESTRICTION;
1108  if (op->type == BOW && !QUERY_FLAG(who, FLAG_USE_BOW))
1109  retval |= CAN_APPLY_RESTRICTION;
1110  if (op->type == RING && !QUERY_FLAG(who, FLAG_USE_RING))
1111  retval |= CAN_APPLY_RESTRICTION;
1112  }
1113  return retval;
1114 }
1115 
1131 int apply_check_weapon_power(const object *who, int improves) {
1132  return (who->level/5)+5 >= improves;
1133 }
1134 
1156 int apply_special(object *who, object *op, int aflags) {
1157  int basic_flag = aflags&AP_BASIC_FLAGS;
1158  object *tmp, *skop;
1159  char name_op[MAX_BUF];
1160 
1161  if (who == NULL) {
1162  LOG(llevError, "apply_special() from object without environment.\n");
1163  return 1;
1164  }
1165 
1166  if (op->env != who)
1167  return 1; /* op is not in inventory */
1168 
1169  /* trying to unequip op */
1170  if (QUERY_FLAG(op, FLAG_APPLIED)) {
1171  /* always apply, so no reason to unapply */
1172  if (basic_flag == AP_APPLY)
1173  return 0;
1174 
1175  if (!(aflags&AP_IGNORE_CURSE)
1177  if (!(aflags&AP_NOPRINT)) {
1178  query_name(op, name_op, MAX_BUF);
1180  "No matter how hard you try, you just can't remove %s.",
1181  name_op);
1182  }
1183  return 1;
1184  }
1185  return unapply_special(who, op, aflags);
1186  }
1187 
1188  if (basic_flag == AP_UNAPPLY)
1189  return 0;
1190 
1191  if (!apply_check_apply_restrictions(who, op, aflags))
1192  return 1;
1193 
1194  if (op->skill && op->type != SKILL && op->type != SKILL_TOOL) {
1195  skop = find_skill_by_name(who, op->skill);
1196  if (!skop) {
1197  if (!(aflags&AP_NOPRINT))
1199  "You need the %s skill to use this item!",
1200  op->skill);
1201  if (who->type == PLAYER)
1202  return 1;
1203 
1204  /* monsters do not care about missing skills */
1205  } else
1206  /* While experience will be credited properly, we want to
1207  * change the skill so that the dam and wc get updated
1208  */
1209  change_skill(who, skop, (aflags&AP_NOPRINT));
1210  } else
1211  skop = NULL;
1212 
1213  if (!apply_check_item_power(who, op, aflags))
1214  return 1;
1215 
1217  return 1;
1218 
1219  /* Ok. We are now at the state where we can apply the new object.
1220  * Note that we don't have the checks for can_use_...
1221  * below - that is already taken care of by apply_can_apply_object().
1222  */
1223 
1224  tmp = op->nrof <= 1 ? NULL : object_split(op, op->nrof-1, NULL, 0);
1225 
1226  switch (op->type) {
1227  case WEAPON:
1228  if (!apply_check_weapon_power(who, op->last_eat)) {
1229  if (!(aflags&AP_NOPRINT))
1231  "That weapon is too powerful for you to use. It would consume your soul!");
1232  if (tmp != NULL)
1234  return 1;
1235  }
1236 
1237  if (!apply_check_owner(who, op, aflags)) {
1238  if (tmp != NULL)
1240  return 1;
1241  }
1242 
1244 
1245  if (skop)
1246  change_skill(who, skop, 1);
1248 
1249  if (!(aflags&AP_NOPRINT)) {
1250  query_name(op, name_op, MAX_BUF);
1252  "You wield %s.",
1253  name_op);
1254  }
1255 
1256  (void)change_abil(who, op);
1257  break;
1258 
1259  case ARMOUR:
1260  case HELMET:
1261  case SHIELD:
1262  case BOOTS:
1263  case GLOVES:
1264  case GIRDLE:
1265  case BRACERS:
1266  case CLOAK:
1267  case RING:
1268  case AMULET:
1270  if (!(aflags&AP_NOPRINT)) {
1271  query_name(op, name_op, MAX_BUF);
1273  "You wear %s.",
1274  name_op);
1275  }
1276  (void)change_abil(who, op);
1277  break;
1278 
1279  /* this part is needed for skill-tools */
1280  case SKILL:
1281  case SKILL_TOOL:
1282  if (who->chosen_skill) {
1283  LOG(llevError, "BUG: apply_special(): can't apply two skills\n");
1284  return 1;
1285  }
1286 
1287  apply_update_ranged_skill(who, op, aflags);
1289  (void)change_abil(who, op);
1290  who->chosen_skill = op;
1292  break;
1293 
1294  case BOW:
1295  if (!apply_check_weapon_power(who, op->last_eat)) {
1296  if (!(aflags&AP_NOPRINT))
1298  "That weapon is too powerful for you to use. It would consume your soul!");
1299  if (tmp != NULL)
1301  return 1;
1302  }
1303 
1304  if (!apply_check_owner(who, op, aflags)) {
1305  if (tmp != NULL)
1307  return 1;
1308  }
1309  /*FALLTHROUGH*/
1310  case WAND:
1311  case ROD:
1312  /* check for skill, alter player status */
1314  if (skop)
1315  change_skill(who, skop, 0);
1316  if (!(aflags&AP_NOPRINT)) {
1317  query_name(op, name_op, MAX_BUF);
1319  "You ready %s.",
1320  name_op);
1321  }
1322  if (who->type == PLAYER) {
1323  if (op->type == BOW) {
1324  (void)change_abil(who, op);
1325  if (!(aflags&AP_NOPRINT)) {
1326  query_name(op, name_op, MAX_BUF);
1328  "You will now fire %s with %s.",
1329  op->race ? op->race : "nothing",
1330  name_op);
1331  }
1332  who->contr->shoottype = range_bow;
1333  } else
1334  who->contr->shoottype = range_misc;
1335  } else {
1336  if (op->type == BOW)
1338  else
1340  }
1341  break;
1342 
1343  case BUILDER:
1344  if (who->contr->ranges[range_builder])
1345  unapply_special(who, who->contr->ranges[range_builder], 0);
1346  who->contr->shoottype = range_builder;
1347  who->contr->ranges[range_builder] = op;
1348  if (!(aflags&AP_NOPRINT)) {
1349  query_name(op, name_op, MAX_BUF);
1351  "You ready your %s.",
1352  name_op);
1353  }
1354  break;
1355 
1356  default:
1357  query_name(op, name_op, MAX_BUF);
1359  "You apply %s.",
1360  name_op);
1361  break;
1362  } /* end of switch op->type */
1363 
1365 
1366  if (tmp != NULL)
1368 
1369  fix_object(who);
1370 
1371  /* We exclude spell casting objects. The fire code will set the
1372  * been applied flag when they are used - until that point,
1373  * you don't know anything about them.
1374  */
1375  if (who->type == PLAYER && op->type != WAND && op->type != ROD)
1377 
1379  if (who->type == PLAYER) {
1381  "Oops, it feels deadly cold!");
1383  }
1384  }
1385  if (who->type == PLAYER)
1387  return 0;
1388 }
1389 
1400 int apply_auto(object *op) {
1401  object *tmp;
1402 
1403  switch (op->type) {
1404  case SHOP_FLOOR:
1405  if (!HAS_RANDOM_ITEMS(op))
1406  return 0;
1407  do {
1408  int i;
1409 
1410  i = 10; /* let's give it 10 tries */
1411  while ((tmp = generate_treasure(op->randomitems, op->stats.exp ? (int)op->stats.exp : MAX(op->map->difficulty, 5))) == NULL
1412  && --i)
1413  ;
1414  if (tmp == NULL)
1415  return 0;
1418  tmp = NULL;
1419  }
1420  } while (!tmp);
1423  if (is_magical(tmp)) {
1425  }
1426  object_insert_in_map_at(tmp, op->map, NULL, 0, op->x, op->y);
1428  identify(tmp);
1429  return 1;
1430  break;
1431 
1432  case TREASURE:
1434  return 0;
1435  while (op->stats.hp-- > 0)
1436  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);
1437 
1438  /* If we generated an object and put it in this object's
1439  * inventory, move it to the parent object as the current
1440  * object is about to disappear. An example of this item
1441  * is the random_ *stuff that is put inside other objects.
1442  */
1443  FOR_INV_PREPARE(op, tmp) {
1444  object_remove(tmp);
1445  if (op->env)
1446  object_insert_in_ob(tmp, op->env);
1447  else
1449  } FOR_INV_FINISH();
1450  object_remove(op);
1452  break;
1453  }
1454  return 0;
1455 }
1456 
1469 static void auto_apply_fix_inventory(mapstruct *m, object *tmp)
1470 {
1471  if (!tmp->inv)
1472  return;
1473  FOR_INV_PREPARE(tmp, invtmp) {
1474  if (invtmp->inv)
1475  auto_apply_fix_inventory(m,invtmp); // Recurse for containers in objects
1476  if (QUERY_FLAG(invtmp, FLAG_AUTO_APPLY))
1477  apply_auto(invtmp);
1478  else if (invtmp->type == TREASURE && HAS_RANDOM_ITEMS(invtmp)) {
1479  while (invtmp->stats.hp-- > 0)
1480  create_treasure(invtmp->randomitems, invtmp, 0, m->difficulty, 0);
1481  invtmp->randomitems = NULL;
1482  } else if (invtmp && invtmp->arch
1483  && invtmp->type != TREASURE
1484  && invtmp->type != SPELL
1485  && invtmp->type != CLASS
1486  && HAS_RANDOM_ITEMS(invtmp)) {
1487  create_treasure(invtmp->randomitems, invtmp, 0, m->difficulty, 0);
1488  /* Need to clear this so that we never try to
1489  * create treasure again for this object
1490  */
1491  invtmp->randomitems = NULL;
1492  }
1493  } FOR_INV_FINISH();
1494  /* This is really temporary - the code at the
1495  * bottom will also set randomitems to null.
1496  * The problem is there are bunches of maps/players
1497  * already out there with items that have spells
1498  * which haven't had the randomitems set
1499  * to null yet.
1500  * MSW 2004-05-13
1501  *
1502  * And if it's a spellbook, it's better to set
1503  * randomitems to NULL too, else you get two spells
1504  * in the book ^_-
1505  * Ryo 2004-08-16
1506  */
1507  if (tmp->type == WAND
1508  || tmp->type == ROD
1509  || tmp->type == SCROLL
1510  || tmp->type == FIREWALL
1511  || tmp->type == POTION
1512  || tmp->type == ALTAR
1513  || tmp->type == SPELLBOOK)
1514  tmp->randomitems = NULL;
1515 }
1516 
1528  int x, y;
1529 
1530  if (m == NULL)
1531  return;
1532 
1533  for (x = 0; x < MAP_WIDTH(m); x++)
1534  for (y = 0; y < MAP_HEIGHT(m); y++)
1535  FOR_MAP_PREPARE(m, x, y, tmp) {
1536  if (tmp->inv) {
1538  }
1540  apply_auto(tmp);
1541  else if ((tmp->type == TREASURE || tmp->type == CONTAINER)
1542  && HAS_RANDOM_ITEMS(tmp)) {
1543  while (tmp->stats.hp-- > 0)
1544  create_treasure(tmp->randomitems, tmp, 0, m->difficulty, 0);
1545  tmp->randomitems = NULL;
1546  } else if (tmp->type == TIMED_GATE) {
1547  object *head = HEAD(tmp);
1548 
1549  if (QUERY_FLAG(head, FLAG_IS_LINKED)) {
1550  tmp->speed = 0;
1552  }
1553  }
1554  /* This function can be called every time a map is loaded,
1555  * even when swapping back in. As such, we don't want to
1556  * create the treasure over and over again, so after we
1557  * generate the treasure, blank out randomitems so if it
1558  * is swapped in again, it won't make anything. This is a
1559  * problem for the above objects, because they have
1560  * counters which say how many times to make the treasure.
1561  */
1562  else if (tmp
1563  && tmp->arch
1564  && tmp->type != PLAYER
1565  && tmp->type != TREASURE
1566  && tmp->type != SPELL
1567  && tmp->type != PLAYER_CHANGER
1568  && tmp->type != CLASS
1569  && HAS_RANDOM_ITEMS(tmp)) {
1570  create_treasure(tmp->randomitems, tmp, 0, m->difficulty, 0);
1571  tmp->randomitems = NULL;
1572  }
1573 
1574  if (QUERY_FLAG(tmp, FLAG_MONSTER))
1576  } FOR_MAP_FINISH();
1577 
1578  for (x = 0; x < MAP_WIDTH(m); x++)
1579  for (y = 0; y < MAP_HEIGHT(m); y++)
1580  FOR_MAP_PREPARE(m, x, y, tmp) {
1581  if (tmp->above
1582  && (tmp->type == TRIGGER_BUTTON || tmp->type == TRIGGER_PEDESTAL))
1583  check_trigger(tmp, tmp->above);
1584  } FOR_MAP_FINISH();
1585 }
1586 
1601 void scroll_failure(object *op, int failure, int power) {
1602  if (abs(failure/4) > power)
1603  power = abs(failure/4); /* set minimum effect */
1604 
1605  if (failure <= -1 && failure > -15) {/* wonder */
1606  object *tmp;
1607 
1609  "Your spell warps!");
1611  cast_wonder(op, op, 0, tmp);
1612  if (op->stats.sp < 0)
1613  /* For some reason the sp can become negative here. */
1614  op->stats.sp = 0;
1616  return;
1617  }
1618 
1620  if (failure <= -35 && failure > -60) { /* confusion */
1622  "The magic recoils on you!");
1623  confuse_living(op, op, power);
1624  return;
1625  }
1626 
1627  if (failure <= -60 && failure > -70) {/* paralysis */
1629  "The magic recoils and paralyzes you!");
1630  paralyze_living(op, power);
1631  return;
1632  }
1633 
1634  if (failure <= -70 && failure > -80) {/* blind */
1636  "The magic recoils on you!");
1637  blind_living(op, op, power);
1638  return;
1639  }
1640 
1641  if (failure <= -80) {/* blast the immediate area */
1642  object *tmp;
1643 
1645  cast_magic_storm(op, tmp, power);
1647  "You unleash uncontrolled mana!");
1648  return;
1649  }
1650  }
1651  /* Either no spell failure on this server, or wrong values,
1652  * in any case let's punish.
1653  */
1655  "Your mana is drained!");
1656  op->stats.sp -= random_roll(0, power-1, op, PREFER_LOW);
1657  if (op->stats.sp < 0)
1658  op->stats.sp = 0;
1659 }
1660 
1672 void apply_changes_to_player(object *pl, object *change, int limit_stats) {
1673  int i, j;
1674  int excess_stat = 0; /* if the stat goes over the maximum
1675  * for the race, put the excess stat some
1676  * where else.
1677  */
1678 
1679  if (change->type != CLASS) return;
1680 
1681  /* the following code assigns stats up to the stat max
1682  * for the race, and if the stat max is exceeded,
1683  * tries to randomly reassign the excess stat
1684  */
1685  if (! (limit_stats & AC_PLAYER_STAT_NO_CHANGE)) {
1686  for (i = 0; i < NUM_STATS; i++) {
1687  int8_t stat = get_attr_value(&pl->contr->orig_stats, i);
1688  int race_bonus = get_attr_value(&pl->arch->clone.stats, i);
1689 
1690  stat += get_attr_value(&change->stats, i);
1691  if (limit_stats & AC_PLAYER_STAT_LIMIT) {
1692  if (stat > 20+race_bonus) {
1693  excess_stat++;
1694  stat = 20+race_bonus;
1695  } else if (stat < 1) {
1696  /* I didn't see any code here before to make sure minimum
1697  * stats were enforced - maybe it was just dumb
1698  * luck that one would not have a stat low enough that then
1699  * has a stat penalty for class that would bring it negative?
1700  * I imagine a negative stat would crash the server pretty
1701  * quickly - MSW, Sept 2010
1702  */
1703  excess_stat += stat;
1704  stat = 1;
1705  }
1706  }
1707  set_attr_value(&pl->contr->orig_stats, i, stat);
1708  }
1709 
1710  /* Maybe we should randomly deduct stats in this case?
1711  * It's will go away sometime soon in any case.
1712  */
1713  if (excess_stat < 0) excess_stat = 0;
1714 
1715  /* We don't put an explicit check for limit_stats here -
1716  * excess stat will never be 0 if limit_stats is not
1717  * true.
1718  */
1719  for (j = 0; excess_stat > 0 && j < 100; j++) {
1720  /* try 100 times to assign excess stats */
1721  int i = rndm(0, NUM_STATS-1);
1722  int stat = get_attr_value(&pl->contr->orig_stats, i);
1723  int race_bonus = get_attr_value(&pl->arch->clone.stats, i);
1724 
1725  if (i == CHARISMA) {
1726  continue; /* exclude cha from this */
1727  }
1728 
1729  if (stat < 20+race_bonus) {
1730  change_attr_value(&pl->contr->orig_stats, i, 1);
1731  excess_stat--;
1732  }
1733  }
1734  }
1735  /* Done with stat processing */
1736 
1737  /* insert the randomitems from the change's treasurelist into
1738  * the player ref: player.c
1739  */
1740  if (change->randomitems != NULL)
1741  give_initial_items(pl, change->randomitems);
1742 
1743 
1744  /* set up the face, for some races. */
1745 
1746  /* first, look for the force object banning changing the
1747  * face. Certain races never change face with class.
1748  */
1749  int has_noclassfacechange = (object_find_by_name(pl, "NOCLASSFACECHANGE") != NULL);
1750  const Animations *anim = NULL;
1751 
1752  if (change->anim_suffix) {
1753  char buf[MAX_BUF];
1754 
1755  snprintf(buf, MAX_BUF, "%s_%s", pl->animation->name, change->anim_suffix);
1757  if (anim) {
1758  pl->animation = anim;
1759  pl->anim_speed = -1;
1761  animate_object(pl, pl->facing);
1762  }
1763  }
1764  /* Check for anim == -1 so that we can override specific class faces for races.
1765  * This allows us to have custom class faces on the races that lack noclassfacechange
1766  *
1767  * Neila Hawkins 2020-09-08
1768  */
1769  if ((!has_noclassfacechange) && anim == 0) {
1770  pl->animation = GET_ANIM(change);
1771  pl->face = change->face;
1772 
1773  if (QUERY_FLAG(change, FLAG_ANIMATE))
1775  else
1777  }
1778 
1779  /* Hard coding in class name is a horrible idea - lets
1780  * use the supported mechanism for this
1781  */
1782  if (object_present_in_ob_by_name(FORCE, "no weapon force", pl))
1784 
1785 }
1786 
1800 static int apply_check_apply_restrictions(object *who, object *op, int aflags) {
1801  int i;
1802 
1804  if (i == 0)
1805  return 1;
1806 
1807  /* Can't just apply this object. Lets see why not and what to do */
1808 
1809  if (i&CAN_APPLY_NEVER) {
1810  if (!(aflags&AP_NOPRINT)) {
1811  char name_op[MAX_BUF];
1812 
1813  query_name(op, name_op, MAX_BUF);
1815  "You don't have the body to use a %s",
1816  name_op);
1817  }
1818  return 0;
1819  }
1820 
1821  if (i&CAN_APPLY_RESTRICTION) {
1822  if (!(aflags&AP_NOPRINT)) {
1823  char name_op[MAX_BUF];
1824 
1825  query_name(op, name_op, MAX_BUF);
1827  "You have a prohibition against using a %s",
1828  name_op);
1829  }
1830  return 0;
1831  }
1832 
1833  if (who->type != PLAYER) {
1834  /* Some error, so don't try to equip something more */
1835  return !unapply_for_ob(who, op, aflags);
1836  }
1837 
1838  if (who->contr->unapply == unapply_never
1839  || (i&CAN_APPLY_UNAPPLY_CHOICE && who->contr->unapply == unapply_nochoice)) {
1840  if (!(aflags&AP_NOPRINT))
1842  "You need to unapply some item(s):");
1844  return 0;
1845  }
1846 
1847  if (who->contr->unapply == unapply_always
1848  || !(i&CAN_APPLY_UNAPPLY_CHOICE)) {
1849  return !unapply_for_ob(who, op, aflags);
1850  }
1851 
1852  return 1;
1853 }
1854 
1867 static int apply_check_item_power(const object *who, const object *op, int aflags) {
1868  if (who->type != PLAYER)
1869  return 1;
1870 
1871  if (op->item_power == 0
1872  || op->item_power+who->contr->item_power <= settings.item_power_factor*who->level)
1873  return 1;
1874 
1875  if (!(aflags&AP_NOPRINT))
1877  "Equipping that combined with other items would consume your soul!");
1878  return 0;
1879 }
1880 
1895 static int apply_check_personalized_blessings(object *who, const object *op) {
1896  const char *owner;
1897  const char *will;
1898  long item_will;
1899  long margin;
1900  const char *msg;
1901  int random_effect;
1902  int damage_percentile;
1903 
1905  return 1;
1906  }
1907 
1908  owner = object_get_value(op, "item_owner");
1909  if (owner == NULL || strcmp(owner, who->name) == 0)
1910  return 1;
1911 
1912  will = object_get_value(op, "item_willpower");
1913  item_will = will != NULL ? atol(will) : 0;
1914  if (item_will > who->stats.exp) {
1916  "This %s refuses to serve you - it keeps evading your hand !",
1917  op->name);
1918  return 0;
1919  }
1920 
1921  margin = item_will != 0 ? who->stats.exp/item_will : who->stats.exp;
1922  random_effect = random_roll(0, 100, who, 1)-margin*20;
1923  if (random_effect > 80) {
1924  msg = "You don't know why, but you have the feeling that the %s is angry at you !";
1925  damage_percentile = 60;
1926  } else if (random_effect > 60) {
1927  msg = "The %s seems to look at you nastily !";
1928  damage_percentile = 45;
1929  } else if (random_effect > 40) {
1930  msg = "You have the strange feeling that the %s is annoyed...";
1931  damage_percentile = 30;
1932  } else if (random_effect > 20) {
1933  msg = "The %s seems tired, or bored, in a way. Very strange !";
1934  damage_percentile = 15;
1935  } else if (random_effect > 0) {
1936  msg = "You hear the %s sighing !";
1937  damage_percentile = 0;
1938  } else {
1939  msg = NULL;
1940  damage_percentile = 0;
1941  }
1942  if (msg != NULL)
1944  msg, op->name);
1945  if (damage_percentile > 0) {
1946  int weapon_bite = (who->stats.hp*damage_percentile)/100;
1947  if (weapon_bite < 1)
1948  weapon_bite = 1;
1949  who->stats.hp -= weapon_bite;
1951  "You get a nasty bite in the hand !");
1952  }
1953 
1954  return 1;
1955 }
1956 
1971 static int apply_check_owner(const object *who, const object *op, int aflags) {
1972  const char *quotepos;
1973 
1974  if (op->level == 0)
1975  return 1;
1976 
1977  quotepos = strstr(op->name, "'");
1978  if (quotepos == NULL || strncmp(op->name, who->name, quotepos-op->name) == 0)
1979  return 1;
1980 
1981  if (!(aflags&AP_NOPRINT))
1983  "The weapon does not recognize you as its owner.");
1984  return 0;
1985 }
1986 
1997 static void apply_update_ranged_skill(const object *who, object *op, int aflags) {
1998  if (who->type != PLAYER) {
1999  return;
2000  }
2001 
2002  who->contr->shoottype = range_skill;
2003  who->contr->ranges[range_skill] = op;
2004  if (op->invisible) {
2005  if (!(aflags&AP_NOPRINT))
2007  "Readied skill: %s.",
2008  op->skill ? op->skill : op->name);
2009  } else {
2010  if (!(aflags&AP_NOPRINT)) {
2011  char name_op[MAX_BUF];
2012 
2013  query_name(op, name_op, MAX_BUF);
2015  "You ready %s.",
2016  name_op);
2018  "You can now use the skill: %s.",
2019  op->skill);
2020  }
2021  }
2022 }
object_was_destroyed
#define object_was_destroyed(op, old_tag)
Definition: object.h:70
paralyze_living
void paralyze_living(object *op, int dam)
Definition: attack.cpp:2398
CLASS
@ CLASS
Definition: object.h:143
FLAG_USE_BOW
#define FLAG_USE_BOW
Definition: define.h:293
Face
Definition: face.h:14
HAS_RANDOM_ITEMS
#define HAS_RANDOM_ITEMS(op)
Definition: define.h:184
unapply_special
static int unapply_special(object *who, object *op, int aflags)
Definition: apply.cpp:751
PLAYER
@ PLAYER
Definition: object.h:112
global.h
FREE_OBJ_NO_DESTROY_CALLBACK
#define FREE_OBJ_NO_DESTROY_CALLBACK
Definition: object.h:545
UPD_FACE
#define UPD_FACE
Definition: newclient.h:306
settings
struct Settings settings
Definition: init.cpp:139
SOUND_TYPE_ITEM
#define SOUND_TYPE_ITEM
Definition: newclient.h:324
FOR_MAP_FINISH
#define FOR_MAP_FINISH()
Definition: define.h:730
object_find_by_type_applied
object * object_find_by_type_applied(const object *who, int type)
Definition: object.cpp:4079
NUM_BODY_LOCATIONS
#define NUM_BODY_LOCATIONS
Definition: object.h:15
AP_APPLY
#define AP_APPLY
Definition: define.h:574
BOW
@ BOW
Definition: object.h:123
BRACERS
@ BRACERS
Definition: object.h:222
llevError
@ llevError
Definition: logger.h:11
FABS
#define FABS(x)
Definition: define.h:22
MOVE_ALL
#define MOVE_ALL
Definition: define.h:398
AP_NO_MERGE
#define AP_NO_MERGE
Definition: define.h:581
WAND
@ WAND
Definition: object.h:225
range_bow
@ range_bow
Definition: player.h:31
FLAG_USE_RING
#define FLAG_USE_RING
Definition: define.h:297
LOG
void LOG(LogLevel logLevel, const char *format,...)
Definition: logger.cpp:58
SET_FLAG
#define SET_FLAG(xyz, p)
Definition: define.h:224
GLOVES
@ GLOVES
Definition: object.h:218
GIRDLE
@ GIRDLE
Definition: object.h:228
diamondslots.x
x
Definition: diamondslots.py:15
FLAG_STARTEQUIP
#define FLAG_STARTEQUIP
Definition: define.h:268
QUERY_FLAG
#define QUERY_FLAG(xyz, p)
Definition: define.h:226
CAN_APPLY_NEVER
#define CAN_APPLY_NEVER
Definition: define.h:630
TRIGGER_PEDESTAL
@ TRIGGER_PEDESTAL
Definition: object.h:139
apply_special
int apply_special(object *who, object *op, int aflags)
Definition: apply.cpp:1156
confuse_living
void confuse_living(object *op, object *hitter, int dam)
Definition: attack.cpp:2311
clear_skill
void clear_skill(object *who)
Definition: skill_util.cpp:398
apply_check_apply_restrictions
static int apply_check_apply_restrictions(object *who, object *op, int aflags)
Definition: apply.cpp:1800
object_merge
object * object_merge(object *op, object *top)
Definition: object.cpp:2051
FALSE
#define FALSE
Definition: compat.h:14
esrv_send_inventory
void esrv_send_inventory(object *pl, object *op)
Definition: item.cpp:316
apply_check_owner
static int apply_check_owner(const object *who, const object *op, int aflags)
Definition: apply.cpp:1971
apply_check_race_restrictions
static int apply_check_race_restrictions(object *who, object *item)
Definition: apply.cpp:557
set_object_face_other
static int set_object_face_other(object *op)
Definition: apply.cpp:173
UPD_WEIGHT
#define UPD_WEIGHT
Definition: newclient.h:305
SHOP_FLOOR
@ SHOP_FLOOR
Definition: object.h:188
METHOD_OK
#define METHOD_OK
Definition: ob_methods.h:15
CAN_APPLY_RESTRICTION
#define CAN_APPLY_RESTRICTION
Definition: define.h:631
object::x
int16_t x
Definition: object.h:335
ARMOUR
@ ARMOUR
Definition: object.h:125
PREFER_LOW
#define PREFER_LOW
Definition: define.h:564
object::map
struct mapstruct * map
Definition: object.h:305
object::anim_suffix
sstring anim_suffix
Definition: object.h:324
WEAPON
@ WEAPON
Definition: object.h:124
TIMED_GATE
@ TIMED_GATE
Definition: object.h:133
MSG_TYPE_APPLY_CURSED
#define MSG_TYPE_APPLY_CURSED
Definition: newclient.h:594
apply_by_living
int apply_by_living(object *pl, object *op, int aflag, int quiet)
Definition: apply.cpp:637
LOOSE_MANA
#define LOOSE_MANA
Definition: spells.h:162
GT_ONLY_GOOD
@ GT_ONLY_GOOD
Definition: treasure.h:34
range_none
@ range_none
Definition: player.h:30
apply_changes_to_player
void apply_changes_to_player(object *pl, object *change, int limit_stats)
Definition: apply.cpp:1672
unapply_for_ob
static int unapply_for_ob(object *who, object *op, int aflags)
Definition: apply.cpp:915
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
play_sound_player_only
void play_sound_player_only(player *pl, int8_t sound_type, object *emitter, int dir, const char *action)
Definition: sounds.cpp:51
TREASURE
@ TREASURE
Definition: object.h:115
SKILL
@ SKILL
Definition: object.h:148
play_sound_map
void play_sound_map(int8_t sound_type, object *emitter, int dir, const char *action)
Definition: sounds.cpp:113
change_skill
int change_skill(object *who, object *new_skill, int flag)
Definition: skill_util.cpp:359
object_copy
void object_copy(const object *src_ob, object *dest_ob)
Definition: object.cpp:1192
GET_ANIM
#define GET_ANIM(ob)
Definition: global.h:164
fix_object
void fix_object(object *op)
Definition: living.cpp:1125
Ice.tmp
int tmp
Definition: Ice.py:207
FLAG_BLESSED
#define FLAG_BLESSED
Definition: define.h:369
NDI_NAVY
#define NDI_NAVY
Definition: newclient.h:233
TRANSPORT
@ TRANSPORT
Definition: object.h:113
UPD_NROF
#define UPD_NROF
Definition: newclient.h:310
unapply_always
@ unapply_always
Definition: player.h:78
scroll_failure
void scroll_failure(object *op, int failure, int power)
Definition: apply.cpp:1601
rndm
int rndm(int min, int max)
Definition: utils.cpp:162
skills.h
TRIGGER_BUTTON
@ TRIGGER_BUTTON
Definition: object.h:137
esrv_add_spells
void esrv_add_spells(player *pl, object *spell)
Definition: request.cpp:1927
object_get_value
const char * object_get_value(const object *op, const char *const key)
Definition: object.cpp:4342
create_treasure
void create_treasure(treasurelist *t, object *op, int flag, int difficulty, int tries)
Definition: treasure.cpp:263
FLAG_APPLIED
#define FLAG_APPLIED
Definition: define.h:235
events_execute_object_event
int events_execute_object_event(object *op, int eventcode, object *activator, object *third, const char *message, int fix)
Definition: events.cpp:299
apply_check_personalized_blessings
static int apply_check_personalized_blessings(object *who, const object *op)
Definition: apply.cpp:1895
auto_apply_fix_inventory
static void auto_apply_fix_inventory(mapstruct *m, object *tmp)
Definition: apply.cpp:1469
buf
StringBuffer * buf
Definition: readable.cpp:1565
do_learn_spell
void do_learn_spell(object *op, object *spell, int special_prayer)
Definition: apply.cpp:484
object_insert_in_ob
object * object_insert_in_ob(object *op, object *where)
Definition: object.cpp:2853
MSG_TYPE_VICTIM
#define MSG_TYPE_VICTIM
Definition: newclient.h:404
MAX
#define MAX(x, y)
Definition: compat.h:24
cast_magic_storm
void cast_magic_storm(object *op, object *tmp, int lvl)
Definition: spell_effect.cpp:49
range_builder
@ range_builder
Definition: player.h:36
esrv_send_item
void esrv_send_item(object *pl, object *op)
Definition: main.cpp:354
METHOD_UNHANDLED
#define METHOD_UNHANDLED
Definition: ob_methods.h:16
FLAG_IS_A_TEMPLATE
#define FLAG_IS_A_TEMPLATE
Definition: define.h:366
object::carrying
int32_t carrying
Definition: object.h:377
AP_NULL
#define AP_NULL
Definition: define.h:573
object::y
int16_t y
Definition: object.h:335
m
static event_registration m
Definition: citylife.cpp:425
autojail.who
who
Definition: autojail.py:3
CLOAK
@ CLOAK
Definition: object.h:209
object_free_drop_inventory
void object_free_drop_inventory(object *ob)
Definition: object.cpp:1560
give_initial_items
void give_initial_items(object *pl, treasurelist *items)
Definition: player.cpp:784
AP_PRINT
#define AP_PRINT
Definition: define.h:583
object_find_by_name
object * object_find_by_name(const object *who, const char *name)
Definition: object.cpp:3952
esrv_remove_spell
void esrv_remove_spell(player *pl, object *spell)
Definition: request.cpp:1790
apply_handle_yield
void apply_handle_yield(object *tmp)
Definition: apply.cpp:122
HELMET
@ HELMET
Definition: object.h:141
FLAG_WAS_WIZ
#define FLAG_WAS_WIZ
Definition: define.h:234
drop
void drop(object *op, object *tmp)
Definition: c_object.cpp:1168
blind_living
void blind_living(object *op, object *hitter, int dam)
Definition: attack.cpp:2354
object_present_in_ob_by_name
object * object_present_in_ob_by_name(int type, const char *str, const object *op)
Definition: object.cpp:3199
MSG_TYPE_APPLY_SUCCESS
#define MSG_TYPE_APPLY_SUCCESS
Definition: newclient.h:592
SPELL_WONDER
#define SPELL_WONDER
Definition: spells.h:163
query_name
void query_name(const object *op, char *buf, size_t size)
Definition: item.cpp:588
FLAG_USE_RANGE
#define FLAG_USE_RANGE
Definition: define.h:292
POTION
@ POTION
Definition: object.h:116
FLAG_KNOWN_CURSED
#define FLAG_KNOWN_CURSED
Definition: define.h:320
BUILDER
@ BUILDER
Definition: object.h:251
archetype::clone
object clone
Definition: object.h:487
apply_by_living_below
void apply_by_living_below(object *pl)
Definition: apply.cpp:695
sword_of_souls.victim
victim
Definition: sword_of_souls.py:12
object::weight_limit
int32_t weight_limit
Definition: object.h:376
apply_anim_suffix
void apply_anim_suffix(object *who, const char *suffix)
Definition: anim.cpp:150
FOR_OB_AND_BELOW_FINISH
#define FOR_OB_AND_BELOW_FINISH()
Definition: define.h:754
HEAD
#define HEAD(op)
Definition: object.h:607
ROD
@ ROD
Definition: object.h:114
CONTAINER
@ CONTAINER
Definition: object.h:236
set_attr_value
void set_attr_value(living *stats, int attr, int8_t value)
Definition: living.cpp:218
object::face
const Face * face
Definition: object.h:341
apply_check_item_power
static int apply_check_item_power(const object *who, const object *op, int aflags)
Definition: apply.cpp:1867
SCRIPT_FIX_ALL
#define SCRIPT_FIX_ALL
Definition: global.h:389
AP_IGNORE_CURSE
#define AP_IGNORE_CURSE
Definition: define.h:582
navar-midane_pickup.msg
list msg
Definition: navar-midane_pickup.py:13
MOVE_FLYING
#define MOVE_FLYING
Definition: define.h:395
object_update_speed
void object_update_speed(object *op)
Definition: object.cpp:1349
object::type
uint8_t type
Definition: object.h:348
INS_NO_MERGE
#define INS_NO_MERGE
Definition: object.h:580
FLAG_DAMNED
#define FLAG_DAMNED
Definition: define.h:317
apply_manual
int apply_manual(object *op, object *tmp, int aflag)
Definition: apply.cpp:597
UPD_FLAGS
#define UPD_FLAGS
Definition: newclient.h:304
FLAG_USE_SHIELD
#define FLAG_USE_SHIELD
Definition: define.h:237
object_free
void object_free(object *ob, int flags)
Definition: object.cpp:1592
do_forget_spell
void do_forget_spell(object *op, const char *spell)
Definition: apply.cpp:525
LAMP
@ LAMP
Definition: object.h:206
Settings::item_power_factor
float item_power_factor
Definition: global.h:303
FOR_INV_FINISH
#define FOR_INV_FINISH()
Definition: define.h:677
INS_BELOW_ORIGINATOR
#define INS_BELOW_ORIGINATOR
Definition: object.h:584
tag_t
uint32_t tag_t
Definition: object.h:14
FLAG_USE_WEAPON
#define FLAG_USE_WEAPON
Definition: define.h:296
sproto.h
IS_SHIELD
#define IS_SHIELD(op)
Definition: define.h:170
find_key
object * find_key(object *pl, object *container, object *door)
Definition: player.cpp:2468
AC_PLAYER_STAT_NO_CHANGE
#define AC_PLAYER_STAT_NO_CHANGE
Definition: define.h:597
MSG_TYPE_VICTIM_WAS_HIT
#define MSG_TYPE_VICTIM_WAS_HIT
Definition: newclient.h:640
animate.anim
string anim
Definition: animate.py:20
FOR_OB_AND_BELOW_PREPARE
#define FOR_OB_AND_BELOW_PREPARE(op_)
Definition: define.h:750
CAN_APPLY_UNAPPLY_MULT
#define CAN_APPLY_UNAPPLY_MULT
Definition: define.h:634
GT_ENVIRONMENT
@ GT_ENVIRONMENT
Definition: treasure.h:31
random_roll
int random_roll(int min, int max, const object *op, int goodbad)
Definition: utils.cpp:42
SOUND_TYPE_SPELL
#define SOUND_TYPE_SPELL
Definition: newclient.h:323
RING
@ RING
Definition: object.h:190
nlohmann::detail::void
j template void())
Definition: json.hpp:4099
object_insert_in_map_at
object * object_insert_in_map_at(object *op, mapstruct *m, object *originator, int flag, int x, int y)
Definition: object.cpp:2100
object::other_arch
struct archetype * other_arch
Definition: object.h:425
FLAG_MONSTER
#define FLAG_MONSTER
Definition: define.h:245
find_skill_by_name
object * find_skill_by_name(object *who, const char *name)
Definition: skill_util.cpp:211
MAP_WIDTH
#define MAP_WIDTH(m)
Definition: map.h:73
should_director_abort
int should_director_abort(const object *op, const object *victim)
Definition: apply.cpp:68
MAX_BUF
#define MAX_BUF
Definition: define.h:35
object_new
object * object_new(void)
Definition: object.cpp:1273
object::head
object * head
Definition: object.h:304
apply_container
int apply_container(object *op, object *sack, int aflags)
Definition: apply.cpp:222
create_archetype
object * create_archetype(const char *name)
Definition: arch.cpp:278
IS_WEAPON
#define IS_WEAPON(op)
Definition: define.h:163
monster_check_apply_all
void monster_check_apply_all(object *monster)
Definition: monster.cpp:1999
apply_check_weapon_power
int apply_check_weapon_power(const object *who, int improves)
Definition: apply.cpp:1131
try_find_animation
Animations * try_find_animation(const char *name)
Definition: assets.cpp:278
apply_auto
int apply_auto(object *op)
Definition: apply.cpp:1400
Settings::spell_failure_effects
uint8_t spell_failure_effects
Definition: global.h:269
FOR_MAP_PREPARE
#define FOR_MAP_PREPARE(map_, mx_, my_, it_)
Definition: define.h:723
FLAG_KNOWN_MAGICAL
#define FLAG_KNOWN_MAGICAL
Definition: define.h:319
change_abil
int change_abil(object *op, object *tmp)
Definition: living.cpp:394
MSG_TYPE_APPLY_BADBODY
#define MSG_TYPE_APPLY_BADBODY
Definition: newclient.h:596
range_misc
@ range_misc
Definition: player.h:33
FLAG_READY_SKILL
#define FLAG_READY_SKILL
Definition: define.h:333
FLAG_READY_BOW
#define FLAG_READY_BOW
Definition: define.h:299
sounds.h
check_trigger
int check_trigger(object *op, object *cause)
Definition: button.cpp:518
FLAG_WIZ
#define FLAG_WIZ
Definition: define.h:231
NDI_UNIQUE
#define NDI_UNIQUE
Definition: newclient.h:251
object::slaying
sstring slaying
Definition: object.h:327
CAN_APPLY_UNAPPLY
#define CAN_APPLY_UNAPPLY
Definition: define.h:633
spells.h
object::name
sstring name
Definition: object.h:319
AP_OPEN
#define AP_OPEN
Definition: define.h:576
IS_ARMOR
#define IS_ARMOR(op)
Definition: define.h:166
unapply_nochoice
@ unapply_nochoice
Definition: player.h:76
FLAG_USE_ARMOUR
#define FLAG_USE_ARMOUR
Definition: define.h:295
item
Definition: item.py:1
apply_can_apply_object
int apply_can_apply_object(const object *who, const object *op)
Definition: apply.cpp:1016
is_magical
int is_magical(const object *op)
Definition: item.cpp:1227
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)
Definition: living.cpp:264
mapstruct
Definition: map.h:313
object::env
object * env
Definition: object.h:301
check_spell_known
object * check_spell_known(object *op, const char *name)
Definition: spell_util.cpp:394
AC_PLAYER_STAT_LIMIT
#define AC_PLAYER_STAT_LIMIT
Definition: define.h:596
sstring
const typedef char * sstring
Definition: sstring.h:2
give.op
op
Definition: give.py:33
Animations
Definition: face.h:25
FLAG_AUTO_APPLY
#define FLAG_AUTO_APPLY
Definition: define.h:250
Settings::personalized_blessings
uint8_t personalized_blessings
Definition: global.h:312
animate_object
void animate_object(object *op, int dir)
Definition: anim.cpp:44
object_split
object * object_split(object *orig_ob, uint32_t nr, char *err, size_t size)
Definition: object.cpp:2633
set_object_face_main
int set_object_face_main(object *op)
Definition: apply.cpp:146
esrv_update_item
void esrv_update_item(int flags, object *pl, object *op)
Definition: main.cpp:359
SKILL_TOOL
@ SKILL_TOOL
Definition: object.h:194
CAN_APPLY_UNAPPLY_CHOICE
#define CAN_APPLY_UNAPPLY_CHOICE
Definition: define.h:635
diamondslots.y
y
Definition: diamondslots.py:16
FLAG_BEEN_APPLIED
#define FLAG_BEEN_APPLIED
Definition: define.h:323
get_item_from_body_location
static object * get_item_from_body_location(object *start, int loc)
Definition: apply.cpp:878
CLEAR_FLAG
#define CLEAR_FLAG(xyz, p)
Definition: define.h:225
ob_apply
method_ret ob_apply(object *op, object *applier, int aflags)
Definition: ob_methods.cpp:44
AP_NOPRINT
#define AP_NOPRINT
Definition: define.h:585
MAP_HEIGHT
#define MAP_HEIGHT(m)
Definition: map.h:75
cast_wonder
int cast_wonder(object *op, object *caster, int dir, object *spell_ob)
Definition: spell_effect.cpp:968
MSG_TYPE_APPLY_FAILURE
#define MSG_TYPE_APPLY_FAILURE
Definition: newclient.h:593
apply_auto_fix
void apply_auto_fix(mapstruct *m)
Definition: apply.cpp:1527
object::body_info
int8_t body_info[NUM_BODY_LOCATIONS]
Definition: object.h:382
FLAG_ANIMATE
#define FLAG_ANIMATE
Definition: define.h:242
UPD_NAME
#define UPD_NAME
Definition: newclient.h:307
object::randomitems
struct treasurelist * randomitems
Definition: object.h:395
draw_ext_info
void draw_ext_info(int flags, int pri, const object *pl, uint8_t type, uint8_t subtype, const char *message)
Definition: main.cpp:308
object_remove
void object_remove(object *op)
Definition: object.cpp:1833
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)
Definition: apply.cpp:54
EVENT_CLOSE
#define EVENT_CLOSE
Definition: events.h:24
object::move_off
MoveType move_off
Definition: object.h:440
FLAG_UNPAID
#define FLAG_UNPAID
Definition: define.h:236
try_find_face
const Face * try_find_face(const char *name, const Face *error)
Definition: assets.cpp:286
AP_BASIC_FLAGS
#define AP_BASIC_FLAGS
Definition: define.h:578
FLAG_READY_RANGE
#define FLAG_READY_RANGE
Definition: define.h:298
METHOD_ERROR
#define METHOD_ERROR
Definition: ob_methods.h:17
generate_treasure
object * generate_treasure(treasurelist *t, int difficulty)
Definition: treasure.cpp:295
SCROLL
@ SCROLL
Definition: object.h:226
FLAG_IS_LINKED
#define FLAG_IS_LINKED
Definition: define.h:315
object::nrof
uint32_t nrof
Definition: object.h:342
MSG_TYPE_APPLY_PROHIBITION
#define MSG_TYPE_APPLY_PROHIBITION
Definition: newclient.h:597
object::stats
living stats
Definition: object.h:378
unapply_never
@ unapply_never
Definition: player.h:77
object_set_value
int object_set_value(object *op, const char *key, const char *value, int add_key)
Definition: object.cpp:4495
object::more
object * more
Definition: object.h:303
get_attr_value
int8_t get_attr_value(const living *stats, int attr)
Definition: living.cpp:313
AP_UNAPPLY
#define AP_UNAPPLY
Definition: define.h:575
range_skill
@ range_skill
Definition: player.h:35
apply_update_ranged_skill
static void apply_update_ranged_skill(const object *who, object *op, int aflags)
Definition: apply.cpp:1997
tod.h
BOOTS
@ BOOTS
Definition: object.h:217
TRUE
#define TRUE
Definition: compat.h:11
SPELL
@ SPELL
Definition: object.h:219
FLAG_READY_WEAPON
#define FLAG_READY_WEAPON
Definition: define.h:334
player_unready_range_ob
void player_unready_range_ob(player *pl, object *ob)
Definition: player.cpp:4449
SHIELD
@ SHIELD
Definition: object.h:140
MSG_TYPE_APPLY
#define MSG_TYPE_APPLY
Definition: newclient.h:397
FLAG_CURSED
#define FLAG_CURSED
Definition: define.h:316
MSG_TYPE_APPLY_ERROR
#define MSG_TYPE_APPLY_ERROR
Definition: newclient.h:590
altar_valkyrie.pl
pl
Definition: altar_valkyrie.py:28
living.h
SPELLBOOK
@ SPELLBOOK
Definition: object.h:208
NUM_STATS
@ NUM_STATS
Definition: living.h:18
FOR_INV_PREPARE
#define FOR_INV_PREPARE(op_, it_)
Definition: define.h:670
FORCE
@ FORCE
Definition: object.h:229
METHOD_SILENT_ERROR
#define METHOD_SILENT_ERROR
Definition: ob_methods.h:18
FLAG_IS_FLOOR
#define FLAG_IS_FLOOR
Definition: define.h:302
banquet.floors
list floors
Definition: banquet.py:29
FLAG_IDENTIFIED
#define FLAG_IDENTIFIED
Definition: define.h:261
give.name
name
Definition: give.py:27
identify
object * identify(object *op)
Definition: item.cpp:1421
MSG_TYPE_APPLY_UNAPPLY
#define MSG_TYPE_APPLY_UNAPPLY
Definition: newclient.h:591