Go to the documentation of this file.
16 #define _GNU_SOURCE // strcasestr() is a GNU extension in string.h
56 "But you have no free hands to steal with!");
70 else if (
op->invisible)
78 roll -= equip->weight/10000;
81 roll -= equip->weight/5000;
83 roll -= equip->weight/2000;
86 roll -= equip->weight/5000;
88 roll -= equip->weight/100;
114 object *success = NULL, *
tmp = NULL;
115 int roll = 0, chance = 0, stats_value;
119 stats_value = ((
who->stats.Dex+
who->stats.Int)*3)/2;
130 "Your attempt is prevented!");
139 op->stats.Wis += (
op->stats.Int/5)+1;
145 "You can't steal from the dungeon master!");
150 "You can't steal from other players!");
207 "%s%s has nothing you can steal!",
217 if (roll >= skill->
level
230 "%s notices your attempted pilfering!",
244 snprintf(
buf,
sizeof(
buf),
"Your %s is missing!",
name);
246 snprintf(
buf,
sizeof(
buf),
"Your pack feels strangely lighter.");
251 if (
who->invisible) {
252 snprintf(
buf,
sizeof(
buf),
"you feel itchy fingers getting at your pack.");
255 snprintf(
buf,
sizeof(
buf),
"%s looks very shifty.",
name);
263 return success ? 1 : 0;
279 int steal(
object *
op,
int dir,
object *skill) {
308 if (
tmp->above == NULL)
356 int difficulty =
pl->map->difficulty ?
pl->map->difficulty : 0;
357 int success = 0, number;
368 if (number < pl->stats.Dex + skill->
level*2 - difficulty ) {
370 success = difficulty;
403 "There is no lock there.");
413 "There is no lock there.");
422 "You can't pick that lock!");
426 if (!
tmp->move_block) {
428 "The door has no lock!");
436 "You fail to pick the lock.");
441 "You pick the lock.");
466 int number, difficulty =
op->map->difficulty;
478 op->invisible += 100;
480 op->contr->tmp_invis = 1;
502 "You don't need to hide while invisible!");
506 if (!
op->hide &&
op->invisible > 0 &&
op->type ==
PLAYER) {
508 "Your attempt to hide breaks the invisibility spell!");
512 if (
op->invisible > 50*skill->
level) {
514 "You are as hidden as you can get.");
520 "You hide in the shadows.");
525 "You fail to conceal yourself.");
562 if (
pl->contr &&
pl->contr->transport){
566 "Your bounce off the walls of %s.", trans_name);
591 for (i = 0; i <= spaces; i++) {
604 "Your jump is blocked.");
615 "You jump into %s%s.",
620 || (
pl->type ==
PLAYER &&
pl->contr->party == NULL)
666 int jump(
object *
pl,
int dir,
object *skill) {
667 int spaces = 0, stats;
668 int str =
pl->stats.Str;
669 int dex =
pl->stats.Dex;
671 dex = dex ? dex : 15;
676 if (
pl->carrying != 0)
677 spaces = (
int)(stats/
pl->carrying);
683 else if (spaces == 0) {
685 "You are carrying too much weight to jump.");
706 &&
tmp->item_power < skill->
level) {
811 int success = 0, chance;
812 int skill_value = (skill->
level &&
pl->stats.Int) ?
pl->stats.Int : 10;
815 uint32_t identified = 0;
816 for (uint32_t i = 0; i <
NROF(
tmp); i++) {
818 if (skill_value >= chance) {
823 if (identified == 0) {
845 if (
pl->type ==
PLAYER && print_on_success) {
853 "The item has a story:\n%s",
875 int success = 0, area, i;
879 if (
tmp->type == obj_class)
888 if (skill->
level > 64) {
890 }
else if (skill->
level > 16) {
892 }
else if (skill->
level > 4) {
898 for (i = 0; i < area; i++) {
910 if (
tmp->type == obj_class)
929 int i, identifiable_types=0;
936 "You look at the objects nearby with your %s skill...", skill->
name);
943 "...and discover cursed items!");
950 "...and discover items imbued with mystic forces!");
960 identifiable_types++;
964 if (identifiable_types == 0) {
965 LOG(
llevError,
"Error: skill_ident() called with skill %d which can't identify any items\n", skill->
subtype);
972 "...and learn nothing more.");
1014 "There is nothing to orate to.");
1024 if (tmp2->type ==
PLAYER)
1038 "There is nothing to orate to.");
1044 "You orate to the %s.",
1053 "Too bad the %s isn't listening!",
1062 "Your follower loves your speech.");
1073 "You convince the %s to follow you instead!",
1088 chance = skill->
level*2+(
pl->stats.Cha-2*
tmp->stats.Int)/2;
1095 "You convince the %s to become your follower.",
1100 tmp->stats.exp /= 5;
1115 "Your speech angers the %s!",
1121 tmp->attack_movement = 0;
1150 int i, exp = 0, chance, mflags;
1180 if (tmp2->type ==
PLAYER) {
1202 chance = skill->
level*2+(
pl->stats.Cha-5-
tmp->stats.Int)/2;
1211 "You calm down the %s",
1221 "Too bad the %s isn't listening!",
1241 int i, expsum = 0, mflags;
1249 for (i = 0; i < 9; i++) {
1267 if (tmp2->type ==
RUNE || tmp2->type ==
TRAP)
1270 if (tmp2->stats.Cha > 1) {
1277 tmp2->stats.Cha = 1;
1284 if (
tmp->stats.Cha > 1) {
1296 "You search the area.");
1312 int i, success = 0, mflags;
1316 for (i = 0; i < 9; i++) {
1334 if ((tmp2->type ==
RUNE || tmp2->type ==
TRAP) && tmp2->stats.Cha <= 1) {
1339 tmp2->stats.exp = tmp2->stats.Cha*tmp2->level;
1353 tmp->stats.exp =
tmp->stats.Cha*
tmp->level;
1390 snprintf(
buf,
sizeof(
buf),
"You pray.");
1400 snprintf(
buf,
sizeof(
buf),
"You pray over the %s.",
tmp->name);
1409 if (
pl->stats.grace <
pl->stats.maxgrace) {
1411 pl->last_grace = -1;
1439 "You can't concentrate while wielding a weapon!");
1451 "You can't concentrate while wearing so much armour!");
1467 if (
pl->stats.sp <
pl->stats.maxsp) {
1470 }
else if (
pl->stats.hp <
pl->stats.maxhp) {
1491 object *newBook = NULL;
1496 "That was interesting...");
1504 "Hmm... what was I going to write?");
1512 "Trying to cheat now are we?");
1529 snprintf(
buf,
sizeof(
buf),
"%s\n",
msg);
1533 if (
item->nrof > 1) {
1551 "You write in the %s.",
buf);
1559 "Your message won't fit in the %s!",
buf);
1579 int success = 0, confused = 0, grace_cost = 0;
1580 object *newscroll, *chosen_spell, *
tmp;
1585 "A spell must be written on a magic scroll!");
1592 if (!chosen_spell) {
1594 "You should ready the spell you wish to inscribe.");
1600 if (grace_cost > 0 && grace_cost >
pl->stats.grace) {
1603 "You don't have enough grace to write a scroll of %s.",
1604 chosen_spell->
name);
1611 "You don't have enough mana to write a scroll of %s.",
1612 chosen_spell->
name);
1624 "Just the idea of writing a scroll of %s makes you sick!",
1635 "Oops! You accidently read it while trying to write on it.");
1656 if (scroll->
nrof > 1) {
1660 newscroll->
nrof = 1;
1671 "You succeed in writing a new scroll.");
1674 if (!chosen_spell) {
1680 "In your confused state, you write down some odd spell.");
1683 if (newscroll->
inv) {
1685 ninv = newscroll->
inv;
1706 if (newscroll == scroll) {
1718 success = success * skill->
level;
1723 if (chosen_spell->
level > skill->
level || confused) {
1726 "Ouch! Your attempt to write a new scroll strains your mind!");
1733 return -30 * chosen_spell->
level;
1738 "Your attempt to write a new scroll rattles your mind!");
1743 "You fail to write a new scroll.");
1764 const char *
string =
params;
1784 "You must learn to read before you can write!");
1791 "You are unable to write while blind.");
1796 if (
string[0] !=
'\0') {
1806 "You haven't marked any items to write on yet.");
1813 "You had better pay for that before you write on it!");
1818 if (msgtype !=
item->type) {
1821 "You must mark a %s to write %s.",
1822 msgtype ==
BOOK ?
"book" :
"magic scroll",
1823 msgtype ==
BOOK ?
"your message on" :
"your spell down");
1827 if (msgtype ==
BOOK) {
1829 }
else if (msgtype ==
SCROLL) {
1854 LOG(
llevError,
"find_throw_ob(): confused! have a NULL thrower!\n");
1855 return (
object *)NULL;
1871 if (tmp2->invisible)
1885 if (tmp2->race == race) {
1904 "You can't throw %s.",
1911 "The %s sticks to your hand!",
1916 LOG(
llevError,
"BUG: find_throw_ob(): couldn't unapply\n");
1923 "You should pay for the %s first.",
1929 LOG(
llevError,
"BUG: find_throw_ob(): object is locked\n");
1954 LOG(
llevError,
"BUG: make_throw_ob(): ob is applied\n");
1987 static int do_throw(
object *
op,
object *part,
object *toss_item,
int dir,
object *skill) {
1988 object *throw_ob = toss_item, *left = NULL;
1989 int eff_str = 0,
str =
op->stats.Str, dam = 0;
1990 int pause_f, weight_f = 0, mflags;
1991 float str_factor = 1.0, load_factor = 1.0, item_factor = 1.0;
1997 if (throw_ob == NULL) {
2000 "You have nothing to throw.");
2007 "The gods won't let you throw that.");
2049 load_factor =
MIN(load_factor, 1.0f);
2053 if (throw_ob->
weight > 0)
2058 "You can't throw %s.",
2063 eff_str =
str*load_factor;
2064 eff_str = (float)eff_str*item_factor*str_factor;
2072 LOG(
llevDebug,
"%s carries %d, eff_str=%d\n",
op->name,
op->carrying, eff_str);
2095 "Your load is so heavy you drop %s to the ground.",
2100 "You throw %s at the ground.",
2104 "Something is in the way.");
2115 if (throw_ob == NULL) {
2132 throw_ob = toss_item;
2133 if (throw_ob->
skill)
2162 throw_ob->
last_sp = (eff_str*3)/5;
2185 throw_ob->
last_sp += eff_str/3;
2206 throw_ob->
speed *= 0.8;
2211 if (throw_ob->
weight > 500)
2212 throw_ob->
speed *= 0.8;
2213 if (throw_ob->
weight > 50)
2214 throw_ob->
speed *= 0.5;
2220 if (throw_ob->
last_sp > eff_str)
2230 pause_f = ((2*eff_str)/3)+20+skill->
level;
2242 op->speed_left -= 50.0/pause_f;
2285 return do_throw(
op, part, throw_ob, dir, skill);
#define object_was_destroyed(op, old_tag)
bool object_value_set(const object *op, const char *const key)
#define GET_MAP_OB(M, X, Y)
object * object_get_owner(object *op)
#define FREE_OBJ_NO_DESTROY_CALLBACK
void object_update_turn_face(object *op)
void remove_friendly_object(object *op)
void LOG(LogLevel logLevel, const char *format,...)
int singing(object *pl, int dir, object *skill)
void drain_specific_stat(object *op, int deplete_stats)
int monster_can_detect_enemy(object *op, object *enemy, rv_vector *rv)
void esrv_map_scroll(socket_struct *ns, int dx, int dy)
static object * find_throw_ob(object *op, sstring race)
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)
object * object_merge(object *op, object *top)
void make_visible(object *op)
#define MSG_TYPE_ATTRIBUTE_GOOD_EFFECT_END
#define FOR_BELOW_PREPARE(op_, it_)
void spring_trap(object *trap, object *victim)
int use_oratory(object *pl, int dir, object *skill)
void object_set_owner(object *op, object *owner)
#define MSG_TYPE_ATTRIBUTE
static int do_throw(object *op, object *part, object *toss_item, int dir, object *skill)
void draw_ext_info_format(int flags, int pri, const object *pl, uint8_t type, uint8_t subtype, const char *format,...) PRINTF_ARGS(6
int detect_magic_on_item(object *pl, object *tmp, object *skill)
void object_copy(const object *src_ob, object *dest_ob)
static int do_skill_detect_magic(object *pl, object *skill)
void fix_object(object *op)
int rndm(int min, int max)
int pray(object *pl, object *skill)
int apply_manual(object *op, object *tmp, int aflag)
#define FOR_OB_AND_ABOVE_FINISH()
int events_execute_object_event(object *op, int eventcode, object *activator, object *third, const char *message, int fix)
object * object_insert_in_ob(object *op, object *where)
int find_traps(object *pl, object *skill)
void cast_dust(object *op, object *throw_ob, int dir)
#define FOR_BELOW_FINISH()
#define FOR_OB_AND_ABOVE_PREPARE(op_)
void remove_door(object *op)
static event_registration m
void object_update(object *op, int action)
static uint32_t NROF(const object *const ob)
#define object_decrease_nrof_by_one(xyz)
short freearr_y[SIZEOFFREE]
static object * make_throw_ob(object *orig)
const typedata * get_typedata(int itemtype)
object * monster_find_throw_ob(object *op)
int pick_lock(object *pl, int dir, object *skill)
void query_name(const object *op, char *buf, size_t size)
int can_see_monsterP(mapstruct *m, int x, int y, int dir)
#define FLAG_KNOWN_CURSED
int64_t calc_skill_exp(const object *who, const object *op, const object *skill)
sstring add_string(const char *str)
#define FOR_OB_AND_BELOW_FINISH()
void query_short_name(const object *op, char *buf, size_t size)
sstring find_string(const char *str)
int is_identified(const object *op)
char * ob_describe(const object *op, const object *observer, int use_media_tags, char *buf, size_t size)
void object_update_speed(object *op)
#define FREE_AND_COPY(sv, nv)
int hide(object *op, object *skill)
static int adj_stealchance(object *op, object *victim, int roll)
static int attempt_pick_lock(object *door, object *pl, object *skill)
int trap_disarm(object *disarmer, object *trap, int risk, object *skill)
void object_free(object *ob, int flags)
#define GET_MAP_MOVE_BLOCK(M, X, Y)
#define INS_BELOW_ORIGINATOR
#define MSG_TYPE_SKILL_MISSING
#define FLAG_UNAGGRESSIVE
int skill_throw(object *op, object *part, int dir, object *skill)
#define FOR_OB_AND_BELOW_PREPARE(op_)
int16_t SP_level_spellpoint_cost(object *caster, object *spell, int flags)
int random_roll(int min, int max, const object *op, int goodbad)
int get_dam_bonus(int stat)
int skill_ident(object *pl, object *skill)
object * object_insert_in_map_at(object *op, mapstruct *m, object *originator, int flag, int x, int y)
object * find_skill_by_name(object *who, const char *name)
#define MSG_TYPE_VICTIM_STEAL
int get_dex_bonus(int stat)
object * object_new(void)
uint32_t get_weight_limit(int stat)
void free_string(sstring str)
int trap_show(object *trap, object *where)
#define FOR_MAP_PREPARE(map_, mx_, my_, it_)
#define FLAG_KNOWN_MAGICAL
#define OUT_OF_REAL_MAP(M, X, Y)
static void stop_jump(object *pl)
int identify_object_with_skill(object *tmp, object *pl, object *skill, int print_on_success)
int allow_denied_spells_writing
#define MSG_TYPE_SKILL_ERROR
int hideability(object *ob)
method_ret ob_process(object *op)
#define MSG_TYPE_SKILL_FAILURE
static int attempt_steal(object *op, object *who, object *skill)
int steal(object *op, int dir, object *skill)
int get_thaco_bonus(int stat)
int object_can_pick(const object *who, const object *item)
void add_friendly_object(object *op)
int get_map_flags(mapstruct *oldmap, mapstruct **newmap, int16_t x, int16_t y, int16_t *nx, int16_t *ny)
#define MSG_TYPE_ITEM_REMOVE
int is_magical(const object *op)
static int write_note(object *pl, object *item, const char *msg)
const typedef char * sstring
void monster_npc_call_help(object *op)
object * object_split(object *orig_ob, uint32_t nr, char *err, size_t size)
int check_pick(object *op)
float get_speed_bonus(int stat)
void object_set_msg(object *op, const char *msg)
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)
int die_roll(int num, int size, const object *op, int goodbad)
#define SCRIPT_FIX_ACTIVATOR
int write_on_item(object *pl, const char *params, object *skill)
int detect_curse_on_item(object *pl, object *tmp, object *skill)
void meditate(object *pl, object *skill)
void draw_ext_info(int flags, int pri, const object *pl, uint8_t type, uint8_t subtype, const char *message)
int book_overflow(const char *buf1, const char *buf2, size_t booksize)
archetype * get_archetype_by_type_subtype(int type, int subtype)
void object_remove(object *op)
int trap_see(object *op, object *trap)
#define OB_TYPE_MOVE_BLOCK(ob1, type)
static int write_scroll(object *pl, object *scroll, object *skill)
static int attempt_jump(object *pl, int dir, int spaces, object *skill)
static int do_skill_detect_curse(object *pl, object *skill)
static int do_skill_ident(object *pl, int obj_class, object *skill)
uint8_t no_player_stealing
#define MSG_TYPE_SKILL_SUCCESS
int stand_near_hostile(object *who)
short freearr_x[SIZEOFFREE]
#define FLAG_READY_WEAPON
#define FLAG_NO_SKILL_IDENT
int jump(object *pl, int dir, object *skill)
void pick_up(object *op, object *alt)
#define MSG_TYPE_ITEM_INFO
object * find_marked_object(object *op)
#define FOR_INV_PREPARE(op_, it_)
int remove_trap(object *op, 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)
static int attempt_hide(object *op, object *skill)
object * identify(object *op)