Browse Source

- Implementing a correct update of mercenary status window on status change updates.
- Fixed Mercenary Heal is reduced 50%.

git-svn-id: https://svn.code.sf.net/p/rathena/svn/trunk@13185 54d463be-8e91-2dee-dedb-b68131a5f0ec

zephyrus 16 năm trước cách đây
mục cha
commit
ef61b07219
4 tập tin đã thay đổi với 94 bổ sung51 xóa
  1. 37 15
      src/map/clif.c
  2. 4 3
      src/map/mercenary.c
  3. 2 2
      src/map/skill.c
  4. 51 31
      src/map/status.c

+ 37 - 15
src/map/clif.c

@@ -12376,36 +12376,56 @@ void clif_send_quest_status(struct map_session_data * sd, int quest_id, bool act
 void clif_mercenary_updatestatus(struct map_session_data *sd, int type)
 {
 	struct mercenary_data *md;
+	struct status_data *status;
 	int fd;
 	if( sd == NULL || (md = sd->md) == NULL )
 		return;
 
 	fd = sd->fd;
+	status = &md->battle_status;
 	WFIFOHEAD(fd,8);
 	WFIFOW(fd,0) = 0x02a2;
 	WFIFOW(fd,2) = type;
 	switch( type )
 	{
-		case SP_HP:
-			WFIFOL(fd,4) = md->battle_status.hp;
+		case SP_ATK1:
+			{
+				int atk = rand()%(status->rhw.atk2 - status->rhw.atk + 1) + status->rhw.atk;
+				WFIFOL(fd,4) = cap_value(atk, 0, SHRT_MAX);
+			}
 			break;
-		case SP_MAXHP:
-			WFIFOL(fd,4) = md->battle_status.max_hp;
+		case SP_MATK1:
+			WFIFOL(fd,4) = cap_value(status->matk_max, 0, SHRT_MAX);
 			break;
-		case SP_SP:
-			WFIFOL(fd,4) = md->battle_status.sp;
+		case SP_HIT:
+			WFIFOL(fd,4) = status->hit;
 			break;
-		case SP_MAXSP:
-			WFIFOL(fd,4) = md->battle_status.max_sp;
+		case SP_CRITICAL:
+			WFIFOL(fd,4) = status->cri/10;
+			break;
+		case SP_DEF1:
+			WFIFOL(fd,4) = status->def;
+			break;
+		case SP_MDEF1:
+			WFIFOL(fd,4) = status->mdef;
 			break;
 		case SP_MERCFLEE:
-			WFIFOL(fd,4) = md->battle_status.flee;
+			WFIFOL(fd,4) = status->flee;
 			break;
-		case SP_ATK1:
-			WFIFOL(fd,4) = md->battle_status.rhw.atk + md->battle_status.rhw.atk2;
+		case SP_ASPD:
+			WFIFOL(fd,4) = status->amotion;
 			break;
-		case SP_HIT:
-			WFIFOL(fd,4) = md->battle_status.hit;
+		case SP_HP:
+			WFIFOL(fd,4) = status->hp;
+			break;
+		case SP_MAXHP:
+			WFIFOL(fd,4) = status->max_hp;
+			break;
+		case SP_SP:
+			WFIFOL(fd,4) = status->sp;
+			break;
+		case SP_MAXSP:
+			WFIFOL(fd,4) = status->max_sp;
 			break;
 		case SP_MERCKILLS:
 			WFIFOL(fd,4) = md->mercenary.kill_count;
@@ -12433,13 +12453,15 @@ void clif_mercenary_info(struct map_session_data *sd)
 	WFIFOHEAD(fd,80);
 	WFIFOW(fd,0) = 0x029b;
 	WFIFOL(fd,2) = md->bl.id;
+
 	// Mercenary shows ATK as a random value between ATK ~ ATK2
-	atk = rand()%(status->rhw.atk - status->rhw.atk2 + 1) + status->rhw.atk;
+	atk = rand()%(status->rhw.atk2 - status->rhw.atk + 1) + status->rhw.atk;
 	WFIFOW(fd,6) = cap_value(atk, 0, SHRT_MAX);
+
 	WFIFOW(fd,8) = cap_value(status->matk_max, 0, SHRT_MAX);
 	WFIFOW(fd,10) = status->hit;
 	WFIFOW(fd,12) = status->cri/10;
-	WFIFOW(fd,14) = status->def + (status->vit/2);
+	WFIFOW(fd,14) = status->def;
 	WFIFOW(fd,16) = status->mdef;
 	WFIFOW(fd,18) = status->flee;
 	WFIFOW(fd,20) = status->amotion;

+ 4 - 3
src/map/mercenary.c

@@ -346,13 +346,14 @@ int mercenary_kills(struct mercenary_data *md)
 	md->mercenary.kill_count = cap_value(md->mercenary.kill_count, 0, INT_MAX);
 
 	if( (md->mercenary.kill_count % 50) == 0 )
+	{
 		mercenary_set_faith(md, 1);
+		mercenary_killbonus(md);
+	}
 
 	if( md->master )
 		clif_mercenary_updatestatus(md->master, SP_MERCKILLS);
 
-	mercenary_killbonus(md);
-
 	return 0;
 }
 
@@ -407,7 +408,7 @@ int read_mercenarydb(void)
 		status->max_sp = atoi(str[5]);
 		status->rhw.range = atoi(str[6]);
 		status->rhw.atk = atoi(str[7]);
-		status->rhw.atk2 = atoi(str[8]);
+		status->rhw.atk2 = status->rhw.atk + atoi(str[8]);
 		status->def = atoi(str[9]);
 		status->mdef = atoi(str[10]);
 		status->str = atoi(str[11]);

+ 2 - 2
src/map/skill.c

@@ -275,8 +275,8 @@ int skill_calc_heal (struct block_list *src, struct block_list *target, int skil
 	if(src->type == BL_HOM && (skill = merc_hom_checkskill(((TBL_HOM*)src), HLIF_BRAIN)) > 0)
 		heal += heal * skill * 2 / 100;
 
-	if(src->type == BL_MER)
-		heal /= 2;
+	if(target && target->type == BL_MER)
+		heal >>= 1;
 
 	sc = status_get_sc(target);
 	if( sc && sc->count )

+ 51 - 31
src/map/status.c

@@ -2945,6 +2945,54 @@ void status_calc_bl_sub_hom(struct homun_data *hd, unsigned long flag)	//[orn]
 		clif_hominfo(hd->master,hd,0);
 }
 
+void status_calc_bl_sub_mer(struct mercenary_data *md, unsigned long flag)
+{
+	struct status_data
+		*status = &md->battle_status,
+		*b_status = &md->base_status;
+
+	if( flag&(SCB_MAXHP|SCB_VIT) )
+	{
+		flag |= SCB_MAXHP;
+		status->max_hp = cap_value(status->max_hp, 1, battle_config.max_hp);
+		status->hp = cap_value(status->hp, 0, status->max_hp);
+	}
+	if( flag&(SCB_MAXSP|SCB_INT) )
+	{
+		flag |= SCB_MAXSP;
+		status->max_sp = cap_value(status->max_sp, 1, battle_config.max_sp);
+		status->sp = cap_value(status->sp, 0, status->max_sp);
+	}
+	if( flag&SCB_VIT )
+	{
+		flag |= SCB_DEF;
+		status->def += status->vit; // Doddler says Merc DEF = DEF + VIT
+	}
+	if( flag == SCB_ALL )
+		return; // Client Refresh invoked by status_calc_mercenary
+
+	if( flag&SCB_WATK )	clif_mercenary_updatestatus(md->master, SP_ATK1);
+	if( flag&SCB_MATK )	clif_mercenary_updatestatus(md->master, SP_MATK1);
+	if( flag&SCB_HIT )	clif_mercenary_updatestatus(md->master, SP_HIT);
+	if( flag&SCB_CRI )	clif_mercenary_updatestatus(md->master, SP_CRITICAL);
+	if( flag&SCB_DEF )	clif_mercenary_updatestatus(md->master, SP_DEF1);
+	if( flag&SCB_MDEF )	clif_mercenary_updatestatus(md->master, SP_MDEF1);
+	if( flag&SCB_FLEE )	clif_mercenary_updatestatus(md->master, SP_MERCFLEE);
+	if( flag&SCB_ASPD )	clif_mercenary_updatestatus(md->master, SP_ASPD);
+
+	if( flag&SCB_MAXHP )
+	{
+		clif_mercenary_updatestatus(md->master, SP_MAXHP);
+		clif_mercenary_updatestatus(md->master, SP_HP);
+	}
+
+	if( flag&SCB_MAXSP )
+	{
+		clif_mercenary_updatestatus(md->master, SP_MAXSP);
+		clif_mercenary_updatestatus(md->master, SP_SP);
+	}
+}
+
 void status_calc_bl(struct block_list *bl, unsigned long flag)
 {
 	struct status_data *b_status, *status;
@@ -3166,6 +3214,9 @@ void status_calc_bl(struct block_list *bl, unsigned long flag)
 		if(flag&SCB_REGEN)
 			status_calc_regen_rate(bl, status_get_regen_data(bl), sc);
 	}
+
+	if(bl->type == BL_MER)
+		status_calc_bl_sub_mer((TBL_MER*)bl, flag);
 }
 /*==========================================
  * Apply shared stat mods from status changes [DracoRPG]
@@ -6241,22 +6292,11 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
 				clif_bossmapinfo(sd->fd, boss_md, 0); // First Message
 			break;
 		case SC_MERC_HPUP:
-			clif_mercenary_updatestatus(((TBL_MER*)bl)->master, SP_MAXHP);
 			status_percent_heal(bl, 100, 0); // Recover Full HP
 			break;
 		case SC_MERC_SPUP:
-			clif_mercenary_updatestatus(((TBL_MER*)bl)->master, SP_MAXSP);
 			status_percent_heal(bl, 0, 100); // Recover Full SP
 			break;
-		case SC_MERC_FLEEUP:
-			clif_mercenary_updatestatus(((TBL_MER*)bl)->master, SP_MERCFLEE);
-			break;
-		case SC_MERC_ATKUP:
-			clif_mercenary_updatestatus(((TBL_MER*)bl)->master, SP_ATK1);
-			break;
-		case SC_MERC_HITUP:
-			clif_mercenary_updatestatus(((TBL_MER*)bl)->master, SP_HIT);
-			break;
 	}
 
 	return 1;
@@ -6784,26 +6824,6 @@ int status_change_end(struct block_list* bl, enum sc_type type, int tid)
 	if (calc_flag)
 		status_calc_bl(bl,calc_flag);
 
-	if( bl->type == BL_MER )
-		switch( type )
-		{ // Update Status Window
-			case SC_MERC_HPUP:
-				clif_mercenary_updatestatus(((TBL_MER*)bl)->master, SP_MAXHP);
-				break;
-			case SC_MERC_SPUP:
-				clif_mercenary_updatestatus(((TBL_MER*)bl)->master, SP_MAXSP);
-				break;
-			case SC_MERC_FLEEUP:
-				clif_mercenary_updatestatus(((TBL_MER*)bl)->master, SP_MERCFLEE);
-				break;
-			case SC_MERC_ATKUP:
-				clif_mercenary_updatestatus(((TBL_MER*)bl)->master, SP_ATK1);
-				break;
-			case SC_MERC_HITUP:
-				clif_mercenary_updatestatus(((TBL_MER*)bl)->master, SP_HIT);
-				break;
-		}
-	
 	if(opt_flag&4) //Out of hiding, invoke on place.
 		skill_unit_move(bl,gettick(),1);