46 #define ADD_EXP(exptotal, exp) {exptotal += exp; if (exptotal > MAX_EXPERIENCE) exptotal = MAX_EXPERIENCE; }
52 -6,-5,-4,-3,-2,-1,-1,0,0,0,0,1,2,3,4,5,6,7,8,9,10,12,14,16,18,20,
63 -10,-10,-9,-8,-7,-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6,7,8,9,10,12,15,20,25,
71 -10,-10,-9,-8,-7,-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6,7,8,9,10,12,15,20,25,
95 10.0, 10.0, 9.0, 8.0, 7.0, 6.0,
96 5.0, 4.5, 4.0, 3.5, 3.0,
97 2.9, 2.8, 2.7, 2.6, 2.5,
98 2.4, 2.3, 2.2, 2.1, 2.0,
99 1.95, 1.90, 1.85, 1.80, 1.75,
100 1.70, 1.65, 1.60, 1.55, 1.50
105 -4,-3,-2,-2,-1,-1,-1,0,0,0,0,0,0,0,1,1,1,2,2,2,3,3,3,4,4,4,5,5,6,6,7
110 -0.4, -0.4, -0.3, -0.3, -0.2, -0.2, -0.2, -0.1, -0.1, -0.1, -0.05, 0, 0, 0,
111 0.05, 0.1, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.8, 1.0, 1.2, 1.4,
112 1.6, 1.8, 2.0, 2.5, 3.0
120 -2,-2,-2,-1,-1,-1,0,0,0,0,0,0,1,1,1,2,2,2,3,3,3,4,4,5,5,6,6,7,8,10,15
125 -2,-2,-1,-1,0,0,0,0,0,0,0,0,0,0,1,1,1,2,2,2,3,3,3,4,4,5,5,6,7,8,10
130 2,4,7,11,16,22,29,37,46,56,67,79,92,106,121,137,154,172,191,211,232,254,277,
131 301,326,352,400,450,500,600,1000
145 250000,300000,350000,400000,500000,
146 600000,700000,800000,900000,1000000,
147 1100000,1200000,1300000,1400000,1500000,
148 1650000,1800000,1950000,2100000,2250000,
149 2400000,2550000,2700000,2850000,3000000,
150 3250000,3500000,3750000,4000000,4500000
155 0,0,0,1,2,4,8,12,16,25,36,45,55,65,70,75,80,85,90,95,100,100,100,100,100,
156 100,100,100,100,100,100
161 100,100,100,100,90,80,70,60,50,40,35,30,25,20,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0,0
166 -1,-1,-1,-1,-1,-1,-1,-1,0,0,0,1,1,1,2,2,2,3,3,3,4,4,5,5,6,7,8,9,10,12,15
171 3,3,3,3,2,2,2,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
178 #define MAX_EXPERIENCE levels[settings.max_level]
195 #define MAX_EXP_IN_OBJ levels[settings.max_level]/(MAX_EXP_CAT - 1)
199 #define MAX_SAVE_LEVEL 110
211 18,17,16,15,14,14,13,13,12,12,12,11,11,11,11,10,10,10,10, 9,
212 9, 9, 9, 9, 8, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 7, 6, 6, 6,
213 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4,
214 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2,
215 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
216 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
221 "physical",
"magical",
"fire",
"electricity",
"cold",
"confusion",
222 "acid",
"drain",
"weaponmagic",
"ghosthit",
"poison",
"slow",
223 "paralyze",
"turn undead",
"fear",
"cancellation",
"depletion",
"death",
224 "chaos",
"counterspell",
"god power",
"holy power",
"blinding",
"",
230 "Oh no! You are weakened!",
231 "You're feeling clumsy!",
232 "You feel less healthy",
233 "You suddenly begin to lose your memory!",
234 "Your face gets distorted!",
235 "Watch out, your mind is going!",
236 "Your spirit feels drained!"
241 "You feel your strength return.",
242 "You feel your agility return.",
243 "You feel your health return.",
244 "You feel your wisdom return.",
245 "You feel your charisma return.",
246 "You feel your memory return.",
247 "You feel your spirits return."
252 "You feel stronger.",
253 "You feel more agile.",
256 "You seem to look better.",
258 "You feel more potent."
265 "You feel less healthy!",
266 "You lose some of your memory!",
269 "You feel less potent!"
274 "strength",
"dexterity",
"constitution",
"wisdom",
"charisma",
"intelligence",
"power"
279 "Str",
"Dex",
"Con",
"Wis",
"Cha",
"Int",
"Pow"
337 if (value==0)
return;
361 LOG(
llevError,
"Invalid attribute in change_attr_value: %d\n", attr);
418 #define DIFF_MSG(flag, subtype1, subtype2, msg1, msg2) \
419 draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_ATTRIBUTE, (flag>0)?subtype1:subtype2, (flag>0)?msg1:msg2, NULL);
452 memcpy(&refop, op,
sizeof(
object));
464 nstat = flag*i + ostat;
471 if (nstat < 1 && i*flag < 0) nstat = 1;
475 if (nstat != ostat) {
519 "Your hands begin to glow red.",
520 "Your hands stop glowing red.");
525 "You feel very protected.",
526 "You don't feel protected anymore.");
531 "A magic force shimmers around you.",
532 "The magic force fades away.");
537 "You feel more safe now, somehow.",
538 "Suddenly you feel less safe, somehow.");
554 "You start to float in the air!.",
555 "You float down to the ground.");
563 "You soar into the air air!.",
565 "You float down to the ground."));
569 "You feel ready for a swim",
570 "You no longer feel like swimming");
586 "Your lifeforce drains away!", NULL);
594 "Your lifeforce returns!", NULL);
601 "You walk more quietly.",
602 "You walk more noisily.");
607 "You become transparent.",
608 "You can see yourself.");
618 "Your mortal self is blinded.", NULL);
621 "You are blinded.", NULL);
629 "Your mortal self can now see again.", NULL);
632 "Your vision returns.", NULL);
645 "Your vision is better in the dark.",
646 "You see less well in the dark.");
654 "Your vision becomes a little clearer.", NULL);
657 "Everything becomes transparent.", NULL);
664 "Your vision becomes a bit out of focus.", NULL);
667 "Everything suddenly looks very solid.", NULL);
677 "You feel more lucky.",
678 "You feel less lucky.");
684 "You feel much more healthy!",
685 "You feel much less healthy!");
691 "You feel one with the powers of magic!",
692 "You suddenly feel very mundane.");
699 "You feel closer to your god!",
700 "You suddenly feel less holy.");
706 "You feel your digestion slowing down.",
707 "You feel your digestion speeding up.");
718 "Your resistance to %s rises to %d%%.",
719 "Your resistance to %s rises to %d%%.",
723 "Your resistance to %s drops to %d%%.",
724 "Your resistance to %s drops to %d%%.",
814 if (new_luck >= -100 && new_luck <= 100) {
902 float f,max=9,added_speed=0,bonus_speed=0, sp_tmp,speed_reduce_from_disease=1;
903 int weapon_weight=0,weapon_speed=0;
904 int best_wc=0, best_ac=0, wc=0, ac=0;
906 object *grace_obj=NULL,*mana_obj=NULL,*wc_obj=NULL,*tmp;
970 prot[i]= op->
resist[i], vuln[i]=0;
972 vuln[i]= -(op->
resist[i]), prot[i]=0;
999 for (tmp=op->
inv;tmp!=NULL;tmp=tmp->
below) {
1014 if (tmp->type ==
SKILL) {
1019 else if (tmp->level > mana_obj->level)
1025 else if (tmp->level > grace_obj->
level)
1042 if (tmp->type ==
BOW)
1045 if (tmp->type ==
WAND || tmp->type ==
ROD || tmp->type==
HORN)
1057 (tmp->type ==
SHIELD) || (tmp->type ==
RING) ||
1062 (tmp->type ==
SKILL)) {
1079 speed_reduce_from_disease = tmp->last_sp / 100.0;
1080 if(speed_reduce_from_disease ==0)
1081 speed_reduce_from_disease = 1;
1089 if (tmp->type !=
POTION) {
1095 if (potion_resist[i])
1096 potion_resist[i] =
MAX(potion_resist[i], tmp->resist[i]);
1098 potion_resist[i] = tmp->resist[i];
1099 }
else if (tmp->resist[i] > 0)
1100 prot[i] += ((100-prot[i])*tmp->resist[i])/100;
1101 else if (tmp->resist[i] < 0)
1102 vuln[i] += ((100-vuln[i])*(-tmp->resist[i]))/100;
1139 if (tmp->stats.exp && tmp->type!=
SKILL) {
1140 if(tmp->stats.exp > 0) {
1141 added_speed+=(float)tmp->stats.exp/3.0;
1142 bonus_speed+=1.0+(
float)tmp->stats.exp/3.0;
1144 added_speed+=(float)tmp->stats.exp;
1147 switch (tmp->type) {
1158 LOG(
llevDebug,
"fix_object, op %s has multiple skills applied\n", op->
name);
1161 if (tmp->stats.dam>0) {
1166 weapon_weight=tmp->weight;
1172 wc-=(tmp->stats.wc+tmp->magic);
1174 if (tmp->slaying!=NULL) {
1181 ac-=(tmp->stats.ac+tmp->magic);
1190 LOG(
llevDebug,
"fix_object, op %s has multiple skills applied\n", op->
name);
1208 wc-=(tmp->stats.wc+tmp->magic);
1210 op->
stats.
dam+=(tmp->stats.dam+tmp->magic);
1212 ac-=(tmp->stats.ac+tmp->magic);
1216 wc-=(tmp->stats.wc+tmp->magic);
1217 if (tmp->stats.ac&&tmp->stats.ac+tmp->magic>0)
1218 ac-=tmp->stats.ac+tmp->magic;
1219 op->
stats.
dam+=(tmp->stats.dam+tmp->magic);
1220 weapon_weight=tmp->weight;
1224 if (tmp->slaying!=NULL) {
1244 if (tmp->stats.wc) {
1245 if (best_wc<tmp->stats.wc+tmp->magic) {
1247 best_wc=tmp->stats.wc+tmp->magic;
1249 wc+=tmp->stats.wc+tmp->magic;
1251 if (tmp->stats.ac) {
1252 if (best_ac<tmp->stats.ac+tmp->magic) {
1254 best_ac=tmp->stats.ac+tmp->magic;
1256 ac+=tmp->stats.ac+tmp->magic;
1258 if (tmp->stats.dam && tmp->type ==
BRACERS)
1259 op->
stats.
dam+=(tmp->stats.dam+tmp->magic);
1261 wc-=(tmp->stats.wc+tmp->magic);
1263 ac-=(tmp->stats.ac+tmp->magic);
1282 op->
resist[i] = prot[i] - vuln[i];
1283 if (potion_resist[i] && ((potion_resist[i] > op->
resist[i]) ||
1284 (potion_resist[i] < 0)))
1285 op->
resist[i] = potion_resist[i];
1301 for (i=1,op->
stats.
maxhp=0;i<=pl_level&&i<=10;i++) {
1312 for (i=11;i<=op->
level;i++)
1328 if (!mana_obj || !mana_obj->level || op->
type!=
PLAYER)
1335 for (i=1;i<=mana_obj->level&&i<=10;i++) {
1353 for (i=11;i<=mana_obj->level;i++)
1374 for (i=1,op->
stats.
maxgrace=0;i<=grace_obj->level&&i<=10;i++) {
1375 float grace_tmp=0.0;
1393 for (i=11;i<=grace_obj->
level;i++)
1416 if (op->
type==
PLAYER && wc_obj && wc_obj->level>1) {
1418 for(i=1;i<wc_obj->level;i++) {
1446 op->
speed+=added_speed/10.0;
1448 op->
speed /= (float)(1.0-added_speed);
1450 op->
speed+=bonus_speed/10.0;
1466 op->
speed = op->
speed * speed_reduce_from_disease;
1472 float M,W,s,D,K,S,M2;
1481 W=weapon_weight/20000.0;
1482 s=2-weapon_speed/10.0;
1484 K=1 + M/3.0 - W/(3*M2) + op->
speed/5.0 + D/2.0;
1572 if (!abil || !skin)
return;
1589 level = (int)(level/5.);
1592 if (pl->
contr != NULL) {
1595 else if (level == 1)
1597 else if (level == 2)
1599 else if (level == 3)
1603 if (skin->
resist[atnr] > 80)
1605 else if (skin->
resist[atnr] > 50)
1624 object *abil = NULL;
1625 object *skin = NULL;
1629 for (tmp=who->
inv; tmp!=NULL; tmp=tmp->
below) {
1631 if (strcmp(tmp->
arch->
name,
"dragon_ability_force")==0)
1633 if (strcmp(tmp->
arch->
name,
"dragon_skin_force")==0)
1638 if (abil == NULL)
return;
1656 "Your metabolism now focuses on %s!",
1657 "Your metabolism now focuses on %s!",
1695 LOG(
llevError,
"add_player_exp: couldn't find skill %s\n", skill_name);
1705 skill_obj->
level = 1;
1754 snprintf(buf,
sizeof(buf),
"You are now level %d in the %s skill.",op->
level,op->
name);
1756 snprintf(buf,
sizeof(buf),
"You are now level %d.",op->
level);
1769 "You are now level %d in the %s skill.",
1770 "You are now level %d in the %s skill.",
1791 return expmul * levels[level];
1837 static void add_player_exp(
object *op, sint64 exp,
const char *skill_name,
int flag) {
1838 object *skill_obj=NULL;
1839 sint64 limit, exp_to_add;
1878 if (exp_to_add > limit) exp_to_add=limit;
1890 if (exp_to_add > limit) exp_to_add=limit;
1921 if (del_exp < 0) del_exp = 0;
1922 if (exp > del_exp) exp=del_exp;
1966 float fraction = (float) exp/(
float) op->
stats.
exp;
1970 for (tmp=op->
inv;tmp;tmp=tmp->
below)
2015 void change_exp(
object *op, sint64 exp,
const char *skill_name,
int flag) {
2021 LOG(
llevDebug,
"change_exp() called for %s, exp = %lld\n",name,exp);
2023 LOG(
llevDebug,
"change_exp() called for %s, exp = %I64d\n",name,exp);
2029 LOG(
llevError,
"change_exp() called for null object!\n");
2036 if (exp == 0)
return;
2053 if (exp < 0)
return;
2076 sint64 percentage_loss;
2079 for (tmp=op->
inv;tmp;tmp=tmp->
below)
2090 if (level_loss < 0) level_loss = 0;
2100 if (level_loss < 0) level_loss = 0;
2150 void share_exp(
object *op, sint64 exp,
const char *skill,
int flag) {
2151 int shares=0,count=0;
2168 if (count==1 || shares>exp)
2171 sint64 share=exp/shares,given=0,nexp;
const int fear_bonus[MAX_STAT+1]
#define NUM_BODY_LOCATIONS
archetype * find_archetype(const char *name)
#define WEAPON_SPEED(xyz)
void share_exp(object *op, sint64 exp, const char *skill, int flag)
void drain_stat(object *op)
void change_exp(object *op, sint64 exp, const char *skill_name, int flag)
#define MSG_TYPE_ATTRIBUTE_PROTECTION_GAIN
const char *const restore_msg[NUM_STATS]
const int dam_bonus[MAX_STAT+1]
#define MSG_TYPE_ATTRIBUTE_BAD_EFFECT_START
sstring add_refcount(sstring str)
uint8 death_penalty_ratio
#define ADD_EXP(exptotal, exp)
#define PERM_EXP_MAX_LOSS_RATIO
const int dex_bonus[MAX_STAT+1]
sint8 get_attr_value(const living *stats, int attr)
void free_string(sstring str)
void draw_ext_info(int flags, int pri, const object *pl, uint8 type, uint8 subtype, const char *message, const char *oldmessage)
sint64 level_exp(int level, double expmul)
static const int sp_bonus[MAX_STAT+1]
object * ranges[range_size]
void change_luck(object *op, int value)
void change_attr_value(living *stats, int attr, sint8 value)
void draw_ext_info_format(int flags, int pri, const object *pl, uint8 type, uint8 subtype, const char *new_format, const char *old_format,...)
sint64 last_skill_exp[NUM_SKILLS]
#define MSG_TYPE_ATTRIBUTE_GOOD_EFFECT_START
static const char *const drain_msg[NUM_STATS]
static const int con_bonus[MAX_STAT+1]
#define MSG_TYPE_ATTRIBUTE_BAD_EFFECT_END
#define MSG_TYPE_ATTRIBUTE_PROTECTION_LOSS
#define MSG_TYPE_ATTRIBUTE_ATTACKTYPE_LOSS
#define IS_MANA_SKILL(num)
object * give_skill_by_name(object *op, const char *skill_name)
#define MSG_TYPE_ATTRIBUTE_LEVEL_LOSS
static void subtract_player_exp(object *op, sint64 exp, const char *skill, int flag)
struct obj * chosen_skill
int change_abil(object *op, object *tmp)
sint64 check_exp_loss(const object *op, sint64 exp)
void player_lvl_adj(object *who, object *op)
static void add_player_exp(object *op, sint64 exp, const char *skill_name, int flag)
const char *const gain_msg[NUM_STATS]
static const int savethrow[MAX_SAVE_LEVEL+1]
const int thaco_bonus[MAX_STAT+1]
#define FLAG_CAN_USE_SKILL
#define MSG_TYPE_ATTRIBUTE_ATTACKTYPE_GAIN
const char *const statname[NUM_STATS]
#define MSG_TYPE_ATTRIBUTE_LEVEL_GAIN
int is_dragon_pl(const object *op)
void set_attr_value(living *stats, int attr, sint8 value)
void drain_specific_stat(object *op, int deplete_stats)
const float speed_bonus[MAX_STAT+1]
int die_roll(int num, int size, const object *op, int goodbad)
archetype * get_archetype_by_skill_name(const char *skill, int type)
#define MSG_TYPE_ATTRIBUTE
#define ARMOUR_SPEED(xyz)
int allowed_class(const object *op)
struct obj * current_weapon
#define PERM_EXP_GAIN_RATIO
EXTERN const char *const change_resist_msg[NROFATTACKS]
const int cleric_chance[MAX_STAT+1]
const float cha_bonus[MAX_STAT+1]
void dragon_level_gain(object *who)
void add_statbonus(object *op)
int on_same_map(const object *op1, const object *op2)
#define QUERY_FLAG(xyz, p)
#define CLEAR_FLAG(xyz, p)
object * insert_ob_in_ob(object *op, object *where)
#define FLAG_READY_WEAPON
#define DIFF_MSG(flag, subtype1, subtype2, msg1, msg2)
void calc_perm_exp(object *op)
const int turn_bonus[MAX_STAT+1]
sint16 resist[NROFATTACKS]
#define MSG_TYPE_ATTRIBUTE_STAT_LOSS
const char *const lose_msg[NUM_STATS]
sint8 body_info[NUM_BODY_LOCATIONS]
#define MSG_TYPE_ATTRIBUTE_RACE
int snprintf(char *dest, int max, const char *format,...)
sint8 body_used[NUM_BODY_LOCATIONS]
uint8 death_penalty_level
object * present_arch_in_ob(const archetype *at, const object *op)
sint64 check_exp_adjust(const object *op, sint64 exp)
const uint32 weight_limit[MAX_STAT+1]
void check_stat_bounds(living *stats)
void apply_death_exp_penalty(object *op)
#define MSG_TYPE_ATTRIBUTE_GOOD_EFFECT_END
void update_ob_speed(object *op)
sstring add_string(const char *str)
EXTERN player * first_player
uint8 permanent_exp_ratio
void dragon_ability_gain(object *who, int atnr, int level)
void LOG(LogLevel logLevel, const char *format,...)
const int learn_spell[MAX_STAT+1]
int did_make_save(const object *op, int level, int bonus)
object * last_skill_ob[NUM_SKILLS]
void set_dragon_name(object *pl, const object *abil, const object *skin)
static const int grace_bonus[MAX_STAT+1]
int check_move_on(object *op, object *originator)
void query_name(const object *op, char *buf, size_t size)
#define SK_SUBTRACT_SKILL_EXP
void remove_statbonus(object *op)
void esrv_update_spells(player *pl)
#define IS_COMBAT_SKILL(num)
int random_roll(int min, int max, const object *op, int goodbad)
const char *const short_stat_name[NUM_STATS]
#define FLAG_REFL_MISSILE
void fix_object(object *op)
#define IS_GRACE_SKILL(num)
object * arch_to_object(archetype *at)
const int max_carry[MAX_STAT+1]
#define MSG_TYPE_ATTRIBUTE_STAT_GAIN
#define MSG_TYPE_ATTRIBUTE_MOVE
const char *const attacks[NROFATTACKS]
int atnr_is_dragon_enabled(int attacknr)