485 lines
17 KiB
C#
485 lines
17 KiB
C#
using BrewMonster.Network;
|
|
using BrewMonster.Scripts;
|
|
using BrewMonster.Scripts.Pet;
|
|
using CSNetwork.GPDataType;
|
|
using ModelRenderer.Scripts.GameData;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using TMPro;
|
|
using UnityEngine;
|
|
using UnityEngine.UI;
|
|
|
|
namespace BrewMonster.UI
|
|
{
|
|
public class DlgPetDetail : AUIDialog
|
|
{
|
|
[SerializeField] private Image m_iconPet;
|
|
[SerializeField] private TMP_Text m_textPetName;
|
|
[SerializeField] private TMP_Text m_textLevel;
|
|
[SerializeField] private TMP_Text m_textExp;
|
|
[SerializeField] private TMP_Text m_descPet;
|
|
[SerializeField] private Sprite m_spriteDefault_Icon;
|
|
|
|
private int m_nSlot;
|
|
|
|
public void UpdatePet(int nSlot)
|
|
{
|
|
if (nSlot != -1)
|
|
{
|
|
m_nSlot = nSlot;
|
|
Show(true);
|
|
UpdatePetInternal();
|
|
}
|
|
else
|
|
{
|
|
ClearPetDetail();
|
|
}
|
|
}
|
|
|
|
private void UpdatePetInternal()
|
|
{
|
|
var pDB = ElementDataManProvider.GetElementDataMan();
|
|
if(pDB == null)
|
|
{
|
|
ClearPetDetail();
|
|
return;
|
|
}
|
|
|
|
var host = CECGameRun.Instance?.GetHostPlayer();
|
|
if (host == null)
|
|
{
|
|
ClearPetDetail();
|
|
return;
|
|
}
|
|
|
|
var pPetCorral = host.GetPetCorral();
|
|
if (pPetCorral == null)
|
|
{
|
|
ClearPetDetail();
|
|
return;
|
|
}
|
|
|
|
var pPet = pPetCorral.GetPetData(m_nSlot);
|
|
if (pPet == null)
|
|
{
|
|
ClearPetDetail();
|
|
return;
|
|
}
|
|
|
|
int nLevel = pPet.GetLevel();
|
|
m_textPetName.text = pPet.GetName();
|
|
m_textLevel.text = "Cấp " + nLevel.ToString();
|
|
m_textExp.text = "EXP " + $"{pPet.GetExp()} / {pPet.GetMaxExp()}";
|
|
|
|
DATA_TYPE dataType = DATA_TYPE.DT_INVALID;
|
|
var petEssenceData = pDB.get_data_ptr((uint)pPet.GetTemplateID(), ID_SPACE.ID_SPACE_ESSENCE, ref dataType);
|
|
|
|
if (petEssenceData != null && dataType == DATA_TYPE.DT_PET_ESSENCE)
|
|
{
|
|
var pPetEssence = (PET_ESSENCE)petEssenceData;
|
|
|
|
UpdatePetIcon(pPetEssence);
|
|
|
|
if (pPet.GetClass() == (int)GP_PET_TYPE.GP_PET_CLASS_MOUNT)
|
|
{
|
|
string description = BuildMountPetDescription(pPet, pPetEssence, nLevel);
|
|
m_descPet.text = description;
|
|
}
|
|
else if (pPet.GetClass() == (int)GP_PET_TYPE.GP_PET_CLASS_COMBAT ||
|
|
pPet.GetClass() == (int)GP_PET_TYPE.GP_PET_CLASS_EVOLUTION)
|
|
{
|
|
string description = BuildCombatPetDescription(pPet, pPetEssence, nLevel);
|
|
m_descPet.text = description;
|
|
}
|
|
else if (pPet.GetClass() == (int)GP_PET_TYPE.GP_PET_CLASS_FOLLOW)
|
|
{
|
|
string description = BuildFollowPetDescription(pPet, pPetEssence, nLevel);
|
|
m_descPet.text = description;
|
|
}
|
|
else if (pPet.GetClass() == (int)GP_PET_TYPE.GP_PET_CLASS_SUMMON)
|
|
{
|
|
string description = BuildSummonPetDescription(pPet, pPetEssence, nLevel);
|
|
m_descPet.text = description;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if(m_spriteDefault_Icon != null)
|
|
m_iconPet.sprite = m_spriteDefault_Icon;
|
|
}
|
|
}
|
|
|
|
private void UpdatePetIcon(PET_ESSENCE pPetEssence)
|
|
{
|
|
if (m_iconPet == null)
|
|
return;
|
|
|
|
try
|
|
{
|
|
string strFile = Path.GetFileNameWithoutExtension(pPetEssence.FileIcon).ToLower();
|
|
var sprite = EC_Game.GetGameRun().GetUIManager().GetSpriteInListIvtr(strFile);
|
|
|
|
if (sprite != null)
|
|
{
|
|
m_iconPet.sprite = sprite;
|
|
m_iconPet.enabled = true;
|
|
m_iconPet.color = Color.white;
|
|
}
|
|
else
|
|
{
|
|
m_iconPet.sprite = m_spriteDefault_Icon;
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Debug.LogError($"[DlgPetDetail] Error loading pet icon: {ex.Message}");
|
|
m_iconPet.sprite = m_spriteDefault_Icon;
|
|
}
|
|
}
|
|
|
|
private string BuildMountPetDescription(CECPetData pPet, PET_ESSENCE pEssence, int nLevel)
|
|
{
|
|
string desc = "";
|
|
|
|
//Loyalty
|
|
int intimacy = pPet.GetIntimacy();
|
|
int nLoyalty = CalculateLoyalty(intimacy);
|
|
string loyaltyDesc = GetStringFromTable(3601 + nLoyalty);
|
|
desc += $"Độ thân thiện: {loyaltyDesc} ({intimacy})\n";
|
|
|
|
//Hunger
|
|
int hunger = pPet.GetHunger();
|
|
string hungerLevel = GetHungerLevel(hunger);
|
|
desc += $"Đói: {hungerLevel}\n";
|
|
|
|
// Speed
|
|
float speed = pEssence.speed_a + pEssence.speed_b * (nLevel - 1);
|
|
string speedUnit = GetStringFromTable(280);
|
|
desc += $"Tốc độ: {speed:F1} {speedUnit}\n";
|
|
|
|
// Required Level
|
|
desc += $"Cấp độ yêu cầu: {pEssence.level_require}\n";
|
|
|
|
//Food types
|
|
string foodTypes = GetFoodTypes(pEssence.food_mask);
|
|
if(!string.IsNullOrEmpty(foodTypes))
|
|
{
|
|
desc += $"Ăn: {foodTypes}\n";
|
|
}
|
|
|
|
//Bind status
|
|
if (pPet.IsBind())
|
|
{
|
|
string bindText = GetStringFromTable(pPet.CanWebTrade() ? 895 : 894);
|
|
desc += $"{bindText}\n";
|
|
}
|
|
|
|
// Color
|
|
if(pEssence.require_dye_count > 0)
|
|
desc += $"Màu: {pEssence.require_dye_count}\n";
|
|
|
|
return desc;
|
|
}
|
|
|
|
private string BuildCombatPetDescription(CECPetData pPet, PET_ESSENCE pEssence, int nLevel)
|
|
{
|
|
string desc = "";
|
|
var pPetCorral = CECGameRun.Instance?.GetHostPlayer()?.GetPetCorral();
|
|
bool bEvolutionActive = (pPet.GetClass() == (int)GP_PET_TYPE.GP_PET_CLASS_EVOLUTION &&
|
|
pPetCorral?.GetActivePetIndex() == m_nSlot);
|
|
|
|
int intimacy = pPet.GetIntimacy();
|
|
int nLoyalty = CalculateLoyalty(intimacy);
|
|
int[] hintAttack = { 100, 90, 80, 70 };
|
|
|
|
//Loyalty
|
|
string loyaltyLevel = GetStringFromTable(3601 + nLoyalty);
|
|
desc += $"Độ thân thiện: {loyaltyLevel} ({intimacy})\n";
|
|
|
|
//Hunger
|
|
int hunger = pPet.GetHunger();
|
|
string hungerLevel = GetHungerLevel(hunger);
|
|
desc += $"Đói: {hungerLevel}\n";
|
|
|
|
if (bEvolutionActive)
|
|
{
|
|
var petProp = pPet.GetExtendProps();
|
|
|
|
//HP
|
|
desc += $"HP: {pPet.GetHP()} / {petProp.bs.max_hp}\n";
|
|
|
|
//Attack
|
|
int avgDamge = (petProp.ak.damage_high - petProp.ak.damage_low) / 2 + petProp.ak.damage_low;
|
|
desc += $"Sát thương: {avgDamge}\n";
|
|
|
|
//Hit rate
|
|
desc += $"Chính xác: {petProp.ak.attack}\n";
|
|
|
|
//Evade
|
|
desc += $"Né tránh: {petProp.df.armor}\n";
|
|
|
|
//Physical defense
|
|
desc += $"Phòng thủ vật lý: {petProp.df.defense}\n";
|
|
|
|
int magDef = 0;
|
|
for (int i = 0; i < 5; i++)
|
|
{
|
|
magDef += petProp.df.resistance[i];
|
|
}
|
|
magDef /= 5;
|
|
desc += $"Phòng thủ phép: {magDef}\n";
|
|
|
|
// Attack speed
|
|
float attackSpeed = petProp.ak.attack_speed > 0 ? 1.0f / (petProp.ak.attack_speed * 0.05f) : 0.0f;
|
|
string speedUnit = GetStringFromTable(279);
|
|
desc += $"Tốc độ đánh: {attackSpeed:F2} {speedUnit}\n";
|
|
}
|
|
else
|
|
{
|
|
//HP
|
|
int nMaxHP = (int)(pEssence.hp_a * (nLevel - pEssence.hp_b * pEssence.level_require + pEssence.hp_c));
|
|
int nCurHP = (int)(nMaxHP * pPet.GetHPFactor());
|
|
desc += $"HP: {nCurHP} / {nMaxHP}\n";
|
|
|
|
//Attack
|
|
int attack = (int)((pEssence.damage_a * (pEssence.damage_b * nLevel * nLevel +
|
|
pEssence.damage_c * nLevel + pEssence.damage_d))) * hintAttack[nLoyalty] / 100;
|
|
desc += $"Sát thương: {attack}\n";
|
|
|
|
//Hit rate
|
|
int definition = (int)(pEssence.attack_a * (nLevel * pEssence.attack_b * pEssence.level_require
|
|
+ pEssence.attack_c));
|
|
desc += $"Chính xác: {definition}\n";
|
|
|
|
//Evade
|
|
int evade = (int)(pEssence.armor_a * (nLevel - pEssence.armor_b * pEssence.level_require + pEssence.armor_c));
|
|
desc += $"Né tránh: {evade}\n";
|
|
|
|
//Physical defense
|
|
int phyDef = (int)(pEssence.physic_defence_a * (pEssence.physic_defence_b * (nLevel - pEssence.physic_defence_c * pEssence.level_require) + pEssence.physic_defence_d));
|
|
desc += $"Phòng thủ vật lý: {phyDef}\n";
|
|
|
|
//Magic defense
|
|
int magDef = (int)(pEssence.magic_defence_a * (pEssence.magic_defence_b * (nLevel - pEssence.magic_defence_c * pEssence.level_require) + pEssence.magic_defence_d));
|
|
desc += $"Phòng thủ phép: {magDef}\n";
|
|
|
|
// Attack speed
|
|
float atkSpeed = 1.0f / pEssence.attack_speed;
|
|
string speedUnit = GetStringFromTable(279);
|
|
desc += $"Tốc độ đánh: {atkSpeed:F2} {speedUnit}\n";
|
|
}
|
|
|
|
// Speed
|
|
float speed = pEssence.speed_a + pEssence.speed_b * (nLevel - 1);
|
|
string moveSpeedUnit = GetStringFromTable(280);
|
|
desc += $"Tốc độ di chuyển: {speed:F1} {moveSpeedUnit}\n";
|
|
|
|
//Type
|
|
string petType = GetStringFromTable(1401 + (int)pEssence.inhabit_type);
|
|
desc += $"Loại: {petType}\n";
|
|
|
|
// Required Level
|
|
desc += $"Cấp độ yêu cầu: {pEssence.level_require}\n";
|
|
|
|
//Food types
|
|
string foodTypes = GetFoodTypes(pEssence.food_mask);
|
|
if(!string.IsNullOrEmpty(foodTypes))
|
|
{
|
|
desc += $"Ăn: {foodTypes}\n";
|
|
}
|
|
|
|
//Bind status
|
|
if (pPet.IsBind())
|
|
{
|
|
string bindText = GetStringFromTable(pPet.CanWebTrade() ? 895 : 894);
|
|
desc += $"{bindText}\n";
|
|
}
|
|
return desc;
|
|
}
|
|
|
|
private string BuildFollowPetDescription(CECPetData pPet, PET_ESSENCE pEssence, int nLevel)
|
|
{
|
|
string desc = "";
|
|
|
|
// HP
|
|
int nMaxHP = (int)(pEssence.hp_a * (nLevel - pEssence.hp_b * pEssence.level_require + pEssence.hp_c));
|
|
int nCurHP = (int)(nMaxHP * pPet.GetHPFactor());
|
|
desc += $"HP: {nCurHP} / {nMaxHP}\n";
|
|
|
|
// Speed
|
|
float speed = pEssence.speed_a + pEssence.speed_b * (nLevel - 1);
|
|
string speedUnit = GetStringFromTable(280);
|
|
desc += $"Tốc độ di chuyển: {speed:F1} {speedUnit}\n";
|
|
|
|
// Required Level
|
|
desc += $"Cấp độ yêu cầu: {pEssence.level_require}\n";
|
|
|
|
//Bind data
|
|
if(pPet.IsBind())
|
|
{
|
|
string bindText = GetStringFromTable(pPet.CanWebTrade() ? 895 : 894);
|
|
desc += $"{bindText}\n";
|
|
}
|
|
|
|
// Food types
|
|
string foodTypes = GetFoodTypes(pEssence.food_mask);
|
|
if (!string.IsNullOrEmpty(foodTypes))
|
|
{
|
|
desc += $"Ăn: {foodTypes}\n";
|
|
}
|
|
return desc;
|
|
}
|
|
|
|
private string BuildSummonPetDescription(CECPetData pPet, PET_ESSENCE pEssence, int nLevel)
|
|
{
|
|
string desc = "";
|
|
var petProp = pPet.GetExtendProps();
|
|
|
|
//HP
|
|
desc += $"HP: {pPet.GetHP()} / {petProp.bs.max_hp}\n";
|
|
|
|
//MP
|
|
desc += $"MP: {pPet.GetMP()} / {petProp.bs.max_mp}\n";
|
|
|
|
//Physical attack
|
|
int avgDamage = (petProp.ak.damage_high - petProp.ak.damage_low) / 2 + petProp.ak.damage_low;
|
|
desc += $"Sát thương vật lý: {avgDamage}\n";
|
|
|
|
//Magic attack
|
|
int avgMagicDamage = (petProp.ak.damage_magic_high - petProp.ak.damage_magic_low) / 2 + petProp.ak.damage_magic_low;
|
|
desc += $"Sát thương phép: {avgMagicDamage}\n";
|
|
|
|
//Physical defense
|
|
desc += $"Phòng thủ vật lý: {petProp.df.defense}\n";
|
|
|
|
//Elemental resistance
|
|
desc += $"Kháng Kim: {petProp.df.resistance[0]}\n";
|
|
desc += $"Kháng Mộc: {petProp.df.resistance[1]}\n";
|
|
desc += $"Kháng Thủy: {petProp.df.resistance[2]}\n";
|
|
desc += $"Kháng Hỏa: {petProp.df.resistance[3]}\n";
|
|
desc += $"Kháng Thổ: {petProp.df.resistance[4]}\n";
|
|
|
|
// Hit rate
|
|
desc += $"Chính xác: {petProp.ak.attack}\n";
|
|
|
|
//Attack speed
|
|
float atkSpeed = petProp.ak.attack_speed > 0 ? 1.0f / (petProp.ak.attack_speed * 0.05f) : 0.0f;
|
|
string speedUnit = GetStringFromTable(279);
|
|
desc += $"Tốc độ đánh: {atkSpeed:F2} {speedUnit}\n";
|
|
|
|
//Evade
|
|
desc += $"Né tránh: {petProp.df.armor}\n";
|
|
|
|
//Move speed
|
|
string moveSpeedUnit = GetStringFromTable(280);
|
|
desc += $"Tốc độ di chuyển: {petProp.mv.run_speed:F1} {moveSpeedUnit}\n";
|
|
|
|
desc += $"Cấp độ yêu cầu: {pEssence.level_require}\n";
|
|
|
|
// Food types
|
|
string foodTypes = GetFoodTypes(pEssence.food_mask);
|
|
if (!string.IsNullOrEmpty(foodTypes))
|
|
{
|
|
desc += $"Ăn: {foodTypes}\n";
|
|
}
|
|
|
|
return desc;
|
|
}
|
|
|
|
private string GetFoodTypes(uint food_mask)
|
|
{
|
|
string foodTypes = "";
|
|
|
|
CECStringTab pDescTab = EC_Game.GetItemDesc();
|
|
if(pDescTab == null)
|
|
return foodTypes;
|
|
for (int i = 0; i < (int)PetFoodType.MAX_PET_FOOD; i++)
|
|
{
|
|
if ((food_mask & (1 << i)) != 0)
|
|
{
|
|
if(!string.IsNullOrEmpty(foodTypes))
|
|
{
|
|
foodTypes += ", ";
|
|
}
|
|
|
|
int stringId = (int)DescriptipionMsg.ITEMDESC_FOOD_GRASS + i;
|
|
string foodName = pDescTab.GetWideString(stringId);
|
|
|
|
if(!string.IsNullOrEmpty(foodName))
|
|
{
|
|
foodTypes += foodName;
|
|
}
|
|
}
|
|
}
|
|
return foodTypes;
|
|
}
|
|
|
|
private int CalculateLoyalty(int intimacy)
|
|
{
|
|
if(intimacy <= 50)
|
|
return 0;
|
|
if(intimacy <= 150)
|
|
return 1;
|
|
if(intimacy <= 500)
|
|
return 2;
|
|
else
|
|
return 3;
|
|
}
|
|
|
|
private string GetHungerLevel(int hunger)
|
|
{
|
|
int nHunger;
|
|
if(hunger == (int)CECPetData.ePetData_HUNGER_LEVEL.HUNGER_LEVEL_0)
|
|
{
|
|
nHunger = 0;
|
|
}
|
|
else if(hunger == (int)CECPetData.ePetData_HUNGER_LEVEL.HUNGER_LEVEL_1)
|
|
{
|
|
nHunger = 1;
|
|
}
|
|
else if (hunger == (int)CECPetData.ePetData_HUNGER_LEVEL.HUNGER_LEVEL_2)
|
|
{
|
|
nHunger = 2;
|
|
}
|
|
else if (hunger == (int)CECPetData.ePetData_HUNGER_LEVEL.HUNGER_LEVEL_4)
|
|
{
|
|
nHunger = 3;
|
|
}
|
|
else if (hunger == (int)CECPetData.ePetData_HUNGER_LEVEL.HUNGER_LEVEL_7)
|
|
{
|
|
nHunger = 4;
|
|
}
|
|
else
|
|
{
|
|
nHunger = 5;
|
|
}
|
|
return GetStringFromTable(3611 + nHunger);
|
|
}
|
|
|
|
public void ClearPetDetail()
|
|
{
|
|
if(m_textPetName != null)
|
|
{
|
|
m_textPetName.text = "";
|
|
}
|
|
if(m_textLevel != null)
|
|
{
|
|
m_textLevel.text = "";
|
|
}
|
|
if(m_textExp != null)
|
|
{
|
|
m_textExp.text = "";
|
|
}
|
|
if (m_iconPet != null && m_spriteDefault_Icon != null)
|
|
{
|
|
m_iconPet.sprite = m_spriteDefault_Icon;
|
|
}
|
|
if(m_descPet != null)
|
|
{
|
|
m_descPet.text = "";
|
|
}
|
|
}
|
|
}
|
|
}
|