Crossfire Server, Trunk  R21466
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 (op->more)
155 
156  if (saved)
157  newface = find_face(saved, newface);
158  if (newface && op->face != &new_faces[newface]) {
159  op->face = &new_faces[newface];
160  return TRUE;
161  }
162  return FALSE;
163 }
164 
176 static int set_object_face_other(object *op) {
177  sstring custom;
178  int newface = 0;
179  object *head = op->head ? op->head : op;
180 
181  if (op->more)
183 
184  if (head->face && head->other_arch && head->other_arch->clone.face)
185  newface = head->other_arch->clone.face->number;
186 
187  if (op->face != op->arch->clone.face) {
188  /* object has a custom face, save it so it gets correctly restored later. */
189  object_set_value(op, "face_closed", op->face->name, 1);
190  }
191 
192  custom = object_get_value(head, "face_opened");
193  if (custom)
194  newface = find_face(custom, newface);
195  if (newface && op->face->number != newface) {
196  op->face = &new_faces[newface];
197  return TRUE;
198  }
199  return FALSE;
200 }
201 
223 int apply_container(object *op, object *sack, int aflags) {
224  char name_sack[MAX_BUF], name_tmp[MAX_BUF];
225  object *tmp = op->container;
226 
227  if (op->type != PLAYER)
228  return 0; /* This might change */
229 
230  if (sack == NULL || sack->type != CONTAINER) {
231  LOG(llevError, "apply_container: '%s' tried to apply %s, which is not a container\n", op->name, sack ? sack->name : "(null)");
232  return 0;
233  }
234 
235  if (sack->head)
236  sack = sack->head;
237 
238  if ( aflags == AP_APPLY || aflags == AP_UNAPPLY || aflags == AP_OPEN ) {
239  // What if the container isn't in the player's inventory?
240  if ( sack->env != op ) {
242  "Not in your inventory: %s",
243  name_sack);
244  return 0;
245  }
246  }
247  if ( aflags == AP_APPLY ) {
248  // What if the container is open? Make it just ready!
249  if ( op->container == sack ) {
250  op->container = NULL;
251  if (op->contr != NULL)
253  CLEAR_FLAG(sack, FLAG_APPLIED);
255  "You readied %s.",
256  name_sack);
257  SET_FLAG(sack, FLAG_APPLIED);
258  // FIXME: This is not flipping the face!
259  if (set_object_face_main(sack)) // change image to closed
261  else
262  esrv_update_item(UPD_FLAGS, op, sack);
263  return 0;
264  }
265  // What if the container is already applied? Do nothing!
266  if (QUERY_FLAG(sack, FLAG_APPLIED)) {
268  "Already readied %s.",
269  name_sack);
270  return 0;
271  }
272  // What if the container is closed? Same as no aflags.
273  aflags = AP_NULL;
274  }
275 
276  if ( aflags == AP_OPEN ) {
277  // What if the container is already open?
278  if ( op->container == sack ) {
280  "Already opened %s.",
281  name_sack);
282  return 0;
283  }
284  // Set the container as applied and then proceed as if no special flags
285  SET_FLAG(sack, FLAG_APPLIED);
286  aflags = AP_NULL;
287  }
288 
289  if ( aflags == AP_UNAPPLY ) {
290  // If not open, two cases:
291  if ( op->container != sack ) {
292  if (QUERY_FLAG(sack, FLAG_APPLIED)) {
293  CLEAR_FLAG(sack, FLAG_APPLIED);
295  "You closed %s.",
296  name_sack);
297  esrv_update_item(UPD_FLAGS, op, sack);
298  return 0;
299  }
300  else {
302  "Already closed %s.",
303  name_sack);
304  return 0;
305  }
306  }
307  // open; same as no special flags
308  aflags = AP_NULL;
309  }
310 
311  /* If we have a currently open container, then it needs
312  * to be closed in all cases if we are opening this one up.
313  * We then fall through if appropriate for opening the new
314  * container.
315  */
316  if (op->container && QUERY_FLAG(op->container, FLAG_APPLIED) &&
317  (QUERY_FLAG(sack, FLAG_APPLIED) || sack->env != op) )
318  {
319  tag_t tmp_tag = op->container->count;
320 
321  if (op->container->env != op) { /* if container is on the ground */
322  object *part = op->container->head ? op->container->head : op->container;
323  while (part) {
324  part->move_off = 0;
325  part = part->more;
326  }
327  }
328 
329  /* Query name before the close event, as the container could be destroyed. */
330  query_name(op->container, name_tmp, MAX_BUF);
331 
332  /* Lauwenmark: Handle for plugin close event */
333  if (execute_event(tmp, EVENT_CLOSE, op, NULL, NULL, SCRIPT_FIX_ALL) != 0)
334  return 1;
335 
338  "You close %s.",
339  name_tmp);
340 
341  op->container = NULL;
342  if (op->contr != NULL)
344 
345  /* The container may have been destroyed by the event handler. */
346  if (!object_was_destroyed(tmp, tmp_tag)) {
347  CLEAR_FLAG(tmp, FLAG_APPLIED);
348  if (set_object_face_main(tmp))
350  else
351  esrv_update_item(UPD_FLAGS, op, tmp);
352  }
353  if (tmp == sack)
354  return 1;
355  }
356 
357  query_name(sack, name_sack, MAX_BUF);
358 
359  /* If the player is trying to open it (which he must be doing
360  * if we got here), and it is locked, check to see if player
361  * has the equipment to open it.
362  */
363 
364  if (sack->slaying) { /* it's locked */
365  tmp = find_key(op, op, sack);
366  if (tmp) {
367  query_name(tmp, name_tmp, MAX_BUF);
370  "You unlock %s with %s.",
371  name_sack, name_tmp);
372  } else {
375  "You don't have the key to unlock %s.",
376  name_sack);
377  return 0;
378  }
379  }
380 
381  /* By the time we get here, we have made sure any other container
382  * has been closed and if this is a locked container, the player
383  * has the key to open it.
384  */
385 
386  /* There are really two cases - the sack is either on the ground,
387  * or the sack is part of the player's inventory. If on the ground,
388  * we assume that the player is opening it, since if it was being
389  * closed, that would have been taken care of above.
390  */
391 
392 
393  if (sack->env != op) {
394  /* Hypothetical case - the player is trying to open a sack
395  * that belongs to someone else. This normally should not
396  * happen, but a misbehaving client/player could
397  * try to do it, so let's handle it gracefully.
398  */
399  if (sack->env) {
401  "You can't open %s",
402  name_sack);
403  return 0;
404  }
405 
406  if (sack->nrof > 1) {
407  object *left = object_split(sack, sack->nrof-1, NULL, 0);
408 
409  object_insert_in_map_at(left, sack->map, NULL, INS_NO_MERGE, sack->x, sack->y);
410  /* recompute the name so it's nice */
411  query_name(sack, name_sack, MAX_BUF);
412  }
413 
414  /* set it so when the player walks off, we can unapply the sack */
415  {
416  object *part = sack->head ? sack->head : sack;
417  while (part) {
418  part->move_off = MOVE_ALL;
419  part = part->more;
420  }
421  }
422 
423  CLEAR_FLAG(sack, FLAG_APPLIED);
425  "You open %s.",
426  name_sack);
427  SET_FLAG(sack, FLAG_APPLIED);
428  op->container = sack;
429  if (op->contr != NULL)
431 
432  if (set_object_face_other(sack))
434  else
435  esrv_update_item(UPD_FLAGS, op, sack);
436  esrv_send_inventory(op, sack);
437  } else { /* sack is in players inventory */
438  if (QUERY_FLAG(sack, FLAG_APPLIED)) { /* readied sack becoming open */
439  CLEAR_FLAG(sack, FLAG_APPLIED);
441  "You open %s.",
442  name_sack);
443  SET_FLAG(sack, FLAG_APPLIED);
444  op->container = sack;
445  if (op->contr != NULL)
447 
448  if (set_object_face_other(sack))
450  else
451  esrv_update_item(UPD_FLAGS, op, sack);
452  esrv_send_inventory(op, sack);
453  } else {
454  object *left = NULL;
455 
456  if (sack->nrof > 1)
457  left = object_split(sack, sack->nrof-1, NULL, 1);
458 
459  CLEAR_FLAG(sack, FLAG_APPLIED);
461  "You readied %s.",
462  name_sack);
463  SET_FLAG(sack, FLAG_APPLIED);
464  esrv_update_item(UPD_FLAGS, op, sack);
465 
466  if (left) {
467  object_insert_in_ob(left, sack->env);
468  esrv_send_item(op, left);
469  }
470  }
471  }
472  return 1;
473 }
474 
486 void do_learn_spell(object *op, object *spell, int special_prayer) {
487  object *tmp;
488 
489  if (op->type != PLAYER) {
490  LOG(llevError, "BUG: do_learn_spell(): not a player\n");
491  return;
492  }
493 
494  /* Upgrade special prayers to normal prayers */
495  tmp = check_spell_known(op, spell->name);
496  if (tmp != NULL) {
497  if (special_prayer && !QUERY_FLAG(tmp, FLAG_STARTEQUIP)) {
498  LOG(llevError, "BUG: do_learn_spell(): spell already known, but not marked as startequip\n");
499  return;
500  }
501  return;
502  }
503 
504  play_sound_player_only(op->contr, SOUND_TYPE_SPELL, spell, 0, "learn");
505  tmp = object_new();
506  object_copy(spell, tmp);
507  object_insert_in_ob(tmp, op);
508 
509  if (special_prayer)
511 
513  "Type 'bind cast %s to store the spell in a key.",
514  spell->name);
515 
516  esrv_add_spells(op->contr, tmp);
517 }
518 
527 void do_forget_spell(object *op, const char *spell) {
528  object *spob;
529 
530  if (op->type != PLAYER) {
531  LOG(llevError, "BUG: do_forget_spell(): not a player\n");
532  return;
533  }
534  spob = check_spell_known(op, spell);
535  if (spob == NULL) {
536  LOG(llevError, "BUG: do_forget_spell(): spell not known\n");
537  return;
538  }
539 
541  "You lose knowledge of %s.",
542  spell);
543  player_unready_range_ob(op->contr, spob);
544  esrv_remove_spell(op->contr, spob);
545  object_remove(spob);
546  object_free(spob, 0);
547 }
548 
562 static int apply_check_race_restrictions(object *who, object *item) {
563  char buf[MAX_BUF];
564  sstring restriction;
565 
566  if (who->type != PLAYER || QUERY_FLAG(who, FLAG_WIZ))
567  return 1;
568 
569  restriction = object_get_value(item, "race_restriction");
570  if (!restriction)
571  return 1;
572 
573  snprintf(buf, sizeof(buf), ":%s:", who->race);
574  buf[sizeof(buf)-1] = '\0';
575 
576  if (strstr(restriction, buf) != NULL)
577  return 1;
578 
579  query_name(item, buf, sizeof(buf));
580  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);
581 
582  return 0;
583 }
584 
605 int apply_manual(object *op, object *tmp, int aflag) {
606  tmp = HEAD(tmp);
607 
608  if (QUERY_FLAG(tmp, FLAG_UNPAID) && !QUERY_FLAG(tmp, FLAG_APPLIED)) {
609  if (op->type == PLAYER) {
611  "You should pay for it first.");
612  return METHOD_SILENT_ERROR;
613  }
614  return 0; /* monsters just skip unpaid items */
615  }
616 
617  if (!apply_check_race_restrictions(op, tmp))
618  return METHOD_SILENT_ERROR;
619 
620  if (op->contr)
621  play_sound_player_only(op->contr, SOUND_TYPE_ITEM, tmp, 0, "apply");
622 
623  return ob_apply(tmp, op, aflag);
624 }
625 
648 int apply_by_living(object *pl, object *op, int aflag, int quiet) {
649  int tmp;
650 
651  if (op->env == NULL && (pl->move_type&MOVE_FLYING)) {
652  /* player is flying and applying object not in inventory */
653  if (!QUERY_FLAG(pl, FLAG_WIZ) && !(op->move_type&MOVE_FLYING)) {
655  "But you are floating high above the ground!");
656  return 0;
657  }
658  }
659 
660  /* Check for PLAYER to avoid a DM to disappear in a puff of smoke if
661  * applied.
662  */
663  if (op->type != PLAYER
664  && QUERY_FLAG(op, FLAG_WAS_WIZ)
665  && !QUERY_FLAG(pl, FLAG_WAS_WIZ)) {
666  play_sound_map(SOUND_TYPE_ITEM, op, 0, "evaporate");
668  "The object disappears in a puff of smoke!");
670  "It must have been an illusion.");
671  object_remove(op);
672  object_free(op, 0);
673  return 1;
674  }
675 
676  tmp = apply_manual(pl, op, aflag);
677  if (!quiet) {
678  if (tmp == METHOD_UNHANDLED) {
679  char name[MAX_BUF];
680 
681  query_name(op, name, MAX_BUF);
683  "I don't know how to apply the %s.",
684  name);
685  } else if (tmp == METHOD_ERROR)
687  "You must get it first!\n");
688  else if (tmp == METHOD_SILENT_ERROR)
689  return tmp;
690  }
691  if (tmp == METHOD_OK) {
692  if (op->anim_suffix != NULL)
694  }
695  return tmp;
696 }
697 
709 void apply_by_living_below(object *pl) {
710  object *tmp;
711  int floors;
712 
713  if (pl->contr->transport && pl->contr->transport->type == TRANSPORT) {
714  ob_apply(pl->contr->transport, pl, 0);
715  return;
716  }
717 
718  /* If using a container, set the starting item to be the top
719  * item in the container. Otherwise, use the map.
720  */
721  tmp = pl->container != NULL ? pl->container->inv : pl->below;
722 
723  /* This is perhaps more complicated. However, I want to make sure that
724  * we don't use a corrupt pointer for the next object, so we get the
725  * next object in the stack before applying. This is can only be a
726  * problem if apply_by_living() has a bug in that it uses the object but
727  * does not return a proper value.
728  */
729  floors = 0;
731  if (QUERY_FLAG(tmp, FLAG_IS_FLOOR))
732  floors++;
733  else if (floors > 0)
734  return; /* process only floor objects after first floor object */
735 
736  /* If it is visible, player can apply it. If it is applied by
737  * person moving on it, also activate. Added code to make it
738  * so that at least one of players movement types be that which
739  * the item needs.
740  */
741  if (!tmp->invisible || (tmp->move_on&pl->move_type)) {
742  if (apply_by_living(pl, tmp, 0, 1) == METHOD_OK)
743  return;
744  }
745  if (floors >= 2)
746  return; /* process at most two floor objects */
748 }
749 
765 static int unapply_special(object *who, object *op, int aflags) {
766  char name[MAX_BUF];
767 
768  if (op->type != LAMP)
770  query_name(op, name, MAX_BUF);
771  switch (op->type) {
772  case WEAPON:
773  if (!(aflags&AP_NOPRINT))
775  "You unwield %s.",
776  name);
777  (void)change_abil(who, op);
779  who->current_weapon = NULL;
780  clear_skill(who);
781  break;
782 
783  case SKILL: /* allows objects to impart skills */
784  case SKILL_TOOL:
785  if (op != who->chosen_skill)
786  LOG(llevError, "BUG: unapply_special(): applied skill is not a chosen skill\n");
787  if (who->type == PLAYER) {
788  if (who->contr->shoottype == range_skill)
789  who->contr->shoottype = range_none;
790  if (!op->invisible) {
791  if (!(aflags&AP_NOPRINT))
793  "You stop using the %s.",
794  name);
795  } else {
796  if (!(aflags&AP_NOPRINT))
798  "You can no longer use the skill: %s.",
799  op->skill);
800  }
801  }
802  (void)change_abil(who, op);
803  who->chosen_skill = NULL;
805  break;
806 
807  case ARMOUR:
808  case HELMET:
809  case SHIELD:
810  case RING:
811  case BOOTS:
812  case GLOVES:
813  case AMULET:
814  case GIRDLE:
815  case BRACERS:
816  case CLOAK:
817  if (!(aflags&AP_NOPRINT))
819  "You unwear %s.",
820  name);
821  (void)change_abil(who, op);
822  break;
823 
824  case BOW:
825  case WAND:
826  case ROD:
827  clear_skill(who);
828  if (!(aflags&AP_NOPRINT))
830  "You unready %s.",
831  name);
832  if (who->type == PLAYER)
833  who->contr->shoottype = range_none;
834  else if (op->type == BOW)
836  else
838  break;
839 
840  case BUILDER:
841  if (!(aflags&AP_NOPRINT))
843  "You unready %s.",
844  name);
845  who->contr->shoottype = range_none;
846  who->contr->ranges[range_builder] = NULL;
847  break;
848 
849  default:
850  if (!(aflags&AP_NOPRINT))
852  "You unapply %s.",
853  name);
854  break;
855  }
856 
857  fix_object(who);
858 
859  if (!(aflags&AP_NO_MERGE)) {
860  object *tmp;
861 
862  tmp = object_merge(op, NULL);
863  if (who->type == PLAYER) {
864  if (tmp) { /* it was merged */
865  op = tmp;
866  }
867  esrv_update_item(UPD_FLAGS, who, op);
868  }
869  }
870  return 0;
871 }
872 
892 static object *get_item_from_body_location(object *start, int loc) {
893  object *tmp;
894 
895  if (!start)
896  return NULL;
897 
898  tmp = start;
900  if (QUERY_FLAG(tmp, FLAG_APPLIED)
901  && tmp->body_info[loc]
902  && (!tmp->invisible || tmp->type == SKILL))
903  return tmp;
905  return NULL;
906 }
907 
929 static int unapply_for_ob(object *who, object *op, int aflags) {
930  int i;
931  object *tmp = NULL, *last;
932  char name[MAX_BUF];
933 
934  /* If we are applying a shield or weapon, unapply any equipped shield
935  * or weapons first - only allowed to use one weapon/shield at a time.
936  */
937  if (op->type == WEAPON || op->type == SHIELD) {
938  FOR_INV_PREPARE(who, tmp) {
939  if (QUERY_FLAG(tmp, FLAG_APPLIED) && tmp->type == op->type) {
940  if (!(aflags&AP_IGNORE_CURSE)
941  && !(aflags&AP_PRINT)
942  && (QUERY_FLAG(tmp, FLAG_CURSED) || QUERY_FLAG(tmp, FLAG_DAMNED))) {
943  /* In this case, we want to try and remove a
944  * cursed item. While we know it won't work, we
945  * want unapply_special to at least generate the
946  * message.
947  */
948  if (!(aflags&AP_NOPRINT)) {
949  query_name(tmp, name, MAX_BUF);
951  "No matter how hard you try, you just can't remove %s.",
952  name);
953  }
954  return 1;
955  }
956 
957  if (aflags&AP_PRINT) {
958  query_name(tmp, name, MAX_BUF);
960  name);
961  } else
962  unapply_special(who, tmp, aflags);
963  }
964  } FOR_INV_FINISH();
965  }
966 
967  for (i = 0; i < NUM_BODY_LOCATIONS; i++) {
968  /* this used up a slot that we need to free */
969  if (op->body_info[i]) {
970  last = who->inv;
971 
972  /* We do a while loop - may need to remove several items
973  * in order to free up enough slots.
974  */
975  while (who->body_used[i]+op->body_info[i] < 0) {
976  tmp = get_item_from_body_location(last, i);
977  if (!tmp)
978  return 1;
979 
980  /* If just printing, we don't care about cursed status */
981  if ((aflags&AP_IGNORE_CURSE)
982  || (aflags&AP_PRINT)
983  || (!(QUERY_FLAG(tmp, FLAG_CURSED) || QUERY_FLAG(tmp, FLAG_DAMNED)))) {
984  if (aflags&AP_PRINT) {
985  query_name(tmp, name, MAX_BUF);
987  name);
988  } else
989  unapply_special(who, tmp, aflags);
990  } else {
991  /* Cursed item that we can't unequip - tell the player.
992  * Note this could be annoying if this is just one of a
993  * few, so it may not be critical (eg, putting on a
994  * ring and you have one cursed ring.)
995  */
996  if (!(aflags&AP_NOPRINT)) {
997  query_name(tmp, name, MAX_BUF);
999  "The %s just won't come off",
1000  name);
1001  }
1002  }
1003  last = tmp->below;
1004  }
1005  /* if we got here, this slot is freed up - otherwise, if it
1006  * wasn't freed up, the return in the !tmp would have
1007  * kicked in.
1008  */
1009  } /* if op is using this body location */
1010  } /* for body locations */
1011  return 0;
1012 }
1013 
1033 int apply_can_apply_object(const object *who, const object *op) {
1034  int i, retval = 0;
1035  object *tmp = NULL, *ws = NULL;
1036 
1037  /* Players have 2 'arm's, so they could in theory equip 2 shields or
1038  * 2 weapons, but we don't want to let them do that. So if they are
1039  * trying to equip a weapon or shield, see if they already have one
1040  * in place and store that way.
1041  */
1042  if (op->type == WEAPON || op->type == SHIELD) {
1043  tmp = object_find_by_type_applied(who, op->type);
1044  if (tmp != NULL) {
1045  retval = CAN_APPLY_UNAPPLY;
1046  ws = tmp;
1047  }
1048  }
1049 
1050  for (i = 0; i < NUM_BODY_LOCATIONS; i++) {
1051  if (op->body_info[i]) {
1052  /* Item uses more slots than we have */
1053  if (FABS(op->body_info[i]) > who->body_info[i]) {
1054  /* Could return now for efficiently - rest of info
1055  * below isn't really needed.
1056  */
1057  retval |= CAN_APPLY_NEVER;
1058  } else if (who->body_used[i]+op->body_info[i] < 0) {
1059  /* in this case, equipping this would use more free
1060  * spots than we have.
1061  */
1062  object *tmp1;
1063 
1064  /* if we have an applied weapon/shield, and unapply
1065  * it would free enough slots to equip the new item,
1066  * then just set this can continue. We don't care
1067  * about the logic below - if you have shield equipped
1068  * and try to equip another shield, there is only one
1069  * choice. However, the check for the number of body
1070  * locations does take into the account cases where what
1071  * is being applied may be two handed for example.
1072  */
1073  if (ws) {
1074  if (who->body_used[i]-ws->body_info[i]+op->body_info[i] >= 0) {
1075  retval |= CAN_APPLY_UNAPPLY;
1076  continue;
1077  }
1078  }
1079 
1080  tmp1 = get_item_from_body_location(who->inv, i);
1081  if (!tmp1)
1082  retval |= CAN_APPLY_NEVER;
1083  else {
1084  /* need to unapply something. However, if this
1085  * something is different than we had found before,
1086  * it means they need to apply multiple objects
1087  */
1088  retval |= CAN_APPLY_UNAPPLY;
1089  if (!tmp)
1090  tmp = tmp1;
1091  else if (tmp != tmp1)
1092  retval |= CAN_APPLY_UNAPPLY_MULT;
1093  /* This object isn't using up all the slots, so
1094  * there must be another. If so, and if the new
1095  * item doesn't need all the slots, the player
1096  * then has a choice.
1097  */
1098  if (who->body_used[i]-tmp1->body_info[i] != who->body_info[i]
1099  && FABS(op->body_info[i]) < who->body_info[i])
1100  retval |= CAN_APPLY_UNAPPLY_CHOICE;
1101 
1102  /* Does unequipping 'tmp1' free up enough slots
1103  * for this to be equipped? If not, there must
1104  * be something else to unapply.
1105  */
1106  if (who->body_used[i]+op->body_info[i]-tmp1->body_info[i] < 0)
1107  retval |= CAN_APPLY_UNAPPLY_MULT;
1108  }
1109  } /* if not enough free slots */
1110  } /* if this object uses location i */
1111  } /* for i -> num_body_locations loop */
1112 
1113  /* Do checks for can_use_weapon/shield/armour. */
1114  if (IS_WEAPON(op) && !QUERY_FLAG(who, FLAG_USE_WEAPON))
1115  retval |= CAN_APPLY_RESTRICTION;
1116  if (IS_SHIELD(op) && !QUERY_FLAG(who, FLAG_USE_SHIELD))
1117  retval |= CAN_APPLY_RESTRICTION;
1118  if (IS_ARMOR(op) && !QUERY_FLAG(who, FLAG_USE_ARMOUR))
1119  retval |= CAN_APPLY_RESTRICTION;
1120 
1121  if (who->type != PLAYER) {
1122  if ((op->type == WAND || op->type == ROD)
1123  && !QUERY_FLAG(who, FLAG_USE_RANGE))
1124  retval |= CAN_APPLY_RESTRICTION;
1125  if (op->type == BOW && !QUERY_FLAG(who, FLAG_USE_BOW))
1126  retval |= CAN_APPLY_RESTRICTION;
1127  if (op->type == RING && !QUERY_FLAG(who, FLAG_USE_RING))
1128  retval |= CAN_APPLY_RESTRICTION;
1129  }
1130  return retval;
1131 }
1132 
1148 int apply_check_weapon_power(const object *who, int improves) {
1149  return (who->level/5)+5 >= improves;
1150 }
1151 
1173 int apply_special(object *who, object *op, int aflags) {
1174  int basic_flag = aflags&AP_BASIC_FLAGS;
1175  object *tmp, *skop;
1176  char name_op[MAX_BUF];
1177 
1178  if (who == NULL) {
1179  LOG(llevError, "apply_special() from object without environment.\n");
1180  return 1;
1181  }
1182 
1183  if (op->env != who)
1184  return 1; /* op is not in inventory */
1185 
1186  /* trying to unequip op */
1187  if (QUERY_FLAG(op, FLAG_APPLIED)) {
1188  /* always apply, so no reason to unapply */
1189  if (basic_flag == AP_APPLY)
1190  return 0;
1191 
1192  if (!(aflags&AP_IGNORE_CURSE)
1193  && (QUERY_FLAG(op, FLAG_CURSED) || QUERY_FLAG(op, FLAG_DAMNED))) {
1194  if (!(aflags&AP_NOPRINT)) {
1195  query_name(op, name_op, MAX_BUF);
1197  "No matter how hard you try, you just can't remove %s.",
1198  name_op);
1199  }
1200  return 1;
1201  }
1202  return unapply_special(who, op, aflags);
1203  }
1204 
1205  if (basic_flag == AP_UNAPPLY)
1206  return 0;
1207 
1208  if (!apply_check_apply_restrictions(who, op, aflags))
1209  return 1;
1210 
1211  if (op->skill && op->type != SKILL && op->type != SKILL_TOOL) {
1212  skop = find_skill_by_name(who, op->skill);
1213  if (!skop) {
1214  if (!(aflags&AP_NOPRINT))
1216  "You need the %s skill to use this item!",
1217  op->skill);
1218  if (who->type == PLAYER)
1219  return 1;
1220 
1221  /* monsters do not care about missing skills */
1222  } else
1223  /* While experience will be credited properly, we want to
1224  * change the skill so that the dam and wc get updated
1225  */
1226  change_skill(who, skop, (aflags&AP_NOPRINT));
1227  } else
1228  skop = NULL;
1229 
1230  if (!apply_check_item_power(who, op, aflags))
1231  return 1;
1232 
1233  if (!apply_check_personalized_blessings(who, op))
1234  return 1;
1235 
1236  /* Ok. We are now at the state where we can apply the new object.
1237  * Note that we don't have the checks for can_use_...
1238  * below - that is already taken care of by apply_can_apply_object().
1239  */
1240 
1241  tmp = op->nrof <= 1 ? NULL : object_split(op, op->nrof-1, NULL, 0);
1242 
1243  switch (op->type) {
1244  case WEAPON:
1245  if (!apply_check_weapon_power(who, op->last_eat)) {
1246  if (!(aflags&AP_NOPRINT))
1248  "That weapon is too powerful for you to use. It would consume your soul!");
1249  if (tmp != NULL)
1250  (void)object_insert_in_ob(tmp, who);
1251  return 1;
1252  }
1253 
1254  if (!apply_check_owner(who, op, aflags)) {
1255  if (tmp != NULL)
1256  (void)object_insert_in_ob(tmp, who);
1257  return 1;
1258  }
1259 
1260  SET_FLAG(op, FLAG_APPLIED);
1261 
1262  if (skop)
1263  change_skill(who, skop, 1);
1265 
1266  if (!(aflags&AP_NOPRINT)) {
1267  query_name(op, name_op, MAX_BUF);
1269  "You wield %s.",
1270  name_op);
1271  }
1272 
1273  (void)change_abil(who, op);
1274  break;
1275 
1276  case ARMOUR:
1277  case HELMET:
1278  case SHIELD:
1279  case BOOTS:
1280  case GLOVES:
1281  case GIRDLE:
1282  case BRACERS:
1283  case CLOAK:
1284  case RING:
1285  case AMULET:
1286  SET_FLAG(op, FLAG_APPLIED);
1287  if (!(aflags&AP_NOPRINT)) {
1288  query_name(op, name_op, MAX_BUF);
1290  "You wear %s.",
1291  name_op);
1292  }
1293  (void)change_abil(who, op);
1294  break;
1295 
1296  /* this part is needed for skill-tools */
1297  case SKILL:
1298  case SKILL_TOOL:
1299  if (who->chosen_skill) {
1300  LOG(llevError, "BUG: apply_special(): can't apply two skills\n");
1301  return 1;
1302  }
1303 
1304  apply_update_ranged_skill(who, op, aflags);
1305  SET_FLAG(op, FLAG_APPLIED);
1306  (void)change_abil(who, op);
1307  who->chosen_skill = op;
1308  SET_FLAG(who, FLAG_READY_SKILL);
1309  break;
1310 
1311  case BOW:
1312  if (!apply_check_weapon_power(who, op->last_eat)) {
1313  if (!(aflags&AP_NOPRINT))
1315  "That weapon is too powerful for you to use. It would consume your soul!");
1316  if (tmp != NULL)
1317  (void)object_insert_in_ob(tmp, who);
1318  return 1;
1319  }
1320 
1321  if (!apply_check_owner(who, op, aflags)) {
1322  if (tmp != NULL)
1323  (void)object_insert_in_ob(tmp, who);
1324  return 1;
1325  }
1326  /*FALLTHROUGH*/
1327  case WAND:
1328  case ROD:
1329  /* check for skill, alter player status */
1330  SET_FLAG(op, FLAG_APPLIED);
1331  if (skop)
1332  change_skill(who, skop, 0);
1333  if (!(aflags&AP_NOPRINT)) {
1334  query_name(op, name_op, MAX_BUF);
1336  "You ready %s.",
1337  name_op);
1338  }
1339  if (who->type == PLAYER) {
1340  if (op->type == BOW) {
1341  (void)change_abil(who, op);
1342  if (!(aflags&AP_NOPRINT)) {
1343  query_name(op, name_op, MAX_BUF);
1345  "You will now fire %s with %s.",
1346  op->race ? op->race : "nothing",
1347  name_op);
1348  }
1349  who->contr->shoottype = range_bow;
1350  } else
1351  who->contr->shoottype = range_misc;
1352  } else {
1353  if (op->type == BOW)
1354  SET_FLAG(who, FLAG_READY_BOW);
1355  else
1356  SET_FLAG(who, FLAG_READY_RANGE);
1357  }
1358  break;
1359 
1360  case BUILDER:
1361  if (who->contr->ranges[range_builder])
1362  unapply_special(who, who->contr->ranges[range_builder], 0);
1363  who->contr->shoottype = range_builder;
1364  who->contr->ranges[range_builder] = op;
1365  if (!(aflags&AP_NOPRINT)) {
1366  query_name(op, name_op, MAX_BUF);
1368  "You ready your %s.",
1369  name_op);
1370  }
1371  break;
1372 
1373  default:
1374  query_name(op, name_op, MAX_BUF);
1376  "You apply %s.",
1377  name_op);
1378  break;
1379  } /* end of switch op->type */
1380 
1381  SET_FLAG(op, FLAG_APPLIED);
1382 
1383  if (tmp != NULL)
1384  tmp = object_insert_in_ob(tmp, who);
1385 
1386  fix_object(who);
1387 
1388  /* We exclude spell casting objects. The fire code will set the
1389  * been applied flag when they are used - until that point,
1390  * you don't know anything about them.
1391  */
1392  if (who->type == PLAYER && op->type != WAND && op->type != ROD)
1394 
1395  if (QUERY_FLAG(op, FLAG_CURSED) || QUERY_FLAG(op, FLAG_DAMNED)) {
1396  if (who->type == PLAYER) {
1398  "Oops, it feels deadly cold!");
1400  }
1401  }
1402  if (who->type == PLAYER)
1404  return 0;
1405 }
1406 
1420 int apply_auto(object *op) {
1421  object *tmp;
1422 
1423  switch (op->type) {
1424  case SHOP_FLOOR:
1425  if (!HAS_RANDOM_ITEMS(op))
1426  return 0;
1427  do {
1428  int i;
1429 
1430  i = 10; /* let's give it 10 tries */
1431  while ((tmp = generate_treasure(op->randomitems, op->stats.exp ? (int)op->stats.exp : MAX(op->map->difficulty, 5))) == NULL
1432  && --i)
1433  ;
1434  if (tmp == NULL)
1435  return 0;
1436  if (QUERY_FLAG(tmp, FLAG_CURSED) || QUERY_FLAG(tmp, FLAG_DAMNED)) {
1438  tmp = NULL;
1439  }
1440  } while (!tmp);
1441  SET_FLAG(tmp, FLAG_UNPAID);
1442  object_insert_in_map_at(tmp, op->map, NULL, 0, op->x, op->y);
1444  identify(tmp);
1445  return 1;
1446  break;
1447 
1448  case TREASURE:
1449  if (QUERY_FLAG(op, FLAG_IS_A_TEMPLATE))
1450  return 0;
1451  while (op->stats.hp-- > 0)
1452  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);
1453 
1454  /* If we generated an object and put it in this object's
1455  * inventory, move it to the parent object as the current
1456  * object is about to disappear. An example of this item
1457  * is the random_ *stuff that is put inside other objects.
1458  */
1459  FOR_INV_PREPARE(op, tmp) {
1460  object_remove(tmp);
1461  if (op->env)
1462  object_insert_in_ob(tmp, op->env);
1463  else
1465  } FOR_INV_FINISH();
1466  object_remove(op);
1468  break;
1469  }
1470  return 0;
1471 }
1472 
1487  int x, y;
1488 
1489  if (m == NULL)
1490  return;
1491 
1492  for (x = 0; x < MAP_WIDTH(m); x++)
1493  for (y = 0; y < MAP_HEIGHT(m); y++)
1494  FOR_MAP_PREPARE(m, x, y, tmp) {
1495  if (tmp->inv) {
1496  FOR_INV_PREPARE(tmp, invtmp) {
1497  if (QUERY_FLAG(invtmp, FLAG_AUTO_APPLY))
1498  apply_auto(invtmp);
1499  else if (invtmp->type == TREASURE && HAS_RANDOM_ITEMS(invtmp)) {
1500  while (invtmp->stats.hp-- > 0)
1501  create_treasure(invtmp->randomitems, invtmp, 0, m->difficulty, 0);
1502  invtmp->randomitems = NULL;
1503  } else if (invtmp && invtmp->arch
1504  && invtmp->type != TREASURE
1505  && invtmp->type != SPELL
1506  && invtmp->type != CLASS
1507  && HAS_RANDOM_ITEMS(invtmp)) {
1508  create_treasure(invtmp->randomitems, invtmp, 0, m->difficulty, 0);
1509  /* Need to clear this so that we never try to
1510  * create treasure again for this object
1511  */
1512  invtmp->randomitems = NULL;
1513  }
1514  } FOR_INV_FINISH();
1515  /* This is really temporary - the code at the
1516  * bottom will also set randomitems to null.
1517  * The problem is there are bunches of maps/players
1518  * already out there with items that have spells
1519  * which haven't had the randomitems set
1520  * to null yet.
1521  * MSW 2004-05-13
1522  *
1523  * And if it's a spellbook, it's better to set
1524  * randomitems to NULL too, else you get two spells
1525  * in the book ^_-
1526  * Ryo 2004-08-16
1527  */
1528  if (tmp->type == WAND
1529  || tmp->type == ROD
1530  || tmp->type == SCROLL
1531  || tmp->type == FIREWALL
1532  || tmp->type == POTION
1533  || tmp->type == ALTAR
1534  || tmp->type == SPELLBOOK)
1535  tmp->randomitems = NULL;
1536  }
1537 
1538  if (QUERY_FLAG(tmp, FLAG_AUTO_APPLY))
1539  apply_auto(tmp);
1540  else if ((tmp->type == TREASURE || tmp->type == CONTAINER)
1541  && HAS_RANDOM_ITEMS(tmp)) {
1542  while (tmp->stats.hp-- > 0)
1543  create_treasure(tmp->randomitems, tmp, 0, m->difficulty, 0);
1544  tmp->randomitems = NULL;
1545  } else if (tmp->type == TIMED_GATE) {
1546  object *head = HEAD(tmp);
1547 
1548  if (QUERY_FLAG(head, FLAG_IS_LINKED)) {
1549  tmp->speed = 0;
1550  object_update_speed(tmp);
1551  }
1552  }
1553  /* This function can be called every time a map is loaded,
1554  * even when swapping back in. As such, we don't want to
1555  * create the treasure over and over again, so after we
1556  * generate the treasure, blank out randomitems so if it
1557  * is swapped in again, it won't make anything. This is a
1558  * problem for the above objects, because they have
1559  * counters which say how many times to make the treasure.
1560  */
1561  else if (tmp
1562  && tmp->arch
1563  && tmp->type != PLAYER
1564  && tmp->type != TREASURE
1565  && tmp->type != SPELL
1566  && tmp->type != PLAYER_CHANGER
1567  && tmp->type != CLASS
1568  && HAS_RANDOM_ITEMS(tmp)) {
1569  create_treasure(tmp->randomitems, tmp, 0, m->difficulty, 0);
1570  tmp->randomitems = NULL;
1571  }
1572 
1573  if (QUERY_FLAG(tmp, FLAG_MONSTER))
1575  } FOR_MAP_FINISH();
1576 
1577  for (x = 0; x < MAP_WIDTH(m); x++)
1578  for (y = 0; y < MAP_HEIGHT(m); y++)
1579  FOR_MAP_PREPARE(m, x, y, tmp) {
1580  if (tmp->above
1581  && (tmp->type == TRIGGER_BUTTON || tmp->type == TRIGGER_PEDESTAL))
1582  check_trigger(tmp, tmp->above);
1583  } FOR_MAP_FINISH();
1584 }
1585 
1600 void scroll_failure(object *op, int failure, int power) {
1601  if (abs(failure/4) > power)
1602  power = abs(failure/4); /* set minimum effect */
1603 
1604  if (failure <= -1 && failure > -15) {/* wonder */
1605  object *tmp;
1606 
1608  "Your spell warps!");
1610  cast_wonder(op, op, 0, tmp);
1611  if (op->stats.sp < 0)
1612  /* For some reason the sp can become negative here. */
1613  op->stats.sp = 0;
1615  return;
1616  }
1617 
1619  if (failure <= -35 && failure > -60) { /* confusion */
1621  "The magic recoils on you!");
1622  confuse_living(op, op, power);
1623  return;
1624  }
1625 
1626  if (failure <= -60 && failure > -70) {/* paralysis */
1628  "The magic recoils and paralyzes you!");
1629  paralyze_living(op, power);
1630  return;
1631  }
1632 
1633  if (failure <= -70 && failure > -80) {/* blind */
1635  "The magic recoils on you!");
1636  blind_living(op, op, power);
1637  return;
1638  }
1639 
1640  if (failure <= -80) {/* blast the immediate area */
1641  object *tmp;
1642 
1644  cast_magic_storm(op, tmp, power);
1646  "You unlease uncontrolled mana!");
1648  return;
1649  }
1650  }
1651  /* Either no spell failure on this server, or wrong values,
1652  * in any case let's punish.
1653  */
1655  "Your mana is drained!");
1656  op->stats.sp -= random_roll(0, power-1, op, PREFER_LOW);
1657  if (op->stats.sp < 0)
1658  op->stats.sp = 0;
1659 }
1660 
1672 void apply_changes_to_player(object *pl, object *change, int limit_stats) {
1673  int i, j;
1674  int excess_stat = 0; /* if the stat goes over the maximum
1675  * for the race, put the excess stat some
1676  * where else.
1677  */
1678 
1679  if (change->type != CLASS) return;
1680 
1681  /* the following code assigns stats up to the stat max
1682  * for the race, and if the stat max is exceeded,
1683  * tries to randomly reassign the excess stat
1684  */
1685  if (! (limit_stats & AC_PLAYER_STAT_NO_CHANGE)) {
1686  for (i = 0; i < NUM_STATS; i++) {
1687  int8_t stat = get_attr_value(&pl->contr->orig_stats, i);
1688  int race_bonus = get_attr_value(&pl->arch->clone.stats, i);
1689 
1690  stat += get_attr_value(&change->stats, i);
1691  if (limit_stats & AC_PLAYER_STAT_LIMIT) {
1692  if (stat > 20+race_bonus) {
1693  excess_stat++;
1694  stat = 20+race_bonus;
1695  } else if (stat < 1) {
1696  /* I didn't see any code here before to make sure minimum
1697  * stats were enforced - maybe it was just dumb
1698  * luck that one would not have a stat low enough that then
1699  * has a stat penalty for class that would bring it negative?
1700  * I imagine a negative stat would crash the server pretty
1701  * quickly - MSW, Sept 2010
1702  */
1703  excess_stat += stat;
1704  stat = 1;
1705  }
1706  }
1707  set_attr_value(&pl->contr->orig_stats, i, stat);
1708  }
1709 
1710  /* Maybe we should randomly deduct stats in this case?
1711  * It's will go away sometime soon in any case.
1712  */
1713  if (excess_stat < 0) excess_stat = 0;
1714 
1715  /* We don't put an explicit check for limit_stats here -
1716  * excess stat will never be 0 if limit_stats is not
1717  * true.
1718  */
1719  for (j = 0; excess_stat > 0 && j < 100; j++) {
1720  /* try 100 times to assign excess stats */
1721  int i = rndm(0, NUM_STATS-1);
1722  int stat = get_attr_value(&pl->contr->orig_stats, i);
1723  int race_bonus = get_attr_value(&pl->arch->clone.stats, i);
1724 
1725  if (i == CHARISMA) {
1726  continue; /* exclude cha from this */
1727  }
1728 
1729  if (stat < 20+race_bonus) {
1730  change_attr_value(&pl->contr->orig_stats, i, 1);
1731  excess_stat--;
1732  }
1733  }
1734  }
1735  /* Done with stat processing */
1736 
1737  /* insert the randomitems from the change's treasurelist into
1738  * the player ref: player.c
1739  */
1740  if (change->randomitems != NULL)
1741  give_initial_items(pl, change->randomitems);
1742 
1743 
1744  /* set up the face, for some races. */
1745 
1746  /* first, look for the force object banning changing the
1747  * face. Certain races never change face with class.
1748  */
1749  int has_noclassfacechange = (object_find_by_name(pl, "NOCLASSFACECHANGE") != NULL);
1750  // Assume 0 is not a valid animation.
1751  int anim = 0;
1752 
1753  if (change->anim_suffix) {
1754  char buf[MAX_BUF];
1755 
1756  snprintf(buf, MAX_BUF, "%s_%s", animations[pl->animation_id].name, change->anim_suffix);
1757  anim = try_find_animation(buf);
1758  if (anim) {
1759  pl->animation_id = anim;
1760  pl->anim_speed = -1;
1761  CLEAR_FLAG(pl, FLAG_ANIMATE);
1762  animate_object(pl, pl->facing);
1763  }
1764  }
1765  /* Check for anim == -1 so that we can override specific class faces for races.
1766  * This allows us to have custom class faces on the races that lack noclassfacechange
1767  *
1768  * Daniel Hawkins 2020-09-08
1769  */
1770  if ((!has_noclassfacechange) && anim == 0) {
1771  pl->animation_id = GET_ANIM_ID(change);
1772  pl->face = change->face;
1773 
1774  if (QUERY_FLAG(change, FLAG_ANIMATE))
1775  SET_FLAG(pl, FLAG_ANIMATE);
1776  else
1777  CLEAR_FLAG(pl, FLAG_ANIMATE);
1778  }
1779 
1780  /* Hard coding in class name is a horrible idea - lets
1781  * use the supported mechanism for this
1782  */
1783  if (object_present_in_ob_by_name(FORCE, "no weapon force", pl))
1785 
1786 }
1787 
1801 static int apply_check_apply_restrictions(object *who, object *op, int aflags) {
1802  int i;
1803 
1804  i = apply_can_apply_object(who, op);
1805  if (i == 0)
1806  return 1;
1807 
1808  /* Can't just apply this object. Lets see why not and what to do */
1809 
1810  if (i&CAN_APPLY_NEVER) {
1811  if (!(aflags&AP_NOPRINT)) {
1812  char name_op[MAX_BUF];
1813 
1814  query_name(op, name_op, MAX_BUF);
1816  "You don't have the body to use a %s",
1817  name_op);
1818  }
1819  return 0;
1820  }
1821 
1822  if (i&CAN_APPLY_RESTRICTION) {
1823  if (!(aflags&AP_NOPRINT)) {
1824  char name_op[MAX_BUF];
1825 
1826  query_name(op, name_op, MAX_BUF);
1828  "You have a prohibition against using a %s",
1829  name_op);
1830  }
1831  return 0;
1832  }
1833 
1834  if (who->type != PLAYER) {
1835  /* Some error, so don't try to equip something more */
1836  return !unapply_for_ob(who, op, aflags);
1837  }
1838 
1839  if (who->contr->unapply == unapply_never
1841  if (!(aflags&AP_NOPRINT))
1843  "You need to unapply some item(s):");
1844  unapply_for_ob(who, op, AP_PRINT);
1845  return 0;
1846  }
1847 
1848  if (who->contr->unapply == unapply_always
1849  || !(i&CAN_APPLY_UNAPPLY_CHOICE)) {
1850  return !unapply_for_ob(who, op, aflags);
1851  }
1852 
1853  return 1;
1854 }
1855 
1868 static int apply_check_item_power(const object *who, const object *op, int aflags) {
1869  if (who->type != PLAYER)
1870  return 1;
1871 
1872  if (op->item_power == 0
1874  return 1;
1875 
1876  if (!(aflags&AP_NOPRINT))
1878  "Equipping that combined with other items would consume your soul!");
1879  return 0;
1880 }
1881 
1896 static int apply_check_personalized_blessings(object *who, const object *op) {
1897  const char *owner;
1898  const char *will;
1899  long item_will;
1900  long margin;
1901  const char *msg;
1902  int random_effect;
1903  int damage_percentile;
1904 
1906  return 1;
1907  }
1908 
1909  owner = object_get_value(op, "item_owner");
1910  if (owner == NULL || strcmp(owner, who->name) == 0)
1911  return 1;
1912 
1913  will = object_get_value(op, "item_willpower");
1914  item_will = will != NULL ? atol(will) : 0;
1915  if (item_will > who->stats.exp) {
1917  "This %s refuses to serve you - it keeps evading your hand !",
1918  op->name);
1919  return 0;
1920  }
1921 
1922  margin = item_will != 0 ? who->stats.exp/item_will : who->stats.exp;
1923  random_effect = random_roll(0, 100, who, 1)-margin*20;
1924  if (random_effect > 80) {
1925  msg = "You don't know why, but you have the feeling that the %s is angry at you !";
1926  damage_percentile = 60;
1927  } else if (random_effect > 60) {
1928  msg = "The %s seems to look at you nastily !";
1929  damage_percentile = 45;
1930  } else if (random_effect > 40) {
1931  msg = "You have the strange feeling that the %s is annoyed...";
1932  damage_percentile = 30;
1933  } else if (random_effect > 20) {
1934  msg = "The %s seems tired, or bored, in a way. Very strange !";
1935  damage_percentile = 15;
1936  } else if (random_effect > 0) {
1937  msg = "You hear the %s sighing !";
1938  damage_percentile = 0;
1939  } else {
1940  msg = NULL;
1941  damage_percentile = 0;
1942  }
1943  if (msg != NULL)
1945  msg, op->name);
1946  if (damage_percentile > 0) {
1947  int weapon_bite = (who->stats.hp*damage_percentile)/100;
1948  if (weapon_bite < 1)
1949  weapon_bite = 1;
1950  who->stats.hp -= weapon_bite;
1952  "You get a nasty bite in the hand !");
1953  }
1954 
1955  return 1;
1956 }
1957 
1972 static int apply_check_owner(const object *who, const object *op, int aflags) {
1973  const char *quotepos;
1974 
1975  if (op->level == 0)
1976  return 1;
1977 
1978  quotepos = strstr(op->name, "'");
1979  if (quotepos == NULL || strncmp(op->name, who->name, quotepos-op->name) == 0)
1980  return 1;
1981 
1982  if (!(aflags&AP_NOPRINT))
1984  "The weapon does not recognize you as its owner.");
1985  return 0;
1986 }
1987 
1998 static void apply_update_ranged_skill(const object *who, object *op, int aflags) {
1999  if (who->type != PLAYER) {
2000  return;
2001  }
2002 
2003  who->contr->shoottype = range_skill;
2004  who->contr->ranges[range_skill] = op;
2005  if (op->invisible) {
2006  if (!(aflags&AP_NOPRINT))
2008  "Readied skill: %s.",
2009  op->skill ? op->skill : op->name);
2010  } else {
2011  if (!(aflags&AP_NOPRINT)) {
2012  char name_op[MAX_BUF];
2013 
2014  query_name(op, name_op, MAX_BUF);
2016  "You ready %s.",
2017  name_op);
2019  "You can now use the skill: %s.",
2020  op->skill);
2021  }
2022  }
2023 }
void draw_ext_info_format(int flags, int pri, const object *pl, uint8_t type, uint8_t subtype, const char *format,...)
Definition: main.c:316
#define AP_UNAPPLY
Definition: define.h:613
static int apply_check_owner(const object *who, const object *op, int aflags)
Definition: apply.c:1972
void set_attr_value(living *stats, int attr, int8_t value)
Definition: living.c:219
#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:562
#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:367
#define FLAG_IS_LINKED
Definition: define.h:316
MoveType move_type
Definition: object.h:426
#define INS_BELOW_ORIGINATOR
Definition: object.h:572
int change_skill(object *who, object *new_skill, int flag)
Definition: skill_util.c:340
void object_free(object *ob, int flags)
Definition: object.c:1411
MoveType move_on
Definition: object.h:429
Definition: object.h:185
#define CAN_APPLY_UNAPPLY_CHOICE
Definition: define.h:673
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:340
#define SET_FLAG(xyz, p)
Definition: define.h:223
object * object_find_by_type_applied(const object *who, int type)
Definition: object.c:4027
#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:418
const char * name
Definition: face.h:27
#define FLAG_USE_ARMOUR
Definition: define.h:296
uint8_t anim_speed
Definition: object.h:419
Definition: object.h:204
struct obj * container
Definition: object.h:291
void do_forget_spell(object *op, const char *spell)
Definition: apply.c:527
#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:1868
#define FLAG_READY_RANGE
Definition: define.h:299
void esrv_update_item(int flags, object *pl, object *op)
Definition: main.c:343
const char * object_get_value(const object *op, const char *const key)
Definition: object.c:4299
struct treasureliststruct * randomitems
Definition: object.h:387
#define MAP_HEIGHT(m)
Definition: map.h:80
object clone
Definition: object.h:472
socket_struct socket
Definition: player.h:94
#define CAN_APPLY_NEVER
Definition: define.h:668
int16_t invisible
Definition: object.h:361
#define PREFER_LOW
Definition: define.h:602
int apply_auto(object *op)
Definition: apply.c:1420
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:340
Definition: object.h:109
static void apply_update_ranged_skill(const object *who, object *op, int aflags)
Definition: apply.c:1998
#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:533
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:314
#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:1600
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:368
#define AP_APPLY
Definition: define.h:612
struct archt * other_arch
Definition: object.h:415
#define FLAG_USE_RING
Definition: define.h:298
object * object_find_by_name(const object *who, const char *name)
Definition: object.c:3900
void draw_ext_info(int flags, int pri, const object *pl, uint8_t type, uint8_t subtype, const char *message)
Definition: main.c:311
Definition: object.h:220
#define MSG_TYPE_APPLY
Definition: newclient.h:384
#define FOR_OB_AND_BELOW_FINISH()
Definition: define.h:792
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:672
#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:1672
void apply_handle_yield(object *tmp)
Definition: apply.c:125
#define AP_OPEN
Definition: define.h:614
#define FLAG_READY_SKILL
Definition: define.h:334
static int apply_check_personalized_blessings(object *who, const object *op)
Definition: apply.c:1896
struct obj * chosen_skill
Definition: object.h:388
int object_set_value(object *op, const char *key, const char *value, int add_key)
Definition: object.c:4428
void object_free_drop_inventory(object *ob)
Definition: object.c:1391
int change_abil(object *op, object *tmp)
Definition: living.c:395
const char * name
Definition: face.h:20
int16_t y
Definition: object.h:326
#define CAN_APPLY_UNAPPLY
Definition: define.h:671
object * object_insert_in_map_at(object *op, mapstruct *m, object *originator, int flag, int x, int y)
Definition: object.c:1935
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:1173
void confuse_living(object *op, object *hitter, int dam)
Definition: attack.c:2266
#define AP_IGNORE_CURSE
Definition: define.h:620
#define MSG_TYPE_VICTIM
Definition: newclient.h:392
object * object_new(void)
Definition: object.c:1070
#define CAN_APPLY_RESTRICTION
Definition: define.h:669
object * create_archetype(const char *name)
Definition: arch.c:620
object * object_insert_in_ob(object *op, object *where)
Definition: object.c:2709
unapplymode unapply
Definition: player.h:108
static object * get_item_from_body_location(object *start, int loc)
Definition: apply.c:892
int32_t weight
Definition: object.h:366
#define AC_PLAYER_STAT_LIMIT
Definition: define.h:635
const char * anim_suffix
Definition: object.h:316
#define METHOD_OK
Definition: ob_methods.h:15
#define AP_PRINT
Definition: define.h:621
#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:1827
#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:715
#define MOVE_FLYING
Definition: define.h:410
void change_attr_value(living *stats, int attr, int8_t value)
Definition: living.c:265
int32_t carrying
Definition: object.h:368
const char * name
Definition: object.h:311
living orig_stats
Definition: player.h:148
struct obj * env
Definition: object.h:293
#define AP_NULL
Definition: define.h:611
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:372
uint32_t nrof
Definition: object.h:333
#define AP_NOPRINT
Definition: define.h:624
#define UPD_FLAGS
Definition: newclient.h:290
void paralyze_living(object *op, int dam)
Definition: attack.c:2349
MoveType move_off
Definition: object.h:430
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:363
int try_find_animation(const char *name)
Definition: anim.c:186
void player_unready_range_ob(player *pl, object *ob)
Definition: player.c:4512
void cast_magic_storm(object *op, object *tmp, int lvl)
Definition: spell_effect.c:45
#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:648
Definition: object.h:214
int cast_wonder(object *op, object *caster, int dir, object *spell_ob)
Definition: spell_effect.c:978
#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:929
#define HEAD(op)
Definition: object.h:594
#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:924
static int apply_check_apply_restrictions(object *who, object *op, int aflags)
Definition: apply.c:1801
const char * skill
Definition: object.h:321
int32_t last_eat
Definition: object.h:357
Definition: object.h:201
#define AC_PLAYER_STAT_NO_CHANGE
Definition: define.h:636
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:765
#define FOR_MAP_FINISH()
Definition: define.h:768
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:616
#define FLAG_CURSED
Definition: define.h:317
Definition: object.h:107
#define AP_NO_MERGE
Definition: define.h:619
void apply_auto_fix(mapstruct *m)
Definition: apply.c:1486
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:374
object * object_split(object *orig_ob, uint32_t nr, char *err, size_t size)
Definition: object.c:2480
#define INS_NO_MERGE
Definition: object.h:568
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
tag_t count
Definition: object.h:299
living stats
Definition: object.h:369
struct archt * arch
Definition: object.h:414
#define UPD_FACE
Definition: newclient.h:292
#define MAP_WIDTH(m)
Definition: map.h:78
void clear_skill(object *who)
Definition: skill_util.c:379
uint8_t type
Definition: object.h:339
struct Settings settings
Definition: init.c:39
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:1883
int execute_event(object *op, int eventcode, object *activator, object *third, const char *message, int fix)
Definition: main.c:365
#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:788
#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:605
object * identify(object *op)
Definition: item.c:1429
#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:871
void apply_by_living_below(object *pl)
Definition: apply.c:709
void do_learn_spell(object *op, object *spell, int special_prayer)
Definition: apply.c:486
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
struct obj * head
Definition: object.h:296
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:761
void play_sound_map(int8_t sound_type, object *emitter, int dir, const char *action)
Definition: sounds.c:107
#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:2536
void query_name(const object *op, char *buf, size_t size)
Definition: item.c:626
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:176
Definition: object.h:120
int16_t level
Definition: object.h:352
int8_t facing
Definition: object.h:336
uint8_t spell_failure_effects
Definition: global.h:271
void fix_object(object *op)
Definition: living.c:1120
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:192
struct obj * more
Definition: object.h:295
void object_update_speed(object *op)
Definition: object.c:1152
int apply_can_apply_object(const object *who, const object *op)
Definition: apply.c:1033
float item_power_factor
Definition: global.h:306
const char * name
Definition: object.h:468
#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:3057
#define FOR_INV_PREPARE(op_, it_)
Definition: define.h:708
void object_remove(object *op)
Definition: object.c:1668
uint8_t personalized_blessings
Definition: global.h:315
int apply_container(object *op, object *sack, int aflags)
Definition: apply.c:223
int8_t body_used[NUM_BODY_LOCATIONS]
Definition: object.h:375
int apply_check_weapon_power(const object *who, int improves)
Definition: apply.c:1148
Definition: object.h:224