From e504a077c1f7589e2c4aa7a4726d985c584f00b3 Mon Sep 17 00:00:00 2001 From: Chomper9981 Date: Tue, 30 Dec 2025 10:19:18 +0700 Subject: [PATCH 1/7] Add itemdataman basic --- .../Common/DataProcess/generate_item_temp.cs | 380 +++++++ .../DataProcess/generate_item_temp.cs.meta | 2 + .../Scripts/Common/DataProcess/itemdataman.cs | 943 ++++++++++++++++++ .../Common/DataProcess/itemdataman.cs.meta | 2 + .../Scripts/Inventory/EC_IvtrType.cs | 1 + .../PerfectWorld/Scripts/MainFiles/EC_Game.cs | 28 +- 6 files changed, 1353 insertions(+), 3 deletions(-) create mode 100644 Assets/PerfectWorld/Scripts/Common/DataProcess/generate_item_temp.cs create mode 100644 Assets/PerfectWorld/Scripts/Common/DataProcess/generate_item_temp.cs.meta create mode 100644 Assets/PerfectWorld/Scripts/Common/DataProcess/itemdataman.cs create mode 100644 Assets/PerfectWorld/Scripts/Common/DataProcess/itemdataman.cs.meta diff --git a/Assets/PerfectWorld/Scripts/Common/DataProcess/generate_item_temp.cs b/Assets/PerfectWorld/Scripts/Common/DataProcess/generate_item_temp.cs new file mode 100644 index 0000000000..e0a5249fe8 --- /dev/null +++ b/Assets/PerfectWorld/Scripts/Common/DataProcess/generate_item_temp.cs @@ -0,0 +1,380 @@ +using BrewMonster.ELEMENT_DATA; +using ModelRenderer.Scripts.GameData; +using BrewMonster; +using System.Runtime.InteropServices; +using System.Collections.Generic; +using System.Linq; + using System; +public static class generate_item_temp +{ + public static int generate_weapon(uint id, ID_SPACE idspace, out byte[] data, out uint size, RAND_CLASS cls, + GEN_ADDON_MODE normal_addon ,item_tag_t tag,List sa_list = null) + { + DATA_TYPE datatype = DATA_TYPE.DT_INVALID; + data = new byte[0]; + size = 0; + int i=0; + object obj = itemdataman._edm.get_data_ptr(id, idspace,ref datatype); + if(obj == null || datatype != DATA_TYPE.DT_WEAPON_ESSENCE) + { + return -1; + } + WEAPON_ESSENCE ess = (WEAPON_ESSENCE)obj; + + //$$$$$$$$$$$ ���ڼ�����Ʒû�ж��������Բ������� + + if(ess.id_sub_type == 300 || ess.id_sub_type == 293 || ess.id_sub_type == 76 || ess.id_sub_type == 291) + { + return -1; + } + size =(uint)(Marshal.SizeOf(typeof(item_data)) + Marshal.SizeOf(typeof(_item_content)) + Marshal.SizeOf(typeof(_weapon_essence))); + + // ����׶? + uint hole_num = 0; + if(normal_addon == GEN_ADDON_MODE.ADDON_LIST_DROP) + { + float[] drop_probability_socket = { ess.drop_probability_socket0, ess.drop_probability_socket1, ess.drop_probability_socket2 }; + hole_num = element_data.RandSelect_SPECIFIC_LOWER(drop_probability_socket.ToList(), SPECIFIC.SPECIFIC_RAND, LOWER.LOWER_TREND); //�׶�����Ŀ + } + else //if(normal_addon == element_data::ADDON_LIST_PRODUCE || normal_addon == element_data::ADDON_LIST_SPEC) + { + float[] make_probability_socket = { ess.make_probability_socket0, ess.make_probability_socket1, ess.make_probability_socket2 }; + hole_num = element_data.RandSelect_SPECIFIC_LOWER(make_probability_socket.ToList(), SPECIFIC.SPECIFIC_RAND, LOWER.LOWER_TREND); //�׶�����Ŀ + } + size += hole_num*sizeof(int); // size ����hole_num������type + + //����tag size + //ASSERT(tag_size >= sizeof(short)); + size += tag.size; + + + // ���addons + uint candidate_num = itemdataman.ELEMENTDATAMAN_MAX_NUM_ADDONS; + byte[] addon_buf = new byte[candidate_num*Marshal.SizeOf(typeof(itemdataman._addon))]; + float[] probability_addon_num = { ess.probability_addon_num0, ess.probability_addon_num1, ess.probability_addon_num2, ess.probability_addon_num3, ess.probability_addon_num4, ess.probability_addon_num5 }; + uint addon_num = element_data.RandSelect_SPECIFIC_LOWER(probability_addon_num.ToList(), SPECIFIC.SPECIFIC_RAND, LOWER.LOWER_TREND); //���Ա���Ŀ����Ŀ + + uint addon_size = 0; + if(ess.fixed_props!=0) + { + // this list store the addon id + // addon_size = generate_equipment_addon_buffer_2(DT_WEAPON_ESSENCE, (int*)&(ess->addons[0]), sizeof(int)+sizeof(float),32, addon_buf,addon_num); + List addon_list = ess.addons.Select(a => (int)a.id_addon).ToList(); + addon_size = itemdataman.generate_equipment_addon_buffer_2(DATA_TYPE.DT_WEAPON_ESSENCE, addon_list, addon_buf,0, ref addon_num); + } + else + { + if(addon_num > 0 || normal_addon == GEN_ADDON_MODE.ADDON_LIST_SPEC) + { + List unique_list = ess.uniques.Select(a => (int)a.id_unique).ToList(); + List produce_list = ess.rands.Select(a => (int)a.id_rand).ToList(); + List addons_list = ess.addons.Select(a => (int)a.id_addon).ToList(); + itemdataman.generate_template_addon( + DATA_TYPE.DT_WEAPON_ESSENCE,ess.probability_unique, + unique_list,produce_list,addons_list, + addon_buf,ref addon_num,ref addon_size,cls,normal_addon,sa_list); + } + else + { + if (normal_addon == GEN_ADDON_MODE.ADDON_LIST_SPEC) + { + addon_size = itemdataman.generate_spec_addon_buffer(DATA_TYPE.DT_WEAPON_ESSENCE,addon_buf,0,itemdataman.ELEMENTDATAMAN_MAX_NUM_ADDONS, ref addon_num,sa_list); + } + } + } + + size += addon_size; + + // allocate the buffer with exact length + // *data = (char *)abase::fastalloc(size); + + data = new byte[size]; + //byte[] buf = data; + int offset = 0; + + // *(unsigned int*)buf = id; buf += sizeof(unsigned int); //��Ʒ��ģ��ID + // *(size_t*)buf = 1; buf += sizeof(size_t); //��Ʒ������ + // *(size_t*)buf = ess->pile_num_max; buf += sizeof(size_t); //��Ʒ�Ķѵ����� + // *(int*)buf = ELEMENTDATAMAN_EQUIP_MASK_WEAPON|(addon_num?0x40000000:0); buf += sizeof(int); //��Ʒ�Ŀ�װ����־���̶�ֵ���� + // *(int*)buf = ess->proc_type; buf += sizeof(int); //��Ʒ�Ĵ�����ʽ + // *(int*)buf = DT_WEAPON_ESSENCE; buf += sizeof(int); //��Ʒ��Ӧ�����ID + WriteUInt(data, ref offset, id); + WriteUInt(data, ref offset, 1); + WriteInt(data, ref offset, ess.pile_num_max); + WriteInt(data, ref offset,(int)(itemdataman.ELEMENTDATAMAN_EQUIP_MASK_WEAPON|(addon_num>0?0x40000000:0))); + WriteUInt(data, ref offset, ess.proc_type); + WriteInt(data, ref offset, (int)DATA_TYPE.DT_WEAPON_ESSENCE); + // if(ess->has_guid == 1){ + // int g1,g2; + // get_item_guid(id,g1,g2); + // *(int*)buf = g1; buf += sizeof(int); //��Ʒ��Ӧ�����ID guid + // *(int*)buf = g2; buf += sizeof(int); //��Ʒ��Ӧ�����ID guid + // } + // else{ + // *(int*)buf = 0; buf += sizeof(int); //��Ʒ��Ӧ�����ID guid + // *(int*)buf = 0; buf += sizeof(int); //��Ʒ��Ӧ�����ID guid + // } + // *(int*)buf = ess->price; buf += sizeof(int); //��Ʒ�ļ۸� + // *(int*)buf = 0; buf += sizeof(int); //����ʱ�� + 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, ess.price); + WriteInt(data, ref offset, 0); + + // size_t* content_length = (size_t*)buf; buf += sizeof(size_t); //��סbuf��ָ�룬�Ժ����� + // char ** item_content = (char **)buf; buf += sizeof(char *); //��סbuf��ָ�룬�Ժ����� + // *item_content = buf; + // *content_length = (char *)(*data)+size-buf; + + // Then content_length store the length of the content. + // The item_content store the position of the start point of the content. + // Skip content_length and item_content pointer. So the remain is the content. + // After that we can calculate the content_length and item_content pointer. + 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); + + // prerequisition + // char * require_ptr = buf; + // *(short*)buf = ess->require_level; buf += sizeof(short); //prerequisition level + // *(short*)buf = ess->character_combo_id&0xFFFF; buf += sizeof(short); //prerequisition race + // *(short*)buf = ess->require_strength; buf += sizeof(short); //prerequisition strength + // *(short*)buf = ess->require_tili; buf += sizeof(short); //prerequisition val + // *(short*)buf = ess->require_agility; buf += sizeof(short); //prerequisition agility + // *(short*)buf = ess->require_energy; buf += sizeof(short); //prerequisition energy + int require_ptr = offset; + WriteShort(data, ref offset, (short)ess.require_level); + WriteShort(data, ref offset, (short)(ess.character_combo_id&0xFFFF)); + WriteShort(data, ref offset, (short)ess.require_strength); + WriteShort(data, ref offset, (short)ess.require_tili); + WriteShort(data, ref offset, (short)ess.require_agility); + WriteShort(data, ref offset, (short)ess.require_energy); + + + // int temp2 = element_data::RandNormal(ess->durability_min, ess->durability_max, cls,element_data::LOWER_TREND); + // int temp; + // if(normal_addon != element_data::ADDON_LIST_DROP || ess->proc_type & 0x1000) + // { + // temp = temp2; + // } + // else + // { + // temp = element_data::RandNormal(ess->durability_drop_min, ess->durability_drop_max, cls,element_data::UPPER_TREND); + // if(temp > temp2) temp = temp2; + // } + int temp2 = element_data.RandNormal_NORMAL_LOWER(ess.durability_min, ess.durability_max, NORMAL.NORMAL_RAND, LOWER.LOWER_TREND); + int temp = temp2; + if(normal_addon != GEN_ADDON_MODE.ADDON_LIST_DROP || (ess.proc_type & 0x1000) != 0) + { + temp = temp2; + } + else + { + temp = element_data.RandNormal_NORMAL_UPPER(ess.durability_drop_min, ess.durability_drop_max, NORMAL.NORMAL_RAND, UPPER.UPPER_TREND); + if(temp > temp2) temp = temp2; + } + + // *(int*)buf = temp; buf += sizeof(int); //prerequisition durability + // *(int*)buf = temp2; buf += sizeof(int); //prerequisition max_durability + WriteInt(data, ref offset, temp); // durability + WriteInt(data, ref offset, temp2); // max_durability + + // //���������߱�ǩע���ǩ���ڱ����С�ͱ�������֮�� + // *(short*)buf = sizeof(_weapon_essence); buf += sizeof(short); //װ�������С���ֽڣ? + // memcpy(buf,tag,tag_size); + // buf += tag_size; + WriteShort(data, ref offset, (short)Marshal.SizeOf(typeof(_weapon_essence))); + WriteTag(data, ref offset, tag); + + //essence //char ����[]; //ÿ�ֲ�ͬװ���ı���ṹ��? + // char * essence_ptr = buf; + int essence_ptr = offset; + // switch(ess->short_range_mode) + // { + // default: + // case 0: *(short*)buf = 1; break; //Զ�� + // case 1: *(short*)buf = 0; break; //���� + // case 2: *(short*)buf = 2; break; //�̿ͽ��� + // } + // buf += sizeof(short); //������? ��Ӧģ����Ľ���Զ�̱�? + switch(ess.short_range_mode) + { + default: + case 0: + WriteShort(data, ref offset, (short)1); + break; + case 1: + WriteShort(data, ref offset, (short)0); + break; + case 2: + WriteShort(data, ref offset, (short)2); + break; + } + // *(short*)buf = 0; buf += sizeof(short); //���ֵ����ʹ�? + // *(int*)buf = ess->id_major_type; buf += sizeof(int); //�������� ��Ӧģ����Ĵ��? ���絶�� ������ + // *(int*)buf = ess->level; buf += sizeof(int); //�������� ijЩ������Ҫ�������� + // *(int*)buf = ess->require_projectile; buf += sizeof(int); //��Ҫ��ҩ������ + // *(int*)buf = ess->damage_low; buf += sizeof(int); //����������С��ֵ + // *(int*)buf = element_data::RandNormal(ess->damage_high_min, ess->damage_high_max, cls,element_data::LOWER_TREND); buf += sizeof(int); //������������ֵ + // *(int*)buf = ess->magic_daage_low; buf += sizeof(int); //ħ���������? + // *(int*)buf = element_data::RandNormal(ess->magic_damage_high_min, ess->magic_damage_high_max, cls,element_data::LOWER_TREND); buf += sizeof(int); //ħ������ + WriteShort(data, ref offset, (short)0); + WriteUInt(data, ref offset, ess.id_major_type); + WriteInt(data, ref offset, ess.level); + WriteUInt(data, ref offset, ess.require_projectile); + WriteInt(data, ref offset, ess.damage_low); + WriteInt(data, ref offset, element_data.RandNormal_NORMAL_LOWER(ess.damage_high_min, ess.damage_high_max, NORMAL.NORMAL_RAND, LOWER.LOWER_TREND)); + WriteInt(data, ref offset, ess.magic_damage_low); + WriteInt(data, ref offset, element_data.RandNormal_NORMAL_LOWER(ess.magic_damage_high_min, ess.magic_damage_high_max, NORMAL.NORMAL_RAND, LOWER.LOWER_TREND)); + + // WEAPON_SUB_TYPE * subtype = (WEAPON_SUB_TYPE * )get_data_ptr(ess->id_sub_type, ID_SPACE_ESSENCE, datatype); + // if(subtype == NULL || datatype != DT_WEAPON_SUB_TYPE) + // { + // // assert(false); + // *(int*)buf = 0; buf += sizeof(int); + // } + // else + // { + // unsigned int index = element_data::RandSelect(&(subtype->probability_fastest), sizeof(float), 5, cls,element_data::MIDDLE_TREND); + // *(int*)buf = (int)(subtype->attack_speed*20.f + 0.1f) + (index - 2); buf += sizeof(int); //ģ���е���0.05���? + // } + WEAPON_SUB_TYPE subtype = new WEAPON_SUB_TYPE(); + object sub_type_temp = itemdataman._edm.get_data_ptr(ess.id_sub_type, ID_SPACE.ID_SPACE_ESSENCE, ref datatype); + if(sub_type_temp == null || datatype != DATA_TYPE.DT_WEAPON_SUB_TYPE) + { + WriteInt(data, ref offset, 0); + } + else + { + subtype = (WEAPON_SUB_TYPE)sub_type_temp; + float[] probability_attack_speed = { subtype.probability_fastest, subtype.probability_fast, subtype.probability_normal, subtype.probability_slow, subtype.probability_slowest }; + int index = element_data.RandSelect_SPECIFIC_MIDDLE(probability_attack_speed.ToList(), SPECIFIC.SPECIFIC_RAND, MIDDLE.MIDDLE_TREND); + WriteInt(data, ref offset, (int)(subtype.attack_speed*20f + 0.1f) + (index - 2)); + } + + // *(float*)buf = ess->attack_range; buf += sizeof(float); + // *(float*)buf = subtype->attack_short_range; buf += sizeof(float); + // *(short*)buf = hole_num; buf += sizeof(short); //�׶�����Ŀ + // *(short*)buf = 0; buf += sizeof(short); //�׶��������������� + // for(i=0; i>13)*sizeof(int)+sizeof(int); + // } + addon_data addon_data = new addon_data(); + prerequisition prerequisition = new prerequisition(); + for(i = 0; i < addon_num; i++) + { + int addon_id; + ReadInt(addon_buf, ref addon_sld, out addon_id); + ReadAddonData(addon_buf, ref addon_sld, out addon_data); + ReadPrerequisition(addon_buf, ref require_ptr, out prerequisition); + itemdataman.addon_update_ess_data(addon_data, essence_ptr, Marshal.SizeOf(typeof(_weapon_essence)), prerequisition); + addon_sld += ((addon_id & 0x6000)>>13)*sizeof(int)+sizeof(int); + } + + // memcpy(buf, addon_buf, addon_size); + // set_to_classid(DT_WEAPON_ESSENCE, (item_data*)(*data), -1); + itemdataman.update_require_data(prerequisition); + WriteAddonData(data, ref offset, addon_data); + itemdataman.set_to_classid(DATA_TYPE.DT_WEAPON_ESSENCE, data, -1); + return 0; + } + + private static void WriteUInt(byte[] buf, ref int offset, uint value) + { + Array.Copy(BitConverter.GetBytes(value), 0, buf, offset, 4); + offset = offset + 4; + } + private static void WriteInt(byte[] buf, ref int offset, int value) + { + Array.Copy(BitConverter.GetBytes(value), 0, buf, offset, 4); + offset = offset + 4; + } + private static void WriteShort(byte[] buf, ref int offset, short value) + { + Array.Copy(BitConverter.GetBytes(value), 0, buf, offset, 2); + offset = offset + 2; + } + private static void WriteFloat(byte[] buf, ref int offset, float value) + { + Array.Copy(BitConverter.GetBytes(value), 0, buf, offset, 4); + offset = offset + 4; + } + private static void WriteTag(byte[] buf, ref int offset, item_tag_t tag) + { + Array.Copy(BitConverter.GetBytes(tag.type), 0, buf, offset, 1); + offset = offset + 1; + Array.Copy(BitConverter.GetBytes(tag.size), 0, buf, offset, 1); + offset = offset + 1; + } + private static void WriteAddonData(byte[] buf, ref int offset, addon_data value) + { + WriteInt(buf, ref offset, value.id); + for(int i = 0; i < 3; i++) + { + WriteInt(buf, ref offset, value.arg[i]); + } + } + private static void ReadInt(byte[] buf, ref int offset, out int value) + { + value = BitConverter.ToInt32(buf, offset); + offset = offset + 4; + } + private static void ReadAddonData(byte[] buf, ref int offset, out addon_data value) + { + value = new addon_data(); + value.id = BitConverter.ToInt32(buf, offset); + offset = offset + 4; + value.arg = new int[3]; + for(int i = 0; i < 3; i++) + { + value.arg[i] = BitConverter.ToInt32(buf, offset); + offset = offset + 4; + } + } + private static void ReadPrerequisition(byte[] buf, ref int offset, out prerequisition value) + { + value = new prerequisition(); + value.level = BitConverter.ToInt16(buf, offset); + offset = offset + 2; + value.race = BitConverter.ToInt16(buf, offset); + offset = offset + 2; + value.strength = BitConverter.ToInt16(buf, offset); + offset = offset + 2; + } +} \ No newline at end of file diff --git a/Assets/PerfectWorld/Scripts/Common/DataProcess/generate_item_temp.cs.meta b/Assets/PerfectWorld/Scripts/Common/DataProcess/generate_item_temp.cs.meta new file mode 100644 index 0000000000..872a95ed0c --- /dev/null +++ b/Assets/PerfectWorld/Scripts/Common/DataProcess/generate_item_temp.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: ef4cf49bb69644c19a3a3904a40db7db \ No newline at end of file diff --git a/Assets/PerfectWorld/Scripts/Common/DataProcess/itemdataman.cs b/Assets/PerfectWorld/Scripts/Common/DataProcess/itemdataman.cs new file mode 100644 index 0000000000..2ca3acce27 --- /dev/null +++ b/Assets/PerfectWorld/Scripts/Common/DataProcess/itemdataman.cs @@ -0,0 +1,943 @@ +using BrewMonster.ELEMENT_DATA; +using BrewMonster.Network; +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using UnityEngine; +using ModelRenderer.Scripts.GameData; +namespace BrewMonster +{ + + public struct LOCATION + { + public DATA_TYPE type; + public object pos; + }; + + namespace abase + { + public static class abase + { + const int RAND_MAX = 0x7fff; + public static int Rand(int lower, int upper) + { + if (upper == lower) + return lower; + else + return new System.Random().Next(lower, upper); + } + + public static float Rand(float lower, float upper) + { + float rng = (float)new System.Random().NextDouble(); + return lower + (upper - lower) * rng / (float)RAND_MAX; + } + + public static int RandNormal(int lower, int upper) { return Rand(lower, upper); } + public static float RandUniform() { return Rand(0f, 1f); } + + public static int RandSelect(List option) + { + int num = option.Count; + float op = RandUniform(); + for (int i = 0; i IndexList; + public int IdxCap; + public int IdxIndex; + public List RandList; + public int RandCap; + public int RandIndex; + //SpecRand() :IndexList(0),IdxCap(0),IdxIndex(0),RandList(0),RandCap(0),RandIndex(0) { } + + public SpecRand() { + IndexList = new List(); + IdxCap = 0; + IdxIndex = 0; + RandList = new List(); + RandCap = 0; + RandIndex = 0; + + } + public int RandSelect(int num) + { + if (IndexList == null || IndexList.Count == 0) return 0; + if (IdxIndex >= IdxCap) return 0; + if (num <= 0) return 0; + int idx = IndexList[IdxIndex++]; + if (idx >= num) idx = num - 1; + return idx; + } + + public int RandNormal(int lower, int upper) + { + if (RandList == null || RandList.Count == 0) return lower; + if (RandIndex >= RandCap) return lower; + float r = RandList[RandIndex++]; + if (r < 0) r = 0f; + if (r >= 1.0f) r = 0.9999999f; + return (int)((upper - lower + 1) * r + lower); + } + + public float Rand(float lower, float upper) + { + if (RandList == null || RandList.Count == 0) return lower; + if (RandIndex >= RandCap) return lower; + float r = RandList[RandIndex++]; + if (r < 0) r = 0f; + if (r >= 1.0f) r = 0.9999999f; + return (float)((upper - lower) * r + lower); + } + } + public class SpecCls + { + SpecRand imp; + public SpecCls(SpecRand tmp) { + imp = tmp; + } + //Could be wrong, need to check + public int RandSelect(List option) + { + int num = option.Count; + if(imp != null) return imp.RandSelect(num); + return 0; + } + + public int RandNormal(int lower, int upper) + { + if (imp != null) return imp.RandNormal(lower, upper); + return lower; + } + + public float Rand(float lower, float upper) + { + if (imp != null) return imp.Rand(lower, upper); + return lower; + } + } + public static class element_data + { + public static int RandNormal(int lower, int upper, TCls c) where TCls : SpecCls + { + return c.RandNormal(lower, upper); + } + public static int RandSelect(List option, TCls c) where TCls : SpecCls + { + return c.RandSelect(option); + } + public static float Rand(float lower, float upper, TCls c) where TCls : SpecCls + { + return c.Rand(lower, upper); + } + public static int RandSelect_NORMAL_LOWER(List option, NORMAL normalType, LOWER lowerTrend) + { + return abase.abase.RandSelect(option); + } + public static int RandSelect_NORMAL_MIDDLE(List option, NORMAL normalType, MIDDLE middleTrend) + { + return abase.abase.RandSelect(option); + } + public static uint RandSelect_SPECIFIC_LOWER(List option, SPECIFIC specificType, LOWER lowerTrend) + { + return 0; + } + public static int RandSelect_SPECIFIC_MIDDLE(List option, SPECIFIC specificType, MIDDLE middleTrend) + { + return option.Count / 2; + } + public static int RandNormal_NORMAL_LOWER(int lower, int upper, NORMAL normalType, LOWER lowerTrend) + { + return abase.abase.RandNormal(lower, upper); + } + public static int RandNormal_NORMAL_UPPER(int lower, int upper, NORMAL normalType, UPPER upperTrend) + { + return abase.abase.RandNormal(lower, upper); + } + public static int RandNormal_NORMAL_MIDDLE(int lower, int upper, NORMAL normalType, MIDDLE middleTrend) + { + return abase.abase.RandNormal(lower, upper); + } + public static int RandNormal_NORMAL_ANY(int lower, int upper, NORMAL normalType, ANY anyTrend) + { + return abase.abase.RandNormal(lower, upper); + } + public static int RandNormal_SPECIFIC_LOWER(int lower, int upper, SPECIFIC specificType, LOWER lowerTrend) + { + return lower; + } + public static int RandNormal_SPECIFIC_UPPER(int lower, int upper, SPECIFIC specificType, UPPER upperTrend) + { + return upper; + } + public static int RandNormal_SPECIFIC_MIDDLE(int lower, int upper, SPECIFIC specificType, MIDDLE middleTrend) + { + return (upper + lower) / 2; + } + public static int RandNormal_SPECIFIC_ANY(int lower, int upper, SPECIFIC specificType, ANY anyTrend) + { + return abase.abase.RandNormal(lower, upper); + } + public static float Rand_NORMAL_LOWER(float lower, float upper, NORMAL normalType, LOWER lowerTrend) + { + return abase.abase.Rand(lower, upper); + } + public static float Rand_NORMAL_MIDDLE(float lower, float upper, NORMAL normalType, MIDDLE middleTrend) + { + return abase.abase.Rand(lower, upper); + } + public static float Rand_NORMAL_UPPER(float lower, float upper, NORMAL normalType, UPPER upperTrend) + { + return abase.abase.Rand(lower, upper); + } + public static float Rand_NORMAL_ANY(float lower, float upper, NORMAL normalType, ANY anyTrend) + { + return abase.abase.Rand(lower, upper); + } + public static float Rand_SPECIFIC_LOWER(float lower, float upper, SPECIFIC specificType, LOWER lowerTrend) + { + return lower; + } + public static float Rand_SPECIFIC_MIDDLE(float lower, float upper, SPECIFIC specificType, MIDDLE middleTrend) + { + return (upper + lower) / 2; + } + public static float Rand_SPECIFIC_UPPER(float lower, float upper, SPECIFIC specificType, UPPER upperTrend) + { + return upper; + } + public static float Rand_SPECIFIC_ANY(float lower, float upper, SPECIFIC specificType, ANY anyTrend) + { + return abase.abase.Rand(lower, upper); + } + } + public enum GEN_ADDON_MODE + { + ADDON_LIST_SHOP, + ADDON_LIST_DROP, + ADDON_LIST_PRODUCE, + ADDON_LIST_SPEC, + }; + public enum ITEM_MAKE_TAG + { + IMT_NULL, + IMT_CREATE, + IMT_DROP, + IMT_SHOP, + IMT_PRODUCE, + IMT_SIGN, //װ����ǩ�� + }; + //#pragma pack(1) + public class item_tag_t + { + public char type; + public char size; + public item_tag_t(char type, char size) + { + this.type = type; + this.size = size; + } + }; + //#pragma pack() + + };// name space element_data + public struct guid_t + { + public int guid1; + public int guid2; + } + public struct item_data + { + public uint type; //��Ʒ��ģ��ID + public int count; //��Ʒ������ + public int pile_limit; //��Ʒ�Ķѵ����� + public int equip_mask; //��Ʒ�Ŀ�װ����־��0x8000��ʾ����Ƕ�� + public int proc_type; //��Ʒ�Ĵ�����ʽ + public int classid; //��Ʒ��Ӧ�����ID + public guid_t guid; //��Ʒ��GUID + public int price; //��Ʒ�ļ۸� + public int expire_date; //����ʱ�� + public int content_length; + public byte item_content; + }; +// #pragma pack(1) + public struct _item_content + { + public prerequisition preq; + public short sizeofessence; //װ�������С���ֽڣ�; + // essence //char ����[]; //ÿ�ֲ�ͬװ���ı���ṹ��ͬ + public int num_hole; //�׶�����Ŀ��������; + // int hole_type[MAX_NUM_HOLES]; //�׶���Ƕ���������[�׶�����Ŀ]; //����׶���ĿΪ0,��������� + public int num_addon; //���Ա���Ŀ����Ŀ��������; + // _addon ad[MAX_NUM_ADDONS]; //[���Ա���Ŀ����Ŀ]; + }; +//#pragma pack() + + public struct addon_data + { + public int id; + public int[] arg; + public addon_data(int id) { + this.id = id; + arg = new int[3]; + } + }; + public struct prerequisition + { + public short level; + public short race; + public short strength; + public short vitality; + public short agility; + public short energy; + public int durability; + public int max_durability; + }; + struct _weapon_essence + { + public enum WEAPON_TYPE + { + WEAPON_TYPE_MELEE = 0, + WEAPON_TYPE_RANGE = 1, + WEAPON_TYPE_MELEE_ASN = 2, //�̿�ʹ�õĽ���������������Ӱ���﹥�⣬�����������ͬ + }; + + public short weapon_type; //������� ��Ӧģ����Ľ���Զ�̱�־ + public short weapon_delay; //�����Ĺ����ӳ�ʱ�䣬��50msΪ��λ + public int weapon_class; //�������� ��Ӧģ����Ĵ��� ���絶�� ������ + public int weapon_level; //�������� ijЩ������Ҫ�������� + public int require_projectile; //��Ҫ��ҩ������ + public int damage_low; //����������С��ֵ + public int damage_high; //������������ֵ + public int magic_damage_low; //ħ������ + public int magic_damage_high; //ħ������ + public int attack_speed; + public float attack_range; + public float attack_short_range; + }; + public static class itemdataman + { +#region const + public const uint ELEMENTDATAMAN_MAX_NUM_ADDON_PARAM = 3; + public struct _addon //������Ŀ + { + public int addon_type; + public int[] addon_arg; // 0 ~ 3 ��Ŀ�� ((type & 0x6000)>>13) + public _addon(int addon_type) { + this.addon_type = addon_type; + addon_arg = new int[ELEMENTDATAMAN_MAX_NUM_ADDON_PARAM]; + } + }; + #region Equip Mask + public const uint ELEMENTDATAMAN_MAX_NUM_HOLES = 5; + public const uint ELEMENTDATAMAN_MAX_NUM_ADDONS = 32; + public const uint ELEMENTDATAMAN_EQUIP_MASK_WEAPON = 0x0001; + public const uint ELEMENTDATAMAN_EQUIP_MASK_HEAD = 0x0002; + public const uint ELEMENTDATAMAN_EQUIP_MASK_NECK = 0x0004; + public const uint ELEMENTDATAMAN_EQUIP_MASK_SHOULDER = 0x0008; + public const uint ELEMENTDATAMAN_EQUIP_MASK_BODY = 0x0010; + public const uint ELEMENTDATAMAN_EQUIP_MASK_WAIST = 0x0020; + public const uint ELEMENTDATAMAN_EQUIP_MASK_LEG = 0x0040; + public const uint ELEMENTDATAMAN_EQUIP_MASK_FOOT = 0x0080; + public const uint ELEMENTDATAMAN_EQUIP_MASK_WRIST = 0x0100; + public const uint ELEMENTDATAMAN_EQUIP_MASK_FINGER1 = 0x0200; + public const uint ELEMENTDATAMAN_EQUIP_MASK_FINGER2 = 0x0400; + public const uint ELEMENTDATAMAN_EQUIP_MASK_PROJECTILE = 0x0800; + public const uint ELEMENTDATAMAN_EQUIP_MASK_FLYSWORD = 0x1000; + public const uint ELEMENTDATAMAN_EQUIP_MASK_DAMAGERUNE = 0x20000; + public const uint ELEMENTDATAMAN_EQUIP_MASK_BIBLE = 0x40000; + public const uint ELEMENTDATAMAN_EQUIP_MASK_SPEAKER = 0x80000; + public const uint ELEMENTDATAMAN_EQUIP_MASK_AUTO_HP = 0x100000; + public const uint ELEMENTDATAMAN_EQUIP_MASK_AUTO_MP = 0x200000; + public const uint ELEMENTDATAMAN_EQUIP_MASK_ELF = 0x800000; //lgc + public const uint ELEMENTDATAMAN_EQUIP_MASK_STALLCARD = 0x1000000; + public const uint ELEMENTDATAMAN_EQUIP_MASK_FORCE_TICKET = 0x4000000; + public const uint ELEMENTDATAMAN_EQUIP_MASK_DYNSKILL_ALL = 0x18000000; public const uint ELEMENTDATAMAN_EQUIP_MASK_HAS_ADDON = 0x40000000; + public const uint ELEMENTDATAMAN_EQUIP_MASK_EXTEND64 = 0x80000000; + public const uint ELEMENTDATAMAN_EQUIP_MASK_HIGH = 0xC0000000; + #endregion +#endregion + public static Dictionary sale_item_id_index_map; + public static elementdataman _edm; + public static int load_data(string pathname, bool disable_bind2) + { + _edm = ElementDataManProvider.GetElementDataMan(); + generate_item_for_sell(disable_bind2); + return 0; + // if(await _edm.load_data(pathname) == 0) + // { + // generate_item_for_sell(disable_bind2); + // return 0; + // } + // else + // return -1; + } + + public static int generate_item_for_sell(bool disable_bind2) + { + //#define CASE_CLEAR_PROC_TYPE(ESSENCE) case DT_##ESSENCE: \ + // {\ + // DATA_TYPE dt2;\ + // ESSENCE* ess = (ESSENCE*)get_data_ptr(id, ID_SPACE_ESSENCE, dt2); \ + // if (dt2 == datatype && ess && disable_bind2) ess->proc_type &= ~(0x0040);\ + // } + + byte[] item; + uint size; + int ret; + + DATA_TYPE datatype = DATA_TYPE.DT_INVALID; + item_tag_t tag = new item_tag_t((char)ITEM_MAKE_TAG.IMT_SHOP, (char)'0'); + //uint id = _edm.get_first_data_id(ID_SPACE.ID_SPACE_ESSENCE,ref datatype); + + + for (uint id = 0; id < _edm.essence_id_data_type_map.Count; id++) + { + _edm.essence_id_data_type_map.TryGetValue(id, out datatype); + switch (datatype) + { + case (DATA_TYPE.DT_WEAPON_ESSENCE): + generate_item_temp.generate_weapon(id,ID_SPACE.ID_SPACE_ESSENCE, + out item,out size,SPECIFIC.SPECIFIC_RAND,GEN_ADDON_MODE.ADDON_LIST_SHOP,tag); + BMLogger.Log("generate_item_for_sell: generate_weapon: " + id); + break; + default: + BMLogger.Log("generate_item_for_sell: default: " + id); + ret = -1; + break; + } + } + + // CASE_CLEAR_PROC_TYPE(ARMOR_ESSENCE) + + // ret = generate_armor(id, ID_SPACE_ESSENCE, (char**)&item, size, element_data::SPECIFIC(0), element_data::ADDON_LIST_SHOP, &tag, sizeof(tag)); + // break; + + // CASE_CLEAR_PROC_TYPE(PROJECTILE_ESSENCE) + + // ret = generate_projectile(id, ID_SPACE_ESSENCE, (char**)&item, size, element_data::SPECIFIC(0)); + // break; + + + // case DT_QUIVER_ESSENCE: + // ret = generate_quiver_for_sell(id, ID_SPACE_ESSENCE, (char**)&item, size, element_data::SPECIFIC(0)); + // break; + + // CASE_CLEAR_PROC_TYPE(STONE_ESSENCE) + + // ret = generate_stone(id, ID_SPACE_ESSENCE, (char**)&item, size, element_data::SPECIFIC(0)); + // break; + + // CASE_CLEAR_PROC_TYPE(DECORATION_ESSENCE) + + // ret = generate_decoration(id, ID_SPACE_ESSENCE, (char**)&item, size, element_data::SPECIFIC(0), element_data::ADDON_LIST_SHOP, &tag, sizeof(tag)); + // break; + + // CASE_CLEAR_PROC_TYPE(MEDICINE_ESSENCE) + + // ret = generate_medicine(id, ID_SPACE_ESSENCE, (char**)&item, size, element_data::SPECIFIC(0)); + // break; + + // CASE_CLEAR_PROC_TYPE(WINGMANWING_ESSENCE) + + // ret = generate_wingmanwing(id, ID_SPACE_ESSENCE, (char**)&item, size, element_data::SPECIFIC(0), &tag, sizeof(tag)); + // break; + + // CASE_CLEAR_PROC_TYPE(MATERIAL_ESSENCE) + + // ret = generate_material(id, ID_SPACE_ESSENCE, (char**)&item, size, (MATERIAL_ESSENCE*)0, DT_MATERIAL_ESSENCE); + // break; + + // CASE_CLEAR_PROC_TYPE(DYE_TICKET_ESSENCE) + + // ret = generate_material(id, ID_SPACE_ESSENCE, (char**)&item, size, (DYE_TICKET_ESSENCE*)0, DT_DYE_TICKET_ESSENCE); + // break; + + // CASE_CLEAR_PROC_TYPE(FIREWORKS_ESSENCE) + + // ret = generate_fireworks(id, ID_SPACE_ESSENCE, (char**)&item, size, element_data::SPECIFIC(0)); + // break; + + // CASE_CLEAR_PROC_TYPE(WAR_TANKCALLIN_ESSENCE) + + // ret = generate_tankcallin(id, ID_SPACE_ESSENCE, (char**)&item, size, element_data::SPECIFIC(0)); + // break; + + // CASE_CLEAR_PROC_TYPE(SKILLMATTER_ESSENCE) + + // ret = generate_skillmatter(id, ID_SPACE_ESSENCE, (char**)&item, size, element_data::SPECIFIC(0)); + // break; + + // CASE_CLEAR_PROC_TYPE(DAMAGERUNE_ESSENCE) + + // ret = generate_damagerune(id, ID_SPACE_ESSENCE, (char**)&item, size, element_data::SPECIFIC(0)); + // break; + + // CASE_CLEAR_PROC_TYPE(ARMORRUNE_ESSENCE) + + // ret = generate_armorrune(id, ID_SPACE_ESSENCE, (char**)&item, size, element_data::SPECIFIC(0)); + // break; + + // CASE_CLEAR_PROC_TYPE(SKILLTOME_ESSENCE) + + // ret = generate_skilltome(id, ID_SPACE_ESSENCE, (char**)&item, size, element_data::SPECIFIC(0)); + // break; + + // CASE_CLEAR_PROC_TYPE(FLYSWORD_ESSENCE) + + // ret = generate_flysword(id, ID_SPACE_ESSENCE, (char**)&item, size, element_data::SPECIFIC(0), &tag, sizeof(tag)); + // break; + + // CASE_CLEAR_PROC_TYPE(TOWNSCROLL_ESSENCE) + + // ret = generate_townscroll(id, ID_SPACE_ESSENCE, (char**)&item, size, element_data::SPECIFIC(0)); + // break; + + // CASE_CLEAR_PROC_TYPE(UNIONSCROLL_ESSENCE) + + // ret = generate_unionscroll(id, ID_SPACE_ESSENCE, (char**)&item, size, element_data::SPECIFIC(0)); + // break; + + // CASE_CLEAR_PROC_TYPE(REVIVESCROLL_ESSENCE) + + // ret = generate_revivescroll(id, ID_SPACE_ESSENCE, (char**)&item, size, element_data::SPECIFIC(0)); + // break; + + // CASE_CLEAR_PROC_TYPE(ELEMENT_ESSENCE) + + // ret = generate_element(id, ID_SPACE_ESSENCE, (char**)&item, size, element_data::SPECIFIC(0)); + // break; + + // CASE_CLEAR_PROC_TYPE(TASKMATTER_ESSENCE) + + // ret = generate_taskmatter(id, ID_SPACE_ESSENCE, (char**)&item, size, element_data::SPECIFIC(0)); + // break; + + // CASE_CLEAR_PROC_TYPE(TOSSMATTER_ESSENCE) + + // ret = generate_tossmatter(id, ID_SPACE_ESSENCE, (char**)&item, size, element_data::SPECIFIC(0)); + // break; + + // CASE_CLEAR_PROC_TYPE(TASKDICE_ESSENCE) + + // ret = generate_taskdice(id, ID_SPACE_ESSENCE, (char**)&item, size, element_data::SPECIFIC(0)); + // break; + + // CASE_CLEAR_PROC_TYPE(TASKNORMALMATTER_ESSENCE) + + // ret = generate_tasknormalmatter(id, ID_SPACE_ESSENCE, (char**)&item, size, element_data::SPECIFIC(0)); + // break; + + // CASE_CLEAR_PROC_TYPE(FASHION_ESSENCE) + + // ret = generate_fashion_item(id, ID_SPACE_ESSENCE, (char**)&item, size, element_data::SPECIFIC(0), &tag, sizeof(tag)); + // break; + + // CASE_CLEAR_PROC_TYPE(FACEPILL_ESSENCE) + + // ret = generate_facepill(id, ID_SPACE_ESSENCE, (char**)&item, size, element_data::SPECIFIC(0)); + // break; + + // CASE_CLEAR_PROC_TYPE(FACETICKET_ESSENCE) + + // ret = generate_faceticket(id, ID_SPACE_ESSENCE, (char**)&item, size, element_data::SPECIFIC(0)); + // break; + + // CASE_CLEAR_PROC_TYPE(GM_GENERATOR_ESSENCE) + + // ret = generate_gm_generator(id, ID_SPACE_ESSENCE, (char**)&item, size, element_data::SPECIFIC(0)); + // break; + + // CASE_CLEAR_PROC_TYPE(PET_EGG_ESSENCE) + + // ret = generate_pet_egg(id, ID_SPACE_ESSENCE, (char**)&item, size, element_data::SPECIFIC(0)); + // break; + + // CASE_CLEAR_PROC_TYPE(PET_FOOD_ESSENCE) + + // ret = generate_pet_food(id, ID_SPACE_ESSENCE, (char**)&item, size, element_data::SPECIFIC(0)); + // break; + + // CASE_CLEAR_PROC_TYPE(REFINE_TICKET_ESSENCE) + + // ret = generate_refine_ticket(id, ID_SPACE_ESSENCE, (char**)&item, size, element_data::SPECIFIC(0)); + // break; + + // CASE_CLEAR_PROC_TYPE(BIBLE_ESSENCE) + + // ret = generate_bible(id, ID_SPACE_ESSENCE, (char**)&item, size, element_data::SPECIFIC(0)); + // break; + + // CASE_CLEAR_PROC_TYPE(SPEAKER_ESSENCE) + + // ret = generate_speaker(id, ID_SPACE_ESSENCE, (char**)&item, size, element_data::SPECIFIC(0)); + // break; + + // CASE_CLEAR_PROC_TYPE(AUTOHP_ESSENCE) + + // ret = generate_hp_amulet(id, ID_SPACE_ESSENCE, (char**)&item, size, element_data::SPECIFIC(0)); + // break; + + // CASE_CLEAR_PROC_TYPE(AUTOMP_ESSENCE) + + // ret = generate_mp_amulet(id, ID_SPACE_ESSENCE, (char**)&item, size, element_data::SPECIFIC(0)); + // break; + + // CASE_CLEAR_PROC_TYPE(DOUBLE_EXP_ESSENCE) + + // ret = generate_double_exp(id, ID_SPACE_ESSENCE, (char**)&item, size, element_data::SPECIFIC(0)); + // break; + + // CASE_CLEAR_PROC_TYPE(TRANSMITSCROLL_ESSENCE) + + // ret = generate_transmitscroll(id, ID_SPACE_ESSENCE, (char**)&item, size, element_data::SPECIFIC(0)); + // break; + + // CASE_CLEAR_PROC_TYPE(GOBLIN_ESSENCE) + + // ret = generate_elf(id, ID_SPACE_ESSENCE, (char**)&item, size); + // break; + + // CASE_CLEAR_PROC_TYPE(GOBLIN_EQUIP_ESSENCE) + + // ret = generate_elf_equip(id, ID_SPACE_ESSENCE, (char**)&item, size); + // break; + + // CASE_CLEAR_PROC_TYPE(GOBLIN_EXPPILL_ESSENCE) + + // ret = generate_elf_exppill(id, ID_SPACE_ESSENCE, (char**)&item, size); + // break; + + // CASE_CLEAR_PROC_TYPE(SELL_CERTIFICATE_ESSENCE) + + // ret = generate_stallcard(id, ID_SPACE_ESSENCE, (char**)&item, size); + // break; + + // CASE_CLEAR_PROC_TYPE(TARGET_ITEM_ESSENCE) + + // ret = generate_skilltrigger2(id, ID_SPACE_ESSENCE, (char**)&item, size); + // break; + + // CASE_CLEAR_PROC_TYPE(LOOK_INFO_ESSENCE) + + // ret = generate_queryotherproperty(id, ID_SPACE_ESSENCE, (char**)&item, size); + // break; + + // CASE_CLEAR_PROC_TYPE(INC_SKILL_ABILITY_ESSENCE) + + // ret = generate_incskillability(id, ID_SPACE_ESSENCE, (char**)&item, size); + // break; + + // CASE_CLEAR_PROC_TYPE(WEDDING_BOOKCARD_ESSENCE) + + // ret = generate_wedding_bookcard(id, ID_SPACE_ESSENCE, (char**)&item, size); + // break; + + // CASE_CLEAR_PROC_TYPE(WEDDING_INVITECARD_ESSENCE) + + // ret = generate_wedding_invitecard(id, ID_SPACE_ESSENCE, (char**)&item, size); + // break; + + // CASE_CLEAR_PROC_TYPE(SHARPENER_ESSENCE) + + // ret = generate_sharpener(id, ID_SPACE_ESSENCE, (char**)&item, size); + // break; + + // CASE_CLEAR_PROC_TYPE(FACTION_MATERIAL_ESSENCE) + + // ret = generate_factionmaterial(id, ID_SPACE_ESSENCE, (char**)&item, size); + // break; + + // CASE_CLEAR_PROC_TYPE(CONGREGATE_ESSENCE) + + // ret = generate_congregate(id, ID_SPACE_ESSENCE, (char**)&item, size); + // break; + + // CASE_CLEAR_PROC_TYPE(FORCE_TOKEN_ESSENCE) + + // ret = generate_force_ticket(id, ID_SPACE_ESSENCE, (char**)&item, size); + // break; + + // CASE_CLEAR_PROC_TYPE(DYNSKILLEQUIP_ESSENCE) + + // ret = generate_dynskillequip(id, ID_SPACE_ESSENCE, (char**)&item, size); + // break; + + // CASE_CLEAR_PROC_TYPE(MONEY_CONVERTIBLE_ESSENCE) + + // ret = generate_moneyconvertibleitem(id, ID_SPACE_ESSENCE, (char**)&item, size); + // break; + + // CASE_CLEAR_PROC_TYPE(MONSTER_SPIRIT_ESSENCE) + + // ret = generate_soul(id, ID_SPACE_ESSENCE, (char**)&item, size); + // break; + + // CASE_CLEAR_PROC_TYPE(POKER_ESSENCE) + + // ret = generate_generalcard(id, ID_SPACE_ESSENCE, (char**)&item, size, element_data::SPECIFIC(0)); + // break; + + // CASE_CLEAR_PROC_TYPE(POKER_DICE_ESSENCE) + + // ret = generate_generalcard_dice(id, ID_SPACE_ESSENCE, (char**)&item, size); + // break; + + // CASE_CLEAR_PROC_TYPE(SHOP_TOKEN_ESSENCE) + + // ret = generate_shoptoken(id, ID_SPACE_ESSENCE, (char**)&item, size); + // break; + + // CASE_CLEAR_PROC_TYPE(UNIVERSAL_TOKEN_ESSENCE) + + // ret = generate_universal_token(id, ID_SPACE_ESSENCE, (char**)&item, size); + // break; + + // case DT_MONSTER_ESSENCE: + // case DT_NPC_ESSENCE: + // default: + // continue; + // } + + // if (ret == 0 && size != 0) + // { + // sale_item_ptr_array.push_back(item); + // sale_item_size_array.push_back(size); + // LOCATION loc; + // loc.type = datatype; + // loc.pos = sale_item_ptr_array.size() - 1; + // sale_item_id_index_map[id] = loc; + // } + // } + return 0; + } + + + public static object get_item_for_sell(uint id) + { + uint pos; + if (sale_item_id_index_map.TryGetValue(id, out var itr)) + { + return itr; + } + return null; + } + + public static uint generate_equipment_addon_buffer_2 + (DATA_TYPE essencetype, + List candidate_addon, + byte[] addon_buffer, int start_offset, + ref uint addon_num) + { + //���ɶ��addon�����ܻ��в�������ʧ�� + if(addon_num == 0) return 0; + byte[] addon_sld = addon_buffer; + int i,j; + int anum = 0; + int offset = start_offset; + for(i=0; i( + DATA_TYPE dt,float unique_prob, + List unique, List produce, List drop, byte[] addon_buf, + ref uint addon_num,ref uint addon_size, RAN_CLASS cls,GEN_ADDON_MODE normal_addon,List sa_list) + { + if(normal_addon == GEN_ADDON_MODE.ADDON_LIST_DROP) + { + uint un = 0; + //ASSERT(addon_size == 0); + if(element_data.Rand_NORMAL_LOWER(0f,1f,NORMAL.NORMAL_RAND,LOWER.LOWER_TREND) < unique_prob) + { + un = 1; + addon_size = generate_equipment_addon_buffer(dt, unique, 16, addon_buf,0, ref un); + addon_num -= un; + } + addon_size += generate_equipment_addon_buffer(dt, drop, 32, addon_buf, (int)addon_size, ref addon_num); + addon_num += un; + } + else if(normal_addon == GEN_ADDON_MODE.ADDON_LIST_PRODUCE) + { + uint un = 0; + //ASSERT(addon_size == 0); + if(element_data.Rand_NORMAL_LOWER(0f,1f,NORMAL.NORMAL_RAND,LOWER.LOWER_TREND) < unique_prob) + { + un = 1; + addon_size = generate_equipment_addon_buffer(dt, unique, 16, addon_buf,0, ref un); + addon_num -= un; + } + addon_size += generate_equipment_addon_buffer(dt, produce, 32, addon_buf, (int)addon_size, ref addon_num); + addon_num += un; + } + else if (normal_addon == GEN_ADDON_MODE.ADDON_LIST_SPEC) + { + addon_size = generate_spec_addon_buffer(dt,addon_buf, 0, itemdataman.ELEMENTDATAMAN_MAX_NUM_ADDONS, ref addon_num,sa_list); + } + else + { + addon_size = 0; + addon_num = 0; + } + } + + public static uint generate_equipment_addon_buffer + (DATA_TYPE essencetype, + List candidate_addon, + int candidate_num, + byte[] addon_buffer, + int start_offset, + ref uint addon_num) + { + if(addon_num == 0) return 0; + int[] addon_list = new int[32]; + int i; + uint anum; + //����addon��������� + for(anum = 0,i=0; i addon_list_converted = new List(); + for (int j = 0; j < anum; j++) + { + addon_list_converted.Add(addon_list[j]); + } + return generate_equipment_addon_buffer_2(essencetype, addon_list_converted, addon_buffer, start_offset, ref addon_num); + } + + public static uint generate_spec_addon_buffer + (DATA_TYPE essencetype, + byte[] addon_buffer, + int start_offset, + uint max_addon_size, + ref uint addon_num, + List sa_list) + { + addon_num = 0; + if(sa_list.Count == 0) return 0; + int i; + for(i = 0; i < max_addon_size; i ++) + { + if(sa_list[i] <= 0) break; + } + if(i == 0 ) return 0; + addon_num = (uint)i; + return generate_equipment_addon_buffer_2(essencetype,sa_list,addon_buffer,start_offset, ref addon_num); + } + public static void get_item_guid( uint id, out int g1, out int g2) + { + EC_Game.get_item_guid(id,out g1,out g2); + } + public static int addon_update_ess_data(addon_data data, object essence,int ess_size, prerequisition require) + { + return EC_Game.addon_update_ess_data(data, essence, ess_size, require); + } + public static void update_require_data(prerequisition require) + { + EC_Game.update_require_data(require); + } + public static void set_to_classid(DATA_TYPE type, byte[] data, int major_type) + { + EC_Game.set_to_classid(type, data, major_type); + } + } + +} \ No newline at end of file diff --git a/Assets/PerfectWorld/Scripts/Common/DataProcess/itemdataman.cs.meta b/Assets/PerfectWorld/Scripts/Common/DataProcess/itemdataman.cs.meta new file mode 100644 index 0000000000..258444a357 --- /dev/null +++ b/Assets/PerfectWorld/Scripts/Common/DataProcess/itemdataman.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: a9c1175c22dab468e92f37bc79dfbef1 \ No newline at end of file diff --git a/Assets/PerfectWorld/Scripts/Inventory/EC_IvtrType.cs b/Assets/PerfectWorld/Scripts/Inventory/EC_IvtrType.cs index 344b4926be..17a088ea27 100644 --- a/Assets/PerfectWorld/Scripts/Inventory/EC_IvtrType.cs +++ b/Assets/PerfectWorld/Scripts/Inventory/EC_IvtrType.cs @@ -2,6 +2,7 @@ namespace BrewMonster.Scripts { public class InventoryConst { + public const int ENDURANCE_SCALE = 100; // Index of item in equipment inventory public const int EQUIPIVTR_WEAPON = 0; public const int EQUIPIVTR_HEAD = 1; diff --git a/Assets/PerfectWorld/Scripts/MainFiles/EC_Game.cs b/Assets/PerfectWorld/Scripts/MainFiles/EC_Game.cs index 05c115bd29..093234939e 100644 --- a/Assets/PerfectWorld/Scripts/MainFiles/EC_Game.cs +++ b/Assets/PerfectWorld/Scripts/MainFiles/EC_Game.cs @@ -6,7 +6,6 @@ using System; using System.Collections.Generic; using System.IO; using UnityEngine; - namespace BrewMonster.Network { public partial class EC_Game @@ -91,11 +90,10 @@ namespace BrewMonster.Network public static bool Init() { m_pElementDataMan = ElementDataManProvider.GetElementDataMan(); - + itemdataman.load_data(Path.Combine(Application.streamingAssetsPath, "data", "elements.data"), false); // Load task templates // if (m_pTaskMan == null) m_pTaskMan = new ATaskTemplMan(); m_pTaskMan = new ATaskTemplMan(); - m_pTaskMan.Init(m_pElementDataMan); m_pConfigs = new CECConfigs(); /*ElementClient.g_GameCfgs*/; if (!m_pTaskMan.InitStorageTask()) @@ -263,6 +261,30 @@ namespace BrewMonster.Network long unixTime = DateTimeOffset.UtcNow.ToUnixTimeSeconds(); return (int)unixTime + m_iTimeError; } + + #region Dummy Methods for itemdataman + public static int addon_generate_arg(DATA_TYPE type, addon_data data, int arg_num/*��ʼ�IJ�������*/) + { + return arg_num; + } + public static void get_item_guid(uint id, out int g1, out int g2) + { + g1 = 0; + g2 = 1; + } + public static int addon_update_ess_data(addon_data data, object essence,int ess_size, prerequisition require) + { + return 0; + } + public static void update_require_data(prerequisition require) + { + require.durability *= BrewMonster.Scripts.InventoryConst.ENDURANCE_SCALE; + require.max_durability *= BrewMonster.Scripts.InventoryConst.ENDURANCE_SCALE; + } + public static void set_to_classid(DATA_TYPE type, byte[] data, int major_type) + { + } + #endregion #endregion } } \ No newline at end of file From b00af6cb70a416675136ca20858c28fb014d82cb Mon Sep 17 00:00:00 2001 From: Chomper9981 Date: Tue, 30 Dec 2025 17:32:22 +0700 Subject: [PATCH 2/7] add some data to UI --- .../DataProcess/ElementDataManProvider.cs | 2 + .../Common/DataProcess/generate_item_temp.cs | 81 ++++++- .../Scripts/Common/DataProcess/itemdataman.cs | 132 +++++++--- .../PerfectWorld/Scripts/MainFiles/EC_Game.cs | 2 +- .../Scripts/Managers/EC_IvtrItem.cs | 17 +- .../Scripts/UI/DlgAward/AwardItem.cs | 17 +- .../Scripts/UI/DlgAward/CDlgAward.cs | 3 +- Assets/PerfectWorld/UI/Award/DlgAward.prefab | 225 +++++++++++++++++- 8 files changed, 424 insertions(+), 55 deletions(-) diff --git a/Assets/PerfectWorld/Scripts/Common/DataProcess/ElementDataManProvider.cs b/Assets/PerfectWorld/Scripts/Common/DataProcess/ElementDataManProvider.cs index a0c091501c..45e9c9355a 100644 --- a/Assets/PerfectWorld/Scripts/Common/DataProcess/ElementDataManProvider.cs +++ b/Assets/PerfectWorld/Scripts/Common/DataProcess/ElementDataManProvider.cs @@ -33,6 +33,8 @@ namespace BrewMonster await UniTask.DelayFrame(1); } var result = await _elementDataMan.load_data(); + //TODO: this is for testing. move it to other place + itemdataman.load_data("",false); if (result == -1) { BMLogger.LogError("ElementDataManProvider: Failed to load element data"); diff --git a/Assets/PerfectWorld/Scripts/Common/DataProcess/generate_item_temp.cs b/Assets/PerfectWorld/Scripts/Common/DataProcess/generate_item_temp.cs index e0a5249fe8..b307f10d82 100644 --- a/Assets/PerfectWorld/Scripts/Common/DataProcess/generate_item_temp.cs +++ b/Assets/PerfectWorld/Scripts/Common/DataProcess/generate_item_temp.cs @@ -29,7 +29,7 @@ public static class generate_item_temp } size =(uint)(Marshal.SizeOf(typeof(item_data)) + Marshal.SizeOf(typeof(_item_content)) + Marshal.SizeOf(typeof(_weapon_essence))); - // ����׶? + // ����׶�? uint hole_num = 0; if(normal_addon == GEN_ADDON_MODE.ADDON_LIST_DROP) { @@ -195,13 +195,13 @@ public static class generate_item_temp WriteInt(data, ref offset, temp2); // max_durability // //���������߱�ǩע���ǩ���ڱ����С�ͱ�������֮�� - // *(short*)buf = sizeof(_weapon_essence); buf += sizeof(short); //װ�������С���ֽڣ? + // *(short*)buf = sizeof(_weapon_essence); buf += sizeof(short); //װ�������С���ֽڣ�? // memcpy(buf,tag,tag_size); // buf += tag_size; WriteShort(data, ref offset, (short)Marshal.SizeOf(typeof(_weapon_essence))); WriteTag(data, ref offset, tag); - //essence //char ����[]; //ÿ�ֲ�ͬװ���ı���ṹ��? + //essence //char ����[]; //ÿ�ֲ�ͬװ���ı���ṹ���? // char * essence_ptr = buf; int essence_ptr = offset; // switch(ess->short_range_mode) @@ -211,7 +211,7 @@ public static class generate_item_temp // case 1: *(short*)buf = 0; break; //���� // case 2: *(short*)buf = 2; break; //�̿ͽ��� // } - // buf += sizeof(short); //������? ��Ӧģ����Ľ���Զ�̱�? + // buf += sizeof(short); //�������? ��Ӧģ����Ľ���Զ�̱��? switch(ess.short_range_mode) { default: @@ -225,13 +225,13 @@ public static class generate_item_temp WriteShort(data, ref offset, (short)2); break; } - // *(short*)buf = 0; buf += sizeof(short); //���ֵ����ʹ�? - // *(int*)buf = ess->id_major_type; buf += sizeof(int); //�������� ��Ӧģ����Ĵ��? ���絶�� ������ + // *(short*)buf = 0; buf += sizeof(short); //���ֵ����ʹ��? + // *(int*)buf = ess->id_major_type; buf += sizeof(int); //�������� ��Ӧģ����Ĵ���? ���絶�� ������ // *(int*)buf = ess->level; buf += sizeof(int); //�������� ijЩ������Ҫ�������� // *(int*)buf = ess->require_projectile; buf += sizeof(int); //��Ҫ��ҩ������ // *(int*)buf = ess->damage_low; buf += sizeof(int); //����������С��ֵ // *(int*)buf = element_data::RandNormal(ess->damage_high_min, ess->damage_high_max, cls,element_data::LOWER_TREND); buf += sizeof(int); //������������ֵ - // *(int*)buf = ess->magic_daage_low; buf += sizeof(int); //ħ���������? + // *(int*)buf = ess->magic_daage_low; buf += sizeof(int); //ħ����������? // *(int*)buf = element_data::RandNormal(ess->magic_damage_high_min, ess->magic_damage_high_max, cls,element_data::LOWER_TREND); buf += sizeof(int); //ħ������ WriteShort(data, ref offset, (short)0); WriteUInt(data, ref offset, ess.id_major_type); @@ -251,7 +251,7 @@ public static class generate_item_temp // else // { // unsigned int index = element_data::RandSelect(&(subtype->probability_fastest), sizeof(float), 5, cls,element_data::MIDDLE_TREND); - // *(int*)buf = (int)(subtype->attack_speed*20.f + 0.1f) + (index - 2); buf += sizeof(int); //ģ���е���0.05���? + // *(int*)buf = (int)(subtype->attack_speed*20.f + 0.1f) + (index - 2); buf += sizeof(int); //ģ���е���0.05����? // } WEAPON_SUB_TYPE subtype = new WEAPON_SUB_TYPE(); object sub_type_temp = itemdataman._edm.get_data_ptr(ess.id_sub_type, ID_SPACE.ID_SPACE_ESSENCE, ref datatype); @@ -273,7 +273,7 @@ public static class generate_item_temp // *(short*)buf = 0; buf += sizeof(short); //�׶��������������� // for(i=0; i>13)*sizeof(int)+sizeof(int); + addon_sld += ((addon_data.id & 0x6000)>>13)*sizeof(int)+sizeof(int); } // memcpy(buf, addon_buf, addon_size); // set_to_classid(DT_WEAPON_ESSENCE, (item_data*)(*data), -1); itemdataman.update_require_data(prerequisition); - WriteAddonData(data, ref offset, addon_data); + // Copy the entire addon buffer instead of writing a single addon_data + if(addon_size > 0) + { + Array.Copy(addon_buf, 0, data, offset, (int)addon_size); + offset += (int)addon_size; + } itemdataman.set_to_classid(DATA_TYPE.DT_WEAPON_ESSENCE, data, -1); return 0; } + public static int generate_tasknormalmatter(uint id, ID_SPACE idspace, out byte[] data, out uint size, RAND_CLASS cls, + GEN_ADDON_MODE normal_addon ,item_tag_t tag,List sa_list = null) + { + // DATA_TYPE datatype; + DATA_TYPE datatype = DATA_TYPE.DT_INVALID; + data = new byte[0]; + size = 0; + int i=0; + // TASKNORMALMATTER_ESSENCE * ess = (TASKNORMALMATTER_ESSENCE *)get_data_ptr(id, idspace, datatype); + object obj = itemdataman._edm.get_data_ptr(id, idspace,ref datatype); + if(obj == null || datatype != DATA_TYPE.DT_TASKNORMALMATTER_ESSENCE) + { + return -1; + } + TASKNORMALMATTER_ESSENCE ess = (TASKNORMALMATTER_ESSENCE)obj; + size =(uint) (Marshal.SizeOf(typeof(item_data)) + Marshal.SizeOf(typeof(TASKNORMALMATTER_ESSENCE))); + data = new byte[size]; + int offset = 0; + WriteUInt(data, ref offset, ess.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_TASKNORMALMATTER_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, ess.price); + WriteInt(data, ref offset, 0); + + int content_length; + 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_TASKNORMALMATTER_ESSENCE, data, -1); + return 0; + } private static void WriteUInt(byte[] buf, ref int offset, uint value) { Array.Copy(BitConverter.GetBytes(value), 0, buf, offset, 4); diff --git a/Assets/PerfectWorld/Scripts/Common/DataProcess/itemdataman.cs b/Assets/PerfectWorld/Scripts/Common/DataProcess/itemdataman.cs index 2ca3acce27..8228de49a7 100644 --- a/Assets/PerfectWorld/Scripts/Common/DataProcess/itemdataman.cs +++ b/Assets/PerfectWorld/Scripts/Common/DataProcess/itemdataman.cs @@ -5,6 +5,7 @@ using System.Collections.Generic; using System.Threading.Tasks; using UnityEngine; using ModelRenderer.Scripts.GameData; +using System.Runtime.InteropServices; namespace BrewMonster { @@ -283,7 +284,7 @@ namespace BrewMonster public int price; //��Ʒ�ļ۸� public int expire_date; //����ʱ�� public int content_length; - public byte item_content; + public byte[] item_content; }; // #pragma pack(1) public struct _item_content @@ -304,7 +305,7 @@ namespace BrewMonster public int[] arg; public addon_data(int id) { this.id = id; - arg = new int[3]; + arg = new int[]{0,0,0}; } }; public struct prerequisition @@ -382,8 +383,11 @@ namespace BrewMonster public const uint ELEMENTDATAMAN_EQUIP_MASK_HIGH = 0xC0000000; #endregion #endregion - public static Dictionary sale_item_id_index_map; + public static Dictionary sale_item_id_index_map = new Dictionary(); public static elementdataman _edm; + + public static List sale_item_ptr_array = new List(); + public static List sale_item_size_array = new List(); public static int load_data(string pathname, bool disable_bind2) { _edm = ElementDataManProvider.GetElementDataMan(); @@ -407,32 +411,42 @@ namespace BrewMonster // if (dt2 == datatype && ess && disable_bind2) ess->proc_type &= ~(0x0040);\ // } - byte[] item; - uint size; - int ret; - + byte[] item = null; + uint size = 0; + int ret = 0; DATA_TYPE datatype = DATA_TYPE.DT_INVALID; item_tag_t tag = new item_tag_t((char)ITEM_MAKE_TAG.IMT_SHOP, (char)'0'); - //uint id = _edm.get_first_data_id(ID_SPACE.ID_SPACE_ESSENCE,ref datatype); + //uint id = _edm.get_first_data_id(ID_SPACE.ID_SPACE_ESSENCE,ref datatype); - - for (uint id = 0; id < _edm.essence_id_data_type_map.Count; id++) - { - _edm.essence_id_data_type_map.TryGetValue(id, out datatype); + for (int i = 0; i < _edm.essence_id_data_type_map.Count; i++) + { + ret = 0; + uint id = _edm.get_data_id(ID_SPACE.ID_SPACE_ESSENCE, i, ref datatype); switch (datatype) { - case (DATA_TYPE.DT_WEAPON_ESSENCE): - generate_item_temp.generate_weapon(id,ID_SPACE.ID_SPACE_ESSENCE, + case DATA_TYPE.DT_WEAPON_ESSENCE: + ret = generate_item_temp.generate_weapon(id,ID_SPACE.ID_SPACE_ESSENCE, + out item,out size,SPECIFIC.SPECIFIC_RAND,GEN_ADDON_MODE.ADDON_LIST_SHOP,tag); + 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); - BMLogger.Log("generate_item_for_sell: generate_weapon: " + id); break; default: - BMLogger.Log("generate_item_for_sell: default: " + id); ret = -1; break; } - } - + //Debug.Log("[THN]return_item_for_sell: ret:" + ret + " size:" + size + " datatype:" + datatype + " id:" + id); + if (ret == 0 && size != 0) + { + sale_item_ptr_array.Add(item); + sale_item_size_array.Add(size); + LOCATION loc; + loc.type = datatype; + loc.pos = sale_item_ptr_array.Count - 1; + sale_item_id_index_map[id] = loc; + } + #region unimplemented // CASE_CLEAR_PROC_TYPE(ARMOR_ESSENCE) // ret = generate_armor(id, ID_SPACE_ESSENCE, (char**)&item, size, element_data::SPECIFIC(0), element_data::ADDON_LIST_SHOP, &tag, sizeof(tag)); @@ -722,28 +736,82 @@ namespace BrewMonster // case DT_NPC_ESSENCE: // default: // continue; + // } - - // if (ret == 0 && size != 0) - // { - // sale_item_ptr_array.push_back(item); - // sale_item_size_array.push_back(size); - // LOCATION loc; - // loc.type = datatype; - // loc.pos = sale_item_ptr_array.size() - 1; - // sale_item_id_index_map[id] = loc; - // } - // } + #endregion + } return 0; } + private static item_data deserialize_item_data(byte[] buffer) + { + // Deserialize item_data from byte array + // Layout matches generate_item_temp.cs serialization order + // type (uint), count (uint written as 1), pile_limit (int), equip_mask (int), + // proc_type (uint), classid (int), guid1 (int), guid2 (int), price (int), expire_date (int), + // content_length (int), item_content pointer (int) + int offset = 0; + item_data item = new item_data(); + + item.type = BitConverter.ToUInt32(buffer, offset); offset += 4; + // count is written as uint but struct has int, read as uint then cast + item.count = (int)BitConverter.ToUInt32(buffer, offset); offset += 4; + item.pile_limit = BitConverter.ToInt32(buffer, offset); offset += 4; + item.equip_mask = BitConverter.ToInt32(buffer, offset); offset += 4; + // proc_type is written as uint but struct has int, read as uint then cast + item.proc_type = (int)BitConverter.ToUInt32(buffer, offset); offset += 4; + item.classid = BitConverter.ToInt32(buffer, offset); offset += 4; + item.guid.guid1 = BitConverter.ToInt32(buffer, offset); offset += 4; + item.guid.guid2 = BitConverter.ToInt32(buffer, offset); offset += 4; + item.price = BitConverter.ToInt32(buffer, offset); offset += 4; + item.expire_date = BitConverter.ToInt32(buffer, offset); offset += 4; + item.content_length = BitConverter.ToInt32(buffer, offset); offset += 4; + + // item_content is stored as an offset/pointer in the buffer (points to where content starts) + int item_content_offset = BitConverter.ToInt32(buffer, offset); offset += 4; + + // Extract the actual content bytes + if (item.content_length > 0 && item_content_offset > 0 && item_content_offset < buffer.Length) + { + int contentStart = item_content_offset; + int contentEnd = Math.Min(contentStart + item.content_length, buffer.Length); + int actualLength = contentEnd - contentStart; + if (actualLength > 0) + { + item.item_content = new byte[actualLength]; + Array.Copy(buffer, contentStart, item.item_content, 0, actualLength); + } + else + { + item.item_content = new byte[0]; + } + } + else + { + item.item_content = new byte[0]; + } + + return item; + } + public static object get_item_for_sell(uint id) { - uint pos; - if (sale_item_id_index_map.TryGetValue(id, out var itr)) + LOCATION itr; + bool result = sale_item_id_index_map.TryGetValue(id, out itr); + if (result) { - return itr; + // itr.pos contains the index into sale_item_ptr_array + int index = (int)itr.pos; + if (index >= 0 && index < sale_item_ptr_array.Count) + { + byte[] itemBuffer = sale_item_ptr_array[index]; + if (itemBuffer != null && itemBuffer.Length > 0) + { + item_data item = deserialize_item_data(itemBuffer); + return item; + } + } } return null; } diff --git a/Assets/PerfectWorld/Scripts/MainFiles/EC_Game.cs b/Assets/PerfectWorld/Scripts/MainFiles/EC_Game.cs index d1b55dcfb9..dc3e4f855c 100644 --- a/Assets/PerfectWorld/Scripts/MainFiles/EC_Game.cs +++ b/Assets/PerfectWorld/Scripts/MainFiles/EC_Game.cs @@ -91,7 +91,7 @@ namespace BrewMonster.Network public static bool Init() { m_pElementDataMan = ElementDataManProvider.GetElementDataMan(); - itemdataman.load_data(Path.Combine(Application.streamingAssetsPath, "data", "elements.data"), false); + // Load task templates // if (m_pTaskMan == null) m_pTaskMan = new ATaskTemplMan(); m_pTaskMan = new ATaskTemplMan(); diff --git a/Assets/PerfectWorld/Scripts/Managers/EC_IvtrItem.cs b/Assets/PerfectWorld/Scripts/Managers/EC_IvtrItem.cs index 27b11f1fae..0e2474fe2a 100644 --- a/Assets/PerfectWorld/Scripts/Managers/EC_IvtrItem.cs +++ b/Assets/PerfectWorld/Scripts/Managers/EC_IvtrItem.cs @@ -1156,8 +1156,21 @@ namespace BrewMonster.Scripts.Managers public void GetDetailDataFromLocal() { - // Placeholder: when itemdataman is ported, this will read default item content. - SetItemInfo(null, 0); + //itemdataman* pItemDataMan = g_pGame->GetItemDataMan(); + object pData_temp = itemdataman.get_item_for_sell((uint)m_tid); + BMLogger.Log($"[THN]GetDetailDataFromLocal: tid:{m_tid} pData_temp:{pData_temp}"); + if(pData_temp == null) + { + SetItemInfo(null, 0); + SetLocalProps(); + m_bLocalDetailData = true; + return; + } + item_data pData = (item_data)pData_temp; + + SetItemInfo(pData.item_content, pData.content_length); + BMLogger.Log($"[THN]GetDetailDataFromLocal: id:{m_tid} content:{pData.item_content} length:{pData.content_length}"); + SetLocalProps(); m_bLocalDetailData = true; } diff --git a/Assets/PerfectWorld/Scripts/UI/DlgAward/AwardItem.cs b/Assets/PerfectWorld/Scripts/UI/DlgAward/AwardItem.cs index 6754b86008..c260895a10 100644 --- a/Assets/PerfectWorld/Scripts/UI/DlgAward/AwardItem.cs +++ b/Assets/PerfectWorld/Scripts/UI/DlgAward/AwardItem.cs @@ -1,12 +1,15 @@ using UnityEngine; using UnityEngine.UI; - +using TMPro; namespace BrewMonster.Scripts.UI { public class AwardItem : MonoBehaviour { [SerializeField] private Image img; [SerializeField] private Button btn; + [SerializeField] private GameObject objHint; + [SerializeField] private TMP_Text txtHint; + private bool _bShowHint = false; private Vector2Int _position; @@ -27,6 +30,7 @@ namespace BrewMonster.Scripts.UI public void SetText(string text) { // TODO: Add a Text component and set its text + } public void SetColor(Color color) @@ -37,6 +41,12 @@ namespace BrewMonster.Scripts.UI public void SetHint(string text) { // TODO : Implement hint functionality + btn.onClick.RemoveAllListeners(); + txtHint.text = text; + btn.onClick.AddListener(() => { + HintBehaviour(); + }); + } public void ClearCover() @@ -49,5 +59,10 @@ namespace BrewMonster.Scripts.UI gameObject.SetActive(show); } + private void HintBehaviour() + { + _bShowHint = !_bShowHint; + objHint.SetActive(_bShowHint); + } } } \ No newline at end of file diff --git a/Assets/PerfectWorld/Scripts/UI/DlgAward/CDlgAward.cs b/Assets/PerfectWorld/Scripts/UI/DlgAward/CDlgAward.cs index 1e3bfcf743..f0e343afbe 100644 --- a/Assets/PerfectWorld/Scripts/UI/DlgAward/CDlgAward.cs +++ b/Assets/PerfectWorld/Scripts/UI/DlgAward/CDlgAward.cs @@ -139,7 +139,8 @@ namespace BrewMonster.Scripts.UI pImage.SetText(_AL("")); pItem.GetDetailDataFromLocal(); - // pImage.SetHint(trans.Translate(pItem.GetDesc())); // TODO + pImage.SetHint(pItem.GetDesc()); // TODO + //Debug.Log("[THN]CDlgAward: pItem.GetDesc():" + pItem.GetDesc()); // af_GetFileTitle(pItem.GetIconFile(), strFile); // TODO strFile.ToLower(); diff --git a/Assets/PerfectWorld/UI/Award/DlgAward.prefab b/Assets/PerfectWorld/UI/Award/DlgAward.prefab index 3a24f98a6b..d538fd83a6 100644 --- a/Assets/PerfectWorld/UI/Award/DlgAward.prefab +++ b/Assets/PerfectWorld/UI/Award/DlgAward.prefab @@ -1,5 +1,81 @@ %YAML 1.1 %TAG !u! tag:unity3d.com,2011: +--- !u!1 &165174036537021008 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 3386269673238764405} + - component: {fileID: 5695467372271221829} + - component: {fileID: 8051377020245334668} + m_Layer: 5 + m_Name: Panel + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 0 +--- !u!224 &3386269673238764405 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 165174036537021008} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 1815682412766530288} + m_Father: {fileID: 2175163742848198118} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 366.661, y: -167.5} + m_SizeDelta: {x: 531, y: 335} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &5695467372271221829 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 165174036537021008} + m_CullTransparentMesh: 1 +--- !u!114 &8051377020245334668 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 165174036537021008} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 10907, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 --- !u!1 &227158560462075115 GameObject: m_ObjectHideFlags: 0 @@ -84,7 +160,7 @@ MonoBehaviour: onValueChanged: m_PersistentCalls: m_Calls: [] - m_IsOn: 1 + m_IsOn: 0 --- !u!1 &598635325287938884 GameObject: m_ObjectHideFlags: 0 @@ -516,7 +592,7 @@ MonoBehaviour: onValueChanged: m_PersistentCalls: m_Calls: [] - m_IsOn: 1 + m_IsOn: 0 --- !u!1 &2100466003483804571 GameObject: m_ObjectHideFlags: 0 @@ -1103,7 +1179,7 @@ MonoBehaviour: onValueChanged: m_PersistentCalls: m_Calls: [] - m_IsOn: 1 + m_IsOn: 0 --- !u!1 &3664700763723290860 GameObject: m_ObjectHideFlags: 0 @@ -1188,7 +1264,7 @@ MonoBehaviour: onValueChanged: m_PersistentCalls: m_Calls: [] - m_IsOn: 1 + m_IsOn: 0 --- !u!1 &3692755084474195755 GameObject: m_ObjectHideFlags: 0 @@ -1222,6 +1298,7 @@ RectTransform: m_ConstrainProportionsScale: 0 m_Children: - {fileID: 504415793170309261} + - {fileID: 3386269673238764405} m_Father: {fileID: 1558872982091896349} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} @@ -1243,6 +1320,8 @@ MonoBehaviour: m_EditorClassIdentifier: img: {fileID: 5798109676702798723} btn: {fileID: 5829300517807457460} + objHint: {fileID: 165174036537021008} + txtHint: {fileID: 7658705790532366309} --- !u!222 &1897581106405175503 CanvasRenderer: m_ObjectHideFlags: 0 @@ -1558,6 +1637,142 @@ MonoBehaviour: m_FillOrigin: 0 m_UseSpriteMesh: 0 m_PixelsPerUnitMultiplier: 1 +--- !u!1 &5403631556117558338 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1815682412766530288} + - component: {fileID: 8320041494551075808} + - component: {fileID: 7658705790532366309} + m_Layer: 5 + m_Name: Text (TMP) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1815682412766530288 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 5403631556117558338} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 3386269673238764405} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: -20, y: -20} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &8320041494551075808 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 5403631556117558338} + m_CullTransparentMesh: 1 +--- !u!114 &7658705790532366309 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 5403631556117558338} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_text: New Text + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 4294967295 + m_fontColor: {r: 0, g: 0, b: 0, a: 1} + m_enableVertexGradient: 0 + m_colorMode: 3 + m_fontColorGradient: + topLeft: {r: 1, g: 1, b: 1, a: 1} + topRight: {r: 1, g: 1, b: 1, a: 1} + bottomLeft: {r: 1, g: 1, b: 1, a: 1} + bottomRight: {r: 1, g: 1, b: 1, a: 1} + m_fontColorGradientPreset: {fileID: 0} + m_spriteAsset: {fileID: 0} + m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: -1183493901 + m_overrideHtmlColors: 0 + m_faceColor: + serializedVersion: 2 + rgba: 4294967295 + m_fontSize: 36 + m_fontSizeBase: 36 + m_fontWeight: 400 + m_enableAutoSizing: 0 + m_fontSizeMin: 18 + m_fontSizeMax: 72 + m_fontStyle: 0 + m_HorizontalAlignment: 1 + m_VerticalAlignment: 256 + m_textAlignment: 65535 + m_characterSpacing: 0 + m_wordSpacing: 0 + m_lineSpacing: 0 + m_lineSpacingMax: 0 + m_paragraphSpacing: 0 + m_charWidthMaxAdj: 0 + m_TextWrappingMode: 1 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_linkedTextComponent: {fileID: 0} + parentLinkedComponent: {fileID: 0} + m_enableKerning: 0 + m_ActiveFontFeatures: 6e72656b + m_enableExtraPadding: 0 + checkPaddingRequired: 0 + m_isRichText: 1 + m_EmojiFallbackSupport: 1 + m_parseCtrlCharacters: 1 + m_isOrthographic: 1 + m_isCullingEnabled: 0 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 + m_VertexBufferAutoSizeReduction: 0 + m_useMaxVisibleDescender: 1 + m_pageToDisplay: 1 + m_margin: {x: 0, y: 0, z: 0, w: 0} + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + m_hasFontAssetChanged: 0 + m_baseMaterial: {fileID: 0} + m_maskOffset: {x: 0, y: 0, z: 0, w: 0} --- !u!1 &5498099694921818792 GameObject: m_ObjectHideFlags: 0 @@ -2020,7 +2235,7 @@ MonoBehaviour: onValueChanged: m_PersistentCalls: m_Calls: [] - m_IsOn: 1 + m_IsOn: 0 --- !u!1 &7637041124332687819 GameObject: m_ObjectHideFlags: 0 From 4c7217929dc0e705e383b0ad1f7be6658a9e11a9 Mon Sep 17 00:00:00 2001 From: Chomper9981 Date: Thu, 8 Jan 2026 15:02:20 +0700 Subject: [PATCH 3/7] Complete add feature "Load weapon data" and show it in the "Quest Chao Hoi Lay Item" --- .../Common/DataProcess/elementdataman.cs | 8 + .../Common/DataProcess/generate_item_temp.cs | 826 +++++++++++++++++- .../Scripts/Common/DataProcess/itemdataman.cs | 110 ++- .../PerfectWorld/Scripts/MainFiles/EC_Game.cs | 19 +- .../Scripts/Managers/EC_InventoryUI.cs | 4 +- .../Scripts/Managers/EC_IvtrEquip.cs | 476 ++++++---- .../Scripts/Managers/EC_IvtrItem.cs | 71 +- .../Scripts/Managers/EC_IvtrType.cs | 208 +++++ .../Scripts/Managers/EC_IvtrWeapon.cs | 436 +++++++++ .../Scripts/Managers/EC_IvtrWeapon.cs.meta | 2 + .../Scripts/Managers/EC_ProfConfigs.cs | 153 ++++ .../Scripts/Managers/EC_ProfConfigs.cs.meta | 2 + Assets/PerfectWorld/Scripts/Move/CECPlayer.cs | 10 +- .../Scripts/Network/CSNetwork/GPDataType.cs | 23 + .../Scripts/UI/DlgAward/CDlgAward.cs | 15 +- .../Scripts/UI/NPCShopDetailPanel.cs | 2 +- .../PerfectWorld/Scripts/Utils/CECRTDebug.cs | 119 ++- Assets/Scripts/CECGameRun.cs | 32 +- Assets/Scripts/CECHostPlayer.cs | 25 + 19 files changed, 2249 insertions(+), 292 deletions(-) create mode 100644 Assets/PerfectWorld/Scripts/Managers/EC_IvtrWeapon.cs create mode 100644 Assets/PerfectWorld/Scripts/Managers/EC_IvtrWeapon.cs.meta create mode 100644 Assets/PerfectWorld/Scripts/Managers/EC_ProfConfigs.cs create mode 100644 Assets/PerfectWorld/Scripts/Managers/EC_ProfConfigs.cs.meta diff --git a/Assets/PerfectWorld/Scripts/Common/DataProcess/elementdataman.cs b/Assets/PerfectWorld/Scripts/Common/DataProcess/elementdataman.cs index 085a7974ea..598086940a 100644 --- a/Assets/PerfectWorld/Scripts/Common/DataProcess/elementdataman.cs +++ b/Assets/PerfectWorld/Scripts/Common/DataProcess/elementdataman.cs @@ -1590,6 +1590,10 @@ namespace ModelRenderer.Scripts.GameData recipe_id_data_map[id] = data; recipe_index_id_map[recipe_index_id_map.Count] = id; break; + case ID_SPACE.ID_SPACE_ADDON: + addon_id_data_map[id] = data; + addon_index_id_map[addon_index_id_map.Count] = id; + break; default: break; @@ -1761,11 +1765,15 @@ namespace ModelRenderer.Scripts.GameData break; case ID_SPACE.ID_SPACE_ADDON: + BMLogger.Log("[thn] weapon addon map count: " + addon_id_data_map.Count); + BMLogger.Log("[thn] weapon addon id: " + id); if (addon_id_data_map.TryGetValue(id, out data)) { + dataType = addon_id_data_type_map[id]; return data; } + BMLogger.Log("[thn] weapon addon data: " + data); break; default: diff --git a/Assets/PerfectWorld/Scripts/Common/DataProcess/generate_item_temp.cs b/Assets/PerfectWorld/Scripts/Common/DataProcess/generate_item_temp.cs index b307f10d82..ea8eeec9a1 100644 --- a/Assets/PerfectWorld/Scripts/Common/DataProcess/generate_item_temp.cs +++ b/Assets/PerfectWorld/Scripts/Common/DataProcess/generate_item_temp.cs @@ -4,7 +4,8 @@ using BrewMonster; using System.Runtime.InteropServices; using System.Collections.Generic; using System.Linq; - using System; +using System; +using BrewMonster.abase; public static class generate_item_temp { public static int generate_weapon(uint id, ID_SPACE idspace, out byte[] data, out uint size, RAND_CLASS cls, @@ -34,12 +35,12 @@ public static class generate_item_temp if(normal_addon == GEN_ADDON_MODE.ADDON_LIST_DROP) { float[] drop_probability_socket = { ess.drop_probability_socket0, ess.drop_probability_socket1, ess.drop_probability_socket2 }; - hole_num = element_data.RandSelect_SPECIFIC_LOWER(drop_probability_socket.ToList(), SPECIFIC.SPECIFIC_RAND, LOWER.LOWER_TREND); //�׶�����Ŀ + hole_num = (uint)element_data.RandSelect_SPECIFIC_LOWER(drop_probability_socket.ToList(), SPECIFIC.SPECIFIC_RAND, LOWER.LOWER_TREND); //�׶�����Ŀ } else //if(normal_addon == element_data::ADDON_LIST_PRODUCE || normal_addon == element_data::ADDON_LIST_SPEC) { float[] make_probability_socket = { ess.make_probability_socket0, ess.make_probability_socket1, ess.make_probability_socket2 }; - hole_num = element_data.RandSelect_SPECIFIC_LOWER(make_probability_socket.ToList(), SPECIFIC.SPECIFIC_RAND, LOWER.LOWER_TREND); //�׶�����Ŀ + hole_num = (uint)element_data.RandSelect_SPECIFIC_LOWER(make_probability_socket.ToList(), SPECIFIC.SPECIFIC_RAND, LOWER.LOWER_TREND); //�׶�����Ŀ } size += hole_num*sizeof(int); // size ����hole_num������type @@ -52,15 +53,36 @@ public static class generate_item_temp uint candidate_num = itemdataman.ELEMENTDATAMAN_MAX_NUM_ADDONS; byte[] addon_buf = new byte[candidate_num*Marshal.SizeOf(typeof(itemdataman._addon))]; float[] probability_addon_num = { ess.probability_addon_num0, ess.probability_addon_num1, ess.probability_addon_num2, ess.probability_addon_num3, ess.probability_addon_num4, ess.probability_addon_num5 }; - uint addon_num = element_data.RandSelect_SPECIFIC_LOWER(probability_addon_num.ToList(), SPECIFIC.SPECIFIC_RAND, LOWER.LOWER_TREND); //���Ա���Ŀ����Ŀ + //log each probability_addon_num + uint addon_num = (uint)element_data.RandSelect_NORMAL_LOWER(probability_addon_num.ToList(), NORMAL.NORMAL_RAND, LOWER.LOWER_TREND); //���Ա���Ŀ����Ŀ uint addon_size = 0; + // if(ess->fixed_props) + // { + // addon_size = generate_equipment_addon_buffer_2(DT_WEAPON_ESSENCE, (int*)&(ess->addons[0]), sizeof(int)+sizeof(float),32, addon_buf,addon_num); + // } + // else + // { + // if(addon_num || normal_addon == element_data::ADDON_LIST_SPEC) + // { + // generate_template_addon(DT_WEAPON_ESSENCE,ess->probability_unique, + // (char*)ess->uniques,(char*)ess->rands,(char*)ess->addons, + // addon_buf,addon_num,addon_size,cls,normal_addon,sa_list); + // } + // else + // { + // if (normal_addon == element_data::ADDON_LIST_SPEC) + // { + // addon_size = generate_spec_addon_buffer(DT_WEAPON_ESSENCE,addon_buf,ELEMENTDATAMAN_MAX_NUM_ADDONS,addon_num,sa_list); + // } + // } + // } if(ess.fixed_props!=0) { // this list store the addon id // addon_size = generate_equipment_addon_buffer_2(DT_WEAPON_ESSENCE, (int*)&(ess->addons[0]), sizeof(int)+sizeof(float),32, addon_buf,addon_num); List addon_list = ess.addons.Select(a => (int)a.id_addon).ToList(); - addon_size = itemdataman.generate_equipment_addon_buffer_2(DATA_TYPE.DT_WEAPON_ESSENCE, addon_list, addon_buf,0, ref addon_num); + addon_size = itemdataman.generate_equipment_addon_buffer_2(DATA_TYPE.DT_WEAPON_ESSENCE, addon_list, addon_buf,0, addon_num); } else { @@ -78,12 +100,13 @@ public static class generate_item_temp { if (normal_addon == GEN_ADDON_MODE.ADDON_LIST_SPEC) { - addon_size = itemdataman.generate_spec_addon_buffer(DATA_TYPE.DT_WEAPON_ESSENCE,addon_buf,0,itemdataman.ELEMENTDATAMAN_MAX_NUM_ADDONS, ref addon_num,sa_list); + addon_size = itemdataman.generate_spec_addon_buffer(DATA_TYPE.DT_WEAPON_ESSENCE,addon_buf,0,itemdataman.ELEMENTDATAMAN_MAX_NUM_ADDONS, addon_num,sa_list); } } } size += addon_size; + BMLogger.Log("[thn]generate_weapon, addon_size: " + addon_size); // allocate the buffer with exact length // *data = (char *)abase::fastalloc(size); @@ -199,7 +222,8 @@ public static class generate_item_temp // memcpy(buf,tag,tag_size); // buf += tag_size; WriteShort(data, ref offset, (short)Marshal.SizeOf(typeof(_weapon_essence))); - WriteTag(data, ref offset, tag); + WriteByte(data, ref offset, tag.type); // MadeFrom + WriteByte(data, ref offset, 0); //essence //char ����[]; //ÿ�ֲ�ͬװ���ı���ṹ���? // char * essence_ptr = buf; @@ -241,7 +265,6 @@ public static class generate_item_temp WriteInt(data, ref offset, element_data.RandNormal_NORMAL_LOWER(ess.damage_high_min, ess.damage_high_max, NORMAL.NORMAL_RAND, LOWER.LOWER_TREND)); WriteInt(data, ref offset, ess.magic_damage_low); WriteInt(data, ref offset, element_data.RandNormal_NORMAL_LOWER(ess.magic_damage_high_min, ess.magic_damage_high_max, NORMAL.NORMAL_RAND, LOWER.LOWER_TREND)); - // WEAPON_SUB_TYPE * subtype = (WEAPON_SUB_TYPE * )get_data_ptr(ess->id_sub_type, ID_SPACE_ESSENCE, datatype); // if(subtype == NULL || datatype != DT_WEAPON_SUB_TYPE) // { @@ -297,18 +320,23 @@ public static class generate_item_temp // } addon_data addon_data = new addon_data(); prerequisition prerequisition = new prerequisition(); + // Read prerequisition from data buffer (where it was written) once before the loop + int require_ptr_copy = require_ptr; + ReadPrerequisition(data, ref require_ptr_copy, out prerequisition); for(i = 0; i < addon_num; i++) { ReadInt(addon_buf, ref addon_sld, out addon_data.id); ReadAddonData(addon_buf, ref addon_sld, out addon_data); - ReadPrerequisition(addon_buf, ref require_ptr, out prerequisition); itemdataman.addon_update_ess_data(addon_data, essence_ptr, Marshal.SizeOf(typeof(_weapon_essence)), prerequisition); addon_sld += ((addon_data.id & 0x6000)>>13)*sizeof(int)+sizeof(int); } // memcpy(buf, addon_buf, addon_size); // set_to_classid(DT_WEAPON_ESSENCE, (item_data*)(*data), -1); - itemdataman.update_require_data(prerequisition); + itemdataman.update_require_data(ref prerequisition); + // Write updated prerequisition back to data buffer + int require_ptr_write = require_ptr; + WritePrerequisition(data, ref require_ptr_write, prerequisition); // Copy the entire addon buffer instead of writing a single addon_data if(addon_size > 0) { @@ -318,7 +346,216 @@ public static class generate_item_temp itemdataman.set_to_classid(DATA_TYPE.DT_WEAPON_ESSENCE, data, -1); return 0; } - + private static void generate_magic_defense(int[] res, List res_list , RAND_CLASS cls, + bool b_fixed = false) // + { + float[] count_prop = {0.35f,0.25f,0.20f,0.15f,0.05f,0.051f}; + float[] md_adjust = {1.0f,1.1f,1.3f,1.6f,2.0f}; + int RE_num = 0; + if(!b_fixed) + { + RE_num = element_data.RandSelect_SPECIFIC_LOWER(count_prop.ToList(), SPECIFIC.SPECIFIC_RAND, LOWER.LOWER_TREND); + } + if(RE_num == 5) return; + // Ensure RE_num is within valid range for md_adjust array (0-4) + if(RE_num < 0 || RE_num >= md_adjust.Length) + { + return; + } + int[] md = {0,1,2,3,4}; + for(int i = 0; i < RE_num; i++) + { + int r = abase.Rand(i,4); + int t = md[i]; + md[i] = md[r]; + md[r] = t; + } + float adj = md_adjust[RE_num]; + for(int i = 0; i < 5 - RE_num; i++) + { + int index = md[i]; + // Check if res_list has enough elements (need at least index*2+2 elements for low and high) + if(res_list == null || res_list.Count < (index * 2 + 2)) + { + // Skip this index if not enough data + continue; + } + int low = res_list[index *2].low; + int high= res_list[index *2+1].high; + res[index] = (int)(element_data.RandNormal_NORMAL_LOWER(low, high, NORMAL.NORMAL_RAND, LOWER.LOWER_TREND) * adj); + } + } + public static int generate_armor(uint id, ID_SPACE idspace, out byte[] data, out uint size, RAND_CLASS cls, + GEN_ADDON_MODE normal_addon ,item_tag_t tag,List sa_list = null) + { + DATA_TYPE datatype = DATA_TYPE.DT_INVALID; + data = new byte[0]; + size = 0; + int i=0; + object obj = itemdataman._edm.get_data_ptr(id, idspace,ref datatype); + if(obj == null || datatype != DATA_TYPE.DT_ARMOR_ESSENCE) + { + return -1; + } + ARMOR_ESSENCE ess = (ARMOR_ESSENCE)obj; + size =(uint) (Marshal.SizeOf(typeof(item_data)) + Marshal.SizeOf(typeof(_item_content)) + Marshal.SizeOf(typeof(ARMOR_ESSENCE))); + data = new byte[size]; + int offset = 0; + short hole_num = 0; + if(normal_addon == GEN_ADDON_MODE.ADDON_LIST_DROP) + { + float[] drop_probability_socket = { ess.drop_probability_socket0, ess.drop_probability_socket1, ess.drop_probability_socket2 }; + hole_num = (short)element_data.RandSelect_SPECIFIC_LOWER(drop_probability_socket.ToList(), SPECIFIC.SPECIFIC_RAND, LOWER.LOWER_TREND); //�׶�����Ŀ + } + else //if(normal_addon == element_data::ADDON_LIST_PRODUCE || normal_addon == element_data::ADDON_LIST_SPEC) + { + float[] make_probability_socket = { ess.make_probability_socket0, ess.make_probability_socket1, ess.make_probability_socket2 }; + hole_num = (short)element_data.RandSelect_SPECIFIC_MIDDLE(make_probability_socket.ToList(), SPECIFIC.SPECIFIC_RAND, MIDDLE.MIDDLE_TREND); //�׶�����Ŀ + } + size += (uint)(hole_num*sizeof(int)); // size ����hole_num������type + size += (uint)Marshal.SizeOf(typeof(item_tag_t)); + uint candidate_num = itemdataman.ELEMENTDATAMAN_MAX_NUM_ADDONS; + byte[] addon_buf = new byte[candidate_num*Marshal.SizeOf(typeof(itemdataman._addon))]; + float[] probability_addon_num = { ess.probability_addon_num0, ess.probability_addon_num1, ess.probability_addon_num2, ess.probability_addon_num3, ess.probability_addon_num4 }; + uint addon_num = (uint)element_data.RandSelect_SPECIFIC_LOWER(probability_addon_num.ToList(), SPECIFIC.SPECIFIC_RAND, LOWER.LOWER_TREND); //���Ա���Ŀ����Ŀ + uint addon_size = 0; + if(ess.fixed_props!=0) + { + List addon_list = ess.addons.Select(a => (int)a.id_addon).ToList(); + addon_size = itemdataman.generate_equipment_addon_buffer_2(DATA_TYPE.DT_ARMOR_ESSENCE, addon_list, addon_buf,0, addon_num); + } + else + { + if(normal_addon == GEN_ADDON_MODE.ADDON_LIST_DROP) + { + List addon_list = ess.addons.Select(a => (int)a.id_addon).ToList(); + addon_size = itemdataman.generate_equipment_addon_buffer(DATA_TYPE.DT_ARMOR_ESSENCE, addon_list, (int)candidate_num, addon_buf,0, addon_num); + } + else if(normal_addon == GEN_ADDON_MODE.ADDON_LIST_PRODUCE) + { + List addon_list = ess.rands.Select(a => (int)a.id_rand).ToList(); + addon_size = itemdataman.generate_equipment_addon_buffer(DATA_TYPE.DT_ARMOR_ESSENCE, addon_list, (int)candidate_num, addon_buf,0, addon_num); + } + else if(normal_addon == GEN_ADDON_MODE.ADDON_LIST_SPEC) + { + addon_size = itemdataman.generate_spec_addon_buffer(DATA_TYPE.DT_ARMOR_ESSENCE,addon_buf,0,itemdataman.ELEMENTDATAMAN_MAX_NUM_ADDONS, addon_num,sa_list); + } + else + { + addon_size = 0; + addon_num = 0; + } + } + size += addon_size; + data = new byte[size]; + WriteUInt(data, ref offset, id); + WriteUInt(data, ref offset, 1); + WriteInt(data, ref offset, ess.pile_num_max); + object sub_type_temp = itemdataman._edm.get_data_ptr(ess.id_sub_type, ID_SPACE.ID_SPACE_ESSENCE, ref datatype); + if(sub_type_temp == null || datatype != DATA_TYPE.DT_ARMOR_SUB_TYPE) + { + return -1; + } + else + { + ARMOR_SUB_TYPE sub_type = (ARMOR_SUB_TYPE)sub_type_temp; + WriteUInt(data, ref offset, sub_type.equip_mask|((addon_num > 0)?itemdataman.ELEMENTDATAMAN_EQUIP_MASK_HAS_ADDON:0)); + } + WriteUInt(data, ref offset, ess.proc_type); + WriteInt(data, ref offset, (int)DATA_TYPE.DT_ARMOR_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, ess.price); + 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); + + int require_ptr = offset; + WriteShort(data, ref offset, (short)ess.require_level); + WriteShort(data, ref offset, (short)(ess.character_combo_id&0xFFFF)); + WriteShort(data, ref offset, (short)ess.require_strength); + WriteShort(data, ref offset, (short)ess.require_tili); + WriteShort(data, ref offset, (short)ess.require_agility); + WriteShort(data, ref offset, (short)ess.require_energy); + + int temp2 = element_data.RandNormal_NORMAL_LOWER(ess.durability_min, ess.durability_max, NORMAL.NORMAL_RAND, LOWER.LOWER_TREND); + int temp = temp2; + if(normal_addon != GEN_ADDON_MODE.ADDON_LIST_DROP || (ess.proc_type & 0x1000) != 0) + { + temp = temp2; + } + else + { + temp = element_data.RandNormal_NORMAL_UPPER(ess.durability_drop_min, ess.durability_drop_max, NORMAL.NORMAL_RAND, UPPER.UPPER_TREND); + if(temp > temp2) temp = temp2; + } + WriteInt(data, ref offset, temp); // durability + WriteInt(data, ref offset, temp2); // max_durability + + WriteShort(data, ref offset, (short)Marshal.SizeOf(typeof(ARMOR_ESSENCE))); + WriteTag(data, ref offset, tag); + int essence_ptr = offset; + WriteInt(data, ref offset, element_data.RandNormal_NORMAL_LOWER(ess.defence_low, ess.defence_high, NORMAL.NORMAL_RAND, LOWER.LOWER_TREND)); + WriteInt(data, ref offset, element_data.RandNormal_NORMAL_LOWER(ess.armor_enhance_low, ess.armor_enhance_high, NORMAL.NORMAL_RAND, LOWER.LOWER_TREND)); + WriteInt(data, ref offset, element_data.RandNormal_NORMAL_LOWER(ess.mp_enhance_low, ess.mp_enhance_high, NORMAL.NORMAL_RAND, LOWER.LOWER_TREND)); + WriteInt(data, ref offset, element_data.RandNormal_NORMAL_LOWER(ess.hp_enhance_low, ess.hp_enhance_high, NORMAL.NORMAL_RAND, LOWER.LOWER_TREND)); + int[] res = {0,0,0,0,0}; + List res_list = ess.magic_defences.ToList(); + generate_magic_defense(res, res_list, cls, ess.force_all_magic_defences != 0 || ess.fixed_props!=0); + WriteInt(data, ref offset, res[0]); + WriteInt(data, ref offset, res[1]); + WriteInt(data, ref offset, res[2]); + WriteInt(data, ref offset, res[3]); + WriteInt(data, ref offset, res[4]); + WriteShort(data, ref offset, hole_num); + WriteShort(data, ref offset, 0); + for(i = 0; i < hole_num; i++) + { + WriteInt(data, ref offset, 0); + } + WriteInt(data, ref offset, (int)addon_num); + int addon_sld = offset; + addon_data addon_data = new addon_data(); + prerequisition prerequisition = new prerequisition(); + // Read prerequisition from data buffer (where it was written) once before the loop + int require_ptr_copy_armor = require_ptr; + ReadPrerequisition(data, ref require_ptr_copy_armor, out prerequisition); + for(i = 0; i < addon_num; i++) + { + ReadInt(addon_buf, ref addon_sld, out addon_data.id); + ReadAddonData(addon_buf, ref addon_sld, out addon_data); + itemdataman.addon_update_ess_data(addon_data, essence_ptr, Marshal.SizeOf(typeof(_weapon_essence)), prerequisition); + addon_sld += ((addon_data.id & 0x6000)>>13)*sizeof(int)+sizeof(int); + } + itemdataman.update_require_data(ref prerequisition); + // Write updated prerequisition back to data buffer + int require_ptr_write_armor = require_ptr; + WritePrerequisition(data, ref require_ptr_write_armor, prerequisition); + if(addon_size > 0) + { + Array.Copy(addon_buf, 0, data, offset, (int)addon_size); + offset += (int)addon_size; + } + itemdataman.set_to_classid(DATA_TYPE.DT_ARMOR_ESSENCE, data, -1); + return 0; + } public static int generate_tasknormalmatter(uint id, ID_SPACE idspace, out byte[] data, out uint size, RAND_CLASS cls, GEN_ADDON_MODE normal_addon ,item_tag_t tag,List sa_list = null) { @@ -370,6 +607,8 @@ public static class generate_item_temp itemdataman.set_to_classid(DATA_TYPE.DT_TASKNORMALMATTER_ESSENCE, data, -1); return 0; } + + #region Write Functions private static void WriteUInt(byte[] buf, ref int offset, uint value) { Array.Copy(BitConverter.GetBytes(value), 0, buf, offset, 4); @@ -392,9 +631,9 @@ public static class generate_item_temp } private static void WriteTag(byte[] buf, ref int offset, item_tag_t tag) { - Array.Copy(BitConverter.GetBytes(tag.type), 0, buf, offset, 1); + buf[offset] = tag.type; offset = offset + 1; - Array.Copy(BitConverter.GetBytes(tag.size), 0, buf, offset, 1); + buf[offset] = tag.size; offset = offset + 1; } private static void WriteAddonData(byte[] buf, ref int offset, addon_data value) @@ -405,6 +644,13 @@ public static class generate_item_temp WriteInt(buf, ref offset, value.arg[i]); } } + private static void WriteByte(byte[] buf, ref int offset, byte value) + { + buf[offset] = value; + offset = offset + 1; + } + #endregion + #region Read Functions private static void ReadInt(byte[] buf, ref int offset, out int value) { value = BitConverter.ToInt32(buf, offset); @@ -431,5 +677,557 @@ public static class generate_item_temp offset = offset + 2; value.strength = BitConverter.ToInt16(buf, offset); offset = offset + 2; + value.vitality = BitConverter.ToInt16(buf, offset); + offset = offset + 2; + value.agility = BitConverter.ToInt16(buf, offset); + offset = offset + 2; + value.energy = BitConverter.ToInt16(buf, offset); + offset = offset + 2; + value.durability = BitConverter.ToInt32(buf, offset); + offset = offset + 4; + value.max_durability = BitConverter.ToInt32(buf, offset); + offset = offset + 4; } -} \ No newline at end of file + private static void WritePrerequisition(byte[] buf, ref int offset, prerequisition value) + { + WriteShort(buf, ref offset, value.level); + WriteShort(buf, ref offset, value.race); + WriteShort(buf, ref offset, value.strength); + WriteShort(buf, ref offset, value.vitality); + WriteShort(buf, ref offset, value.agility); + WriteShort(buf, ref offset, value.energy); + WriteInt(buf, ref offset, value.durability); + WriteInt(buf, ref offset, value.max_durability); + } + #endregion + + private static void PrintData(byte[] buf, int offset, int size) + { + for(int i = offset; i < offset + size; i++) + { + BMLogger.Log("[thn]PrintData: buf[" + i + "]: " + buf[i]); + } + } + private static void PrintPreData(byte[] buf, int offset, int size) + { + for(int i = offset-1; i >= offset - size; i--) + { + BMLogger.Log("[thn]PrintPreData: buf[" + i + "]: " + buf[i]); + } + } +} + +#region unimplemented + +// template +// int generate_projectile(unsigned int id, ID_SPACE idspace, char ** data, size_t& size, RAND_CLASS cls) +// { +// DATA_TYPE datatype; +// PROJECTILE_ESSENCE * ess = (PROJECTILE_ESSENCE *)get_data_ptr(id, idspace, datatype); +// if(ess == NULL || datatype != DT_PROJECTILE_ESSENCE) return -1; + +// size = sizeof(item_data) + sizeof(_item_content) + sizeof(_projectile_essence); +// // �޿׶� +// // �̶�addons 4�� +// char addon_buf[ELEMENTDATAMAN_MAX_NUM_ADDONS*sizeof(_addon)]; +// unsigned int addon_num = 4; //���Ա���Ŀ����Ŀ�̶� 4 + +// size_t addon_size = generate_equipment_addon_buffer_2(DT_PROJECTILE_ESSENCE, (int*)&(ess->id_addon0),sizeof(int), 4, addon_buf,addon_num); +// size += addon_size; + +// //����tag size +// size += sizeof(short); + +// // allocate the buffer with exact length +// *data = (char *)abase::fastalloc(size); +// char * buf = *data; + +// *(unsigned int*)buf = id; buf += sizeof(unsigned int); //��Ʒ��ģ��ID +// *(size_t*)buf = 1; buf += sizeof(size_t); //��Ʒ������ +// *(size_t*)buf = ess->pile_num_max; buf += sizeof(size_t); //��Ʒ�Ķѵ����� +// *(int*)buf = ELEMENTDATAMAN_EQUIP_MASK_PROJECTILE|(addon_num?0x40000000:0); buf += sizeof(int); //��Ʒ�Ŀ�װ����־ +// *(int*)buf = ess->proc_type; buf += sizeof(int); //��Ʒ�Ĵ�����ʽ +// *(int*)buf = DT_PROJECTILE_ESSENCE; buf += sizeof(int); //��Ʒ��Ӧ�����ID +// if(ess->has_guid == 1){ +// int g1,g2; +// get_item_guid(id,g1,g2); +// *(int*)buf = g1; buf += sizeof(int); //��Ʒ��Ӧ�����ID guid +// *(int*)buf = g2; buf += sizeof(int); //��Ʒ��Ӧ�����ID guid +// } +// else{ +// *(int*)buf = 0; buf += sizeof(int); //��Ʒ��Ӧ�����ID guid +// *(int*)buf = 0; buf += sizeof(int); //��Ʒ��Ӧ�����ID guid +// } +// *(int*)buf = ess->price; buf += sizeof(int); //��Ʒ�ļ۸� +// *(int*)buf = 0; buf += sizeof(int); //����ʱ�� +// size_t* content_length = (size_t*)buf; buf += sizeof(size_t); //��סbuf��ָ�룬�Ժ����� +// char ** item_content = (char **)buf; buf += sizeof(char *); //��סbuf��ָ�룬�Ժ����� +// *content_length = (char*)(*data)+size-buf; +// *item_content = buf; + +// // prerequisition +// char * require_ptr = buf; +// //����int����6�� +// *(short*)buf = 0; buf += sizeof(short); //prerequisition level +// *(short*)buf = (short)0xFFFF; buf += sizeof(short); +// *(short*)buf = 0; buf += sizeof(short); //prerequisition strength +// *(short*)buf = 0; buf += sizeof(short); +// *(short*)buf = 0; buf += sizeof(short); //prerequisition agility +// *(short*)buf = 0; buf += sizeof(short); + +// *(int*)buf = 1; buf += sizeof(int); //prerequisition durability +// *(int*)buf = 1; buf += sizeof(int); //prerequisition max_durability +// *(short*)buf = sizeof(_projectile_essence); buf += sizeof(short); //װ�������С���ֽڣ� +// *(char*)buf = element_data::IMT_NULL;buf += sizeof(char); +// *(char*)buf = 0; buf += sizeof(char); + +// // projectile_essence ���� +// char * essence_ptr = buf; +// *(int*)buf = ess->type; buf += sizeof(int); //��ҩ���� +// *(int*)buf = ess->damage_enhance; buf += sizeof(int); //���������Ĺ����� +// *(int*)buf = ess->damage_scale_enhance; buf += sizeof(int); //���ձ������ӹ����� +// *(int*)buf = ess->require_weapon_level_min; buf += sizeof(int); //��Ҫ�����ȼ� +// *(int*)buf = ess->require_weapon_level_max; buf += sizeof(int); //��Ҫ�����ȼ� + +// // �׶� +// *(short*)buf = 0; buf += sizeof(short); +// *(short*)buf = 0; buf += sizeof(short); + + +// // addon +// *(int*)buf = addon_num; buf += sizeof(int); + +// char * addon_sld = addon_buf; +// for(size_t i=0; i>13)*sizeof(int)+sizeof(int); +// } +// update_require_data((prerequisition*)require_ptr); +// memcpy(buf, addon_buf, addon_size); +// set_to_classid(DT_PROJECTILE_ESSENCE, (item_data*)(*data), -1); + +// return 0; +// } +// template +// int generate_quiver(unsigned int id, ID_SPACE idspace, char ** data, size_t& size, RAND_CLASS cls) +// { +// DATA_TYPE datatype; +// QUIVER_ESSENCE * ess = (QUIVER_ESSENCE *)get_data_ptr(id, ID_SPACE_ESSENCE, datatype); +// if(ess == NULL || datatype != DT_QUIVER_ESSENCE) return -1; +// datatype = DT_PROJECTILE_ESSENCE; +// //���ﲻ����dup��ʽ +// // if(generate_projectile(ess->id_projectile, ID_SPACE_ESSENCE, (char **)data, size, cls) == 0) +// int ret = duplicate_static_item(id, data,size); +// if(ret == 0) +// { +// ASSERT(ess->num_max < (int)((item_data*)(*data))->pile_limit); +// ((item_data*)(*data))->count = element_data::RandNormal(ess->num_min,ess->num_max,cls,element_data::LOWER_TREND); +// return 0; +// } +// else +// return -1; +// /* { +// ASSERT(ess->num_max < (int)((item_data*)(*data))->pile_limit); +// ((item_data*)(*data))->count = element_data::RandNormal(ess->num_min,ess->num_max,cls); +// return 0; +// } +// else +// return -1; +// */ +// } + + +// template +// int generate_quiver_for_sell(unsigned int id, ID_SPACE idspace, char ** data, size_t& size, RAND_CLASS cls) +// { +// DATA_TYPE datatype; +// QUIVER_ESSENCE * ess = (QUIVER_ESSENCE *)get_data_ptr(id, ID_SPACE_ESSENCE, datatype); +// if(ess == NULL || datatype != DT_QUIVER_ESSENCE) return -1; +// datatype = DT_PROJECTILE_ESSENCE; +// //�����޷���dup����Ϊ���� +// if(generate_projectile(ess->id_projectile, ID_SPACE_ESSENCE, (char **)data, size, cls) == 0) +// { +// ASSERT(ess->num_max < (int)((item_data*)(*data))->pile_limit); +// ((item_data*)(*data))->count = element_data::RandNormal(ess->num_min,ess->num_max,cls,element_data::LOWER_TREND); +// return 0; +// } +// else +// return -1; +// } + +// template +// int generate_decoration(unsigned int id, ID_SPACE idspace, char ** data, size_t& size, RAND_CLASS cls,element_data::GEN_ADDON_MODE normal_addon,const void * tag,size_t tag_size, int * sa_list = NULL) +// { +// DATA_TYPE datatype; +// size_t i=0; +// DECORATION_ESSENCE * ess = (DECORATION_ESSENCE *)get_data_ptr(id, idspace, datatype); +// if(ess == NULL || datatype != DT_DECORATION_ESSENCE) return -1; + +// size = sizeof(item_data) + sizeof(_item_content) + sizeof(_decoration_essence); +// // �׶� +// unsigned int hole_num = 0; //�׶�����Ŀ + +// // ���addons +// char addon_buf[ELEMENTDATAMAN_MAX_NUM_ADDONS*sizeof(_addon)]; +// unsigned int addon_num = element_data::RandSelect(&(ess->probability_addon_num0),sizeof(float), 5,cls,element_data::LOWER_TREND); //���Ա���Ŀ����Ŀ + +// size_t addon_size = 0; +// if(ess->fixed_props) +// { +// addon_size = generate_equipment_addon_buffer_2(DT_DECORATION_ESSENCE, (int*)&(ess->addons[0]), sizeof(int)+sizeof(float),32, addon_buf,addon_num); +// } +// else +// { +// if(normal_addon == element_data::ADDON_LIST_DROP) +// addon_size = generate_equipment_addon_buffer(DT_DECORATION_ESSENCE, (char*)&(ess->addons[0]), 32, addon_buf,addon_num); +// else if(normal_addon == element_data::ADDON_LIST_PRODUCE) +// addon_size = generate_equipment_addon_buffer(DT_DECORATION_ESSENCE, (char*)&(ess->rands[0]), 32, addon_buf,addon_num); +// else if (normal_addon == element_data::ADDON_LIST_SPEC) +// { +// addon_size = generate_spec_addon_buffer(DT_DECORATION_ESSENCE,addon_buf,ELEMENTDATAMAN_MAX_NUM_ADDONS,addon_num,sa_list); +// } +// else +// { +// addon_size = 0; +// addon_num = 0; +// } +// } +// size += addon_size; + +// //����tag size +// ASSERT(tag_size >= sizeof(short)); +// size += tag_size; + + +// // allocate the buffer with exact length +// *data = (char *)abase::fastalloc(size); +// char * buf = (*data); + + +// *(unsigned int*)buf = id; buf += sizeof(unsigned int); //��Ʒ��ģ��ID +// *(size_t*)buf = 1; buf += sizeof(size_t); //��Ʒ������ +// *(size_t*)buf = ess->pile_num_max; buf += sizeof(size_t); //��Ʒ�Ķѵ����� +// DECORATION_SUB_TYPE* sub_type = (DECORATION_SUB_TYPE*)get_data_ptr(ess->id_sub_type, ID_SPACE_ESSENCE, datatype); +// if(sub_type == NULL || datatype != DT_DECORATION_SUB_TYPE) // error +// return -1; +// *(int*)buf = sub_type->equip_mask|(addon_num?ELEMENTDATAMAN_EQUIP_MASK_HAS_ADDON:0); buf += sizeof(int); //��Ʒ�Ŀ�װ����־ +// *(int*)buf = ess->proc_type; buf += sizeof(int); //��Ʒ�Ĵ�����ʽ +// *(int*)buf = DT_DECORATION_ESSENCE; buf += sizeof(int); //��Ʒ��Ӧ�����ID +// if(ess->has_guid == 1){ +// int g1,g2; +// get_item_guid(id,g1,g2); +// *(int*)buf = g1; buf += sizeof(int); //��Ʒ��Ӧ�����ID guid +// *(int*)buf = g2; buf += sizeof(int); //��Ʒ��Ӧ�����ID guid +// } +// else{ +// *(int*)buf = 0; buf += sizeof(int); //��Ʒ��Ӧ�����ID guid +// *(int*)buf = 0; buf += sizeof(int); //��Ʒ��Ӧ�����ID guid +// } +// *(int*)buf = ess->price; buf += sizeof(int); //��Ʒ�ļ۸� +// *(int*)buf = 0; buf += sizeof(int); //����ʱ�� +// size_t* content_length = (size_t*)buf; buf += sizeof(size_t); //��סbuf��ָ�룬�Ժ����� +// char ** item_content = (char **)buf; buf += sizeof(char *); //��סbuf��ָ�룬�Ժ����� +// *content_length = (char*)(*data)+size-buf; +// *item_content = buf; + +// // prerequisition +// char * require_ptr = buf; +// *(short*)buf = ess->require_level; buf += sizeof(short); //prerequisition level +// *(short*)buf = ess->character_combo_id&0xFFFF; buf += sizeof(short); //prerequisition race +// *(short*)buf = ess->require_strength; buf += sizeof(short); //prerequisition strength +// *(short*)buf = ess->require_tili; buf += sizeof(short); //prerequisition val +// *(short*)buf = ess->require_agility; buf += sizeof(short); //prerequisition agility +// *(short*)buf = ess->require_energy; buf += sizeof(short); //prerequisition energy + +// int temp2 = element_data::RandNormal(ess->durability_min, ess->durability_max, cls,element_data::LOWER_TREND); +// int temp; +// if(normal_addon != element_data::ADDON_LIST_DROP || ess->proc_type & 0x1000) +// { +// temp = temp2; +// } +// else +// { +// temp = element_data::RandNormal(ess->durability_drop_min, ess->durability_drop_max, cls,element_data::UPPER_TREND); +// if(temp > temp2) temp = temp2; +// } +// *(int*)buf = temp; buf += sizeof(int); //prerequisition durability +// *(int*)buf = temp2; buf += sizeof(int); //prerequisition max_durability + +// //���������߱�ǩע���ǩ���ڱ����С�ͱ�������֮�� +// *(short*)buf = sizeof(_decoration_essence); buf += sizeof(short); //װ�������С���ֽڣ� +// memcpy(buf,tag,tag_size); +// buf += tag_size; + + +// // ���� +// char * essence_ptr = buf; +// *(int*)buf = element_data::RandNormal(ess->damage_low, ess->damage_high, cls,element_data::LOWER_TREND); buf += sizeof(int); //int damage; +// *(int*)buf = element_data::RandNormal(ess->magic_damage_low, ess->magic_damage_high, cls,element_data::LOWER_TREND); buf += sizeof(int); //int magic_damage; +// *(int*)buf = element_data::RandNormal(ess->defence_low, ess->defence_high, cls,element_data::LOWER_TREND); buf += sizeof(int); //int defense; +// *(int*)buf = element_data::RandNormal(ess->armor_enhance_low, ess->armor_enhance_high, cls,element_data::LOWER_TREND); buf += sizeof(int); //int armor; + +// //���� +// int res[5] = {0,0,0,0,0}; +// generate_magic_defense(res,(int*)(ess->magic_defences),cls,ess->fixed_props!=0); + +// *(int*)buf = res[0]; buf += sizeof(int); +// *(int*)buf = res[1]; buf += sizeof(int); +// *(int*)buf = res[2]; buf += sizeof(int); +// *(int*)buf = res[3]; buf += sizeof(int); +// *(int*)buf = res[4]; buf += sizeof(int); + +// // �׶� +// *(short*)buf = hole_num; buf += sizeof(short); //�׶�����Ŀ +// *(short*)buf = 0; buf += sizeof(short); //�׶��������������� + +// // addon +// *(int*)buf = addon_num; buf += sizeof(int); +// char * addon_sld = addon_buf; +// for(i=0; i>13)*sizeof(int)+sizeof(int); +// } +// update_require_data((prerequisition*)require_ptr); +// memcpy(buf, addon_buf, addon_size); +// set_to_classid(DT_DECORATION_ESSENCE, (item_data*)(*data), -1); + +// return 0; +// } + +// template +// int generate_stone(unsigned int id, ID_SPACE idspace, char ** data, size_t& size, RAND_CLASS cls) +// { +// DATA_TYPE datatype; +// STONE_ESSENCE * ess = (STONE_ESSENCE *)get_data_ptr(id, idspace, datatype); +// if(ess == NULL || datatype != DT_STONE_ESSENCE) return -1; + + +// char addon_buf[ELEMENTDATAMAN_MAX_NUM_ADDONS*sizeof(_addon)]; +// int *pBuf = (int*)addon_buf; +// *pBuf = 1; //only one weapon addon now +// size_t addon_size = generate_addon_buffer(datatype,ess->id_addon_damage, (char*)(pBuf + 1)); +// if(addon_size) +// { +// pBuf = (int*)(((char*)(pBuf+1)) + addon_size); +// } +// else +// { +// ASSERT(false); +// return -1; +// } + +// *pBuf = 1; //only one armor addon now +// addon_size = generate_addon_buffer(datatype,ess->id_addon_defence, (char*)(pBuf + 1)); +// if(addon_size) +// { +// pBuf = (int*)(((char*)(pBuf+1)) + addon_size); +// } +// else +// { +// ASSERT(false); +// return -1; +// } + +// size_t ess_size = ((char*)pBuf) - addon_buf; +// size = sizeof(item_data) + ess_size; + +// // allocate the buffer with exact length +// *data = (char *)abase::fastalloc(size); +// char *buf = *data; +// *(unsigned int*)buf = id; buf += sizeof(unsigned int); //��Ʒ��ģ��ID +// *(size_t*)buf = 1; buf += sizeof(size_t); //��Ʒ������ +// *(size_t*)buf = ess->pile_num_max;buf += sizeof(size_t); //��Ʒ�Ķѵ����� +// *(int*)buf = 0; buf += sizeof(int); //��Ʒ�Ŀ�װ����־ +// *(int*)buf = ess->proc_type; buf += sizeof(int); //��Ʒ�Ĵ�����ʽ +// *(int*)buf = DT_STONE_ESSENCE; buf += sizeof(int); //��Ʒ��Ӧ�����ID +// *(int*)buf = 0; buf += sizeof(int); //��Ʒ��Ӧ�����ID guid +// *(int*)buf = 0; buf += sizeof(int); //��Ʒ��Ӧ�����ID guid +// *(int*)buf = ess->price; buf += sizeof(int); //��Ʒ�ļ۸� +// *(int*)buf = 0; buf += sizeof(int); //����ʱ�� +// size_t* content_length = (size_t*)buf; buf += sizeof(size_t); //��סbuf��ָ�룬�Ժ����� +// char ** item_content = (char **)buf; buf += sizeof(char *); //��סbuf��ָ�룬�Ժ����� +// *content_length = size - (buf - (char*)(*data)); +// *item_content = buf; +// memcpy(buf, addon_buf, ess_size); +// set_to_classid(DT_STONE_ESSENCE, (item_data*)(*data), -1); +// return 0; +// } + +// template +// int generate_medicine(unsigned int id, ID_SPACE idspace, char ** data, size_t& size, RAND_CLASS cls) +// { +// DATA_TYPE datatype; +// MEDICINE_ESSENCE * ess = (MEDICINE_ESSENCE *)get_data_ptr(id, idspace, datatype); +// if(ess == NULL || datatype != DT_MEDICINE_ESSENCE) return -1; + +// size = sizeof(item_data); + +// switch(ess->id_major_type) +// { +// case 1794: // ��Ѫ���� +// case 1802: // ��ħ���� +// case 1810: // ��Ѫ��ħ���� +// size += sizeof(size_t) + sizeof(int) + sizeof(int) + sizeof(int); +// break; +// case 1815: // �ⶾҩ +// case 2038: // ˲��ⶾҩ +// size += sizeof(int) + sizeof(int); +// break; +// default: +// return -1; +// } + +// // allocate the buffer with exact length +// *data = (char *)abase::fastalloc(size); +// char * buf = (*data); + +// *(unsigned int*)buf = id; buf += sizeof(unsigned int); //��Ʒ��ģ��ID +// *(size_t*)buf = 1; buf += sizeof(size_t); //��Ʒ������ +// *(size_t*)buf = ess->pile_num_max; buf += sizeof(size_t); //��Ʒ�Ķѵ����� +// *(int*)buf = 0; buf += sizeof(int); //��Ʒ�Ŀ�װ����־ +// *(int*)buf = ess->proc_type; buf += sizeof(int); //��Ʒ�Ĵ�����ʽ +// *(int*)buf = DT_MEDICINE_ESSENCE; buf += sizeof(int); //��Ʒ��Ӧ�����ID +// if(ess->has_guid == 1){ +// int g1,g2; +// get_item_guid(id,g1,g2); +// *(int*)buf = g1; buf += sizeof(int); //��Ʒ��Ӧ�����ID guid +// *(int*)buf = g2; buf += sizeof(int); //��Ʒ��Ӧ�����ID guid +// } +// else{ +// *(int*)buf = 0; buf += sizeof(int); //��Ʒ��Ӧ�����ID guid +// *(int*)buf = 0; buf += sizeof(int); //��Ʒ��Ӧ�����ID guid +// } +// *(int*)buf = ess->price; buf += sizeof(int); //��Ʒ�ļ۸� +// *(int*)buf = 0; buf += sizeof(int); //����ʱ�� +// size_t* content_length = (size_t*)buf; buf += sizeof(size_t); //��סbuf��ָ�룬�Ժ����� +// char ** item_content = (char **)buf; buf += sizeof(char *); //��סbuf��ָ�룬�Ժ����� +// *content_length = (char*)(*data)+size-buf; +// *item_content = buf; + +// switch(ess->id_major_type) +// { +// case 1794: // ��Ѫ���� +// if(ess->cool_time < 1000) ess->cool_time *= 100; +// *(int*)buf = ess->hp_add_total; buf += sizeof(int); +// *(int*)buf = ess->hp_add_time; buf += sizeof(int); +// *(int*)buf = ess->cool_time; buf += sizeof(int); +// *(int*)buf = ess->require_level; buf += sizeof(int); +// ASSERT(ess->hp_add_time && ess->hp_add_total); +// ASSERT(ess->hp_add_total/ess->hp_add_time); +// break; +// case 1802: // ��ħ���� +// if(ess->cool_time < 1000) ess->cool_time *= 100; +// *(int*)buf = ess->mp_add_total; buf += sizeof(int); +// *(int*)buf = ess->mp_add_time; buf += sizeof(int); +// *(int*)buf = ess->cool_time; buf += sizeof(int); +// *(int*)buf = ess->require_level; buf += sizeof(int); +// ASSERT(ess->mp_add_time && ess->mp_add_total); +// ASSERT(ess->mp_add_total/ess->mp_add_time); +// break; +// case 1810: // ��Ѫ��ħ���� +// if(ess->cool_time < 1000) ess->cool_time *= 100; +// *(int*)buf = ess->mp_add_total; buf += sizeof(int); +// *(int*)buf = ess->hp_add_total; buf += sizeof(int); +// *(int*)buf = ess->cool_time; buf += sizeof(int); +// *(int*)buf = ess->require_level; buf += sizeof(int); +// ASSERT(ess->hp_add_time || ess->mp_add_total); +// break; +// case 1815: // �ⶾҩ +// case 2038: // ˲��ⶾҩ +// if(ess->cool_time < 1000) ess->cool_time *= 100; +// *(int*)buf = ess->cool_time; buf += sizeof(int); +// *(int*)buf = ess->require_level; buf += sizeof(int); +// break; +// default: +// return -1; +// } +// set_to_classid(DT_MEDICINE_ESSENCE, (item_data*)(*data), ess->id_major_type); + +// return 0; +// } + +// template +// int generate_material(unsigned int id, ID_SPACE idspace, char ** data, size_t& size, ESSENCE * p, DATA_TYPE DTYPE) +// { +// DATA_TYPE datatype; +// ESSENCE * ess = (ESSENCE *)get_data_ptr(id, idspace, datatype); +// if(ess == NULL || datatype != DTYPE) return -1; + +// size = sizeof(item_data) ; + +// // allocate the buffer with exact length +// *data = (char *)abase::fastalloc(size); +// char * buf = (*data); + +// *(unsigned int*)buf = id; buf += sizeof(unsigned int); //��Ʒ��ģ��ID +// *(size_t*)buf = 1; buf += sizeof(size_t); //��Ʒ������ +// *(size_t*)buf = ess->pile_num_max; buf += sizeof(size_t); //��Ʒ�Ķѵ����� +// *(int*)buf = 0; buf += sizeof(int); //��Ʒ�Ŀ�װ����־ +// *(int*)buf = ess->proc_type; buf += sizeof(int); //��Ʒ�Ĵ�����ʽ +// *(int*)buf = DTYPE; buf += sizeof(int); //��Ʒ��Ӧ�����ID +// if(ess->has_guid == 1){ +// int g1,g2; +// get_item_guid(id,g1,g2); +// *(int*)buf = g1; buf += sizeof(int); //��Ʒ��Ӧ�����ID guid +// *(int*)buf = g2; buf += sizeof(int); //��Ʒ��Ӧ�����ID guid +// } +// else{ +// *(int*)buf = 0; buf += sizeof(int); //��Ʒ��Ӧ�����ID guid +// *(int*)buf = 0; buf += sizeof(int); //��Ʒ��Ӧ�����ID guid +// } +// *(int*)buf = ess->price; buf += sizeof(int); //��Ʒ�ļ۸� +// *(int*)buf = 0; buf += sizeof(int); //����ʱ�� +// size_t* content_length = (size_t*)buf; buf += sizeof(size_t); //��סbuf��ָ�룬�Ժ����� +// char ** item_content = (char **)buf; buf += sizeof(char *); //��סbuf��ָ�룬�Ժ����� +// *content_length = (char*)(*data)+size-buf; +// *item_content = buf; + +// set_to_classid(DTYPE, (item_data*)(*data), -1); +// return 0; +// } + +// template +// int generate_skilltome(unsigned int id, ID_SPACE idspace, char ** data, size_t& size, RAND_CLASS cls) +// { +// DATA_TYPE datatype; +// SKILLTOME_ESSENCE * ess = (SKILLTOME_ESSENCE *)get_data_ptr(id, idspace, datatype); +// if(ess == NULL || datatype != DT_SKILLTOME_ESSENCE) return -1; + +// size = sizeof(item_data); + +// // allocate the buffer with exact length +// *data = (char *)abase::fastalloc(size); +// char * buf = (*data); + +// *(unsigned int*)buf = id; buf += sizeof(unsigned int); //��Ʒ��ģ��ID +// *(size_t*)buf = 1; buf += sizeof(size_t); //��Ʒ������ +// *(size_t*)buf = ess->pile_num_max; buf += sizeof(size_t); //��Ʒ�Ķѵ����� +// *(int*)buf = 0; buf += sizeof(int); //��Ʒ�Ŀ�װ����־ +// *(int*)buf = ess->proc_type; buf += sizeof(int); //��Ʒ�Ĵ�����ʽ +// *(int*)buf = DT_SKILLTOME_ESSENCE; buf += sizeof(int); //��Ʒ��Ӧ�����ID +// if(ess->has_guid == 1){ +// int g1,g2; +// get_item_guid(id,g1,g2); +// *(int*)buf = g1; buf += sizeof(int); //��Ʒ��Ӧ�����ID guid +// *(int*)buf = g2; buf += sizeof(int); //��Ʒ��Ӧ�����ID guid +// } +// else{ +// *(int*)buf = 0; buf += sizeof(int); //��Ʒ��Ӧ�����ID guid +// *(int*)buf = 0; buf += sizeof(int); //��Ʒ��Ӧ�����ID guid +// } +// *(int*)buf = ess->price; buf += sizeof(int); //��Ʒ�ļ۸� +// *(int*)buf = 0; buf += sizeof(int); //����ʱ�� +// size_t* content_length = (size_t*)buf; buf += sizeof(size_t); //��סbuf��ָ�룬�Ժ����� +// char ** item_content = (char **)buf; buf += sizeof(char *); //��סbuf��ָ�룬�Ժ����� +// *content_length = (char*)(*data)+size-buf; +// *item_content = buf; + +// set_to_classid(DT_SKILLTOME_ESSENCE, (item_data*)(*data), -1); +// return 0; +// } + +#endregion \ No newline at end of file diff --git a/Assets/PerfectWorld/Scripts/Common/DataProcess/itemdataman.cs b/Assets/PerfectWorld/Scripts/Common/DataProcess/itemdataman.cs index 8228de49a7..3f61028741 100644 --- a/Assets/PerfectWorld/Scripts/Common/DataProcess/itemdataman.cs +++ b/Assets/PerfectWorld/Scripts/Common/DataProcess/itemdataman.cs @@ -9,12 +9,7 @@ using System.Runtime.InteropServices; namespace BrewMonster { - public struct LOCATION - { - public DATA_TYPE type; - public object pos; - }; - + namespace abase { public static class abase @@ -24,8 +19,15 @@ namespace BrewMonster { if (upper == lower) return lower; - else - return new System.Random().Next(lower, upper); + // Handle invalid range where lower > upper + if (lower > upper) + { + // Swap values to ensure valid range + int temp = lower; + lower = upper; + upper = temp; + } + return new System.Random().Next(lower, upper); } public static float Rand(float lower, float upper) @@ -164,7 +166,7 @@ namespace BrewMonster { return abase.abase.RandSelect(option); } - public static uint RandSelect_SPECIFIC_LOWER(List option, SPECIFIC specificType, LOWER lowerTrend) + public static int RandSelect_SPECIFIC_LOWER(List option, SPECIFIC specificType, LOWER lowerTrend) { return 0; } @@ -254,11 +256,12 @@ namespace BrewMonster IMT_SIGN, //װ����ǩ�� }; //#pragma pack(1) - public class item_tag_t + [StructLayout(LayoutKind.Sequential, Pack = 1)] + public struct item_tag_t { - public char type; - public char size; - public item_tag_t(char type, char size) + public byte type; + public byte size; + public item_tag_t(byte type, byte size) { this.type = type; this.size = size; @@ -267,6 +270,11 @@ namespace BrewMonster //#pragma pack() };// name space element_data + public struct LOCATION + { + public DATA_TYPE type; + public object pos; + }; public struct guid_t { public int guid1; @@ -286,7 +294,6 @@ namespace BrewMonster public int content_length; public byte[] item_content; }; -// #pragma pack(1) public struct _item_content { public prerequisition preq; @@ -297,15 +304,13 @@ namespace BrewMonster public int num_addon; //���Ա���Ŀ����Ŀ��������; // _addon ad[MAX_NUM_ADDONS]; //[���Ա���Ŀ����Ŀ]; }; -//#pragma pack() - public struct addon_data { public int id; public int[] arg; - public addon_data(int id) { + public addon_data(int id =0) { this.id = id; - arg = new int[]{0,0,0}; + arg = new int[3]{0,0,0}; } }; public struct prerequisition @@ -319,15 +324,17 @@ namespace BrewMonster public int durability; public int max_durability; }; - struct _weapon_essence - { - public enum WEAPON_TYPE + public enum WEAPON_TYPE { WEAPON_TYPE_MELEE = 0, WEAPON_TYPE_RANGE = 1, WEAPON_TYPE_MELEE_ASN = 2, //�̿�ʹ�õĽ���������������Ӱ���﹥�⣬�����������ͬ }; + [StructLayout(LayoutKind.Sequential, Pack = 1)] + public struct _weapon_essence + { + public short weapon_type; //������� ��Ӧģ����Ľ���Զ�̱�־ public short weapon_delay; //�����Ĺ����ӳ�ʱ�䣬��50msΪ��λ public int weapon_class; //�������� ��Ӧģ����Ĵ��� ���絶�� ������ @@ -343,7 +350,7 @@ namespace BrewMonster }; public static class itemdataman { -#region const + #region const public const uint ELEMENTDATAMAN_MAX_NUM_ADDON_PARAM = 3; public struct _addon //������Ŀ { @@ -382,7 +389,7 @@ namespace BrewMonster public const uint ELEMENTDATAMAN_EQUIP_MASK_EXTEND64 = 0x80000000; public const uint ELEMENTDATAMAN_EQUIP_MASK_HIGH = 0xC0000000; #endregion -#endregion + #endregion public static Dictionary sale_item_id_index_map = new Dictionary(); public static elementdataman _edm; @@ -391,6 +398,7 @@ namespace BrewMonster public static int load_data(string pathname, bool disable_bind2) { _edm = ElementDataManProvider.GetElementDataMan(); + generate_item_for_sell(disable_bind2); return 0; // if(await _edm.load_data(pathname) == 0) @@ -404,6 +412,7 @@ namespace BrewMonster public static int generate_item_for_sell(bool disable_bind2) { + //#define CASE_CLEAR_PROC_TYPE(ESSENCE) case DT_##ESSENCE: \ // {\ // DATA_TYPE dt2;\ @@ -415,9 +424,9 @@ namespace BrewMonster uint size = 0; int ret = 0; DATA_TYPE datatype = DATA_TYPE.DT_INVALID; - item_tag_t tag = new item_tag_t((char)ITEM_MAKE_TAG.IMT_SHOP, (char)'0'); + item_tag_t tag = new item_tag_t((byte)ITEM_MAKE_TAG.IMT_SHOP, (byte)'0'); //uint id = _edm.get_first_data_id(ID_SPACE.ID_SPACE_ESSENCE,ref datatype); - + BMLogger.Log("[THN]itemdataman: generate_item_for_sell: _edm.essence_id_data_type_map.Count: " + _edm.essence_id_data_type_map.Count); for (int i = 0; i < _edm.essence_id_data_type_map.Count; i++) { ret = 0; @@ -428,6 +437,10 @@ namespace BrewMonster ret = generate_item_temp.generate_weapon(id,ID_SPACE.ID_SPACE_ESSENCE, out item,out size,SPECIFIC.SPECIFIC_RAND,GEN_ADDON_MODE.ADDON_LIST_SHOP,tag); break; + case DATA_TYPE.DT_ARMOR_ESSENCE: + ret = generate_item_temp.generate_armor(id, ID_SPACE.ID_SPACE_ESSENCE, + out item,out size,SPECIFIC.SPECIFIC_RAND,GEN_ADDON_MODE.ADDON_LIST_SHOP,tag); + 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); @@ -447,10 +460,7 @@ namespace BrewMonster sale_item_id_index_map[id] = loc; } #region unimplemented - // CASE_CLEAR_PROC_TYPE(ARMOR_ESSENCE) - // ret = generate_armor(id, ID_SPACE_ESSENCE, (char**)&item, size, element_data::SPECIFIC(0), element_data::ADDON_LIST_SHOP, &tag, sizeof(tag)); - // break; // CASE_CLEAR_PROC_TYPE(PROJECTILE_ESSENCE) @@ -740,6 +750,7 @@ namespace BrewMonster // } #endregion } + BMLogger.Log("[THN]itemdataman: generate_item_for_sell: sale_item_ptr_array.Count: " + sale_item_ptr_array.Count); return 0; } @@ -770,7 +781,6 @@ namespace BrewMonster // item_content is stored as an offset/pointer in the buffer (points to where content starts) int item_content_offset = BitConverter.ToInt32(buffer, offset); offset += 4; - // Extract the actual content bytes if (item.content_length > 0 && item_content_offset > 0 && item_content_offset < buffer.Length) { @@ -791,7 +801,6 @@ namespace BrewMonster { item.item_content = new byte[0]; } - return item; } @@ -820,23 +829,25 @@ namespace BrewMonster (DATA_TYPE essencetype, List candidate_addon, byte[] addon_buffer, int start_offset, - ref uint addon_num) + uint addon_num) { + //���ɶ��addon�����ܻ��в�������ʧ�� - if(addon_num == 0) return 0; + if(addon_num == 0) + return 0; byte[] addon_sld = addon_buffer; int i,j; int anum = 0; int offset = start_offset; for(i=0; i sa_list) { addon_num = 0; @@ -988,7 +1002,7 @@ namespace BrewMonster } if(i == 0 ) return 0; addon_num = (uint)i; - return generate_equipment_addon_buffer_2(essencetype,sa_list,addon_buffer,start_offset, ref addon_num); + return generate_equipment_addon_buffer_2(essencetype,sa_list,addon_buffer,start_offset, addon_num); } public static void get_item_guid( uint id, out int g1, out int g2) { @@ -998,9 +1012,9 @@ namespace BrewMonster { return EC_Game.addon_update_ess_data(data, essence, ess_size, require); } - public static void update_require_data(prerequisition require) + public static void update_require_data(ref prerequisition require) { - EC_Game.update_require_data(require); + EC_Game.update_require_data(ref require); } public static void set_to_classid(DATA_TYPE type, byte[] data, int major_type) { diff --git a/Assets/PerfectWorld/Scripts/MainFiles/EC_Game.cs b/Assets/PerfectWorld/Scripts/MainFiles/EC_Game.cs index dc3e4f855c..b06afcf91e 100644 --- a/Assets/PerfectWorld/Scripts/MainFiles/EC_Game.cs +++ b/Assets/PerfectWorld/Scripts/MainFiles/EC_Game.cs @@ -23,8 +23,10 @@ namespace BrewMonster.Network private static BrewMonster.CECStringTab m_FixedMsgs; // Fixed message table private static BrewMonster.CECStringTab m_ItemDesc; // Item desciption string table private static BrewMonster.CECStringTab m_ItemExtDesc; // Item extend description string table + private static BrewMonster.CECStringTab m_ItemExtProp; // Item extend prop string table private static BrewMonster.CECStringTab m_SkillDesc = new CECStringTab(); // Skill description string table private static BrewMonster.CECStringTab m_BuffDesc; // Buff description string table + private static Dictionary m_ItemMsgMap; // TemplateId -> (MessageId, DisplayMode) private static CECConfigs m_pConfigs; private static int m_iCurCursor; // Current cursor @@ -69,6 +71,10 @@ namespace BrewMonster.Network { return m_BuffDesc; } + public static BrewMonster.CECStringTab GetItemExtProp() + { + return m_ItemExtProp; + } public static bool TryGetItemMsg(int templateId, out int messageId, out int displayMode) { @@ -132,7 +138,7 @@ namespace BrewMonster.Network m_ItemExtDesc = new BrewMonster.CECStringTab(); m_SkillDesc = new BrewMonster.CECStringTab(); m_BuffDesc = new BrewMonster.CECStringTab(); - + m_ItemExtProp = new BrewMonster.CECStringTab(); try { // Addressables-only loading (no StreamingAssets/configs file IO). @@ -162,7 +168,11 @@ namespace BrewMonster.Network { Debug.LogWarning("[EC_Game] Failed to load skillstr.txt"); } - + var itemExtPropTa = Addressables.LoadAssetAsync("Assets/Addressable/item_ext_prop.txt").WaitForCompletion(); + if (!m_ItemExtProp.InitFromTextAsset(itemExtPropTa, true)) + { + Debug.LogWarning("[EC_Game] Failed to load item_ext_prop.txt"); + } // Note: There's no buff_desc.txt file in the configs folder // You may need to create this file or use a different source for buff descriptions // (If you add it to Addressables later, load it here.) @@ -264,7 +274,7 @@ namespace BrewMonster.Network long unixTime = DateTimeOffset.UtcNow.ToUnixTimeSeconds(); return (int)unixTime + m_iTimeError; } - + #region Dummy Methods for itemdataman public static int addon_generate_arg(DATA_TYPE type, addon_data data, int arg_num/*��ʼ�IJ�������*/) { @@ -279,7 +289,7 @@ namespace BrewMonster.Network { return 0; } - public static void update_require_data(prerequisition require) + public static void update_require_data(ref prerequisition require) { require.durability *= BrewMonster.Scripts.InventoryConst.ENDURANCE_SCALE; require.max_durability *= BrewMonster.Scripts.InventoryConst.ENDURANCE_SCALE; @@ -288,6 +298,7 @@ namespace BrewMonster.Network { } #endregion + #endregion } } \ No newline at end of file diff --git a/Assets/PerfectWorld/Scripts/Managers/EC_InventoryUI.cs b/Assets/PerfectWorld/Scripts/Managers/EC_InventoryUI.cs index 4107c5d1fb..2ec6e46f6e 100644 --- a/Assets/PerfectWorld/Scripts/Managers/EC_InventoryUI.cs +++ b/Assets/PerfectWorld/Scripts/Managers/EC_InventoryUI.cs @@ -293,7 +293,7 @@ namespace BrewMonster.Scripts.Managers equipment.Count = itemData.m_iCount; equipment.PriceScale = 1.0f; equipment.ScaleType = 0; - + // Parse item info if available (use Content field) if (itemData.Content != null && itemData.Content.Length > 0) { @@ -856,7 +856,7 @@ namespace BrewMonster.Scripts.Managers string fullDesc = null; if (showEquipmentDetails && currentSelectedEquipment != null) { - fullDesc = currentSelectedEquipment.GetNormalDesc(); + fullDesc = currentSelectedEquipment.GetDesc(); } else { diff --git a/Assets/PerfectWorld/Scripts/Managers/EC_IvtrEquip.cs b/Assets/PerfectWorld/Scripts/Managers/EC_IvtrEquip.cs index b834389bf0..19ec8ee42d 100644 --- a/Assets/PerfectWorld/Scripts/Managers/EC_IvtrEquip.cs +++ b/Assets/PerfectWorld/Scripts/Managers/EC_IvtrEquip.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; using System.Linq; using UnityEngine; +using UnityEngine.AddressableAssets; using ModelRenderer.Scripts.GameData; using ModelRenderer.Scripts.Common; using BrewMonster; @@ -29,9 +30,15 @@ namespace PerfectWorld.Scripts.Managers public const int ICID_WEAPON = 2; // Item Made From Types - public const byte IMT_NULL = 0; - public const byte IMT_SIGN = 1; - + public enum ITEM_MAKE_TAG + { + IMT_NULL, + IMT_CREATE, // GM ���� + IMT_DROP, // ������� + IMT_SHOP, // �̳ǻ��̵���� + IMT_PRODUCE, // ������ + IMT_SIGN, // װ��ǩ�� + }; // Property Effect Essence Flags public const uint PEE_PHYDAMAGE = 0x00000001; public const uint PEE_MAGICDAMAGE = 0x00000002; @@ -96,7 +103,7 @@ namespace PerfectWorld.Scripts.Managers #endregion - #region Fields + #region Public Fields // Basic Item Properties public int TemplateId { get; set; } @@ -135,11 +142,9 @@ namespace PerfectWorld.Scripts.Managers // Equipment Arrays public List Holes { get; set; } public List Props { get; set; } - - // Description - protected string m_strDesc = ""; - #endregion + + #region Base Stats (from Element Data) @@ -496,7 +501,7 @@ namespace PerfectWorld.Scripts.Managers #region Constructor - public EC_IvtrEquip(int tid, int expireDate) + public EC_IvtrEquip(int tid, int expireDate) : base(tid, expireDate) { TemplateId = tid; ExpireDate = expireDate; @@ -567,8 +572,9 @@ namespace PerfectWorld.Scripts.Managers /// /// Set item detail information from binary data /// - public bool SetItemInfo(byte[] infoData, int dataLen) + public override bool SetItemInfo(byte[] infoData, int dataLen) { + base.SetItemInfo(infoData, dataLen); if (infoData == null || dataLen == 0) return true; @@ -576,6 +582,7 @@ namespace PerfectWorld.Scripts.Managers // [6 x short requirements][2 x int endurance][short essenceSize][maker info][essence bytes][short numHole][WORD stoneMask][numHole x int holes][int numProp][props] if (TryParseEquipInfoNative(infoData, dataLen)) { + BMLogger.Log("CECIvtrEquip::SetItemInfo, native order success"); ParseProperties(); return true; } @@ -583,11 +590,11 @@ namespace PerfectWorld.Scripts.Managers // Fallback to legacy/custom order if server payload differs if (TryParseEquipInfoLegacy(infoData, dataLen)) { + BMLogger.Log("CECIvtrEquip::SetItemInfo, legacy order success"); ParseProperties(); return true; } - Debug.LogError("EC_IvtrEquip::SetItemInfo: could not parse detail payload"); return false; } @@ -595,62 +602,50 @@ namespace PerfectWorld.Scripts.Managers { try { - int offset = 0; - - if (len < 6 * 2 + 2 * 4 + 2) return false; - - LevelReq = BitConverter.ToInt16(data, offset); offset += 2; - ProfReq = BitConverter.ToInt16(data, offset); offset += 2; - StrengthReq= BitConverter.ToInt16(data, offset); offset += 2; - VitalityReq= BitConverter.ToInt16(data, offset); offset += 2; - AgilityReq = BitConverter.ToInt16(data, offset); offset += 2; - EnergyReq = BitConverter.ToInt16(data, offset); offset += 2; - - CurEndurance = BitConverter.ToInt32(data, offset); offset += 4; - MaxEndurance = BitConverter.ToInt32(data, offset); offset += 4; - - int essenceSize = BitConverter.ToInt16(data, offset); offset += 2; - - // Maker info (type + length + payload) - if (offset + 2 <= len) + CECDataReader dr = new CECDataReader(data, len); + LevelReq = dr.ReadShort(); + ProfReq = dr.ReadShort(); + StrengthReq= dr.ReadShort(); + VitalityReq= dr.ReadShort(); + AgilityReq = dr.ReadShort(); + EnergyReq = dr.ReadShort(); + CurEndurance = dr.ReadInt(); + MaxEndurance = dr.ReadInt(); + int essenceSize = dr.ReadShort(); + ReadMakerInfo(dr); + dr.Offset(essenceSize, CECDataReader.SEEK_CUR); + if(essenceSize < 0 ) { - ReadMakerInfo(data, ref offset); + throw new Exception("TYPE_DATAERR"); } - if (essenceSize < 0 || offset + essenceSize > len) return false; - offset += essenceSize; // skip essence for now - - if (offset + 2 + 2 > len) return false; - int numHole = BitConverter.ToInt16(data, offset); offset += 2; - StoneMask = BitConverter.ToUInt16(data, offset); offset += 2; - - Holes.Clear(); + int numHole = dr.ReadShort(); + StoneMask = (ushort)dr.ReadShort(); if (numHole > 0) { - if (offset + 4 * numHole > len) return false; + Holes.Clear(); Holes.Capacity = numHole; for (int i = 0; i < numHole; i++) { - Holes.Add(BitConverter.ToInt32(data, offset)); offset += 4; + Holes.Add(dr.ReadInt()); } } - else if (numHole < 0) + else if (numHole == 0) { - return false; + Holes.Clear(); } - - if (offset + 4 > len) return false; - int numProp = BitConverter.ToInt32(data, offset); offset += 4; - - Props.Clear(); + else + { + throw new Exception("TYPE_DATAERR"); + } + int numProp = dr.ReadInt(); if (numProp > 0) { + Props.Clear(); Props.Capacity = numProp; for (int i = 0; i < numProp; i++) { - if (offset + 4 > len) return false; - int type = BitConverter.ToInt32(data, offset); offset += 4; - + int type = dr.ReadInt(); Property prop = new Property(); prop.Type = type & 0x1fff; prop.NumParam = (type & 0x6000) >> 13; @@ -661,15 +656,18 @@ namespace PerfectWorld.Scripts.Managers for (int j = 0; j < prop.NumParam; j++) { - if (offset + 4 > len) return false; - prop.Params[j] = BitConverter.ToInt32(data, offset); offset += 4; + prop.Params[j] = dr.ReadInt(); } Props.Add(prop); } } - else if (numProp < 0) + else if (numProp == 0) { - return false; + Props.Clear(); + } + else + { + throw new Exception("TYPE_DATAERR"); } // Sanity check to catch misalignment @@ -678,7 +676,10 @@ namespace PerfectWorld.Scripts.Managers return true; } - catch { return false; } + catch (System.Exception ex) { + BMLogger.LogError("CECIvtrEquip::SetItemInfo, data read error (" + ex.GetType() + ")" + ex.StackTrace); + return false; + } } private bool TryParseEquipInfoLegacy(byte[] data, int len) @@ -705,7 +706,7 @@ namespace PerfectWorld.Scripts.Managers MaxEndurance = BitConverter.ToInt32(data, offset); offset += 4; int essenceSize = BitConverter.ToInt16(data, offset); offset += 2; - ReadMakerInfo(data, ref offset); + //ReadMakerInfo(data, ref offset); if (essenceSize < 0 || offset + essenceSize > len) return false; offset += essenceSize; @@ -751,39 +752,41 @@ namespace PerfectWorld.Scripts.Managers /// /// Read maker information from binary data /// - private void ReadMakerInfo(byte[] data, ref int offset) + private void ReadMakerInfo(CECDataReader dr) { - MadeFrom = data[offset++]; - int makerLen = data[offset++]; - + MadeFrom = dr.ReadByte(); + int makerLen = dr.ReadByte(); if (makerLen > 0) { - if (MadeFrom == IMT_SIGN) + if (MadeFrom == (byte)ITEM_MAKE_TAG.IMT_SIGN) { - ushort color = BitConverter.ToUInt16(data, offset); offset += 2; - makerLen -= 2; + ushort color = (ushort)dr.ReadShort(); + makerLen -= sizeof(ushort); - string maker = System.Text.Encoding.Unicode.GetString(data, offset, makerLen); - offset += makerLen; + byte[] makerData = dr.ReadData(makerLen); + string maker = System.Text.Encoding.Unicode.GetString(makerData, 0, makerData.Length); if (string.IsNullOrEmpty(maker)) { - Debug.LogWarning($"EC_IvtrEquip::ReadMakerInfo: Invalid maker info with makerLen={makerLen + 2}"); return; } - - SetNewMark(maker, ColorFromWord(color)); + //#define FASHION_WORDCOLOR_TO_A3DCOLOR(c) A3DCOLORRGB(((c) & (0x1f << 10)) >> 7, ((c) & (0x1f << 5)) >> 2, ((c) & 0x1f) << 3) + //A3DCOLOR clr = FASHION_WORDCOLOR_TO_A3DCOLOR(color); + Color clr = ColorFromWord(color); + SetNewMark(maker, clr); } else { - Maker = System.Text.Encoding.Unicode.GetString(data, offset, makerLen); - offset += makerLen; + //m_strMaker = ACString((ACHAR*)dr.Read_Data(iMakerLen), iMakerLen / sizeof (ACHAR)); + byte[] makerData = dr.ReadData(makerLen); + Maker = System.Text.Encoding.Unicode.GetString(makerData, 0, makerData.Length); } } else { Maker = ""; } + BMLogger.Log("[thn]CECIvtrEquip::ReadMakerInfo, Maker: " + Maker); } /// @@ -808,7 +811,7 @@ namespace PerfectWorld.Scripts.Managers // Add equipment mark display string Maker = string.Format(GetItemDescString(DescriptipionMsg.ITEMDESC_EQUIPMARK), Maker); } - MadeFrom = string.IsNullOrEmpty(mark) ? IMT_NULL : IMT_SIGN; + MadeFrom = string.IsNullOrEmpty(mark) ? (byte)ITEM_MAKE_TAG.IMT_NULL : (byte)ITEM_MAKE_TAG.IMT_SIGN; } #endregion @@ -818,7 +821,7 @@ namespace PerfectWorld.Scripts.Managers /// /// Get item name /// - public string GetName() + public virtual string GetName() { return EC_IvtrItemUtils.Instance.ResolveItemName(TemplateId); } @@ -928,7 +931,7 @@ namespace PerfectWorld.Scripts.Managers /// /// Check if item is rare /// - public bool IsRare() + public virtual bool IsRare() { return RefineLvl >= 3; } @@ -1132,71 +1135,147 @@ namespace PerfectWorld.Scripts.Managers try { - // Parse configs/item_ext_prop.txt to learn valid property type ids - string path = Path.Combine(UnityEngine.Application.streamingAssetsPath, "configs/item_ext_prop.txt"); - if (File.Exists(path)) + // Load item_ext_prop.txt from Addressables (same as EC_Game.cs) + Addressables.InitializeAsync().WaitForCompletion(); + var itemExtPropTa = Addressables.LoadAssetAsync("Assets/Addressable/item_ext_prop.txt").WaitForCompletion(); + + if (itemExtPropTa != null && !string.IsNullOrEmpty(itemExtPropTa.text)) { int currentType = -1; bool inTypeBlock = false; bool inBlockComment = false; - foreach (var rawLine in File.ReadLines(path)) + + using (var sr = new StringReader(itemExtPropTa.text)) { - string src = rawLine; - if (string.IsNullOrEmpty(src)) continue; - - // strip block comments /* ... */ possibly spanning lines - System.Text.StringBuilder sb = new System.Text.StringBuilder(); - int i = 0; - while (i < src.Length) + string rawLine; + while ((rawLine = sr.ReadLine()) != null) { - if (inBlockComment) - { - int end = src.IndexOf("*/", i, StringComparison.Ordinal); - if (end < 0) { i = src.Length; break; } - inBlockComment = false; i = end + 2; continue; - } - int start = src.IndexOf("/*", i, StringComparison.Ordinal); - if (start < 0) - { - sb.Append(src, i, src.Length - i); - break; - } - sb.Append(src, i, start - i); - int end2 = src.IndexOf("*/", start + 2, StringComparison.Ordinal); - if (end2 < 0) { inBlockComment = true; break; } - i = end2 + 2; - } - string line = sb.ToString().Trim(); - if (line.Length == 0) continue; - if (line.StartsWith("//")) continue; + string src = rawLine; + if (string.IsNullOrEmpty(src)) continue; - // Detect a new type section: e.g., "type: 45" - var typeMatch = Regex.Match(line, "^type:\\s*(?\\d+)"); - if (typeMatch.Success) - { - if (int.TryParse(typeMatch.Groups["type"].Value, out int t)) currentType = t; - inTypeBlock = line.Contains("{"); - if (line.Contains("}")) { inTypeBlock = false; currentType = -1; } - continue; - } - - if (line.Contains("{")) inTypeBlock = true; - if (line.Contains("}")) { inTypeBlock = false; currentType = -1; } - - if (inTypeBlock && currentType >= 0) - { - foreach (Match m in Regex.Matches(line, "\\b(?\\d{1,6})\\b")) + // strip block comments /* ... */ possibly spanning lines + System.Text.StringBuilder sb = new System.Text.StringBuilder(); + int i = 0; + while (i < src.Length) { - if (int.TryParse(m.Groups["id"].Value, out int id)) + if (inBlockComment) { - if (!s_propIdToType.ContainsKey(id)) s_propIdToType[id] = (byte)Mathf.Clamp(currentType, 0, 255); + int end = src.IndexOf("*/", i, StringComparison.Ordinal); + if (end < 0) { i = src.Length; break; } + inBlockComment = false; i = end + 2; continue; + } + int start = src.IndexOf("/*", i, StringComparison.Ordinal); + if (start < 0) + { + sb.Append(src, i, src.Length - i); + break; + } + sb.Append(src, i, start - i); + int end2 = src.IndexOf("*/", start + 2, StringComparison.Ordinal); + if (end2 < 0) { inBlockComment = true; break; } + i = end2 + 2; + } + string line = sb.ToString().Trim(); + if (line.Length == 0) continue; + if (line.StartsWith("//")) continue; + + // Detect a new type section: e.g., "type: 45" + var typeMatch = Regex.Match(line, "^type:\\s*(?\\d+)"); + if (typeMatch.Success) + { + if (int.TryParse(typeMatch.Groups["type"].Value, out int t)) currentType = t; + inTypeBlock = line.Contains("{"); + if (line.Contains("}")) { inTypeBlock = false; currentType = -1; } + continue; + } + + if (line.Contains("{")) inTypeBlock = true; + if (line.Contains("}")) { inTypeBlock = false; currentType = -1; } + + if (inTypeBlock && currentType >= 0) + { + foreach (Match m in Regex.Matches(line, "\\b(?\\d{1,6})\\b")) + { + if (int.TryParse(m.Groups["id"].Value, out int id)) + { + if (!s_propIdToType.ContainsKey(id)) s_propIdToType[id] = (byte)Mathf.Clamp(currentType, 0, 255); + } + } + } + } + } + } + else + { + // Fallback to StreamingAssets if Addressables fails + string path = Path.Combine(UnityEngine.Application.streamingAssetsPath, "configs/item_ext_prop.txt"); + if (File.Exists(path)) + { + int currentType = -1; + bool inTypeBlock = false; + bool inBlockComment = false; + foreach (var rawLine in File.ReadLines(path)) + { + string src = rawLine; + if (string.IsNullOrEmpty(src)) continue; + + // strip block comments /* ... */ possibly spanning lines + System.Text.StringBuilder sb = new System.Text.StringBuilder(); + int i = 0; + while (i < src.Length) + { + if (inBlockComment) + { + int end = src.IndexOf("*/", i, StringComparison.Ordinal); + if (end < 0) { i = src.Length; break; } + inBlockComment = false; i = end + 2; continue; + } + int start = src.IndexOf("/*", i, StringComparison.Ordinal); + if (start < 0) + { + sb.Append(src, i, src.Length - i); + break; + } + sb.Append(src, i, start - i); + int end2 = src.IndexOf("*/", start + 2, StringComparison.Ordinal); + if (end2 < 0) { inBlockComment = true; break; } + i = end2 + 2; + } + string line = sb.ToString().Trim(); + if (line.Length == 0) continue; + if (line.StartsWith("//")) continue; + + // Detect a new type section: e.g., "type: 45" + var typeMatch = Regex.Match(line, "^type:\\s*(?\\d+)"); + if (typeMatch.Success) + { + if (int.TryParse(typeMatch.Groups["type"].Value, out int t)) currentType = t; + inTypeBlock = line.Contains("{"); + if (line.Contains("}")) { inTypeBlock = false; currentType = -1; } + continue; + } + + if (line.Contains("{")) inTypeBlock = true; + if (line.Contains("}")) { inTypeBlock = false; currentType = -1; } + + if (inTypeBlock && currentType >= 0) + { + foreach (Match m in Regex.Matches(line, "\\b(?\\d{1,6})\\b")) + { + if (int.TryParse(m.Groups["id"].Value, out int id)) + { + if (!s_propIdToType.ContainsKey(id)) s_propIdToType[id] = (byte)Mathf.Clamp(currentType, 0, 255); + } } } } } } } - catch { /* ignore parse errors; fallback below will handle */ } + catch (Exception ex) + { + Debug.LogError($"[EC_IvtrEquip] Error loading property map: {ex.Message}"); + } s_propMapLoaded = true; } @@ -1295,7 +1374,7 @@ namespace PerfectWorld.Scripts.Managers /// Get normal in-inventory description, mirroring C++ CECIvtrEquip::GetNormalDesc. /// This is a single formatted string using ^color codes and '\\r' as line separators. /// - public string GetNormalDesc() + protected override string GetNormalDesc(bool bRepair) { // Build addon and refine properties and save it (like C++ does first) int[] aPEEVals = new int[MAX_PEEINDEX]; @@ -1991,7 +2070,7 @@ namespace PerfectWorld.Scripts.Managers { return 0; } - + /// /// Check the special refine property /// @@ -2079,12 +2158,16 @@ namespace PerfectWorld.Scripts.Managers RefineLvl = 0; PropNum = 0; EmbedNum = 0; - + BMLogger.Log("[thn]CECIvtrEquip::ParseProperties, Props.Count: " + Props.Count); if (Props.Count == 0) return; foreach (Property prop in Props) { + Debug.Log("[thn]CECIvtrEquip::ParseProperties, prop.Type: " + prop.Type); + Debug.Log("[thn]CECIvtrEquip::ParseProperties, prop.Embed: " + prop.Embed); + Debug.Log("[thn]CECIvtrEquip::ParseProperties, prop.Suite: " + prop.Suite); + Debug.Log("[thn]CECIvtrEquip::ParseProperties, prop.Engraved: " + prop.Engraved); int level = 0; if (prop.Embed) { @@ -2221,7 +2304,7 @@ namespace PerfectWorld.Scripts.Managers /// /// Add description text /// - private void AddDescText(int color, bool newLine, string format, params object[] args) + protected override void AddDescText(int color, bool newLine, string format, params object[] args) { if (color >= 0) { @@ -2580,40 +2663,40 @@ namespace PerfectWorld.Scripts.Managers if (!IsSharpenerProperty(propType)) { switch (propType) - { + { case 0: // ������ - if(!local) - { - if (aPEEVals != null) - aPEEVals[PEEI_PHYDAMAGE] += p0; - } - - AddDescText(color, false, GetItemDescString(DescriptipionMsg.ITEMDESC_ADDPHYDAMAGE)); - AddDescText(color, true, " %+d", p0); - break; + if(!local) + { + if (aPEEVals != null) + aPEEVals[PEEI_PHYDAMAGE] += p0; + } + + AddDescText(color, false, GetItemDescString(DescriptipionMsg.ITEMDESC_ADDPHYDAMAGE)); + AddDescText(color, true, " %+d", p0); + break; case 1: // ���������� - if(local) - { - if(p0 != p1) - { - AddDescText(color, false, GetItemDescString(DescriptipionMsg.ITEMDESC_MAXPHYDAMAGE), p0); - AddDescText(color, true, "~%d", p1); - } - else - { - AddDescText(color, true, GetItemDescString(DescriptipionMsg.ITEMDESC_MAXPHYDAMAGE), p0); - } - } - else - { - if (aPEEVals != null) - aPEEVals[PEEI_MAX_PHYDAMAGE] += p0; - - AddDescText(color, true, GetItemDescString(DescriptipionMsg.ITEMDESC_MAXPHYDAMAGE), p0); - } + if(local) + { + if(p0 != p1) + { + AddDescText(color, false, GetItemDescString(DescriptipionMsg.ITEMDESC_MAXPHYDAMAGE), p0); + AddDescText(color, true, "~%d", p1); + } + else + { + AddDescText(color, true, GetItemDescString(DescriptipionMsg.ITEMDESC_MAXPHYDAMAGE), p0); + } + } + else + { + if (aPEEVals != null) + aPEEVals[PEEI_MAX_PHYDAMAGE] += p0; + + AddDescText(color, true, GetItemDescString(DescriptipionMsg.ITEMDESC_MAXPHYDAMAGE), p0); + } break; case 2: // ������(%) @@ -4019,22 +4102,26 @@ namespace PerfectWorld.Scripts.Managers /// /// Build add-ons properties description /// - private void BuildAddOnPropDesc(int[] aPEEVals, int[] aRefines) + protected void BuildAddOnPropDesc(int[] aPEEVals, int[] aRefines) { + BMLogger.Log("[THN]EC_IvtrEquip: BuildAddOnPropDesc: Props.Count: " + Props.Count); if (Props.Count == 0) return; // Change color m_strDesc += GetColorString(DescriptipionMsg.ITEMDESC_COL_LIGHTBLUE); - + BMLogger.Log("[THN]EC_IvtrEquip: BuildAddOnPropDesc: m_strDesc: " + m_strDesc); + Debug.Log("[THN]EC_IvtrEquip: BuildAddOnPropDesc: Props.Count: " + Props.Count); foreach (Property prop in Props) { // Properties added by Embedded stone will be printed by BuildTesseraDesc() later // Ignore suite properties also if (prop.Embed || prop.Suite || prop.Engraved) continue; - + BMLogger.Log("[THN]EC_IvtrEquip: BuildAddOnPropDesc: prop.Type: " + prop.Type); + BMLogger.Log("[THN]EC_IvtrEquip: BuildAddOnPropDesc: prop.Params: " + prop.Params[0] + " " + prop.Params[1] + " " + prop.Params[2]); AddOneAddOnPropDesc(prop.Type, prop.Params, aPEEVals, aRefines, prop.Local); + BMLogger.Log("[THN]EC_IvtrEquip: BuildAddOnPropDesc: m_strDesc: " + m_strDesc); } } @@ -4064,7 +4151,7 @@ namespace PerfectWorld.Scripts.Managers /// /// Build tessera description (socketed gems/stones) /// - private void BuildTesseraDesc() + protected void BuildTesseraDesc() { if (Holes.Count == 0) return; @@ -4093,7 +4180,7 @@ namespace PerfectWorld.Scripts.Managers /// /// Add suite description /// - private void AddSuiteDesc() + protected void AddSuiteDesc() { int idSuite = GetSuiteID(); if (idSuite == 0) @@ -4200,7 +4287,7 @@ namespace PerfectWorld.Scripts.Managers /// /// Add reputation requirement description /// - private void AddReputationReqDesc() + protected void AddReputationReqDesc() { if (ReputationReq == 0) return; @@ -4233,7 +4320,7 @@ namespace PerfectWorld.Scripts.Managers /// /// Add sharpener description (磨刀石 properties) /// - private void AddSharpenerDesc() + protected void AddSharpenerDesc() { if (Props.Count == 0) return; @@ -4412,7 +4499,7 @@ namespace PerfectWorld.Scripts.Managers /// Append engraved property descriptions to the current description buffer. /// Mirrors the behaviour of the original C++ AddEngravedDesc. /// - private void AddEngravedDesc() + protected void AddEngravedDesc() { if (Props.Count == 0) return; @@ -4444,14 +4531,14 @@ namespace PerfectWorld.Scripts.Managers /// /// Append maker description (signature / crafted by) to the description buffer. /// - private void AddMakerDesc() + protected void AddMakerDesc() { if (string.IsNullOrEmpty(Maker)) return; m_strDesc += "\\r"; // For signed marks (IMT_SIGN), Maker already contains color codes and formatted text. - if (MadeFrom == IMT_SIGN) + if (MadeFrom == (byte)ITEM_MAKE_TAG.IMT_SIGN) { m_strDesc += Maker; } @@ -4532,7 +4619,7 @@ namespace PerfectWorld.Scripts.Managers /// /// Get preview info /// - public string GetPreviewInfo() + public virtual string GetPreviewInfo() { m_strDesc = ""; BuildAddOnPropDesc(null, null); @@ -4595,7 +4682,60 @@ namespace PerfectWorld.Scripts.Managers return m_strDesc; } - + public struct RefineEffect + { + int m_refineIndex; + public int RefineIndex{ get { return m_refineIndex; } set { m_refineIndex = value; } } + int m_incEffect; + public int IncEffect{ get { return m_incEffect; } set { m_incEffect = value; } } + + int[] m_aPEEVals; + public int[] APEEVals{ get { return m_aPEEVals; } set { m_aPEEVals = value; } } + int[] m_aRefines; + public int[] ARefines{ get { return m_aRefines; } set { m_aRefines = value; } } + + string m_clrAttribute; + public string ClrAttribute{ get { return m_clrAttribute; } set { m_clrAttribute = value; } } + string m_clrEffect; + public string ClrEffect{ get { return m_clrEffect; } set { m_clrEffect = value; } } + + public RefineEffect(int[] aPEEVals, int[] aRefines, string clrAttribute, string clrEffect) + { + m_refineIndex = -1; + m_incEffect = 0; + m_aPEEVals = aPEEVals; + m_aRefines = aRefines; + m_clrAttribute = clrAttribute; + m_clrEffect = clrEffect; + } + + public void Set(int refineIndex, int incEffect){ + m_refineIndex = refineIndex; + m_incEffect = incEffect; + } + + public int GetIncEffect(){ + return m_incEffect; + } + public string GetClrAttribute(){ + return m_clrAttribute; + } + public string GetClrEffect(){ + return m_clrEffect; + } + }; + public virtual bool GetRefineEffectFor(string strEffect, RefineEffect rhs){ return false; } + public static int CalcRefineEffect(int refineLevel, int baseEffect) + { + const int MAX_REFINE_LEVEL = 12; + float[] refine_factor = new float[MAX_REFINE_LEVEL + 1] + { 0, 1.0f, 2.0f, 3.05f, 4.3f, 5.75f, 7.55f, 9.95f, 13f, 17.05f, 22.3f, 29f, 37.5f }; + if (refineLevel >= 0 && refineLevel <= MAX_REFINE_LEVEL){ + return (int)(baseEffect * refine_factor[refineLevel] + 0.1f); + } + return 0; + } + #endregion } diff --git a/Assets/PerfectWorld/Scripts/Managers/EC_IvtrItem.cs b/Assets/PerfectWorld/Scripts/Managers/EC_IvtrItem.cs index 0e2474fe2a..129416724c 100644 --- a/Assets/PerfectWorld/Scripts/Managers/EC_IvtrItem.cs +++ b/Assets/PerfectWorld/Scripts/Managers/EC_IvtrItem.cs @@ -707,7 +707,7 @@ namespace BrewMonster.Scripts.Managers public bool m_bNeedUpdate; // true, detail data needs to be updated public bool m_bUpdating; // true, being updating detail data public uint m_dwUptTime; // Time when updating request was sent (ms) - public string m_strDesc; // Item description + public string m_strDesc = ""; // Item description public bool m_bIsInNPCPack; // true, this item is in NPC package public bool m_bLocalDetailData; // true, data from GetDetailDataFromLocal @@ -812,6 +812,18 @@ namespace BrewMonster.Scripts.Managers public static EC_IvtrItem CreateItem(int tid, int expire_date, int iCount, int idSpace = 0) { var pItem = new EC_IvtrItem(tid, expire_date); + DATA_TYPE DataType = DATA_TYPE.DT_INVALID; + object data = ElementDataManProvider.GetElementDataMan().get_data_ptr((uint)tid, ID_SPACE.ID_SPACE_ESSENCE, ref DataType); + switch(DataType) + { + case DATA_TYPE.DT_WEAPON_ESSENCE: + pItem = new EC_IvtrWeapon(tid, expire_date); + BMLogger.Log("[THN]EC_IvtrItem: CreateItem: Weapon Item: tid: " + tid + ", expire_date: " + expire_date + ", pItem: " + pItem); + break; + default: + BMLogger.Log("[THN]EC_IvtrItem: CreateItem: Default Item: tid: " + tid + ", expire_date: " + expire_date + ", pItem: " + pItem); + break; + } pItem.SetCount(iCount); return pItem; } @@ -1154,11 +1166,10 @@ namespace BrewMonster.Scripts.Managers // m_dwUptTime could be set from a game time provider when available. } - public void GetDetailDataFromLocal() + public virtual void GetDetailDataFromLocal() { //itemdataman* pItemDataMan = g_pGame->GetItemDataMan(); object pData_temp = itemdataman.get_item_for_sell((uint)m_tid); - BMLogger.Log($"[THN]GetDetailDataFromLocal: tid:{m_tid} pData_temp:{pData_temp}"); if(pData_temp == null) { SetItemInfo(null, 0); @@ -1167,9 +1178,7 @@ namespace BrewMonster.Scripts.Managers return; } item_data pData = (item_data)pData_temp; - SetItemInfo(pData.item_content, pData.content_length); - BMLogger.Log($"[THN]GetDetailDataFromLocal: id:{m_tid} content:{pData.item_content} length:{pData.content_length}"); SetLocalProps(); m_bLocalDetailData = true; } @@ -1201,25 +1210,9 @@ namespace BrewMonster.Scripts.Managers m_strDesc = string.Empty; // Item name line - string name = GetName(); - if (!string.IsNullOrEmpty(name)) - { - AddDescText(0, true, name); - } - - // Core description from item_desc.txt (via EC_Game / TryGetItemMsg) - string mainDesc = TryGetItemMainDesc(); - if (!string.IsNullOrEmpty(mainDesc)) - { - AddDescText(0, true, mainDesc); - } - - // Extended description from item_ext_desc.txt - string extDesc = TryGetItemExtDesc(); - if (!string.IsNullOrEmpty(extDesc)) - { - AddDescText(0, true, extDesc); - } + CECStringTab pDescTab = EC_Game.GetItemDesc(); + AddDescText((int)DescriptipionMsg.ITEMDESC_COL_WHITE, false, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_ERRORITEM)); + AddDescText((int)DescriptipionMsg.ITEMDESC_COL_WHITE, false, "({0})", m_tid); TrimLastReturn(); return m_strDesc; @@ -1243,8 +1236,32 @@ namespace BrewMonster.Scripts.Managers AddDescText(col, true, "Price: {0}", price); } - protected virtual void AddProfReqDesc(int iProfReq) + protected virtual void AddProfReqDesc(uint iProfReq) { + if (EC_ProfConfigs.ContainsAllProfession(iProfReq)) + { + return;// All profession permit equirement + } + CECStringTab pDescTab = EC_Game.GetItemDesc(); + CECGameRun pGameRun = EC_Game.GetGameRun(); + CECHostPlayer pHost = pGameRun.GetHostPlayer(); + int col = (iProfReq & (1 << pHost.GetProfession())) != 0 ? (int)DescriptipionMsg.ITEMDESC_COL_WHITE : (int)DescriptipionMsg.ITEMDESC_COL_RED; + AddDescText(col, false, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_PROFESSIONREQ)); + for (int i = 0; i < (int)Profession.NUM_PROFESSION; i++) + { + if ((iProfReq & (1 << i)) != 0) + { + m_strDesc += " "; + string profName = pGameRun.GetProfName(i); + // Remove newline and carriage return characters that cause UI display issues + if (!string.IsNullOrEmpty(profName)) + { + profName = profName.Replace("\r", "").Replace("\n", "").Trim(); + } + AddDescText(col, false, profName); + } + } + AddDescText(col, true, " "); } protected virtual int DecideNameCol() @@ -1256,7 +1273,7 @@ namespace BrewMonster.Scripts.Managers { } - protected void AddDescText(int iCol, bool bRet, string szText, params object[] args) + protected virtual void AddDescText(int iCol, bool bRet, string szText, params object[] args) { string line = (args != null && args.Length > 0) ? string.Format(szText, args) : szText; m_strDesc += line; @@ -1455,6 +1472,8 @@ namespace BrewMonster.Scripts.Managers { // Optional: show internal id for debugging AddDescText(0, true, "ID: {0}", m_tid); + BMLogger.Log("[THN]EC_IvtrItem: AddIDDescText: m_tid: " + m_tid); + BMLogger.Log("[THN]EC_IvtrItem: AddIDDescText: m_strDesc: " + m_strDesc); } protected void AddBindDescText() diff --git a/Assets/PerfectWorld/Scripts/Managers/EC_IvtrType.cs b/Assets/PerfectWorld/Scripts/Managers/EC_IvtrType.cs index b42a4e4aba..965f28b649 100644 --- a/Assets/PerfectWorld/Scripts/Managers/EC_IvtrType.cs +++ b/Assets/PerfectWorld/Scripts/Managers/EC_IvtrType.cs @@ -49,7 +49,215 @@ namespace BrewMonster.Scripts.Managers SIZE_ALL_EQUIPIVTR, SIZE_GENERALCARD_EQUIPIVTR = SIZE_ALL_EQUIPIVTR - EQUIPIVTR_GENERALCARD1, } + #region Inventory Essence Struct + #pragma pack(1) + public struct IVTR_ESSENCE_WEAPON + { + public short weapon_type; + public short weapon_dealy; + public int weapon_class; + public int weapon_level; + public int require_projectile; // ��Ҫ��ҩ������ + public int damage_low; // ����������С��ֵ + public int damage_high; // ������������ֵ + public int magic_damage_low; // ħ������ + public int magic_damage_high; // ħ������ + // public int attack; // ������ + public int attack_speed; + public float attack_range; + public float attack_short_range; + public IVTR_ESSENCE_WEAPON( byte[] data) + { + Debug.Log("IVTR_ESSENCE_WEAPON: data.Length: " + data.Length); + CECDataReader dr = new (data, data.Length); + weapon_type = dr.ReadShort(); + weapon_dealy = dr.ReadShort(); + weapon_class = dr.ReadInt(); + weapon_level = dr.ReadInt(); + require_projectile = dr.ReadInt(); + damage_low = dr.ReadInt(); + damage_high = dr.ReadInt(); + magic_damage_low = dr.ReadInt(); + magic_damage_high = dr.ReadInt(); + attack_speed = dr.ReadInt(); + attack_range = dr.ReadFloat(); + attack_short_range = dr.ReadFloat(); + } + }; + public struct IVTR_ESSENCE_ARROW + { + // TODO : implement data later + // DWORD dwBowMask; + // int iDamage; + // int iDamageScale; + // int iWeaponReqLow; + // int iWeaponReqHigh; + }; + public struct IVTR_ESSENCE_DECORATION + { + // TODO : implement data later + // int damage; + // int magic_damage; + // int defense; + // int armor; + // int resistance[NUM_MAGICCLASS]; + }; + + public struct IVTR_ESSENCE_ARMOR + { + // TODO : implement data later + // int defense; + // int armor; + // int mp_enhance; + // int hp_enhance; + // int resistance[NUM_MAGICCLASS]; + }; + + public struct IVTR_ESSENCE_FASHION + { + // TODO : implement data later + // int require_level; + // unsigned short color; + // unsigned short gender; + }; + + 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 struct IVTR_ESSENCE_WING + { + // TODO : implement data later + // int require_level; + // size_t mp_launch; + // size_t mp_per_second; + // float speed_increase; + }; + + public struct IVTR_ESSENCE_AUTOHP + { + // TODO : implement data later + // int hp_left; + // float trigger; + }; + + public struct IVTR_ESSENCE_AUTOMP + { + // TODO : implement data later + // int mp_left; + // float trigger; + }; + + public struct IVTR_ESSENCE_PETEGG + { + // TODO : implement data later + // int req_level; + // int req_class; + // int honor_point; + // int pet_tid; + // int pet_vis_tid; + // int pet_egg_tid; + // int pet_class; + // short level; + // unsigned short color; + // int exp; + // int skill_point; + // unsigned short name_len; + // unsigned short skill_count; + // wchar_t name[8]; + }; + + public struct IVTR_ESSENCE_DESTROYING + { + // TODO : implement data later + // int tid; + }; + + public struct IVTR_ESSENCE_GOBLIN + { + struct _GOBLIN_DATA + { + // TODO : implement data later + // unsigned int exp; + // short level; + // short total_attribute; + // short strength; + // short agility; + // short vitality; + // short energy; + // short total_genius; + // short genius[5]; + // short refine_level; + // int stamina; + // int status_value; + }; + + // TODO : implement data later + // _GOBLIN_DATA data; + // int equip_cnt; + // int skill_cnt; + }; + + public struct IVTR_ESSENCE_WEDDING_BOOKCARD + { + // TODO : implement data later + // int year; + // int month; + // int day; + }; + + public struct IVTR_ESSENCE_WEDDING_INVITECARD + { + // TODO : implement data later + // int start_time; + // int end_time; + // int groom; + // int bride; + // int scene; + // int invitee; + }; + + public struct IVTR_ESSENCE_FORCE_TOKEN + { + // TODO : implement data later + // int require_force; + // int repu_total; + // int repu_inc_ratio; + }; + + public struct IVTR_ESSENCE_MONSTERSPIRIT + { + // TODO : implement data later + // int level; + // int type; + // int power; + }; + + public struct IVTR_ESSENCE_GENERALCARD + { + // TODO : implement data later + // int type; + // int rank; + // int require_level; + // int require_leadership; + // int max_level; + // int level; + // int exp; + // int rebirth_times; + }; + #pragma pack() + #endregion public static class EC_IvtrType { diff --git a/Assets/PerfectWorld/Scripts/Managers/EC_IvtrWeapon.cs b/Assets/PerfectWorld/Scripts/Managers/EC_IvtrWeapon.cs new file mode 100644 index 0000000000..318e03c7e2 --- /dev/null +++ b/Assets/PerfectWorld/Scripts/Managers/EC_IvtrWeapon.cs @@ -0,0 +1,436 @@ +// /* +// * FILE: EC_IvtrWeapon.cpp +// * +// * DESCRIPTION: +// * +// * CREATED BY: Duyuxin, 2004/11/19 +// * +// * HISTORY: +// * +// * Copyright (c) 2004 Archosaur Studio, All Rights Reserved. +// */ + +// #include "EC_Global.h" +// #include "EC_IvtrWeapon.h" +// #include "EC_Game.h" +// #include "EC_FixedMsg.h" +// #include "EC_GameRun.h" +// #include "EC_HostPlayer.h" +// #include "EC_RTDebug.h" +// #include "elementdataman.h" +// #include "EC_Configs.h" +using BrewMonster; +using ModelRenderer.Scripts.GameData; +using System.Collections.Generic; +using BrewMonster.Network; +using BrewMonster.Scripts.Managers; +using BrewMonster.Scripts; +#region C# regions +// #define new A_DEBUG_NEW + +// /////////////////////////////////////////////////////////////////////////// +// // +// // Define and Macro +// // +// /////////////////////////////////////////////////////////////////////////// + + +// /////////////////////////////////////////////////////////////////////////// +// // +// // Reference to External variables and functions +// // +// /////////////////////////////////////////////////////////////////////////// + + +// /////////////////////////////////////////////////////////////////////////// +// // +// // Local Types and Variables and Global variables +// // +// /////////////////////////////////////////////////////////////////////////// + + +// /////////////////////////////////////////////////////////////////////////// +// // +// // Local functions +// // +// /////////////////////////////////////////////////////////////////////////// + +// /////////////////////////////////////////////////////////////////////////// +// // +// // Implement CECIvtrWeapon +// // +// /////////////////////////////////////////////////////////////////////////// +#endregion + +namespace PerfectWorld.Scripts.Managers +{ + + public class EC_IvtrWeapon : EC_IvtrEquip + { + //Attributes + //Weapon essence data + protected IVTR_ESSENCE_WEAPON m_Essence; + // data in database + protected WEAPON_MAJOR_TYPE m_pDBMajorType; + protected WEAPON_SUB_TYPE m_pDBSubType; + protected WEAPON_ESSENCE m_pDBEssence; + + public EC_IvtrWeapon(int tid, int expire_date) : base(tid, expire_date) + { + m_iCID = ICID_WEAPON; + elementdataman pDB = ElementDataManProvider.GetElementDataMan(); + DATA_TYPE DataType = DATA_TYPE.DT_INVALID; + m_pDBEssence = (WEAPON_ESSENCE)pDB.get_data_ptr((uint)tid, ID_SPACE.ID_SPACE_ESSENCE, ref DataType); + m_pDBMajorType = (WEAPON_MAJOR_TYPE)pDB.get_data_ptr(m_pDBEssence.id_major_type, ID_SPACE.ID_SPACE_ESSENCE, ref DataType); + m_pDBSubType = (WEAPON_SUB_TYPE)pDB.get_data_ptr(m_pDBEssence.id_sub_type, 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_i64EquipMask = EC_IvtrEquip.ICID_WEAPON; + m_iProcType = (int)m_pDBEssence.proc_type; + + FixProps = m_pDBEssence.fixed_props; + RepairFee = m_pDBEssence.repairfee; + ReputationReq = m_pDBEssence.require_reputation; + } + public EC_IvtrWeapon(EC_IvtrWeapon other) : base(other) + { + m_pDBEssence = other.m_pDBEssence; + m_pDBMajorType = other.m_pDBMajorType; + m_pDBSubType = other.m_pDBSubType; + m_Essence = other.m_Essence; + } + + // CECIvtrWeapon::~CECIvtrWeapon() + // { + // } + + 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); + // Skip equip requirements and endurance + dr.Offset(6 * sizeof(short), CECDataReader.SEEK_CUR); + dr.Offset(2 * sizeof(int), CECDataReader.SEEK_CUR); + int iEssenceSize = dr.ReadShort(); + // Skip maker's information + dr.ReadByte(); + int iMakerLen = dr.ReadByte(); + dr.Offset(iMakerLen, CECDataReader.SEEK_CUR); + byte[] iEssenceData = dr.ReadData(iEssenceSize); + m_Essence = new IVTR_ESSENCE_WEAPON(iEssenceData); + BMLogger.Log("[thn] weapon addon m_Essence: " + m_Essence.ToString()); + // ���븽������˵�� + if(m_pDBEssence.fixed_props != 0 && m_pDBEssence.probability_addon_num0 != 1.0f) + { + // Get database data + elementdataman pDataMan = ElementDataManProvider.GetElementDataMan(); + CECStringTab PropTab = EC_Game.GetItemExtProp(); + int i, iSize = 0; + for(i=0;i<32;i++) + { + if(m_pDBEssence.addons[i].id_addon != 0) + iSize++; + } + if(iSize > 0 && Props.Count == 0) + { + Props.Capacity = iSize; + for(i=0;i<32;i++) + { + if(m_pDBEssence.addons[i].id_addon != 0) + { + Property Prop = new Property(); + Prop.Type = (int)m_pDBEssence.addons[i].id_addon; + Prop.Embed = false; + Prop.Suite = false; + Prop.Engraved = false; + Prop.Local = false; + byte bType = PropTab.GetWideString(Prop.Type) != null ? (byte)0xff : (byte)0xff; + DATA_TYPE DataType = DATA_TYPE.DT_INVALID; + object pData = pDataMan.get_data_ptr(m_pDBEssence.addons[i].id_addon, ID_SPACE.ID_SPACE_ADDON, ref DataType); + if (DataType != DATA_TYPE.DT_EQUIPMENT_ADDON) + { + return false; + } + EQUIPMENT_ADDON pAddon = (EQUIPMENT_ADDON)pData; + Prop.NumParam = pAddon.num_params; + for(int j=0; j < Prop.NumParam; j++) + { + if(j==0) + { + Prop.Params[0] = pAddon.param1; + } + else if(j==1) + { + Prop.Params[1] = pAddon.param2; + } + else if(j==2) + { + Prop.Params[2] = pAddon.param3; + } + } + Props.Add(Prop); + } + } + } + } + return true; + } + catch ( System.Exception e) + { + return false; + } + } + // Get item default information from database + public override void DefaultInfo() + { + LevelReq = m_pDBEssence.require_level; + StrengthReq = m_pDBEssence.require_strength; + AgilityReq = m_pDBEssence.require_agility; + ReputationReq = m_pDBEssence.require_reputation; + CurEndurance = m_pDBEssence.durability_min * ENDURANCE_SCALE; + MaxEndurance = m_pDBEssence.durability_min * ENDURANCE_SCALE; + } + // Get item icon file name + public override string GetIconFile() + { + return m_pDBEssence.FileIcon; + } + // Get item name + public override string GetName() + { + BMLogger.Log("[THN]EC_IvtrWeapon: GetName: m_pDBEssence.Name: " + m_pDBEssence.Name); + return m_pDBEssence.Name; + } + // Get preview info + public override string GetPreviewInfo() + { + int[] aPEEVals = new int[MAX_PEEINDEX]; + int[] aRefines = new int[MAX_REFINEINDEX]; + for(int i=0; i 0) + { + AddDescText(namecol, false, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_NAMESOCKET), GetName(), Holes.Count); + } + else + { + AddDescText(namecol, false, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_NAME), GetName()); + } + if (RefineLvl > 0) + AddDescText(-1, true, "{0} {1}", pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_LEVEL), RefineLvl); + else + m_strDesc += "\\r"; + AddIDDescText(); + AddBindDescText(); + // Is destroying? + AddDestroyingDesc((int)m_pDBEssence.id_drop_after_damaged, m_pDBEssence.num_drop_after_damaged); + AddExpireTimeDesc(); + // Sub class name + AddDescText(white, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_CLASSNAME), m_Essence.weapon_type.ToString()); + // Weapon level + AddDescText(-1, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_LEVEL), m_Essence.weapon_level); + // Attack speed + int col = ((dwPEE & PEE_ATKSPEED) != 0) ? lblue : white; + if (Props != null && Props.Count > 0 && Props[0].Local) + col = white; + AddDescText(col, false, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_ATKSPEED)); + AddDescText(col, true, " {0:F2}", 1.0f / (m_Essence.attack_speed * 0.05f)); + // Attack distance + AddDescText(white, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_ATKDISTANCE), m_Essence.attack_range - aPEEVals[PEEI_ATKDIST]); + // Weak distance + if (m_Essence.weapon_type == (int)WEAPON_TYPE.WEAPON_TYPE_RANGE) + AddDescText(white, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_WEAKDIST), m_Essence.attack_short_range); + // Physical damage + if (m_Essence.damage_low != 0 || m_Essence.damage_high != 0 || aRefines[REFINE_PHYDAMAGE] != 0) + { + AddDescText(white, false, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_PHYDAMAGE)); + AddDescText(white, true, " {0}-{1}", m_Essence.damage_low - aPEEVals[PEEI_PHYDAMAGE] + aRefines[REFINE_PHYDAMAGE], + m_Essence.damage_high - aPEEVals[PEEI_PHYDAMAGE] - aPEEVals[PEEI_MAX_PHYDAMAGE] + aRefines[REFINE_PHYDAMAGE]); + } + // Magic damage + if (m_Essence.magic_damage_low != 0 || m_Essence.magic_damage_high != 0 || aRefines[REFINE_MAGICDAMAGE] != 0) + { + AddDescText(white, false, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_MAGICDAMAGE)); + AddDescText(white, true, " {0}-{1}", m_Essence.magic_damage_low - aPEEVals[PEEI_MAGICDAMAGE] + aRefines[REFINE_MAGICDAMAGE], + m_Essence.magic_damage_high - aPEEVals[PEEI_MAGICDAMAGE] - aPEEVals[PEEI_MAX_MAGICDAMAGE] + aRefines[REFINE_MAGICDAMAGE]); + } + // Endurance + col = white; + if (CurEndurance == 0) + col = red; + else if ((dwPEE & PEE_ENDURANCE) != 0) + col = lblue; + AddDescText(col, false, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_ENDURANCE)); + AddDescText(col, true, " {0}/{1}", VisualizeEndurance(CurEndurance), VisualizeEndurance(MaxEndurance)); + // Projectile requirement + if (m_Essence.weapon_type == (int)WEAPON_TYPE.WEAPON_TYPE_RANGE && m_Essence.require_projectile != 0) + { + DATA_TYPE DataType = DATA_TYPE.DT_INVALID; + object pData = ElementDataManProvider.GetElementDataMan().get_data_ptr((uint)m_Essence.require_projectile, ID_SPACE.ID_SPACE_ESSENCE, ref DataType); + PROJECTILE_TYPE pProjectile = (PROJECTILE_TYPE)pData; + AddDescText(white, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_PROJECTILE), pProjectile.name); + } + // Profession requirement + AddProfReqDesc((uint)ProfReq); + // Level requirment + if (LevelReq != 0) + { + col = pHost.GetMaxLevelSofar() >= LevelReq ? white : red; + AddDescText(col, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_LEVELREQ), LevelReq); + } + // Strength requirment + if (StrengthReq != 0) + { + col = pHost.GetExtendProps().bs.strength < StrengthReq ? red : ((dwPEE & PEE_STRENGTHREQ) != 0 ? lblue : white); + AddDescText(col, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_STRENGTHREQ), StrengthReq); + } + // Agility requirment + if (AgilityReq != 0) + { + col = pHost.GetExtendProps().bs.agility < AgilityReq ? red : ((dwPEE & PEE_AGILITYREQ) != 0 ? lblue : white); + AddDescText(col, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_AGILITYREQ), AgilityReq); + } + // Vitality requirment + if (VitalityReq != 0) + { + col = pHost.GetExtendProps().bs.vitality < VitalityReq ? red : ((dwPEE & PEE_VITALITYREQ) != 0 ? lblue : white); + AddDescText(col, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_VITALITYREQ), VitalityReq); + } + // Energy requirment + if (EnergyReq != 0) + { + col = pHost.GetExtendProps().bs.energy < EnergyReq ? red : ((dwPEE & PEE_ENERGYREQ) != 0 ? lblue : white); + AddDescText(col, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_ENERGYREQ), EnergyReq); + } + // Reputation requirement + AddReputationReqDesc(); + // Add addon properties + if (!string.IsNullOrEmpty(strAddon)) + m_strDesc += strAddon; + // Build tessera description + BuildTesseraDesc(); + // Price + AddPriceDesc(white, bRepair); + if(m_pDBEssence.fixed_props == 0 && m_bIsInNPCPack) + AddDescText((int)DescriptipionMsg.ITEMDESC_COL2_BRIGHTBLUE, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_HASRANDOM_PROP)); + AddSharpenerDesc(); + AddEngravedDesc(); + AddMakerDesc(); + AddSuiteDesc(); + AddExtDescText(); + return m_strDesc; + } + // Get weapon attack speed index + public int GetAttackSpeedIndex() + { + float fCurSpeed = m_Essence.attack_speed * 0.05f - m_pDBSubType.attack_speed; + if (fCurSpeed < -0.101f) + return (int)DescriptipionMsg.ITEMDESC_ATKSPD_VERYFAST; + else if (fCurSpeed < -0.001f) + return (int)DescriptipionMsg.ITEMDESC_ATKSPD_FAST; + else if (fCurSpeed < 0.001f) + return (int)DescriptipionMsg.ITEMDESC_ATKSPD_NORMAL; + else if (fCurSpeed <= 0.101f) + return (int)DescriptipionMsg.ITEMDESC_ATKSPD_SLOW; + else + return (int)DescriptipionMsg.ITEMDESC_ATKSPD_VERYSLOW; + } + // // Does this equipment has random property ? + public bool HasRandomProp() + { + for (int i = 0; i < Props.Count; i++) + { + if (!Props[i].Embed && !Props[i].Engraved && Props[i].Type == 472) + return true; + } + return false; + } + public int GetRefineMaterialNum() + { + return m_pDBEssence.material_need; + } + public override uint GetRefineAddOn() + { + return (uint)m_pDBEssence.levelup_addon; + } + public override string GetDropModel() + { + return m_pDBEssence.FileMatter; + } + public override bool IsRare() + { + return base.IsRare() || m_Essence.weapon_level >= 6; + } + public override int GetItemLevel() + { + return m_Essence.weapon_level; + } + } +} \ No newline at end of file diff --git a/Assets/PerfectWorld/Scripts/Managers/EC_IvtrWeapon.cs.meta b/Assets/PerfectWorld/Scripts/Managers/EC_IvtrWeapon.cs.meta new file mode 100644 index 0000000000..0d5674d09d --- /dev/null +++ b/Assets/PerfectWorld/Scripts/Managers/EC_IvtrWeapon.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 6a4959477dd834d3089fcc85d831669a \ No newline at end of file diff --git a/Assets/PerfectWorld/Scripts/Managers/EC_ProfConfigs.cs b/Assets/PerfectWorld/Scripts/Managers/EC_ProfConfigs.cs new file mode 100644 index 0000000000..9376a5aca3 --- /dev/null +++ b/Assets/PerfectWorld/Scripts/Managers/EC_ProfConfigs.cs @@ -0,0 +1,153 @@ +using BrewMonster.Scripts; +using BrewMonster; +public static class EC_ProfConfigs +{ + + public static bool IsProfession(int prof) + { + return prof >= 0 && prof < (int)Profession.NUM_PROFESSION; + } + + public static bool IsGender(int gender) + { + return gender >= 0 && gender < (int)Gender.NUM_GENDER; + } + + public static bool IsRace(int race) + { + return race >= 0 && race < (int)Race.NUM_RACE; + } + + public static bool IsExist(int prof, int gender) + { + if (IsProfession(prof) && IsGender(gender)){ + bool[,] s_bExist = { + { true, true}, // 0:���� + { true, true}, // 1:��ʦ + { true, true}, // 2:��ʦ + { false, true}, // 3:���� + { true, false}, // 4:���� + { true, true}, // 5:�̿� + { true, true}, // 6:��â + { true, true}, // 7:���� + { true, true}, // 8:���� + { true, true}, // 9:���� + { true, true}, // 10:ҹӰ + { true, true}, // 11:���� + }; + return s_bExist[prof, gender]; + }else{ + //BMLogger.LogError("EC_ProfConfigs: IsExist: prof: {0} gender: {1} is not exist", prof, gender); + return false; + } + } + + public static int GetCounterpartGender(int gender) + { + return gender == (int)Gender.GENDER_MALE ? (int)Gender.GENDER_FEMALE : (int)Gender.GENDER_MALE; + } + + public static bool CanShowOnCreate(int prof, int gender) + { + // ������ɫʱ�Ƿ�Ӧ����ʾ��ְҵģ�ͣ�ÿְҵ��ʾһ���Ա� + if (IsProfession(prof) && IsGender(gender)){ + bool[] s_bShowMale = { + true, // 0:������ + false, // 1:��ʦ�� + false, // 2:��ʦ�� + false, // 3:������ + true, // 4:������ + true, // 5:�̿��� + true, // 6:��â�� + false, // 7:������ + true, // 8:������ + false, // 9:������ + true, // 8:ҹӰ�� + false, // 9:������ + }; + return (gender == (int)Gender.GENDER_MALE) ? s_bShowMale[prof] : !s_bShowMale[prof]; + } + //BMLogger.LogError("EC_ProfConfigs: CanShowOnCreate: prof: {0} gender: {1} is not exist", prof, gender); + return false; + } + + public static int GetRaceShowOrder(int race) + { + // ֵԽС���ȼ�Խ�� + if (IsRace(race)){ + int[] s_nRaceOrder = { + 1, + 2, + 3, + 4, + 5, + 0, + }; + return s_nRaceOrder[race]; + } + //BMLogger.LogError("EC_ProfConfigs: GetRaceShowOrder: race: {0} is not exist", race); + return -1; + } + + public static int GetRaceByProfession(int prof) + { + if (IsProfession(prof)){ + int[] s_nProfRace = { + (int)Race.RACE_HUMAN, + (int)Race.RACE_HUMAN, + (int)Race.RACE_GHOST, + (int)Race.RACE_ORC, + (int)Race.RACE_ORC, + (int)Race.RACE_GHOST, + (int)Race.RACE_ELF, + (int)Race.RACE_ELF, + (int)Race.RACE_LING, + (int)Race.RACE_LING, + (int)Race.RACE_OBORO, + (int)Race.RACE_OBORO, + }; + return s_nProfRace[prof]; + } + //BMLogger.LogError("EC_ProfConfigs: GetRaceByProfession: prof: {0} is not exist", prof); + return -1; + } + + public static int GetProfessionShowOrderInRace(int prof) + { + // ֵԽС���ȼ�Խ�� + if (IsProfession(prof)){ + int[] s_nRaceZeroShowOrderProf = { + (int)Profession.PROF_WARRIOR, // ���ࣺ���� + (int)Profession.PROF_ORC, // ���壺���� + (int)Profession.PROF_ANGEL, // ���ˣ����� + (int)Profession.PROF_MONK, // ϫ�壺��ʦ + (int)Profession.PROF_JIANLING, // ���壺���� + (int)Profession.PROF_YEYING, // ���壺ҹӰ + }; + int race = GetRaceByProfession(prof); + return prof == s_nRaceZeroShowOrderProf[race] ? 0 : 1; + } + //BMLogger.LogError("EC_ProfConfigs: GetProfessionShowOrderInRace: prof: {0} is not exist", prof); + return -1; + } + + public static bool ContainsAllProfession(uint mask){ + return (GetAllProfessionMask() & mask) == GetAllProfessionMask(); + } + + public static uint GetAllProfessionMask(){ + const uint ALL_PROFESSION_MASK = (1 << (int)Profession.NUM_PROFESSION)-1; + return ALL_PROFESSION_MASK; + } + + public static int GetMaxBodyID(int prof) + { + if (IsProfession(prof)){ + // PROF_ANGEL, PROF_ARCHOR, PROF_MAGE, PROF_WARRIOR didn't have nBodyID + int[] s_maxBodyID = {-1, -1, 4, 5, 3, 4, -1, -1, 4, 4, 1, 1 }; + return s_maxBodyID[prof]; + } + //BMLogger.LogError("EC_ProfConfigs: GetMaxBodyID: prof: {0} is not exist", prof); + return -1; + } +} \ No newline at end of file diff --git a/Assets/PerfectWorld/Scripts/Managers/EC_ProfConfigs.cs.meta b/Assets/PerfectWorld/Scripts/Managers/EC_ProfConfigs.cs.meta new file mode 100644 index 0000000000..311fa84a47 --- /dev/null +++ b/Assets/PerfectWorld/Scripts/Managers/EC_ProfConfigs.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 642d432c42e2d4929aa9b4b989d5334e \ No newline at end of file diff --git a/Assets/PerfectWorld/Scripts/Move/CECPlayer.cs b/Assets/PerfectWorld/Scripts/Move/CECPlayer.cs index e934330b0b..7965d58957 100644 --- a/Assets/PerfectWorld/Scripts/Move/CECPlayer.cs +++ b/Assets/PerfectWorld/Scripts/Move/CECPlayer.cs @@ -442,6 +442,10 @@ namespace BrewMonster { return m_PlayerInfo; } + // Get basic properties + public ROLEBASICPROP GetBasicProps() { return m_BasicProps; } + // Get extend properties + public ROLEEXTPROP GetExtendProps() { return m_ExtProps; } protected override void Update() { base.Update(); @@ -869,12 +873,6 @@ namespace BrewMonster //return iLevel * iLevel * 500; } - // Get basic properties - public ROLEBASICPROP GetBasicProps() - { - return m_BasicProps; - } - public override void TurnFaceTo(int idTarget, float dwTime = 200) { if (idTarget != 0) diff --git a/Assets/PerfectWorld/Scripts/Network/CSNetwork/GPDataType.cs b/Assets/PerfectWorld/Scripts/Network/CSNetwork/GPDataType.cs index bddd3ad28d..21aec35b30 100644 --- a/Assets/PerfectWorld/Scripts/Network/CSNetwork/GPDataType.cs +++ b/Assets/PerfectWorld/Scripts/Network/CSNetwork/GPDataType.cs @@ -2020,5 +2020,28 @@ namespace CSNetwork.GPDataType public int player_id; public int item_type; }; + + [StructLayout(LayoutKind.Sequential, Pack = 1)] + public struct cmd_reincarnation_tome_info + { + public int tome_exp; + public char tome_active; // 1����0δ���� + public int count; + public struct _entry + { + public int level; + public int timestamp; + public int exp; + }; + public _entry[] records; + public bool CheckValid(int buf_size, out int sz) + { sz = 0; + if (count < 0) + return false; + sz = Marshal.SizeOf() - Marshal.SizeOf<_entry[]>(); + sz += count * Marshal.SizeOf<_entry>(); + return buf_size >= sz; + } + }; } diff --git a/Assets/PerfectWorld/Scripts/UI/DlgAward/CDlgAward.cs b/Assets/PerfectWorld/Scripts/UI/DlgAward/CDlgAward.cs index f0e343afbe..de8eeb4b6f 100644 --- a/Assets/PerfectWorld/Scripts/UI/DlgAward/CDlgAward.cs +++ b/Assets/PerfectWorld/Scripts/UI/DlgAward/CDlgAward.cs @@ -87,9 +87,9 @@ namespace BrewMonster.Scripts.UI pTask.GetAwardCandidates(idTask, ref ad); if (ad.m_ulCandItems > 1) { - string szName; + string szName = ""; string strFile = ""; - string szText; + string szText = ""; EC_IvtrItem pItem; // AUICTranslate trans; // TODO // int i, j, idItem, nNum; @@ -128,22 +128,25 @@ namespace BrewMonster.Scripts.UI { idItem = ad.m_CandItems[i - 1].m_AwardItems[j - 1].m_ulItemTemplId; pItem = EC_IvtrItem.CreateItem((int)idItem, 0, 1); - + var pWeapon = pItem as EC_IvtrWeapon; nNum = ad.m_CandItems[i - 1].m_AwardItems[j - 1].m_ulItemNum; if (nNum > 1) { a_sprintf(out szText, _AL("%d"), nNum); + pImage.SetText(szText); } else pImage.SetText(_AL("")); - pItem.GetDetailDataFromLocal(); - pImage.SetHint(pItem.GetDesc()); // TODO + pWeapon.GetDetailDataFromLocal(); + string strDesc = pWeapon.GetDesc(); + pImage.SetHint(strDesc); // TODO //Debug.Log("[THN]CDlgAward: pItem.GetDesc():" + pItem.GetDesc()); // af_GetFileTitle(pItem.GetIconFile(), strFile); // TODO strFile.ToLower(); - + BMLogger.Log("[THN]CDlgAward: pItem.GetDesc():" + strDesc); + // TODO: Set the image cover here // pImage.SetCover(GetGameUIMan().m_pA2DSpriteIcons[CECGameUIMan::ICONS_INVENTORY], // GetGameUIMan().m_IconMap[CECGameUIMan::ICONS_INVENTORY][strFile]); diff --git a/Assets/PerfectWorld/Scripts/UI/NPCShopDetailPanel.cs b/Assets/PerfectWorld/Scripts/UI/NPCShopDetailPanel.cs index 1af4021df2..1f0c0e00b6 100644 --- a/Assets/PerfectWorld/Scripts/UI/NPCShopDetailPanel.cs +++ b/Assets/PerfectWorld/Scripts/UI/NPCShopDetailPanel.cs @@ -126,7 +126,7 @@ public class NPCShopDetailPanel : MonoBehaviour // For NPC shop items, we typically have static data only // Try to get description using GetNormalDesc() which works with base stats - string equipDesc = equipment.GetNormalDesc(); + string equipDesc = equipment.GetDesc(); if (!string.IsNullOrEmpty(equipDesc)) { // Replace C++ style "\r" line separators with real newlines for TMP diff --git a/Assets/PerfectWorld/Scripts/Utils/CECRTDebug.cs b/Assets/PerfectWorld/Scripts/Utils/CECRTDebug.cs index 7de115ac55..f59f79ac45 100644 --- a/Assets/PerfectWorld/Scripts/Utils/CECRTDebug.cs +++ b/Assets/PerfectWorld/Scripts/Utils/CECRTDebug.cs @@ -11,36 +11,125 @@ namespace BrewMonster } public class CECDataReader { - private byte[] data; - private int offset; - private int length; + public const int SEEK_SET = 0; /* set file offset to offset */ + public const int SEEK_CUR = 1; /* set file offset to current plus offset */ + public const int SEEK_END = 2; /* set file offset to EOF plus offset */ - public CECDataReader(byte[] data, int offset, int length) + private byte[] data; + private int length; + private int m_pStart; + private int m_pCur; + private int m_pEnd; + public CECDataReader(byte[] pDataBuf, int iDataLen) { - this.data = data; - this.offset = offset; - this.length = length; + if (pDataBuf == null || iDataLen <= 0) + { + throw new System.InvalidOperationException("Invalid data"); + } + + data = new byte[iDataLen]; + System.Array.Copy(pDataBuf, data, iDataLen); + this.length = iDataLen; + m_pStart = 0; + m_pCur = 0; + m_pEnd = iDataLen; + } + + public void Offset(int iOffset, int iSeekFlag) + { + int pCur = 0; + switch (iSeekFlag) + { + case SEEK_SET: pCur = m_pStart + iOffset; break; + case SEEK_CUR: pCur = m_pCur + iOffset; break; + case SEEK_END: pCur = m_pEnd + iOffset; break; + } + m_pCur = pCur; + BoundCheck(0); } public int ReadInt() { - if (offset + sizeof(int) > offset + length) - throw new System.InvalidOperationException("Not enough data to read int"); + BoundCheck(sizeof(int)); - int value = System.BitConverter.ToInt32(data, offset); - offset += sizeof(int); + int value = System.BitConverter.ToInt32(data, m_pCur); + m_pCur += sizeof(int); + return value; + } + public short ReadShort() + { + BoundCheck(sizeof(short)); + + short value = System.BitConverter.ToInt16(data, m_pCur); + m_pCur += sizeof(short); + return value; + } + public uint ReadUInt() + { + BoundCheck(sizeof(uint)); + + uint value = System.BitConverter.ToUInt32(data, m_pCur); + m_pCur += sizeof(uint); + return value; + } + public float ReadFloat() + { + BoundCheck(sizeof(float)); + + float value = System.BitConverter.ToSingle(data, m_pCur); + m_pCur += sizeof(float); + return value; + } + public byte ReadByte() + { + BoundCheck(sizeof(byte)); + + byte value = data[m_pCur]; + m_pCur += sizeof(byte); return value; } public byte[] ReadData(int size) { - if (offset + size > offset + length) - throw new System.InvalidOperationException($"Not enough data to read {size} bytes"); + BoundCheck(size); byte[] result = new byte[size]; - System.Array.Copy(data, offset, result, 0, size); - offset += size; + System.Array.Copy(data, m_pCur, result, 0, size); + m_pCur += size; return result; } + public ushort[] ReadUshortArray(int size) + { + BoundCheck(size * sizeof(ushort)); + + ushort[] result = new ushort[size]; + System.Array.Copy(data, m_pCur, result, 0, size * sizeof(ushort)); + m_pCur += size * sizeof(ushort); + return result; + } + public byte[] ReadByteArray(int size) + { + BoundCheck(size); + + byte[] result = new byte[size]; + System.Array.Copy(data, m_pCur, result, 0, size); + m_pCur += size; + return result; + } + public void PrintData(int size) + { + for(int i =m_pCur; i < m_pCur + size; i++) + { + BMLogger.Log("[thn]CECDataReader: PrintData: data[" + i + "]: " + data[i]); + } + } + void BoundCheck(int dwSize) + { + if (m_pCur + dwSize < m_pStart || m_pCur + dwSize > m_pEnd) + { + throw new System.InvalidOperationException("Out of bounds"); + } + } + } } diff --git a/Assets/Scripts/CECGameRun.cs b/Assets/Scripts/CECGameRun.cs index a51430797c..8daa2164a0 100644 --- a/Assets/Scripts/CECGameRun.cs +++ b/Assets/Scripts/CECGameRun.cs @@ -290,13 +290,12 @@ public partial class CECGameRun } pData = pUncompBuf; - dataOffset = 0; } try { // Create data reader / 创建数据读取器 - CECDataReader dr = new CECDataReader(pData, dataOffset, (int)dwRealLen); + CECDataReader dr = new CECDataReader(pData, (int)dwRealLen); // Load host configs / 加载主机配置 CECHostPlayer pHost = GetHostPlayer(); @@ -464,4 +463,33 @@ public partial class CECGameRun } return null; } + public string GetProfName(int i) + { + string szRet = null; + if (i >= 0 && i < (int)Profession.NUM_PROFESSION) + { + int[] s_ProfDesc = { + (int)FixedMsg.FIXMSG_PROF_WARRIOR, + (int)FixedMsg.FIXMSG_PROF_MAGE, + (int)FixedMsg.FIXMSG_PROF_MONK, + (int)FixedMsg.FIXMSG_PROF_HAG, + (int)FixedMsg.FIXMSG_PROF_ORC, + (int)FixedMsg.FIXMSG_PROF_GHOST, + (int)FixedMsg.FIXMSG_PROF_ARCHOR, + (int)FixedMsg.FIXMSG_PROF_ANGEL, + (int)FixedMsg.FIXMSG_PROF_JIANLING, + (int)FixedMsg.FIXMSG_PROF_MEILING, + (int)FixedMsg.FIXMSG_PROF_YEYING, + (int)FixedMsg.FIXMSG_PROF_YUEXIAN, + }; + CECStringTab pStrTab = EC_Game.GetFixedMsgs(); + szRet = pStrTab.GetWideString(s_ProfDesc[i]); + } + else + { + //BMLogger.LogError("CECGameRun::GetProfName, i: {0} is not exist", i); + return null; + } + return szRet; + } } diff --git a/Assets/Scripts/CECHostPlayer.cs b/Assets/Scripts/CECHostPlayer.cs index 5636f0de10..6742e612da 100644 --- a/Assets/Scripts/CECHostPlayer.cs +++ b/Assets/Scripts/CECHostPlayer.cs @@ -5616,5 +5616,30 @@ namespace BrewMonster } } } + + [StructLayout(LayoutKind.Sequential, Pack = 1)] + public struct REINCARNATION_TOME + { + public int tome_exp; + public char tome_active; // 1已激活0未激活 / 1 activated 0 not activated + public int max_level; // 历史最高等级 / Historical highest level + public List reincarnations; + public const int max_exp = 0; // TODO: Set actual value + public void Clear(){ + tome_exp = 0; + tome_active = (char)0; + max_level = 0; + if (reincarnations != null) + { + reincarnations.Clear(); + } + else + { + reincarnations = new List(); + } + } + }; + REINCARNATION_TOME m_ReincarnationTome; + public int GetMaxLevelSofar() { return Math.Max(m_ReincarnationTome.max_level, m_BasicProps.iLevel);} } } \ No newline at end of file From 22bf1bddcbe39c7b3b6f3c87f0bedcf3cbc41689 Mon Sep 17 00:00:00 2001 From: Chomper9981 Date: Mon, 12 Jan 2026 15:52:09 +0700 Subject: [PATCH 4/7] add armor dialog for quest "chao hoi" --- .../Common/DataProcess/elementdataman.cs | 4 - .../Common/DataProcess/generate_item_temp.cs | 45 +- .../Scripts/Common/DataProcess/itemdataman.cs | 204 ++++--- .../Scripts/Inventory/EC_IvtrType.cs | 3 + .../Scripts/Managers/EC_IvtrArmor.cs | 537 ++++++++++++++++++ .../Scripts/Managers/EC_IvtrArmor.cs.meta | 2 + .../Scripts/Managers/EC_IvtrEquip.cs | 45 +- .../Scripts/Managers/EC_IvtrItem.cs | 8 +- .../Scripts/Managers/EC_IvtrType.cs | 24 +- .../Scripts/Managers/EC_IvtrWeapon.cs | 8 +- .../Scripts/Network/UnityGameSession.cs | 1 - .../Scripts/UI/Dialogs/AUIListBox.cs | 1 + .../PerfectWorld/Scripts/UI/Dialogs/DlgNPC.cs | 1 - .../Scripts/UI/DlgAward/CDlgAward.cs | 5 +- .../Scripts/UI/Login/LoginScreenUI.cs | 3 - 15 files changed, 734 insertions(+), 157 deletions(-) create mode 100644 Assets/PerfectWorld/Scripts/Managers/EC_IvtrArmor.cs create mode 100644 Assets/PerfectWorld/Scripts/Managers/EC_IvtrArmor.cs.meta diff --git a/Assets/PerfectWorld/Scripts/Common/DataProcess/elementdataman.cs b/Assets/PerfectWorld/Scripts/Common/DataProcess/elementdataman.cs index 598086940a..45aa4f3edb 100644 --- a/Assets/PerfectWorld/Scripts/Common/DataProcess/elementdataman.cs +++ b/Assets/PerfectWorld/Scripts/Common/DataProcess/elementdataman.cs @@ -1765,15 +1765,11 @@ namespace ModelRenderer.Scripts.GameData break; case ID_SPACE.ID_SPACE_ADDON: - BMLogger.Log("[thn] weapon addon map count: " + addon_id_data_map.Count); - BMLogger.Log("[thn] weapon addon id: " + id); if (addon_id_data_map.TryGetValue(id, out data)) { - dataType = addon_id_data_type_map[id]; return data; } - BMLogger.Log("[thn] weapon addon data: " + data); break; default: diff --git a/Assets/PerfectWorld/Scripts/Common/DataProcess/generate_item_temp.cs b/Assets/PerfectWorld/Scripts/Common/DataProcess/generate_item_temp.cs index ea8eeec9a1..36685b2f41 100644 --- a/Assets/PerfectWorld/Scripts/Common/DataProcess/generate_item_temp.cs +++ b/Assets/PerfectWorld/Scripts/Common/DataProcess/generate_item_temp.cs @@ -35,12 +35,12 @@ public static class generate_item_temp if(normal_addon == GEN_ADDON_MODE.ADDON_LIST_DROP) { float[] drop_probability_socket = { ess.drop_probability_socket0, ess.drop_probability_socket1, ess.drop_probability_socket2 }; - hole_num = (uint)element_data.RandSelect_SPECIFIC_LOWER(drop_probability_socket.ToList(), SPECIFIC.SPECIFIC_RAND, LOWER.LOWER_TREND); //�׶�����Ŀ + hole_num = (uint)element_data.RandSelect(drop_probability_socket.ToList(), cls, LOWER.LOWER_TREND); //�׶�����Ŀ } else //if(normal_addon == element_data::ADDON_LIST_PRODUCE || normal_addon == element_data::ADDON_LIST_SPEC) { float[] make_probability_socket = { ess.make_probability_socket0, ess.make_probability_socket1, ess.make_probability_socket2 }; - hole_num = (uint)element_data.RandSelect_SPECIFIC_LOWER(make_probability_socket.ToList(), SPECIFIC.SPECIFIC_RAND, LOWER.LOWER_TREND); //�׶�����Ŀ + hole_num = (uint)element_data.RandSelect(make_probability_socket.ToList(), cls, LOWER.LOWER_TREND); //�׶�����Ŀ } size += hole_num*sizeof(int); // size ����hole_num������type @@ -54,7 +54,7 @@ public static class generate_item_temp byte[] addon_buf = new byte[candidate_num*Marshal.SizeOf(typeof(itemdataman._addon))]; float[] probability_addon_num = { ess.probability_addon_num0, ess.probability_addon_num1, ess.probability_addon_num2, ess.probability_addon_num3, ess.probability_addon_num4, ess.probability_addon_num5 }; //log each probability_addon_num - uint addon_num = (uint)element_data.RandSelect_NORMAL_LOWER(probability_addon_num.ToList(), NORMAL.NORMAL_RAND, LOWER.LOWER_TREND); //���Ա���Ŀ����Ŀ + uint addon_num = (uint)element_data.RandSelect(probability_addon_num.ToList(), cls, LOWER.LOWER_TREND); //���Ա���Ŀ����Ŀ uint addon_size = 0; // if(ess->fixed_props) @@ -106,7 +106,6 @@ public static class generate_item_temp } size += addon_size; - BMLogger.Log("[thn]generate_weapon, addon_size: " + addon_size); // allocate the buffer with exact length // *data = (char *)abase::fastalloc(size); @@ -200,7 +199,7 @@ public static class generate_item_temp // temp = element_data::RandNormal(ess->durability_drop_min, ess->durability_drop_max, cls,element_data::UPPER_TREND); // if(temp > temp2) temp = temp2; // } - int temp2 = element_data.RandNormal_NORMAL_LOWER(ess.durability_min, ess.durability_max, NORMAL.NORMAL_RAND, LOWER.LOWER_TREND); + int temp2 = element_data.RandNormal(ess.durability_min, ess.durability_max, cls, LOWER.LOWER_TREND); int temp = temp2; if(normal_addon != GEN_ADDON_MODE.ADDON_LIST_DROP || (ess.proc_type & 0x1000) != 0) { @@ -208,7 +207,7 @@ public static class generate_item_temp } else { - temp = element_data.RandNormal_NORMAL_UPPER(ess.durability_drop_min, ess.durability_drop_max, NORMAL.NORMAL_RAND, UPPER.UPPER_TREND); + temp = element_data.RandNormal(ess.durability_drop_min, ess.durability_drop_max, cls, UPPER.UPPER_TREND); if(temp > temp2) temp = temp2; } @@ -222,8 +221,9 @@ public static class generate_item_temp // memcpy(buf,tag,tag_size); // buf += tag_size; WriteShort(data, ref offset, (short)Marshal.SizeOf(typeof(_weapon_essence))); + WriteByte(data, ref offset, tag.type); // MadeFrom - WriteByte(data, ref offset, 0); + WriteByte(data, ref offset, (byte)tag.size); //essence //char ����[]; //ÿ�ֲ�ͬװ���ı���ṹ���? // char * essence_ptr = buf; @@ -262,9 +262,9 @@ public static class generate_item_temp WriteInt(data, ref offset, ess.level); WriteUInt(data, ref offset, ess.require_projectile); WriteInt(data, ref offset, ess.damage_low); - WriteInt(data, ref offset, element_data.RandNormal_NORMAL_LOWER(ess.damage_high_min, ess.damage_high_max, NORMAL.NORMAL_RAND, LOWER.LOWER_TREND)); + WriteInt(data, ref offset, element_data.RandNormal(ess.damage_high_min, ess.damage_high_max, cls, LOWER.LOWER_TREND)); WriteInt(data, ref offset, ess.magic_damage_low); - WriteInt(data, ref offset, element_data.RandNormal_NORMAL_LOWER(ess.magic_damage_high_min, ess.magic_damage_high_max, NORMAL.NORMAL_RAND, LOWER.LOWER_TREND)); + WriteInt(data, ref offset, element_data.RandNormal(ess.magic_damage_high_min, ess.magic_damage_high_max, cls, LOWER.LOWER_TREND)); // WEAPON_SUB_TYPE * subtype = (WEAPON_SUB_TYPE * )get_data_ptr(ess->id_sub_type, ID_SPACE_ESSENCE, datatype); // if(subtype == NULL || datatype != DT_WEAPON_SUB_TYPE) // { @@ -286,7 +286,7 @@ public static class generate_item_temp { subtype = (WEAPON_SUB_TYPE)sub_type_temp; float[] probability_attack_speed = { subtype.probability_fastest, subtype.probability_fast, subtype.probability_normal, subtype.probability_slow, subtype.probability_slowest }; - int index = element_data.RandSelect_SPECIFIC_MIDDLE(probability_attack_speed.ToList(), SPECIFIC.SPECIFIC_RAND, MIDDLE.MIDDLE_TREND); + int index = element_data.RandSelect(probability_attack_speed.ToList(), cls, MIDDLE.MIDDLE_TREND); WriteInt(data, ref offset, (int)(subtype.attack_speed*20f + 0.1f) + (index - 2)); } @@ -354,7 +354,7 @@ public static class generate_item_temp int RE_num = 0; if(!b_fixed) { - RE_num = element_data.RandSelect_SPECIFIC_LOWER(count_prop.ToList(), SPECIFIC.SPECIFIC_RAND, LOWER.LOWER_TREND); + RE_num = element_data.RandSelect(count_prop.ToList(), cls, LOWER.LOWER_TREND); } if(RE_num == 5) return; // Ensure RE_num is within valid range for md_adjust array (0-4) @@ -382,7 +382,7 @@ public static class generate_item_temp } int low = res_list[index *2].low; int high= res_list[index *2+1].high; - res[index] = (int)(element_data.RandNormal_NORMAL_LOWER(low, high, NORMAL.NORMAL_RAND, LOWER.LOWER_TREND) * adj); + res[index] = (int)(element_data.RandNormal(low, high, cls, LOWER.LOWER_TREND) * adj); } } public static int generate_armor(uint id, ID_SPACE idspace, out byte[] data, out uint size, RAND_CLASS cls, @@ -405,19 +405,19 @@ public static class generate_item_temp if(normal_addon == GEN_ADDON_MODE.ADDON_LIST_DROP) { float[] drop_probability_socket = { ess.drop_probability_socket0, ess.drop_probability_socket1, ess.drop_probability_socket2 }; - hole_num = (short)element_data.RandSelect_SPECIFIC_LOWER(drop_probability_socket.ToList(), SPECIFIC.SPECIFIC_RAND, LOWER.LOWER_TREND); //�׶�����Ŀ + hole_num = (short)element_data.RandSelect(drop_probability_socket.ToList(), cls, LOWER.LOWER_TREND); //�׶�����Ŀ } else //if(normal_addon == element_data::ADDON_LIST_PRODUCE || normal_addon == element_data::ADDON_LIST_SPEC) { float[] make_probability_socket = { ess.make_probability_socket0, ess.make_probability_socket1, ess.make_probability_socket2 }; - hole_num = (short)element_data.RandSelect_SPECIFIC_MIDDLE(make_probability_socket.ToList(), SPECIFIC.SPECIFIC_RAND, MIDDLE.MIDDLE_TREND); //�׶�����Ŀ + hole_num = (short)element_data.RandSelect(make_probability_socket.ToList(), cls, MIDDLE.MIDDLE_TREND); //�׶�����Ŀ } size += (uint)(hole_num*sizeof(int)); // size ����hole_num������type size += (uint)Marshal.SizeOf(typeof(item_tag_t)); uint candidate_num = itemdataman.ELEMENTDATAMAN_MAX_NUM_ADDONS; byte[] addon_buf = new byte[candidate_num*Marshal.SizeOf(typeof(itemdataman._addon))]; float[] probability_addon_num = { ess.probability_addon_num0, ess.probability_addon_num1, ess.probability_addon_num2, ess.probability_addon_num3, ess.probability_addon_num4 }; - uint addon_num = (uint)element_data.RandSelect_SPECIFIC_LOWER(probability_addon_num.ToList(), SPECIFIC.SPECIFIC_RAND, LOWER.LOWER_TREND); //���Ա���Ŀ����Ŀ + uint addon_num = (uint)element_data.RandSelect(probability_addon_num.ToList(), cls, LOWER.LOWER_TREND); //���Ա���Ŀ����Ŀ uint addon_size = 0; if(ess.fixed_props!=0) { @@ -495,7 +495,7 @@ public static class generate_item_temp WriteShort(data, ref offset, (short)ess.require_agility); WriteShort(data, ref offset, (short)ess.require_energy); - int temp2 = element_data.RandNormal_NORMAL_LOWER(ess.durability_min, ess.durability_max, NORMAL.NORMAL_RAND, LOWER.LOWER_TREND); + int temp2 = element_data.RandNormal(ess.durability_min, ess.durability_max, cls, LOWER.LOWER_TREND); int temp = temp2; if(normal_addon != GEN_ADDON_MODE.ADDON_LIST_DROP || (ess.proc_type & 0x1000) != 0) { @@ -503,19 +503,20 @@ public static class generate_item_temp } else { - temp = element_data.RandNormal_NORMAL_UPPER(ess.durability_drop_min, ess.durability_drop_max, NORMAL.NORMAL_RAND, UPPER.UPPER_TREND); + temp = element_data.RandNormal(ess.durability_drop_min, ess.durability_drop_max, cls, UPPER.UPPER_TREND); if(temp > temp2) temp = temp2; } WriteInt(data, ref offset, temp); // durability WriteInt(data, ref offset, temp2); // max_durability WriteShort(data, ref offset, (short)Marshal.SizeOf(typeof(ARMOR_ESSENCE))); - WriteTag(data, ref offset, tag); + WriteByte(data, ref offset, (byte)tag.type); // MadeFrom + WriteByte(data, ref offset, (byte)tag.size); int essence_ptr = offset; - WriteInt(data, ref offset, element_data.RandNormal_NORMAL_LOWER(ess.defence_low, ess.defence_high, NORMAL.NORMAL_RAND, LOWER.LOWER_TREND)); - WriteInt(data, ref offset, element_data.RandNormal_NORMAL_LOWER(ess.armor_enhance_low, ess.armor_enhance_high, NORMAL.NORMAL_RAND, LOWER.LOWER_TREND)); - WriteInt(data, ref offset, element_data.RandNormal_NORMAL_LOWER(ess.mp_enhance_low, ess.mp_enhance_high, NORMAL.NORMAL_RAND, LOWER.LOWER_TREND)); - WriteInt(data, ref offset, element_data.RandNormal_NORMAL_LOWER(ess.hp_enhance_low, ess.hp_enhance_high, NORMAL.NORMAL_RAND, LOWER.LOWER_TREND)); + WriteInt(data, ref offset, element_data.RandNormal(ess.defence_low, ess.defence_high, cls, LOWER.LOWER_TREND)); + WriteInt(data, ref offset, element_data.RandNormal(ess.armor_enhance_low, ess.armor_enhance_high, cls, LOWER.LOWER_TREND)); + WriteInt(data, ref offset, element_data.RandNormal(ess.mp_enhance_low, ess.mp_enhance_high, cls, LOWER.LOWER_TREND)); + WriteInt(data, ref offset, element_data.RandNormal(ess.hp_enhance_low, ess.hp_enhance_high, cls, LOWER.LOWER_TREND)); int[] res = {0,0,0,0,0}; List res_list = ess.magic_defences.ToList(); generate_magic_defense(res, res_list, cls, ess.force_all_magic_defences != 0 || ess.fixed_props!=0); diff --git a/Assets/PerfectWorld/Scripts/Common/DataProcess/itemdataman.cs b/Assets/PerfectWorld/Scripts/Common/DataProcess/itemdataman.cs index 3f61028741..b4085ec4c8 100644 --- a/Assets/PerfectWorld/Scripts/Common/DataProcess/itemdataman.cs +++ b/Assets/PerfectWorld/Scripts/Common/DataProcess/itemdataman.cs @@ -36,7 +36,7 @@ namespace BrewMonster return lower + (upper - lower) * rng / (float)RAND_MAX; } - public static int RandNormal(int lower, int upper) { return Rand(lower, upper); } + public static int RandNormal(float lower, float upper) { return (int)Rand(lower, upper); } public static float RandUniform() { return Rand(0f, 1f); } public static int RandSelect(List option) @@ -146,97 +146,115 @@ namespace BrewMonster } public static class element_data { - public static int RandNormal(int lower, int upper, TCls c) where TCls : SpecCls - { - return c.RandNormal(lower, upper); - } - public static int RandSelect(List option, TCls c) where TCls : SpecCls - { - return c.RandSelect(option); - } - public static float Rand(float lower, float upper, TCls c) where TCls : SpecCls - { - return c.Rand(lower, upper); - } - public static int RandSelect_NORMAL_LOWER(List option, NORMAL normalType, LOWER lowerTrend) - { - return abase.abase.RandSelect(option); - } - public static int RandSelect_NORMAL_MIDDLE(List option, NORMAL normalType, MIDDLE middleTrend) - { - return abase.abase.RandSelect(option); - } - public static int RandSelect_SPECIFIC_LOWER(List option, SPECIFIC specificType, LOWER lowerTrend) + public static int RandNormal(int lower, int upper, TCls c ,TTrend trend) { + if(c != null && c.Equals(NORMAL.NORMAL_RAND)) + { + if (trend != null && trend.Equals(LOWER.LOWER_TREND)) + { + return abase.abase.RandNormal(lower, upper); + } + else if (trend != null && trend.Equals(MIDDLE.MIDDLE_TREND)) + { + return abase.abase.RandNormal(lower, upper); + } + else if (trend != null && trend.Equals(UPPER.UPPER_TREND)) + { + return abase.abase.RandNormal(lower, upper); + } + else if (trend != null && trend.Equals(ANY.ANY_TREND)) + { + return abase.abase.RandNormal(lower, upper); + } + } + else if(c != null && c.Equals(SPECIFIC.SPECIFIC_RAND)) + { + if (trend != null && trend.Equals(LOWER.LOWER_TREND)) + { + return lower; + } + else if (trend != null && trend.Equals(MIDDLE.MIDDLE_TREND)) + { + return (lower + upper) / 2; + } + else if (trend != null && trend.Equals(UPPER.UPPER_TREND)) + { + return upper; + } + else if (trend != null && trend.Equals(ANY.ANY_TREND)) + { + return abase.abase.RandNormal(lower, upper); + } + } return 0; } - public static int RandSelect_SPECIFIC_MIDDLE(List option, SPECIFIC specificType, MIDDLE middleTrend) + public static int RandSelect(List option, TCls c, TTrend trend) { - return option.Count / 2; + if(c != null && c.Equals(NORMAL.NORMAL_RAND)) + { + if (trend != null && trend.Equals(LOWER.LOWER_TREND)) + { + return abase.abase.RandSelect(option); + } + else if (trend != null && trend.Equals(MIDDLE.MIDDLE_TREND)) + { + return abase.abase.RandSelect(option); + } + } + else if(c != null && c.Equals(SPECIFIC.SPECIFIC_RAND)) + { + if (trend != null && trend.Equals(LOWER.LOWER_TREND)) + { + return 0; + } + else if (trend != null && trend.Equals(MIDDLE.MIDDLE_TREND)) + { + return option.Count /2; + } + } + return 0; } - public static int RandNormal_NORMAL_LOWER(int lower, int upper, NORMAL normalType, LOWER lowerTrend) + public static float Rand(float lower, float upper, TCls c, TTrend trend) { - return abase.abase.RandNormal(lower, upper); - } - public static int RandNormal_NORMAL_UPPER(int lower, int upper, NORMAL normalType, UPPER upperTrend) - { - return abase.abase.RandNormal(lower, upper); - } - public static int RandNormal_NORMAL_MIDDLE(int lower, int upper, NORMAL normalType, MIDDLE middleTrend) - { - return abase.abase.RandNormal(lower, upper); - } - public static int RandNormal_NORMAL_ANY(int lower, int upper, NORMAL normalType, ANY anyTrend) - { - return abase.abase.RandNormal(lower, upper); - } - public static int RandNormal_SPECIFIC_LOWER(int lower, int upper, SPECIFIC specificType, LOWER lowerTrend) - { - return lower; - } - public static int RandNormal_SPECIFIC_UPPER(int lower, int upper, SPECIFIC specificType, UPPER upperTrend) - { - return upper; - } - public static int RandNormal_SPECIFIC_MIDDLE(int lower, int upper, SPECIFIC specificType, MIDDLE middleTrend) - { - return (upper + lower) / 2; - } - public static int RandNormal_SPECIFIC_ANY(int lower, int upper, SPECIFIC specificType, ANY anyTrend) - { - return abase.abase.RandNormal(lower, upper); - } - public static float Rand_NORMAL_LOWER(float lower, float upper, NORMAL normalType, LOWER lowerTrend) - { - return abase.abase.Rand(lower, upper); - } - public static float Rand_NORMAL_MIDDLE(float lower, float upper, NORMAL normalType, MIDDLE middleTrend) - { - return abase.abase.Rand(lower, upper); - } - public static float Rand_NORMAL_UPPER(float lower, float upper, NORMAL normalType, UPPER upperTrend) - { - return abase.abase.Rand(lower, upper); - } - public static float Rand_NORMAL_ANY(float lower, float upper, NORMAL normalType, ANY anyTrend) - { - return abase.abase.Rand(lower, upper); - } - public static float Rand_SPECIFIC_LOWER(float lower, float upper, SPECIFIC specificType, LOWER lowerTrend) - { - return lower; - } - public static float Rand_SPECIFIC_MIDDLE(float lower, float upper, SPECIFIC specificType, MIDDLE middleTrend) - { - return (upper + lower) / 2; - } - public static float Rand_SPECIFIC_UPPER(float lower, float upper, SPECIFIC specificType, UPPER upperTrend) - { - return upper; - } - public static float Rand_SPECIFIC_ANY(float lower, float upper, SPECIFIC specificType, ANY anyTrend) - { - return abase.abase.Rand(lower, upper); + if(c != null && c.Equals(NORMAL.NORMAL_RAND)) + { + if (trend != null && trend.Equals(LOWER.LOWER_TREND)) + { + return abase.abase.Rand(lower, upper); + } + else if (trend != null && trend.Equals(MIDDLE.MIDDLE_TREND)) + { + return abase.abase.Rand(lower, upper); + } + else if (trend != null && trend.Equals(UPPER.UPPER_TREND)) + { + return abase.abase.Rand(lower, upper); + } + else if (trend != null && trend.Equals(ANY.ANY_TREND)) + { + return abase.abase.Rand(lower, upper); + } + } + else if(c != null && c.Equals(SPECIFIC.SPECIFIC_RAND)) + { + if (trend != null && trend.Equals(LOWER.LOWER_TREND)) + { + return lower; + } + else if (trend != null && trend.Equals(MIDDLE.MIDDLE_TREND)) + { + return (lower + upper) / 2; + } + else if (trend != null && trend.Equals(UPPER.UPPER_TREND)) + { + return upper; + } + else if (trend != null && trend.Equals(ANY.ANY_TREND)) + { + return abase.abase.Rand(lower, upper); + } + } + return 0; } } public enum GEN_ADDON_MODE @@ -424,9 +442,8 @@ namespace BrewMonster uint size = 0; int ret = 0; DATA_TYPE datatype = DATA_TYPE.DT_INVALID; - item_tag_t tag = new item_tag_t((byte)ITEM_MAKE_TAG.IMT_SHOP, (byte)'0'); + item_tag_t tag = new item_tag_t((byte)ITEM_MAKE_TAG.IMT_SHOP, (byte)0); //uint id = _edm.get_first_data_id(ID_SPACE.ID_SPACE_ESSENCE,ref datatype); - BMLogger.Log("[THN]itemdataman: generate_item_for_sell: _edm.essence_id_data_type_map.Count: " + _edm.essence_id_data_type_map.Count); for (int i = 0; i < _edm.essence_id_data_type_map.Count; i++) { ret = 0; @@ -749,8 +766,7 @@ namespace BrewMonster // } #endregion - } - BMLogger.Log("[THN]itemdataman: generate_item_for_sell: sale_item_ptr_array.Count: " + sale_item_ptr_array.Count); + } return 0; } @@ -833,8 +849,8 @@ namespace BrewMonster { //���ɶ��addon�����ܻ��в�������ʧ�� - if(addon_num == 0) - return 0; + //if(addon_num == 0) + //return 0; byte[] addon_sld = addon_buffer; int i,j; int anum = 0; @@ -910,7 +926,7 @@ namespace BrewMonster { uint un = 0; //ASSERT(addon_size == 0); - if(element_data.Rand_NORMAL_LOWER(0f,1f,NORMAL.NORMAL_RAND,LOWER.LOWER_TREND) < unique_prob) + if(element_data.Rand(0f,1f,cls,LOWER.LOWER_TREND) < unique_prob) { un = 1; addon_size = generate_equipment_addon_buffer(dt, unique, 16, addon_buf,0, un); @@ -923,7 +939,7 @@ namespace BrewMonster { uint un = 0; //ASSERT(addon_size == 0); - if(element_data.Rand_NORMAL_LOWER(0f,1f,NORMAL.NORMAL_RAND,LOWER.LOWER_TREND) < unique_prob) + if(element_data.Rand(0f,1f,cls,LOWER.LOWER_TREND) < unique_prob) { un = 1; addon_size = generate_equipment_addon_buffer(dt, unique, 16, addon_buf,0, un); diff --git a/Assets/PerfectWorld/Scripts/Inventory/EC_IvtrType.cs b/Assets/PerfectWorld/Scripts/Inventory/EC_IvtrType.cs index 17a088ea27..27a4b3dcf8 100644 --- a/Assets/PerfectWorld/Scripts/Inventory/EC_IvtrType.cs +++ b/Assets/PerfectWorld/Scripts/Inventory/EC_IvtrType.cs @@ -2,7 +2,10 @@ namespace BrewMonster.Scripts { public class InventoryConst { + // Equipment endurance scale public const int ENDURANCE_SCALE = 100; + // NUM_MAGICCLASS + public const int NUM_MAGICCLASS = 5; // Index of item in equipment inventory public const int EQUIPIVTR_WEAPON = 0; public const int EQUIPIVTR_HEAD = 1; diff --git a/Assets/PerfectWorld/Scripts/Managers/EC_IvtrArmor.cs b/Assets/PerfectWorld/Scripts/Managers/EC_IvtrArmor.cs new file mode 100644 index 0000000000..1a87d95aae --- /dev/null +++ b/Assets/PerfectWorld/Scripts/Managers/EC_IvtrArmor.cs @@ -0,0 +1,537 @@ +// /* +// * FILE: EC_IvtrWeapon.cpp +// * +// * DESCRIPTION: +// * +// * CREATED BY: Duyuxin, 2004/11/19 +// * +// * HISTORY: +// * +// * Copyright (c) 2004 Archosaur Studio, All Rights Reserved. +// */ + +// #include "EC_Global.h" +// #include "EC_IvtrWeapon.h" +// #include "EC_Game.h" +// #include "EC_FixedMsg.h" +// #include "EC_GameRun.h" +// #include "EC_HostPlayer.h" +// #include "EC_RTDebug.h" +// #include "elementdataman.h" +// #include "EC_Configs.h" +using BrewMonster; +using ModelRenderer.Scripts.GameData; +using System.Collections.Generic; +using BrewMonster.Network; +using BrewMonster.Scripts.Managers; +using BrewMonster.Scripts; +#region C# regions +// #define new A_DEBUG_NEW + +// /////////////////////////////////////////////////////////////////////////// +// // +// // Define and Macro +// // +// /////////////////////////////////////////////////////////////////////////// + + +// /////////////////////////////////////////////////////////////////////////// +// // +// // Reference to External variables and functions +// // +// /////////////////////////////////////////////////////////////////////////// + + +// /////////////////////////////////////////////////////////////////////////// +// // +// // Local Types and Variables and Global variables +// // +// /////////////////////////////////////////////////////////////////////////// + + +// /////////////////////////////////////////////////////////////////////////// +// // +// // Local functions +// // +// /////////////////////////////////////////////////////////////////////////// + +// /////////////////////////////////////////////////////////////////////////// +// // +// // Implement CECIvtrWeapon +// // +// /////////////////////////////////////////////////////////////////////////// +#endregion + +namespace PerfectWorld.Scripts.Managers +{ + + public class EC_IvtrArmor : EC_IvtrEquip + { + //Attributes + //Weapon essence data + protected IVTR_ESSENCE_ARMOR m_Essence; + // data in database + protected ARMOR_MAJOR_TYPE m_pDBMajorType; + protected ARMOR_SUB_TYPE m_pDBSubType; + protected ARMOR_ESSENCE m_pDBEssence; + + public EC_IvtrArmor(int tid, int expire_date) : base(tid, expire_date) + { + m_iCID = ICID_WEAPON; + elementdataman pDB = ElementDataManProvider.GetElementDataMan(); + DATA_TYPE DataType = DATA_TYPE.DT_INVALID; + m_pDBEssence = (ARMOR_ESSENCE)pDB.get_data_ptr((uint)tid, ID_SPACE.ID_SPACE_ESSENCE, ref DataType); + m_pDBMajorType = (ARMOR_MAJOR_TYPE)pDB.get_data_ptr(m_pDBEssence.id_major_type, ID_SPACE.ID_SPACE_ESSENCE, ref DataType); + m_pDBSubType = (ARMOR_SUB_TYPE)pDB.get_data_ptr(m_pDBEssence.id_sub_type, 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_i64EquipMask = EC_IvtrEquip.ICID_WEAPON; + m_iProcType = (int)m_pDBEssence.proc_type; + + FixProps = m_pDBEssence.fixed_props; + RepairFee = m_pDBEssence.repairfee; + ReputationReq = m_pDBEssence.require_reputation; + } + public EC_IvtrArmor(EC_IvtrArmor other) : base(other) + { + m_pDBEssence = other.m_pDBEssence; + m_pDBMajorType = other.m_pDBMajorType; + m_pDBSubType = other.m_pDBSubType; + m_Essence = other.m_Essence; + } + + // CECIvtrWeapon::~CECIvtrWeapon() + // { + // } + + 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); + // Skip equip requirements and endurance + dr.Offset(6 * sizeof(short), CECDataReader.SEEK_CUR); + dr.Offset(2 * sizeof(int), CECDataReader.SEEK_CUR); + int iEssenceSize = dr.ReadShort(); + // Skip maker's information + dr.ReadByte(); + int iMakerLen = dr.ReadByte(); + dr.Offset(iMakerLen, CECDataReader.SEEK_CUR); + byte[] iEssenceData = dr.ReadData(iEssenceSize); + m_Essence = new IVTR_ESSENCE_ARMOR(iEssenceData); + // ���븽������˵�� + if(m_pDBEssence.fixed_props != 0 && m_pDBEssence.probability_addon_num0 != 1.0f) + { + // Get database data + elementdataman pDataMan = ElementDataManProvider.GetElementDataMan(); + CECStringTab PropTab = EC_Game.GetItemExtProp(); + int i, iSize = 0; + for(i=0;i<32;i++) + { + if(m_pDBEssence.addons[i].id_addon != 0) + iSize++; + } + if(iSize > 0 && Props.Count == 0) + { + Props.Capacity = iSize; + for(i=0;i<32;i++) + { + if(m_pDBEssence.addons[i].id_addon != 0) + { + Property Prop = new Property(); + Prop.Type = (int)m_pDBEssence.addons[i].id_addon; + Prop.Embed = false; + Prop.Suite = false; + Prop.Engraved = false; + Prop.Local = false; + byte bType = PropTab.GetWideString(Prop.Type) != null ? (byte)0xff : (byte)0xff; + DATA_TYPE DataType = DATA_TYPE.DT_INVALID; + object pData = pDataMan.get_data_ptr(m_pDBEssence.addons[i].id_addon, ID_SPACE.ID_SPACE_ADDON, ref DataType); + if (DataType != DATA_TYPE.DT_EQUIPMENT_ADDON) + { + return false; + } + EQUIPMENT_ADDON pAddon = (EQUIPMENT_ADDON)pData; + Prop.NumParam = pAddon.num_params; + for(int j=0; j < Prop.NumParam; j++) + { + if(j==0) + { + Prop.Params[0] = pAddon.param1; + } + else if(j==1) + { + Prop.Params[1] = pAddon.param2; + } + else if(j==2) + { + Prop.Params[2] = pAddon.param3; + } + } + Props.Add(Prop); + } + } + } + } + return true; + } + catch ( System.Exception e) + { + return false; + } + } + // Get item default information from database + public override void DefaultInfo() + { + LevelReq = m_pDBEssence.require_level; + StrengthReq = m_pDBEssence.require_strength; + AgilityReq = m_pDBEssence.require_agility; + ReputationReq = m_pDBEssence.require_reputation; + CurEndurance = m_pDBEssence.durability_min * ENDURANCE_SCALE; + MaxEndurance = m_pDBEssence.durability_min * ENDURANCE_SCALE; + } + // Get item icon file name + public override string GetIconFile() + { + return m_pDBEssence.FileIcon; + } + // Get item name + public override string GetName() + { + return m_pDBEssence.Name; + } + // Get preview info + public override string GetPreviewInfo() + { + int[] aPEEVals = new int[MAX_PEEINDEX]; + int[] aRefines = new int[MAX_REFINEINDEX]; + for(int i=0; i 0) + { + AddDescText(namecol, false, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_NAMESOCKET), GetName(), Holes.Count); + } + else + { + AddDescText(namecol, false, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_NAME), GetName()); + } + // Refine level + if (RefineLvl > 0) + AddDescText(-1, true, "{0} +{1}", pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_LEVEL), RefineLvl); + else + m_strDesc += "\\r"; + AddIDDescText(); + AddBindDescText(); + // Is destroying? + AddDestroyingDesc((int)m_pDBEssence.id_drop_after_damaged, m_pDBEssence.num_drop_after_damaged); + AddExpireTimeDesc(); + // Sub class name + AddDescText(white, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_CLASSNAME), m_pDBSubType.name.ToString()); + // Weapon level + AddDescText(-1, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_LEVEL), m_pDBEssence.level); + + // Physical defence + if (m_Essence.defense - aPEEVals[PEEI_PHYDEF] + aRefines[REFINE_PHYDEF] != 0) + { + AddDescText(white, false, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_PHYDEFENCE)); + AddDescText(white, true, " +{0}", m_Essence.defense - aPEEVals[PEEI_PHYDEF] + aRefines[REFINE_PHYDEF]); + } + // Dodge + if (m_Essence.armor - aPEEVals[PEEI_DODGE] + aRefines[REFINE_DODGE] != 0) + { + AddDescText(white, false, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_DODGE)); + AddDescText(white, true, " +{0}", m_Essence.armor - aPEEVals[PEEI_DODGE] + aRefines[REFINE_DODGE]); + } + // HP + if (m_Essence.hp_enhance - aPEEVals[PEEI_HP] + aRefines[REFINE_HP] != 0) + { + AddDescText(white, false, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_ADDHP)); + AddDescText(white, true, " +{0}", m_Essence.hp_enhance - aPEEVals[PEEI_HP] + aRefines[REFINE_HP]); + } + // MP + if (m_Essence.mp_enhance - aPEEVals[PEEI_MP] != 0) + { + AddDescText(white, false, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_ADDMP)); + AddDescText(white, true, " +{0}", m_Essence.mp_enhance - aPEEVals[PEEI_MP]); + } + // Gold Resistance + if (m_Essence.resistance[0] - aPEEVals[PEEI_GOLDDEF] + aRefines[REFINE_GOLDDEF] != 0) + { + AddDescText(white, false, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_GOLDDEFENCE)); + AddDescText(white, true, " +{0}", m_Essence.resistance[0] - aPEEVals[PEEI_GOLDDEF] + aRefines[REFINE_GOLDDEF]); + } + // Wood Resistance + if (m_Essence.resistance[1] - aPEEVals[PEEI_WOODDEF] + aRefines[REFINE_WOODDEF] != 0) + { + AddDescText(white, false, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_WOODDEFENCE)); + AddDescText(white, true, " +{0}", m_Essence.resistance[1] - aPEEVals[PEEI_WOODDEF] + aRefines[REFINE_WOODDEF]); + } + // Water Resistance + if (m_Essence.resistance[2] - aPEEVals[PEEI_WATERDEF] + aRefines[REFINE_WATERDEF] != 0) + { + AddDescText(white, false, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_WATERDEFENCE)); + AddDescText(white, true, " +{0}", m_Essence.resistance[2] - aPEEVals[PEEI_WATERDEF] + aRefines[REFINE_WATERDEF]); + } + // Fire Resistance + if (m_Essence.resistance[3] - aPEEVals[PEEI_FIREDEF] + aRefines[REFINE_FIREDEF] != 0) + { + AddDescText(white, false, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_FIREDEFENCE)); + AddDescText(white, true, " +{0}", m_Essence.resistance[3] - aPEEVals[PEEI_FIREDEF] + aRefines[REFINE_FIREDEF]); + } + // Earth Resistance + if (m_Essence.resistance[4] - aPEEVals[PEEI_EARTHDEF] + aRefines[REFINE_EARTHDEF] != 0) + { + AddDescText(white, false, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_EARTHDEFENCE)); + AddDescText(white, true, " +{0}", m_Essence.resistance[4] - aPEEVals[PEEI_EARTHDEF] + aRefines[REFINE_EARTHDEF]); + } + // Endurance + int col = white; + if (CurEndurance == 0) + col = red; + else if ((dwPEE & PEE_ENDURANCE) != 0) + col = lblue; + AddDescText(col, false, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_ENDURANCE)); + AddDescText(col, true, " {0}/{1}", VisualizeEndurance(CurEndurance), VisualizeEndurance(MaxEndurance)); + + // Profession requirement + AddProfReqDesc((uint)ProfReq); + // Level requirment + if (LevelReq != 0) + { + col = pHost.GetMaxLevelSofar() >= LevelReq ? white : red; + AddDescText(col, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_LEVELREQ), LevelReq); + } + // Strength requirment + if (StrengthReq != 0) + { + col = pHost.GetExtendProps().bs.strength < StrengthReq ? red : ((dwPEE & PEE_STRENGTHREQ) != 0 ? lblue : white); + AddDescText(col, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_STRENGTHREQ), StrengthReq); + } + // Agility requirment + if (AgilityReq != 0) + { + col = pHost.GetExtendProps().bs.agility < AgilityReq ? red : ((dwPEE & PEE_AGILITYREQ) != 0 ? lblue : white); + AddDescText(col, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_AGILITYREQ), AgilityReq); + } + // Vitality requirment + if (VitalityReq != 0) + { + col = pHost.GetExtendProps().bs.vitality < VitalityReq ? red : ((dwPEE & PEE_VITALITYREQ) != 0 ? lblue : white); + AddDescText(col, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_VITALITYREQ), VitalityReq); + } + // Energy requirment + if (EnergyReq != 0) + { + col = pHost.GetExtendProps().bs.energy < EnergyReq ? red : ((dwPEE & PEE_ENERGYREQ) != 0 ? lblue : white); + AddDescText(col, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_ENERGYREQ), EnergyReq); + } + // Reputation requirement + AddReputationReqDesc(); + // Add addon properties + if (!string.IsNullOrEmpty(strAddon)) + m_strDesc += strAddon; + // Build tessera description + BuildTesseraDesc(); + if(m_pDBEssence.fixed_props == 0 && m_bIsInNPCPack) + AddDescText((int)DescriptipionMsg.ITEMDESC_COL2_BRIGHTBLUE, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_HASRANDOM_PROP)); + // Price + AddPriceDesc(white, bRepair); + AddSharpenerDesc(); + AddEngravedDesc(); + AddMakerDesc(); + AddSuiteDesc(); + AddExtDescText(); + return m_strDesc; + } + // // Does this equipment has random property ? + public bool HasRandomProp() + { + for (int i = 0; i < Props.Count; i++) + { + if (!Props[i].Embed && !Props[i].Engraved && Props[i].Type == 472) + return true; + } + return false; + } + public int GetRefineMaterialNum() + { + return m_pDBEssence.material_need; + } + public override uint GetRefineAddOn() + { + return (uint)m_pDBEssence.levelup_addon; + } + public override string GetDropModel() + { + return m_pDBEssence.FileMatter; + } + public override bool IsRare() + { + return base.IsRare() || m_pDBEssence.level >= 6; + } + public override int GetItemLevel() + { + return m_pDBEssence.level; + } + } +} \ No newline at end of file diff --git a/Assets/PerfectWorld/Scripts/Managers/EC_IvtrArmor.cs.meta b/Assets/PerfectWorld/Scripts/Managers/EC_IvtrArmor.cs.meta new file mode 100644 index 0000000000..3b702f712f --- /dev/null +++ b/Assets/PerfectWorld/Scripts/Managers/EC_IvtrArmor.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: c94b2c779cdb94d398d4aa10eb44cac6 \ No newline at end of file diff --git a/Assets/PerfectWorld/Scripts/Managers/EC_IvtrEquip.cs b/Assets/PerfectWorld/Scripts/Managers/EC_IvtrEquip.cs index 19ec8ee42d..12546f0fe8 100644 --- a/Assets/PerfectWorld/Scripts/Managers/EC_IvtrEquip.cs +++ b/Assets/PerfectWorld/Scripts/Managers/EC_IvtrEquip.cs @@ -754,6 +754,8 @@ namespace PerfectWorld.Scripts.Managers /// private 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 MadeFrom = dr.ReadByte(); int makerLen = dr.ReadByte(); if (makerLen > 0) @@ -764,8 +766,17 @@ namespace PerfectWorld.Scripts.Managers makerLen -= sizeof(ushort); byte[] makerData = dr.ReadData(makerLen); - string maker = System.Text.Encoding.Unicode.GetString(makerData, 0, makerData.Length); - + // Find null terminator (0x00 0x00 for Unicode) and decode only up to that point + int actualLength = makerLen; + for (int i = 0; i < makerLen - 1; i += 2) + { + if (makerData[i] == 0 && makerData[i + 1] == 0) + { + actualLength = i; + break; + } + } + string maker = System.Text.Encoding.Unicode.GetString(makerData, 0, actualLength).TrimEnd('\0'); if (string.IsNullOrEmpty(maker)) { return; @@ -779,14 +790,23 @@ namespace PerfectWorld.Scripts.Managers { //m_strMaker = ACString((ACHAR*)dr.Read_Data(iMakerLen), iMakerLen / sizeof (ACHAR)); byte[] makerData = dr.ReadData(makerLen); - Maker = System.Text.Encoding.Unicode.GetString(makerData, 0, makerData.Length); + // Find null terminator (0x00 0x00 for Unicode) and decode only up to that point + int actualLength = makerLen; + for (int i = 0; i < makerLen - 1; i += 2) + { + if (makerData[i] == 0 && makerData[i + 1] == 0) + { + actualLength = i; + break; + } + } + Maker = System.Text.Encoding.Unicode.GetString(makerData, 0, actualLength).TrimEnd('\0'); } } else { Maker = ""; } - BMLogger.Log("[thn]CECIvtrEquip::ReadMakerInfo, Maker: " + Maker); } /// @@ -2158,16 +2178,11 @@ namespace PerfectWorld.Scripts.Managers RefineLvl = 0; PropNum = 0; EmbedNum = 0; - BMLogger.Log("[thn]CECIvtrEquip::ParseProperties, Props.Count: " + Props.Count); if (Props.Count == 0) return; foreach (Property prop in Props) { - Debug.Log("[thn]CECIvtrEquip::ParseProperties, prop.Type: " + prop.Type); - Debug.Log("[thn]CECIvtrEquip::ParseProperties, prop.Embed: " + prop.Embed); - Debug.Log("[thn]CECIvtrEquip::ParseProperties, prop.Suite: " + prop.Suite); - Debug.Log("[thn]CECIvtrEquip::ParseProperties, prop.Engraved: " + prop.Engraved); int level = 0; if (prop.Embed) { @@ -4104,24 +4119,18 @@ namespace PerfectWorld.Scripts.Managers /// protected void BuildAddOnPropDesc(int[] aPEEVals, int[] aRefines) { - BMLogger.Log("[THN]EC_IvtrEquip: BuildAddOnPropDesc: Props.Count: " + Props.Count); if (Props.Count == 0) return; // Change color m_strDesc += GetColorString(DescriptipionMsg.ITEMDESC_COL_LIGHTBLUE); - BMLogger.Log("[THN]EC_IvtrEquip: BuildAddOnPropDesc: m_strDesc: " + m_strDesc); - Debug.Log("[THN]EC_IvtrEquip: BuildAddOnPropDesc: Props.Count: " + Props.Count); foreach (Property prop in Props) { // Properties added by Embedded stone will be printed by BuildTesseraDesc() later // Ignore suite properties also if (prop.Embed || prop.Suite || prop.Engraved) continue; - BMLogger.Log("[THN]EC_IvtrEquip: BuildAddOnPropDesc: prop.Type: " + prop.Type); - BMLogger.Log("[THN]EC_IvtrEquip: BuildAddOnPropDesc: prop.Params: " + prop.Params[0] + " " + prop.Params[1] + " " + prop.Params[2]); AddOneAddOnPropDesc(prop.Type, prop.Params, aPEEVals, aRefines, prop.Local); - BMLogger.Log("[THN]EC_IvtrEquip: BuildAddOnPropDesc: m_strDesc: " + m_strDesc); } } @@ -4131,7 +4140,6 @@ namespace PerfectWorld.Scripts.Managers public int GetSoulPowerAdded() { int added = 0; - int propertyCount = Props.Count; foreach (Property prop in Props) { @@ -4536,21 +4544,26 @@ namespace PerfectWorld.Scripts.Managers if (string.IsNullOrEmpty(Maker)) return; + BMLogger.Log("[THN]EC_IvtrEquip: AddMakerDesc: Maker: " + Maker); m_strDesc += "\\r"; // For signed marks (IMT_SIGN), Maker already contains color codes and formatted text. if (MadeFrom == (byte)ITEM_MAKE_TAG.IMT_SIGN) { + BMLogger.Log("[THN]EC_IvtrEquip: AddMakerDesc IF: Maker: " + Maker); m_strDesc += Maker; } else { + BMLogger.Log("[THN]EC_IvtrEquip: AddMakerDesc ELSE: Maker: " + Maker); // Normal "made by" line using item-desc string if available string fmt = GetItemDescString(DescriptipionMsg.ITEMDESC_MADEFROM); if (string.IsNullOrEmpty(fmt)) { fmt = "Made by {0}"; } + BMLogger.Log("[THN]EC_IvtrEquip: AddMakerDesc ELSE: fmt: " + fmt); AddDescText((int)DescriptipionMsg.ITEMDESC_COL_GREEN, false, fmt, Maker); + BMLogger.Log("[THN]EC_IvtrEquip: AddMakerDesc ELSE: m_strDesc: " + m_strDesc); } } diff --git a/Assets/PerfectWorld/Scripts/Managers/EC_IvtrItem.cs b/Assets/PerfectWorld/Scripts/Managers/EC_IvtrItem.cs index 129416724c..92590d7e46 100644 --- a/Assets/PerfectWorld/Scripts/Managers/EC_IvtrItem.cs +++ b/Assets/PerfectWorld/Scripts/Managers/EC_IvtrItem.cs @@ -818,10 +818,12 @@ namespace BrewMonster.Scripts.Managers { case DATA_TYPE.DT_WEAPON_ESSENCE: pItem = new EC_IvtrWeapon(tid, expire_date); - BMLogger.Log("[THN]EC_IvtrItem: CreateItem: Weapon Item: tid: " + tid + ", expire_date: " + expire_date + ", pItem: " + pItem); + break; + case DATA_TYPE.DT_ARMOR_ESSENCE: + pItem = new EC_IvtrArmor(tid, expire_date); break; default: - BMLogger.Log("[THN]EC_IvtrItem: CreateItem: Default Item: tid: " + tid + ", expire_date: " + expire_date + ", pItem: " + pItem); + BMLogger.Log("[THN]EC_IvtrItem: CreateItem: Default Item: tid: " + tid + ", expire_date: " + expire_date + ", pItem: " + pItem.GetName()); break; } pItem.SetCount(iCount); @@ -1472,8 +1474,6 @@ namespace BrewMonster.Scripts.Managers { // Optional: show internal id for debugging AddDescText(0, true, "ID: {0}", m_tid); - BMLogger.Log("[THN]EC_IvtrItem: AddIDDescText: m_tid: " + m_tid); - BMLogger.Log("[THN]EC_IvtrItem: AddIDDescText: m_strDesc: " + m_strDesc); } protected void AddBindDescText() diff --git a/Assets/PerfectWorld/Scripts/Managers/EC_IvtrType.cs b/Assets/PerfectWorld/Scripts/Managers/EC_IvtrType.cs index 965f28b649..d95633329b 100644 --- a/Assets/PerfectWorld/Scripts/Managers/EC_IvtrType.cs +++ b/Assets/PerfectWorld/Scripts/Managers/EC_IvtrType.cs @@ -107,11 +107,25 @@ namespace BrewMonster.Scripts.Managers public struct IVTR_ESSENCE_ARMOR { // TODO : implement data later - // int defense; - // int armor; - // int mp_enhance; - // int hp_enhance; - // int resistance[NUM_MAGICCLASS]; + public int defense; + public int armor; + public int mp_enhance; + public int hp_enhance; + public int[] resistance; + public IVTR_ESSENCE_ARMOR(byte[] data) + { + Debug.Log("IVTR_ESSENCE_ARMOR: data.Length: " + data.Length); + resistance = new int[InventoryConst.NUM_MAGICCLASS]; + CECDataReader dr = new (data, data.Length); + defense = dr.ReadInt(); + armor = dr.ReadInt(); + mp_enhance = dr.ReadInt(); + hp_enhance = dr.ReadInt(); + for(int i = 0; i < InventoryConst.NUM_MAGICCLASS; i++) + { + resistance[i] = dr.ReadInt(); + } + } }; public struct IVTR_ESSENCE_FASHION diff --git a/Assets/PerfectWorld/Scripts/Managers/EC_IvtrWeapon.cs b/Assets/PerfectWorld/Scripts/Managers/EC_IvtrWeapon.cs index 318e03c7e2..6613a03129 100644 --- a/Assets/PerfectWorld/Scripts/Managers/EC_IvtrWeapon.cs +++ b/Assets/PerfectWorld/Scripts/Managers/EC_IvtrWeapon.cs @@ -284,7 +284,7 @@ namespace PerfectWorld.Scripts.Managers AddDescText(namecol, false, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_NAME), GetName()); } if (RefineLvl > 0) - AddDescText(-1, true, "{0} {1}", pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_LEVEL), RefineLvl); + AddDescText(-1, true, "{0} +{1}", pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_LEVEL), RefineLvl); else m_strDesc += "\\r"; AddIDDescText(); @@ -293,7 +293,7 @@ namespace PerfectWorld.Scripts.Managers AddDestroyingDesc((int)m_pDBEssence.id_drop_after_damaged, m_pDBEssence.num_drop_after_damaged); AddExpireTimeDesc(); // Sub class name - AddDescText(white, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_CLASSNAME), m_Essence.weapon_type.ToString()); + AddDescText(white, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_CLASSNAME), m_pDBSubType.name.ToString()); // Weapon level AddDescText(-1, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_LEVEL), m_Essence.weapon_level); // Attack speed @@ -376,10 +376,10 @@ namespace PerfectWorld.Scripts.Managers m_strDesc += strAddon; // Build tessera description BuildTesseraDesc(); - // Price - AddPriceDesc(white, bRepair); if(m_pDBEssence.fixed_props == 0 && m_bIsInNPCPack) AddDescText((int)DescriptipionMsg.ITEMDESC_COL2_BRIGHTBLUE, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_HASRANDOM_PROP)); + // Price + AddPriceDesc(white, bRepair); AddSharpenerDesc(); AddEngravedDesc(); AddMakerDesc(); diff --git a/Assets/PerfectWorld/Scripts/Network/UnityGameSession.cs b/Assets/PerfectWorld/Scripts/Network/UnityGameSession.cs index 89d4492329..4025adeb25 100644 --- a/Assets/PerfectWorld/Scripts/Network/UnityGameSession.cs +++ b/Assets/PerfectWorld/Scripts/Network/UnityGameSession.cs @@ -368,7 +368,6 @@ namespace BrewMonster.Network public static void GetRoleBaseInfo(int iNumRole, List aRoleIDs) { - BMLogger.Log($"GetRoleBaseInfo: {iNumRole} {string.Join(", ", aRoleIDs)}"); Instance._gameSession.GetRoleBaseInfo(iNumRole, aRoleIDs); } diff --git a/Assets/PerfectWorld/Scripts/UI/Dialogs/AUIListBox.cs b/Assets/PerfectWorld/Scripts/UI/Dialogs/AUIListBox.cs index f17662e05c..ed88106549 100644 --- a/Assets/PerfectWorld/Scripts/UI/Dialogs/AUIListBox.cs +++ b/Assets/PerfectWorld/Scripts/UI/Dialogs/AUIListBox.cs @@ -55,6 +55,7 @@ namespace BrewMonster.UI return -1; m_Item[nIndex].strDataName[nSubIndex] = strName; m_Item[nIndex].dwData[nSubIndex] = dwItemData; + Debug.Log("[THN]AUIListBox: SetItemData: nIndex: " + nIndex + ", dwItemData: " + dwItemData + ", nSubIndex: " + nSubIndex + ", strName: " + strName); m_Item[nIndex].SetActOnClickBtn(m_OnClickBtn, nIndex); return nIndex; diff --git a/Assets/PerfectWorld/Scripts/UI/Dialogs/DlgNPC.cs b/Assets/PerfectWorld/Scripts/UI/Dialogs/DlgNPC.cs index e6b4c0231c..db0b980284 100644 --- a/Assets/PerfectWorld/Scripts/UI/Dialogs/DlgNPC.cs +++ b/Assets/PerfectWorld/Scripts/UI/Dialogs/DlgNPC.cs @@ -3117,7 +3117,6 @@ namespace BrewMonster.UI if (Enum.IsDefined(typeof(SERVICE_TYPE), idFunction)) { SERVICE_TYPE k = (SERVICE_TYPE)idFunction; - BMLogger.Log($" PopupCorrespondingServiceDialog: {k}"); } if (idFunction == (int)SERVICE_TYPE.NPC_SELL || idFunction == (int)SERVICE_TYPE.NPC_BUY) diff --git a/Assets/PerfectWorld/Scripts/UI/DlgAward/CDlgAward.cs b/Assets/PerfectWorld/Scripts/UI/DlgAward/CDlgAward.cs index de8eeb4b6f..7421e320c7 100644 --- a/Assets/PerfectWorld/Scripts/UI/DlgAward/CDlgAward.cs +++ b/Assets/PerfectWorld/Scripts/UI/DlgAward/CDlgAward.cs @@ -128,7 +128,6 @@ namespace BrewMonster.Scripts.UI { idItem = ad.m_CandItems[i - 1].m_AwardItems[j - 1].m_ulItemTemplId; pItem = EC_IvtrItem.CreateItem((int)idItem, 0, 1); - var pWeapon = pItem as EC_IvtrWeapon; nNum = ad.m_CandItems[i - 1].m_AwardItems[j - 1].m_ulItemNum; if (nNum > 1) { @@ -139,8 +138,8 @@ namespace BrewMonster.Scripts.UI else pImage.SetText(_AL("")); - pWeapon.GetDetailDataFromLocal(); - string strDesc = pWeapon.GetDesc(); + pItem.GetDetailDataFromLocal(); + string strDesc = pItem.GetDesc(); pImage.SetHint(strDesc); // TODO //Debug.Log("[THN]CDlgAward: pItem.GetDesc():" + pItem.GetDesc()); // af_GetFileTitle(pItem.GetIconFile(), strFile); // TODO diff --git a/Assets/PerfectWorld/Scripts/UI/Login/LoginScreenUI.cs b/Assets/PerfectWorld/Scripts/UI/Login/LoginScreenUI.cs index 6eb4e68544..d9c0f8cc13 100644 --- a/Assets/PerfectWorld/Scripts/UI/Login/LoginScreenUI.cs +++ b/Assets/PerfectWorld/Scripts/UI/Login/LoginScreenUI.cs @@ -102,14 +102,11 @@ namespace BrewMonster.UI /// private void OnGetRoleListComplete(List roleInfos) { - BMLogger.Log($"OnGetRoleListComplete {roleInfos.Count}"); - _roleInfos = roleInfos; } private void OnClickSelectCharacter(RoleInfo roleInfo) { - BMLogger.Log($"OnClickSelectCharacter {roleInfo.name}"); UnityGameSession.SelectRoleAsync(roleInfo, OnSelectRoleComplete); } From 007c23599d3aa4fdbb2373be15eb18105d6318ca Mon Sep 17 00:00:00 2001 From: Tungdv Date: Wed, 14 Jan 2026 16:48:00 +0700 Subject: [PATCH 5/7] fix: update logic anim fly HP. --- Assets/PerfectWorld/Scripts/Move/CECPlayer.cs | 30 +++++++++---------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/Assets/PerfectWorld/Scripts/Move/CECPlayer.cs b/Assets/PerfectWorld/Scripts/Move/CECPlayer.cs index 7de9bc56fd..b56a5d404e 100644 --- a/Assets/PerfectWorld/Scripts/Move/CECPlayer.cs +++ b/Assets/PerfectWorld/Scripts/Move/CECPlayer.cs @@ -68,7 +68,7 @@ namespace BrewMonster private QueueActionEvent queueActionEvent; protected static PLAYER_LEVELEXP_CONFIG _player_levelup_exp; private CECPlayerActionController m_pActionController; - private enumWingType m_wingType; + private enumWingType m_wingType = enumWingType.WINGTYPE_FLYSWORD; protected int m_idCurSkillTarget; protected CECSkill m_pCurSkill; protected int m_idFaction; // ID of player's faction @@ -961,13 +961,13 @@ namespace BrewMonster else iAction = (int)PLAYER_ACTION_TYPE.ACT_WALK; } - //else if (iMoveEnv == MOVEENV_AIR) - //{ - // //if (/*UsingWing()*/ m_wingType == WINGTYPE_WING) - // // iAction = ACT_FLY; - // //else - // // iAction = ACT_FLY_SWORD; - //} + else if (iMoveEnv == (int)MoveEnvironment.MOVEENV_AIR) + { + if (/*UsingWing()*/ m_wingType == enumWingType.WINGTYPE_WING) + iAction = (int)PLAYER_ACTION_TYPE.ACT_FLY; + else + iAction = (int)PLAYER_ACTION_TYPE.ACT_FLY_SWORD; + } else if (iMoveEnv == (int)MoveEnvironment.MOVEENV_WATER) { //if (CanCombineWithMoveForSkill()) @@ -990,13 +990,13 @@ namespace BrewMonster else iAction = (int)PLAYER_ACTION_TYPE.ACT_STAND; } - //else if (iMoveEnv == MOVEENV_AIR) - //{ - // if (/*UsingWing()*/ m_wingType == WINGTYPE_WING) - // iAction = ACT_HANGINAIR; - // else - // iAction = ACT_HANGINAIR_SWORD; - //} + else if (iMoveEnv == (int)MoveEnvironment.MOVEENV_AIR) + { + if (/*UsingWing()*/ m_wingType == enumWingType.WINGTYPE_WING) + iAction = (int)PLAYER_ACTION_TYPE.ACT_HANGINAIR; + else + iAction = (int)PLAYER_ACTION_TYPE.ACT_HANGINAIR_SWORD; + } else if (iMoveEnv == (int)MoveEnvironment.MOVEENV_WATER) iAction = (int)PLAYER_ACTION_TYPE.ACT_HANGINWATER; } From b26e76b92f46648a717ecf99742711e89ee9832d Mon Sep 17 00:00:00 2001 From: Chomper9981 Date: Wed, 14 Jan 2026 17:30:37 +0700 Subject: [PATCH 6/7] fix cant choose npc in first section --- Assets/PerfectWorld/Scripts/Managers/EC_HostInputFilter.cs | 5 ++++- Assets/PerfectWorld/Scripts/UI/Dialogs/AUIListBox.cs | 3 +-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/Assets/PerfectWorld/Scripts/Managers/EC_HostInputFilter.cs b/Assets/PerfectWorld/Scripts/Managers/EC_HostInputFilter.cs index 5294ce8632..382034bd47 100644 --- a/Assets/PerfectWorld/Scripts/Managers/EC_HostInputFilter.cs +++ b/Assets/PerfectWorld/Scripts/Managers/EC_HostInputFilter.cs @@ -6,6 +6,7 @@ using PerfectWorld.Scripts; using CSNetwork; using UnityEngine; using static BrewMonster.Scripts.CECHPWork; +using System.Linq; namespace BrewMonster { @@ -149,9 +150,11 @@ namespace BrewMonster // For now, we'll proceed with raycast if (Physics.RaycastNonAlloc(ray, hits) > 0) { + //sort hits by distance. skip null hits. + hits = hits.OrderBy(h => h.distance).Where(h => h.collider != null).ToArray(); // Check if hit terrain, building, or forest (no CECObject component) if (!hits[0].collider.gameObject.TryGetComponent(out CECObject clickedObject)) - { + { //ENABLE LATER - CURRENT WORKING FINE // Hit terrain / building / forest / Hit terrain // if (m_pWorkMan.IsSitting()) diff --git a/Assets/PerfectWorld/Scripts/UI/Dialogs/AUIListBox.cs b/Assets/PerfectWorld/Scripts/UI/Dialogs/AUIListBox.cs index ed88106549..8e3068f447 100644 --- a/Assets/PerfectWorld/Scripts/UI/Dialogs/AUIListBox.cs +++ b/Assets/PerfectWorld/Scripts/UI/Dialogs/AUIListBox.cs @@ -55,8 +55,7 @@ namespace BrewMonster.UI return -1; m_Item[nIndex].strDataName[nSubIndex] = strName; m_Item[nIndex].dwData[nSubIndex] = dwItemData; - Debug.Log("[THN]AUIListBox: SetItemData: nIndex: " + nIndex + ", dwItemData: " + dwItemData + ", nSubIndex: " + nSubIndex + ", strName: " + strName); - + m_Item[nIndex].SetActOnClickBtn(m_OnClickBtn, nIndex); return nIndex; } From 9167c63229cba0d9553d196e6318cc52f626a890 Mon Sep 17 00:00:00 2001 From: Chomper9981 Date: Wed, 14 Jan 2026 17:34:27 +0700 Subject: [PATCH 7/7] remove Lingq code --- .../Scripts/Managers/EC_HostInputFilter.cs | 26 +++++++++++++++---- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/Assets/PerfectWorld/Scripts/Managers/EC_HostInputFilter.cs b/Assets/PerfectWorld/Scripts/Managers/EC_HostInputFilter.cs index 382034bd47..e67b805838 100644 --- a/Assets/PerfectWorld/Scripts/Managers/EC_HostInputFilter.cs +++ b/Assets/PerfectWorld/Scripts/Managers/EC_HostInputFilter.cs @@ -6,7 +6,6 @@ using PerfectWorld.Scripts; using CSNetwork; using UnityEngine; using static BrewMonster.Scripts.CECHPWork; -using System.Linq; namespace BrewMonster { @@ -149,11 +148,28 @@ namespace BrewMonster // Note: This would require GetMouseOnPateTextNPC implementation // For now, we'll proceed with raycast if (Physics.RaycastNonAlloc(ray, hits) > 0) - { - //sort hits by distance. skip null hits. - hits = hits.OrderBy(h => h.distance).Where(h => h.collider != null).ToArray(); + { + //Becauce of using RaycastNonAlloc, we need to sort hits by distance. + GameObject closestObject = null; + float closestDistance = float.MaxValue; + foreach (var hit in hits) + { + if(hit.collider == null) + { + continue; + } + if(hit.distance < closestDistance) + { + closestDistance = hit.distance; + closestObject = hit.collider.gameObject; + } + } + if(closestObject == null) + { + return; + } // Check if hit terrain, building, or forest (no CECObject component) - if (!hits[0].collider.gameObject.TryGetComponent(out CECObject clickedObject)) + if (!closestObject.TryGetComponent(out CECObject clickedObject)) { //ENABLE LATER - CURRENT WORKING FINE // Hit terrain / building / forest / Hit terrain