diff options
-rw-r--r-- | Changelog-Trunk.txt | 3 | ||||
-rw-r--r-- | src/map/map.h | 21 | ||||
-rw-r--r-- | src/map/pc.c | 51 | ||||
-rw-r--r-- | src/map/pc.h | 3 | ||||
-rw-r--r-- | src/map/status.c | 170 | ||||
-rw-r--r-- | src/map/unit.c | 6 |
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(®en->tick, 0, sizeof(regen->tick)); + if (regen->sregen) + memset(®en->sregen->tick, 0, sizeof(regen->sregen->tick)); + if (regen->ssregen) + memset(®en->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; |