Index: common/init.c
===================================================================
RCS file: /cvsroot/crossfire/crossfire/common/init.c,v
retrieving revision 1.47
diff -C5 -r1.47 init.c
*** common/init.c 11 Feb 2006 14:05:32 -0000 1.47
--- common/init.c 6 Mar 2006 18:48:17 -0000
***************
*** 54,64 ****
PLAYERDIR, MAPDIR, ARCHETYPES,REGIONS,TREASURES,
UNIQUE_DIR, TEMPLATE_DIR,
TMPDIR,
STAT_LOSS_ON_DEATH,
PK_LUCK_PENALTY,
! USE_PERMANENT_EXPERIENCE,
BALANCED_STAT_LOSS,
NOT_PERMADETH,
SIMPLE_EXP,
RESET_LOCATION_TIME,
SET_TITLE,
--- 54,66 ----
PLAYERDIR, MAPDIR, ARCHETYPES,REGIONS,TREASURES,
UNIQUE_DIR, TEMPLATE_DIR,
TMPDIR,
STAT_LOSS_ON_DEATH,
PK_LUCK_PENALTY,
! PERMANENT_EXPERIENCE_RATIO,
! DEATH_PENALTY_RATIO,
! DEATH_PENALTY_LEVEL,
BALANCED_STAT_LOSS,
NOT_PERMADETH,
SIMPLE_EXP,
RESET_LOCATION_TIME,
SET_TITLE,
Index: common/living.c
===================================================================
RCS file: /cvsroot/crossfire/crossfire/common/living.c,v
retrieving revision 1.76
diff -C5 -r1.76 living.c
*** common/living.c 9 Feb 2006 00:48:36 -0000 1.76
--- common/living.c 6 Mar 2006 18:48:24 -0000
***************
*** 1591,1602 ****
*/
void calc_perm_exp(object *op)
{
int p_exp_min;
! /* Ensure that our permanent experience minimum is met. */
! p_exp_min = (int)(PERM_EXP_MINIMUM_RATIO * (float)(op->stats.exp));
if (op->perm_exp < p_exp_min)
op->perm_exp = p_exp_min;
/* Cap permanent experience. */
--- 1591,1604 ----
*/
void calc_perm_exp(object *op)
{
int p_exp_min;
! /* Ensure that our permanent experience minimum is met.
! * permenent_exp_ratio is an integer percentage, we divide by 100
! * to get the fraction */
! p_exp_min = (int)(settings.permanent_exp_ratio * (float)(op->stats.exp)/100);
if (op->perm_exp < p_exp_min)
op->perm_exp = p_exp_min;
/* Cap permanent experience. */
***************
*** 1658,1679 ****
exp_to_add = exp;
limit=(levels[op->level+1]-levels[op->level])/2;
if (exp_to_add > limit) exp_to_add=limit;
ADD_EXP(op->stats.exp, (float) exp_to_add * (skill_obj? skill_obj->expmul:1));
! if (settings.use_permanent_experience) {
ADD_EXP(op->perm_exp, (float) exp_to_add * PERM_EXP_GAIN_RATIO * (skill_obj? skill_obj->expmul:1));
calc_perm_exp(op);
}
player_lvl_adj(op,NULL);
if (skill_obj) {
exp_to_add = exp;
limit=(levels[skill_obj->level+1]-levels[skill_obj->level])/2;
if (exp_to_add > limit) exp_to_add=limit;
ADD_EXP(skill_obj->stats.exp, exp_to_add);
! if (settings.use_permanent_experience) {
skill_obj->perm_exp += exp_to_add * PERM_EXP_GAIN_RATIO;
calc_perm_exp(skill_obj);
}
player_lvl_adj(op,skill_obj);
}
--- 1660,1681 ----
exp_to_add = exp;
limit=(levels[op->level+1]-levels[op->level])/2;
if (exp_to_add > limit) exp_to_add=limit;
ADD_EXP(op->stats.exp, (float) exp_to_add * (skill_obj? skill_obj->expmul:1));
! if (settings.permanent_exp_ratio) {
ADD_EXP(op->perm_exp, (float) exp_to_add * PERM_EXP_GAIN_RATIO * (skill_obj? skill_obj->expmul:1));
calc_perm_exp(op);
}
player_lvl_adj(op,NULL);
if (skill_obj) {
exp_to_add = exp;
limit=(levels[skill_obj->level+1]-levels[skill_obj->level])/2;
if (exp_to_add > limit) exp_to_add=limit;
ADD_EXP(skill_obj->stats.exp, exp_to_add);
! if (settings.permanent_exp_ratio) {
skill_obj->perm_exp += exp_to_add * PERM_EXP_GAIN_RATIO;
calc_perm_exp(skill_obj);
}
player_lvl_adj(op,skill_obj);
}
***************
*** 1690,1700 ****
sint64 check_exp_loss(const object *op, sint64 exp)
{
sint64 del_exp;
if (exp > op->stats.exp) exp = op->stats.exp;
! if (settings.use_permanent_experience) {
del_exp = (op->stats.exp - op->perm_exp) * PERM_EXP_MAX_LOSS_RATIO;
if (del_exp < 0) del_exp = 0;
if (exp > del_exp) exp=del_exp;
}
return exp;
--- 1692,1702 ----
sint64 check_exp_loss(const object *op, sint64 exp)
{
sint64 del_exp;
if (exp > op->stats.exp) exp = op->stats.exp;
! if (settings.permanent_exp_ratio) {
del_exp = (op->stats.exp - op->perm_exp) * PERM_EXP_MAX_LOSS_RATIO;
if (del_exp < 0) del_exp = 0;
if (exp > del_exp) exp=del_exp;
}
return exp;
***************
*** 1811,1853 ****
subtract_player_exp(op, FABS(exp), skill_name, flag);
}
}
! /* Applies a death penalty experience. 20% or 3 levels, whichever is
! * less experience lost.
*/
void apply_death_exp_penalty(object *op) {
object *tmp;
sint64 loss;
! sint64 loss_20p; /* 20 percent experience loss */
! sint64 loss_3l; /* 3 level experience loss */
for(tmp=op->inv;tmp;tmp=tmp->below)
if(tmp->type==SKILL && tmp->stats.exp) {
! loss_20p = tmp->stats.exp * 0.20;
! loss_3l = tmp->stats.exp - levels[MAX(0,tmp->level -3)];
/* With the revised exp system, you can get cases where
! * losing 3 levels would still require that you have more
! * exp than you current have - this is true if the levels
* tables is a lot harder.
*/
! if (loss_3l < 0) loss_3l = 0;
! loss = check_exp_loss(tmp, MIN(loss_3l, loss_20p));
tmp->stats.exp -= loss;
player_lvl_adj(op,tmp);
}
! loss_20p = op->stats.exp * 0.20;
! loss_3l = op->stats.exp - levels[MAX(0,op->level -3)];
! if (loss_3l < 0) loss_3l = 0;
! loss = check_exp_loss(op, MIN(loss_3l, loss_20p));
op->stats.exp -= loss;
player_lvl_adj(op,NULL);
}
--- 1813,1856 ----
subtract_player_exp(op, FABS(exp), skill_name, flag);
}
}
! /* Applies a death penalty experience, the size of this is defined by the
! * settings death_penalty_percentage and death_penalty_levels, and by the
! * amount of permenent experience, whichever gives the lowest loss.
*/
void apply_death_exp_penalty(object *op) {
object *tmp;
sint64 loss;
! sint64 percentage_loss; /* defined by the setting 'death_penalty_percent' */
! sint64 level_loss; /* defined by the setting 'death_penalty_levels */
for(tmp=op->inv;tmp;tmp=tmp->below)
if(tmp->type==SKILL && tmp->stats.exp) {
! percentage_loss = tmp->stats.exp * settings.death_penalty_ratio/100;
! level_loss = tmp->stats.exp - levels[MAX(0,tmp->level - settings.death_penalty_level)];
/* With the revised exp system, you can get cases where
! * losing several levels would still require that you have more
! * exp than you currently have - this is true if the levels
* tables is a lot harder.
*/
! if (level_loss < 0) level_loss = 0;
! loss = check_exp_loss(tmp, MIN(level_loss, percentage_loss));
tmp->stats.exp -= loss;
player_lvl_adj(op,tmp);
}
! percentage_loss = op->stats.exp * settings.death_penalty_ratio/100;
! level_loss = op->stats.exp - levels[MAX(0,op->level - settings.death_penalty_level)];
! if (level_loss < 0) level_loss = 0;
! loss = check_exp_loss(op, MIN(level_loss, percentage_loss));
op->stats.exp -= loss;
player_lvl_adj(op,NULL);
}
Index: include/config.h
===================================================================
RCS file: /cvsroot/crossfire/crossfire/include/config.h,v
retrieving revision 1.69
diff -C5 -r1.69 config.h
*** include/config.h 29 Oct 2005 09:34:02 -0000 1.69
--- include/config.h 6 Mar 2006 18:48:27 -0000
***************
*** 116,126 ****
/* Don't edit these values. They are configured in lib/settings. These are
Simply the defaults. */
#define BALANCED_STAT_LOSS FALSE
! #define USE_PERMANENT_EXPERIENCE FALSE
#define SET_TITLE TRUE
#define SIMPLE_EXP TRUE
#define SPELLPOINT_LEVEL_DEPEND TRUE
#define SPELL_ENCUMBRANCE TRUE
#define SPELL_FAILURE_EFFECTS FALSE
--- 116,128 ----
/* Don't edit these values. They are configured in lib/settings. These are
Simply the defaults. */
#define BALANCED_STAT_LOSS FALSE
! #define PERMANENT_EXPERIENCE_RATIO 25
! #define DEATH_PENALTY_RATIO 20
! #define DEATH_PENALTY_LEVEL 3
#define SET_TITLE TRUE
#define SIMPLE_EXP TRUE
#define SPELLPOINT_LEVEL_DEPEND TRUE
#define SPELL_ENCUMBRANCE TRUE
#define SPELL_FAILURE_EFFECTS FALSE
***************
*** 225,266 ****
*/
/*
#define PARTY_KILL_LOG 20
*/
! /* Use permanent experience code?
! * This code allows players to build up a small amount of 'permanent
! * experience' which reduces the effect of large experience drains, such as
! * death. This makes multiple frequent deaths less devastating, and also
! * ensures that any character will make some gradual progress even if they
! * die all of the time.
! * A nice option if your keep dying due to massive client/server lags despite
! * playing well... or you like to swim well outside of your depth. :)
! *
! * The PERM_EXP values adjust the behaviour of this option - if
! * USE_PERMAMENT_EXPERIENCE if off, these values have no meaning. If it
! * is on, the minimum ratio is the minimum amount of permanent exp relative
! * to the total exp in the skill (ie, at a default of .25, if you had 100
! * experience, at least 25 of it would be permanent). The gain ratio
! * is how much of experienced experience goes to the permanent value.
! * This does not detract from total exp gain (ie, if you gained 100 exp,
! * 100 would go to the skill total and 10 to the permanent value).
! * the loss ratio is the maximum amount of experience that can be lost
! * in any one hit - this is calculated as total exp - perm exp * loss ratio.
*
* A few thoughts on these default value (by MSW)
* gain ratio is pretty much meaningless until exp has been lost, as until
! * that poin, the minimum ratio will be used.
* It is also impossible for the exp to actually be reduced to the permanent
* exp ratio - since the loss ratio is .5, it will just get closer and
* closer. However, after about half a dozen hits, pretty much all the
* exp that can be lost has been lost, and after that, only minor loss
* will occur.
*/
/* GD */
- #define PERM_EXP_MINIMUM_RATIO 0.25f
#define PERM_EXP_GAIN_RATIO 0.10f
#define PERM_EXP_MAX_LOSS_RATIO 0.50f
/*
* WATCHDOG lets sends datagrams to port 13325 on localhost
--- 227,259 ----
*/
/*
#define PARTY_KILL_LOG 20
*/
! /*
! * The PERM_EXP values adjust the behaviour of permenent experience. - if
! * the setting permanent_experience_percentage is zero, these values have
! * no meaning. The value in the settings file is the percentage of the
! * experience that is permenent, the rest could be lost on death. When dying,
! * the greatest amount of non-permenent exp it is possible to lose at one time
! * is PERM_EXP_MAX_LOSS_RATIO - this is calculated as
! * total exp - perm exp * loss ratio. The gain ratio is how much of experienced
! * experience goes to the permanent value. This does not detract from total
! * exp gain (ie, if you gained 100 exp, 100 would go to the skill total and
! * 10 to the permanent value).
*
* A few thoughts on these default value (by MSW)
* gain ratio is pretty much meaningless until exp has been lost, as until
! * that poin, the value in the settings file will be used.
* It is also impossible for the exp to actually be reduced to the permanent
* exp ratio - since the loss ratio is .5, it will just get closer and
* closer. However, after about half a dozen hits, pretty much all the
* exp that can be lost has been lost, and after that, only minor loss
* will occur.
*/
/* GD */
#define PERM_EXP_GAIN_RATIO 0.10f
#define PERM_EXP_MAX_LOSS_RATIO 0.50f
/*
* WATCHDOG lets sends datagrams to port 13325 on localhost
Index: include/global.h
===================================================================
RCS file: /cvsroot/crossfire/crossfire/include/global.h,v
retrieving revision 1.62
diff -C5 -r1.62 global.h
*** include/global.h 8 Jan 2006 16:31:17 -0000 1.62
--- include/global.h 6 Mar 2006 18:48:29 -0000
***************
*** 326,346 ****
char *uniquedir; /* directory for the unique items */
char *templatedir; /* directory for the template map */
char *tmpdir; /* Directory to use for temporary files */
uint8 stat_loss_on_death; /* If true, chars lose a random stat when they die */
sint16 pk_luck_penalty; /* Amount by which player luck is reduced if they PK */
! uint8 use_permanent_experience; /* If true, players can gain perm exp */
uint8 balanced_stat_loss; /* If true, Death stat depletion based on level etc */
uint8 not_permadeth; /* if true, death is non-permament */
uint8 simple_exp; /* If true, use the simple experience system */
int reset_loc_time; /* Number of seconds to put player back at home */
uint8 set_title; /* players can set thier title */
uint8 resurrection; /* ressurection possible w/ permadeth on */
uint8 search_items; /* search_items command */
uint8 spell_encumbrance; /* encumbrance effects spells */
uint8 spell_failure_effects; /* nasty backlash to spell failures */
! uint16 set_friendly_fire; /* Percent of damage done by peaceful player vs player damage */
uint8 casting_time; /* it takes awhile to cast a spell */
uint8 real_wiz; /* use mud-like wizards */
uint8 recycle_tmp_maps; /* re-use tmp maps. */
uint8 explore_mode; /* explore mode allowed? */
uint8 spellpoint_level_depend; /* spell costs go up with level */
--- 326,348 ----
char *uniquedir; /* directory for the unique items */
char *templatedir; /* directory for the template map */
char *tmpdir; /* Directory to use for temporary files */
uint8 stat_loss_on_death; /* If true, chars lose a random stat when they die */
sint16 pk_luck_penalty; /* Amount by which player luck is reduced if they PK */
! uint8 permanent_exp_ratio; /* how much exp should be 'permenant' and unable to be lost*/
! uint8 death_penalty_ratio; /* how much exp should be lost at death */
! uint8 death_penalty_level; /* how many levels worth of exp may be lost on one death */
uint8 balanced_stat_loss; /* If true, Death stat depletion based on level etc */
uint8 not_permadeth; /* if true, death is non-permament */
uint8 simple_exp; /* If true, use the simple experience system */
int reset_loc_time; /* Number of seconds to put player back at home */
uint8 set_title; /* players can set thier title */
uint8 resurrection; /* ressurection possible w/ permadeth on */
uint8 search_items; /* search_items command */
uint8 spell_encumbrance; /* encumbrance effects spells */
uint8 spell_failure_effects; /* nasty backlash to spell failures */
! uint16 set_friendly_fire; /* Percent of damage done by peaceful player vs player damage */
uint8 casting_time; /* it takes awhile to cast a spell */
uint8 real_wiz; /* use mud-like wizards */
uint8 recycle_tmp_maps; /* re-use tmp maps. */
uint8 explore_mode; /* explore mode allowed? */
uint8 spellpoint_level_depend; /* spell costs go up with level */
Index: lib/settings
===================================================================
RCS file: /cvsroot/crossfire/crossfire/lib/settings,v
retrieving revision 1.22
diff -C5 -r1.22 settings
*** lib/settings 22 Jan 2006 02:32:46 -0000 1.22
--- lib/settings 6 Mar 2006 18:48:31 -0000
***************
*** 198,230 ****
# Setting it to true keeps the old behaviour. This can be
# changed at run time via -stat_loss_on_death or +stat_loss_on_death.
stat_loss_on_death false
! # This makes repeated stat loss at lower levels more mercifull. Basically,
# the more stats you have lost, the less likely that
# you will lose more. Additionally, lower level characters are shown
# a lot more mercy (there are caps on how much of a stat you can lose too).
! # On the nasty side, if you are higher level, you can lose mutiple stats
# _at_once_ and are shown less mercy when you die. But when you're higher
# level, it is much easier to buy back your stats with potions.
# Turn this on if you want death-based stat loss to be more merciful
# at low levels and more cruel at high levels.
# Only works when stats are depleted rather than lost. This option has
# no effect if you are using genuine stat loss.
balanced_stat_loss false
! # This allows players to build up a small amount of 'permanent
! # experience' which reduces the effect of large experience drains, such as
! # death. This makes multiple frequent deaths less devastating, and also
! # ensures that any character will make some gradual progress even if they
! # die all of the time.
! # A nice option if your keep dying due to massive client/server lags despite
! # playing well... or you like to swim well outside of your depth. :)
! use_permanent_experience false
# This is the penalty to luck that is given to a player who kills another
# player (PK's). The value here is deducted from their luck value, so set this
# high to discourage PK-ing and zero (or negative) to encourage it.
# Range is limited to -100 to 100, since this is the value range that the luck
--- 198,241 ----
# Setting it to true keeps the old behaviour. This can be
# changed at run time via -stat_loss_on_death or +stat_loss_on_death.
stat_loss_on_death false
! # This makes repeated stat loss at lower levels more merciful. Basically,
# the more stats you have lost, the less likely that
# you will lose more. Additionally, lower level characters are shown
# a lot more mercy (there are caps on how much of a stat you can lose too).
! # On the nasty side, if you are higher level, you can lose multiple stats
# _at_once_ and are shown less mercy when you die. But when you're higher
# level, it is much easier to buy back your stats with potions.
# Turn this on if you want death-based stat loss to be more merciful
# at low levels and more cruel at high levels.
# Only works when stats are depleted rather than lost. This option has
# no effect if you are using genuine stat loss.
balanced_stat_loss false
! # This defines how much of a player's experience should be 'permanent' and
! # not able to be lost on death. A high value makes multiple frequent deaths
! # less devastating, and also ensures that any character will make some
! # gradual progress even if they die all of the time. This value is the minimum
! # amount of a player's exp that can ever be 'permanent' so setting this to 0
! # would allow all exp to be lost, and setting it to 100 would stop exp loss
! # entirely (the same effect would be achieved by setting the two
! # death_penalty settings below to 0).
!
! permanent_experience_percentage 25
!
! # When a player dies, they lose a proportion of their experience, which is
! # defined by the following two values. They will lose either
! # death_penalty_percentage% of their experience, or no more than
! # death_penalty_levels levels, or half of their non-permenent experience,
! # whichever is the least of these. Note that this is calculated per-skill,
! # so which method is used could vary for different skills.
! death_penalty_percentage 20
! death_penalty_levels 3
# This is the penalty to luck that is given to a player who kills another
# player (PK's). The value here is deducted from their luck value, so set this
# high to discourage PK-ing and zero (or negative) to encourage it.
# Range is limited to -100 to 100, since this is the value range that the luck
Index: server/init.c
===================================================================
RCS file: /cvsroot/crossfire/crossfire/server/init.c,v
retrieving revision 1.73
diff -C5 -r1.73 init.c
*** server/init.c 10 Feb 2006 23:59:27 -0000 1.73
--- server/init.c 6 Mar 2006 18:48:36 -0000
***************
*** 574,592 ****
} else {
LOG(llevError, "load_settings: Unknown value for "
"stat_loss_on_death: %s\n", cp);
}
} else if (!strcasecmp(buf, "use_permanent_experience")) {
! if (!strcasecmp(cp, "on") || !strcasecmp(cp, "true")) {
! settings.use_permanent_experience=TRUE;
! } else if (!strcasecmp(cp, "off") || !strcasecmp(cp, "false")) {
! settings.use_permanent_experience=FALSE;
! } else {
! LOG(llevError, "load_settings: Unknown value for "
! "use_permanent_experience: %s\n", cp);
! }
! } else if (!strcasecmp(buf, "balanced_stat_loss")) {
if (!strcasecmp(cp, "on") || !strcasecmp(cp, "true")) {
settings.balanced_stat_loss=TRUE;
} else if (!strcasecmp(cp, "off") || !strcasecmp(cp, "false")) {
settings.balanced_stat_loss=FALSE;
} else {
--- 574,607 ----
} else {
LOG(llevError, "load_settings: Unknown value for "
"stat_loss_on_death: %s\n", cp);
}
} else if (!strcasecmp(buf, "use_permanent_experience")) {
! LOG(llevError, "use_permanent_experience is deprecated, use"
! "permenent_experience_percentage instead\n");
! } else if (!strcasecmp(buf, "permanent_experience_percentage")) {
! int val = atoi(cp);
! if (val < 0 || val >100)
! LOG(llevError, "load_settings: permenent_experience_percentage"
! "must be between 0 and 100, %d is invalid\n", val);
! else
! settings.permanent_exp_ratio = val;
! } else if (!strcasecmp(buf, "death_penalty_percentage")) {
! int val = atoi(cp);
! if (val < 0 || val >100)
! LOG(llevError, "load_settings: death_penalty_percentage"
! "must be between 0 and 100, %d is invalid\n", val);
! else
! settings.death_penalty_ratio = val;
! } else if (!strcasecmp(buf, "death_penalty_levels")) {
! int val = atoi(cp);
! if (val < 0 || val > 255)
! LOG(llevError, "load_settings: death_penalty_levels"
! "can not be negative, %d is invalid\n", val);
! else
! settings.death_penalty_level = val;
! }else if (!strcasecmp(buf, "balanced_stat_loss")) {
if (!strcasecmp(cp, "on") || !strcasecmp(cp, "true")) {
settings.balanced_stat_loss=TRUE;
} else if (!strcasecmp(cp, "off") || !strcasecmp(cp, "false")) {
settings.balanced_stat_loss=FALSE;
} else {
Index: server/skill_util.c
===================================================================
RCS file: /cvsroot/crossfire/crossfire/server/skill_util.c,v
retrieving revision 1.63
diff -C5 -r1.63 skill_util.c
*** server/skill_util.c 17 Feb 2006 21:29:48 -0000 1.63
--- server/skill_util.c 6 Mar 2006 18:48:37 -0000
***************
*** 655,671 ****
/* Need to have a pointer and use strdup for qsort to work properly */
char skills[NUM_SKILLS][MAX_BUF];
for (tmp=op->inv; tmp!=NULL; tmp=tmp->below) {
! if (tmp->type == SKILL) {
if ( search && strstr(tmp->name,search)==NULL ) continue;
/* Basically want to fill this out to 40 spaces with periods */
sprintf(buf,"%s%s", tmp->name, periods);
buf[40] = 0;
! if (settings.use_permanent_experience) {
#ifdef WIN32
sprintf(skills[num_skills_found++],"%slvl:%3d (xp:%I64d/%I64d/%d%%)",
buf,tmp->level,
tmp->stats.exp,
level_exp(tmp->level+1, op->expmul),
--- 655,671 ----
/* Need to have a pointer and use strdup for qsort to work properly */
char skills[NUM_SKILLS][MAX_BUF];
for (tmp=op->inv; tmp!=NULL; tmp=tmp->below) {
! if (tmp->type == SKILL) {
if ( search && strstr(tmp->name,search)==NULL ) continue;
/* Basically want to fill this out to 40 spaces with periods */
sprintf(buf,"%s%s", tmp->name, periods);
buf[40] = 0;
! if (settings.permanent_exp_ratio) {
#ifdef WIN32
sprintf(skills[num_skills_found++],"%slvl:%3d (xp:%I64d/%I64d/%d%%)",
buf,tmp->level,
tmp->stats.exp,
level_exp(tmp->level+1, op->expmul),