Jelajahi Sumber

- Cleaned up some more the regen_data structure, so that skill/sitting-skill related data is optional (since only players have it).

git-svn-id: https://svn.code.sf.net/p/rathena/svn/trunk@8410 54d463be-8e91-2dee-dedb-b68131a5f0ec
skotlex 19 tahun lalu
induk
melakukan
2fa44057cb
6 mengubah file dengan 141 tambahan dan 113 penghapusan
  1. 3 0
      Changelog-Trunk.txt
  2. 20 1
      src/map/map.h
  3. 1 50
      src/map/pc.c
  4. 0 3
      src/map/pc.h
  5. 117 53
      src/map/status.c
  6. 0 6
      src/map/unit.c

+ 3 - 0
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]

+ 20 - 1
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]

+ 1 - 50
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;
 }
 

+ 0 - 3
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);

+ 117 - 53
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
 		}
 	}

+ 0 - 6
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;