Crossfire Server, Trunk  R21219
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' tried to apply %s, which is not a container\n", op->name, 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  if (op->contr)
526  play_sound_player_only(op->contr, SOUND_TYPE_ITEM, tmp, 0, "apply");
527 
528  return ob_apply(tmp, op, aflag);
529 }
530 
553 int apply_by_living(object *pl, object *op, int aflag, int quiet) {
554  int tmp;
555 
556  if (op->env == NULL && (pl->move_type&MOVE_FLYING)) {
557  /* player is flying and applying object not in inventory */
558  if (!QUERY_FLAG(pl, FLAG_WIZ) && !(op->move_type&MOVE_FLYING)) {
560  "But you are floating high above the ground!");
561  return 0;
562  }
563  }
564 
565  /* Check for PLAYER to avoid a DM to disappear in a puff of smoke if
566  * applied.
567  */
568  if (op->type != PLAYER
569  && QUERY_FLAG(op, FLAG_WAS_WIZ)
570  && !QUERY_FLAG(pl, FLAG_WAS_WIZ)) {
571  play_sound_map(SOUND_TYPE_ITEM, op, 0, "evaporate");
573  "The object disappears in a puff of smoke!");
575  "It must have been an illusion.");
576  object_remove(op);
577  object_free2(op, 0);
578  return 1;
579  }
580 
581  tmp = apply_manual(pl, op, aflag);
582  if (!quiet) {
583  if (tmp == METHOD_UNHANDLED) {
584  char name[MAX_BUF];
585 
586  query_name(op, name, MAX_BUF);
588  "I don't know how to apply the %s.",
589  name);
590  } else if (tmp == METHOD_ERROR)
592  "You must get it first!\n");
593  else if (tmp == METHOD_SILENT_ERROR)
594  return tmp;
595  }
596  if (tmp == METHOD_OK) {
597  if (op->anim_suffix != NULL)
599  }
600  return tmp;
601 }
602 
614 void apply_by_living_below(object *pl) {
615  object *tmp;
616  int floors;
617 
618  if (pl->contr->transport && pl->contr->transport->type == TRANSPORT) {
619  ob_apply(pl->contr->transport, pl, 0);
620  return;
621  }
622 
623  /* If using a container, set the starting item to be the top
624  * item in the container. Otherwise, use the map.
625  */
626  tmp = pl->container != NULL ? pl->container->inv : pl->below;
627 
628  /* This is perhaps more complicated. However, I want to make sure that
629  * we don't use a corrupt pointer for the next object, so we get the
630  * next object in the stack before applying. This is can only be a
631  * problem if apply_by_living() has a bug in that it uses the object but
632  * does not return a proper value.
633  */
634  floors = 0;
636  if (QUERY_FLAG(tmp, FLAG_IS_FLOOR))
637  floors++;
638  else if (floors > 0)
639  return; /* process only floor objects after first floor object */
640 
641  /* If it is visible, player can apply it. If it is applied by
642  * person moving on it, also activate. Added code to make it
643  * so that at least one of players movement types be that which
644  * the item needs.
645  */
646  if (!tmp->invisible || (tmp->move_on&pl->move_type)) {
647  if (apply_by_living(pl, tmp, 0, 1) == METHOD_OK)
648  return;
649  }
650  if (floors >= 2)
651  return; /* process at most two floor objects */
653 }
654 
670 static int unapply_special(object *who, object *op, int aflags) {
671  char name[MAX_BUF];
672 
673  if (op->type != LAMP)
675  query_name(op, name, MAX_BUF);
676  switch (op->type) {
677  case WEAPON:
678  if (!(aflags&AP_NOPRINT))
680  "You unwield %s.",
681  name);
682  (void)change_abil(who, op);
684  who->current_weapon = NULL;
685  clear_skill(who);
686  break;
687 
688  case SKILL: /* allows objects to impart skills */
689  case SKILL_TOOL:
690  if (op != who->chosen_skill)
691  LOG(llevError, "BUG: unapply_special(): applied skill is not a chosen skill\n");
692  if (who->type == PLAYER) {
693  if (who->contr->shoottype == range_skill)
694  who->contr->shoottype = range_none;
695  if (!op->invisible) {
696  if (!(aflags&AP_NOPRINT))
698  "You stop using the %s.",
699  name);
700  } else {
701  if (!(aflags&AP_NOPRINT))
703  "You can no longer use the skill: %s.",
704  op->skill);
705  }
706  }
707  (void)change_abil(who, op);
708  who->chosen_skill = NULL;
710  break;
711 
712  case ARMOUR:
713  case HELMET:
714  case SHIELD:
715  case RING:
716  case BOOTS:
717  case GLOVES:
718  case AMULET:
719  case GIRDLE:
720  case BRACERS:
721  case CLOAK:
722  if (!(aflags&AP_NOPRINT))
724  "You unwear %s.",
725  name);
726  (void)change_abil(who, op);
727  break;
728 
729  case BOW:
730  case WAND:
731  case ROD:
732  clear_skill(who);
733  if (!(aflags&AP_NOPRINT))
735  "You unready %s.",
736  name);
737  if (who->type == PLAYER)
738  who->contr->shoottype = range_none;
739  else if (op->type == BOW)
741  else
743  break;
744 
745  case BUILDER:
746  if (!(aflags&AP_NOPRINT))
748  "You unready %s.",
749  name);
750  who->contr->shoottype = range_none;
751  who->contr->ranges[range_builder] = NULL;
752  break;
753 
754  default:
755  if (!(aflags&AP_NOPRINT))
757  "You unapply %s.",
758  name);
759  break;
760  }
761 
762  fix_object(who);
763 
764  if (!(aflags&AP_NO_MERGE)) {
765  object *tmp;
766 
767  tmp = object_merge(op, NULL);
768  if (who->type == PLAYER) {
769  if (tmp) { /* it was merged */
770  op = tmp;
771  }
772  esrv_update_item(UPD_FLAGS, who, op);
773  }
774  }
775  return 0;
776 }
777 
797 static object *get_item_from_body_location(object *start, int loc) {
798  object *tmp;
799 
800  if (!start)
801  return NULL;
802 
803  tmp = start;
805  if (QUERY_FLAG(tmp, FLAG_APPLIED)
806  && tmp->body_info[loc]
807  && (!tmp->invisible || tmp->type == SKILL))
808  return tmp;
810  return NULL;
811 }
812 
834 static int unapply_for_ob(object *who, object *op, int aflags) {
835  int i;
836  object *tmp = NULL, *last;
837  char name[MAX_BUF];
838 
839  /* If we are applying a shield or weapon, unapply any equipped shield
840  * or weapons first - only allowed to use one weapon/shield at a time.
841  */
842  if (op->type == WEAPON || op->type == SHIELD) {
843  FOR_INV_PREPARE(who, tmp) {
844  if (QUERY_FLAG(tmp, FLAG_APPLIED) && tmp->type == op->type) {
845  if (!(aflags&AP_IGNORE_CURSE)
846  && !(aflags&AP_PRINT)
847  && (QUERY_FLAG(tmp, FLAG_CURSED) || QUERY_FLAG(tmp, FLAG_DAMNED))) {
848  /* In this case, we want to try and remove a
849  * cursed item. While we know it won't work, we
850  * want unapply_special to at least generate the
851  * message.
852  */
853  if (!(aflags&AP_NOPRINT)) {
854  query_name(tmp, name, MAX_BUF);
856  "No matter how hard you try, you just can't remove %s.",
857  name);
858  }
859  return 1;
860  }
861 
862  if (aflags&AP_PRINT) {
863  query_name(tmp, name, MAX_BUF);
865  name);
866  } else
867  unapply_special(who, tmp, aflags);
868  }
869  } FOR_INV_FINISH();
870  }
871 
872  for (i = 0; i < NUM_BODY_LOCATIONS; i++) {
873  /* this used up a slot that we need to free */
874  if (op->body_info[i]) {
875  last = who->inv;
876 
877  /* We do a while loop - may need to remove several items
878  * in order to free up enough slots.
879  */
880  while (who->body_used[i]+op->body_info[i] < 0) {
881  tmp = get_item_from_body_location(last, i);
882  if (!tmp)
883  return 1;
884 
885  /* If just printing, we don't care about cursed status */
886  if ((aflags&AP_IGNORE_CURSE)
887  || (aflags&AP_PRINT)
888  || (!(QUERY_FLAG(tmp, FLAG_CURSED) || QUERY_FLAG(tmp, FLAG_DAMNED)))) {
889  if (aflags&AP_PRINT) {
890  query_name(tmp, name, MAX_BUF);
892  name);
893  } else
894  unapply_special(who, tmp, aflags);
895  } else {
896  /* Cursed item that we can't unequip - tell the player.
897  * Note this could be annoying if this is just one of a
898  * few, so it may not be critical (eg, putting on a
899  * ring and you have one cursed ring.)
900  */
901  if (!(aflags&AP_NOPRINT)) {
902  query_name(tmp, name, MAX_BUF);
904  "The %s just won't come off",
905  name);
906  }
907  }
908  last = tmp->below;
909  }
910  /* if we got here, this slot is freed up - otherwise, if it
911  * wasn't freed up, the return in the !tmp would have
912  * kicked in.
913  */
914  } /* if op is using this body location */
915  } /* for body locations */
916  return 0;
917 }
918 
938 int apply_can_apply_object(const object *who, const object *op) {
939  int i, retval = 0;
940  object *tmp = NULL, *ws = NULL;
941 
942  /* Players have 2 'arm's, so they could in theory equip 2 shields or
943  * 2 weapons, but we don't want to let them do that. So if they are
944  * trying to equip a weapon or shield, see if they already have one
945  * in place and store that way.
946  */
947  if (op->type == WEAPON || op->type == SHIELD) {
948  tmp = object_find_by_type_applied(who, op->type);
949  if (tmp != NULL) {
950  retval = CAN_APPLY_UNAPPLY;
951  ws = tmp;
952  }
953  }
954 
955  for (i = 0; i < NUM_BODY_LOCATIONS; i++) {
956  if (op->body_info[i]) {
957  /* Item uses more slots than we have */
958  if (FABS(op->body_info[i]) > who->body_info[i]) {
959  /* Could return now for efficiently - rest of info
960  * below isn't really needed.
961  */
962  retval |= CAN_APPLY_NEVER;
963  } else if (who->body_used[i]+op->body_info[i] < 0) {
964  /* in this case, equipping this would use more free
965  * spots than we have.
966  */
967  object *tmp1;
968 
969  /* if we have an applied weapon/shield, and unapply
970  * it would free enough slots to equip the new item,
971  * then just set this can continue. We don't care
972  * about the logic below - if you have shield equipped
973  * and try to equip another shield, there is only one
974  * choice. However, the check for the number of body
975  * locations does take into the account cases where what
976  * is being applied may be two handed for example.
977  */
978  if (ws) {
979  if (who->body_used[i]-ws->body_info[i]+op->body_info[i] >= 0) {
980  retval |= CAN_APPLY_UNAPPLY;
981  continue;
982  }
983  }
984 
985  tmp1 = get_item_from_body_location(who->inv, i);
986  if (!tmp1)
987  retval |= CAN_APPLY_NEVER;
988  else {
989  /* need to unapply something. However, if this
990  * something is different than we had found before,
991  * it means they need to apply multiple objects
992  */
993  retval |= CAN_APPLY_UNAPPLY;
994  if (!tmp)
995  tmp = tmp1;
996  else if (tmp != tmp1)
997  retval |= CAN_APPLY_UNAPPLY_MULT;
998  /* This object isn't using up all the slots, so
999  * there must be another. If so, and if the new
1000  * item doesn't need all the slots, the player
1001  * then has a choice.
1002  */
1003  if (who->body_used[i]-tmp1->body_info[i] != who->body_info[i]
1004  && FABS(op->body_info[i]) < who->body_info[i])
1005  retval |= CAN_APPLY_UNAPPLY_CHOICE;
1006 
1007  /* Does unequipping 'tmp1' free up enough slots
1008  * for this to be equipped? If not, there must
1009  * be something else to unapply.
1010  */
1011  if (who->body_used[i]+op->body_info[i]-tmp1->body_info[i] < 0)
1012  retval |= CAN_APPLY_UNAPPLY_MULT;
1013  }
1014  } /* if not enough free slots */
1015  } /* if this object uses location i */
1016  } /* for i -> num_body_locations loop */
1017 
1018  /* Do checks for can_use_weapon/shield/armour. */
1019  if (IS_WEAPON(op) && !QUERY_FLAG(who, FLAG_USE_WEAPON))
1020  retval |= CAN_APPLY_RESTRICTION;
1021  if (IS_SHIELD(op) && !QUERY_FLAG(who, FLAG_USE_SHIELD))
1022  retval |= CAN_APPLY_RESTRICTION;
1023  if (IS_ARMOR(op) && !QUERY_FLAG(who, FLAG_USE_ARMOUR))
1024  retval |= CAN_APPLY_RESTRICTION;
1025 
1026  if (who->type != PLAYER) {
1027  if ((op->type == WAND || op->type == ROD)
1028  && !QUERY_FLAG(who, FLAG_USE_RANGE))
1029  retval |= CAN_APPLY_RESTRICTION;
1030  if (op->type == BOW && !QUERY_FLAG(who, FLAG_USE_BOW))
1031  retval |= CAN_APPLY_RESTRICTION;
1032  if (op->type == RING && !QUERY_FLAG(who, FLAG_USE_RING))
1033  retval |= CAN_APPLY_RESTRICTION;
1034  }
1035  return retval;
1036 }
1037 
1053 int apply_check_weapon_power(const object *who, int improves) {
1054  return (who->level/5)+5 >= improves;
1055 }
1056 
1078 int apply_special(object *who, object *op, int aflags) {
1079  int basic_flag = aflags&AP_BASIC_FLAGS;
1080  object *tmp, *skop;
1081  char name_op[MAX_BUF];
1082 
1083  if (who == NULL) {
1084  LOG(llevError, "apply_special() from object without environment.\n");
1085  return 1;
1086  }
1087 
1088  if (op->env != who)
1089  return 1; /* op is not in inventory */
1090 
1091  /* trying to unequip op */
1092  if (QUERY_FLAG(op, FLAG_APPLIED)) {
1093  /* always apply, so no reason to unapply */
1094  if (basic_flag == AP_APPLY)
1095  return 0;
1096 
1097  if (!(aflags&AP_IGNORE_CURSE)
1098  && (QUERY_FLAG(op, FLAG_CURSED) || QUERY_FLAG(op, FLAG_DAMNED))) {
1099  if (!(aflags&AP_NOPRINT)) {
1100  query_name(op, name_op, MAX_BUF);
1102  "No matter how hard you try, you just can't remove %s.",
1103  name_op);
1104  }
1105  return 1;
1106  }
1107  return unapply_special(who, op, aflags);
1108  }
1109 
1110  if (basic_flag == AP_UNAPPLY)
1111  return 0;
1112 
1113  if (!apply_check_apply_restrictions(who, op, aflags))
1114  return 1;
1115 
1116  if (op->skill && op->type != SKILL && op->type != SKILL_TOOL) {
1117  skop = find_skill_by_name(who, op->skill);
1118  if (!skop) {
1119  if (!(aflags&AP_NOPRINT))
1121  "You need the %s skill to use this item!",
1122  op->skill);
1123  if (who->type == PLAYER)
1124  return 1;
1125 
1126  /* monsters do not care about missing skills */
1127  } else
1128  /* While experience will be credited properly, we want to
1129  * change the skill so that the dam and wc get updated
1130  */
1131  change_skill(who, skop, (aflags&AP_NOPRINT));
1132  } else
1133  skop = NULL;
1134 
1135  if (!apply_check_item_power(who, op, aflags))
1136  return 1;
1137 
1138  if (!apply_check_personalized_blessings(who, op))
1139  return 1;
1140 
1141  /* Ok. We are now at the state where we can apply the new object.
1142  * Note that we don't have the checks for can_use_...
1143  * below - that is already taken care of by apply_can_apply_object().
1144  */
1145 
1146  tmp = op->nrof <= 1 ? NULL : object_split(op, op->nrof-1, NULL, 0);
1147 
1148  switch (op->type) {
1149  case WEAPON:
1150  if (!apply_check_weapon_power(who, op->last_eat)) {
1151  if (!(aflags&AP_NOPRINT))
1153  "That weapon is too powerful for you to use. It would consume your soul!");
1154  if (tmp != NULL)
1155  (void)object_insert_in_ob(tmp, who);
1156  return 1;
1157  }
1158 
1159  if (!apply_check_owner(who, op, aflags)) {
1160  if (tmp != NULL)
1161  (void)object_insert_in_ob(tmp, who);
1162  return 1;
1163  }
1164 
1165  SET_FLAG(op, FLAG_APPLIED);
1166 
1167  if (skop)
1168  change_skill(who, skop, 1);
1170 
1171  if (!(aflags&AP_NOPRINT)) {
1172  query_name(op, name_op, MAX_BUF);
1174  "You wield %s.",
1175  name_op);
1176  }
1177 
1178  (void)change_abil(who, op);
1179  break;
1180 
1181  case ARMOUR:
1182  case HELMET:
1183  case SHIELD:
1184  case BOOTS:
1185  case GLOVES:
1186  case GIRDLE:
1187  case BRACERS:
1188  case CLOAK:
1189  case RING:
1190  case AMULET:
1191  SET_FLAG(op, FLAG_APPLIED);
1192  if (!(aflags&AP_NOPRINT)) {
1193  query_name(op, name_op, MAX_BUF);
1195  "You wear %s.",
1196  name_op);
1197  }
1198  (void)change_abil(who, op);
1199  break;
1200 
1201  /* this part is needed for skill-tools */
1202  case SKILL:
1203  case SKILL_TOOL:
1204  if (who->chosen_skill) {
1205  LOG(llevError, "BUG: apply_special(): can't apply two skills\n");
1206  return 1;
1207  }
1208 
1209  apply_update_ranged_skill(who, op, aflags);
1210  SET_FLAG(op, FLAG_APPLIED);
1211  (void)change_abil(who, op);
1212  who->chosen_skill = op;
1213  SET_FLAG(who, FLAG_READY_SKILL);
1214  break;
1215 
1216  case BOW:
1217  if (!apply_check_weapon_power(who, op->last_eat)) {
1218  if (!(aflags&AP_NOPRINT))
1220  "That weapon is too powerful for you to use. It would consume your soul!");
1221  if (tmp != NULL)
1222  (void)object_insert_in_ob(tmp, who);
1223  return 1;
1224  }
1225 
1226  if (!apply_check_owner(who, op, aflags)) {
1227  if (tmp != NULL)
1228  (void)object_insert_in_ob(tmp, who);
1229  return 1;
1230  }
1231  /*FALLTHROUGH*/
1232  case WAND:
1233  case ROD:
1234  /* check for skill, alter player status */
1235  SET_FLAG(op, FLAG_APPLIED);
1236  if (skop)
1237  change_skill(who, skop, 0);
1238  if (!(aflags&AP_NOPRINT)) {
1239  query_name(op, name_op, MAX_BUF);
1241  "You ready %s.",
1242  name_op);
1243  }
1244  if (who->type == PLAYER) {
1245  if (op->type == BOW) {
1246  (void)change_abil(who, op);
1247  if (!(aflags&AP_NOPRINT)) {
1248  query_name(op, name_op, MAX_BUF);
1250  "You will now fire %s with %s.",
1251  op->race ? op->race : "nothing",
1252  name_op);
1253  }
1254  who->contr->shoottype = range_bow;
1255  } else
1256  who->contr->shoottype = range_misc;
1257  } else {
1258  if (op->type == BOW)
1259  SET_FLAG(who, FLAG_READY_BOW);
1260  else
1261  SET_FLAG(who, FLAG_READY_RANGE);
1262  }
1263  break;
1264 
1265  case BUILDER:
1266  if (who->contr->ranges[range_builder])
1267  unapply_special(who, who->contr->ranges[range_builder], 0);
1268  who->contr->shoottype = range_builder;
1269  who->contr->ranges[range_builder] = op;
1270  if (!(aflags&AP_NOPRINT)) {
1271  query_name(op, name_op, MAX_BUF);
1273  "You ready your %s.",
1274  name_op);
1275  }
1276  break;
1277 
1278  default:
1279  query_name(op, name_op, MAX_BUF);
1281  "You apply %s.",
1282  name_op);
1283  break;
1284  } /* end of switch op->type */
1285 
1286  SET_FLAG(op, FLAG_APPLIED);
1287 
1288  if (tmp != NULL)
1289  tmp = object_insert_in_ob(tmp, who);
1290 
1291  fix_object(who);
1292 
1293  /* We exclude spell casting objects. The fire code will set the
1294  * been applied flag when they are used - until that point,
1295  * you don't know anything about them.
1296  */
1297  if (who->type == PLAYER && op->type != WAND && op->type != ROD)
1299 
1300  if (QUERY_FLAG(op, FLAG_CURSED) || QUERY_FLAG(op, FLAG_DAMNED)) {
1301  if (who->type == PLAYER) {
1303  "Oops, it feels deadly cold!");
1305  }
1306  }
1307  if (who->type == PLAYER)
1309  return 0;
1310 }
1311 
1325 int apply_auto(object *op) {
1326  object *tmp;
1327 
1328  switch (op->type) {
1329  case SHOP_FLOOR:
1330  if (!HAS_RANDOM_ITEMS(op))
1331  return 0;
1332  do {
1333  int i;
1334 
1335  i = 10; /* let's give it 10 tries */
1336  while ((tmp = generate_treasure(op->randomitems, op->stats.exp ? (int)op->stats.exp : MAX(op->map->difficulty, 5))) == NULL
1337  && --i)
1338  ;
1339  if (tmp == NULL)
1340  return 0;
1341  if (QUERY_FLAG(tmp, FLAG_CURSED) || QUERY_FLAG(tmp, FLAG_DAMNED)) {
1343  tmp = NULL;
1344  }
1345  } while (!tmp);
1346  SET_FLAG(tmp, FLAG_UNPAID);
1347  object_insert_in_map_at(tmp, op->map, NULL, 0, op->x, op->y);
1349  identify(tmp);
1350  return 1;
1351  break;
1352 
1353  case TREASURE:
1354  if (QUERY_FLAG(op, FLAG_IS_A_TEMPLATE))
1355  return 0;
1356  while (op->stats.hp-- > 0)
1357  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);
1358 
1359  /* If we generated an object and put it in this object's
1360  * inventory, move it to the parent object as the current
1361  * object is about to disappear. An example of this item
1362  * is the random_ *stuff that is put inside other objects.
1363  */
1364  FOR_INV_PREPARE(op, tmp) {
1365  object_remove(tmp);
1366  if (op->env)
1367  object_insert_in_ob(tmp, op->env);
1368  else
1370  } FOR_INV_FINISH();
1371  object_remove(op);
1373  break;
1374  }
1375  return 0;
1376 }
1377 
1392  int x, y;
1393 
1394  if (m == NULL)
1395  return;
1396 
1397  for (x = 0; x < MAP_WIDTH(m); x++)
1398  for (y = 0; y < MAP_HEIGHT(m); y++)
1399  FOR_MAP_PREPARE(m, x, y, tmp) {
1400  if (tmp->inv) {
1401  FOR_INV_PREPARE(tmp, invtmp) {
1402  if (QUERY_FLAG(invtmp, FLAG_AUTO_APPLY))
1403  apply_auto(invtmp);
1404  else if (invtmp->type == TREASURE && HAS_RANDOM_ITEMS(invtmp)) {
1405  while (invtmp->stats.hp-- > 0)
1406  create_treasure(invtmp->randomitems, invtmp, 0, m->difficulty, 0);
1407  invtmp->randomitems = NULL;
1408  } else if (invtmp && invtmp->arch
1409  && invtmp->type != TREASURE
1410  && invtmp->type != SPELL
1411  && invtmp->type != CLASS
1412  && HAS_RANDOM_ITEMS(invtmp)) {
1413  create_treasure(invtmp->randomitems, invtmp, 0, m->difficulty, 0);
1414  /* Need to clear this so that we never try to
1415  * create treasure again for this object
1416  */
1417  invtmp->randomitems = NULL;
1418  }
1419  } FOR_INV_FINISH();
1420  /* This is really temporary - the code at the
1421  * bottom will also set randomitems to null.
1422  * The problem is there are bunches of maps/players
1423  * already out there with items that have spells
1424  * which haven't had the randomitems set
1425  * to null yet.
1426  * MSW 2004-05-13
1427  *
1428  * And if it's a spellbook, it's better to set
1429  * randomitems to NULL too, else you get two spells
1430  * in the book ^_-
1431  * Ryo 2004-08-16
1432  */
1433  if (tmp->type == WAND
1434  || tmp->type == ROD
1435  || tmp->type == SCROLL
1436  || tmp->type == FIREWALL
1437  || tmp->type == POTION
1438  || tmp->type == ALTAR
1439  || tmp->type == SPELLBOOK)
1440  tmp->randomitems = NULL;
1441  }
1442 
1443  if (QUERY_FLAG(tmp, FLAG_AUTO_APPLY))
1444  apply_auto(tmp);
1445  else if ((tmp->type == TREASURE || tmp->type == CONTAINER)
1446  && HAS_RANDOM_ITEMS(tmp)) {
1447  while (tmp->stats.hp-- > 0)
1448  create_treasure(tmp->randomitems, tmp, 0, m->difficulty, 0);
1449  tmp->randomitems = NULL;
1450  } else if (tmp->type == TIMED_GATE) {
1451  object *head = HEAD(tmp);
1452 
1453  if (QUERY_FLAG(head, FLAG_IS_LINKED)) {
1454  tmp->speed = 0;
1455  object_update_speed(tmp);
1456  }
1457  }
1458  /* This function can be called every time a map is loaded,
1459  * even when swapping back in. As such, we don't want to
1460  * create the treasure over and over again, so after we
1461  * generate the treasure, blank out randomitems so if it
1462  * is swapped in again, it won't make anything. This is a
1463  * problem for the above objects, because they have
1464  * counters which say how many times to make the treasure.
1465  */
1466  else if (tmp
1467  && tmp->arch
1468  && tmp->type != PLAYER
1469  && tmp->type != TREASURE
1470  && tmp->type != SPELL
1471  && tmp->type != PLAYER_CHANGER
1472  && tmp->type != CLASS
1473  && HAS_RANDOM_ITEMS(tmp)) {
1474  create_treasure(tmp->randomitems, tmp, 0, m->difficulty, 0);
1475  tmp->randomitems = NULL;
1476  }
1477 
1478  if (QUERY_FLAG(tmp, FLAG_MONSTER))
1480  } FOR_MAP_FINISH();
1481 
1482  for (x = 0; x < MAP_WIDTH(m); x++)
1483  for (y = 0; y < MAP_HEIGHT(m); y++)
1484  FOR_MAP_PREPARE(m, x, y, tmp) {
1485  if (tmp->above
1486  && (tmp->type == TRIGGER_BUTTON || tmp->type == TRIGGER_PEDESTAL))
1487  check_trigger(tmp, tmp->above);
1488  } FOR_MAP_FINISH();
1489 }
1490 
1505 void scroll_failure(object *op, int failure, int power) {
1506  if (abs(failure/4) > power)
1507  power = abs(failure/4); /* set minimum effect */
1508 
1509  if (failure <= -1 && failure > -15) {/* wonder */
1510  object *tmp;
1511 
1513  "Your spell warps!");
1515  cast_wonder(op, op, 0, tmp);
1516  if (op->stats.sp < 0)
1517  /* For some reason the sp can become negative here. */
1518  op->stats.sp = 0;
1520  return;
1521  }
1522 
1524  if (failure <= -35 && failure > -60) { /* confusion */
1526  "The magic recoils on you!");
1527  confuse_living(op, op, power);
1528  return;
1529  }
1530 
1531  if (failure <= -60 && failure > -70) {/* paralysis */
1533  "The magic recoils and paralyzes you!");
1534  paralyze_living(op, power);
1535  return;
1536  }
1537 
1538  if (failure <= -70 && failure > -80) {/* blind */
1540  "The magic recoils on you!");
1541  blind_living(op, op, power);
1542  return;
1543  }
1544 
1545  if (failure <= -80) {/* blast the immediate area */
1546  object *tmp;
1547 
1549  cast_magic_storm(op, tmp, power);
1551  "You unlease uncontrolled mana!");
1553  return;
1554  }
1555  }
1556  /* Either no spell failure on this server, or wrong values,
1557  * in any case let's punish.
1558  */
1560  "Your mana is drained!");
1561  op->stats.sp -= random_roll(0, power-1, op, PREFER_LOW);
1562  if (op->stats.sp < 0)
1563  op->stats.sp = 0;
1564 }
1565 
1577 void apply_changes_to_player(object *pl, object *change, int limit_stats) {
1578  int i, j;
1579  int excess_stat = 0; /* if the stat goes over the maximum
1580  * for the race, put the excess stat some
1581  * where else.
1582  */
1583 
1584  if (change->type != CLASS) return;
1585 
1586  /* the following code assigns stats up to the stat max
1587  * for the race, and if the stat max is exceeded,
1588  * tries to randomly reassign the excess stat
1589  */
1590  if (! (limit_stats & AC_PLAYER_STAT_NO_CHANGE)) {
1591  for (i = 0; i < NUM_STATS; i++) {
1592  int8_t stat = get_attr_value(&pl->contr->orig_stats, i);
1593  int race_bonus = get_attr_value(&pl->arch->clone.stats, i);
1594 
1595  stat += get_attr_value(&change->stats, i);
1596  if (limit_stats & AC_PLAYER_STAT_LIMIT) {
1597  if (stat > 20+race_bonus) {
1598  excess_stat++;
1599  stat = 20+race_bonus;
1600  } else if (stat < 1) {
1601  /* I didn't see any code here before to make sure minimum
1602  * stats were enforced - maybe it was just dumb
1603  * luck that one would not have a stat low enough that then
1604  * has a stat penalty for class that would bring it negative?
1605  * I imagine a negative stat would crash the server pretty
1606  * quickly - MSW, Sept 2010
1607  */
1608  excess_stat += stat;
1609  stat = 1;
1610  }
1611  }
1612  set_attr_value(&pl->contr->orig_stats, i, stat);
1613  }
1614 
1615  /* Maybe we should randomly deduct stats in this case?
1616  * It's will go away sometime soon in any case.
1617  */
1618  if (excess_stat < 0) excess_stat = 0;
1619 
1620  /* We don't put an explicit check for limit_stats here -
1621  * excess stat will never be 0 if limit_stats is not
1622  * true.
1623  */
1624  for (j = 0; excess_stat > 0 && j < 100; j++) {
1625  /* try 100 times to assign excess stats */
1626  int i = rndm(0, NUM_STATS-1);
1627  int stat = get_attr_value(&pl->contr->orig_stats, i);
1628  int race_bonus = get_attr_value(&pl->arch->clone.stats, i);
1629 
1630  if (i == CHARISMA) {
1631  continue; /* exclude cha from this */
1632  }
1633 
1634  if (stat < 20+race_bonus) {
1635  change_attr_value(&pl->contr->orig_stats, i, 1);
1636  excess_stat--;
1637  }
1638  }
1639  }
1640  /* Done with stat processing */
1641 
1642  /* insert the randomitems from the change's treasurelist into
1643  * the player ref: player.c
1644  */
1645  if (change->randomitems != NULL)
1646  give_initial_items(pl, change->randomitems);
1647 
1648 
1649  /* set up the face, for some races. */
1650 
1651  /* first, look for the force object banning changing the
1652  * face. Certain races never change face with class.
1653  */
1654  if (object_find_by_name(pl, "NOCLASSFACECHANGE") == NULL) {
1655  pl->animation_id = GET_ANIM_ID(change);
1656  pl->face = change->face;
1657 
1658  if (QUERY_FLAG(change, FLAG_ANIMATE))
1659  SET_FLAG(pl, FLAG_ANIMATE);
1660  else
1661  CLEAR_FLAG(pl, FLAG_ANIMATE);
1662  }
1663 
1664  if (change->anim_suffix) {
1665  char buf[MAX_BUF];
1666  int anim;
1667 
1668  snprintf(buf, MAX_BUF, "%s_%s", animations[pl->animation_id].name, change->anim_suffix);
1669  anim = try_find_animation(buf);
1670  if (anim) {
1671  pl->animation_id = anim;
1672  pl->anim_speed = -1;
1673  CLEAR_FLAG(pl, FLAG_ANIMATE);
1674  animate_object(pl, pl->facing);
1675  }
1676  }
1677  /* Hard coding in class name is a horrible idea - lets
1678  * use the supported mechanism for this
1679  */
1680  if (object_present_in_ob_by_name(FORCE, "no weapon force", pl))
1682 
1683 }
1684 
1685 void legacy_apply_container(object *op, object *sack) {
1686  apply_container(op, sack);
1687 }
1688 
1702 static int apply_check_apply_restrictions(object *who, object *op, int aflags) {
1703  int i;
1704 
1705  i = apply_can_apply_object(who, op);
1706  if (i == 0)
1707  return 1;
1708 
1709  /* Can't just apply this object. Lets see why not and what to do */
1710 
1711  if (i&CAN_APPLY_NEVER) {
1712  if (!(aflags&AP_NOPRINT)) {
1713  char name_op[MAX_BUF];
1714 
1715  query_name(op, name_op, MAX_BUF);
1717  "You don't have the body to use a %s",
1718  name_op);
1719  }
1720  return 0;
1721  }
1722 
1723  if (i&CAN_APPLY_RESTRICTION) {
1724  if (!(aflags&AP_NOPRINT)) {
1725  char name_op[MAX_BUF];
1726 
1727  query_name(op, name_op, MAX_BUF);
1729  "You have a prohibition against using a %s",
1730  name_op);
1731  }
1732  return 0;
1733  }
1734 
1735  if (who->type != PLAYER) {
1736  /* Some error, so don't try to equip something more */
1737  return !unapply_for_ob(who, op, aflags);
1738  }
1739 
1740  if (who->contr->unapply == unapply_never
1742  if (!(aflags&AP_NOPRINT))
1744  "You need to unapply some item(s):");
1745  unapply_for_ob(who, op, AP_PRINT);
1746  return 0;
1747  }
1748 
1749  if (who->contr->unapply == unapply_always
1750  || !(i&CAN_APPLY_UNAPPLY_CHOICE)) {
1751  return !unapply_for_ob(who, op, aflags);
1752  }
1753 
1754  return 1;
1755 }
1756 
1769 static int apply_check_item_power(const object *who, const object *op, int aflags) {
1770  if (who->type != PLAYER)
1771  return 1;
1772 
1773  if (op->item_power == 0
1775  return 1;
1776 
1777  if (!(aflags&AP_NOPRINT))
1779  "Equipping that combined with other items would consume your soul!");
1780  return 0;
1781 }
1782 
1797 static int apply_check_personalized_blessings(object *who, const object *op) {
1798  const char *owner;
1799  const char *will;
1800  long item_will;
1801  long margin;
1802  const char *msg;
1803  int random_effect;
1804  int damage_percentile;
1805 
1807  return 1;
1808  }
1809 
1810  owner = object_get_value(op, "item_owner");
1811  if (owner == NULL || strcmp(owner, who->name) == 0)
1812  return 1;
1813 
1814  will = object_get_value(op, "item_willpower");
1815  item_will = will != NULL ? atol(will) : 0;
1816  if (item_will > who->stats.exp) {
1818  "This %s refuses to serve you - it keeps evading your hand !",
1819  op->name);
1820  return 0;
1821  }
1822 
1823  margin = item_will != 0 ? who->stats.exp/item_will : who->stats.exp;
1824  random_effect = random_roll(0, 100, who, 1)-margin*20;
1825  if (random_effect > 80) {
1826  msg = "You don't know why, but you have the feeling that the %s is angry at you !";
1827  damage_percentile = 60;
1828  } else if (random_effect > 60) {
1829  msg = "The %s seems to look at you nastily !";
1830  damage_percentile = 45;
1831  } else if (random_effect > 40) {
1832  msg = "You have the strange feeling that the %s is annoyed...";
1833  damage_percentile = 30;
1834  } else if (random_effect > 20) {
1835  msg = "The %s seems tired, or bored, in a way. Very strange !";
1836  damage_percentile = 15;
1837  } else if (random_effect > 0) {
1838  msg = "You hear the %s sighing !";
1839  damage_percentile = 0;
1840  } else {
1841  msg = NULL;
1842  damage_percentile = 0;
1843  }
1844  if (msg != NULL)
1846  msg, op->name);
1847  if (damage_percentile > 0) {
1848  int weapon_bite = (who->stats.hp*damage_percentile)/100;
1849  if (weapon_bite < 1)
1850  weapon_bite = 1;
1851  who->stats.hp -= weapon_bite;
1853  "You get a nasty bite in the hand !");
1854  }
1855 
1856  return 1;
1857 }
1858 
1873 static int apply_check_owner(const object *who, const object *op, int aflags) {
1874  const char *quotepos;
1875 
1876  if (op->level == 0)
1877  return 1;
1878 
1879  quotepos = strstr(op->name, "'");
1880  if (quotepos == NULL || strncmp(op->name, who->name, quotepos-op->name) == 0)
1881  return 1;
1882 
1883  if (!(aflags&AP_NOPRINT))
1885  "The weapon does not recognize you as its owner.");
1886  return 0;
1887 }
1888 
1899 static void apply_update_ranged_skill(const object *who, object *op, int aflags) {
1900  if (who->type != PLAYER) {
1901  return;
1902  }
1903 
1904  who->contr->shoottype = range_skill;
1905  who->contr->ranges[range_skill] = op;
1906  if (op->invisible) {
1907  if (!(aflags&AP_NOPRINT))
1909  "Readied skill: %s.",
1910  op->skill ? op->skill : op->name);
1911  } else {
1912  if (!(aflags&AP_NOPRINT)) {
1913  char name_op[MAX_BUF];
1914 
1915  query_name(op, name_op, MAX_BUF);
1917  "You ready %s.",
1918  name_op);
1920  "You can now use the skill: %s.",
1921  op->skill);
1922  }
1923  }
1924 }
void draw_ext_info_format(int flags, int pri, const object *pl, uint8_t type, uint8_t subtype, const char *format,...)
Definition: main.c:315
#define AP_UNAPPLY
Definition: define.h:613
static int apply_check_owner(const object *who, const object *op, int aflags)
Definition: apply.c:1873
void set_attr_value(living *stats, int attr, int8_t value)
Definition: living.c:218
#define NUM_BODY_LOCATIONS
Definition: object.h:13
Definition: player.h:92
static int apply_check_race_restrictions(object *who, object *item)
Definition: apply.c:467
#define FLAG_DAMNED
Definition: define.h:318
#define FLAG_IS_FLOOR
Definition: define.h:303
#define FLAG_UNPAID
Definition: define.h:236
int32_t weight_limit
Definition: object.h:366
#define FLAG_IS_LINKED
Definition: define.h:316
MoveType move_type
Definition: object.h:424
#define INS_BELOW_ORIGINATOR
Definition: object.h:570
int change_skill(object *who, object *new_skill, int flag)
Definition: skill_util.c:339
void legacy_apply_container(object *op, object *sack)
Definition: apply.c:1685
MoveType move_on
Definition: object.h:427
Definition: object.h:185
#define CAN_APPLY_UNAPPLY_CHOICE
Definition: define.h:672
object * check_spell_known(object *op, const char *name)
Definition: spell_util.c:433
const char * race
Definition: object.h:318
#define MSG_TYPE_APPLY_PROHIBITION
Definition: newclient.h:603
void esrv_send_item(object *pl, object *op)
Definition: main.c:339
#define SET_FLAG(xyz, p)
Definition: define.h:223
object * object_find_by_type_applied(const object *who, int type)
Definition: object.c:3997
#define FABS(x)
Definition: define.h:22
Definition: object.h:221
#define MSG_TYPE_APPLY_FAILURE
Definition: newclient.h:599
New_Face * new_faces
Definition: image.c:33
#define MSG_TYPE_APPLY_BADBODY
Definition: newclient.h:602
uint16_t animation_id
Definition: object.h:416
const char * name
Definition: face.h:27
#define FLAG_USE_ARMOUR
Definition: define.h:296
uint8_t anim_speed
Definition: object.h:417
Definition: object.h:204
struct obj * container
Definition: object.h:291
void do_forget_spell(object *op, const char *spell)
Definition: apply.c:432
#define METHOD_ERROR
Definition: ob_methods.h:17
static int apply_check_item_power(const object *who, const object *op, int aflags)
Definition: apply.c:1769
#define FLAG_READY_RANGE
Definition: define.h:299
void esrv_update_item(int flags, object *pl, object *op)
Definition: main.c:342
const char * object_get_value(const object *op, const char *const key)
Definition: object.c:4269
struct treasureliststruct * randomitems
Definition: object.h:385
#define MAP_HEIGHT(m)
Definition: map.h:80
object clone
Definition: object.h:470
socket_struct socket
Definition: player.h:94
#define CAN_APPLY_NEVER
Definition: define.h:667
int16_t invisible
Definition: object.h:360
#define PREFER_LOW
Definition: define.h:602
int apply_auto(object *op)
Definition: apply.c:1325
rangetype shoottype
Definition: player.h:99
Definition: object.h:119
Definition: object.h:136
const char * slaying
Definition: object.h:319
#define IS_WEAPON(op)
Definition: define.h:162
void esrv_send_inventory(object *pl, object *op)
Definition: item.c:307
Definition: object.h:138
object * ranges[range_size]
Definition: player.h:103
uint8_t subtype
Definition: object.h:339
Definition: object.h:109
static void apply_update_ranged_skill(const object *who, object *op, int aflags)
Definition: apply.c:1899
#define FLAG_USE_WEAPON
Definition: define.h:297
int64_t exp
Definition: living.h:47
#define FLAG_BLESSED
Definition: define.h:378
#define SPELL_WONDER
Definition: spells.h:163
#define FREE_OBJ_NO_DESTROY_CALLBACK
Definition: object.h:531
void blind_living(object *op, object *hitter, int dam)
Definition: attack.c:2305
uint16_t container_position
Definition: newserver.h:115
#define object_was_destroyed(op, old_tag)
Definition: object.h:68
#define TRUE
Definition: compat.h:10
Definition: object.h:223
Definition: object.h:139
int8_t get_attr_value(const living *stats, int attr)
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)
Definition: ob_methods.c:44
void scroll_failure(object *op, int failure, int power)
Definition: apply.c:1505
int set_object_face_main(object *op)
Definition: apply.c:149
int16_t sp
Definition: living.h:42
Definition: object.h:212
#define SCRIPT_FIX_ALL
Definition: global.h:361
#define AP_APPLY
Definition: define.h:612
struct archt * other_arch
Definition: object.h:413
#define FLAG_USE_RING
Definition: define.h:298
object * object_find_by_name(const object *who, const char *name)
Definition: object.c:3902
void draw_ext_info(int flags, int pri, const object *pl, uint8_t type, uint8_t subtype, const char *message)
Definition: main.c:310
Definition: object.h:220
#define MSG_TYPE_APPLY
Definition: newclient.h:384
#define FOR_OB_AND_BELOW_FINISH()
Definition: define.h:791
void esrv_add_spells(player *pl, object *spell)
Definition: request.c:1767
int16_t hp
Definition: living.h:40
uint16_t number
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)
Definition: treasure.c:488
#define LOOSE_MANA
Definition: spells.h:162
#define CAN_APPLY_UNAPPLY_MULT
Definition: define.h:671
#define MOVE_ALL
Definition: define.h:413
int rndm(int min, int max)
Definition: utils.c:162
void apply_changes_to_player(object *pl, object *change, int limit_stats)
Definition: apply.c:1577
void apply_handle_yield(object *tmp)
Definition: apply.c:125
#define FLAG_READY_SKILL
Definition: define.h:334
static int apply_check_personalized_blessings(object *who, const object *op)
Definition: apply.c:1797
struct obj * chosen_skill
Definition: object.h:386
int object_set_value(object *op, const char *key, const char *value, int add_key)
Definition: object.c:4398
void object_free_drop_inventory(object *ob)
Definition: object.c:1389
int change_abil(object *op, object *tmp)
Definition: living.c:394
const char * name
Definition: face.h:20
int16_t y
Definition: object.h:326
#define CAN_APPLY_UNAPPLY
Definition: define.h:670
object * object_insert_in_map_at(object *op, mapstruct *m, object *originator, int flag, int x, int y)
Definition: object.c:1936
int should_director_abort(const object *op, const object *victim)
Definition: apply.c:68
Definition: object.h:118
int apply_special(object *who, object *op, int aflags)
Definition: apply.c:1078
void confuse_living(object *op, object *hitter, int dam)
Definition: attack.c:2266
#define AP_IGNORE_CURSE
Definition: define.h:619
#define MSG_TYPE_VICTIM
Definition: newclient.h:392
object * object_new(void)
Definition: object.c:1068
#define CAN_APPLY_RESTRICTION
Definition: define.h:668
object * create_archetype(const char *name)
Definition: arch.c:620
object * object_insert_in_ob(object *op, object *where)
Definition: object.c:2710
unapplymode unapply
Definition: player.h:108
static object * get_item_from_body_location(object *start, int loc)
Definition: apply.c:797
int32_t weight
Definition: object.h:365
#define AC_PLAYER_STAT_LIMIT
Definition: define.h:634
const char * anim_suffix
Definition: object.h:316
#define METHOD_OK
Definition: ob_methods.h:15
#define AP_PRINT
Definition: define.h:620
#define FLAG_USE_SHIELD
Definition: define.h:237
#define FLAG_USE_RANGE
Definition: define.h:293
struct mapdef * map
Definition: object.h:297
void monster_check_apply_all(object *monster)
Definition: monster.c:1821
#define snprintf
Definition: win32.h:46
#define MSG_TYPE_APPLY_ERROR
Definition: newclient.h:596
#define EVENT_CLOSE
Definition: plugin.h:75
object * transport
Definition: player.h:195
#define FOR_INV_FINISH()
Definition: define.h:714
#define MOVE_FLYING
Definition: define.h:410
void change_attr_value(living *stats, int attr, int8_t value)
Definition: living.c:264
int32_t carrying
Definition: object.h:367
const char * name
Definition: object.h:311
living orig_stats
Definition: player.h:148
struct obj * env
Definition: object.h:293
struct obj * below
Definition: object.h:287
#define MSG_TYPE_VICTIM_WAS_HIT
Definition: newclient.h:647
#define FLAG_IS_A_TEMPLATE
Definition: define.h:375
struct obj * current_weapon
Definition: object.h:370
uint32_t nrof
Definition: object.h:333
#define AP_NOPRINT
Definition: define.h:623
#define UPD_FLAGS
Definition: newclient.h:290
void paralyze_living(object *op, int dam)
Definition: attack.c:2349
MoveType move_off
Definition: object.h:428
EXTERN Animations * animations
Definition: global.h:163
int transport_can_hold(const object *transport, const object *op, int nrof)
Definition: apply.c:54
Definition: object.h:111
struct pl * contr
Definition: object.h:276
int8_t item_power
Definition: object.h:362
int try_find_animation(const char *name)
Definition: anim.c:186
void player_unready_range_ob(player *pl, object *ob)
Definition: player.c:4449
void cast_magic_storm(object *op, object *tmp, int lvl)
Definition: spell_effect.c:44
#define UPD_WEIGHT
Definition: newclient.h:291
uint32_t tag_t
Definition: object.h:12
int apply_by_living(object *pl, object *op, int aflag, int quiet)
Definition: apply.c:553
Definition: object.h:214
int cast_wonder(object *op, object *caster, int dir, object *spell_ob)
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)
Definition: apply.c:834
#define HEAD(op)
Definition: object.h:592
#define MSG_TYPE_APPLY_UNAPPLY
Definition: newclient.h:597
#define FLAG_WIZ
Definition: define.h:231
#define FLAG_BEEN_APPLIED
Definition: define.h:324
#define MAX_BUF
Definition: define.h:35
#define METHOD_UNHANDLED
Definition: ob_methods.h:16
void give_initial_items(object *pl, treasurelist *items)
Definition: player.c:763
#define IS_SHIELD(op)
Definition: define.h:169
Definition: object.h:126
int16_t x
Definition: object.h:326
void drop(object *op, object *tmp)
Definition: c_object.c:920
static int apply_check_apply_restrictions(object *who, object *op, int aflags)
Definition: apply.c:1702
const char * skill
Definition: object.h:321
int32_t last_eat
Definition: object.h:356
Definition: object.h:201
#define AC_PLAYER_STAT_NO_CHANGE
Definition: define.h:635
uint16_t difficulty
Definition: map.h:343
#define FLAG_READY_WEAPON
Definition: define.h:335
static int unapply_special(object *who, object *op, int aflags)
Definition: apply.c:670
#define FOR_MAP_FINISH()
Definition: define.h:767
void animate_object(object *op, int dir)
Definition: anim.c:213
#define FLAG_KNOWN_CURSED
Definition: define.h:321
const char * sstring
Definition: global.h:40
#define AP_BASIC_FLAGS
Definition: define.h:615
#define FLAG_CURSED
Definition: define.h:317
Definition: object.h:107
#define AP_NO_MERGE
Definition: define.h:618
void apply_auto_fix(mapstruct *m)
Definition: apply.c:1391
Definition: object.h:135
#define FLAG_ANIMATE
Definition: define.h:242
#define FLAG_AUTO_APPLY
Definition: define.h:250
int8_t body_info[NUM_BODY_LOCATIONS]
Definition: object.h:372
object * object_split(object *orig_ob, uint32_t nr, char *err, size_t size)
Definition: object.c:2481
#define INS_NO_MERGE
Definition: object.h:566
Definition: object.h:122
void play_sound_player_only(player *pl, int8_t sound_type, object *emitter, int dir, const char *action)
Definition: sounds.c:51
#define UPD_NROF
Definition: newclient.h:296
signed char int8_t
Definition: win32.h:158
Definition: object.h:143
int apply_container(object *op, object *sack)
Definition: apply.c:216
tag_t count
Definition: object.h:299
living stats
Definition: object.h:368
struct archt * arch
Definition: object.h:412
#define UPD_FACE
Definition: newclient.h:292
#define MAP_WIDTH(m)
Definition: map.h:78
void clear_skill(object *who)
Definition: skill_util.c:378
uint8_t type
Definition: object.h:338
struct Settings settings
Definition: init.c:40
void object_free2(object *ob, int flags)
Definition: object.c:1412
void esrv_remove_spell(player *pl, object *spell)
Definition: request.c:1630
#define METHOD_SILENT_ERROR
Definition: ob_methods.h:18
#define FLAG_APPLIED
Definition: define.h:235
object * object_merge(object *op, object *top)
Definition: object.c:1884
int execute_event(object *op, int eventcode, object *activator, object *third, const char *message, int fix)
Definition: main.c:364
#define UPD_NAME
Definition: newclient.h:293
#define MSG_TYPE_APPLY_SUCCESS
Definition: newclient.h:598
#define FOR_OB_AND_BELOW_PREPARE(op_)
Definition: define.h:787
#define FLAG_STARTEQUIP
Definition: define.h:268
#define GET_ANIM_ID(ob)
Definition: global.h:171
int apply_manual(object *op, object *tmp, int aflag)
Definition: apply.c:510
object * identify(object *op)
Definition: item.c:1432
#define MSG_TYPE_APPLY_CURSED
Definition: newclient.h:600
#define FLAG_MONSTER
Definition: define.h:245
void object_copy(const object *src_ob, object *dest_ob)
Definition: object.c:869
void apply_by_living_below(object *pl)
Definition: apply.c:614
void do_learn_spell(object *op, object *spell, int special_prayer)
Definition: apply.c:391
struct obj * inv
Definition: object.h:290
#define NDI_UNIQUE
Definition: newclient.h:245
void apply_anim_suffix(object *who, sstring suffix)
Definition: anim.c:319
Definition: object.h:213
#define FLAG_READY_BOW
Definition: define.h:300
void LOG(LogLevel logLevel, const char *format,...)
Definition: logger.c:51
int16_t item_power
Definition: player.h:117
#define FLAG_WAS_WIZ
Definition: define.h:234
#define FOR_MAP_PREPARE(map_, mx_, my_, it_)
Definition: define.h:760
void play_sound_map(int8_t sound_type, object *emitter, int dir, const char *action)
Definition: sounds.c:98
#define IS_ARMOR(op)
Definition: define.h:165
int check_trigger(object *op, object *cause)
Definition: button.c:523
object * find_key(object *pl, object *container, object *door)
Definition: player.c:2532
void query_name(const object *op, char *buf, size_t size)
Definition: item.c:623
object * generate_treasure(treasurelist *t, int difficulty)
Definition: treasure.c:516
Definition: map.h:325
int random_roll(int min, int max, const object *op, int goodbad)
Definition: utils.c:42
const New_Face * face
Definition: object.h:332
static int set_object_face_other(object *op)
Definition: apply.c:173
Definition: object.h:120
int16_t level
Definition: object.h:351
int8_t facing
Definition: object.h:335
uint8_t spell_failure_effects
Definition: global.h:265
void fix_object(object *op)
Definition: living.c:1119
unsigned find_face(const char *name, unsigned error)
Definition: image.c:303
#define SOUND_TYPE_SPELL
Definition: newclient.h:309
object * find_skill_by_name(object *who, const char *name)
Definition: skill_util.c:191
void object_update_speed(object *op)
Definition: object.c:1150
int apply_can_apply_object(const object *who, const object *op)
Definition: apply.c:938
float item_power_factor
Definition: global.h:300
const char * name
Definition: object.h:466
#define FLAG_USE_BOW
Definition: define.h:294
#define HAS_RANDOM_ITEMS(op)
Definition: define.h:183
object * object_present_in_ob_by_name(int type, const char *str, const object *op)
Definition: object.c:3059
#define FOR_INV_PREPARE(op_, it_)
Definition: define.h:707
void object_remove(object *op)
Definition: object.c:1669
uint8_t personalized_blessings
Definition: global.h:309
int8_t body_used[NUM_BODY_LOCATIONS]
Definition: object.h:373
int apply_check_weapon_power(const object *who, int improves)
Definition: apply.c:1053
Definition: object.h:224