Crossfire Server, Trunk  R20513
apply.c
Go to the documentation of this file.
1 /*
2  * Crossfire -- cooperative multi-player graphical RPG and adventure game
3  *
4  * Copyright (c) 1999-2014 Mark Wedel and the Crossfire Development Team
5  * Copyright (c) 1992 Frank Tore Johansen
6  *
7  * Crossfire is free software and comes with ABSOLUTELY NO WARRANTY. You are
8  * welcome to redistribute it under certain conditions. For details, please
9  * see COPYING and LICENSE.
10  *
11  * The authors can be reached via e-mail at <crossfire@metalforge.org>.
12  */
13 
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 
125 void apply_handle_yield(object *tmp) {
126  const char *yield;
127 
128  yield = object_get_value(tmp, "on_use_yield");
129  if (yield != NULL) {
130  object *drop = create_archetype(yield);
131  if (tmp->env)
132  drop = object_insert_in_ob(drop, tmp->env);
133  else
134  object_insert_in_map_at(drop, tmp->map, tmp, INS_BELOW_ORIGINATOR, tmp->x, tmp->y);
135  }
136 }
137 
149 int set_object_face_main(object *op) {
150  int newface = op->arch->clone.face->number;
151  sstring saved = object_get_value(op, "face_closed");
152 
153  if (saved)
154  newface = find_face(saved, newface);
155  if (newface && op->face != &new_faces[newface]) {
156  op->face = &new_faces[newface];
157  return TRUE;
158  }
159  return FALSE;
160 }
161 
173 static int set_object_face_other(object *op) {
174  sstring custom;
175  int newface = 0;
176 
177  if (op->face && op->other_arch && op->other_arch->clone.face)
178  newface = op->other_arch->clone.face->number;
179 
180  if (op->face != op->arch->clone.face) {
181  /* object has a custom face, save it so it gets correctly restored later. */
182  object_set_value(op, "face_closed", op->face->name, 1);
183  }
184 
185  custom = object_get_value(op, "face_opened");
186  if (custom)
187  newface = find_face(custom, newface);
188  if (newface && op->face->number != newface) {
189  op->face = &new_faces[newface];
190  return TRUE;
191  }
192  return FALSE;
193 }
194 
216 int apply_container(object *op, object *sack) {
217  char name_sack[MAX_BUF], name_tmp[MAX_BUF];
218  object *tmp = op->container;
219 
220  if (op->type != PLAYER)
221  return 0; /* This might change */
222 
223  if (sack == NULL || sack->type != CONTAINER) {
224  LOG(llevError, "apply_container: %s is not container!\n", sack ? sack->name : "NULL");
225  return 0;
226  }
227 
228  /* If we have a currently open container, then it needs
229  * to be closed in all cases if we are opening this one up.
230  * We then fall through if appropriate for opening the new
231  * container.
232  */
233  if (op->container && QUERY_FLAG(op->container, FLAG_APPLIED)) {
234  tag_t tmp_tag = op->container->count;
235 
236  if (op->container->env != op) { /* if container is on the ground */
237  op->container->move_off = 0;
238  }
239 
240  /* Query name before the close event, as the container could be destroyed. */
241  query_name(op->container, name_tmp, MAX_BUF);
242 
243  /* Lauwenmark: Handle for plugin close event */
244  if (execute_event(tmp, EVENT_CLOSE, op, NULL, NULL, SCRIPT_FIX_ALL) != 0)
245  return 1;
246 
249  "You close %s.",
250  name_tmp);
251 
252  op->container = NULL;
253  if (op->contr != NULL)
255 
256  /* The container may have been destroyed by the event handler. */
257  if (!object_was_destroyed(tmp, tmp_tag)) {
258  CLEAR_FLAG(tmp, FLAG_APPLIED);
259  if (set_object_face_main(tmp))
261  else
262  esrv_update_item(UPD_FLAGS, op, tmp);
263  }
264  if (tmp == sack)
265  return 1;
266  }
267 
268  query_name(sack, name_sack, MAX_BUF);
269 
270  /* If the player is trying to open it (which he must be doing
271  * if we got here), and it is locked, check to see if player
272  * has the equipment to open it.
273  */
274 
275  if (sack->slaying) { /* it's locked */
276  tmp = find_key(op, op, sack);
277  if (tmp) {
278  query_name(tmp, name_tmp, MAX_BUF);
281  "You unlock %s with %s.",
282  name_sack, name_tmp);
283  } else {
286  "You don't have the key to unlock %s.",
287  name_sack);
288  return 0;
289  }
290  }
291 
292  /* By the time we get here, we have made sure any other container
293  * has been closed and if this is a locked container, the player
294  * has the key to open it.
295  */
296 
297  /* There are really two cases - the sack is either on the ground,
298  * or the sack is part of the player's inventory. If on the ground,
299  * we assume that the player is opening it, since if it was being
300  * closed, that would have been taken care of above.
301  */
302 
303 
304  if (sack->env != op) {
305  /* Hypothetical case - the player is trying to open a sack
306  * that belongs to someone else. This normally should not
307  * happen, but a misbehaving client/player could
308  * try to do it, so let's handle it gracefully.
309  */
310  if (sack->env) {
312  "You can't open %s",
313  name_sack);
314  return 0;
315  }
316 
317  if (sack->nrof > 1) {
318  object *left = object_split(sack, sack->nrof-1, NULL, 0);
319 
320  object_insert_in_map_at(left, sack->map, NULL, INS_NO_MERGE, sack->x, sack->y);
321  /* recompute the name so it's nice */
322  query_name(sack, name_sack, MAX_BUF);
323  }
324 
325  /* set it so when the player walks off, we can unapply the sack */
326  sack->move_off = MOVE_ALL; /* trying force closing it */
327 
328  CLEAR_FLAG(sack, FLAG_APPLIED);
330  "You open %s.",
331  name_sack);
332  SET_FLAG(sack, FLAG_APPLIED);
333  op->container = sack;
334  if (op->contr != NULL)
336 
337  if (set_object_face_other(sack))
339  else
340  esrv_update_item(UPD_FLAGS, op, sack);
341  esrv_send_inventory(op, sack);
342  } else { /* sack is in players inventory */
343  if (QUERY_FLAG(sack, FLAG_APPLIED)) { /* readied sack becoming open */
344  CLEAR_FLAG(sack, FLAG_APPLIED);
346  "You open %s.",
347  name_sack);
348  SET_FLAG(sack, FLAG_APPLIED);
349  op->container = sack;
350  if (op->contr != NULL)
352 
353  if (set_object_face_other(sack))
355  else
356  esrv_update_item(UPD_FLAGS, op, sack);
357  esrv_send_inventory(op, sack);
358  } else {
359  object *left = NULL;
360 
361  if (sack->nrof > 1)
362  left = object_split(sack, sack->nrof-1, NULL, 1);
363 
364  CLEAR_FLAG(sack, FLAG_APPLIED);
366  "You readied %s.",
367  name_sack);
368  SET_FLAG(sack, FLAG_APPLIED);
369  esrv_update_item(UPD_FLAGS, op, sack);
370 
371  if (left) {
372  object_insert_in_ob(left, sack->env);
373  esrv_send_item(op, left);
374  }
375  }
376  }
377  return 1;
378 }
379 
391 void do_learn_spell(object *op, object *spell, int special_prayer) {
392  object *tmp;
393 
394  if (op->type != PLAYER) {
395  LOG(llevError, "BUG: do_learn_spell(): not a player\n");
396  return;
397  }
398 
399  /* Upgrade special prayers to normal prayers */
400  tmp = check_spell_known(op, spell->name);
401  if (tmp != NULL) {
402  if (special_prayer && !QUERY_FLAG(tmp, FLAG_STARTEQUIP)) {
403  LOG(llevError, "BUG: do_learn_spell(): spell already known, but not marked as startequip\n");
404  return;
405  }
406  return;
407  }
408 
409  play_sound_player_only(op->contr, SOUND_TYPE_SPELL, spell, 0, "learn");
410  tmp = object_new();
411  object_copy(spell, tmp);
412  object_insert_in_ob(tmp, op);
413 
414  if (special_prayer)
416 
418  "Type 'bind cast %s to store the spell in a key.",
419  spell->name);
420 
421  esrv_add_spells(op->contr, tmp);
422 }
423 
432 void do_forget_spell(object *op, const char *spell) {
433  object *spob;
434 
435  if (op->type != PLAYER) {
436  LOG(llevError, "BUG: do_forget_spell(): not a player\n");
437  return;
438  }
439  spob = check_spell_known(op, spell);
440  if (spob == NULL) {
441  LOG(llevError, "BUG: do_forget_spell(): spell not known\n");
442  return;
443  }
444 
446  "You lose knowledge of %s.",
447  spell);
448  player_unready_range_ob(op->contr, spob);
449  esrv_remove_spell(op->contr, spob);
450  object_remove(spob);
451  object_free2(spob, 0);
452 }
453 
467 static int apply_check_race_restrictions(object *who, object *item) {
468  char buf[MAX_BUF];
469  sstring restriction;
470 
471  if (who->type != PLAYER || QUERY_FLAG(who, FLAG_WIZ))
472  return 1;
473 
474  restriction = object_get_value(item, "race_restriction");
475  if (!restriction)
476  return 1;
477 
478  snprintf(buf, sizeof(buf), ":%s:", who->race);
479  buf[sizeof(buf)-1] = '\0';
480 
481  if (strstr(restriction, buf) != NULL)
482  return 1;
483 
484  query_name(item, buf, sizeof(buf));
485  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);
486 
487  return 0;
488 }
489 
510 int apply_manual(object *op, object *tmp, int aflag) {
511  tmp = HEAD(tmp);
512 
513  if (QUERY_FLAG(tmp, FLAG_UNPAID) && !QUERY_FLAG(tmp, FLAG_APPLIED)) {
514  if (op->type == PLAYER) {
516  "You should pay for it first.");
517  return METHOD_SILENT_ERROR;
518  }
519  return 0; /* monsters just skip unpaid items */
520  }
521 
522  if (!apply_check_race_restrictions(op, tmp))
523  return METHOD_SILENT_ERROR;
524 
525  /* Lauwenmark: Handle for plugin apply event */
526  if (execute_event(tmp, EVENT_APPLY, op, NULL, NULL, SCRIPT_FIX_ALL) != 0)
527  return METHOD_OK;
528 
529  if (op->contr)
530  play_sound_player_only(op->contr, SOUND_TYPE_ITEM, tmp, 0, "apply");
531 
532  return ob_apply(tmp, op, aflag);
533 }
534 
557 int apply_by_living(object *pl, object *op, int aflag, int quiet) {
558  int tmp;
559 
560  if (op->env == NULL && (pl->move_type&MOVE_FLYING)) {
561  /* player is flying and applying object not in inventory */
562  if (!QUERY_FLAG(pl, FLAG_WIZ) && !(op->move_type&MOVE_FLYING)) {
564  "But you are floating high above the ground!");
565  return 0;
566  }
567  }
568 
569  /* Check for PLAYER to avoid a DM to disappear in a puff of smoke if
570  * applied.
571  */
572  if (op->type != PLAYER
573  && QUERY_FLAG(op, FLAG_WAS_WIZ)
574  && !QUERY_FLAG(pl, FLAG_WAS_WIZ)) {
575  play_sound_map(SOUND_TYPE_ITEM, op, 0, "evaporate");
577  "The object disappears in a puff of smoke!");
579  "It must have been an illusion.");
580  object_remove(op);
581  object_free2(op, 0);
582  return 1;
583  }
584 
585  tmp = apply_manual(pl, op, aflag);
586  if (!quiet) {
587  if (tmp == METHOD_UNHANDLED) {
588  char name[MAX_BUF];
589 
590  query_name(op, name, MAX_BUF);
592  "I don't know how to apply the %s.",
593  name);
594  } else if (tmp == METHOD_ERROR)
596  "You must get it first!\n");
597  else if (tmp == METHOD_SILENT_ERROR)
598  return tmp;
599  }
600  if (tmp == METHOD_OK) {
601  if (op->anim_suffix != NULL)
603  }
604  return tmp;
605 }
606 
618 void apply_by_living_below(object *pl) {
619  object *tmp;
620  int floors;
621 
622  if (pl->contr->transport && pl->contr->transport->type == TRANSPORT) {
623  ob_apply(pl->contr->transport, pl, 0);
624  return;
625  }
626 
627  /* If using a container, set the starting item to be the top
628  * item in the container. Otherwise, use the map.
629  */
630  tmp = pl->container != NULL ? pl->container->inv : pl->below;
631 
632  /* This is perhaps more complicated. However, I want to make sure that
633  * we don't use a corrupt pointer for the next object, so we get the
634  * next object in the stack before applying. This is can only be a
635  * problem if apply_by_living() has a bug in that it uses the object but
636  * does not return a proper value.
637  */
638  floors = 0;
640  if (QUERY_FLAG(tmp, FLAG_IS_FLOOR))
641  floors++;
642  else if (floors > 0)
643  return; /* process only floor objects after first floor object */
644 
645  /* If it is visible, player can apply it. If it is applied by
646  * person moving on it, also activate. Added code to make it
647  * so that at least one of players movement types be that which
648  * the item needs.
649  */
650  if (!tmp->invisible || (tmp->move_on&pl->move_type)) {
651  if (apply_by_living(pl, tmp, 0, 1) == METHOD_OK)
652  return;
653  }
654  if (floors >= 2)
655  return; /* process at most two floor objects */
657 }
658 
674 static int unapply_special(object *who, object *op, int aflags) {
675  char name[MAX_BUF];
676 
677  if (op->type != LAMP)
679  query_name(op, name, MAX_BUF);
680  switch (op->type) {
681  case WEAPON:
682  if (!(aflags&AP_NOPRINT))
684  "You unwield %s.",
685  name);
686  (void)change_abil(who, op);
688  who->current_weapon = NULL;
689  clear_skill(who);
690  break;
691 
692  case SKILL: /* allows objects to impart skills */
693  case SKILL_TOOL:
694  if (op != who->chosen_skill)
695  LOG(llevError, "BUG: unapply_special(): applied skill is not a chosen skill\n");
696  if (who->type == PLAYER) {
697  if (who->contr->shoottype == range_skill)
698  who->contr->shoottype = range_none;
699  if (!op->invisible) {
700  if (!(aflags&AP_NOPRINT))
702  "You stop using the %s.",
703  name);
704  } else {
705  if (!(aflags&AP_NOPRINT))
707  "You can no longer use the skill: %s.",
708  op->skill);
709  }
710  }
711  (void)change_abil(who, op);
712  who->chosen_skill = NULL;
714  break;
715 
716  case ARMOUR:
717  case HELMET:
718  case SHIELD:
719  case RING:
720  case BOOTS:
721  case GLOVES:
722  case AMULET:
723  case GIRDLE:
724  case BRACERS:
725  case CLOAK:
726  if (!(aflags&AP_NOPRINT))
728  "You unwear %s.",
729  name);
730  (void)change_abil(who, op);
731  break;
732 
733  case BOW:
734  case WAND:
735  case ROD:
736  clear_skill(who);
737  if (!(aflags&AP_NOPRINT))
739  "You unready %s.",
740  name);
741  if (who->type == PLAYER)
742  who->contr->shoottype = range_none;
743  else if (op->type == BOW)
745  else
747  break;
748 
749  case BUILDER:
750  if (!(aflags&AP_NOPRINT))
752  "You unready %s.",
753  name);
754  who->contr->shoottype = range_none;
755  who->contr->ranges[range_builder] = NULL;
756  break;
757 
758  default:
759  if (!(aflags&AP_NOPRINT))
761  "You unapply %s.",
762  name);
763  break;
764  }
765 
766  fix_object(who);
767 
768  if (!(aflags&AP_NO_MERGE)) {
769  object *tmp;
770 
771  tmp = object_merge(op, NULL);
772  if (who->type == PLAYER) {
773  if (tmp) { /* it was merged */
774  op = tmp;
775  }
776  esrv_update_item(UPD_FLAGS, who, op);
777  }
778  }
779  return 0;
780 }
781 
801 static object *get_item_from_body_location(object *start, int loc) {
802  object *tmp;
803 
804  if (!start)
805  return NULL;
806 
807  tmp = start;
809  if (QUERY_FLAG(tmp, FLAG_APPLIED)
810  && tmp->body_info[loc]
811  && (!tmp->invisible || tmp->type == SKILL))
812  return tmp;
814  return NULL;
815 }
816 
838 static int unapply_for_ob(object *who, object *op, int aflags) {
839  int i;
840  object *tmp = NULL, *last;
841  char name[MAX_BUF];
842 
843  /* If we are applying a shield or weapon, unapply any equipped shield
844  * or weapons first - only allowed to use one weapon/shield at a time.
845  */
846  if (op->type == WEAPON || op->type == SHIELD) {
847  FOR_INV_PREPARE(who, tmp) {
848  if (QUERY_FLAG(tmp, FLAG_APPLIED) && tmp->type == op->type) {
849  if (!(aflags&AP_IGNORE_CURSE)
850  && !(aflags&AP_PRINT)
851  && (QUERY_FLAG(tmp, FLAG_CURSED) || QUERY_FLAG(tmp, FLAG_DAMNED))) {
852  /* In this case, we want to try and remove a
853  * cursed item. While we know it won't work, we
854  * want unapply_special to at least generate the
855  * message.
856  */
857  if (!(aflags&AP_NOPRINT)) {
858  query_name(tmp, name, MAX_BUF);
860  "No matter how hard you try, you just can't remove %s.",
861  name);
862  }
863  return 1;
864  }
865 
866  if (aflags&AP_PRINT) {
867  query_name(tmp, name, MAX_BUF);
869  name);
870  } else
871  unapply_special(who, tmp, aflags);
872  }
873  } FOR_INV_FINISH();
874  }
875 
876  for (i = 0; i < NUM_BODY_LOCATIONS; i++) {
877  /* this used up a slot that we need to free */
878  if (op->body_info[i]) {
879  last = who->inv;
880 
881  /* We do a while loop - may need to remove several items
882  * in order to free up enough slots.
883  */
884  while (who->body_used[i]+op->body_info[i] < 0) {
885  tmp = get_item_from_body_location(last, i);
886  if (!tmp)
887  return 1;
888 
889  /* If just printing, we don't care about cursed status */
890  if ((aflags&AP_IGNORE_CURSE)
891  || (aflags&AP_PRINT)
892  || (!(QUERY_FLAG(tmp, FLAG_CURSED) || QUERY_FLAG(tmp, FLAG_DAMNED)))) {
893  if (aflags&AP_PRINT) {
894  query_name(tmp, name, MAX_BUF);
896  name);
897  } else
898  unapply_special(who, tmp, aflags);
899  } else {
900  /* Cursed item that we can't unequip - tell the player.
901  * Note this could be annoying if this is just one of a
902  * few, so it may not be critical (eg, putting on a
903  * ring and you have one cursed ring.)
904  */
905  if (!(aflags&AP_NOPRINT)) {
906  query_name(tmp, name, MAX_BUF);
908  "The %s just won't come off",
909  name);
910  }
911  }
912  last = tmp->below;
913  }
914  /* if we got here, this slot is freed up - otherwise, if it
915  * wasn't freed up, the return in the !tmp would have
916  * kicked in.
917  */
918  } /* if op is using this body location */
919  } /* for body locations */
920  return 0;
921 }
922 
942 int apply_can_apply_object(const object *who, const object *op) {
943  int i, retval = 0;
944  object *tmp = NULL, *ws = NULL;
945 
946  /* Players have 2 'arm's, so they could in theory equip 2 shields or
947  * 2 weapons, but we don't want to let them do that. So if they are
948  * trying to equip a weapon or shield, see if they already have one
949  * in place and store that way.
950  */
951  if (op->type == WEAPON || op->type == SHIELD) {
952  tmp = object_find_by_type_applied(who, op->type);
953  if (tmp != NULL) {
954  retval = CAN_APPLY_UNAPPLY;
955  ws = tmp;
956  }
957  }
958 
959  for (i = 0; i < NUM_BODY_LOCATIONS; i++) {
960  if (op->body_info[i]) {
961  /* Item uses more slots than we have */
962  if (FABS(op->body_info[i]) > who->body_info[i]) {
963  /* Could return now for efficiently - rest of info
964  * below isn't really needed.
965  */
966  retval |= CAN_APPLY_NEVER;
967  } else if (who->body_used[i]+op->body_info[i] < 0) {
968  /* in this case, equipping this would use more free
969  * spots than we have.
970  */
971  object *tmp1;
972 
973  /* if we have an applied weapon/shield, and unapply
974  * it would free enough slots to equip the new item,
975  * then just set this can continue. We don't care
976  * about the logic below - if you have shield equipped
977  * and try to equip another shield, there is only one
978  * choice. However, the check for the number of body
979  * locations does take into the account cases where what
980  * is being applied may be two handed for example.
981  */
982  if (ws) {
983  if (who->body_used[i]-ws->body_info[i]+op->body_info[i] >= 0) {
984  retval |= CAN_APPLY_UNAPPLY;
985  continue;
986  }
987  }
988 
989  tmp1 = get_item_from_body_location(who->inv, i);
990  if (!tmp1)
991  retval |= CAN_APPLY_NEVER;
992  else {
993  /* need to unapply something. However, if this
994  * something is different than we had found before,
995  * it means they need to apply multiple objects
996  */
997  retval |= CAN_APPLY_UNAPPLY;
998  if (!tmp)
999  tmp = tmp1;
1000  else if (tmp != tmp1)
1001  retval |= CAN_APPLY_UNAPPLY_MULT;
1002  /* This object isn't using up all the slots, so
1003  * there must be another. If so, and if the new
1004  * item doesn't need all the slots, the player
1005  * then has a choice.
1006  */
1007  if (who->body_used[i]-tmp1->body_info[i] != who->body_info[i]
1008  && FABS(op->body_info[i]) < who->body_info[i])
1009  retval |= CAN_APPLY_UNAPPLY_CHOICE;
1010 
1011  /* Does unequipping 'tmp1' free up enough slots
1012  * for this to be equipped? If not, there must
1013  * be something else to unapply.
1014  */
1015  if (who->body_used[i]+op->body_info[i]-tmp1->body_info[i] < 0)
1016  retval |= CAN_APPLY_UNAPPLY_MULT;
1017  }
1018  } /* if not enough free slots */
1019  } /* if this object uses location i */
1020  } /* for i -> num_body_locations loop */
1021 
1022  /* Do checks for can_use_weapon/shield/armour. */
1023  if (IS_WEAPON(op) && !QUERY_FLAG(who, FLAG_USE_WEAPON))
1024  retval |= CAN_APPLY_RESTRICTION;
1025  if (IS_SHIELD(op) && !QUERY_FLAG(who, FLAG_USE_SHIELD))
1026  retval |= CAN_APPLY_RESTRICTION;
1027  if (IS_ARMOR(op) && !QUERY_FLAG(who, FLAG_USE_ARMOUR))
1028  retval |= CAN_APPLY_RESTRICTION;
1029 
1030  if (who->type != PLAYER) {
1031  if ((op->type == WAND || op->type == ROD)
1032  && !QUERY_FLAG(who, FLAG_USE_RANGE))
1033  retval |= CAN_APPLY_RESTRICTION;
1034  if (op->type == BOW && !QUERY_FLAG(who, FLAG_USE_BOW))
1035  retval |= CAN_APPLY_RESTRICTION;
1036  if (op->type == RING && !QUERY_FLAG(who, FLAG_USE_RING))
1037  retval |= CAN_APPLY_RESTRICTION;
1038  }
1039  return retval;
1040 }
1041 
1057 int apply_check_weapon_power(const object *who, int improves) {
1058  return (who->level/5)+5 >= improves;
1059 }
1060 
1082 int apply_special(object *who, object *op, int aflags) {
1083  int basic_flag = aflags&AP_BASIC_FLAGS;
1084  object *tmp, *skop;
1085  char name_op[MAX_BUF];
1086 
1087  if (who == NULL) {
1088  LOG(llevError, "apply_special() from object without environment.\n");
1089  return 1;
1090  }
1091 
1092  if (op->env != who)
1093  return 1; /* op is not in inventory */
1094 
1095  /* trying to unequip op */
1096  if (QUERY_FLAG(op, FLAG_APPLIED)) {
1097  /* always apply, so no reason to unapply */
1098  if (basic_flag == AP_APPLY)
1099  return 0;
1100 
1101  if (!(aflags&AP_IGNORE_CURSE)
1102  && (QUERY_FLAG(op, FLAG_CURSED) || QUERY_FLAG(op, FLAG_DAMNED))) {
1103  if (!(aflags&AP_NOPRINT)) {
1104  query_name(op, name_op, MAX_BUF);
1106  "No matter how hard you try, you just can't remove %s.",
1107  name_op);
1108  }
1109  return 1;
1110  }
1111  return unapply_special(who, op, aflags);
1112  }
1113 
1114  if (basic_flag == AP_UNAPPLY)
1115  return 0;
1116 
1117  if (!apply_check_apply_restrictions(who, op, aflags))
1118  return 1;
1119 
1120  if (op->skill && op->type != SKILL && op->type != SKILL_TOOL) {
1121  skop = find_skill_by_name(who, op->skill);
1122  if (!skop) {
1123  if (!(aflags&AP_NOPRINT))
1125  "You need the %s skill to use this item!",
1126  op->skill);
1127  if (who->type == PLAYER)
1128  return 1;
1129 
1130  /* monsters do not care about missing skills */
1131  } else
1132  /* While experience will be credited properly, we want to
1133  * change the skill so that the dam and wc get updated
1134  */
1135  change_skill(who, skop, (aflags&AP_NOPRINT));
1136  } else
1137  skop = NULL;
1138 
1139  if (!apply_check_item_power(who, op, aflags))
1140  return 1;
1141 
1142  if (!apply_check_personalized_blessings(who, op))
1143  return 1;
1144 
1145  /* Ok. We are now at the state where we can apply the new object.
1146  * Note that we don't have the checks for can_use_...
1147  * below - that is already taken care of by apply_can_apply_object().
1148  */
1149 
1150  tmp = op->nrof <= 1 ? NULL : object_split(op, op->nrof-1, NULL, 0);
1151 
1152  switch (op->type) {
1153  case WEAPON:
1154  if (!apply_check_weapon_power(who, op->last_eat)) {
1155  if (!(aflags&AP_NOPRINT))
1157  "That weapon is too powerful for you to use. It would consume your soul!");
1158  if (tmp != NULL)
1159  (void)object_insert_in_ob(tmp, who);
1160  return 1;
1161  }
1162 
1163  if (!apply_check_owner(who, op, aflags)) {
1164  if (tmp != NULL)
1165  (void)object_insert_in_ob(tmp, who);
1166  return 1;
1167  }
1168 
1169  SET_FLAG(op, FLAG_APPLIED);
1170 
1171  if (skop)
1172  change_skill(who, skop, 1);
1174 
1175  if (!(aflags&AP_NOPRINT)) {
1176  query_name(op, name_op, MAX_BUF);
1178  "You wield %s.",
1179  name_op);
1180  }
1181 
1182  (void)change_abil(who, op);
1183  break;
1184 
1185  case ARMOUR:
1186  case HELMET:
1187  case SHIELD:
1188  case BOOTS:
1189  case GLOVES:
1190  case GIRDLE:
1191  case BRACERS:
1192  case CLOAK:
1193  case RING:
1194  case AMULET:
1195  SET_FLAG(op, FLAG_APPLIED);
1196  if (!(aflags&AP_NOPRINT)) {
1197  query_name(op, name_op, MAX_BUF);
1199  "You wear %s.",
1200  name_op);
1201  }
1202  (void)change_abil(who, op);
1203  break;
1204 
1205  /* this part is needed for skill-tools */
1206  case SKILL:
1207  case SKILL_TOOL:
1208  if (who->chosen_skill) {
1209  LOG(llevError, "BUG: apply_special(): can't apply two skills\n");
1210  return 1;
1211  }
1212 
1213  apply_update_ranged_skill(who, op, aflags);
1214  SET_FLAG(op, FLAG_APPLIED);
1215  (void)change_abil(who, op);
1216  who->chosen_skill = op;
1217  SET_FLAG(who, FLAG_READY_SKILL);
1218  break;
1219 
1220  case BOW:
1221  if (!apply_check_weapon_power(who, op->last_eat)) {
1222  if (!(aflags&AP_NOPRINT))
1224  "That weapon is too powerful for you to use. It would consume your soul!");
1225  if (tmp != NULL)
1226  (void)object_insert_in_ob(tmp, who);
1227  return 1;
1228  }
1229 
1230  if (!apply_check_owner(who, op, aflags)) {
1231  if (tmp != NULL)
1232  (void)object_insert_in_ob(tmp, who);
1233  return 1;
1234  }
1235  /*FALLTHROUGH*/
1236  case WAND:
1237  case ROD:
1238  /* check for skill, alter player status */
1239  SET_FLAG(op, FLAG_APPLIED);
1240  if (skop)
1241  change_skill(who, skop, 0);
1242  if (!(aflags&AP_NOPRINT)) {
1243  query_name(op, name_op, MAX_BUF);
1245  "You ready %s.",
1246  name_op);
1247  }
1248  if (who->type == PLAYER) {
1249  if (op->type == BOW) {
1250  (void)change_abil(who, op);
1251  if (!(aflags&AP_NOPRINT)) {
1252  query_name(op, name_op, MAX_BUF);
1254  "You will now fire %s with %s.",
1255  op->race ? op->race : "nothing",
1256  name_op);
1257  }
1258  who->contr->shoottype = range_bow;
1259  } else
1260  who->contr->shoottype = range_misc;
1261  } else {
1262  if (op->type == BOW)
1263  SET_FLAG(who, FLAG_READY_BOW);
1264  else
1265  SET_FLAG(who, FLAG_READY_RANGE);
1266  }
1267  break;
1268 
1269  case BUILDER:
1270  if (who->contr->ranges[range_builder])
1271  unapply_special(who, who->contr->ranges[range_builder], 0);
1272  who->contr->shoottype = range_builder;
1273  who->contr->ranges[range_builder] = op;
1274  if (!(aflags&AP_NOPRINT)) {
1275  query_name(op, name_op, MAX_BUF);
1277  "You ready your %s.",
1278  name_op);
1279  }
1280  break;
1281 
1282  default:
1283  query_name(op, name_op, MAX_BUF);
1285  "You apply %s.",
1286  name_op);
1287  break;
1288  } /* end of switch op->type */
1289 
1290  SET_FLAG(op, FLAG_APPLIED);
1291 
1292  if (tmp != NULL)
1293  tmp = object_insert_in_ob(tmp, who);
1294 
1295  fix_object(who);
1296 
1297  /* We exclude spell casting objects. The fire code will set the
1298  * been applied flag when they are used - until that point,
1299  * you don't know anything about them.
1300  */
1301  if (who->type == PLAYER && op->type != WAND && op->type != ROD)
1303 
1304  if (QUERY_FLAG(op, FLAG_CURSED) || QUERY_FLAG(op, FLAG_DAMNED)) {
1305  if (who->type == PLAYER) {
1307  "Oops, it feels deadly cold!");
1309  }
1310  }
1311  if (who->type == PLAYER)
1313  return 0;
1314 }
1315 
1329 int apply_auto(object *op) {
1330  object *tmp;
1331 
1332  switch (op->type) {
1333  case SHOP_FLOOR:
1334  if (!HAS_RANDOM_ITEMS(op))
1335  return 0;
1336  do {
1337  int i;
1338 
1339  i = 10; /* let's give it 10 tries */
1340  while ((tmp = generate_treasure(op->randomitems, op->stats.exp ? (int)op->stats.exp : MAX(op->map->difficulty, 5))) == NULL
1341  && --i)
1342  ;
1343  if (tmp == NULL)
1344  return 0;
1345  if (QUERY_FLAG(tmp, FLAG_CURSED) || QUERY_FLAG(tmp, FLAG_DAMNED)) {
1347  tmp = NULL;
1348  }
1349  } while (!tmp);
1350  SET_FLAG(tmp, FLAG_UNPAID);
1351  object_insert_in_map_at(tmp, op->map, NULL, 0, op->x, op->y);
1353  identify(tmp);
1354  return 1;
1355  break;
1356 
1357  case TREASURE:
1358  if (QUERY_FLAG(op, FLAG_IS_A_TEMPLATE))
1359  return 0;
1360  while (op->stats.hp-- > 0)
1361  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);
1362 
1363  /* If we generated an object and put it in this object's
1364  * inventory, move it to the parent object as the current
1365  * object is about to disappear. An example of this item
1366  * is the random_ *stuff that is put inside other objects.
1367  */
1368  FOR_INV_PREPARE(op, tmp) {
1369  object_remove(tmp);
1370  if (op->env)
1371  object_insert_in_ob(tmp, op->env);
1372  else
1374  } FOR_INV_FINISH();
1375  object_remove(op);
1377  break;
1378  }
1379  return 0;
1380 }
1381 
1396  int x, y;
1397 
1398  if (m == NULL)
1399  return;
1400 
1401  for (x = 0; x < MAP_WIDTH(m); x++)
1402  for (y = 0; y < MAP_HEIGHT(m); y++)
1403  FOR_MAP_PREPARE(m, x, y, tmp) {
1404  if (tmp->inv) {
1405  FOR_INV_PREPARE(tmp, invtmp) {
1406  if (QUERY_FLAG(invtmp, FLAG_AUTO_APPLY))
1407  apply_auto(invtmp);
1408  else if (invtmp->type == TREASURE && HAS_RANDOM_ITEMS(invtmp)) {
1409  while (invtmp->stats.hp-- > 0)
1410  create_treasure(invtmp->randomitems, invtmp, 0, m->difficulty, 0);
1411  invtmp->randomitems = NULL;
1412  } else if (invtmp && invtmp->arch
1413  && invtmp->type != TREASURE
1414  && invtmp->type != SPELL
1415  && invtmp->type != CLASS
1416  && HAS_RANDOM_ITEMS(invtmp)) {
1417  create_treasure(invtmp->randomitems, invtmp, 0, m->difficulty, 0);
1418  /* Need to clear this so that we never try to
1419  * create treasure again for this object
1420  */
1421  invtmp->randomitems = NULL;
1422  }
1423  } FOR_INV_FINISH();
1424  /* This is really temporary - the code at the
1425  * bottom will also set randomitems to null.
1426  * The problem is there are bunches of maps/players
1427  * already out there with items that have spells
1428  * which haven't had the randomitems set
1429  * to null yet.
1430  * MSW 2004-05-13
1431  *
1432  * And if it's a spellbook, it's better to set
1433  * randomitems to NULL too, else you get two spells
1434  * in the book ^_-
1435  * Ryo 2004-08-16
1436  */
1437  if (tmp->type == WAND
1438  || tmp->type == ROD
1439  || tmp->type == SCROLL
1440  || tmp->type == FIREWALL
1441  || tmp->type == POTION
1442  || tmp->type == ALTAR
1443  || tmp->type == SPELLBOOK)
1444  tmp->randomitems = NULL;
1445  }
1446 
1447  if (QUERY_FLAG(tmp, FLAG_AUTO_APPLY))
1448  apply_auto(tmp);
1449  else if ((tmp->type == TREASURE || tmp->type == CONTAINER)
1450  && HAS_RANDOM_ITEMS(tmp)) {
1451  while (tmp->stats.hp-- > 0)
1452  create_treasure(tmp->randomitems, tmp, 0, m->difficulty, 0);
1453  tmp->randomitems = NULL;
1454  } else if (tmp->type == TIMED_GATE) {
1455  object *head = HEAD(tmp);
1456 
1457  if (QUERY_FLAG(head, FLAG_IS_LINKED)) {
1458  tmp->speed = 0;
1459  object_update_speed(tmp);
1460  }
1461  }
1462  /* This function can be called every time a map is loaded,
1463  * even when swapping back in. As such, we don't want to
1464  * create the treasure over and over again, so after we
1465  * generate the treasure, blank out randomitems so if it
1466  * is swapped in again, it won't make anything. This is a
1467  * problem for the above objects, because they have
1468  * counters which say how many times to make the treasure.
1469  */
1470  else if (tmp
1471  && tmp->arch
1472  && tmp->type != PLAYER
1473  && tmp->type != TREASURE
1474  && tmp->type != SPELL
1475  && tmp->type != PLAYER_CHANGER
1476  && tmp->type != CLASS
1477  && HAS_RANDOM_ITEMS(tmp)) {
1478  create_treasure(tmp->randomitems, tmp, 0, m->difficulty, 0);
1479  tmp->randomitems = NULL;
1480  }
1481 
1482  if (QUERY_FLAG(tmp, FLAG_MONSTER))
1484  } FOR_MAP_FINISH();
1485 
1486  for (x = 0; x < MAP_WIDTH(m); x++)
1487  for (y = 0; y < MAP_HEIGHT(m); y++)
1488  FOR_MAP_PREPARE(m, x, y, tmp) {
1489  if (tmp->above
1490  && (tmp->type == TRIGGER_BUTTON || tmp->type == TRIGGER_PEDESTAL))
1491  check_trigger(tmp, tmp->above);
1492  } FOR_MAP_FINISH();
1493 }
1494 
1509 void scroll_failure(object *op, int failure, int power) {
1510  if (abs(failure/4) > power)
1511  power = abs(failure/4); /* set minimum effect */
1512 
1513  if (failure <= -1 && failure > -15) {/* wonder */
1514  object *tmp;
1515 
1517  "Your spell warps!");
1519  cast_wonder(op, op, 0, tmp);
1520  if (op->stats.sp < 0)
1521  /* For some reason the sp can become negative here. */
1522  op->stats.sp = 0;
1524  return;
1525  }
1526 
1528  if (failure <= -35 && failure > -60) { /* confusion */
1530  "The magic recoils on you!");
1531  confuse_living(op, op, power);
1532  return;
1533  }
1534 
1535  if (failure <= -60 && failure > -70) {/* paralysis */
1537  "The magic recoils and paralyzes you!");
1538  paralyze_living(op, power);
1539  return;
1540  }
1541 
1542  if (failure <= -70 && failure > -80) {/* blind */
1544  "The magic recoils on you!");
1545  blind_living(op, op, power);
1546  return;
1547  }
1548 
1549  if (failure <= -80) {/* blast the immediate area */
1550  object *tmp;
1551 
1553  cast_magic_storm(op, tmp, power);
1555  "You unlease uncontrolled mana!");
1557  return;
1558  }
1559  }
1560  /* Either no spell failure on this server, or wrong values,
1561  * in any case let's punish.
1562  */
1564  "Your mana is drained!");
1565  op->stats.sp -= random_roll(0, power-1, op, PREFER_LOW);
1566  if (op->stats.sp < 0)
1567  op->stats.sp = 0;
1568 }
1569 
1581 void apply_changes_to_player(object *pl, object *change, int limit_stats) {
1582  int i, j;
1583  int excess_stat = 0; /* if the stat goes over the maximum
1584  * for the race, put the excess stat some
1585  * where else.
1586  */
1587 
1588  if (change->type != CLASS) return;
1589 
1590  /* the following code assigns stats up to the stat max
1591  * for the race, and if the stat max is exceeded,
1592  * tries to randomly reassign the excess stat
1593  */
1594  if (! (limit_stats & AC_PLAYER_STAT_NO_CHANGE)) {
1595  for (i = 0; i < NUM_STATS; i++) {
1596  int8_t stat = get_attr_value(&pl->contr->orig_stats, i);
1597  int race_bonus = get_attr_value(&pl->arch->clone.stats, i);
1598 
1599  stat += get_attr_value(&change->stats, i);
1600  if (limit_stats & AC_PLAYER_STAT_LIMIT) {
1601  if (stat > 20+race_bonus) {
1602  excess_stat++;
1603  stat = 20+race_bonus;
1604  } else if (stat < 1) {
1605  /* I didn't see any code here before to make sure minimum
1606  * stats were enforced - maybe it was just dumb
1607  * luck that one would not have a stat low enough that then
1608  * has a stat penalty for class that would bring it negative?
1609  * I imagine a negative stat would crash the server pretty
1610  * quickly - MSW, Sept 2010
1611  */
1612  excess_stat += stat;
1613  stat = 1;
1614  }
1615  }
1616  set_attr_value(&pl->contr->orig_stats, i, stat);
1617  }
1618 
1619  /* Maybe we should randomly deduct stats in this case?
1620  * It's will go away sometime soon in any case.
1621  */
1622  if (excess_stat < 0) excess_stat = 0;
1623 
1624  /* We don't put an explicit check for limit_stats here -
1625  * excess stat will never be 0 if limit_stats is not
1626  * true.
1627  */
1628  for (j = 0; excess_stat > 0 && j < 100; j++) {
1629  /* try 100 times to assign excess stats */
1630  int i = rndm(0, NUM_STATS-1);
1631  int stat = get_attr_value(&pl->contr->orig_stats, i);
1632  int race_bonus = get_attr_value(&pl->arch->clone.stats, i);
1633 
1634  if (i == CHARISMA) {
1635  continue; /* exclude cha from this */
1636  }
1637 
1638  if (stat < 20+race_bonus) {
1639  change_attr_value(&pl->contr->orig_stats, i, 1);
1640  excess_stat--;
1641  }
1642  }
1643  }
1644  /* Done with stat processing */
1645 
1646  /* insert the randomitems from the change's treasurelist into
1647  * the player ref: player.c
1648  */
1649  if (change->randomitems != NULL)
1650  give_initial_items(pl, change->randomitems);
1651 
1652 
1653  /* set up the face, for some races. */
1654 
1655  /* first, look for the force object banning changing the
1656  * face. Certain races never change face with class.
1657  */
1658  if (object_find_by_name(pl, "NOCLASSFACECHANGE") == NULL) {
1659  pl->animation_id = GET_ANIM_ID(change);
1660  pl->face = change->face;
1661 
1662  if (QUERY_FLAG(change, FLAG_ANIMATE))
1663  SET_FLAG(pl, FLAG_ANIMATE);
1664  else
1665  CLEAR_FLAG(pl, FLAG_ANIMATE);
1666  }
1667 
1668  if (change->anim_suffix) {
1669  char buf[MAX_BUF];
1670  int anim;
1671 
1672  snprintf(buf, MAX_BUF, "%s_%s", animations[pl->animation_id].name, change->anim_suffix);
1673  anim = try_find_animation(buf);
1674  if (anim) {
1675  pl->animation_id = anim;
1676  pl->anim_speed = -1;
1677  CLEAR_FLAG(pl, FLAG_ANIMATE);
1678  animate_object(pl, pl->facing);
1679  }
1680  }
1681  /* Hard coding in class name is a horrible idea - lets
1682  * use the supported mechanism for this
1683  */
1684  if (object_present_in_ob_by_name(FORCE, "no weapon force", pl))
1686 
1687 }
1688 
1689 void legacy_apply_container(object *op, object *sack) {
1690  apply_container(op, sack);
1691 }
1692 
1706 static int apply_check_apply_restrictions(object *who, object *op, int aflags) {
1707  int i;
1708 
1709  i = apply_can_apply_object(who, op);
1710  if (i == 0)
1711  return 1;
1712 
1713  /* Can't just apply this object. Lets see why not and what to do */
1714 
1715  if (i&CAN_APPLY_NEVER) {
1716  if (!(aflags&AP_NOPRINT)) {
1717  char name_op[MAX_BUF];
1718 
1719  query_name(op, name_op, MAX_BUF);
1721  "You don't have the body to use a %s",
1722  name_op);
1723  }
1724  return 0;
1725  }
1726 
1727  if (i&CAN_APPLY_RESTRICTION) {
1728  if (!(aflags&AP_NOPRINT)) {
1729  char name_op[MAX_BUF];
1730 
1731  query_name(op, name_op, MAX_BUF);
1733  "You have a prohibition against using a %s",
1734  name_op);
1735  }
1736  return 0;
1737  }
1738 
1739  if (who->type != PLAYER) {
1740  /* Some error, so don't try to equip something more */
1741  return !unapply_for_ob(who, op, aflags);
1742  }
1743 
1744  if (who->contr->unapply == unapply_never
1746  if (!(aflags&AP_NOPRINT))
1748  "You need to unapply some item(s):");
1749  unapply_for_ob(who, op, AP_PRINT);
1750  return 0;
1751  }
1752 
1753  if (who->contr->unapply == unapply_always
1754  || !(i&CAN_APPLY_UNAPPLY_CHOICE)) {
1755  return !unapply_for_ob(who, op, aflags);
1756  }
1757 
1758  return 1;
1759 }
1760 
1773 static int apply_check_item_power(const object *who, const object *op, int aflags) {
1774  if (who->type != PLAYER)
1775  return 1;
1776 
1777  if (op->item_power == 0
1779  return 1;
1780 
1781  if (!(aflags&AP_NOPRINT))
1783  "Equipping that combined with other items would consume your soul!");
1784  return 0;
1785 }
1786 
1801 static int apply_check_personalized_blessings(object *who, const object *op) {
1802  const char *owner;
1803  const char *will;
1804  long item_will;
1805  long margin;
1806  const char *msg;
1807  int random_effect;
1808  int damage_percentile;
1809 
1811  return 1;
1812  }
1813 
1814  owner = object_get_value(op, "item_owner");
1815  if (owner == NULL || strcmp(owner, who->name) == 0)
1816  return 1;
1817 
1818  will = object_get_value(op, "item_willpower");
1819  item_will = will != NULL ? atol(will) : 0;
1820  if (item_will > who->stats.exp) {
1822  "This %s refuses to serve you - it keeps evading your hand !",
1823  op->name);
1824  return 0;
1825  }
1826 
1827  margin = item_will != 0 ? who->stats.exp/item_will : who->stats.exp;
1828  random_effect = random_roll(0, 100, who, 1)-margin*20;
1829  if (random_effect > 80) {
1830  msg = "You don't know why, but you have the feeling that the %s is angry at you !";
1831  damage_percentile = 60;
1832  } else if (random_effect > 60) {
1833  msg = "The %s seems to look at you nastily !";
1834  damage_percentile = 45;
1835  } else if (random_effect > 40) {
1836  msg = "You have the strange feeling that the %s is annoyed...";
1837  damage_percentile = 30;
1838  } else if (random_effect > 20) {
1839  msg = "The %s seems tired, or bored, in a way. Very strange !";
1840  damage_percentile = 15;
1841  } else if (random_effect > 0) {
1842  msg = "You hear the %s sighing !";
1843  damage_percentile = 0;
1844  } else {
1845  msg = NULL;
1846  damage_percentile = 0;
1847  }
1848  if (msg != NULL)
1850  msg, op->name);
1851  if (damage_percentile > 0) {
1852  int weapon_bite = (who->stats.hp*damage_percentile)/100;
1853  if (weapon_bite < 1)
1854  weapon_bite = 1;
1855  who->stats.hp -= weapon_bite;
1857  "You get a nasty bite in the hand !");
1858  }
1859 
1860  return 1;
1861 }
1862 
1877 static int apply_check_owner(const object *who, const object *op, int aflags) {
1878  const char *quotepos;
1879 
1880  if (op->level == 0)
1881  return 1;
1882 
1883  quotepos = strstr(op->name, "'");
1884  if (quotepos == NULL || strncmp(op->name, who->name, quotepos-op->name) == 0)
1885  return 1;
1886 
1887  if (!(aflags&AP_NOPRINT))
1889  "The weapon does not recognize you as its owner.");
1890  return 0;
1891 }
1892 
1903 static void apply_update_ranged_skill(const object *who, object *op, int aflags) {
1904  if (who->type != PLAYER) {
1905  return;
1906  }
1907 
1908  who->contr->shoottype = range_skill;
1909  who->contr->ranges[range_skill] = op;
1910  if (op->invisible) {
1911  if (!(aflags&AP_NOPRINT))
1913  "Readied skill: %s.",
1914  op->skill ? op->skill : op->name);
1915  } else {
1916  if (!(aflags&AP_NOPRINT)) {
1917  char name_op[MAX_BUF];
1918 
1919  query_name(op, name_op, MAX_BUF);
1921  "You ready %s.",
1922  name_op);
1924  "You can now use the skill: %s.",
1925  op->skill);
1926  }
1927  }
1928 }
void draw_ext_info_format(int flags, int pri, const object *pl, uint8_t type, uint8_t subtype, const char *format,...)
Sends message to player(s).
Definition: main.c:315
Error, serious thing.
Definition: logger.h:11
#define AP_UNAPPLY
Item is to be remvoed.
Definition: define.h:611
Use skill.
Definition: player.h:22
static int apply_check_owner(const object *who, const object *op, int aflags)
Checks that the item&#39;s owner matches the applier.
Definition: apply.c:1877
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.c:218
Will unapply whatever is necessary - this goes beyond no choice - if there are multiple ojbect of the...
Definition: player.h:65
#define NUM_BODY_LOCATIONS
Number of body locations.
Definition: object.h:13
One player.
Definition: player.h:92
Sound-related defines.
static int apply_check_race_restrictions(object *who, object *item)
Checks if an item is restricted to a race.
Definition: apply.c:467
#define FLAG_DAMNED
The object is very cursed.
Definition: define.h:318
#define FLAG_IS_FLOOR
Can&#39;t see what&#39;s underneath this object.
Definition: define.h:303
#define FLAG_UNPAID
Object hasn&#39;t been paid for yet.
Definition: define.h:236
int32_t weight_limit
Weight-limit of object.
Definition: object.h:366
#define FLAG_IS_LINKED
The object is linked with other objects.
Definition: define.h:316
MoveType move_type
Type of movement this object uses.
Definition: object.h:424
see doc/Developers/objects
Definition: object.h:108
#define INS_BELOW_ORIGINATOR
Insert new object immediately below originator.
Definition: object.h:572
int change_skill(object *who, object *new_skill, int flag)
This changes the object&#39;s skill to new_skill.
Definition: skill_util.c:356
Spell-related defines: spellpath, subtypes, ...
void legacy_apply_container(object *op, object *sack)
Definition: apply.c:1689
MoveType move_on
Move types affected moving on to this space.
Definition: object.h:427
See Ring.
Definition: object.h:185
#define CAN_APPLY_UNAPPLY_CHOICE
Definition: define.h:670
object * check_spell_known(object *op, const char *name)
Checks to see if player knows the spell.
Definition: spell_util.c:435
const char * race
Human, goblin, dragon, etc.
Definition: object.h:318
#define MSG_TYPE_APPLY_PROHIBITION
Class/god prohibiiton on obj.
Definition: newclient.h:603
void esrv_send_item(object *pl, object *op)
Sends item&#39;s info to player.
Definition: main.c:339
#define SET_FLAG(xyz, p)
Definition: define.h:223
See Bracers.
Definition: object.h:217
object * object_find_by_type_applied(const object *who, int type)
Find applied object in inventory.
Definition: object.c:3974
#define FABS(x)
Decstations have trouble with fabs()...
Definition: define.h:22
See Scroll.
Definition: object.h:221
#define MSG_TYPE_APPLY_FAILURE
Apply OK, but no/bad result.
Definition: newclient.h:599
Defines for the ingame clock, ticks management and weather system.
New_Face * new_faces
Contains face information, with names, numbers, magicmap color and such.
Definition: image.c:33
#define MSG_TYPE_APPLY_BADBODY
Don&#39;t have body to use object.
Definition: newclient.h:602
uint16_t animation_id
An index into the animation array.
Definition: object.h:416
const char * name
Name of the animation sequence.
Definition: face.h:27
#define FLAG_USE_ARMOUR
(Monster) can wear armour/shield/helmet
Definition: define.h:296
uint8_t anim_speed
Ticks between animation-frames.
Definition: object.h:417
See Cloak.
Definition: object.h:204
struct obj * container
Current container being used.
Definition: object.h:291
void do_forget_spell(object *op, const char *spell)
Erases spell from player&#39;s inventory.
Definition: apply.c:432
#define METHOD_ERROR
Definition: ob_methods.h:17
No range selected.
Definition: player.h:17
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.c:1773
#define FLAG_READY_RANGE
(Monster) has a range attack readied...
Definition: define.h:299
void esrv_update_item(int flags, object *pl, object *op)
Updates object *op for player *pl.
Definition: main.c:342
See Spellbook.
Definition: object.h:203
const char * object_get_value(const object *op, const char *const key)
Get an extra value by key.
Definition: object.c:4246
struct treasureliststruct * randomitems
Items to be generated.
Definition: object.h:385
#define MAP_HEIGHT(m)
Map height.
Definition: map.h:80
object clone
An object from which to do object_copy()
Definition: object.h:470
socket_struct socket
Socket information for this player.
Definition: player.h:94
#define CAN_APPLY_NEVER
Definition: define.h:665
int16_t invisible
How much longer the object will be invis.
Definition: object.h:360
#define PREFER_LOW
Definition: define.h:600
int apply_auto(object *op)
Map was just loaded, handle op&#39;s initialization.
Definition: apply.c:1329
rangetype shoottype
Which range-attack is being used by player.
Definition: player.h:99
See Weapon.
Definition: object.h:119
See Helmet.
Definition: object.h:136
const char * slaying
Which race to do double damage to.
Definition: object.h:319
#define IS_WEAPON(op)
Definition: define.h:162
void esrv_send_inventory(object *pl, object *op)
Sends inventory of a container.
Definition: item.c:307
Object for applying character class modifications to someone.
Definition: object.h:138
object * ranges[range_size]
Object for each range.
Definition: player.h:103
uint8_t subtype
Subtype of object.
Definition: object.h:339
See Rod.
Definition: object.h:109
static void apply_update_ranged_skill(const object *who, object *op, int aflags)
Updates ranged skill information.
Definition: apply.c:1903
#define FLAG_USE_WEAPON
(Monster) can wield weapons
Definition: define.h:297
int64_t exp
Experience.
Definition: living.h:46
#define FLAG_BLESSED
Item has a blessing, opposite of cursed/damned.
Definition: define.h:378
#define SPELL_WONDER
Definition: spells.h:163
#define FREE_OBJ_NO_DESTROY_CALLBACK
Do not run the destroy callback.
Definition: object.h:533
void blind_living(object *op, object *hitter, int dam)
Blind a living thing.
Definition: attack.c:2260
uint16_t container_position
Start of container contents to send to client.
Definition: newserver.h:127
See Button Trigger.
Definition: object.h:132
Misc items.
Definition: player.h:20
#define object_was_destroyed(op, old_tag)
Checks if an object still exists.
Definition: object.h:68
#define TRUE
Definition: compat.h:10
See Girdle.
Definition: object.h:223
See Amulet.
Definition: object.h:139
int8_t get_attr_value(const living *stats, int attr)
Gets the value of a stat.
Definition: living.c:313
#define FALSE
Definition: compat.h:11
#define MAX(x, y)
Definition: compat.h:20
method_ret ob_apply(object *op, object *applier, int aflags)
Applies an object.
Definition: ob_methods.c:42
void scroll_failure(object *op, int failure, int power)
op made some mistake with a scroll, this takes care of punishment.
Definition: apply.c:1509
int set_object_face_main(object *op)
Makes an object&#39;s face the main face, which is supposed to be the "closed" one.
Definition: apply.c:149
int16_t sp
Spell points.
Definition: living.h:41
Global type definitions and header inclusions.
See Boots.
Definition: object.h:212
#define SCRIPT_FIX_ALL
Definition: global.h:361
#define AP_APPLY
Item is to be applied.
Definition: define.h:610
struct archt * other_arch
Pointer used for various things - mostly used for what this objects turns into or what this object cr...
Definition: object.h:413
Will not unapply objects automatically.
Definition: player.h:64
#define FLAG_USE_RING
(Monster) can use rings, boots, gauntlets, etc
Definition: define.h:298
object * object_find_by_name(const object *who, const char *name)
Finds an object in inventory name.
Definition: object.c:3879
void draw_ext_info(int flags, int pri, const object *pl, uint8_t type, uint8_t subtype, const char *message)
Sends message to player(s).
Definition: main.c:310
See Wand & Staff.
Definition: object.h:220
#define MSG_TYPE_APPLY
Applying objects.
Definition: newclient.h:384
#define FOR_OB_AND_BELOW_FINISH()
Finishes FOR_OB_AND_BELOW_PREPARE().
Definition: define.h:789
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&#39;s ...
Definition: request.c:1738
int16_t hp
Hit Points.
Definition: living.h:39
uint16_t number
This is the image id.
Definition: face.h:15
#define SOUND_TYPE_ITEM
Definition: newclient.h:310
#define NDI_NAVY
Definition: newclient.h:223
void create_treasure(treasurelist *t, object *op, int flag, int difficulty, int tries)
This calls the appropriate treasure creation function.
Definition: treasure.c:490
#define LOOSE_MANA
Definition: spells.h:162
#define CAN_APPLY_UNAPPLY_MULT
Definition: define.h:669
#define MOVE_ALL
Mask of all movement types.
Definition: define.h:413
Don&#39;t generate bad/cursed items.
Definition: treasure.h:34
Allows the use of a skill.
Definition: object.h:189
int rndm(int min, int max)
Returns a number between min and max.
Definition: utils.c:161
void apply_changes_to_player(object *pl, object *change, int limit_stats)
Applies (race) changes to a player.
Definition: apply.c:1581
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.c:125
Generic item builder, see subtypes below.
Definition: object.h:246
#define FLAG_READY_SKILL
(Monster or Player) has a skill readied
Definition: define.h:334
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.c:1801
struct obj * chosen_skill
The skill chosen to use.
Definition: object.h:386
int object_set_value(object *op, const char *key, const char *value, int add_key)
Updates the key in op to value.
Definition: object.c:4375
void object_free_drop_inventory(object *ob)
Frees everything allocated by an object, removes it from the list of used objects, and puts it on the list of free objects.
Definition: object.c:1368
int change_abil(object *op, object *tmp)
Permanently alters an object&#39;s stats/flags based on another object.
Definition: living.c:394
const char * name
Face name, as used by archetypes and such.
Definition: face.h:20
int16_t y
Position in the map for this object.
Definition: object.h:326
#define CAN_APPLY_UNAPPLY
Definition: define.h:668
object * object_insert_in_map_at(object *op, mapstruct *m, object *originator, int flag, int x, int y)
Same as object_insert_in_map() except it handle separate coordinates and do a clean job preparing mul...
Definition: object.c:1921
int should_director_abort(const object *op, const object *victim)
Check if op should abort moving victim because of it&#39;s race or slaying.
Definition: apply.c:68
See Shooting Weapon.
Definition: object.h:118
int apply_special(object *who, object *op, int aflags)
Apply an object.
Definition: apply.c:1082
void confuse_living(object *op, object *hitter, int dam)
Confuse a living thing.
Definition: attack.c:2221
#define AP_IGNORE_CURSE
Apply/unapply regardless of cursed/damned status.
Definition: define.h:617
#define MSG_TYPE_VICTIM
Something bad is happening to the player.
Definition: newclient.h:392
object * object_new(void)
Grabs an object from the list of unused objects, makes sure it is initialised, and returns it...
Definition: object.c:1037
#define CAN_APPLY_RESTRICTION
Definition: define.h:666
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.c:620
object * object_insert_in_ob(object *op, object *where)
This function inserts the object op in the linked list inside the object environment.
Definition: object.c:2690
unapplymode unapply
Method for auto unapply.
Definition: player.h:108
static object * get_item_from_body_location(object *start, int loc)
Returns the object that is using body location &#39;loc&#39;.
Definition: apply.c:801
See Treasure.
Definition: object.h:110
int32_t weight
Attributes of the object.
Definition: object.h:365
#define AC_PLAYER_STAT_LIMIT
Definition: define.h:632
const char * anim_suffix
Used to determine combined animations.
Definition: object.h:316
#define METHOD_OK
Definition: ob_methods.h:15
#define AP_PRINT
Print what to do, don&#39;t actually do it Note this is supported in all the functions.
Definition: define.h:618
#define FLAG_USE_SHIELD
Can this creature use a shield?
Definition: define.h:237
#define FLAG_USE_RANGE
(Monster) can apply and use range items
Definition: define.h:293
struct mapdef * map
Pointer to the map in which this object is present.
Definition: object.h:297
void monster_check_apply_all(object *monster)
Calls monster_check_apply() for all inventory objects.
Definition: monster.c:1757
#define snprintf
Definition: win32.h:46
Map builder.
Definition: player.h:23
#define MSG_TYPE_APPLY_ERROR
Definition: newclient.h:596
#define EVENT_CLOSE
Container closed.
Definition: plugin.h:75
object * transport
Transport the player is in.
Definition: player.h:195
#define FOR_INV_FINISH()
Finishes FOR_INV_PREPARE().
Definition: define.h:712
#define MOVE_FLYING
Combo of fly_low and fly_high.
Definition: define.h:410
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.c:264
int32_t carrying
How much weight this object contains.
Definition: object.h:367
const char * name
The name of the object, obviously...
Definition: object.h:311
living orig_stats
Permanent real stats of player.
Definition: player.h:148
struct obj * env
Pointer to the object which is the environment.
Definition: object.h:293
struct obj * below
Pointer to the object stacked below this one.
Definition: object.h:287
#define MSG_TYPE_VICTIM_WAS_HIT
Player was hit by something.
Definition: newclient.h:647
#define FLAG_IS_A_TEMPLATE
Object has no ingame life until instantiated.
Definition: define.h:375
struct obj * current_weapon
Pointer to the weapon currently used.
Definition: object.h:370
uint32_t nrof
How many of the objects.
Definition: object.h:333
#define AP_NOPRINT
Don&#39;t print messages - caller will do that may be some that still print.
Definition: define.h:621
#define UPD_FLAGS
Definition: newclient.h:290
void paralyze_living(object *op, int dam)
Paralyze a living thing.
Definition: attack.c:2304
MoveType move_off
Move types affected moving off this space.
Definition: object.h:428
Number of statistics.
Definition: living.h:18
EXTERN Animations * animations
Definition: global.h:165
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, possible transport may have more restrictions or weight reduction like containers.
Definition: apply.c:54
See Potion.
Definition: object.h:111
struct pl * contr
Pointer to the player which control this object.
Definition: object.h:276
int8_t item_power
Power rating of the object.
Definition: object.h:362
int try_find_animation(const char *name)
Tries to find the animation id that matches name, don&#39;t LOG() an error if not found.
Definition: anim.c:159
void player_unready_range_ob(player *pl, object *ob)
Unready an object for a player.
Definition: player.c:4439
void cast_magic_storm(object *op, object *tmp, int lvl)
This is really used mostly for spell fumbles and the like.
Definition: spell_effect.c:44
#define UPD_WEIGHT
Definition: newclient.h:291
uint32_t tag_t
Object tag, unique during the whole game.
Definition: object.h:12
int apply_by_living(object *pl, object *op, int aflag, int quiet)
Living thing is applying an object.
Definition: apply.c:557
See Spell.
Definition: object.h:214
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.c:961
#define QUERY_FLAG(xyz, p)
Definition: define.h:225
#define CLEAR_FLAG(xyz, p)
Definition: define.h:224
static int unapply_for_ob(object *who, object *op, int aflags)
Remove equipment so an object can be applied.
Definition: apply.c:838
#define HEAD(op)
Returns the head part of an object.
Definition: object.h:594
#define MSG_TYPE_APPLY_UNAPPLY
Unapply an object.
Definition: newclient.h:597
#define FLAG_WIZ
Object has special privilegies.
Definition: define.h:231
#define FLAG_BEEN_APPLIED
The object has been applied.
Definition: define.h:324
#define MAX_BUF
Used for all kinds of things.
Definition: define.h:35
#define METHOD_UNHANDLED
Definition: ob_methods.h:16
void give_initial_items(object *pl, treasurelist *items)
Gives a new player her initial items.
Definition: player.c:762
#define IS_SHIELD(op)
Definition: define.h:169
See Door.
Definition: object.h:126
See Magic Wall.
Definition: object.h:168
int16_t x
Definition: object.h:326
void drop(object *op, object *tmp)
Drop an item, either on the floor or in a container.
Definition: c_object.c:910
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.c:1706
const char * skill
Name of the skill this object uses/grants.
Definition: object.h:321
int32_t last_eat
How long since we last ate.
Definition: object.h:356
Skill-related defines, including subtypes.
Lamp.
Definition: object.h:201
#define AC_PLAYER_STAT_NO_CHANGE
Definition: define.h:633
See Container.
Definition: object.h:231
uint16_t difficulty
What level the player should be to play here.
Definition: map.h:343
#define FLAG_READY_WEAPON
(Monster or Player) has a weapon readied
Definition: define.h:335
static int unapply_special(object *who, object *op, int aflags)
Unapplies specified item.
Definition: apply.c:674
#define FOR_MAP_FINISH()
Finishes FOR_MAP_PREPARE().
Definition: define.h:765
void animate_object(object *op, int dir)
Updates the face-variable of an object.
Definition: anim.c:186
#define FLAG_KNOWN_CURSED
The object is known to be cursed.
Definition: define.h:321
const char * sstring
Strings that should be manipulated through add_string() and free_string().
Definition: global.h:40
#define AP_BASIC_FLAGS
Definition: define.h:613
#define FLAG_CURSED
The object is cursed.
Definition: define.h:317
See Player.
Definition: object.h:107
#define AP_NO_MERGE
Don&#39;t try to merge object after (un)applying it.
Definition: define.h:616
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.c:1395
See Shield.
Definition: object.h:135
#define FLAG_ANIMATE
The object looks at archetype for faces.
Definition: define.h:242
#define FLAG_AUTO_APPLY
Will be applied when created.
Definition: define.h:250
int8_t body_info[NUM_BODY_LOCATIONS]
Body info as loaded from the file.
Definition: object.h:372
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.c:2463
#define INS_NO_MERGE
Don&#39;t try to merge with other items.
Definition: object.h:568
See Altar.
Definition: object.h:122
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.c:51
#define UPD_NROF
Definition: newclient.h:296
signed char int8_t
Type definitions for fixed-size integer types.
Definition: win32.h:158
Also see SKILL_TOOL (74) below.
Definition: object.h:143
int apply_container(object *op, object *sack)
Handle apply on containers.
Definition: apply.c:216
tag_t count
Unique object number for this object.
Definition: object.h:299
#define EVENT_APPLY
Object applied-unapplied.
Definition: plugin.h:64
living stats
Str, Con, Dex, etc.
Definition: object.h:368
struct archt * arch
Pointer to archetype.
Definition: object.h:412
See Shop Floor.
Definition: object.h:183
#define UPD_FACE
Definition: newclient.h:292
#define MAP_WIDTH(m)
Map width.
Definition: map.h:78
void clear_skill(object *who)
This function just clears the chosen_skill and range_skill values in the player.
Definition: skill_util.c:396
uint8_t type
PLAYER, BULLET, etc.
Definition: object.h:338
struct Settings settings
Server settings.
Definition: init.c:40
void object_free2(object *ob, int flags)
Frees everything allocated by an object, removes it from the list of used objects, and puts it on the list of free objects.
Definition: object.c:1391
void esrv_remove_spell(player *pl, object *spell)
Definition: request.c:1603
#define METHOD_SILENT_ERROR
Player was warned she can&#39;t use the item for now.
Definition: ob_methods.h:18
#define FLAG_APPLIED
Object is ready for use by living.
Definition: define.h:235
object * object_merge(object *op, object *top)
This function goes through all objects below and including top, and merges op to the first matching o...
Definition: object.c:1869
See Timed Gate.
Definition: object.h:128
int execute_event(object *op, int eventcode, object *activator, object *third, const char *message, int fix)
Definition: main.c:364
#define MSG_TYPE_APPLY_SUCCESS
Was able to apply object.
Definition: newclient.h:598
#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:785
#define FLAG_STARTEQUIP
Object was given to player at start.
Definition: define.h:268
Bow.
Definition: player.h:18
#define GET_ANIM_ID(ob)
Definition: global.h:173
int apply_manual(object *op, object *tmp, int aflag)
Main apply handler.
Definition: apply.c:510
object * identify(object *op)
Identifies an item.
Definition: item.c:1437
#define MSG_TYPE_APPLY_CURSED
Applied a cursed object (BAD)
Definition: newclient.h:600
#define FLAG_MONSTER
Will attack players.
Definition: define.h:245
Will unapply objects when there no choice to unapply.
Definition: player.h:63
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.c:838
void apply_by_living_below(object *pl)
Attempt to apply the object &#39;below&#39; the player.
Definition: apply.c:618
void do_learn_spell(object *op, object *spell, int special_prayer)
Actually makes op learn spell.
Definition: apply.c:391
struct obj * inv
Pointer to the first object in the inventory.
Definition: object.h:290
#define NDI_UNIQUE
Print immediately, don&#39;t buffer.
Definition: newclient.h:245
void apply_anim_suffix(object *who, sstring suffix)
Applies a compound animation to an object.
Definition: anim.c:292
char * name
Account name.
Definition: account.c:77
See Gloves.
Definition: object.h:213
#define FLAG_READY_BOW
not implemented yet
Definition: define.h:300
void LOG(LogLevel logLevel, const char *format,...)
Logs a message to stderr, or to file.
Definition: logger.c:51
int16_t item_power
Total item power of objects equipped.
Definition: player.h:117
#define FLAG_WAS_WIZ
Player was once a wiz.
Definition: define.h:234
#define FOR_MAP_PREPARE(map_, mx_, my_, it_)
Constructs a loop iterating over all objects of a map tile.
Definition: define.h:758
void play_sound_map(int8_t sound_type, object *emitter, int dir, const char *action)
Plays a sound on a map.
Definition: sounds.c:101
#define IS_ARMOR(op)
Definition: define.h:165
Structure containing object statistics.
int check_trigger(object *op, object *cause)
Definition: button.c:523
object * find_key(object *pl, object *container, object *door)
We try to find a key for the door as passed.
Definition: player.c:2538
void query_name(const object *op, char *buf, size_t size)
Describes an item.
Definition: item.c:625
object * generate_treasure(treasurelist *t, int difficulty)
Generate a treasure from a list generating a single item.
Definition: treasure.c:518
This is a game-map.
Definition: map.h:325
int random_roll(int min, int max, const object *op, int goodbad)
Roll a random number between min and max.
Definition: utils.c:42
const New_Face * face
Face with colors.
Definition: object.h:332
static int set_object_face_other(object *op)
Makes an object&#39;s face the other_arch face, supposed to be the "opened" one.
Definition: apply.c:173
See Breastplate Armor.
Definition: object.h:120
int16_t level
Level of creature or object.
Definition: object.h:351
int8_t facing
Object is oriented/facing that way.
Definition: object.h:335
uint8_t spell_failure_effects
Nasty backlash to spell failures.
Definition: global.h:267
void fix_object(object *op)
Updates all abilities given by applied objects in the inventory of the given object.
Definition: living.c:1120
unsigned find_face(const char *name, unsigned error)
This returns an the face number of face &#39;name&#39;.
Definition: image.c:303
#define SOUND_TYPE_SPELL
Definition: newclient.h:309
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.c:213
void object_update_speed(object *op)
Updates the speed of an object.
Definition: object.c:1129
int apply_can_apply_object(const object *who, const object *op)
Checks to see if &#39;who&#39; can apply object &#39;op&#39;.
Definition: apply.c:942
float item_power_factor
See note in setings file.
Definition: global.h:301
const char * name
More definite name, like "generate_kobold".
Definition: object.h:466
#define FLAG_USE_BOW
(Monster) can apply and fire bows
Definition: define.h:294
#define HAS_RANDOM_ITEMS(op)
This return TRUE if object has still randomitems which could be expanded.
Definition: define.h:183
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.c:3039
#define FOR_INV_PREPARE(op_, it_)
Constructs a loop iterating over the inventory of an object.
Definition: define.h:705
void object_remove(object *op)
This function removes the object op from the linked list of objects which it is currently tied to...
Definition: object.c:1654
uint8_t personalized_blessings
If 1, blessed weapons get an owner and a willpower value.
Definition: global.h:310
int8_t body_used[NUM_BODY_LOCATIONS]
Calculated value based on items equipped.
Definition: object.h:373
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.c:1057
Definition: object.h:224