add all item till level 20 through the quest for TIT(tien thu). fix the bug suite not count decoration data.

This commit is contained in:
Chomper9981
2026-01-23 09:31:55 +07:00
parent 00c32e50e6
commit 46cfb747c6
10 changed files with 474 additions and 25 deletions
@@ -919,6 +919,53 @@ public static class generate_item_temp
itemdataman.set_to_classid(DATA_TYPE.DT_FASHION_ESSENCE, data, -1);
return 0;
}
public static int generate_taskdice<RAND_CLASS>(uint id, ID_SPACE idspace, out byte[] data, out uint size, RAND_CLASS cls)
{
DATA_TYPE datatype = DATA_TYPE.DT_INVALID;
data = new byte[0];
size = 0;
object obj = itemdataman._edm.get_data_ptr(id, idspace, ref datatype);
if(obj == null || datatype != DATA_TYPE.DT_TASKDICE_ESSENCE)
{
return -1;
}
TASKDICE_ESSENCE ess = (TASKDICE_ESSENCE)obj;
size = (uint)(Marshal.SizeOf(typeof(item_data)) + Marshal.SizeOf(typeof(TASKDICE_ESSENCE)));
data = new byte[size];
int offset = 0;
WriteUInt(data, ref offset, id);
WriteUInt(data, ref offset, 1);
WriteInt(data, ref offset, ess.pile_num_max);
WriteInt(data, ref offset, 0);
WriteUInt(data, ref offset, ess.proc_type);
WriteInt(data, ref offset, (int)DATA_TYPE.DT_TASKDICE_ESSENCE);
if(ess.has_guid == 1)
{
int g1,g2;
itemdataman.get_item_guid(id,out g1,out g2);
WriteInt(data, ref offset, g1);
WriteInt(data, ref offset, g2);
}
else
{
WriteInt(data, ref offset, 0);
WriteInt(data, ref offset, 0);
}
WriteInt(data, ref offset, 0);
WriteInt(data, ref offset, 0);
int content_length = 0;
int content_length_ptr = offset;
WriteInt(data, ref offset, 0);
int item_content = offset;
WriteInt(data, ref offset, 0);
content_length = (int)(size - offset);
WriteInt(data, ref content_length_ptr, content_length);
WriteInt(data, ref item_content, offset);
itemdataman.set_to_classid(DATA_TYPE.DT_TASKDICE_ESSENCE, data, -1);
return 0;
}
public static int generate_tasknormalmatter<RAND_CLASS>(uint id, ID_SPACE idspace, out byte[] data, out uint size, RAND_CLASS cls,
GEN_ADDON_MODE normal_addon ,item_tag_t tag,List<int> sa_list = null)
{
@@ -469,6 +469,9 @@ namespace BrewMonster
case DATA_TYPE.DT_FASHION_ESSENCE:
ret = generate_item_temp.generate_fashion_item(id, ID_SPACE.ID_SPACE_ESSENCE, out item, out size, SPECIFIC.SPECIFIC_RAND, tag);
break;
case DATA_TYPE.DT_TASKDICE_ESSENCE:
ret = generate_item_temp.generate_taskdice(id, ID_SPACE.ID_SPACE_ESSENCE, out item, out size, SPECIFIC.SPECIFIC_RAND);
break;
case DATA_TYPE.DT_TASKNORMALMATTER_ESSENCE:
ret = generate_item_temp.generate_tasknormalmatter(id,ID_SPACE.ID_SPACE_ESSENCE,
out item,out size,SPECIFIC.SPECIFIC_RAND,GEN_ADDON_MODE.ADDON_LIST_SHOP,tag);
@@ -1508,16 +1508,16 @@ namespace BrewMonster
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)]
public byte[] file_model; // Model file path
public string FileModel => ByteToStringUtils.ByteArrayToCP936String(file_model);
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)]
public byte[] file_model2; // Second model file path
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)]
public byte[] file_matter; // Material file path
public string FileMatter => ByteToStringUtils.ByteArrayToCP936String(file_matter);
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)]
public byte[] file_icon; // Icon file path
public string FileIcon => ByteToStringUtils.ByteArrayToCP936String(file_icon);
public int price; // Price
public int shop_price; // Shop price
@@ -1785,9 +1785,10 @@ namespace BrewMonster
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)]
public byte[] file_matter; // matter file path
public string FileMatter { get { return ByteToStringUtils.ByteArrayToCP936String(file_matter); } }
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)]
public byte[] file_icon; // icon file path
public string FileIcon { get { return ByteToStringUtils.ByteArrayToCP936String(file_icon); } }
[StructLayout(LayoutKind.Sequential)]
public struct TaskList
@@ -819,7 +819,7 @@ namespace PerfectWorld.Scripts.Managers
/// <summary>
/// Read maker information from binary data
/// </summary>
private void ReadMakerInfo(CECDataReader dr)
protected void ReadMakerInfo(CECDataReader dr)
{
// Debug: Log the bytes at current position before reading
// We need to check what bytes are actually at the reader position
@@ -1,20 +1,228 @@
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 PerfectWorld.Scripts.Managers
{
public class EC_IvtrFlysword : EC_IvtrItem
/// <summary>
/// Flysword Item (Phi kiem).
/// </summary>
public class EC_IvtrFlysword : EC_IvtrEquip
{
protected int m_iCurTime; // Current time counter in ms
protected IVTR_ESSENCE_FLYSWORD m_Essence;
protected FLYSWORD_ESSENCE m_pDBEssence;
/// <summary>
/// Not create logic yet (add summary later)
/// Flysword Item (Phi kiem)
/// </summary>
/// <param name="tid">Template id</param>
/// <param name="expire_date">Expire date</param>
public EC_IvtrFlysword(int tid, int expire_date) : base(tid, expire_date)
{
m_iCID = (int)InventoryClassId.ICID_FLYSWORD;
// Get database data
elementdataman pDB = ElementDataManProvider.GetElementDataMan();
DATA_TYPE DataType = DATA_TYPE.DT_INVALID;
m_pDBEssence = (FLYSWORD_ESSENCE)pDB.get_data_ptr((uint)tid, ID_SPACE.ID_SPACE_ESSENCE, ref DataType);
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 = EC_IvtrType.EQUIP_MASK64_FLYSWORD;
m_bUseable = true;
m_bNeedUpdate = false;
}
public EC_IvtrFlysword(EC_IvtrFlysword other) : base(other)
{
m_iCurTime = other.m_iCurTime;
m_Essence = other.m_Essence;
m_pDBEssence = other.m_pDBEssence;
MadeFrom = other.MadeFrom;
Maker = other.Maker;
}
public override bool SetItemInfo(byte[] pInfoData, int iDataLen)
{
// Note: because fly sword isn't an absolute equipment, so skip
// CECIvtrEquip::SetItemInfo().
if (pInfoData == null || iDataLen == 0)
{
m_bNeedUpdate = false;
return true;
}
try
{
CECDataReader dr = new CECDataReader(pInfoData, iDataLen);
m_Essence = new IVTR_ESSENCE_FLYSWORD(dr.ReadData(Marshal.SizeOf<IVTR_ESSENCE_FLYSWORD>()));
base.ReadMakerInfo(dr);
}
catch (Exception e)
{
Debug.LogError("CECIvtrFlySword::SetItemInfo, data read error (" + e.GetType() + ")");
return false;
}
LevelReq = m_Essence.require_level;
m_bNeedUpdate = false;
m_iCurTime = m_Essence.cur_time * 1000;
return true;
}
public override string GetIconFile()
{
return m_pDBEssence.FileIcon;
}
protected override string GetNormalDesc(bool bRepair)
{
if (m_bNeedUpdate)
return string.Empty;
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();
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();
// Is destroying?
AddDestroyingDesc((int)m_pDBEssence.id_drop_after_damaged, m_pDBEssence.num_drop_after_damaged);
AddExpireTimeDesc();
// level
AddDescText(white, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_LEVEL), m_Essence.level);
// whether can be improved
if (IsImprovable())
AddDescText((int)DescriptipionMsg.ITEMDESC_COL_GREEN,true,pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_FLYSWORD_IMPROVE),m_Essence.improve_level,GetMaxImproveLevel());
else
AddDescText(white,true,pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_FLYSWORD_NOIMPROVED));
// Normal fly speed bonus
if (m_Essence.speed_increase > 0)
AddDescText(white, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_ADDFLYSPEED), m_Essence.speed_increase);
// Quick fly speed bonus
if (m_Essence.speed_increase2 > 0)
AddDescText(white, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_ADDFLYSPEED2), m_Essence.speed_increase2);
// Remain time
if (GetMaxTime() > 0)
AddDescText(white, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_REMAINTIME), GetCurTime(), GetMaxTime());
// Profession requirement
AddProfReqDesc((uint)m_Essence.profession);
// Level requirement
if (LevelReq > 0)
{
int col = pHost.GetMaxLevelSofar() >= LevelReq ? white : red;
AddDescText(col, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_LEVELREQ), LevelReq);
}
// Element consume
// AddDescText(white, true, pDescTab->GetWideString(ITEMDESC_ELEMENTTIME), m_Essence.time_per_element);
// Price
AddPriceDesc(white, bRepair);
AddMakerDesc();
// Suite description
AddSuiteDesc();
// Extend description
AddExtDescText();
return m_strDesc;
}
// Get max time
protected int GetMaxTime()
{
return (int)m_Essence.max_time;
}
// Get max element number
protected int GetMaxElement()
{
return (int)((float)m_Essence.max_time / m_Essence.time_per_element + 0.5f);
}
// Get time each element equal to
protected int GetElementTime()
{
return m_Essence.time_per_element;
}
// Get number of element if time is filled to full. This is just the number
// of element which has been used
protected int GetUsedElementNum()
{
return (int)((m_Essence.max_time - GetCurTime()) / (float)m_Essence.time_per_element);
}
// Get drop model for shown
protected string GetDropModel()
{
return m_pDBEssence.FileMatter;
}
public override bool IsRare()
{
return base.IsRare() || m_Essence.level >= 6;
}
protected bool IsImprovable()
{
return m_pDBEssence.max_improve_level > 0 && m_pDBEssence.improve_config[0].require_item_num > 0;
}
protected bool CanBeImproved()
{
if(m_pDBEssence.max_improve_level <=0) return false;
if(m_Essence.improve_level>= GetMaxImproveLevel()) return false;
return m_pDBEssence.improve_config[m_Essence.improve_level].require_item_num > 0;
}
protected int GetMaxImproveLevel()
{
int maxL = m_pDBEssence.improve_config.Length;
int i = 0;
for (i = 0; i < maxL; i++)
{
if(m_pDBEssence.improve_config[i].require_item_num == 0)
break;
}
return Mathf.Min(m_pDBEssence.max_improve_level, i);
}
protected int GetCurTime() { return m_Essence.cur_time; }
}
}
@@ -194,8 +194,82 @@ namespace PerfectWorld.Scripts.Managers
}
private string GetRidingPetDesc(bool bRepair)
{
Debug.Log("GetRidingPetDesc. This is not implemented yet.");
return "";
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)
{
@@ -1,19 +1,84 @@
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 PerfectWorld.Scripts.Managers
{
/// <summary>
/// Task Dice Item (Tui qua random).
/// This is a part of IvtrTaskItem(C++)
/// </summary>
public class EC_IvtrTaskDice : EC_IvtrItem
{
protected TASKDICE_ESSENCE m_pDBEssence;
/// <summary>
/// Not create logic yet (add summary later)
/// Task Dice Item
/// </summary>
/// <param name="tid">Template id</param>
/// <param name="expire_date">Expire date</param>
public EC_IvtrTaskDice(int tid, int expire_date) : base(tid, expire_date)
/// <param name="tid"></param>
/// <param name="expire_date"></param>
public EC_IvtrTaskDice(int tid, int expire_date) : base(tid, expire_date)
{
}
m_iCID = (int)InventoryClassId.ICID_TASKDICE;
elementdataman pDB = ElementDataManProvider.GetElementDataMan();
DATA_TYPE DataType = DATA_TYPE.DT_INVALID;
m_pDBEssence = (TASKDICE_ESSENCE)pDB.get_data_ptr((uint)tid, ID_SPACE.ID_SPACE_ESSENCE, ref DataType);
m_iPileLimit = m_pDBEssence.pile_num_max;
m_iPrice = 0;
m_iShopPrice = 0;
m_iProcType = (int)m_pDBEssence.proc_type;
m_bUseable = true;
m_bNeedUpdate = false;
}
public EC_IvtrTaskDice(EC_IvtrTaskDice other) : base(other)
{
m_pDBEssence = other.m_pDBEssence;
}
public override bool SetItemInfo(byte[] pInfoData, int iDataLen)
{
base.SetItemInfo(pInfoData, iDataLen);
return true;
}
public override string GetIconFile()
{
return m_pDBEssence.FileIcon;
}
protected override string GetNormalDesc(bool bRepair)
{
m_strDesc = "";
// Try to build item description
CECStringTab pDescTab = EC_Game.GetItemDesc();
int white = (int)DescriptipionMsg.ITEMDESC_COL_WHITE;
int namecol = DecideNameCol();
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();
AddExpireTimeDesc();
AddPriceDesc(white, bRepair);
// Extend description
AddExtDescText();
return m_strDesc;
}
public override string GetDropModel()
{
return m_pDBEssence.FileMatter;
}
}
}
@@ -160,16 +160,28 @@ namespace BrewMonster.Scripts.Managers
};
public struct IVTR_ESSENCE_FLYSWORD
{
// TODO : implement data later
// int cur_time;
// int max_time;
// short require_level;
// char level;
// char improve_level;
// int profession;
// size_t time_per_element;
// float speed_increase;
// float speed_increase2;
public int cur_time;
public int max_time;
public short require_level;
public char level;
public char improve_level;
public int profession;
public int time_per_element;
public float speed_increase;
public float speed_increase2;
public IVTR_ESSENCE_FLYSWORD(byte[] data)
{
CECDataReader dr = new (data, data.Length);
cur_time = dr.ReadInt();
max_time = dr.ReadInt();
require_level = dr.ReadShort();
level = (char)dr.ReadByte();
improve_level = (char)dr.ReadByte();
profession = dr.ReadInt();
time_per_element = dr.ReadInt();
speed_increase = dr.ReadFloat();
speed_increase2 = dr.ReadFloat();
}
};
public struct IVTR_ESSENCE_WING
{
@@ -81,6 +81,7 @@ namespace BrewMonster
protected int m_iBoothState = 0; // Booth state. 0, none; 1, prepare; 2, open booth; 3, visite other's booth
public int m_idFRole = GNETRoles._R_UNMEMBER; // ID of player's faction role
protected int m_idCountry = 0; // ¹úÕ½ÕóÓª id
public static int MAX_REINCARNATION = 2;
protected List<int> m_aCurEffects = new List<int>(); // Current effects
@@ -1905,4 +1906,42 @@ namespace BrewMonster
enumSkinShowArmet,
enumSkinShowHand,
};
/// <summary>
/// Place holder for riding pet. Not test logic yet.
/// </summary>
public struct RIDINGPET
{
public int id;
public ushort color;
public RIDINGPET(bool isReset = true)
{
id = 0;
color = 0;
}
public bool GetColor(Color clr)
{
// ȡǰȾɫɫ
return id>0 && GetColor(color, clr);
}
public static bool GetColor(ushort c, Color clr)
{
// ѯǰǷȾɫȾɫرȾ֮ɫ
bool bRet = false;
if ((c & (1<<(8-1))) != 0)
{
// unsigned short λΪ1ʱʾȾɫʱɻȡɫ
clr = new Color(((c) & (0x1f << 10)) >> 7, ((c) & (0x1f << 5)) >> 2, ((c) & 0x1f) << 3);
bRet = true;
}
return bRet;
}
public static Color GetDefaultColor()
{
return new Color(255, 255, 255);
}
};
}
+1 -1
View File
@@ -6948,7 +6948,7 @@ namespace BrewMonster
for(i = 0; i < m_pEquipPack.GetSize(); i++)
{
var pItem = m_pEquipPack.GetItem(i);
if(pItem == null || (pItem is not EC_IvtrWeapon && pItem is not EC_IvtrArmor))
if(pItem == null)
{
continue;
}