55 return op->weight*nrof+transport->carrying <= transport->weight_limit;
69 int arch_flag, name_flag, race_flag;
72 if (victim->type == DOOR)
86 arch_flag = op->subtype&1;
87 name_flag = op->subtype&2;
88 race_flag = op->subtype&4;
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)))
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))))
147 const Face *newface = op->arch->clone.face;
155 if (newface && op->face != newface) {
175 const Face *newface = NULL;
176 object *head = op->head ? op->head : op;
181 if (head->face && head->other_arch && head->other_arch->clone.face)
182 newface = head->other_arch->clone.face;
184 if (op->face != op->arch->clone.face) {
192 if (newface && op->face != newface) {
224 object *tmp = op->container;
226 if (op->type != PLAYER)
229 if (sack == NULL || sack->type != CONTAINER) {
230 LOG(
llevError,
"apply_container: '%s' tried to apply %s, which is not a container\n", op->name, sack ? sack->name :
"(null)");
241 if ( sack->env != op ) {
243 "Not in your inventory: %s",
250 if ( op->container == sack ) {
251 op->container = NULL;
252 if (op->contr != NULL)
253 op->contr->socket.container_position = 0;
269 "Already readied %s.",
279 if ( op->container == sack ) {
281 "Already opened %s.",
292 if ( op->container != sack ) {
303 "Already closed %s.",
320 tag_t tmp_tag = op->container->count;
322 if (op->container->env != op) {
323 object *part = op->container->head ? op->container->head : op->container;
341 op->container = NULL;
342 if (op->contr != NULL)
343 op->contr->socket.container_position = 0;
346 if (!object_was_destroyed(tmp, tmp_tag)) {
368 "You unlock %s with %s.",
369 name_sack, name_tmp);
373 "You don't have the key to unlock %s.",
391 if (sack->env != op) {
404 if (sack->nrof > 1) {
405 object *left =
object_split(sack, sack->nrof-1, NULL, 0);
414 object *part = sack->head ? sack->head : sack;
426 op->container = sack;
427 if (op->contr != NULL)
428 op->contr->socket.container_position = 0;
442 op->container = sack;
443 if (op->contr != NULL)
444 op->contr->socket.container_position = 0;
487 if (op->type != PLAYER) {
488 LOG(
llevError,
"BUG: do_learn_spell(): not a player\n");
496 LOG(
llevError,
"BUG: do_learn_spell(): spell already known, but not marked as startequip\n");
511 "Type 'bind cast %s to store the spell in a key.",
528 if (op->type != PLAYER) {
529 LOG(
llevError,
"BUG: do_forget_spell(): not a player\n");
534 LOG(
llevError,
"BUG: do_forget_spell(): spell not known\n");
539 "You lose knowledge of %s.",
568 snprintf(buf,
sizeof(buf),
":%s:", who->race);
569 buf[
sizeof(
buf)-1] =
'\0';
571 if (strstr(restriction, buf) != NULL)
601 if (op->type == PLAYER) {
603 "You should pay for it first.");
640 if (op->env == NULL && (pl->move_type&
MOVE_FLYING)) {
644 "But you are floating high above the ground!");
652 if (op->type != PLAYER
657 "The object disappears in a puff of smoke!");
659 "It must have been an illusion.");
672 "I don't know how to apply the %s.",
676 "You must get it first!\n");
681 if (op->anim_suffix != NULL)
699 if (pl->contr->transport && pl->contr->transport->type == TRANSPORT) {
700 ob_apply(pl->contr->transport, pl, 0);
707 tmp = pl->container != NULL ? pl->container->inv : pl->below;
727 if (!tmp->invisible || (tmp->move_on&pl->move_type)) {
754 if (op->type != LAMP)
765 who->current_weapon = NULL;
771 if (op != who->chosen_skill)
772 LOG(
llevError,
"BUG: unapply_special(): applied skill is not a chosen skill\n");
773 if (who->type == PLAYER) {
776 if (!op->invisible) {
777 if (!(aflags&AP_NOPRINT))
779 "You stop using the %s.",
782 if (!(aflags&AP_NOPRINT))
784 "You can no longer use the skill: %s.",
789 who->chosen_skill = NULL;
803 if (!(aflags&AP_NOPRINT))
814 if (!(aflags&AP_NOPRINT))
818 if (who->type == PLAYER)
820 else if (op->type == BOW)
827 if (!(aflags&AP_NOPRINT))
836 if (!(aflags&AP_NOPRINT))
849 if (who->type == PLAYER) {
887 && tmp->body_info[loc]
888 && (!tmp->invisible || tmp->type == SKILL))
917 object *tmp = NULL, *last;
923 if (op->type == WEAPON || op->type == SHIELD) {
937 "No matter how hard you try, you just can't remove %s.",
943 if (aflags&AP_PRINT) {
953 for (i = 0; i < NUM_BODY_LOCATIONS; i++) {
955 if (op->body_info[i]) {
961 while (who->body_used[i]+op->body_info[i] < 0) {
970 if (aflags&AP_PRINT) {
985 "The %s just won't come off",
1018 object *tmp = NULL, *ws = NULL;
1025 if (op->type == WEAPON || op->type == SHIELD) {
1033 for (i = 0; i < NUM_BODY_LOCATIONS; i++) {
1034 if (op->body_info[i]) {
1036 if (
FABS(op->body_info[i]) > who->body_info[i]) {
1041 }
else if (who->body_used[i]+op->body_info[i] < 0) {
1057 if (who->body_used[i]-ws->body_info[i]+op->body_info[i] >= 0) {
1074 else if (tmp != tmp1)
1081 if (who->body_used[i]-tmp1->body_info[i] != who->body_info[i]
1082 &&
FABS(op->body_info[i]) < who->body_info[i])
1089 if (who->body_used[i]+op->body_info[i]-tmp1->body_info[i] < 0)
1104 if (who->type != PLAYER) {
1105 if ((op->type == WAND || op->type == ROD)
1132 return (who->level/5)+5 >= improves;
1162 LOG(
llevError,
"apply_special() from object without environment.\n");
1180 "No matter how hard you try, you just can't remove %s.",
1194 if (op->skill && op->type != SKILL && op->type != SKILL_TOOL) {
1199 "You need the %s skill to use this item!",
1201 if (who->type == PLAYER)
1224 tmp = op->nrof <= 1 ? NULL :
object_split(op, op->nrof-1, NULL, 0);
1231 "That weapon is too powerful for you to use. It would consume your soul!");
1270 if (!(aflags&AP_NOPRINT)) {
1282 if (who->chosen_skill) {
1283 LOG(
llevError,
"BUG: apply_special(): can't apply two skills\n");
1290 who->chosen_skill = op;
1296 if (!(aflags&AP_NOPRINT))
1298 "That weapon is too powerful for you to use. It would consume your soul!");
1316 if (!(aflags&AP_NOPRINT)) {
1322 if (who->type == PLAYER) {
1323 if (op->type == BOW) {
1325 if (!(aflags&AP_NOPRINT)) {
1328 "You will now fire %s with %s.",
1329 op->race ? op->race :
"nothing",
1336 if (op->type == BOW)
1348 if (!(aflags&AP_NOPRINT)) {
1351 "You ready your %s.",
1375 if (who->type == PLAYER && op->type != WAND && op->type != ROD)
1379 if (who->type == PLAYER) {
1381 "Oops, it feels deadly cold!");
1385 if (who->type == PLAYER)
1411 while ((tmp =
generate_treasure(op->randomitems, op->stats.exp ? (
int)op->stats.exp :
MAX(op->map->difficulty, 5))) == NULL
1431 while (op->stats.hp-- > 0)
1477 while (invtmp->stats.hp-- > 0)
1479 invtmp->randomitems = NULL;
1480 }
else if (invtmp && invtmp->arch
1481 && invtmp->type != TREASURE
1482 && invtmp->type != SPELL
1483 && invtmp->type != CLASS
1489 invtmp->randomitems = NULL;
1505 if (tmp->type == WAND
1507 || tmp->type == SCROLL
1508 || tmp->type == FIREWALL
1509 || tmp->type == POTION
1510 || tmp->type == ALTAR
1511 || tmp->type == SPELLBOOK)
1512 tmp->randomitems = NULL;
1517 else if ((tmp->type == TREASURE || tmp->type == CONTAINER)
1519 while (tmp->stats.hp-- > 0)
1521 tmp->randomitems = NULL;
1522 }
else if (tmp->type == TIMED_GATE) {
1523 object *head = HEAD(tmp);
1540 && tmp->type != PLAYER
1541 && tmp->type != TREASURE
1542 && tmp->type != SPELL
1543 && tmp->type != PLAYER_CHANGER
1544 && tmp->type != CLASS
1547 tmp->randomitems = NULL;
1558 && (tmp->type == TRIGGER_BUTTON || tmp->type == TRIGGER_PEDESTAL))
1578 if (abs(failure/4) > power)
1579 power = abs(failure/4);
1581 if (failure <= -1 && failure > -15) {
1585 "Your spell warps!");
1588 if (op->stats.sp < 0)
1596 if (failure <= -35 && failure > -60) {
1598 "The magic recoils on you!");
1603 if (failure <= -60 && failure > -70) {
1605 "The magic recoils and paralyzes you!");
1610 if (failure <= -70 && failure > -80) {
1612 "The magic recoils on you!");
1617 if (failure <= -80) {
1623 "You unleash uncontrolled mana!");
1631 "Your mana is drained!");
1633 if (op->stats.sp < 0)
1650 int excess_stat = 0;
1655 if (change->type != CLASS)
return;
1668 if (stat > 20+race_bonus) {
1670 stat = 20+race_bonus;
1671 }
else if (stat < 1) {
1679 excess_stat += stat;
1689 if (excess_stat < 0) excess_stat = 0;
1695 for (j = 0; excess_stat > 0 && j < 100; j++) {
1697 int i =
rndm(0, NUM_STATS-1);
1705 if (stat < 20+race_bonus) {
1716 if (change->randomitems != NULL)
1728 if (change->anim_suffix) {
1731 snprintf(buf,
MAX_BUF,
"%s_%s", pl->animation->name, change->anim_suffix);
1734 pl->animation = anim;
1735 pl->anim_speed = -1;
1745 if ((!has_noclassfacechange) && anim == 0) {
1747 pl->face = change->face;
1791 "You don't have the body to use a %s",
1803 "You have a prohibition against using a %s",
1809 if (who->type != PLAYER) {
1818 "You need to unapply some item(s):");
1844 if (who->type != PLAYER)
1847 if (op->item_power == 0
1853 "Equipping that combined with other items would consume your soul!");
1878 int damage_percentile;
1885 if (owner == NULL || strcmp(owner, who->name) == 0)
1889 item_will = will != NULL ? atol(will) : 0;
1890 if (item_will > who->stats.exp) {
1892 "This %s refuses to serve you - it keeps evading your hand !",
1897 margin = item_will != 0 ? who->stats.exp/item_will : who->stats.exp;
1898 random_effect =
random_roll(0, 100, who, 1)-margin*20;
1899 if (random_effect > 80) {
1900 msg =
"You don't know why, but you have the feeling that the %s is angry at you !";
1901 damage_percentile = 60;
1902 }
else if (random_effect > 60) {
1903 msg =
"The %s seems to look at you nastily !";
1904 damage_percentile = 45;
1905 }
else if (random_effect > 40) {
1906 msg =
"You have the strange feeling that the %s is annoyed...";
1907 damage_percentile = 30;
1908 }
else if (random_effect > 20) {
1909 msg =
"The %s seems tired, or bored, in a way. Very strange !";
1910 damage_percentile = 15;
1911 }
else if (random_effect > 0) {
1912 msg =
"You hear the %s sighing !";
1913 damage_percentile = 0;
1916 damage_percentile = 0;
1921 if (damage_percentile > 0) {
1922 int weapon_bite = (who->stats.hp*damage_percentile)/100;
1923 if (weapon_bite < 1)
1925 who->stats.hp -= weapon_bite;
1927 "You get a nasty bite in the hand !");
1948 const char *quotepos;
1953 quotepos = strstr(op->name,
"'");
1954 if (quotepos == NULL || strncmp(op->name, who->name, quotepos-op->name) == 0)
1959 "The weapon does not recognize you as its owner.");
1974 if (who->type != PLAYER) {
1980 if (op->invisible) {
1983 "Readied skill: %s.",
1984 op->skill ? op->skill : op->name);
1994 "You can now use the skill: %s.",
void draw_ext_info_format(int flags, int pri, const object *pl, uint8_t type, uint8_t subtype, const char *format,...)
static int apply_check_owner(const object *who, const object *op, int aflags)
void set_attr_value(living *stats, int attr, int8_t value)
static int apply_check_race_restrictions(object *who, object *item)
int change_skill(object *who, object *new_skill, int flag)
void object_free(object *ob, int flags)
#define CAN_APPLY_UNAPPLY_CHOICE
object * check_spell_known(object *op, const char *name)
#define MSG_TYPE_APPLY_PROHIBITION
void apply_anim_suffix(object *who, const char *suffix)
void esrv_send_item(object *pl, object *op)
object * object_find_by_type_applied(const object *who, int type)
#define MSG_TYPE_APPLY_FAILURE
#define MSG_TYPE_APPLY_BADBODY
void do_forget_spell(object *op, const char *spell)
static int apply_check_item_power(const object *who, const object *op, int aflags)
void esrv_update_item(int flags, object *pl, object *op)
const char * object_get_value(const object *op, const char *const key)
int apply_auto(object *op)
void esrv_send_inventory(object *pl, object *op)
static void apply_update_ranged_skill(const object *who, object *op, int aflags)
void blind_living(object *op, object *hitter, int dam)
int8_t get_attr_value(const living *stats, int attr)
method_ret ob_apply(object *op, object *applier, int aflags)
void scroll_failure(object *op, int failure, int power)
int set_object_face_main(object *op)
object * object_find_by_name(const object *who, const char *name)
void draw_ext_info(int flags, int pri, const object *pl, uint8_t type, uint8_t subtype, const char *message)
#define FOR_OB_AND_BELOW_FINISH()
void esrv_add_spells(player *pl, object *spell)
void create_treasure(treasurelist *t, object *op, int flag, int difficulty, int tries)
#define CAN_APPLY_UNAPPLY_MULT
int rndm(int min, int max)
void apply_changes_to_player(object *pl, object *change, int limit_stats)
const Face * try_find_face(const char *name, const Face *error)
void apply_handle_yield(object *tmp)
static int apply_check_personalized_blessings(object *who, const object *op)
int object_set_value(object *op, const char *key, const char *value, int add_key)
void object_free_drop_inventory(object *ob)
int change_abil(object *op, object *tmp)
#define CAN_APPLY_UNAPPLY
object * object_insert_in_map_at(object *op, mapstruct *m, object *originator, int flag, int x, int y)
int should_director_abort(const object *op, const object *victim)
int apply_special(object *who, object *op, int aflags)
void confuse_living(object *op, object *hitter, int dam)
object * object_new(void)
#define CAN_APPLY_RESTRICTION
object * object_insert_in_ob(object *op, object *where)
static object * get_item_from_body_location(object *start, int loc)
#define AC_PLAYER_STAT_LIMIT
object * create_archetype(const char *name)
void monster_check_apply_all(object *monster)
#define MSG_TYPE_APPLY_ERROR
void change_attr_value(living *stats, int attr, int8_t value)
#define MSG_TYPE_VICTIM_WAS_HIT
#define FLAG_IS_A_TEMPLATE
void paralyze_living(object *op, int dam)
int transport_can_hold(const object *transport, const object *op, int nrof)
void player_unready_range_ob(player *pl, object *ob)
void cast_magic_storm(object *op, object *tmp, int lvl)
int apply_by_living(object *pl, object *op, int aflag, int quiet)
int cast_wonder(object *op, object *caster, int dir, object *spell_ob)
#define QUERY_FLAG(xyz, p)
#define CLEAR_FLAG(xyz, p)
static int unapply_for_ob(object *who, object *op, int aflags)
#define MSG_TYPE_APPLY_UNAPPLY
#define FLAG_BEEN_APPLIED
void give_initial_items(object *pl, treasurelist *items)
void drop(object *op, object *tmp)
static int apply_check_apply_restrictions(object *who, object *op, int aflags)
#define AC_PLAYER_STAT_NO_CHANGE
#define FLAG_READY_WEAPON
static int unapply_special(object *who, object *op, int aflags)
void animate_object(object *op, int dir)
#define FLAG_KNOWN_CURSED
void apply_auto_fix(mapstruct *m)
object * object_split(object *orig_ob, uint32_t nr, char *err, size_t size)
void play_sound_player_only(player *pl, int8_t sound_type, object *emitter, int dir, const char *action)
Animations * try_find_animation(const char *name)
void clear_skill(object *who)
void esrv_remove_spell(player *pl, object *spell)
#define METHOD_SILENT_ERROR
object * object_merge(object *op, object *top)
#define MSG_TYPE_APPLY_SUCCESS
#define FOR_OB_AND_BELOW_PREPARE(op_)
int apply_manual(object *op, object *tmp, int aflag)
object * identify(object *op)
#define MSG_TYPE_APPLY_CURSED
void object_copy(const object *src_ob, object *dest_ob)
int events_execute_object_event(object *op, int eventcode, object *activator, object *third, const char *message, int fix)
void apply_by_living_below(object *pl)
void do_learn_spell(object *op, object *spell, int special_prayer)
void LOG(LogLevel logLevel, const char *format,...)
#define FOR_MAP_PREPARE(map_, mx_, my_, it_)
void play_sound_map(int8_t sound_type, object *emitter, int dir, const char *action)
object * find_key(object *pl, object *container, object *door)
void query_name(const object *op, char *buf, size_t size)
object * generate_treasure(treasurelist *t, int difficulty)
int random_roll(int min, int max, const object *op, int goodbad)
static int set_object_face_other(object *op)
uint8_t spell_failure_effects
void fix_object(object *op)
object * find_skill_by_name(object *who, const char *name)
void object_update_speed(object *op)
int apply_can_apply_object(const object *who, const object *op)
#define HAS_RANDOM_ITEMS(op)
object * object_present_in_ob_by_name(int type, const char *str, const object *op)
#define FOR_INV_PREPARE(op_, it_)
void object_remove(object *op)
uint8_t personalized_blessings
int apply_container(object *op, object *sack, int aflags)
int apply_check_weapon_power(const object *who, int improves)