442 lines
18 KiB
C#
442 lines
18 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Reflection;
|
|
using System.IO;
|
|
using BrewMonster;
|
|
using ModelRenderer.Scripts.Common;
|
|
using ModelRenderer.Scripts.GameData;
|
|
using UnityEngine;
|
|
using PerfectWorld.Scripts.Managers;
|
|
using BrewMonster.Network;
|
|
using BrewMonster.Scripts.Managers;
|
|
using BrewMonster.Scripts;
|
|
using CSNetwork.GPDataType;
|
|
using System.Runtime.InteropServices;
|
|
namespace BrewMonster.Scripts
|
|
{
|
|
public struct PETSKILL
|
|
{
|
|
public int idSkill;
|
|
public int iLevel;
|
|
};
|
|
/// <summary>
|
|
/// Class for Pet Egg(cac loai trung pet(thu cuoi, chien dau, di theo, p2w pet)). This is a part of IvtrPetItem(C++)
|
|
/// </summary>
|
|
public class EC_IvtrPetEgg : EC_IvtrItem
|
|
{
|
|
List<PETSKILL> m_aSkills;
|
|
|
|
IVTR_ESSENCE_PETEGG m_Essence;
|
|
string m_strName;
|
|
|
|
// Data in database
|
|
PET_EGG_ESSENCE m_pDBEssence;
|
|
PET_ESSENCE m_pPetEssence;
|
|
PET_ESSENCE m_pEvoPetEssence;
|
|
PET_EVOLVED_SKILL_CONFIG m_pEvoNatureConfig;
|
|
_evo_prop m_EvoProp; // ������̳�����
|
|
/// <summary>
|
|
/// Constructor for Pet Egg(cac loai trung pet(thu cuoi, chien dau, di theo, p2w pet))
|
|
/// </summary>
|
|
/// <param name="tid">Template id</param>
|
|
/// <param name="expire_date">Expire date</param>
|
|
public EC_IvtrPetEgg(int tid, int expire_date) : base(tid, expire_date)
|
|
{
|
|
m_iCID = (int)InventoryClassId.ICID_PETEGG;
|
|
|
|
// Get database data
|
|
elementdataman pDB = ElementDataManProvider.GetElementDataMan();
|
|
DATA_TYPE DataType = DATA_TYPE.DT_INVALID;
|
|
m_pDBEssence = (PET_EGG_ESSENCE)pDB.get_data_ptr((uint)tid, ID_SPACE.ID_SPACE_ESSENCE, ref DataType);
|
|
m_pPetEssence = (PET_ESSENCE)pDB.get_data_ptr((uint)m_pDBEssence.id_pet, ID_SPACE.ID_SPACE_ESSENCE, ref DataType);
|
|
// ASSERT(m_pPetEssence);
|
|
|
|
//struct can't be null
|
|
//m_pEvoPetEssence = null;
|
|
m_pEvoPetEssence = new PET_ESSENCE();
|
|
if (m_pPetEssence.id >=0)
|
|
{
|
|
object pTempDBEssenceObj = pDB.get_data_ptr((uint)m_pPetEssence.id_pet_egg_evolved, ID_SPACE.ID_SPACE_ESSENCE, ref DataType);
|
|
if (pTempDBEssenceObj != null)
|
|
{
|
|
PET_EGG_ESSENCE pTempDBEssence = (PET_EGG_ESSENCE)pTempDBEssenceObj;
|
|
if (pTempDBEssence.id >=0)
|
|
{
|
|
object pEvoPetEssenceObj = pDB.get_data_ptr((uint)pTempDBEssence.id_pet, ID_SPACE.ID_SPACE_ESSENCE, ref DataType);
|
|
if (pEvoPetEssenceObj != null)
|
|
m_pEvoPetEssence = (PET_ESSENCE)pEvoPetEssenceObj;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
m_iPileLimit = m_pDBEssence.pile_num_max;
|
|
m_iPrice = m_pDBEssence.price;
|
|
m_iShopPrice = m_pDBEssence.shop_price;
|
|
m_iProcType = (int)m_pDBEssence.proc_type;
|
|
m_i64EquipMask = 0;
|
|
// m_bUseable = true;
|
|
// m_dwUseFlags = USE_PERSIST;
|
|
|
|
m_Essence = new IVTR_ESSENCE_PETEGG();
|
|
m_EvoProp = new _evo_prop{
|
|
r_attack = 0,
|
|
r_defense = 0,
|
|
r_hp = 0,
|
|
r_atk_lvl = 0,
|
|
r_def_lvl = 0,
|
|
nature = 0
|
|
};
|
|
|
|
m_pEvoNatureConfig = new PET_EVOLVED_SKILL_CONFIG();
|
|
}
|
|
|
|
public EC_IvtrPetEgg(EC_IvtrPetEgg other) : base(other)
|
|
{
|
|
m_pDBEssence = other.m_pDBEssence;
|
|
m_pPetEssence = other.m_pPetEssence;
|
|
m_Essence = other.m_Essence;
|
|
m_strName = other.m_strName;
|
|
|
|
// Copy skills
|
|
int i, iNumSkill = other.m_aSkills.Count;
|
|
m_aSkills = new List<PETSKILL>(iNumSkill);
|
|
|
|
for (i=0; i < iNumSkill; i++)
|
|
m_aSkills[i] = other.m_aSkills[i];
|
|
|
|
m_EvoProp = other.m_EvoProp;
|
|
m_pEvoNatureConfig = other.m_pEvoNatureConfig;
|
|
m_pEvoPetEssence = other.m_pEvoPetEssence;
|
|
}
|
|
public override bool SetItemInfo(byte[] pInfoData, int iDataLen)
|
|
{
|
|
base.SetItemInfo(pInfoData, iDataLen);
|
|
|
|
if (pInfoData == null || iDataLen == 0)
|
|
return true;
|
|
|
|
try {
|
|
CECDataReader dr = new CECDataReader(pInfoData, iDataLen);
|
|
m_Essence = new IVTR_ESSENCE_PETEGG(dr.ReadData(Marshal.SizeOf<IVTR_ESSENCE_PETEGG>()));
|
|
|
|
if (m_Essence.name_len != 0)
|
|
{
|
|
m_strName = ByteToStringUtils.UshortArrayToUnicodeString(m_Essence.name);
|
|
EC_Game.GetGameRun().GetUIManager().FilterBadWords(ref m_strName);
|
|
}
|
|
|
|
m_aSkills = new List<PETSKILL>(m_Essence.skill_count);
|
|
for (int i=0; i < m_Essence.skill_count; i++)
|
|
{
|
|
PETSKILL s = new PETSKILL();
|
|
s.idSkill = dr.ReadInt();
|
|
s.iLevel = dr.ReadInt();
|
|
m_aSkills.Add(s);
|
|
}
|
|
|
|
if (m_Essence.pet_class == (int)GP_PET_TYPE.GP_PET_CLASS_EVOLUTION)
|
|
{
|
|
m_EvoProp.r_attack = dr.ReadInt();
|
|
m_EvoProp.r_defense = dr.ReadInt();
|
|
m_EvoProp.r_hp = dr.ReadInt();
|
|
m_EvoProp.r_atk_lvl = dr.ReadInt();
|
|
m_EvoProp.r_def_lvl = dr.ReadInt();
|
|
m_EvoProp.nature = dr.ReadInt();
|
|
|
|
elementdataman pDB = ElementDataManProvider.GetElementDataMan();
|
|
DATA_TYPE DataType = DATA_TYPE.DT_INVALID;
|
|
object pDBData = pDB.get_data_ptr((uint)m_EvoProp.nature, ID_SPACE.ID_SPACE_CONFIG, ref DataType);
|
|
if (pDBData != null && DataType == DATA_TYPE.DT_PET_EVOLVED_SKILL_CONFIG)
|
|
m_pEvoNatureConfig = (PET_EVOLVED_SKILL_CONFIG)pDBData;
|
|
}
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
Debug.LogError("EC_IvtrPetEgg::SetItemInfo, data read error (" + e.GetType() + e.StackTrace + ")");
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
public override string GetIconFile()
|
|
{
|
|
return m_pDBEssence.FileIcon;
|
|
}
|
|
|
|
public override string GetName()
|
|
{
|
|
// Try Unicode first (for Vietnamese/wide char names), then fallback to CP936
|
|
if (m_pDBEssence.name != null && m_pDBEssence.name.Length > 0)
|
|
{
|
|
string s = ByteToStringUtils.UshortArrayToUnicodeString(m_pDBEssence.name);
|
|
if (!string.IsNullOrEmpty(s) && !string.IsNullOrWhiteSpace(s))
|
|
return s;
|
|
// Fallback to legacy CP936 if Unicode was empty
|
|
s = ByteToStringUtils.UshortArrayToCP936String(m_pDBEssence.name);
|
|
if (!string.IsNullOrEmpty(s))
|
|
return s;
|
|
}
|
|
return base.GetName(); // Fallback to base class method
|
|
}
|
|
protected override string GetNormalDesc(bool bRepair)
|
|
{
|
|
string szDesc = "";
|
|
switch (m_Essence.pet_class)
|
|
{
|
|
case (int)GP_PET_TYPE.GP_PET_CLASS_MOUNT: szDesc = GetRidingPetDesc(bRepair); break;
|
|
case (int)GP_PET_TYPE.GP_PET_CLASS_COMBAT: szDesc = GetCombatPetDesc(bRepair); break;
|
|
case (int)GP_PET_TYPE.GP_PET_CLASS_FOLLOW: szDesc = GetFollowPetDesc(bRepair); break;
|
|
case (int)GP_PET_TYPE.GP_PET_CLASS_EVOLUTION:szDesc = GetEvolutionPetDesc(bRepair); break;
|
|
}
|
|
|
|
return szDesc;
|
|
}
|
|
private string GetRidingPetDesc(bool bRepair)
|
|
{
|
|
if (m_bNeedUpdate)
|
|
return "";
|
|
|
|
m_strDesc = string.Empty;
|
|
|
|
// Try to build item description
|
|
CECStringTab pDescTab = EC_Game.GetItemDesc();
|
|
CECHostPlayer pHost = EC_Game.GetGameRun().GetHostPlayer();
|
|
|
|
int white = (int)DescriptipionMsg.ITEMDESC_COL_WHITE;
|
|
int red = (int)DescriptipionMsg.ITEMDESC_COL_RED;
|
|
int namecol = DecideNameCol();
|
|
|
|
// Item name: always use the name in template
|
|
if (m_iCount > 1)
|
|
AddDescText(namecol, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_NAMENUMBER), m_pDBEssence.Name/* GetName() */, m_iCount);
|
|
else
|
|
AddDescText(namecol, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_NAME), m_pDBEssence.Name/* GetName() */);
|
|
|
|
AddIDDescText();
|
|
|
|
AddBindDescText();
|
|
|
|
AddExpireTimeDesc();
|
|
|
|
// ������ɫ��Ϣ
|
|
if (m_pPetEssence.id != 0 && m_pPetEssence.require_dye_count > 0)
|
|
{
|
|
if (m_iScaleType == (int)ScaleType.SCALE_BUY)
|
|
{
|
|
AddDescText(white, false, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_COLOR));
|
|
AddDescText(white, true, " ???");
|
|
}
|
|
else
|
|
{
|
|
Color clr = new Color(255, 255, 255);
|
|
if (RIDINGPET.GetColor(m_Essence.color, clr))
|
|
clr = RIDINGPET.GetDefaultColor();
|
|
string strColor = string.Format("^{0:X2}{1:X2}{2:X2}", clr.r, clr.g, clr.b);
|
|
AddDescText(white, false, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_COLOR));
|
|
m_strDesc += " ";
|
|
AddDescText(-1, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_COLORRECT), strColor);
|
|
}
|
|
}
|
|
// Food type requirement
|
|
AddFoodTypeDesc();
|
|
|
|
if (m_pPetEssence.id != 0)
|
|
{
|
|
// Pet level
|
|
AddDescText(white, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_PETLEVEL), m_Essence.level);
|
|
|
|
// Move speed
|
|
float fSpeed = m_pPetEssence.speed_a + (m_Essence.level - 1) * m_pPetEssence.speed_b;
|
|
AddDescText(-1, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_MOVESPEED), fSpeed);
|
|
|
|
// Profession requirement
|
|
AddProfReqDesc(m_pPetEssence.character_combo_id);
|
|
}
|
|
|
|
// Level requirement
|
|
int iLevelReq = Mathf.Max((int)m_Essence.level, m_Essence.req_level);
|
|
if (iLevelReq > 0)
|
|
{
|
|
int col = pHost.GetMaxLevelSofar() >= iLevelReq ? white : red;
|
|
AddDescText(col, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_LEVELREQ), iLevelReq);
|
|
}
|
|
|
|
// Price
|
|
AddPriceDesc(white, bRepair);
|
|
|
|
// Extend description
|
|
AddExtDescText();
|
|
|
|
return m_strDesc;
|
|
}
|
|
private string GetCombatPetDesc(bool bRepair)
|
|
{
|
|
if (m_bNeedUpdate)
|
|
return "";
|
|
|
|
m_strDesc = "";
|
|
|
|
// Try to build item description
|
|
CECStringTab pDescTab = EC_Game.GetItemDesc();
|
|
CECHostPlayer pHost = EC_Game.GetGameRun().GetHostPlayer();
|
|
|
|
int white = (int)DescriptipionMsg.ITEMDESC_COL_WHITE;
|
|
int red = (int)DescriptipionMsg.ITEMDESC_COL_RED;
|
|
int namecol = DecideNameCol();
|
|
|
|
// Item name: always use the name in template
|
|
if (m_iCount > 1)
|
|
AddDescText(namecol, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_NAMENUMBER), GetName(), m_iCount);
|
|
else
|
|
AddDescText(namecol, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_NAME), GetName());
|
|
|
|
AddIDDescText();
|
|
|
|
AddBindDescText();
|
|
|
|
AddExpireTimeDesc();
|
|
|
|
// Food type requirement
|
|
AddFoodTypeDesc();
|
|
|
|
if (m_pPetEssence.id != 0)
|
|
{
|
|
// Pet level
|
|
AddDescText(white, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_PETLEVEL), m_Essence.level);
|
|
|
|
// Physical damage
|
|
int iVal = (int)(((PET_ESSENCE)m_pPetEssence).damage_a * (((PET_ESSENCE)m_pPetEssence).damage_b * m_Essence.level * m_Essence.level + ((PET_ESSENCE)m_pPetEssence).damage_c * m_Essence.level + ((PET_ESSENCE)m_pPetEssence).damage_d));
|
|
AddDescText(-1, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_DAMAGE), iVal);
|
|
|
|
// Attack speed
|
|
AddDescText(-1, false, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_ATKSPEED));
|
|
AddDescText(-1, true, " %.2f", 1.0f / ((PET_ESSENCE)m_pPetEssence).attack_speed);
|
|
|
|
//Attack rating
|
|
iVal = (int)(((PET_ESSENCE)m_pPetEssence).attack_a * (m_Essence.level - ((PET_ESSENCE)m_pPetEssence).attack_b * ((PET_ESSENCE)m_pPetEssence).level_require + ((PET_ESSENCE)m_pPetEssence).attack_c));
|
|
AddDescText(-1, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_ATTACKRATE), iVal);
|
|
|
|
// Physical defence
|
|
iVal = (int)(((PET_ESSENCE)m_pPetEssence).physic_defence_a * (((PET_ESSENCE)m_pPetEssence).physic_defence_b * (m_Essence.level - ((PET_ESSENCE)m_pPetEssence).physic_defence_c * ((PET_ESSENCE)m_pPetEssence).level_require) + ((PET_ESSENCE)m_pPetEssence).physic_defence_d));
|
|
AddDescText(-1, false, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_PHYDEFENCE));
|
|
AddDescText(-1, true, " %d", iVal);
|
|
|
|
// Magic defence
|
|
iVal = (int)(((PET_ESSENCE)m_pPetEssence).magic_defence_a * (((PET_ESSENCE)m_pPetEssence).magic_defence_b * (m_Essence.level - ((PET_ESSENCE)m_pPetEssence).magic_defence_c * ((PET_ESSENCE)m_pPetEssence).level_require) + ((PET_ESSENCE)m_pPetEssence).magic_defence_d));
|
|
AddDescText(-1, false, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_ALLMAGICDEF));
|
|
AddDescText(-1, true, " %d", iVal);
|
|
|
|
// Dodge
|
|
iVal = (int)(((PET_ESSENCE)m_pPetEssence).armor_a * (m_Essence.level - ((PET_ESSENCE)m_pPetEssence).armor_b * ((PET_ESSENCE)m_pPetEssence).level_require + ((PET_ESSENCE)m_pPetEssence).armor_c));
|
|
AddDescText(-1, false, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_DODGE));
|
|
AddDescText(-1, true, " %d", iVal);
|
|
|
|
// hp
|
|
iVal = (int)(((PET_ESSENCE)m_pPetEssence).hp_a * (m_Essence.level - ((PET_ESSENCE)m_pPetEssence).hp_b * ((PET_ESSENCE)m_pPetEssence).level_require + ((PET_ESSENCE)m_pPetEssence).hp_c));
|
|
AddDescText(-1, false, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_ADDHP));
|
|
AddDescText(-1, true, " %d", iVal);
|
|
|
|
// Profession requirement
|
|
AddProfReqDesc(((PET_ESSENCE)m_pPetEssence).character_combo_id);
|
|
}
|
|
|
|
// Level requirement
|
|
int iLevelReq = Mathf.Max((int)m_Essence.level, m_Essence.req_level);
|
|
if (iLevelReq > 0)
|
|
{
|
|
int col = pHost.GetMaxLevelSofar() >= iLevelReq ? white : red;
|
|
AddDescText(col, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_LEVELREQ), iLevelReq);
|
|
}
|
|
|
|
// Skill list
|
|
for (int i=0; i < m_aSkills.Count; i++)
|
|
{
|
|
PETSKILL skill = m_aSkills[i];
|
|
string szName = EC_Game.GetSkillDesc().GetWideString(skill.idSkill * 10);
|
|
AddDescText((int)DescriptipionMsg.ITEMDESC_COL_YELLOW, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_PETSKILL), szName != null ? szName : "", skill.iLevel);
|
|
|
|
}
|
|
|
|
// �ɽ���
|
|
if (m_pEvoPetEssence.id != 0)
|
|
{
|
|
AddDescText((int)DescriptipionMsg.ITEMDESC_COL_WHITE, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_PET_EVO_NAME), ByteToStringUtils.UshortArrayToUnicodeString(((PET_ESSENCE)m_pEvoPetEssence).name));
|
|
}
|
|
|
|
// Price
|
|
AddPriceDesc(white, bRepair);
|
|
|
|
// Extend description
|
|
AddExtDescText();
|
|
|
|
return m_strDesc;
|
|
}
|
|
private string GetFollowPetDesc(bool bRepair)
|
|
{
|
|
Debug.Log("[THN]GetFollowPetDesc. This is not implemented yet.");
|
|
return "";
|
|
}
|
|
|
|
public PET_EGG_ESSENCE GetDBEssence()
|
|
{
|
|
return m_pDBEssence;
|
|
}
|
|
|
|
private string GetEvolutionPetDesc(bool bRepair)
|
|
{
|
|
Debug.Log("[THN]GetEvolutionPetDesc. This is not implemented yet.");
|
|
return "";
|
|
}
|
|
private void AddFoodTypeDesc()
|
|
{
|
|
elementdataman pDB = ElementDataManProvider.GetElementDataMan();
|
|
DATA_TYPE DataType = DATA_TYPE.DT_INVALID;
|
|
object pPetEssence = pDB.get_data_ptr((uint)m_Essence.pet_tid, ID_SPACE.ID_SPACE_ESSENCE, ref DataType);
|
|
if (pPetEssence == null)
|
|
return;
|
|
|
|
CECStringTab pDescTab = EC_Game.GetItemDesc();
|
|
AddDescText((int)DescriptipionMsg.ITEMDESC_COL_WHITE, false, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_FOODTYPE));
|
|
|
|
for (int i=0; i < (int)PetFoodType.MAX_PET_FOOD; i++)
|
|
{
|
|
if ((((PET_ESSENCE)pPetEssence).food_mask & (1 << i)) != 0)
|
|
{
|
|
m_strDesc += " ";
|
|
AddDescText(-1, false, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_FOOD_GRASS+i));
|
|
}
|
|
}
|
|
|
|
m_strDesc += "\\r";
|
|
}
|
|
// Get item description for booth buying
|
|
protected override string GetBoothBuyDesc()
|
|
{
|
|
m_strDesc = "";
|
|
|
|
CECStringTab pDescTab = EC_Game.GetItemDesc();
|
|
|
|
int white = (int)DescriptipionMsg.ITEMDESC_COL_WHITE;
|
|
|
|
// Item name
|
|
AddDescText(white, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_NAME), ByteToStringUtils.UshortArrayToUnicodeString(m_pDBEssence.name));
|
|
|
|
// Price
|
|
AddPriceDesc(white, false);
|
|
|
|
return m_strDesc;
|
|
}
|
|
|
|
// Get drop model for shown
|
|
public override string GetDropModel()
|
|
{
|
|
return ByteToStringUtils.ByteArrayToCP936String(m_pDBEssence.file_matter);
|
|
}
|
|
|
|
// Get essence data
|
|
public IVTR_ESSENCE_PETEGG GetEssence() { return m_Essence; }
|
|
}
|
|
}
|
|
|