summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Changelog-Trunk.txt3
-rw-r--r--src/map/map.h21
-rw-r--r--src/map/pc.c51
-rw-r--r--src/map/pc.h3
-rw-r--r--src/map/status.c170
-rw-r--r--src/map/unit.c6
6 files changed, 141 insertions, 113 deletions
diff --git a/Changelog-Trunk.txt b/Changelog-Trunk.txt
index c3fd8ebf3..871560f86 100644
--- a/Changelog-Trunk.txt
+++ b/Changelog-Trunk.txt
@@ -4,6 +4,9 @@ AS OF SVN REV. 5091, WE ARE NOW USING TRUNK. ALL UNTESTED BUGFIXES/FEATURES GO
IF YOU HAVE A WORKING AND TESTED BUGFIX PUT IT INTO STABLE AS WELL AS TRUNK.
2006/08/21
+ * Cleaned up some more the regen_data structure, so that
+ skill/sitting-skill related data is optional (since only players have it).
+ [Skotlex]
* Fixed AM_RESURRECTION, thanks to RockmanEXE for %HP values [Toms]
* Fixed HAMI_CASTLE, HAMI_DEFENCE & HLIF_AVOID [Toms]
* Adjusted Glittering's success rate to 20+10*lv% [Skotlex]
diff --git a/src/map/map.h b/src/map/map.h
index a23133150..bd9da7080 100644
--- a/src/map/map.h
+++ b/src/map/map.h
@@ -465,6 +465,22 @@ struct view_data {
unsigned dead_sit : 2;
};
+//Additional regen data that only players have.
+struct regen_data_sub {
+ unsigned short
+ hp,sp;
+
+ //tick accumulation before healing.
+ struct {
+ unsigned int hp,sp;
+ } tick;
+
+ //Regen rates (where every 1 means +100% regen)
+ struct {
+ unsigned char hp,sp;
+ } rate;
+};
+
struct regen_data {
unsigned short flag; //Marks what stuff you may heal or not.
@@ -488,6 +504,9 @@ struct regen_data {
unsigned overweight :2; //overweight state (1: 50%, 2: 90%)
unsigned block :2; //Block regen flag (1: Hp, 2: Sp)
} state;
+
+ //skill-regen, sitting-skill-regen (since not all chars with regen need it)
+ struct regen_data_sub *sregen, *ssregen;
};
struct party_member_data {
@@ -522,6 +541,7 @@ struct map_session_data {
struct weapon_atk base_lhw, battle_lhw; //Left-hand weapon atk data.
struct status_change sc;
struct regen_data regen;
+ struct regen_data_sub sregen, ssregen;
//NOTE: When deciding to add a flag to state or special_state, take into consideration that state is preserved in
//status_calc_pc, while special_state is recalculated in each call. [Skotlex]
struct {
@@ -627,7 +647,6 @@ struct map_session_data {
unsigned int canlog_tick;
unsigned int canuseitem_tick; // [Skotlex]
unsigned int cantalk_tick;
- int inchealspirithptick,inchealspiritsptick;
short weapontype1,weapontype2;
short disguise; // [Valaris]
diff --git a/src/map/pc.c b/src/map/pc.c
index efc621333..6327719bd 100644
--- a/src/map/pc.c
+++ b/src/map/pc.c
@@ -4807,7 +4807,6 @@ int pc_dead(struct map_session_data *sd,struct block_list *src)
pc_setdead(sd);
//Reset ticks.
- sd->inchealspirithptick = sd->inchealspiritsptick =
sd->hp_loss_tick = sd->sp_loss_tick = 0;
pc_setglobalreg(sd,"PC_DIE_COUNTER",++sd->die_counter);
@@ -6753,54 +6752,6 @@ struct map_session_data *pc_get_child (struct map_session_data *sd)
return NULL;
}
-int pc_spirit_heal_hp(struct map_session_data *sd, unsigned int diff_tick)
-{
- int interval = battle_config.natural_heal_skill_interval;
-
- if(!pc_issit(sd))
- return 0;
-
- if(sd->regen.state.overweight)
- interval += interval;
-
- sd->inchealspirithptick += diff_tick;
-
- while(sd->inchealspirithptick >= interval)
- {
- sd->inchealspirithptick -= interval;
- if(status_heal(&sd->bl, sd->nsshealhp, 0, 3) < sd->nsshealhp)
- {
- sd->inchealspirithptick = 0;
- return 1;
- }
- }
- return 0;
-}
-
-int pc_spirit_heal_sp(struct map_session_data *sd, unsigned int diff_tick)
-{
- int interval = battle_config.natural_heal_skill_interval;
-
- if(!pc_issit(sd))
- return 0;
-
- if(sd->regen.state.overweight)
- interval += interval;
-
- sd->inchealspiritsptick += diff_tick;
-
- while(sd->inchealspiritsptick >= interval)
- {
- sd->inchealspiritsptick -= interval;
- if(status_heal(&sd->bl, 0, sd->nsshealsp, 3) < sd->nsshealsp)
- {
- sd->inchealspiritsptick = 0;
- return 1;
- }
- }
- return 0;
-}
-
void pc_bleeding (struct map_session_data *sd, unsigned int diff_tick)
{
int hp = 0, sp = 0;
@@ -6985,7 +6936,7 @@ void pc_setstand(struct map_session_data *sd){
status_change_end(&sd->bl,SC_TENSIONRELAX,-1);
//Reset sitting tick.
- sd->inchealspirithptick = sd->inchealspiritsptick = 0;
+ sd->ssregen.tick.hp = sd->ssregen.tick.sp = 0;
sd->state.dead_sit = sd->vd.dead_sit = 0;
}
diff --git a/src/map/pc.h b/src/map/pc.h
index f3c05b92c..d1b7ea964 100644
--- a/src/map/pc.h
+++ b/src/map/pc.h
@@ -256,11 +256,8 @@ struct map_session_data *pc_get_father(struct map_session_data *sd);
struct map_session_data *pc_get_mother(struct map_session_data *sd);
struct map_session_data *pc_get_child(struct map_session_data *sd);
-int pc_spirit_heal_hp(struct map_session_data *sd, unsigned int diff_tick);
-int pc_spirit_heal_sp(struct map_session_data *sd, unsigned int diff_tick);
void pc_bleeding (struct map_session_data *sd, unsigned int diff_tick);
-
int pc_set_gm_level(int account_id, int level);
void pc_setstand(struct map_session_data *sd);
int pc_candrop(struct map_session_data *sd,struct item *item);
diff --git a/src/map/status.c b/src/map/status.c
index 71fc5dc62..435d7ca6e 100644
--- a/src/map/status.c
+++ b/src/map/status.c
@@ -708,8 +708,13 @@ int status_damage(struct block_list *src,struct block_list *target,int hp, int s
if(target->type&BL_REGEN)
{ //Reset regen ticks.
struct regen_data *regen = status_get_regen_data(target);
- if (regen)
+ if (regen) {
memset(&regen->tick, 0, sizeof(regen->tick));
+ if (regen->sregen)
+ memset(&regen->sregen->tick, 0, sizeof(regen->sregen->tick));
+ if (regen->ssregen)
+ memset(&regen->ssregen->tick, 0, sizeof(regen->ssregen->tick));
+ }
}
if(flag&4) //Delete from memory. (also invokes map removal code)
unit_free(target,1);
@@ -1499,7 +1504,8 @@ int status_calc_pc(struct map_session_data* sd,int first)
sd->battle_status.sp = sd->status.sp;
sd->battle_status.lhw = &sd->battle_lhw;
sd->base_status.lhw = &sd->base_lhw;
-
+ sd->regen.sregen = &sd->sregen;
+ sd->regen.ssregen = &sd->ssregen;
sd->weight=0;
for(i=0;i<MAX_INVENTORY;i++){
if(sd->status.inventory[i].nameid==0 || sd->inventory_data[i] == NULL)
@@ -2327,40 +2333,48 @@ void status_calc_regen(struct block_list *bl, struct status_data *status, struct
if(sd)
{
+ struct regen_data_sub *sregen;
if((skill=pc_checkskill(sd,HP_MEDITATIO)) > 0)
{
val = regen->sp*(100+3*skill)/100;
regen->sp = cap_value(val, 1, SHRT_MAX);
}
+ //Only players have skill/sitting skill regen for now.
+ sregen = regen->sregen;
+
val = 0;
if((skill=pc_checkskill(sd,SM_RECOVERY)) > 0)
val += skill*5 + (status->max_hp*skill/500);
- regen->shp = cap_value(val, 0, SHRT_MAX);
+ sregen->hp = cap_value(val, 0, SHRT_MAX);
val = 0;
if((skill=pc_checkskill(sd,MG_SRECOVERY)) > 0)
val += skill*3 + (status->max_sp*skill/500);
if((skill=pc_checkskill(sd,NJ_NINPOU)) > 0)
val += skill*3 + (status->max_sp*skill/500);
- regen->ssp = cap_value(val, 0, SHRT_MAX);
+ sregen->sp = cap_value(val, 0, SHRT_MAX);
// Skill-related recovery (only when sit)
- sd->nsshealhp = sd->nsshealsp = 0;
+ sregen = regen->ssregen;
+
+ val = 0;
if((skill=pc_checkskill(sd,MO_SPIRITSRECOVERY)) > 0)
- {
- sd->nsshealhp+= skill*4 + (status->max_hp*skill/500);
- sd->nsshealsp+= skill*2 + (status->max_sp*skill/500);
- }
+ val += skill*4 + (status->max_hp*skill/500);
+
if((skill=pc_checkskill(sd,TK_HPTIME)) > 0 && sd->state.rest)
- sd->nsshealhp+= skill*30 + (status->max_hp*skill/500);
+ val += skill*30 + (status->max_hp*skill/500);
+ sregen->hp = cap_value(val, 0, SHRT_MAX);
+
+ val = 0;
if((skill=pc_checkskill(sd,TK_SPTIME)) > 0 && sd->state.rest)
{
- sd->nsshealsp+= skill*3 + (status->max_sp*skill/500);
+ val += skill*3 + (status->max_sp*skill/500);
if ((skill=pc_checkskill(sd,SL_KAINA)) > 0) //Power up Enjoyable Rest
- sd->nsshealsp += (30+10*skill)*sd->nsshealsp/100;
+ val += (30+10*skill)*val/100;
}
- if(sd->nsshealhp > SHRT_MAX) sd->nsshealhp = SHRT_MAX;
- if(sd->nsshealsp > SHRT_MAX) sd->nsshealsp = SHRT_MAX;
+ if((skill=pc_checkskill(sd,MO_SPIRITSRECOVERY)) > 0)
+ val += skill*2 + (status->max_sp*skill/500);
+ sregen->sp = cap_value(val, 0, SHRT_MAX);
}
if(bl->type==BL_HOM && ((TBL_HOM*)bl)->master)
@@ -2386,13 +2400,25 @@ void status_calc_regen_rate(struct block_list *bl, struct regen_data *regen, str
return;
regen->flag = RGN_HP|RGN_SP;
- if (regen->shp)
- regen->flag|=RGN_SHP;
- if (regen->ssp)
- regen->flag|=RGN_SSP;
+ if(regen->sregen)
+ {
+ if (regen->sregen->hp)
+ regen->flag|=RGN_SHP;
- regen->rate.hp = regen->rate.sp =
- regen->rate.shp = regen->rate.ssp = 1;
+ if (regen->sregen->sp)
+ regen->flag|=RGN_SSP;
+ regen->sregen->rate.hp = regen->sregen->rate.sp = 1;
+ }
+ if (regen->ssregen)
+ {
+ if (regen->ssregen->hp)
+ regen->flag|=RGN_SHP;
+
+ if (regen->ssregen->sp)
+ regen->flag|=RGN_SSP;
+ regen->ssregen->rate.hp = regen->ssregen->rate.sp = 1;
+ }
+ regen->rate.hp = regen->rate.sp = 1;
if (!sc || !sc->count)
return;
@@ -2419,7 +2445,8 @@ void status_calc_regen_rate(struct block_list *bl, struct regen_data *regen, str
sc->data[SC_TENSIONRELAX].timer!=-1
) {
regen->rate.hp += 2;
- regen->rate.shp += 3;
+ if (regen->sregen)
+ regen->sregen->rate.hp += 3;
}
if (sc->data[SC_MAGNIFICAT].timer != -1)
{
@@ -4398,7 +4425,6 @@ int status_get_sc_tick(struct block_list *bl, int type, int tick)
int status_change_start(struct block_list *bl,int type,int rate,int val1,int val2,int val3,int val4,int tick,int flag)
{
struct map_session_data *sd = NULL;
- struct homun_data *hd = NULL;
struct status_change* sc;
struct status_data *status;
struct view_data *vd;
@@ -4416,9 +4442,6 @@ int status_change_start(struct block_list *bl,int type,int rate,int val1,int val
case BL_PC:
sd=(struct map_session_data *)bl;
break;
- case BL_HOM:
- hd=(struct homun_data *)bl; //[orn]
- break;
case BL_MOB:
if (((struct mob_data*)bl)->class_ == MOBID_EMPERIUM && type != SC_SAFETYWALL)
return 0; //Emperium can't be afflicted by status changes.
@@ -6795,6 +6818,8 @@ static int status_natural_heal(DBKey key,void * data,va_list app)
struct status_data *status;
struct status_change *sc;
struct unit_data *ud;
+ struct view_data *vd = NULL;
+ struct regen_data_sub *sregen;
struct map_session_data *sd;
int val,rate,bonus = 0,flag;
@@ -6821,16 +6846,45 @@ static int status_natural_heal(DBKey key,void * data,va_list app)
))
flag=0;
- if (sd)
- {
- if (sd->hp_loss_value > 0 || sd->sp_loss_value > 0)
- pc_bleeding(sd, natural_heal_diff_tick);
- if (sd->nsshealhp && flag&RGN_HP &&
- pc_spirit_heal_hp(sd, natural_heal_diff_tick))
- flag&=~RGN_HP;
- if (sd->nsshealsp && flag&RGN_SP &&
- pc_spirit_heal_sp(sd, natural_heal_diff_tick))
- flag&=~RGN_SP;
+ if (sd && (sd->hp_loss_value > 0 || sd->sp_loss_value > 0))
+ pc_bleeding(sd, natural_heal_diff_tick);
+
+ if(flag&(RGN_SHP|RGN_SSP) && regen->ssregen &&
+ (vd = status_get_viewdata(bl)) && vd->dead_sit == 2)
+ { //Apply sitting regen bonus.
+ sregen = regen->ssregen;
+ if(flag&(RGN_SHP))
+ { //Sitting HP regen
+ val = natural_heal_diff_tick * sregen->rate.hp;
+ if (regen->state.overweight)
+ val>>=1; //Half as fast when overweight.
+ sregen->tick.hp += val;
+ while(sregen->tick.hp >= (unsigned int)battle_config.natural_heal_skill_interval)
+ {
+ sregen->tick.hp -= battle_config.natural_heal_skill_interval;
+ if(status_heal(bl, sregen->hp, 0, 3) < sregen->hp)
+ { //Full
+ flag&=~(RGN_HP|RGN_SHP);
+ break;
+ }
+ }
+ }
+ if(flag&(RGN_SSP))
+ { //Sitting SP regen
+ val = natural_heal_diff_tick * sregen->rate.sp;
+ if (regen->state.overweight)
+ val>>=1; //Half as fast when overweight.
+ sregen->tick.sp += val;
+ while(sregen->tick.sp >= (unsigned int)battle_config.natural_heal_skill_interval)
+ {
+ sregen->tick.sp -= battle_config.natural_heal_skill_interval;
+ if(status_heal(bl, 0, sregen->sp, 3) < sregen->sp)
+ { //Full
+ flag&=~(RGN_SP|RGN_SSP);
+ break;
+ }
+ }
+ }
}
if (flag && regen->state.overweight)
@@ -6850,8 +6904,8 @@ static int status_natural_heal(DBKey key,void * data,va_list app)
if (flag&(RGN_HP|RGN_SP))
{
- struct view_data *vd = status_get_viewdata(bl);
- if(vd && vd->dead_sit)
+ if(!vd) vd = status_get_viewdata(bl);
+ if(vd && vd->dead_sit == 2)
bonus++;
if(map_getcell(bl->m,bl->x,bl->y,CELL_CHKREGEN))
bonus++;
@@ -6859,6 +6913,7 @@ static int status_natural_heal(DBKey key,void * data,va_list app)
bonus++;
}
+ //Natural Hp regen
if (flag&RGN_HP)
{
rate = natural_heal_diff_tick*(regen->rate.hp+bonus);
@@ -6877,17 +6932,8 @@ static int status_natural_heal(DBKey key,void * data,va_list app)
flag&=~RGN_SHP; //full.
}
}
- if(flag&RGN_SHP)
- {
- regen->tick.shp += natural_heal_diff_tick * regen->rate.shp;
-
- while(regen->tick.shp >= (unsigned int)battle_config.natural_heal_skill_interval)
- {
- regen->tick.shp -= battle_config.natural_heal_skill_interval;
- if(status_heal(bl, regen->shp, 0, 3) < regen->shp)
- break; //Full
- }
- }
+
+ //Natural SP regen
if(flag&RGN_SP)
{
regen->tick.sp += natural_heal_diff_tick*(regen->rate.sp+bonus);
@@ -6903,13 +6949,31 @@ static int status_natural_heal(DBKey key,void * data,va_list app)
flag&=~RGN_SSP; //full.
}
}
+
+ if (!regen->sregen)
+ return flag;
+
+ //Skill regen
+ sregen = regen->sregen;
+
+ if(flag&RGN_SHP)
+ { //Skill HP regen
+ sregen->tick.hp += natural_heal_diff_tick * sregen->rate.hp;
+
+ while(sregen->tick.hp >= (unsigned int)battle_config.natural_heal_skill_interval)
+ {
+ sregen->tick.hp -= battle_config.natural_heal_skill_interval;
+ if(status_heal(bl, sregen->hp, 0, 3) < sregen->hp)
+ break; //Full
+ }
+ }
if(flag&RGN_SSP)
- {
- regen->tick.ssp += natural_heal_diff_tick * regen->rate.ssp;
- while(regen->tick.ssp >= (unsigned int)battle_config.natural_heal_skill_interval)
+ { //Skill SP regen
+ sregen->tick.sp += natural_heal_diff_tick * sregen->rate.sp;
+ while(sregen->tick.sp >= (unsigned int)battle_config.natural_heal_skill_interval)
{
- regen->tick.ssp -= battle_config.natural_heal_skill_interval;
- if(status_heal(bl, 0, regen->ssp, 3) < regen->ssp)
+ sregen->tick.sp -= battle_config.natural_heal_skill_interval;
+ if(status_heal(bl, 0, sregen->sp, 3) < sregen->sp)
break; //Full
}
}
diff --git a/src/map/unit.c b/src/map/unit.c
index 5c48cf8e4..1fa676823 100644
--- a/src/map/unit.c
+++ b/src/map/unit.c
@@ -127,12 +127,6 @@ static int unit_walktoxy_timer(int tid,unsigned int tick,int id,int data)
if(ud->walkpath.path_pos>=ud->walkpath.path_len)
return 0;
- //歩いたので息吹のタイマーを初期化
- if(sd) {
- sd->inchealspirithptick = 0;
- sd->inchealspiritsptick = 0;
- }
-
if(ud->walkpath.path[ud->walkpath.path_pos]>=8)
return 1;
x = bl->x;