Go to the documentation of this file.
15 #define _GNU_SOURCE // strcasestr() is a GNU extension in string.h
54 "But you have no free hands to steal with!");
68 else if (
op->invisible)
76 roll -= equip->weight/10000;
79 roll -= equip->weight/5000;
81 roll -= equip->weight/2000;
84 roll -= equip->weight/5000;
86 roll -= equip->weight/100;
112 object *success = NULL, *
tmp = NULL;
113 int roll = 0, chance = 0, stats_value;
117 stats_value = ((
who->stats.Dex+
who->stats.Int)*3)/2;
128 "Your attempt is prevented!");
137 op->stats.Wis += (
op->stats.Int/5)+1;
143 "You can't steal from the dungeon master!");
148 "You can't steal from other players!");
205 "%s%s has nothing you can steal!",
215 if (roll >= skill->
level
228 "%s notices your attempted pilfering!",
242 snprintf(
buf,
sizeof(
buf),
"Your %s is missing!",
name);
244 snprintf(
buf,
sizeof(
buf),
"Your pack feels strangely lighter.");
249 if (
who->invisible) {
250 snprintf(
buf,
sizeof(
buf),
"you feel itchy fingers getting at your pack.");
253 snprintf(
buf,
sizeof(
buf),
"%s looks very shifty.",
name);
261 return success ? 1 : 0;
277 int steal(
object *
op,
int dir,
object *skill) {
306 if (
tmp->above == NULL)
354 int difficulty =
pl->map->difficulty ?
pl->map->difficulty : 0;
355 int success = 0, number;
366 if (number < pl->stats.Dex + skill->
level*2 - difficulty ) {
368 success = difficulty;
401 "There is no lock there.");
411 "There is no lock there.");
420 "You can't pick that lock!");
424 if (!
tmp->move_block) {
426 "The door has no lock!");
434 "You fail to pick the lock.");
439 "You pick the lock.");
464 int number, difficulty =
op->map->difficulty;
476 op->invisible += 100;
478 op->contr->tmp_invis = 1;
500 "You don't need to hide while invisible!");
504 if (!
op->hide &&
op->invisible > 0 &&
op->type ==
PLAYER) {
506 "Your attempt to hide breaks the invisibility spell!");
510 if (
op->invisible > 50*skill->
level) {
512 "You are as hidden as you can get.");
518 "You hide in the shadows.");
523 "You fail to conceal yourself.");
564 "Your bounce off the walls of %s.", trans_name);
589 for (i = 0; i <= spaces; i++) {
602 "Your jump is blocked.");
613 "You jump into %s%s.",
664 int jump(
object *
pl,
int dir,
object *skill) {
665 int spaces = 0, stats;
666 int str =
pl->stats.Str;
667 int dex =
pl->stats.Dex;
669 dex = dex ? dex : 15;
674 if (
pl->carrying != 0)
675 spaces = (
int)(stats/
pl->carrying);
681 else if (spaces == 0) {
683 "You are carrying too much weight to jump.");
704 &&
tmp->item_power < skill->
level) {
809 int success = 0, chance;
810 int skill_value = (skill->
level &&
pl->stats.Int) ?
pl->stats.Int : 10;
813 uint32_t identified = 0;
814 for (uint32_t i = 0; i <
NROF(
tmp); i++) {
816 if (skill_value >= chance) {
821 if (identified == 0) {
843 if (
pl->type ==
PLAYER && print_on_success) {
851 "The item has a story:\n%s",
873 int success = 0, area, i;
877 if (
tmp->type == obj_class)
886 if (skill->
level > 64) {
888 }
else if (skill->
level > 16) {
890 }
else if (skill->
level > 4) {
896 for (i = 0; i < area; i++) {
908 if (
tmp->type == obj_class)
927 int i, identifiable_types=0;
934 "You look at the objects nearby with your %s skill...", skill->
name);
941 "...and discover cursed items!");
948 "...and discover items imbued with mystic forces!");
958 identifiable_types++;
962 if (identifiable_types == 0) {
963 LOG(
llevError,
"Error: skill_ident() called with skill %d which can't identify any items\n", skill->
subtype);
970 "...and learn nothing more.");
1012 "There is nothing to orate to.");
1022 if (tmp2->type ==
PLAYER)
1036 "There is nothing to orate to.");
1042 "You orate to the %s.",
1051 "Too bad the %s isn't listening!",
1060 "Your follower loves your speech.");
1071 "You convince the %s to follow you instead!",
1086 chance = skill->
level*2+(
pl->stats.Cha-2*
tmp->stats.Int)/2;
1093 "You convince the %s to become your follower.",
1098 tmp->stats.exp /= 5;
1113 "Your speech angers the %s!",
1119 tmp->attack_movement = 0;
1148 int i, exp = 0, chance, mflags;
1178 if (tmp2->type ==
PLAYER) {
1200 chance = skill->
level*2+(
pl->stats.Cha-5-
tmp->stats.Int)/2;
1209 "You calm down the %s",
1219 "Too bad the %s isn't listening!",
1239 int i, expsum = 0, mflags;
1247 for (i = 0; i < 9; i++) {
1265 if (tmp2->type ==
RUNE || tmp2->type ==
TRAP)
1268 if (tmp2->stats.Cha > 1) {
1275 tmp2->stats.Cha = 1;
1282 if (
tmp->stats.Cha > 1) {
1294 "You search the area.");
1310 int i, success = 0, mflags;
1314 for (i = 0; i < 9; i++) {
1332 if ((tmp2->type ==
RUNE || tmp2->type ==
TRAP) && tmp2->stats.Cha <= 1) {
1337 tmp2->stats.exp = tmp2->stats.Cha*tmp2->level;
1351 tmp->stats.exp =
tmp->stats.Cha*
tmp->level;
1388 snprintf(
buf,
sizeof(
buf),
"You pray.");
1398 snprintf(
buf,
sizeof(
buf),
"You pray over the %s.",
tmp->name);
1407 if (
pl->stats.grace <
pl->stats.maxgrace) {
1409 pl->last_grace = -1;
1437 "You can't concentrate while wielding a weapon!");
1449 "You can't concentrate while wearing so much armour!");
1465 if (
pl->stats.sp <
pl->stats.maxsp) {
1468 }
else if (
pl->stats.hp <
pl->stats.maxhp) {
1489 object *newBook = NULL;
1494 "That was interesting...");
1502 "Hmm... what was I going to write?");
1510 "Trying to cheat now are we?");
1527 snprintf(
buf,
sizeof(
buf),
"%s\n",
msg);
1531 if (
item->nrof > 1) {
1549 "You write in the %s.",
buf);
1557 "Your message won't fit in the %s!",
buf);
1577 int success = 0, confused = 0, grace_cost = 0;
1578 object *newscroll, *chosen_spell, *
tmp;
1583 "A spell must be written on a magic scroll!");
1590 if (!chosen_spell) {
1592 "You should ready the spell you wish to inscribe.");
1598 if (grace_cost > 0 && grace_cost >
pl->stats.grace) {
1601 "You don't have enough grace to write a scroll of %s.",
1602 chosen_spell->
name);
1609 "You don't have enough mana to write a scroll of %s.",
1610 chosen_spell->
name);
1622 "Just the idea of writing a scroll of %s makes you sick!",
1633 "Oops! You accidently read it while trying to write on it.");
1654 if (scroll->
nrof > 1) {
1658 newscroll->
nrof = 1;
1669 "You succeed in writing a new scroll.");
1672 if (!chosen_spell) {
1678 "In your confused state, you write down some odd spell.");
1681 if (newscroll->
inv) {
1683 ninv = newscroll->
inv;
1704 if (newscroll == scroll) {
1716 success = success * skill->
level;
1721 if (chosen_spell->
level > skill->
level || confused) {
1724 "Ouch! Your attempt to write a new scroll strains your mind!");
1731 return -30 * chosen_spell->
level;
1736 "Your attempt to write a new scroll rattles your mind!");
1741 "You fail to write a new scroll.");
1762 const char *
string =
params;
1782 "You must learn to read before you can write!");
1789 "You are unable to write while blind.");
1794 if (
string[0] !=
'\0') {
1804 "You haven't marked any items to write on yet.");
1811 "You had better pay for that before you write on it!");
1816 if (msgtype !=
item->type) {
1819 "You must mark a %s to write %s.",
1820 msgtype ==
BOOK ?
"book" :
"magic scroll",
1821 msgtype ==
BOOK ?
"your message on" :
"your spell down");
1825 if (msgtype ==
BOOK) {
1827 }
else if (msgtype ==
SCROLL) {
1852 LOG(
llevError,
"find_throw_ob(): confused! have a NULL thrower!\n");
1853 return (
object *)NULL;
1869 if (tmp2->invisible)
1883 if (tmp2->race == race) {
1902 "You can't throw %s.",
1909 "The %s sticks to your hand!",
1914 LOG(
llevError,
"BUG: find_throw_ob(): couldn't unapply\n");
1921 "You should pay for the %s first.",
1927 LOG(
llevError,
"BUG: find_throw_ob(): object is locked\n");
1952 LOG(
llevError,
"BUG: make_throw_ob(): ob is applied\n");
1985 static int do_throw(
object *
op,
object *part,
object *toss_item,
int dir,
object *skill) {
1986 object *throw_ob = toss_item, *left = NULL;
1987 int eff_str = 0,
str =
op->stats.Str, dam = 0;
1988 int pause_f, weight_f = 0, mflags;
1989 float str_factor = 1.0, load_factor = 1.0, item_factor = 1.0;
1995 if (throw_ob == NULL) {
1998 "You have nothing to throw.");
2005 "The gods won't let you throw that.");
2047 load_factor =
MIN(load_factor, 1.0f);
2051 if (throw_ob->
weight > 0)
2056 "You can't throw %s.",
2061 eff_str =
str*load_factor;
2062 eff_str = (float)eff_str*item_factor*str_factor;
2070 LOG(
llevDebug,
"%s carries %d, eff_str=%d\n",
op->name,
op->carrying, eff_str);
2093 "Your load is so heavy you drop %s to the ground.",
2098 "You throw %s at the ground.",
2102 "Something is in the way.");
2113 if (throw_ob == NULL) {
2130 throw_ob = toss_item;
2131 if (throw_ob->
skill)
2160 throw_ob->
last_sp = (eff_str*3)/5;
2183 throw_ob->
last_sp += eff_str/3;
2204 throw_ob->
speed *= 0.8;
2209 if (throw_ob->
weight > 500)
2210 throw_ob->
speed *= 0.8;
2211 if (throw_ob->
weight > 50)
2212 throw_ob->
speed *= 0.5;
2218 if (throw_ob->
last_sp > eff_str)
2228 pause_f = ((2*eff_str)/3)+20+skill->
level;
2240 op->speed_left -= 50.0/pause_f;
2283 return do_throw(
op, part, throw_ob, dir, skill);
#define object_was_destroyed(op, old_tag)
#define GET_MAP_OB(M, X, Y)
uint32_t get_weight_limit(int stat)
int remove_trap(object *op, object *skill)
static int write_note(object *pl, object *item, const char *msg)
static int attempt_pick_lock(object *door, object *pl, object *skill)
#define FREE_OBJ_NO_DESTROY_CALLBACK
void object_free(object *ob, int flags)
sstring add_string(const char *str)
void object_remove(object *op)
void remove_friendly_object(object *op)
int singing(object *pl, int dir, object *skill)
int monster_can_detect_enemy(object *op, object *enemy, rv_vector *rv)
void esrv_map_scroll(socket_struct *ns, int dx, int dy)
void object_update(object *op, int action)
object * find_random_spell_in_ob(object *ob, const char *skill)
#define QUERY_FLAG(xyz, p)
void confuse_living(object *op, object *hitter, int dam)
int write_on_item(object *pl, const char *params, object *skill)
void make_visible(object *op)
#define MSG_TYPE_ATTRIBUTE_GOOD_EFFECT_END
object * object_new(void)
#define FOR_BELOW_PREPARE(op_, it_)
int steal(object *op, int dir, object *skill)
void spring_trap(object *trap, object *victim)
#define MSG_TYPE_ATTRIBUTE
static object * make_throw_ob(object *orig)
static int attempt_steal(object *op, object *who, object *skill)
int jump(object *pl, int dir, object *skill)
int hide(object *op, object *skill)
int apply_manual(object *op, object *tmp, int aflag)
#define FOR_OB_AND_ABOVE_FINISH()
int get_dex_bonus(int stat)
int events_execute_object_event(object *op, int eventcode, object *activator, object *third, const char *message, int fix)
method_ret ob_process(object *op)
void cast_dust(object *op, object *throw_ob, int dir)
short freearr_x[SIZEOFFREE]
short freearr_y[SIZEOFFREE]
#define FOR_BELOW_FINISH()
object * object_merge(object *op, object *top)
#define FOR_OB_AND_ABOVE_PREPARE(op_)
object * identify(object *op)
void free_string(sstring str)
void remove_door(object *op)
static event_registration m
static uint32_t NROF(const object *const ob)
#define object_decrease_nrof_by_one(xyz)
object * monster_find_throw_ob(object *op)
void object_copy(const object *src_ob, object *dest_ob)
void query_name(const object *op, char *buf, size_t size)
int skill_throw(object *op, object *part, int dir, object *skill)
void object_update_turn_face(object *op)
#define FLAG_KNOWN_CURSED
static int do_skill_detect_curse(object *pl, object *skill)
int64_t calc_skill_exp(const object *who, const object *op, const object *skill)
#define FOR_OB_AND_BELOW_FINISH()
int object_can_pick(const object *who, const object *item)
int identify_object_with_skill(object *tmp, object *pl, object *skill, int print_on_success)
sstring find_string(const char *str)
void query_short_name(const object *op, char *buf, size_t size)
int get_dam_bonus(int stat)
#define FREE_AND_COPY(sv, nv)
int find_traps(object *pl, object *skill)
int skill_ident(object *pl, object *skill)
void fix_object(object *op)
int trap_disarm(object *disarmer, object *trap, int risk, object *skill)
int is_magical(const object *op)
#define GET_MAP_MOVE_BLOCK(M, X, Y)
static int adj_stealchance(object *op, object *victim, int roll)
#define INS_BELOW_ORIGINATOR
#define MSG_TYPE_SKILL_MISSING
const typedef char * sstring
int rndm(int min, int max)
#define FLAG_UNAGGRESSIVE
static int do_skill_ident(object *pl, int obj_class, object *skill)
#define FOR_OB_AND_BELOW_PREPARE(op_)
int16_t SP_level_spellpoint_cost(object *caster, object *spell, int flags)
static int write_scroll(object *pl, object *scroll, object *skill)
void object_set_owner(object *op, object *owner)
object * find_skill_by_name(object *who, const char *name)
#define MSG_TYPE_VICTIM_STEAL
int use_oratory(object *pl, int dir, object *skill)
int trap_show(object *trap, object *where)
int random_roll(int min, int max, const object *op, int goodbad)
#define FOR_MAP_PREPARE(map_, mx_, my_, it_)
#define FLAG_KNOWN_MAGICAL
#define OUT_OF_REAL_MAP(M, X, Y)
char * ob_describe(const object *op, const object *observer, int use_media_tags, char *buf, size_t size)
void object_set_msg(object *op, const char *msg)
int allow_denied_spells_writing
static int do_throw(object *op, object *part, object *toss_item, int dir, object *skill)
#define MSG_TYPE_SKILL_ERROR
int hideability(object *ob)
int die_roll(int num, int size, const object *op, int goodbad)
#define MSG_TYPE_SKILL_FAILURE
void meditate(object *pl, object *skill)
int pray(object *pl, object *skill)
void add_friendly_object(object *op)
#define MSG_TYPE_ITEM_REMOVE
void LOG(LogLevel logLevel, const char *format,...)
void monster_npc_call_help(object *op)
bool object_value_set(const object *op, const char *const key)
static int attempt_jump(object *pl, int dir, int spaces, object *skill)
int check_pick(object *op)
void esrv_update_item(int flags, object *pl, object *op)
#define CLEAR_FLAG(xyz, p)
int apply_special(object *who, object *op, int aflags)
#define NUM_ANIMATIONS(ob)
object * object_insert_in_ob(object *op, object *where)
const typedata * get_typedata(int itemtype)
void object_update_speed(object *op)
float get_speed_bonus(int stat)
#define SCRIPT_FIX_ACTIVATOR
object * ranges[range_size]
object * object_insert_in_map_at(object *op, mapstruct *m, object *originator, int flag, int x, int y)
void draw_ext_info(int flags, int pri, const object *pl, uint8_t type, uint8_t subtype, const char *message)
int detect_curse_on_item(object *pl, object *tmp, object *skill)
archetype * get_archetype_by_type_subtype(int type, int subtype)
int get_thaco_bonus(int stat)
int trap_see(object *op, object *trap)
#define OB_TYPE_MOVE_BLOCK(ob1, type)
static void stop_jump(object *pl)
int pick_lock(object *pl, int dir, object *skill)
uint8_t no_player_stealing
static int attempt_hide(object *op, object *skill)
#define MSG_TYPE_SKILL_SUCCESS
static object * find_throw_ob(object *op, sstring race)
int book_overflow(const char *buf1, const char *buf2, size_t booksize)
int stand_near_hostile(object *who)
static int do_skill_detect_magic(object *pl, object *skill)
int get_map_flags(mapstruct *oldmap, mapstruct **newmap, int16_t x, int16_t y, int16_t *nx, int16_t *ny)
void drain_specific_stat(object *op, int deplete_stats)
#define FLAG_READY_WEAPON
#define FLAG_NO_SKILL_IDENT
void pick_up(object *op, object *alt)
object * object_split(object *orig_ob, uint32_t nr, char *err, size_t size)
#define MSG_TYPE_ITEM_INFO
object * find_marked_object(object *op)
#define FOR_INV_PREPARE(op_, it_)
int can_see_monsterP(mapstruct *m, int x, int y, int dir)
void draw_ext_info_format(int flags, int pri, const object *pl, uint8_t type, uint8_t subtype, const char *format,...)
int detect_magic_on_item(object *pl, object *tmp, object *skill)
void skill_attack(object *tmp, object *pl, int dir, const char *string, object *skill)
#define FREE_PLAYER_LOAD_PERCENT
void pray_at_altar(object *pl, object *altar, object *skill)
object * object_get_owner(object *op)
int is_identified(const object *op)