This commit is contained in:
Le Duc Anh
2026-01-22 15:00:15 +07:00
114 changed files with 17361 additions and 2954 deletions
@@ -15,7 +15,7 @@ MonoBehaviour:
m_DefaultGroup: 712e3991f28e549e7a56ee582a977810
m_currentHash:
serializedVersion: 2
Hash: 00000000000000000000000000000000
Hash: f31c7227b70701eab297439e808bd57d
m_OptimizeCatalogSize: 0
m_BuildRemoteCatalog: 0
m_CatalogRequestsTimeout: 0
File diff suppressed because it is too large Load Diff
@@ -29,3 +29,7 @@ MonoBehaviour:
prefab: {fileID: 6032603119232429246, guid: 8350aa55906d08448bb47e10a473ca61, type: 3}
- id: Win_Produce
prefab: {fileID: 5750242998044155948, guid: ecf0d8daf08db6f4a8d94a4bb07847ec, type: 3}
- id: Win_Inventory
prefab: {fileID: 5910006447059157136, guid: 22d3972b131ebdb4288f9cbdf996d691, type: 3}
- id: Win_Enchase
prefab: {fileID: 5636724581774400035, guid: de6ac6f2630425044a55299c703670f1, type: 3}
File diff suppressed because it is too large Load Diff
@@ -458,10 +458,40 @@ namespace BrewMonster
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_DECORATION_ESSENCE:
ret = generate_item_temp.generate_decoration(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_PROJECTILE_ESSENCE:
ret = generate_item_temp.generate_projectile(id,ID_SPACE.ID_SPACE_ESSENCE,
out item,out size,SPECIFIC.SPECIFIC_RAND);
break;
case DATA_TYPE.DT_FASHION_ESSENCE:
ret = generate_item_temp.generate_fashion_item(id, ID_SPACE.ID_SPACE_ESSENCE, out item, out size, SPECIFIC.SPECIFIC_RAND, tag);
break;
case DATA_TYPE.DT_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);
break;
case DATA_TYPE.DT_MEDICINE_ESSENCE:
ret = generate_item_temp.generate_medicine(id, ID_SPACE.ID_SPACE_ESSENCE, out item, out size, SPECIFIC.SPECIFIC_RAND);
break;
case DATA_TYPE.DT_MATERIAL_ESSENCE:
ret = generate_item_temp.generate_material(id, ID_SPACE.ID_SPACE_ESSENCE, out item, out size, SPECIFIC.SPECIFIC_RAND);
break;
case DATA_TYPE.DT_SKILLTOME_ESSENCE:
ret = generate_item_temp.generate_skilltome(id, ID_SPACE.ID_SPACE_ESSENCE, out item, out size, SPECIFIC.SPECIFIC_RAND);
break;
case DATA_TYPE.DT_PET_EGG_ESSENCE:
ret = generate_item_temp.generate_pet_egg(id, ID_SPACE.ID_SPACE_ESSENCE, out item, out size, SPECIFIC.SPECIFIC_RAND);
break;
case DATA_TYPE.DT_PET_FOOD_ESSENCE:
ret = generate_item_temp.generate_pet_food(id, ID_SPACE.ID_SPACE_ESSENCE, out item, out size, SPECIFIC.SPECIFIC_RAND);
break;
case DATA_TYPE.DT_TOWNSCROLL_ESSENCE:
ret = generate_item_temp.generate_townscroll(id, ID_SPACE.ID_SPACE_ESSENCE, out item, out size, SPECIFIC.SPECIFIC_RAND);
break;
default:
ret = -1;
break;
@@ -55,12 +55,15 @@ namespace BrewMonster
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
public ushort[] name; // Weapon sub-type name
public string Name => ByteToStringUtils.UshortArrayToUnicodeString(name);
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)]
public byte[] file_hitgfx; // Hit effect file path
public string FileHitGfx => ByteToStringUtils.ByteArrayToCP936String(file_hitgfx);
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)]
public byte[] file_hitsfx; // Hit sound effect file path
public byte[] file_hitsfx; // Hit sound effect file pathpublic string FileHitSfx => ByteToStringUtils.ByteArrayToCP936String(file_hitsfx);
public string FileHitSfx => ByteToStringUtils.ByteArrayToCP936String(file_hitsfx);
public float probability_fastest; // Attack frequency probability: Fastest -0.1
public float probability_fast; // Attack frequency probability: Fast -0.05
public float probability_normal; // Attack frequency probability: Normal 0
@@ -250,14 +253,20 @@ namespace BrewMonster
+ ByteToStringUtils.ByteArrayToCP936String(file_model_left) + "\n";
}
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct MagicDefence
{
public int low; // Minimum magic defense
public int high; // Maximum magic defense
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct ARMOR_MAJOR_TYPE
{
public uint id; // Armor major type ID
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
public ushort[] name; // Armor major type name
public ushort[] name; // Armor major type name public string Name => ByteToStringUtils.UshortArrayToUnicodeString(name);
public string Name => ByteToStringUtils.UshortArrayToUnicodeString(name);
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
@@ -267,6 +276,7 @@ namespace BrewMonster
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
public ushort[] name; // Armor sub-type name
public string Name => ByteToStringUtils.UshortArrayToUnicodeString(name);
public uint equip_mask; // Equipment slot mask
}
@@ -321,12 +331,7 @@ namespace BrewMonster
public int defence_low; // Minimum physical defense
public int defence_high; // Maximum physical defense
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct MagicDefence
{
public int low; // Minimum magic defense
public int high; // Maximum magic defense
}
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 5)]
public MagicDefence[] magic_defences; // Magic defenses for 5 elements
@@ -433,6 +438,8 @@ namespace BrewMonster
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
public ushort[] name; // Decoration sub-type name
public string Name => ByteToStringUtils.UshortArrayToUnicodeString(name);
public uint equip_mask; // Equipment slot mask
}
@@ -447,16 +454,22 @@ namespace BrewMonster
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
public ushort[] name; // Decoration name, max 15 characters
public string Name => ByteToStringUtils.UshortArrayToUnicodeString(name);
// Display information
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)]
public byte[] file_model; // Model file path
public string FileModel => ByteToStringUtils.ByteArrayToCP936String(file_model);
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)]
public byte[] file_matter; // Matter model file path
public string FileMatter => ByteToStringUtils.ByteArrayToCP936String(file_matter);
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)]
public byte[] file_icon; // Icon file path
public string FileIcon => ByteToStringUtils.ByteArrayToCP936String(file_icon);
public int level; // Decoration level
// Equipment requirements
@@ -482,13 +495,6 @@ namespace BrewMonster
public int defence_low; // Minimum physical defense
public int defence_high; // Maximum physical defense
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct MagicDefence
{
public int low; // Minimum magic defense
public int high; // Maximum magic defense
}
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 5)]
public MagicDefence[] magic_defences; // Magic defenses for 5 elements
@@ -737,6 +743,7 @@ namespace BrewMonster
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
public ushort[] name; // Fashion sub-type name
public string Name => ByteToStringUtils.UshortArrayToCP936String(name);
public uint equip_fashion_mask; // Fashion equipment slot mask
}
@@ -751,18 +758,18 @@ namespace BrewMonster
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
public ushort[] name; // Fashion name, max 15 characters
public string Name => ByteToStringUtils.UshortArrayToCP936String(name);
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
public byte[] realname; // Real fashion name
public string RealName => ByteToStringUtils.ByteArrayToUnicodeString(realname);
// Display information
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)]
public byte[] file_matter; // Matter model file path
public string FileMatter => ByteToStringUtils.ByteArrayToCP936String(file_matter);
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)]
public byte[] file_icon; // Icon file path
@@ -793,7 +800,6 @@ namespace BrewMonster
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
public byte[] wear_action; // Wear action
public string WearAction => ByteToStringUtils.ByteArrayToUnicodeString(wear_action);
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)]
@@ -827,6 +833,7 @@ namespace BrewMonster
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
public ushort[] name; // Medicine major type name
public string Name => ByteToStringUtils.UshortArrayToUnicodeString(name);
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
@@ -847,13 +854,18 @@ namespace BrewMonster
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
public ushort[] name; // Medicine name, max 15 characters
public string Name => ByteToStringUtils.UshortArrayToCP936String(name);
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)]
public byte[] file_matter; // Matter model file path
public string FileMatter => ByteToStringUtils.ByteArrayToCP936String(file_matter);
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)]
public byte[] file_icon; // Icon file path
public string FileIcon => ByteToStringUtils.ByteArrayToCP936String(file_icon);
public int require_level; // Required level
public int cool_time; // Cooldown time (seconds)
@@ -933,12 +945,18 @@ namespace BrewMonster
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
public ushort[] name; // Name, max 15 characters
public string Name => ByteToStringUtils.UshortArrayToCP936String(name);
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)]
public byte[] file_matter; // Matter model file path
public string FileMatter => ByteToStringUtils.ByteArrayToCP936String(file_matter);
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)]
public byte[] file_icon; // Icon file path
public string FileIcon => ByteToStringUtils.ByteArrayToCP936String(file_icon);
public int total_hp; // Total HP recovery
public float trigger_amount; // Trigger HP threshold
public int cool_time; // Cooldown time (seconds)
@@ -959,13 +977,18 @@ namespace BrewMonster
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
public ushort[] name; // Name, max 15 characters
public string Name => ByteToStringUtils.UshortArrayToCP936String(name);
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)]
public byte[] file_matter; // Matter model file path
public byte[] file_matter; // Matter model file path
public string FileMatter => ByteToStringUtils.ByteArrayToCP936String(file_matter);
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)]
public byte[] file_icon; // Icon file path
public string FileIcon => ByteToStringUtils.ByteArrayToCP936String(file_icon);
public int total_mp; // Total MP recovery
public float trigger_amount; // Trigger MP threshold
public int cool_time; // Cooldown time (seconds)
@@ -1038,6 +1061,7 @@ namespace BrewMonster
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
public ushort[] name; // Material major type name
public string Name => ByteToStringUtils.UshortArrayToUnicodeString(name);
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
@@ -1047,6 +1071,7 @@ namespace BrewMonster
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
public ushort[] name; // Material sub-type name
public string Name => ByteToStringUtils.UshortArrayToUnicodeString(name);
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
@@ -1058,13 +1083,15 @@ namespace BrewMonster
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
public ushort[] name; // Material name, max 15 characters
public string Name => ByteToStringUtils.UshortArrayToCP936String(name);
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)]
public byte[] file_matter; // Matter model file path
public string FileMatter => ByteToStringUtils.ByteArrayToCP936String(file_matter);
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)]
public byte[] file_icon; // Icon file path
public string FileIcon => ByteToStringUtils.ByteArrayToCP936String(file_icon);
public int price; // Base price
public int shop_price; // Shop price
@@ -1304,10 +1331,10 @@ namespace BrewMonster
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)]
public byte[] file_matter; // Matter model file path
public string FileMatter => ByteToStringUtils.ByteArrayToCP936String(file_matter);
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)]
public byte[] file_icon; // Icon file path
public string FileIcon => ByteToStringUtils.ByteArrayToCP936String(file_icon);
public int price; // Base price
public int shop_price; // Shop price
@@ -1576,10 +1603,11 @@ namespace BrewMonster
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)]
public byte[] file_matter; // Material file path
public string FileMatter => ByteToStringUtils.ByteArrayToCP936String(file_matter);
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)]
public byte[] file_icon; // Icon file path
public string FileIcon => ByteToStringUtils.ByteArrayToCP936String(file_icon);
public float use_time; // Use time (seconds)
public int price; // Price
@@ -1600,9 +1628,11 @@ namespace BrewMonster
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)]
public byte[] file_matter; // Material file path
public string FileMatter => ByteToStringUtils.ByteArrayToCP936String(file_matter);
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)]
public byte[] file_icon; // Icon file path
public string FileIcon => ByteToStringUtils.ByteArrayToCP936String(file_icon);
public int price; // Price
public int shop_price; // Shop price
@@ -1717,6 +1747,7 @@ namespace BrewMonster
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)]
public byte[] file_icon; // Icon file path
public string FileIcon { get { return ByteToStringUtils.ByteArrayToCP936String(file_icon); } }
public int pile_num_max; // Max stack count
public uint has_guid; // Whether item has GUID
@@ -1733,9 +1764,11 @@ namespace BrewMonster
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)]
public byte[] file_matter; // Material file path
public string FileMatter { get { return ByteToStringUtils.ByteArrayToCP936String(file_matter); } }
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)]
public byte[] file_icon; // Icon file path
public string FileIcon { get { return ByteToStringUtils.ByteArrayToCP936String(file_icon); } }
public int price; // Price
public int shop_price; // Shop price
@@ -1825,6 +1858,7 @@ namespace BrewMonster
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
public ushort[] name; // name, max 15 chars
public string Name => ByteToStringUtils.UshortArrayToUnicodeString(name);
}
public struct PROJECTILE_ESSENCE
@@ -1837,12 +1871,14 @@ namespace BrewMonster
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)]
public byte[] file_model; // model file path
public string FileModel { get { return ByteToStringUtils.ByteArrayToCP936String(file_model); } }
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)]
public byte[] file_matter; // matter file path
public string FileMatter { get { return ByteToStringUtils.ByteArrayToCP936String(file_matter); } }
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)]
public byte[] file_icon; // icon file path
public string FileIcon { get { return ByteToStringUtils.ByteArrayToCP936String(file_icon); } }
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)]
public byte[] file_firegfx; // fire effect file
@@ -2086,6 +2122,7 @@ namespace BrewMonster
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)]
public byte[] file_icon; // icon file path
public string FileIcon { get { return ByteToStringUtils.ByteArrayToCP936String(file_icon); } }
public int id_pet; // pet ID
@@ -2124,9 +2161,11 @@ namespace BrewMonster
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)]
public byte[] file_matter; // matter file path
public string FileMatter { get { return ByteToStringUtils.ByteArrayToCP936String(file_matter); } }
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)]
public byte[] file_icon; // icon file path
public string FileIcon { get { return ByteToStringUtils.ByteArrayToCP936String(file_icon); } }
public int level; // level
@@ -2965,31 +3004,29 @@ namespace BrewMonster
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
public ushort[] name; // name, max 15 characters
public string Name => ByteToStringUtils.UshortArrayToCP936String(name);
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)]
public byte[] file_model1; // state 1 model file
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)]
public byte[] file_model2; // state 2 model file
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)]
public byte[] file_model3; // state 3 model file
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)]
public byte[] file_model4; // state 4 model file
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)]
public byte[] file_matter; // matter model path
public string FileMatter => ByteToStringUtils.ByteArrayToCP936String(file_matter);
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)]
public byte[] file_icon1; // state 1 icon path
public string FileIcon1 => ByteToStringUtils.ByteArrayToCP936String(file_icon1);
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)]
public byte[] file_icon2; // state 2 icon path
public string FileIcon2 => ByteToStringUtils.ByteArrayToCP936String(file_icon2);
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)]
public byte[] file_icon3; // state 3 icon path
public string FileIcon3 => ByteToStringUtils.ByteArrayToCP936String(file_icon3);
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)]
public byte[] file_icon4; // state 4 icon path
@@ -80,4 +80,14 @@ namespace BrewMonster.Scripts
SIZE_FASHIONSCSET = 240,
};
// Pet food type
enum PetFoodType
{
PET_FOOD_GRASS = 0,
PET_FOOD_MEAT,
PET_FOOD_VEGETABLE,
PET_FOOD_FRUIT,
PET_FOOD_WATER,
MAX_PET_FOOD,
};
}
@@ -84,7 +84,6 @@ namespace BrewMonster.Network
}
public static Dictionary<int, int> GetSuiteEquipTab()
{
Debug.Log("[EC_Game] GetSuiteEquipTab: " + m_SuiteEquipTab.Count);
return m_SuiteEquipTab;
}
public static bool TryGetItemMsg(int templateId, out int messageId, out int displayMode)
@@ -64,7 +64,9 @@ using BrewMonster.Scripts;
namespace PerfectWorld.Scripts.Managers
{
/// <summary>
/// Armor item class (Mu + Ao + Quan + Giay) / Armor item class (Helmet + Armor + Pants + Boots)
/// </summary>
public class EC_IvtrArmor : EC_IvtrEquip
{
//Attributes
@@ -75,6 +77,11 @@ namespace PerfectWorld.Scripts.Managers
protected ARMOR_SUB_TYPE m_pDBSubType;
protected ARMOR_ESSENCE m_pDBEssence;
/// <summary>
/// Constructor for armor item (Mu + Ao + Quan + Giay) / Constructor for armor item (Helmet + Armor + Pants + Boots)
/// </summary>
/// <param name="tid">Template id</param>
/// <param name="expire_date">Expire date</param>
public EC_IvtrArmor(int tid, int expire_date) : base(tid, expire_date)
{
m_iCID = (int)InventoryClassId.ICID_ARMOR;
@@ -93,6 +100,10 @@ namespace PerfectWorld.Scripts.Managers
RepairFee = m_pDBEssence.repairfee;
ReputationReq = m_pDBEssence.require_reputation;
}
/// <summary>
/// Copy constructor for armor item (Mu + Ao + Quan + Giay) / Copy constructor for armor item (Helmet + Armor + Pants + Boots)
/// </summary>
/// <param name="other">Other armor item to copy from</param>
public EC_IvtrArmor(EC_IvtrArmor other) : base(other)
{
m_pDBEssence = other.m_pDBEssence;
@@ -386,10 +397,9 @@ 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_pDBSubType.name.ToString());
AddDescText(white, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_CLASSNAME), m_pDBSubType.Name);
// 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)
{
@@ -4,6 +4,11 @@ namespace PerfectWorld.Scripts.Managers
{
public class EC_IvtrArmorrune : EC_IvtrItem
{
/// <summary>
/// Not create logic yet (add summary later)
/// </summary>
/// <param name="tid">Template id</param>
/// <param name="expire_date">Expire date</param>
public EC_IvtrArmorrune(int tid, int expire_date) : base(tid, expire_date)
{
}
@@ -1,14 +1,170 @@
using System;
using System.Collections.Generic;
using System.Reflection;
using System.IO;
using BrewMonster;
using ModelRenderer.Scripts.Common;
using ModelRenderer.Scripts.GameData;
using UnityEngine;
using PerfectWorld.Scripts.Managers;
using BrewMonster.Network;
using BrewMonster.Scripts.Managers;
using BrewMonster.Scripts;
using CSNetwork.GPDataType;
using System.Runtime.InteropServices;
namespace PerfectWorld.Scripts.Managers
{
/// <summary>
/// Arrow item class (cac loai mui ten)
/// </summary>
public class EC_IvtrArrow : EC_IvtrEquip
{
protected IVTR_ESSENCE_ARROW m_Essence; // Arrow essence data
// Data in database
protected PROJECTILE_TYPE m_pDBType;
protected PROJECTILE_ESSENCE m_pDBEssence;
/// <summary>
/// Arrow item class (cac loai mui ten)
/// </summary>
/// <param name="tid">Template id</param>
/// <param name="expire_date">Expire date</param>
public EC_IvtrArrow(int tid, int expire_date) : base(tid, expire_date)
{
m_iCID = (int)InventoryClassId.ICID_ARROW;
m_Essence = new IVTR_ESSENCE_ARROW();
// Get database data
elementdataman pDB = ElementDataManProvider.GetElementDataMan();
DATA_TYPE DataType = DATA_TYPE.DT_INVALID;
m_pDBEssence = (PROJECTILE_ESSENCE)pDB.get_data_ptr((uint)tid, ID_SPACE.ID_SPACE_ESSENCE, ref DataType);
m_pDBType = (PROJECTILE_TYPE)pDB.get_data_ptr((uint)m_pDBEssence.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_iProcType = (int)m_pDBEssence.proc_type;
m_i64EquipMask = EC_IvtrType.EQUIP_MASK64_PROJECTILE;
}
public EC_IvtrArrow(EC_IvtrArrow other) : base(other)
{
m_pDBType = other.m_pDBType;
m_pDBEssence = other.m_pDBEssence;
m_Essence = other.m_Essence;
}
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(5 * sizeof (int), CECDataReader.SEEK_CUR);
int iEssenceSize = dr.ReadInt();
//ASSERT(iEssenceSize == sizeof (IVTR_ESSENCE_ARROW));
m_Essence = new IVTR_ESSENCE_ARROW(dr.ReadData(iEssenceSize));
}
catch (Exception e)
{
Debug.LogError("CECIvtrArrow::SetItemInfo, data read error (" + e.GetType() + e.StackTrace + ")");
return false;
}
return true;
}
// Get item icon file name
public override string GetIconFile()
{
return m_pDBEssence.FileIcon;
}
// Get item name
public override string GetName()
{
// Try Unicode first (for Vietnamese/wide char names), then fallback to CP936
if (m_pDBEssence.name != null && m_pDBEssence.name.Length > 0)
{
string s = ByteToStringUtils.UshortArrayToUnicodeString(m_pDBEssence.name);
if (!string.IsNullOrEmpty(s) && !string.IsNullOrWhiteSpace(s))
return s;
// Fallback to legacy CP936 if Unicode was empty
s = ByteToStringUtils.UshortArrayToCP936String(m_pDBEssence.name);
if (!string.IsNullOrEmpty(s))
return s;
}
return base.GetName(); // Fallback to base class method
}
// Get item description text
protected override string GetNormalDesc(bool bRepair)
{
if (m_bNeedUpdate)
return "";
// Build addon and refine properties and save it
m_strDesc = "";
BuildAddOnPropDesc(null, null);
string strAddon = m_strDesc;
m_strDesc = "";
// Try to build item description
CECStringTab pDescTab = EC_Game.GetItemDesc();
int white = (int)DescriptipionMsg.ITEMDESC_COL_WHITE;
int namecol = DecideNameCol();
if (m_iCount > 1)
AddDescText(namecol, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_NAMENUMBER), GetName(), m_iCount);
else
AddDescText(namecol, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_NAME), GetName());
AddIDDescText();
AddExpireTimeDesc();
// Weapon requirement
AddDescText(white, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_WEAPONREQ), m_Essence.iWeaponReqLow,
m_Essence.iWeaponReqHigh, m_pDBType.Name);
// Damage enhance
if (m_pDBEssence.damage_enhance != 0)
{
AddDescText(-1, false, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_ADDPHYDAMAGE));
AddDescText(-1, true, " %+d", m_pDBEssence.damage_enhance);
}
// Add addon properties
if (strAddon.Length > 0)
m_strDesc += strAddon;
// Price
AddPriceDesc(white, bRepair);
// Suite description
AddSuiteDesc();
// Extend description
AddExtDescText();
return m_strDesc;
}
// Get drop model for shown
public override string GetDropModel()
{
return m_pDBEssence.FileMatter;
}
}
}
@@ -1,15 +1,174 @@
///////////////////////////////////////////////////////////////////////////
//
// Define and Macro
//
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
//
// Reference to External variables and functions
//
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
//
// Local Types and Variables and Global variables
//
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
//
// Local functions
//
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
//
// Implement CECIvtrDecoration
//
///////////////////////////////////////////////////////////////////////////
using BrewMonster;
using ModelRenderer.Scripts.GameData;
using System.Collections.Generic;
using BrewMonster.Network;
using BrewMonster.Scripts.Managers;
using BrewMonster.Scripts;
using System.Runtime.InteropServices;
using System;
using CSNetwork.GPDataType;
namespace PerfectWorld.Scripts.Managers
{
public class EC_IvtrAutoHp : EC_IvtrItem
/// <summary>
/// Auto HP item class (tu dong hoi mau). This is a part of CEC_IvtrEquipMatter(C++)
/// </summary>
public class EC_IvtrAutoHp : EC_IvtrEquip
{
public IVTR_ESSENCE_AUTOHP m_Essence;
// Data in database
public AUTOHP_ESSENCE m_pDBEssence;
/// <summary>
/// Constructor for auto HP item (tu dong hoi mau) / Constructor for auto HP item (automatic HP recovery)
/// </summary>
/// <param name="tid">Template id</param>
/// <param name="expire_date">Expire date</param>
public EC_IvtrAutoHp(int tid, int expire_date) : base(tid, expire_date)
{
m_iCID = (int)InventoryClassId.ICID_AUTOHP;
// Get database data
elementdataman pDB = ElementDataManProvider.GetElementDataMan();
DATA_TYPE DataType = DATA_TYPE.DT_INVALID;
m_pDBEssence = (AUTOHP_ESSENCE)pDB.get_data_ptr((uint)tid, ID_SPACE.ID_SPACE_ESSENCE, ref DataType);
m_iPileLimit = m_pDBEssence.pile_num_max;
m_iPrice = m_pDBEssence.price;
m_iShopPrice = m_pDBEssence.shop_price;
m_iProcType = (int)m_pDBEssence.proc_type;
m_i64EquipMask = (long)EC_IvtrType.EQUIP_MASK64_AUTOHP;
}
/// <summary>
/// Copy constructor for auto HP item (tu dong hoi mau) / Copy constructor for auto HP item (automatic HP recovery)
/// </summary>
/// <param name="other">Other auto HP item to copy from</param>
public EC_IvtrAutoHp(EC_IvtrAutoHp other) : base(other)
{
m_pDBEssence = other.m_pDBEssence;
m_Essence = other.m_Essence;
}
public override bool SetItemInfo(byte[] pInfoData, int iDataLen)
{
base.SetItemInfo(pInfoData, iDataLen);
if (pInfoData == null || iDataLen == 0)
return true;
try
{
CECDataReader dr = new CECDataReader(pInfoData, iDataLen);
m_Essence = new IVTR_ESSENCE_AUTOHP(dr.ReadData(Marshal.SizeOf<IVTR_ESSENCE_AUTOHP>()));
}
catch (Exception e)
{
BMLogger.LogError("CECIvtrAutoHP::SetItemInfo, data read error (" + e.GetType() + ")");
return false;
}
return true;
}
// 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 item description text
protected override string GetNormalDesc(bool bRepair)
{
if (m_bNeedUpdate)
return null;
m_strDesc = string.Empty;
// Try to build item description
CECStringTab pDescTab = EC_Game.GetItemDesc();
CECHostPlayer pHost = EC_Game.GetGameRun().GetHostPlayer();
int white = (int)DescriptipionMsg.ITEMDESC_COL_WHITE;
int red = (int)DescriptipionMsg.ITEMDESC_COL_RED;
if (m_iCount > 1)
AddDescText(white, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_NAMENUMBER), GetName(), m_iCount);
else
AddDescText(white, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_NAME), GetName());
AddIDDescText();
AddBindDescText();
AddExpireTimeDesc();
AddDescText(white, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_AUTOHP1), m_Essence.hp_left, m_pDBEssence.total_hp);
AddDescText(white, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_AUTOHP2), (int)(m_pDBEssence.trigger_amount * 100.0f + 0.5f));
AddDescText(white, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_COOLTIME), m_pDBEssence.cool_time / 1000);
// Price
AddPriceDesc(white, bRepair);
// Suite description
AddSuiteDesc();
// Extend description
AddExtDescText();
return m_strDesc;
}
// Get drop model for shown
public override string GetDropModel()
{
return m_pDBEssence.FileMatter;
}
// Get item cool time
public int GetCoolTime(ref int piMax)
{
CECHostPlayer pHost = EC_Game.GetGameRun().GetHostPlayer();
return pHost != null ? pHost.GetCoolTime((int)CoolTimeIndex.GP_CT_AUTOHP, ref piMax) : 0;
}
}
}
@@ -1,14 +1,174 @@
///////////////////////////////////////////////////////////////////////////
//
// Define and Macro
//
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
//
// Reference to External variables and functions
//
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
//
// Local Types and Variables and Global variables
//
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
//
// Local functions
//
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
//
// Implement CECIvtrDecoration
//
///////////////////////////////////////////////////////////////////////////
using BrewMonster;
using ModelRenderer.Scripts.GameData;
using System.Collections.Generic;
using BrewMonster.Network;
using BrewMonster.Scripts.Managers;
using BrewMonster.Scripts;
using System.Runtime.InteropServices;
using System;
using CSNetwork.GPDataType;
namespace PerfectWorld.Scripts.Managers
{
public class EC_IvtrAutoMp : EC_IvtrItem
/// <summary>
/// Auto MP item class (tu dong hoi mana). This is a part of CEC_IvtrEquipMatter(C++)
/// </summary>
public class EC_IvtrAutoMp : EC_IvtrEquip
{
public IVTR_ESSENCE_AUTOMP m_Essence;
// Data in database
public AUTOMP_ESSENCE m_pDBEssence;
/// <summary>
/// Constructor for auto MP item (tu dong hoi mana) / Constructor for auto MP item (automatic MP recovery)
/// </summary>
/// <param name="tid">Template id</param>
/// <param name="expire_date">Expire date</param>
public EC_IvtrAutoMp(int tid, int expire_date) : base(tid, expire_date)
{
m_iCID = (int)InventoryClassId.ICID_AUTOMP;
// Get database data
elementdataman pDB = ElementDataManProvider.GetElementDataMan();
DATA_TYPE DataType = DATA_TYPE.DT_INVALID;
m_pDBEssence = (AUTOMP_ESSENCE)pDB.get_data_ptr((uint)tid, ID_SPACE.ID_SPACE_ESSENCE, ref DataType);
m_iPileLimit = m_pDBEssence.pile_num_max;
m_iPrice = m_pDBEssence.price;
m_iShopPrice = m_pDBEssence.shop_price;
m_iProcType = (int)m_pDBEssence.proc_type;
m_i64EquipMask = (long)EC_IvtrType.EQUIP_MASK64_AUTOMP;
}
/// <summary>
/// Copy constructor for auto MP item (tu dong hoi mana) / Copy constructor for auto MP item (automatic MP recovery)
/// </summary>
/// <param name="other">Other auto MP item to copy from</param>
public EC_IvtrAutoMp(EC_IvtrAutoMp other) : base(other)
{
m_pDBEssence = other.m_pDBEssence;
m_Essence = other.m_Essence;
}
public override bool SetItemInfo(byte[] pInfoData, int iDataLen)
{
base.SetItemInfo(pInfoData, iDataLen);
if (pInfoData == null || iDataLen == 0)
return true;
try
{
CECDataReader dr = new CECDataReader(pInfoData, iDataLen);
m_Essence = new IVTR_ESSENCE_AUTOMP(dr.ReadData(Marshal.SizeOf<IVTR_ESSENCE_AUTOMP>()));
}
catch (Exception e)
{
BMLogger.LogError("CECIvtrAutoHP::SetItemInfo, data read error (" + e.GetType() + ")");
return false;
}
return true;
}
// 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 item description text
protected override string GetNormalDesc(bool bRepair)
{
if (m_bNeedUpdate)
return null;
m_strDesc = string.Empty;
// Try to build item description
CECStringTab pDescTab = EC_Game.GetItemDesc();
CECHostPlayer pHost = EC_Game.GetGameRun().GetHostPlayer();
int white = (int)DescriptipionMsg.ITEMDESC_COL_WHITE;
int red = (int)DescriptipionMsg.ITEMDESC_COL_RED;
if (m_iCount > 1)
AddDescText(white, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_NAMENUMBER), GetName(), m_iCount);
else
AddDescText(white, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_NAME), GetName());
AddIDDescText();
AddBindDescText();
AddExpireTimeDesc();
AddDescText(white, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_AUTOMP1), m_Essence.mp_left, m_pDBEssence.total_mp);
AddDescText(white, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_AUTOMP2), (int)(m_pDBEssence.trigger_amount * 100.0f + 0.5f));
AddDescText(white, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_COOLTIME), m_pDBEssence.cool_time / 1000);
// Price
AddPriceDesc(white, bRepair);
// Suite description
AddSuiteDesc();
// Extend description
AddExtDescText();
return m_strDesc;
}
// Get drop model for shown
public override string GetDropModel()
{
return m_pDBEssence.FileMatter;
}
// Get item cool time
public int GetCoolTime(ref int piMax)
{
CECHostPlayer pHost = EC_Game.GetGameRun().GetHostPlayer();
return pHost != null ? pHost.GetCoolTime((int)CoolTimeIndex.GP_CT_AUTOMP, ref piMax) : 0;
}
}
}
@@ -3,6 +3,11 @@ namespace PerfectWorld.Scripts.Managers
{
public class EC_IvtrBible : EC_IvtrItem
{
/// <summary>
/// Not create logic yet (add summary later)
/// </summary>
/// <param name="tid">Template id</param>
/// <param name="expire_date">Expire date</param>
public EC_IvtrBible(int tid, int expire_date) : base(tid, expire_date)
{
}
@@ -3,6 +3,11 @@ namespace PerfectWorld.Scripts.Managers
{
public class EC_IvtrCertificate : EC_IvtrItem
{
/// <summary>
/// Not create logic yet (add summary later)
/// </summary>
/// <param name="tid">Template id</param>
/// <param name="expire_date">Expire date</param>
public EC_IvtrCertificate(int tid, int expire_date) : base(tid, expire_date)
{
}
@@ -3,6 +3,11 @@ namespace PerfectWorld.Scripts.Managers
{
public class EC_IvtrCongregate : EC_IvtrItem
{
/// <summary>
/// Not create logic yet (add summary later)
/// </summary>
/// <param name="tid">Template id</param>
/// <param name="expire_date">Expire date</param>
public EC_IvtrCongregate(int tid, int expire_date) : base(tid, expire_date)
{
}
@@ -3,6 +3,11 @@ namespace PerfectWorld.Scripts.Managers
{
public class EC_IvtrDamagerune : EC_IvtrItem
{
/// <summary>
/// Not create logic yet (add summary later)
/// </summary>
/// <param name="tid">Template id</param>
/// <param name="expire_date">Expire date</param>
public EC_IvtrDamagerune(int tid, int expire_date) : base(tid, expire_date)
{
}
@@ -39,7 +39,9 @@ using BrewMonster.Scripts.Managers;
using BrewMonster.Scripts;
namespace PerfectWorld.Scripts.Managers
{
/// <summary>
/// Decoration item class (boi + nhan + ) / Decoration item class (various types of decorations)
/// </summary>
public class EC_IvtrDecoration : EC_IvtrEquip
{
protected IVTR_ESSENCE_DECORATION m_Essence;
@@ -47,6 +49,11 @@ namespace PerfectWorld.Scripts.Managers
protected DECORATION_SUB_TYPE m_pDBSubType;
protected DECORATION_ESSENCE m_pDBEssence;
/// <summary>
/// Constructor for decoration item (cac loai trang suc) / Constructor for decoration item (various types of decorations)
/// </summary>
/// <param name="tid">Template id</param>
/// <param name="expire_date">Expire date</param>
public EC_IvtrDecoration(int tid, int expire_date) : base(tid, expire_date)
{
m_iCID = (int)InventoryClassId.ICID_DECORATION;
@@ -66,6 +73,10 @@ namespace PerfectWorld.Scripts.Managers
ReputationReq = m_pDBEssence.require_reputation;
}
/// <summary>
/// Copy constructor for decoration item (cac loai trang suc) / Copy constructor for decoration item (various types of decorations)
/// </summary>
/// <param name="other">Other decoration item to copy from</param>
public EC_IvtrDecoration(EC_IvtrDecoration other) : base(other)
{
m_pDBEssence = other.m_pDBEssence;
@@ -73,7 +84,435 @@ namespace PerfectWorld.Scripts.Managers
m_pDBSubType = other.m_pDBSubType;
m_Essence = other.m_Essence;
}
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_DECORATION(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;
}
}
public override void DefaultInfo()
{
LevelReq = m_pDBEssence.require_level;
StrengthReq = 0;
AgilityReq = 0;
ReputationReq = m_pDBEssence.require_reputation;
CurEndurance = m_pDBEssence.durability_min * ENDURANCE_SCALE;
MaxEndurance = m_pDBEssence.durability_min * ENDURANCE_SCALE;
}
public override string GetIconFile()
{
return m_pDBEssence.FileIcon;
}
// Get item name
public override string GetName()
{
return m_pDBEssence.Name;
}
public override string GetPreviewInfo()
{
int[] aPEEVals = new int[MAX_PEEINDEX];
int[] aRefines = new int[MAX_REFINEINDEX];
for(int i=0; i<MAX_PEEINDEX; i++)
aPEEVals[i] = 0;
for(int i=0; i<MAX_REFINEINDEX; i++)
aRefines[i] = 0;
m_strDesc = "";
BuildAddOnPropDesc(aPEEVals, aRefines);
CECStringTab pDescTab = EC_Game.GetItemDesc();
// Add physical damage
if (m_Essence.damage - aPEEVals[PEEI_PHYDAMAGE] + aRefines[REFINE_PHYDAMAGE] != 0)
{
AddDescText((int)DescriptipionMsg.ITEMDESC_COL_WHITE, false, EC_Game.GetItemDesc().GetWideString((int)DescriptipionMsg.ITEMDESC_PHYDAMAGE));
AddDescText((int)DescriptipionMsg.ITEMDESC_COL_WHITE, true, " %+d", m_Essence.damage - aPEEVals[PEEI_PHYDAMAGE] + aRefines[REFINE_PHYDAMAGE]);
}
// Add magic damage
if (m_Essence.magic_damage - aPEEVals[PEEI_MAGICDAMAGE] + aRefines[REFINE_MAGICDAMAGE] != 0)
{
AddDescText((int)DescriptipionMsg.ITEMDESC_COL_WHITE, false, EC_Game.GetItemDesc().GetWideString((int)DescriptipionMsg.ITEMDESC_MAGICDAMAGE));
AddDescText((int)DescriptipionMsg.ITEMDESC_COL_WHITE, true, " %+d", m_Essence.magic_damage - aPEEVals[PEEI_MAGICDAMAGE] + aRefines[REFINE_MAGICDAMAGE]);
}
// Physical defense
if (m_Essence.defense - aPEEVals[PEEI_PHYDEF] + aRefines[REFINE_PHYDEF] != 0)
{
AddDescText((int)DescriptipionMsg.ITEMDESC_COL_WHITE, false, EC_Game.GetItemDesc().GetWideString((int)DescriptipionMsg.ITEMDESC_PHYDEFENCE));
AddDescText((int)DescriptipionMsg.ITEMDESC_COL_WHITE, true, " %+d", m_Essence.defense - aPEEVals[PEEI_PHYDEF] + aRefines[REFINE_PHYDEF]);
}
// Dodge
if (m_Essence.armor - aPEEVals[PEEI_DODGE] + aRefines[REFINE_DODGE] != 0)
{
AddDescText((int)DescriptipionMsg.ITEMDESC_COL_WHITE, false, EC_Game.GetItemDesc().GetWideString((int)DescriptipionMsg.ITEMDESC_DODGE));
AddDescText((int)DescriptipionMsg.ITEMDESC_COL_WHITE, true, " %+d", m_Essence.armor - aPEEVals[PEEI_DODGE] + aRefines[REFINE_DODGE]);
}
//Gold Resistance
if (m_Essence.resistance[0] - aPEEVals[PEEI_GOLDDEF] + aRefines[REFINE_GOLDDEF] != 0)
{
AddDescText((int)DescriptipionMsg.ITEMDESC_COL_WHITE, false, EC_Game.GetItemDesc().GetWideString((int)DescriptipionMsg.ITEMDESC_GOLDDEFENCE));
AddDescText((int)DescriptipionMsg.ITEMDESC_COL_WHITE, true, " %+d", 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((int)DescriptipionMsg.ITEMDESC_COL_WHITE, false, EC_Game.GetItemDesc().GetWideString((int)DescriptipionMsg.ITEMDESC_WOODDEFENCE));
AddDescText((int)DescriptipionMsg.ITEMDESC_COL_WHITE, true, " %+d", 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((int)DescriptipionMsg.ITEMDESC_COL_WHITE, false, EC_Game.GetItemDesc().GetWideString((int)DescriptipionMsg.ITEMDESC_WATERDEFENCE));
AddDescText((int)DescriptipionMsg.ITEMDESC_COL_WHITE, true, " %+d", 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((int)DescriptipionMsg.ITEMDESC_COL_WHITE, false, EC_Game.GetItemDesc().GetWideString((int)DescriptipionMsg.ITEMDESC_FIREDEFENCE));
AddDescText((int)DescriptipionMsg.ITEMDESC_COL_WHITE, true, " %+d", 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((int)DescriptipionMsg.ITEMDESC_COL_WHITE, false, EC_Game.GetItemDesc().GetWideString((int)DescriptipionMsg.ITEMDESC_EARTHDEFENCE));
AddDescText((int)DescriptipionMsg.ITEMDESC_COL_WHITE, true, " %+d", m_Essence.resistance[4] - aPEEVals[PEEI_EARTHDEF] + aRefines[REFINE_EARTHDEF]);
}
return m_strDesc;
}
public override bool GetRefineEffectFor(string strEffect, RefineEffect rhs){
strEffect = "";
if (!m_bNeedUpdate){
switch (rhs.RefineIndex){
case REFINE_PHYDAMAGE:
strEffect = string.Format("{0}{1} {2}(+{3})",
rhs.GetClrAttribute(),
EC_Game.GetItemDesc().GetWideString((int)DescriptipionMsg.ITEMDESC_PHYDAMAGE),
m_Essence.damage - rhs.APEEVals[PEEI_PHYDAMAGE] + rhs.ARefines[REFINE_PHYDAMAGE] + rhs.GetIncEffect(),
rhs.GetClrEffect(),
rhs.GetIncEffect());
break;
case REFINE_MAGICDAMAGE:
strEffect = string.Format("{0}{1} {2}(+{3})",
rhs.GetClrAttribute(),
EC_Game.GetItemDesc().GetWideString((int)DescriptipionMsg.ITEMDESC_MAGICDAMAGE),
m_Essence.magic_damage - rhs.APEEVals[PEEI_MAGICDAMAGE] + rhs.ARefines[REFINE_MAGICDAMAGE] + rhs.GetIncEffect(),
rhs.GetClrEffect(),
rhs.GetIncEffect());
break;
case REFINE_PHYDEF:
strEffect = string.Format("{0}{1} {2}(+{3})",
rhs.GetClrAttribute(),
EC_Game.GetItemDesc().GetWideString((int)DescriptipionMsg.ITEMDESC_PHYDEFENCE),
m_Essence.defense - rhs.APEEVals[PEEI_PHYDEF] + rhs.ARefines[REFINE_PHYDEF] + rhs.GetIncEffect(),
rhs.GetClrEffect(),
rhs.GetIncEffect());
break;
case REFINE_DODGE:
strEffect = string.Format("{0}{1} {2}(+{3})",
rhs.GetClrAttribute(),
EC_Game.GetItemDesc().GetWideString((int)DescriptipionMsg.ITEMDESC_DODGE),
m_Essence.armor - rhs.APEEVals[PEEI_DODGE] + rhs.ARefines[REFINE_DODGE] + rhs.GetIncEffect(),
rhs.GetClrEffect(),
rhs.GetIncEffect());
break;
case REFINE_GOLDDEF:
strEffect = string.Format("{0}{1} {2}(+{3})",
rhs.GetClrAttribute(),
EC_Game.GetItemDesc().GetWideString((int)DescriptipionMsg.ITEMDESC_GOLDDEFENCE),
m_Essence.resistance[0] - rhs.APEEVals[PEEI_GOLDDEF] + rhs.ARefines[REFINE_GOLDDEF] + rhs.GetIncEffect(),
rhs.GetClrEffect(),
rhs.GetIncEffect());
break;
case REFINE_WOODDEF:
strEffect = string.Format("{0}{1} {2}(+{3})",
rhs.GetClrAttribute(),
EC_Game.GetItemDesc().GetWideString((int)DescriptipionMsg.ITEMDESC_WOODDEFENCE),
m_Essence.resistance[1] - rhs.APEEVals[PEEI_WOODDEF] + rhs.ARefines[REFINE_WOODDEF] + rhs.GetIncEffect(),
rhs.GetClrEffect(),
rhs.GetIncEffect());
break;
case REFINE_WATERDEF:
strEffect = string.Format("{0}{1} {2}(+{3})",
rhs.GetClrAttribute(),
EC_Game.GetItemDesc().GetWideString((int)DescriptipionMsg.ITEMDESC_WATERDEFENCE),
m_Essence.resistance[2] - rhs.APEEVals[PEEI_WATERDEF] + rhs.ARefines[REFINE_WATERDEF] + rhs.GetIncEffect(),
rhs.GetClrEffect(),
rhs.GetIncEffect());
break;
case REFINE_FIREDEF:
strEffect = string.Format("{0}{1} {2}(+{3})",
rhs.GetClrAttribute(),
EC_Game.GetItemDesc().GetWideString((int)DescriptipionMsg.ITEMDESC_FIREDEFENCE),
m_Essence.resistance[3] - rhs.APEEVals[PEEI_FIREDEF] + rhs.ARefines[REFINE_FIREDEF] + rhs.GetIncEffect(),
rhs.GetClrEffect(),
rhs.GetIncEffect());
break;
case REFINE_EARTHDEF:
strEffect = string.Format("{0}{1} {2}(+{3})",
rhs.GetClrAttribute(),
EC_Game.GetItemDesc().GetWideString((int)DescriptipionMsg.ITEMDESC_EARTHDEFENCE),
m_Essence.resistance[4] - rhs.APEEVals[PEEI_EARTHDEF] + rhs.ARefines[REFINE_EARTHDEF] + rhs.GetIncEffect(),
rhs.GetClrEffect(),
rhs.GetIncEffect());
break;
}
}
return !string.IsNullOrEmpty(strEffect);
}
protected override string GetNormalDesc(bool bRepair){
if (m_bNeedUpdate)
return null;
int[] aPEEVals = new int[MAX_PEEINDEX];
int[] aRefines = new int[MAX_REFINEINDEX];
for(int i=0; i<MAX_PEEINDEX; i++)
aPEEVals[i] = 0;
for(int i=0; i<MAX_REFINEINDEX; i++)
aRefines[i] = 0;
m_strDesc = "";
BuildAddOnPropDesc(aPEEVals, aRefines);
string strAddon = m_strDesc;
m_strDesc = "";
CECStringTab pDescTab = EC_Game.GetItemDesc();
CECHostPlayer pHost = EC_Game.GetGameRun().GetHostPlayer();
int white = (int)DescriptipionMsg.ITEMDESC_COL_WHITE;
int lblue = (int)DescriptipionMsg.ITEMDESC_COL_LIGHTBLUE;
int red = (int)DescriptipionMsg.ITEMDESC_COL_RED;
int namecol = DecideNameCol();
uint dwPEE = PropEffectEssence();
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);
// Decoration level
AddDescText(-1, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_LEVEL), m_pDBEssence.level);
//add Physical damage
if (m_Essence.damage - aPEEVals[PEEI_PHYDAMAGE] + aRefines[REFINE_PHYDAMAGE] != 0)
{
AddDescText(white, false, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_PHYDAMAGE));
AddDescText(white, true, " +{0}", m_Essence.damage - aPEEVals[PEEI_PHYDAMAGE] + aRefines[REFINE_PHYDAMAGE]);
}
//add Magic damage
if (m_Essence.magic_damage - aPEEVals[PEEI_MAGICDAMAGE] + aRefines[REFINE_MAGICDAMAGE] != 0)
{
AddDescText(white, false, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_MAGICDAMAGE));
AddDescText(white, true, " +{0}", m_Essence.magic_damage - aPEEVals[PEEI_MAGICDAMAGE] + aRefines[REFINE_MAGICDAMAGE]);
}
// 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]);
}
// 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();
m_strDesc += "\\r";
AddSuiteDesc();
AddExtDescText();
return m_strDesc;
}
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;
}
}
}
@@ -3,6 +3,11 @@ namespace PerfectWorld.Scripts.Managers
{
public class EC_IvtrDestroyingEssence : EC_IvtrItem
{
/// <summary>
/// Not create logic yet (add summary later)
/// </summary>
/// <param name="tid">Template id</param>
/// <param name="expire_date">Expire date</param>
public EC_IvtrDestroyingEssence(int tid, int expire_date) : base(tid, expire_date)
{
}
@@ -3,6 +3,11 @@ namespace PerfectWorld.Scripts.Managers
{
public class EC_IvtrDoubleExp : EC_IvtrItem
{
/// <summary>
/// Not create logic yet (add summary later)
/// </summary>
/// <param name="tid">Template id</param>
/// <param name="expire_date">Expire date</param>
public EC_IvtrDoubleExp(int tid, int expire_date) : base(tid, expire_date)
{
}
@@ -3,6 +3,11 @@ namespace PerfectWorld.Scripts.Managers
{
public class EC_IvtrDyeTicket : EC_IvtrItem
{
/// <summary>
/// Not create logic yet (add summary later)
/// </summary>
/// <param name="tid">Template id</param>
/// <param name="expire_date">Expire date</param>
public EC_IvtrDyeTicket(int tid, int expire_date) : base(tid, expire_date)
{
}
@@ -3,6 +3,11 @@ namespace PerfectWorld.Scripts.Managers
{
public class EC_IvtrDynSkillEquip : EC_IvtrEquip
{
/// <summary>
/// Not create logic yet (add summary later)
/// </summary>
/// <param name="tid">Template id</param>
/// <param name="expire_date">Expire date</param>
public EC_IvtrDynSkillEquip(int tid, int expire_date) : base(tid, expire_date)
{
}
@@ -3,6 +3,11 @@ namespace PerfectWorld.Scripts.Managers
{
public class EC_IvtrElement : EC_IvtrItem
{
/// <summary>
/// Not create logic yet (add summary later)
/// </summary>
/// <param name="tid">Template id</param>
/// <param name="expire_date">Expire date</param>
public EC_IvtrElement(int tid, int expire_date) : base(tid, expire_date)
{
}
File diff suppressed because it is too large Load Diff
@@ -3,6 +3,11 @@ namespace PerfectWorld.Scripts.Managers
{
public class EC_IvtrFacePill : EC_IvtrItem
{
/// <summary>
/// Not create logic yet (add summary later)
/// </summary>
/// <param name="tid">Template id</param>
/// <param name="expire_date">Expire date</param>
public EC_IvtrFacePill(int tid, int expire_date) : base(tid, expire_date)
{
}
@@ -3,6 +3,11 @@ namespace PerfectWorld.Scripts.Managers
{
public class EC_IvtrFaceTicket : EC_IvtrItem
{
/// <summary>
/// Not create logic yet (add summary later)
/// </summary>
/// <param name="tid">Template id</param>
/// <param name="expire_date">Expire date</param>
public EC_IvtrFaceTicket(int tid, int expire_date) : base(tid, expire_date)
{
}
@@ -3,6 +3,11 @@ namespace PerfectWorld.Scripts.Managers
{
public class EC_IvtrFactionMaterial : EC_IvtrItem
{
/// <summary>
/// Not create logic yet (add summary later)
/// </summary>
/// <param name="tid">Template id</param>
/// <param name="expire_date">Expire date</param>
public EC_IvtrFactionMaterial(int tid, int expire_date) : base(tid, expire_date)
{
}
@@ -1,14 +1,242 @@
using System;
using System.Collections.Generic;
using System.Reflection;
using System.IO;
using BrewMonster;
using ModelRenderer.Scripts.Common;
using ModelRenderer.Scripts.GameData;
using UnityEngine;
using PerfectWorld.Scripts.Managers;
using BrewMonster.Network;
using BrewMonster.Scripts.Managers;
using BrewMonster.Scripts;
using CSNetwork.GPDataType;
using System.Runtime.InteropServices;
namespace PerfectWorld.Scripts.Managers
{
public class EC_IvtrFashion : EC_IvtrItem
public class EC_IvtrFashion : EC_IvtrEquip
{
protected int m_iGender; // required gender
protected ushort m_wColor; // color in X1R5G5B5 format
protected uint m_color; // color in X8R8G8B8 format
protected IVTR_ESSENCE_FASHION m_Essence; // Fashion essence data
// Data in database
protected FASHION_MAJOR_TYPE m_pDBMajorType;
protected FASHION_SUB_TYPE m_pDBSubType;
protected FASHION_ESSENCE m_pDBEssence;
/// <summary>
/// Not create logic yet (add summary later)
/// </summary>
/// <param name="tid">Template id</param>
/// <param name="expire_date">Expire date</param>
public EC_IvtrFashion(int tid, int expire_date) : base(tid, expire_date)
{
m_iCID = (int)InventoryClassId.ICID_FASHION;
m_Essence = new IVTR_ESSENCE_FASHION();
// Get database data
elementdataman pDB = ElementDataManProvider.GetElementDataMan();
DATA_TYPE DataType = DATA_TYPE.DT_INVALID;
m_pDBEssence = (FASHION_ESSENCE)pDB.get_data_ptr((uint)tid, ID_SPACE.ID_SPACE_ESSENCE, ref DataType);
m_pDBMajorType = (FASHION_MAJOR_TYPE)pDB.get_data_ptr(m_pDBEssence.id_major_type, ID_SPACE.ID_SPACE_ESSENCE, ref DataType);
m_pDBSubType = (FASHION_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 = m_pDBSubType.equip_fashion_mask;
m_iProcType = (int)m_pDBEssence.proc_type;
// reset the info
DefaultInfo();
}
public EC_IvtrFashion(EC_IvtrFashion other) : base(other)
{
m_pDBEssence = other.m_pDBEssence;
m_pDBMajorType = other.m_pDBMajorType;
m_pDBSubType = other.m_pDBSubType;
m_Essence = other.m_Essence;
m_iGender = other.m_iGender;
m_wColor = other.m_wColor;
m_color = other.m_color;
}
// Set item detail information
public override bool SetItemInfo(byte[] pInfoData, int iDataLen)
{
// Note: because fashion is not an absolute equipment, so skip
// CECIvtrEquip::SetItemInfo().
if (pInfoData == null || iDataLen == 0)
{
m_bNeedUpdate = false;
return true;
}
try
{
CECDataReader dr = new CECDataReader(pInfoData, iDataLen);
var size = Marshal.SizeOf<IVTR_ESSENCE_FASHION>();
m_Essence = new IVTR_ESSENCE_FASHION(dr.ReadData(size));
}
catch (Exception e)
{
Debug.LogError("CECIvtrFashion::SetItemInfo, data read error (" + e.GetType() + e.StackTrace + ")");
return false;
}
LevelReq = m_Essence.require_level;
m_wColor = m_Essence.color;
m_iGender = m_Essence.gender;
m_color = (uint)FASHION_WORDCOLOR_TO_A3DCOLOR(m_wColor).GetHashCode();
m_bNeedUpdate = false;
return true;
}
// Get item default information from database
public override void DefaultInfo()
{
LevelReq = m_pDBEssence.require_level;
m_wColor = 0x7fff;
m_iGender = m_pDBEssence.gender;
m_color = 0xffffffff;
// these data also stored in essence, sync it here
m_Essence.require_level = LevelReq;
m_Essence.color = m_wColor;
m_Essence.gender = (ushort)m_iGender;
}
public static Color FASHION_WORDCOLOR_TO_A3DCOLOR(ushort color)
{
return new Color(((color & (0x1f << 10)) >> 7), ((color & (0x1f << 5)) >> 2), ((color & 0x1f) << 3));
}
public string GetSubTypeName()
{
// Try Unicode first (for Vietnamese/wide char names), then fallback to CP936
if (m_pDBSubType.name != null && m_pDBSubType.name.Length > 0)
{
string s = ByteToStringUtils.UshortArrayToUnicodeString(m_pDBSubType.name);
if (!string.IsNullOrEmpty(s) && !string.IsNullOrWhiteSpace(s))
return s;
// Fallback to legacy CP936 if Unicode was empty
s = ByteToStringUtils.UshortArrayToCP936String(m_pDBSubType.name);
if (!string.IsNullOrEmpty(s))
return s;
}
return "";
}
protected override string GetNormalDesc(bool bRepair)
{
if (m_bNeedUpdate)
return "";
m_strDesc = "";
// Try to build item description
CECStringTab pDescTab = EC_Game.GetItemDesc();
CECHostPlayer pHost = EC_Game.GetGameRun().GetHostPlayer();
int white = (int)DescriptipionMsg.ITEMDESC_COL_WHITE;
int red = (int)DescriptipionMsg.ITEMDESC_COL_RED;
int namecol = DecideNameCol();
// Item name
AddDescText(namecol, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_NAME), GetName());
AddIDDescText();
AddBindDescText();
AddExpireTimeDesc();
// Sub class name
AddDescText(white, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_CLASSNAME), GetSubTypeName());
// Color
// Use m_iScaleType == SCALE_BUY to judge whether this item is in NPC's pack,
// this may not be a valid way
if (m_pDBEssence.equip_location != (int)enumSkinShow.enumSkinShowArmet && m_pDBEssence.equip_location != (int)enumSkinShow.enumSkinShowHand)
{
if (m_iScaleType == (int)EC_IvtrItem.ScaleType.SCALE_BUY)
{
AddDescText(white, false, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_COLOR));
AddDescText(white, true, (" ???"));
}
else
{
// Extract RGB components from m_color (X8R8G8B8 format)
int colorRed = (int)((m_color >> 16) & 0xFF);
int colorGreen = (int)((m_color >> 8) & 0xFF);
int colorBlue = (int)(m_color & 0xFF);
string szCol = string.Format("^{0:X2}{1:X2}{2:X2}", colorRed, colorGreen, colorBlue);
AddDescText(white, false, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_COLOR));
m_strDesc += " ";
AddDescText(-1, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_COLORRECT), szCol);
}
}
// Level requirment
if (LevelReq > 0)
{
int lcol = pHost.GetMaxLevelSofar() >= LevelReq ? white : red;
AddDescText(lcol, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_LEVELREQ), LevelReq);
}
// fashion weapon profession requirment and weapon action type
if (m_pDBEssence.equip_location == (int)enumSkinShow.enumSkinShowHand)
{
AddDescText(-1, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_LEVEL), m_pDBEssence.level);
AddProfReqDesc(m_pDBEssence.character_combo_id);
AddActionTypeDescText((int)m_pDBEssence.action_type);
}
// Gender requirement
CECStringTab pFixMsg = EC_Game.GetFixedMsgs();
int col = (pHost.GetGender() == m_iGender) ? white : red;
AddDescText(col, false, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_GENDERREQ));
m_strDesc += " ";
if (m_iGender == (int)GENDER.GENDER_MALE)
AddDescText(col, true, pFixMsg.GetWideString((int)FixedMsg.FIXMSG_GENDER_MALE));
else
AddDescText(col, true, pFixMsg.GetWideString((int)FixedMsg.FIXMSG_GENDER_FEMALE));
// Price
AddPriceDesc(white, bRepair);
// Fashion level
if (m_pDBEssence.level > 0)
{
m_strDesc += "\\r";
m_strDesc += pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_COL_WHITE);
for (int i=0; i < m_pDBEssence.level; i++)
m_strDesc += pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_PENTAGON);
}
// Extend description
AddExtDescText();
return m_strDesc;
}
public bool HasRandomProp()
{
return false;
}
// Get drop model for shown
public override string GetDropModel()
{
return m_pDBEssence.FileMatter;
}
public int GetFashionSuiteID()
{
Dictionary<int, int> suiteEquipTab = EC_Game.GetSuiteEquipTab();
return suiteEquipTab.ContainsKey(TemplateId) ? suiteEquipTab[TemplateId] : 0;
}
}
}
@@ -3,6 +3,11 @@ namespace PerfectWorld.Scripts.Managers
{
public class EC_IvtrFirework : EC_IvtrItem
{
/// <summary>
/// Not create logic yet (add summary later)
/// </summary>
/// <param name="tid">Template id</param>
/// <param name="expire_date">Expire date</param>
public EC_IvtrFirework(int tid, int expire_date) : base(tid, expire_date)
{
}
@@ -3,6 +3,11 @@ namespace PerfectWorld.Scripts.Managers
{
public class EC_IvtrFlysword : EC_IvtrItem
{
/// <summary>
/// Not create logic yet (add summary later)
/// </summary>
/// <param name="tid">Template id</param>
/// <param name="expire_date">Expire date</param>
public EC_IvtrFlysword(int tid, int expire_date) : base(tid, expire_date)
{
}
@@ -3,6 +3,11 @@ namespace PerfectWorld.Scripts.Managers
{
public class EC_IvtrForceToken : EC_IvtrItem
{
/// <summary>
/// Not create logic yet (add summary later)
/// </summary>
/// <param name="tid">Template id</param>
/// <param name="expire_date">Expire date</param>
public EC_IvtrForceToken(int tid, int expire_date) : base(tid, expire_date)
{
}
@@ -3,6 +3,11 @@ namespace PerfectWorld.Scripts.Managers
{
public class EC_IvtrGeneralCard : EC_IvtrItem
{
/// <summary>
/// Not create logic yet (add summary later)
/// </summary>
/// <param name="tid">Template id</param>
/// <param name="expire_date">Expire date</param>
public EC_IvtrGeneralCard(int tid, int expire_date) : base(tid, expire_date)
{
}
@@ -3,6 +3,11 @@ namespace PerfectWorld.Scripts.Managers
{
public class EC_IvtrGeneralCardDice : EC_IvtrItem
{
/// <summary>
/// Not create logic yet (add summary later)
/// </summary>
/// <param name="tid">Template id</param>
/// <param name="expire_date">Expire date</param>
public EC_IvtrGeneralCardDice(int tid, int expire_date) : base(tid, expire_date)
{
}
@@ -3,6 +3,11 @@ namespace PerfectWorld.Scripts.Managers
{
public class EC_IvtrGmGenerator : EC_IvtrItem
{
/// <summary>
/// Not create logic yet (add summary later)
/// </summary>
/// <param name="tid">Template id</param>
/// <param name="expire_date">Expire date</param>
public EC_IvtrGmGenerator(int tid, int expire_date) : base(tid, expire_date)
{
}
@@ -1,15 +1,763 @@
using BrewMonster.Scripts.Managers;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.IO;
using BrewMonster;
using ModelRenderer.Scripts.Common;
using ModelRenderer.Scripts.GameData;
using UnityEngine;
using PerfectWorld.Scripts.Managers;
using BrewMonster.Network;
using CSNetwork.GPDataType;
using System.Runtime.InteropServices;
using BrewMonster.Scripts;
using BrewMonster.Scripts.Skills;
namespace PerfectWorld.Scripts.Managers
{
public class EC_IvtrGoblin : EC_IvtrItem
/// <summary>
/// The goblin item class (cac loai tinh linh).(not completed, need generate class).
/// This feature is skip for now.
/// </summary>
public class EC_IvtrGoblin : EC_IvtrEquip
{
#region const, enum and struct
const int MAX_ELF_REFINE_LEVEL = 36;
const int INITIAL_MAX_VIGOR = 1000;
enum ElfSkillNum
{
MAX_SKILLNUM = 8, // Max skill num
SKILL_LEARN_PT = 40, // ÿSKILL_LEARN_PTܶѧһ (ѹʱ 2009-08-24)
INIT_SKILL_NUM = 4, // ʼ
};
public struct GOBLINSKILL
{
public ushort skill;
public short level;
}
#endregion
#region Array and List declaration
// Refine effect of goblin
int[,] m_iRefineEffect = new int[MAX_ELF_REFINE_LEVEL, 3] {
{45,0,0},
{100,0,0},
{165,0,0},
{240,0,0},
{325,0,0},
{420,0,0},
{420,1,0},
{420,2,0},
{420,2,1},
{420,2,2}, // 10
{420,3,3},
{420,4,4},
{420,6,5},
{420,9,6},
{420,12,7},
{420,16,8},
{420,20,9},
{420,24,11},
{420,28,13},
{420,32,15}, // 20
{420,36,17},
{420,41,19},
{420,46,21},
{420,51,24},
{420,56,27},
{420,61,30},
{420,66,33},
{420,72,36},
{420,78,39},
{420,84,42}, // 30
{420,90,45},
{420,96,48},
{420,102,51},
{420,108,54},
{420,114,57},
{420,120,60}
};
int[] m_iRefineMaterial = new int[MAX_ELF_REFINE_LEVEL] {
1, 2, 7, 20, 50, 110, 220, 390, 500, 550, // 10
600, 650, 700, 750, 800, 850, 900, 950, 1000, 1050, // 20
1100, 1150, 1200, 1250, 1300, 1350, 1400, 1450, 1500, 1550, // 30
1600, 1650, 1700, 1750, 1800, 1850,
};
static int[] elf_exp_loss_constant = new int[151] {0, //no use
1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
51, 52, 53, 54, 55, 56, 57, 58, 59, 60,
61, 62, 63, 64, 65, 66, 67, 68, 69, 70,
71, 72, 73, 74, 75, 76, 77, 78, 79, 80,
81, 82, 83, 84, 85, 86, 87, 88, 89, 90,
91, 92, 93, 94, 95, 96, 97, 98, 99, 100,
100, 100, 100, 100, 100, //105
// ΪڷԳȼ150
100, 100, 100, 100, 100, //110
100, 100, 100, 100, 100,
100, 100, 100, 100, 100, //120
100, 100, 100, 100, 100,
100, 100, 100, 100, 100, //130
100, 100, 100, 100, 100,
100, 100, 100, 100, 100, //140
100, 100, 100, 100, 100,
100, 100, 100, 100, 100, //150
};
//ʹrmbĿȼӦijɹ
float[] elf_refine_succ_prob_ticket0 = new float[MAX_ELF_REFINE_LEVEL+1] {
1.0f, 0.4f, 0.315789474f, 0.338983051f, 0.377358491f, 0.417754569f, 0.463208685f, 0.510769231f, 0.55f, 0.55f,
0.55f, 0.55f, 0.55f, 0.55f, 0.55f, 0.55f, 0.55f, 0.55f, 0.55f, 0.55f,
0.55f, 0.55f, 0.55f, 0.55f, 0.55f, 0.55f, 0.55f, 0.55f, 0.55f, 0.55f,
0.55f, 0.55f, 0.55f, 0.55f, 0.55f, 0.55f,
0.0f}; // [36]: cannot refine any more
//ʹ絤(߳ɹʣʧܵȼ0)ĿȼӦijɹ
static float[] elf_refine_succ_prob_ticket1 = new float[MAX_ELF_REFINE_LEVEL+1]{
1.0f, 0.6f, 0.368421053f, 0.355932203f, 0.383647799f, 0.420365535f, 0.464414958f, 0.511384615f, 0.557001027f, 0.60032861f,
0.640836732f, 0.678052261f, 0.7f, 0.7f, 0.7f, 0.7f, 0.7f, 0.7f, 0.7f, 0.7f,
0.7f, 0.7f, 0.7f, 0.7f, 0.7f, 0.7f, 0.7f, 0.7f, 0.7f, 0.7f,
0.7f, 0.7f, 0.7f, 0.7f, 0.7f, 0.7f,
0.0f
};
//ʹϵ(ɹʣʧܵȼ1)ĿȼӦijɹ
static float[] elf_refine_succ_prob_ticket2 = new float[MAX_ELF_REFINE_LEVEL+1]{
1.0f, 0.6f, 0.333333333f, 0.296296296f, 0.3f, 0.314814815f, 0.337313433f, 0.360708535f, 0.381453155f, 0.4f,
0.4f, 0.4f, 0.4f, 0.4f, 0.4f, 0.4f, 0.4f, 0.4f, 0.4f, 0.4f,
0.4f, 0.4f, 0.4f, 0.4f, 0.4f, 0.4f, 0.4f, 0.4f, 0.4f, 0.4f,
0.4f, 0.4f, 0.4f, 0.4f, 0.4f, 0.4f,
0.0f
};
//ʹλõ(ɹʹøиޣʧܵȼ)ĿȼӦʹɹ=/Էŵ
static int[] elf_refine_max_use_ticket3 = new int[MAX_ELF_REFINE_LEVEL+1]{
1 , 2 , 7 , 20 , 50 , 112 , 223 , 398 , 648 , 974 ,
1366 , 1806 , 2271 , 2739 , 3191 , 3612 , 3993 , 4331 , 4623 , 4873 ,
5084 , 5260 , 5405 , 5525 , 5623 , 5702 , 5767 , 5819 , 5861 , 5895 ,
5923 , 5945 , 5962 , 5977 , 5988 , 5997,
100000000
};
#endregion
List<GOBLINSKILL> m_aSkills;
List<uint> m_aEquipID;
IVTR_ESSENCE_GOBLIN m_Essence; // Goblin essence data
// Data in database
GOBLIN_ESSENCE m_pDBEssence;
/// <summary>
/// Create goblin item (cac loai tinh linh).
/// </summary>
/// <param name="tid">Template id</param>
/// <param name="expire_date">Expire date</param>
public EC_IvtrGoblin(int tid, int expire_date) : base(tid, expire_date)
{
m_iCID = (int)InventoryClassId.ICID_GOBLIN;
// Get database data
elementdataman pDB = ElementDataManProvider.GetElementDataMan();
DATA_TYPE DataType = DATA_TYPE.DT_INVALID;
m_pDBEssence = (GOBLIN_ESSENCE)pDB.get_data_ptr((uint)tid, ID_SPACE.ID_SPACE_ESSENCE, ref DataType);
m_iPileLimit = m_pDBEssence.pile_num_max;
Price = m_pDBEssence.price;
m_iShopPrice = m_pDBEssence.shop_price;
m_iProcType = (int)m_pDBEssence.proc_type;
m_bNeedUpdate = false;
m_i64EquipMask = (long)EC_IvtrType.EQUIP_MASK64_GOBLIN;
CurEndurance = 1;
MaxEndurance = 1;
}
public EC_IvtrGoblin(EC_IvtrGoblin other) : base(other)
{
m_pDBEssence = other.m_pDBEssence;
m_Essence = other.m_Essence; // Copy essence
// Copy skills
int i, iNumSkill = other.m_aSkills.Count;
m_aSkills = new List<GOBLINSKILL>(iNumSkill);
for (i=0; i < iNumSkill; i++)
m_aSkills[i] = other.m_aSkills[i];
// Copy equipments
int iNumEquip = other.m_aEquipID.Count;
m_aEquipID = new List<uint>(iNumEquip);
for(i=0; i< iNumEquip; i++)
m_aEquipID[i] = other.m_aEquipID[i];
}
public IVTR_ESSENCE_GOBLIN GetEssence() { return m_Essence; }
// Get database data
public GOBLIN_ESSENCE GetDBEssence() { return m_pDBEssence; }
// Get skill number
public int GetSkillNum() { return m_aSkills.Count; }
public GOBLINSKILL GetSkill(int id) { if(id>=0 && id<m_aSkills.Count) return m_aSkills[id]; else throw new Exception("id is out of range"); }
// Set Goblin inventory stamina
void SetStamina(int iStamina) { m_Essence.data.stamina = iStamina; }
// Set Goblin Exp
public void SetExp(int iExp) { m_Essence.data.exp = (uint)iExp; }
float GetRefineSuccProb0(int iLevel)
{
return elf_refine_succ_prob_ticket0[iLevel];
}
float GetRefineSuccProb1(int iLevel)
{
if (iLevel < 0 || iLevel > MAX_ELF_REFINE_LEVEL)
{
throw new Exception("iLevel is out of range");
}
return elf_refine_succ_prob_ticket1[iLevel];
}
float GetRefineSuccProb2(int iLevel)
{
if (iLevel < 0 || iLevel > MAX_ELF_REFINE_LEVEL)
{
throw new Exception("iLevel is out of range");
}
return elf_refine_succ_prob_ticket2[iLevel];
}
float GetRefineSuccProb3(int iLevel, int iNum)
{
if (iLevel < 0 || iLevel > MAX_ELF_REFINE_LEVEL)
{
throw new Exception("iLevel is out of range");
}
if (iNum >= elf_refine_max_use_ticket3[iLevel])
{
return 1.0f;
}
if (iLevel == MAX_ELF_REFINE_LEVEL)
{
return 0.0f;
}
return (float)iNum / (float)elf_refine_max_use_ticket3[iLevel];
}
int GetRefineLife(int iLevel)
{
if (iLevel < 1 || iLevel > MAX_ELF_REFINE_LEVEL)
{
throw new Exception("iLevel is out of range");
}
return m_iRefineEffect[iLevel-1, 0];
}
int GetRefineAtkLvl(int iLevel)
{
if (iLevel < 1 || iLevel > MAX_ELF_REFINE_LEVEL)
{
throw new Exception("iLevel is out of range");
}
return m_iRefineEffect[iLevel-1, 1];
}
int GetRefineDfsLvl(int iLevel)
{
if (iLevel < 1 || iLevel > MAX_ELF_REFINE_LEVEL)
{
throw new Exception("iLevel is out of range");
}
return m_iRefineEffect[iLevel-1, 2];
}
int GetRefineMaterial(int iLevel)
{
if (iLevel < 1 || iLevel > MAX_ELF_REFINE_LEVEL)
{
throw new Exception("iLevel is out of range");
}
return m_iRefineMaterial[iLevel-1];
}
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);
// Set _GOBLIN_DATA info
// Calculate size manually: uint(4) + 7*short(14) + short[5](10) + short(2) + 2*int(8) = 40 bytes
const int GOBLIN_DATA_SIZE = 40;
m_Essence.data = new IVTR_ESSENCE_GOBLIN._GOBLIN_DATA(dr.ReadData(GOBLIN_DATA_SIZE));
// Change proc type
if(m_Essence.data.status_value < 0)
{
m_iProcType |= (int)ProcType.PROC_SELLABLE;
m_iProcType |= (int)ProcType.PROC_TRADEABLE;
}
else
{
m_iProcType &= ~(int)ProcType.PROC_SELLABLE;
m_iProcType &= ~(int)ProcType.PROC_TRADEABLE;
}
// Set equipment info
int i, iEquipCnt = dr.ReadInt();
m_Essence.equip_cnt = iEquipCnt;
m_aEquipID = new List<uint>(iEquipCnt);
for(i=0; i< iEquipCnt; i++)
{
m_aEquipID[i] = (uint)dr.ReadInt();
}
// Set skill info
int iSkillCnt = dr.ReadInt();
m_Essence.skill_cnt = iSkillCnt;
m_aSkills = new List<GOBLINSKILL>(iSkillCnt);
for(i=0; i< iSkillCnt; i++)
{
GOBLINSKILL s = m_aSkills[i];
s.skill = (ushort)dr.ReadShort();
s.level = (short)dr.ReadShort();
}
}
catch (Exception e)
{
Debug.LogError("CECIvtrGoblin::SetItemInfo, data read error (" + e.GetType() + ")");
return false;
}
return true;
}
public override void DefaultInfo()
{
base.DefaultInfo();
}
public override string GetIconFile()
{
return m_pDBEssence.FileIcon1;
}
public override string GetName()
{
return m_pDBEssence.Name;
}
protected override string GetNormalDesc(bool bRepair)
{
if (m_bNeedUpdate)
{
return string.Empty;
}
m_strDesc = "";
// Try to build item description
CECStringTab pDescTab = EC_Game.GetItemDesc();
int white = (int)DescriptipionMsg.ITEMDESC_COL_WHITE;
int yellow = (int)DescriptipionMsg.ITEMDESC_COL_YELLOW;
int green = (int)DescriptipionMsg.ITEMDESC_COL_GREEN;
int color = white;
int i;
int namecol = DecideNameCol();
// Item name: always use the name in template
if(m_Essence.data.refine_level != 0)
{
AddDescText(namecol, false, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_NAME), m_pDBEssence.Name);
AddDescText(namecol, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_GOBLIN_REFINE_LEVEL), m_Essence.data.refine_level);
}
else
{
AddDescText(namecol, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_NAME), m_pDBEssence.Name);
}
AddIDDescText();
// Goblin level
AddDescText(white, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_GOBLIN_LEVEL), m_Essence.data.level);
// Strength, Agility, Vitality, Energy + gained from equipment
int iEquipStrength = 0;
int iEquipAgility = 0;
int iEquipTili = 0;
int iEquipEnergy = 0;
// Get database data
elementdataman pDB = ElementDataManProvider.GetElementDataMan();
DATA_TYPE DataType = DATA_TYPE.DT_INVALID;
GOBLIN_EQUIP_ESSENCE pDBEssence;
for(i=0; i< m_aEquipID.Count; i++)
{
pDBEssence = (GOBLIN_EQUIP_ESSENCE)pDB.get_data_ptr(m_aEquipID[i], ID_SPACE.ID_SPACE_ESSENCE, ref DataType);
iEquipStrength += pDBEssence.strength;
iEquipAgility += pDBEssence.agility;
iEquipTili += pDBEssence.tili;
iEquipEnergy += pDBEssence.energy;
}
color = (iEquipStrength == 0) ? white : green;
AddDescText(color, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_STRENGTH), iEquipStrength + m_Essence.data.strength + m_pDBEssence.init_strength);
color = (iEquipAgility == 0) ? white : green;
AddDescText(color, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_AGILITY), iEquipAgility + m_Essence.data.agility + m_pDBEssence.init_agility);
color = (iEquipTili == 0) ? white : green;
AddDescText(color, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_VITALITY), iEquipTili + m_Essence.data.vitality + m_pDBEssence.init_tili);
color = (iEquipEnergy == 0) ? white : green;
AddDescText(color, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_ENERGY), iEquipEnergy + m_Essence.data.energy + m_pDBEssence.init_energy);
// Grow degree
AddDescText(white, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_GOBLIN_GROW_DEGREE), GetGrowDegree());
// Random status point
int iMaxRandPt = GetMaxRandomStatusPt();
if(iMaxRandPt != 0)
{
int iRandPt = GetRandomStatusPt();
int iGrowDegree = GetGrowDegree();
int iRandomPt = GetRandomStatusPt();
int iMaxPt= GetMaxStautsPt();
if(iRandomPt <= iGrowDegree*0.8)
color = (int)DescriptipionMsg.ITEMDESC_COL_GREEN;
else if(iRandomPt <= iGrowDegree)
color = (int)DescriptipionMsg.ITEMDESC_COL_LIGHTBLUE;
else if(iRandomPt <= (iMaxPt - iGrowDegree)*0.2 + iGrowDegree)
color = (int)DescriptipionMsg.ITEMDESC_COL_PURPLE;
else if(iRandomPt < iMaxPt)
color = (int)DescriptipionMsg.ITEMDESC_COL_YELLOW;
else if(iRandomPt == iMaxPt)
color = (int)DescriptipionMsg.ITEMDESC_COL_DARKGOLD;
AddDescText(color, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_GOBLIN_RANDPT), iRandPt, iMaxRandPt);
}
// Energy
int iEnergy = INITIAL_MAX_VIGOR + GetBasicProp(2);
AddDescText(white, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_GOBLIN_ENERGY), iEnergy);
// Energy restore speed
float fRestoreSpeed = 1.0f + GetBasicProp(3)*0.02f;
AddDescText(white, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_GOBLIN_ENERGY_RESTORE), fRestoreSpeed);
// Current stamina
int iCurrStamina = m_Essence.data.stamina;
if(iCurrStamina > 999999)
iCurrStamina = 999999;
AddDescText(white, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_GOBLIN_STAMINA), iCurrStamina);
// Current refine effect
if(m_Essence.data.refine_level != 0)
{
int iAttackLevel, iDefenceLevel, iLife;
iLife = GetRefineLife(m_Essence.data.refine_level);
iAttackLevel = GetRefineAtkLvl(m_Essence.data.refine_level);
iDefenceLevel = GetRefineDfsLvl(m_Essence.data.refine_level);
AddDescText(white, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_GOBLIN_REFINE_EFFECT), iLife, iAttackLevel, iDefenceLevel);
}
// Trade state
int iTradeState = m_Essence.data.status_value;
if(iTradeState == 0)
AddDescText(white,true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_GOBLIN_TRADE_PROTECT));
else if(iTradeState > 0)
AddDescText(white, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_GOBLIN_TRADE_UNPROTECT));
else if(iTradeState < 0)
AddDescText(white, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_GOBLIN_CANTRADE));
// Price
AddPriceDesc(white, bRepair);
// Equipment info
if(m_aEquipID.Count != 0)
m_strDesc += "\\r";
for(i=0; i< m_aEquipID.Count; i++)
{
pDBEssence = (GOBLIN_EQUIP_ESSENCE)pDB.get_data_ptr(m_aEquipID[i], ID_SPACE.ID_SPACE_ESSENCE, ref DataType);
AddDescText(white, false, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_GOBLINEQUIP_POS_1 + pDBEssence.equip_type));
AddDescText(white, true, " %s", pDBEssence.name);
}
// Skill list
if(m_aSkills.Count != 0 && m_aEquipID.Count == 0)
m_strDesc += "\\r";
for (i=0; i < m_aSkills.Count; i++)
{
GOBLINSKILL gSkill = m_aSkills[i];
string szName = EC_Game.GetSkillDesc().GetWideString(gSkill.skill * 10);
if(i==m_aSkills.Count-1)
AddDescText((int)DescriptipionMsg.ITEMDESC_COL_YELLOW, false, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_PETSKILL), szName != null ? szName : "", gSkill.level);
else
AddDescText((int)DescriptipionMsg.ITEMDESC_COL_YELLOW, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_PETSKILL), szName != null ? szName : "", gSkill.level);
}
AddExtDescText();
return m_strDesc;
}
// Get grow degree
int GetGrowDegree()
{
float fGrowDegree = 0.0f;
for(int i=0;i<10;i++)
{
fGrowDegree += m_pDBEssence.rand_prop[i].rand_num * m_pDBEssence.rand_prop[i].rand_rate;
}
return (int)(fGrowDegree*10 + 0.5f);
}
// Max random status points that this goblin can get, depending on player's RP value
int GetMaxRandomStatusPt()
{
return (GetMaxStautsPt()/10) * (m_Essence.data.level/10);
}
// Max status points that this goblin can get
int GetMaxStautsPt()
{
int iMaxPt = 0;
for(int i= 0;i<10;i++)
{
if(iMaxPt < m_pDBEssence.rand_prop[i].rand_num)
iMaxPt = m_pDBEssence.rand_prop[i].rand_num;
}
return iMaxPt * 10;
}
// Current random status point
int GetRandomStatusPt()
{
return m_Essence.data.total_attribute - (m_Essence.data.level-1);
}
// Get basic property
int GetBasicProp(int iIndex)
{
if(iIndex < 0 || iIndex >= 4)
{
throw new Exception("iIndex is out of range");
}
int i, iRet = 0;
// Strength, Agility, Vitality, Energy + gained from equipment
int iEquipStrength = 0;
int iEquipAgility = 0;
int iEquipTili = 0;
int iEquipEnergy = 0;
// Get database data
elementdataman pDB = ElementDataManProvider.GetElementDataMan();
DATA_TYPE DataType = DATA_TYPE.DT_INVALID;
GOBLIN_EQUIP_ESSENCE pDBEssence;
for(i=0; i< m_aEquipID.Count; i++)
{
pDBEssence = (GOBLIN_EQUIP_ESSENCE)pDB.get_data_ptr(m_aEquipID[i], ID_SPACE.ID_SPACE_ESSENCE, ref DataType);
iEquipStrength += pDBEssence.strength;
iEquipAgility += pDBEssence.agility;
iEquipTili += pDBEssence.tili;
iEquipEnergy += pDBEssence.energy;
}
if(iIndex == 0)
iRet = iEquipStrength + m_Essence.data.strength + m_pDBEssence.init_strength;
else if(iIndex == 1)
iRet = iEquipAgility + m_Essence.data.agility + m_pDBEssence.init_agility;
else if(iIndex == 2)
iRet = iEquipTili + m_Essence.data.vitality + m_pDBEssence.init_tili;
else if(iIndex == 3)
iRet = iEquipEnergy + m_Essence.data.energy + m_pDBEssence.init_energy;
return iRet;
}
uint GetDestroyExp()
{
double dRetExp = 0;
int iLevel = m_Essence.data.level;
uint iCurrExp = m_Essence.data.exp;
double factor = 0.0f;
for(int i=1;i<iLevel;i++)
{
uint iPlayerLvlUpExp = (uint)(EC_Game.GetGameRun().GetHostPlayer().GetLevelUpExp(i) * m_pDBEssence.exp_factor);
factor = (double)elf_exp_loss_constant[i]/(double)elf_exp_loss_constant[m_Essence.data.level];
dRetExp += (((double)iPlayerLvlUpExp * 0.1) / factor);
}
dRetExp += ((double)iCurrExp * 0.1);
return (dRetExp>4200000000.0) ? 4200000000 : (uint)dRetExp;
}
// Check whether goblin can trade
public override bool IsTradeable()
{
return (m_iProcType & (int)ProcType.PROC_TRADEABLE) != 0;
}
// Get drop model for shown
public override string GetDropModel() => m_pDBEssence.FileMatter;
// Get Equipment id
public uint GetEquip(int id)
{
if(id<0 || id>=4)
throw new Exception("id is out of range");
int iEquipPos = (int)m_aEquipID[id];
if(iEquipPos == id)
return m_aEquipID[id];
return 0;
}
// Check whether goblin can learn specified skill
// 0:ɹ 1:SP 2:
// 3: 4:ܸ 5:ID
// 6:Ǯ 7:С 8:ûм
// 9:ȼ 10:޲ 11:ְҵƥ
// 12:޲ְҵƥ
int CheckSkillLearnCondition(int idSkill, bool bCheckBook)
{
int iLevel = 1, i;
for(i=0;i<m_aSkills.Count;i++)
{
if(m_aSkills[i].skill == idSkill)
{
iLevel = m_aSkills[i].level + 1;
break;
}
}
CECHostPlayer pHost = EC_Game.GetGameRun().GetHostPlayer();
if (iLevel == 1 && bCheckBook)
{
// Do we have the skill book ?
int idBook = ElementSkill.GetRequiredBook((uint)idSkill, iLevel);
if ((idBook != 0) && (pHost.GetPack().FindItem(idBook) == -1))
return 8;
}
// Build player information
GoblinRequirement Info;
Info = new GoblinRequirement();
for(i=0;i<5;i++)
{
Info.genius[i] = GetGenius(i);
}
Info.profession = pHost.GetProfession();
Info.sp = pHost.GetBasicProps().iSP;
Info.money = (int)pHost.GetMoneyAmount();
Info.level = m_Essence.data.level;
Info.mp = INITIAL_MAX_VIGOR + GetBasicProp(2);
int iRet = ElementSkill.GoblinLearn((uint)idSkill, Info, iLevel);
if(iRet == 0) // success
{
if((GetSkillNum() > GetCurrMaxSkillNum()) ||
(GetSkillNum() == GetCurrMaxSkillNum() && iLevel == 1))
return 4;
}
return iRet;
}
// Get genius point
int GetGenius(int iIndex)
{
if(iIndex < 0 || iIndex >= 5)
{
throw new Exception("iIndex is out of range");
}
int i, iRet = m_Essence.data.genius[iIndex];
// Get database data
elementdataman pDB = ElementDataManProvider.GetElementDataMan();
DATA_TYPE DataType = DATA_TYPE.DT_INVALID;
GOBLIN_EQUIP_ESSENCE pDBEssence;
for(i=0; i< m_aEquipID.Count; i++)
{
pDBEssence = (GOBLIN_EQUIP_ESSENCE)pDB.get_data_ptr(m_aEquipID[i], ID_SPACE.ID_SPACE_ESSENCE, ref DataType);
iRet += pDBEssence.magic[iIndex];
}
return (iRet > 8) ? 8 : iRet;
}
int GetCurrMaxSkillNum()
{
int iRandPt = GetRandomStatusPt();
if(iRandPt > 90)
return 8;
else if(iRandPt > 80)
return 7;
else if(iRandPt > 70)
return 6;
else if(iRandPt > 50)
return 5;
return (int)ElfSkillNum.INIT_SKILL_NUM;
}
//Check whether goblin can cast specified skill
/// <summary>
/// implement later
/// </summary>
/// <param name="index"></param>
/// <returns></returns>
bool CheckSkillCastCondition(int index)
{
return true;
// if(index<0 || index >= m_aSkills.Count)
// {
// throw new Exception("index is out of range");
// return false;
// }
// if (EC_Game.GetGameRun().GetHostPlayer().GetBattleInfo().IsChariotWar())
// return false; // սս ֹ
// GNET::GoblinUseRequirement Info;
// memset(&Info, 0, sizeof(Info));
// for(int i=0;i<5;i++)
// {
// Info.genius[i] = GetGenius(i);
// }
// Info.level = m_Essence.data.level;
// Info.move_env = g_pGame->GetGameRun()->GetHostPlayer()->GetMoveEnv();
// GOBLINSKILL pSkill = GetSkill(index);
// int ret = GNET::ElementSkill::GoblinCondition(pSkill.skill, Info, pSkill.level);
// if(ret == 4)
// return false;
// return true;
}
int GetModelLevel()
{
int iGrowDegree = GetGrowDegree();
int iRandomPt = GetRandomStatusPt();
int iMaxPt= GetMaxStautsPt();
int iModelLvl = 0;
// ɳȡģ͵Ĺϵ֪ͬ
if(iRandomPt <= iGrowDegree*0.8)
iModelLvl = 1;
else if(iRandomPt <= iGrowDegree)
iModelLvl = 2;
else if(iRandomPt <= (iMaxPt - iGrowDegree)*0.2 + iGrowDegree)
iModelLvl = 3;
else
iModelLvl = 4;
return iModelLvl;
}
}
}
// Get current max skill number
@@ -3,6 +3,11 @@ namespace PerfectWorld.Scripts.Managers
{
public class EC_IvtrGoblinEquip : EC_IvtrEquip
{
/// <summary>
/// Not create logic yet (add summary later)
/// </summary>
/// <param name="tid">Template id</param>
/// <param name="expire_date">Expire date</param>
public EC_IvtrGoblinEquip(int tid, int expire_date) : base(tid, expire_date)
{
}
@@ -3,6 +3,11 @@ namespace PerfectWorld.Scripts.Managers
{
public class EC_IvtrGoblinExpPill : EC_IvtrItem
{
/// <summary>
/// Not create logic yet (add summary later)
/// </summary>
/// <param name="tid">Template id</param>
/// <param name="expire_date">Expire date</param>
public EC_IvtrGoblinExpPill(int tid, int expire_date) : base(tid, expire_date)
{
}
@@ -3,6 +3,11 @@ namespace PerfectWorld.Scripts.Managers
{
public class EC_IvtrIncSkillAbility : EC_IvtrItem
{
/// <summary>
/// Not create logic yet (add summary later)
/// </summary>
/// <param name="tid">Template id</param>
/// <param name="expire_date">Expire date</param>
public EC_IvtrIncSkillAbility(int tid, int expire_date) : base(tid, expire_date)
{
}
@@ -807,7 +807,8 @@ namespace BrewMonster.Scripts.Managers
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);
Debug.Log("DataType: " + DataType);
//Active this to log the data type of item when creating an item
//Debug.Log("Create item data: DataType: " + DataType + " tid: " + tid );
switch(DataType)
{
case DATA_TYPE.DT_WEAPON_ESSENCE:
@@ -844,7 +845,7 @@ namespace BrewMonster.Scripts.Managers
pItem = new EC_IvtrFlysword(tid, expire_date);
break;
case DATA_TYPE.DT_TOWNSCROLL_ESSENCE:
pItem = new EC_IvtrTownscroll(tid, expire_date);
pItem = new EC_IvtrTownScroll(tid, expire_date);
break;
case DATA_TYPE.DT_UNIONSCROLL_ESSENCE:
pItem = new EC_IvtrUnionscroll(tid, expire_date);
@@ -859,7 +860,7 @@ namespace BrewMonster.Scripts.Managers
pItem = new EC_IvtrTossMat(tid, expire_date);
break;
case DATA_TYPE.DT_TASKMATTER_ESSENCE:
pItem = new EC_IvtrTaskmatter(tid, expire_date);
pItem = new EC_IvtrTaskItem(tid, expire_date);
break;
case DATA_TYPE.DT_STONE_ESSENCE:
pItem = new EC_IvtrStone(tid, expire_date);
@@ -1199,9 +1200,11 @@ namespace BrewMonster.Scripts.Managers
/// <summary>Add item amount. Returns new amount of item.</summary>
public int AddAmount(int iAmount)
{
Debug.Log($"[EC_IvtrItem] Old Amount: {m_iCount}");
m_iCount += iAmount;
if (m_iCount < 0) m_iCount = 0;
if (m_iCount > m_iPileLimit) m_iCount = m_iPileLimit;
//if (m_iCount > m_iPileLimit) m_iCount = m_iPileLimit;
Debug.Log($"[EC_IvtrItem] New Amount: {m_iCount}");
return m_iCount;
}
@@ -1383,6 +1386,8 @@ namespace BrewMonster.Scripts.Managers
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);
m_strDesc += "\\r";
AddDescText((int)DescriptipionMsg.ITEMDESC_COL_RED, false, "This Item Type is not implemented yet. Type of {0}", this.GetType().Name);
TrimLastReturn();
return m_strDesc;
@@ -1401,9 +1406,63 @@ namespace BrewMonster.Scripts.Managers
protected virtual void AddPriceDesc(int col, bool bRepair)
{
// Basic price string using scaled price; color is ignored at this level.
int price = GetScaledPrice();
if (price <= 0) return;
AddDescText(col, true, "Price: {0}", price);
if ((!IsEquipment() && bRepair) || m_iPrice == 0 || m_fPriceScale == 0.0f)
{
TrimLastReturn();
return;
}
// use specific color for the item price
if((int)DescriptipionMsg.ITEMDESC_COL_WHITE == col)
{
if( m_iPrice >= 100000000) // 100 million
col = (int)DescriptipionMsg.ITEMDESC_COL_GREEN;
else if ( m_iPrice >= 10000000) // 10 million
col = (int)DescriptipionMsg.ITEMDESC_COL_DARKGOLD;
else if ( m_iPrice >= 1000000) // 1 million
col = (int)DescriptipionMsg.ITEMDESC_COL_YELLOW;
}
CECStringTab pDescTab = EC_Game.GetItemDesc();
if (m_iScaleType == (int)ScaleType.SCALE_OFFLINESHOP)
{
AddDescText(col, false, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_PRICE));
string s1,s2;
BuildPriceNumberStr(m_iPrice, out s1);
if (GetCount()>1)
{
s2 = (m_iPrice * (long)GetCount()).ToString();
AddDescText(-1, false, " %s (%s)", s1, s2);
}
else
AddDescText(-1, false, " %s", s1);
}
else if (m_iScaleType == (int)ScaleType.SCALE_BOOTH || m_tid == 21652) // 21651: yinpiao
{
string s1;
BuildPriceNumberStr(m_iPrice, out s1);
AddDescText(col, false, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_UNITPRICE));
AddDescText(-1, false, " %s", s1);
}
else if (m_iScaleType == (int)ScaleType.SCALE_SELL && m_iCount > 1 && m_tid != 21652)
{
string s1, s2;
BuildPriceNumberStr(m_iPrice, out s1);
BuildPriceNumberStr(GetScaledPrice(), out s2);
AddDescText(col, false, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_PRICE));
AddDescText(-1, false, " %s (%s)", s1, s2);
}
else
{
string s1;
BuildPriceNumberStr(GetScaledPrice(), out s1);
AddDescText(col, false, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_PRICE));
AddDescText(-1, false, " %s", s1);
}
}
protected virtual void AddProfReqDesc(uint iProfReq)
@@ -1445,12 +1504,131 @@ namespace BrewMonster.Scripts.Managers
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;
// Add color prefix if color is specified
if (iCol >= 0)
{
string colorStr = GetColorString((DescriptipionMsg)iCol);
m_strDesc += colorStr;
}
string line;
if (args != null && args.Length > 0)
{
// Accept both C#-style ("{0}") and printf-style ("%d", "%+d", "%.2f", "%%") formats
if (szText.IndexOf('%') >= 0 && szText.IndexOf('{') < 0)
{
line = FormatPrintfLike(szText, args);
}
else
{
line = string.Format(szText, args);
}
}
else
{
line = szText;
}
m_strDesc += line;
if (bRet)
m_strDesc += "\n";
}
/// <summary>
/// Get color string for color ID
/// Returns color codes in ^RRGGBB format (6 hex digits) for text formatting
/// </summary>
protected virtual string GetColorString(DescriptipionMsg colorId)
{
switch (colorId)
{
case DescriptipionMsg.ITEMDESC_COL_WHITE: return "^FFFFFF"; // White
case DescriptipionMsg.ITEMDESC_COL_GREEN: return "^00FF00"; // Green
case DescriptipionMsg.ITEMDESC_COL_YELLOW: return "^FFFF00"; // Yellow
case DescriptipionMsg.ITEMDESC_COL_DARKGOLD: return "^FF8C00"; // Dark Gold / Orange
case DescriptipionMsg.ITEMDESC_COL_LIGHTBLUE: return "^5998FF"; // Light Blue
case DescriptipionMsg.ITEMDESC_COL_CYANINE: return "^00FFFF"; // Cyan
case DescriptipionMsg.ITEMDESC_COL_RED: return "^FF0000"; // Red
case DescriptipionMsg.ITEMDESC_COL_GRAY: return "^808080"; // Gray
default: return "^FFFFFF"; // Default to white
}
}
/// <summary>
/// Format string using printf-style format specifiers (%d, %+d, %.2f, %s, etc.)
/// Converts printf-style formats to C# string formatting
/// </summary>
private static string FormatPrintfLike(string fmt, object[] args)
{
System.Text.StringBuilder sb = new System.Text.StringBuilder();
int argIndex = 0;
for (int i = 0; i < fmt.Length; i++)
{
char c = fmt[i];
if (c != '%')
{
sb.Append(c);
continue;
}
if (i + 1 < fmt.Length && fmt[i + 1] == '%')
{
sb.Append('%');
i += 1;
continue;
}
bool plus = false;
int precision = -1;
int j = i + 1;
if (j < fmt.Length && fmt[j] == '+') { plus = true; j++; }
if (j < fmt.Length && fmt[j] == '.')
{
// precision like %.2f
j++;
int start = j;
while (j < fmt.Length && char.IsDigit(fmt[j])) j++;
int.TryParse(fmt.Substring(start, j - start), out precision);
}
if (j < fmt.Length)
{
char spec = fmt[j];
if (spec == 'd')
{
object val = argIndex < args.Length ? args[argIndex++] : 0;
long iv = Convert.ToInt64(val);
string s = iv.ToString();
if (plus && iv >= 0) s = "+" + s;
sb.Append(s);
i = j;
continue;
}
else if (spec == 'f')
{
object val = argIndex < args.Length ? args[argIndex++] : 0.0;
double dv = Convert.ToDouble(val);
string s = precision >= 0 ? dv.ToString("F" + precision) : dv.ToString("F");
if (plus && dv >= 0) s = "+" + s;
sb.Append(s);
i = j;
continue;
}
else if (spec == 's')
{
object val = argIndex < args.Length ? args[argIndex++] : "";
string s = val != null ? val.ToString() : "";
sb.Append(s);
i = j;
continue;
}
}
// Fallback: treat '%' as literal if format not recognized
sb.Append('%');
}
return sb.ToString();
}
// Add extend description to description string / 添加扩展描述到描述字符串
protected void AddExtDescText()
{
@@ -1467,22 +1645,9 @@ namespace BrewMonster.Scripts.Managers
var pDescTab = EC_Game.GetItemDesc();
// Note: ITEMDESC_COL2_BRIGHTBLUE constant - adjust based on actual string table / 注意:ITEMDESC_COL2_BRIGHTBLUE常量 - 根据实际字符串表调整
int green = (int)DescriptipionMsg.ITEMDESC_COL2_BRIGHTBLUE; // ITEMDESC_COL2_BRIGHTBLUE placeholder - adjust this value
if(typeof(EC_IvtrArmor) == this.GetType())
{
Debug.Log("This is an armor");
}
Debug.Log("armor m_iCID: " + m_iCID);
Debug.Log("armor m_iProcType: " + m_iProcType);
if (m_iCID != (int)InventoryClassId.ICID_GOBLIN) // goblin does not need to display these special properties / 地精不需要显示这些特殊属性
{
Debug.Log("m_iCID != (int)InventoryClassId.ICID_GOBLIN");
Debug.Log("m_iProcType: " + m_iProcType);
Debug.Log("m_iProcType & (int)ProcType.PROC_NO_USER_TRASH: " + (m_iProcType & (int)ProcType.PROC_NO_USER_TRASH));
Debug.Log("!((m_iProcType & (int)ProcType.PROC_BINDING) != 0): " + !((m_iProcType & (int)ProcType.PROC_BINDING) != 0));
Debug.Log("((m_iProcType & (int)ProcType.PROC_DROPWHENDIE) != 0): " + ((m_iProcType & (int)ProcType.PROC_DROPWHENDIE) != 0));
Debug.Log("((m_iProcType & (int)ProcType.PROC_DROPPABLE) != 0): " + ((m_iProcType & (int)ProcType.PROC_DROPPABLE) != 0));
Debug.Log("((m_iProcType & (int)ProcType.PROC_SELLABLE) != 0): " + ((m_iProcType & (int)ProcType.PROC_SELLABLE) != 0));
// Exact C++ logic: (PROC_NO_USER_TRASH) || (!PROC_BINDING && (PROC_DROPWHENDIE || ...))
// 精确的C++逻辑:(PROC_NO_USER_TRASH) || (!PROC_BINDING && (PROC_DROPWHENDIE || ...))
if ((m_iProcType & (int)ProcType.PROC_NO_USER_TRASH) != 0
@@ -1506,8 +1671,6 @@ namespace BrewMonster.Scripts.Managers
m_strDesc += szCol;
}
}
Debug.Log("m_iProcType: " + m_iProcType);
Debug.Log("m_iProcType & (int)ProcType.PROC_DROPWHENDIE: " + (m_iProcType & (int)ProcType.PROC_DROPWHENDIE));
if ((m_iProcType & (int)ProcType.PROC_DROPWHENDIE) != 0)
{
m_strDesc += "\\r";
@@ -1517,10 +1680,7 @@ namespace BrewMonster.Scripts.Managers
if (!string.IsNullOrEmpty(desc))
m_strDesc += desc;
}
Debug.Log("m_strDesc: " + m_strDesc);
}
Debug.Log("m_iProcType: " + m_iProcType);
Debug.Log("m_iProcType & (int)ProcType.PROC_DROPPABLE: " + (m_iProcType & (int)ProcType.PROC_DROPPABLE));
if ((m_iProcType & (int)ProcType.PROC_DROPPABLE) != 0)
{
m_strDesc += "\\r";
@@ -1530,10 +1690,7 @@ namespace BrewMonster.Scripts.Managers
if (!string.IsNullOrEmpty(desc))
m_strDesc += desc;
}
Debug.Log("m_strDesc: " + m_strDesc);
}
Debug.Log("m_iProcType: " + m_iProcType);
Debug.Log("m_iProcType & (int)ProcType.PROC_SELLABLE: " + (m_iProcType & (int)ProcType.PROC_SELLABLE));
if ((m_iProcType & (int)ProcType.PROC_SELLABLE) != 0)
{
m_strDesc += "\\r";
@@ -1543,10 +1700,7 @@ namespace BrewMonster.Scripts.Managers
if (!string.IsNullOrEmpty(desc))
m_strDesc += desc;
}
Debug.Log("m_strDesc: " + m_strDesc);
}
Debug.Log("m_iProcType: " + m_iProcType);
Debug.Log("m_iProcType & (int)ProcType.PROC_TRADEABLE: " + (m_iProcType & (int)ProcType.PROC_TRADEABLE));
if ((m_iProcType & (int)ProcType.PROC_TRADEABLE) != 0)
{
m_strDesc += "\\r";
@@ -1556,10 +1710,7 @@ namespace BrewMonster.Scripts.Managers
if (!string.IsNullOrEmpty(desc))
m_strDesc += desc;
}
Debug.Log("m_strDesc: " + m_strDesc);
}
Debug.Log("m_iProcType: " + m_iProcType);
Debug.Log("m_iProcType & (int)ProcType.PROC_DISAPEAR: " + (m_iProcType & (int)ProcType.PROC_DISAPEAR));
if ((m_iProcType & (int)ProcType.PROC_DISAPEAR) != 0)
{
m_strDesc += "\\r";
@@ -1569,10 +1720,7 @@ namespace BrewMonster.Scripts.Managers
if (!string.IsNullOrEmpty(desc))
m_strDesc += desc;
}
Debug.Log("m_strDesc: " + m_strDesc);
}
Debug.Log("m_iProcType: " + m_iProcType);
Debug.Log("m_iProcType & (int)ProcType.PROC_USE: " + (m_iProcType & (int)ProcType.PROC_USE));
if ((m_iProcType & (int)ProcType.PROC_USE) != 0)
{
m_strDesc += "\\r";
@@ -1582,10 +1730,7 @@ namespace BrewMonster.Scripts.Managers
if (!string.IsNullOrEmpty(desc))
m_strDesc += desc;
}
Debug.Log("m_strDesc: " + m_strDesc);
}
Debug.Log("m_iProcType: " + m_iProcType);
Debug.Log("m_iProcType & (int)ProcType.PROC_DEADDROP: " + (m_iProcType & (int)ProcType.PROC_DEADDROP));
if ((m_iProcType & (int)ProcType.PROC_DEADDROP) != 0)
{
m_strDesc += "\\r";
@@ -1595,10 +1740,7 @@ namespace BrewMonster.Scripts.Managers
if (!string.IsNullOrEmpty(desc))
m_strDesc += desc;
}
Debug.Log("m_strDesc: " + m_strDesc);
}
Debug.Log("m_iProcType: " + m_iProcType);
Debug.Log("m_iProcType & (int)ProcType.PROC_OFFLINE: " + (m_iProcType & (int)ProcType.PROC_OFFLINE));
if ((m_iProcType & (int)ProcType.PROC_OFFLINE) != 0)
{
m_strDesc += "\\r";
@@ -1608,10 +1750,7 @@ namespace BrewMonster.Scripts.Managers
if (!string.IsNullOrEmpty(desc))
m_strDesc += desc;
}
Debug.Log("m_strDesc: " + m_strDesc);
}
Debug.Log("m_iProcType: " + m_iProcType);
Debug.Log("m_iProcType & (int)ProcType.PROC_UNREPAIRABLE: " + (m_iProcType & (int)ProcType.PROC_UNREPAIRABLE));
if ((m_iProcType & (int)ProcType.PROC_UNREPAIRABLE) != 0)
{
m_strDesc += "\\r";
@@ -1621,10 +1760,7 @@ namespace BrewMonster.Scripts.Managers
if (!string.IsNullOrEmpty(desc))
m_strDesc += desc;
}
Debug.Log("m_strDesc: " + m_strDesc);
}
Debug.Log("m_iProcType: " + m_iProcType);
Debug.Log("m_iProcType & (int)ProcType.PROC_NO_USER_TRASH: " + (m_iProcType & (int)ProcType.PROC_NO_USER_TRASH));
if ((m_iProcType & (int)ProcType.PROC_NO_USER_TRASH) != 0)
{
m_strDesc += "\\r";
@@ -1634,12 +1770,10 @@ namespace BrewMonster.Scripts.Managers
if (!string.IsNullOrEmpty(desc))
m_strDesc += desc;
}
Debug.Log("m_strDesc: " + m_strDesc);
}
}
else
{
Debug.Log("m_iCID == (int)InventoryClassId.ICID_GOBLIN");
TrimLastReturn();
}
}
@@ -1673,7 +1807,10 @@ namespace BrewMonster.Scripts.Managers
protected void AddIDDescText()
{
// Optional: show internal id for debugging
AddDescText(0, true, "ID: {0}", m_tid);
#if UNITY_EDITOR
AddDescText(0, true, "ID: {0}", m_tid);
#endif
}
protected void AddBindDescText()
@@ -3,6 +3,11 @@ namespace PerfectWorld.Scripts.Managers
{
public class EC_IvtrLookInfoItem : EC_IvtrItem
{
/// <summary>
/// Not create logic yet (add summary later)
/// </summary>
/// <param name="tid">Template id</param>
/// <param name="expire_date">Expire date</param>
public EC_IvtrLookInfoItem(int tid, int expire_date) : base(tid, expire_date)
{
}
@@ -1,15 +1,104 @@
using BrewMonster.Scripts.Managers;
using BrewMonster;
using BrewMonster.Scripts;
using ModelRenderer.Scripts.GameData;
using ModelRenderer.Scripts.Common;
using BrewMonster.Network;
namespace PerfectWorld.Scripts.Managers
{
public class EC_IvtrMaterial : EC_IvtrItem
{
protected MATERIAL_MAJOR_TYPE m_pDBMajorType;
protected MATERIAL_SUB_TYPE m_pDBSubType;
protected MATERIAL_ESSENCE m_pDBEssence;
/// <summary>
/// Not create logic yet (add summary later)
/// </summary>
/// <param name="tid">Template id</param>
/// <param name="expire_date">Expire date</param>
public EC_IvtrMaterial(int tid, int expire_date) : base(tid, expire_date)
{
m_iCID = (int)InventoryClassId.ICID_MATERIAL;
elementdataman pDB = ElementDataManProvider.GetElementDataMan();
DATA_TYPE DataType = DATA_TYPE.DT_INVALID;
m_pDBEssence = (MATERIAL_ESSENCE)pDB.get_data_ptr((uint)tid, ID_SPACE.ID_SPACE_ESSENCE, ref DataType);
m_pDBMajorType = (MATERIAL_MAJOR_TYPE)pDB.get_data_ptr(m_pDBEssence.id_major_type, ID_SPACE.ID_SPACE_ESSENCE, ref DataType);
m_pDBSubType = (MATERIAL_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_iProcType = (int)m_pDBEssence.proc_type;
m_i64EquipMask = 0;
m_bNeedUpdate = false;
}
public EC_IvtrMaterial(EC_IvtrMaterial other) : base(other)
{
m_pDBEssence = other.m_pDBEssence;
m_pDBMajorType = other.m_pDBMajorType;
m_pDBSubType = other.m_pDBSubType;
}
public override bool SetItemInfo(byte[] pInfoData, int iDataLen)
{
base.SetItemInfo(pInfoData, iDataLen);
return true;
}
// Get item icon file name
public override string GetIconFile()
{
return m_pDBEssence.FileIcon;
}
// Get item name
public override string GetName()
{
// Try Unicode first (for Vietnamese/wide char names), then fallback to CP936
if (m_pDBEssence.name != null && m_pDBEssence.name.Length > 0)
{
string s = ByteToStringUtils.UshortArrayToUnicodeString(m_pDBEssence.name);
if (!string.IsNullOrEmpty(s) && !string.IsNullOrWhiteSpace(s))
return s;
// Fallback to legacy CP936 if Unicode was empty
s = ByteToStringUtils.UshortArrayToCP936String(m_pDBEssence.name);
if (!string.IsNullOrEmpty(s))
return s;
}
return base.GetName(); // Fallback to base class method
}
// Get item description text
protected override string GetNormalDesc(bool bRepair)
{
m_strDesc = "";
// Try to build item description
CECStringTab pDescTab = EC_Game.GetItemDesc();
int white = (int)DescriptipionMsg.ITEMDESC_COL_WHITE;
int namecol = DecideNameCol();
if (m_iCount > 1)
AddDescText(namecol, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_NAMENUMBER), GetName(), m_iCount);
else
AddDescText(namecol, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_NAME), GetName());
AddIDDescText();
AddExpireTimeDesc();
// Price
AddPriceDesc(white, bRepair);
// Extend description
AddExtDescText();
return m_strDesc;
}
// Get drop model for shown
public override string GetDropModel()
{
return m_pDBEssence.FileMatter;
}
}
}
}
@@ -1,15 +1,192 @@
using BrewMonster;
using ModelRenderer.Scripts.GameData;
using System.Collections.Generic;
using BrewMonster.Network;
using BrewMonster.Scripts.Managers;
using BrewMonster.Scripts;
using CSNetwork.GPDataType;
namespace PerfectWorld.Scripts.Managers
{
/// <summary>
/// Medicine item class (cac loai thuoc).
/// This is a part of CEC_IvtrConsume(C++)
/// </summary>
public class EC_IvtrMedicine : EC_IvtrItem
{
protected MEDICINE_MAJOR_TYPE m_pDBMajorType;
protected MEDICINE_SUB_TYPE m_pDBSubType;
protected MEDICINE_ESSENCE m_pDBEssence;
protected int m_iLevelReq;
/// <summary>
/// Create medicine item (cac loai thuoc)
/// </summary>
/// <param name="tid">Template id</param>
/// <param name="expire_date">Expire date</param>
public EC_IvtrMedicine(int tid, int expire_date) : base(tid, expire_date)
{
m_iCID = (int)InventoryClassId.ICID_MEDICINE;
elementdataman pDB = ElementDataManProvider.GetElementDataMan();
DATA_TYPE DataType = DATA_TYPE.DT_INVALID;
m_pDBEssence = (MEDICINE_ESSENCE)pDB.get_data_ptr((uint)tid, ID_SPACE.ID_SPACE_ESSENCE, ref DataType);
m_pDBMajorType = (MEDICINE_MAJOR_TYPE)pDB.get_data_ptr(m_pDBEssence.id_major_type, ID_SPACE.ID_SPACE_ESSENCE, ref DataType);
m_pDBSubType = (MEDICINE_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 = 0;
m_iLevelReq = m_pDBEssence.require_level;
m_iProcType = (int)m_pDBEssence.proc_type;
m_bUseable = true;
m_bNeedUpdate = false;
}
public EC_IvtrMedicine(EC_IvtrMedicine other) : base(other)
{
m_pDBEssence = other.m_pDBEssence;
m_pDBMajorType = other.m_pDBMajorType;
m_pDBSubType = other.m_pDBSubType;
m_iLevelReq = other.m_iLevelReq;
}
public override bool SetItemInfo(byte[] pInfoData, int iDataLen)
{
base.SetItemInfo(pInfoData, iDataLen);
return true;
}
// Get item icon file name
public override string GetIconFile()
{
return m_pDBEssence.FileIcon;
}
// Get item name
public override string GetName()
{
return m_pDBEssence.Name;
}
public int GetCoolTime(ref int piMax/* NULL */)
{
CECHostPlayer pHost = CECGameRun.Instance.GetHostPlayer();
if (!pHost)
return 0;
int iTime = 0;
switch (m_pDBMajorType.id)
{
case 1810: iTime = pHost.GetCoolTime((int)CoolTimeIndex.GP_CT_REJUVENATION_POTION, ref piMax); break;
case 1794: iTime = pHost.GetCoolTime((int)CoolTimeIndex.GP_CT_HP_POTION, ref piMax); break;
case 1802: iTime = pHost.GetCoolTime((int)CoolTimeIndex.GP_CT_MP_POTION, ref piMax); break;
case 1815:
case 2038: iTime = pHost.GetCoolTime((int)CoolTimeIndex.GP_CT_ANTIDOTE_POTION, ref piMax); break;
}
return iTime;
}
// Get item description text
protected override string GetNormalDesc(bool bRepair)
{
m_strDesc = string.Empty;
BMLogger.Log("EC_IvtrMedicine: GetNormalDesc: m_iLevelReq: " + m_iLevelReq);
// Level requirement
if (m_iLevelReq > 0)
{
BMLogger.Log("EC_IvtrMedicine: m_iLevelReq: " + m_iLevelReq);
BMLogger.Log("EC_IvtrMedicine: GetMaxLevelSofar: " + CECGameRun.Instance.GetHostPlayer().GetMaxLevelSofar());
int col = CECGameRun.Instance.GetHostPlayer().GetMaxLevelSofar() >= m_iLevelReq ? (int)DescriptipionMsg.ITEMDESC_COL_WHITE : (int)DescriptipionMsg.ITEMDESC_COL_RED;
AddDescText(col, true, EC_Game.GetItemDesc().GetWideString((int)DescriptipionMsg.ITEMDESC_LEVELREQ), m_iLevelReq);
}
// Build effect description
BuildEffectDesc();
// Price
AddPriceDesc((int)DescriptipionMsg.ITEMDESC_COL_WHITE, bRepair);
// Extend description
AddExtDescText();
return m_strDesc;
}
// Build medicine effect description
protected void BuildEffectDesc()
{
CECStringTab pDescTab = EC_Game.GetItemDesc();
int white = (int)DescriptipionMsg.ITEMDESC_COL_WHITE;
AddDescText(white, false, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_USEEFFECT));
switch (m_pDBMajorType.id)
{
case 1794: // Recruit HP
if (m_pDBEssence.hp_add_total > 0)
{
BMLogger.Log("EC_IvtrMedicine: BuildEffectDesc: m_pDBEssence.hp_add_total: " + m_pDBEssence.hp_add_total);
BMLogger.Log("EC_IvtrMedicine: BuildEffectDesc: m_pDBEssence.hp_add_time: " + m_pDBEssence.hp_add_time);
if (m_pDBEssence.hp_add_time > 0)
AddDescText(white, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_ADDHPINTIME), m_pDBEssence.hp_add_time, m_pDBEssence.hp_add_total);
else
AddDescText(white, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_RECRUITHP), m_pDBEssence.hp_add_total);
}
break;
case 1802: // Recruit MP
if (m_pDBEssence.mp_add_total > 0)
{
if (m_pDBEssence.mp_add_time > 0)
AddDescText(white, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_ADDMPINTIME), m_pDBEssence.mp_add_time, m_pDBEssence.mp_add_total);
else
AddDescText(white, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_RECRUITMP), m_pDBEssence.mp_add_total);
}
break;
case 1810: // Recruit HP and MP
AddDescText(white, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_RECRUITHPMP), m_pDBEssence.hp_add_total, m_pDBEssence.mp_add_total);
break;
case 1815:
AddDescText(white, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_DECHALFPOISON));
break;
case 2038:
AddDescText(white, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_ANTIDOTE));
break;
default:
BMLogger.LogError("EC_IvtrMedicine: Unknown major type: " + m_pDBMajorType.id);
return;
}
}
// Check item use condition
protected bool CheckUseCondition()
{
CECHostPlayer pHost = CECGameRun.Instance.GetHostPlayer();
if (pHost.GetMaxLevelSofar() < m_iLevelReq)
return false;
return true;
}
// Get drop model for shown
public override string GetDropModel()
{
return m_pDBEssence.FileMatter;
}
}
}
@@ -3,6 +3,11 @@ namespace PerfectWorld.Scripts.Managers
{
public class EC_IvtrMoneyConvertible : EC_IvtrItem
{
/// <summary>
/// Not create logic yet (add summary later)
/// </summary>
/// <param name="tid">Template id</param>
/// <param name="expire_date">Expire date</param>
public EC_IvtrMoneyConvertible(int tid, int expire_date) : base(tid, expire_date)
{
}
@@ -3,6 +3,11 @@ namespace PerfectWorld.Scripts.Managers
{
public class EC_IvtrMonsterSpirit : EC_IvtrItem
{
/// <summary>
/// Not create logic yet (add summary later)
/// </summary>
/// <param name="tid">Template id</param>
/// <param name="expire_date">Expire date</param>
public EC_IvtrMonsterSpirit(int tid, int expire_date) : base(tid, expire_date)
{
}
@@ -1,15 +1,360 @@
using System;
using System.Collections.Generic;
using System.Reflection;
using System.IO;
using BrewMonster;
using ModelRenderer.Scripts.Common;
using ModelRenderer.Scripts.GameData;
using UnityEngine;
using PerfectWorld.Scripts.Managers;
using BrewMonster.Network;
using BrewMonster.Scripts.Managers;
using BrewMonster.Scripts;
using CSNetwork.GPDataType;
using System.Runtime.InteropServices;
namespace PerfectWorld.Scripts.Managers
{
public struct PETSKILL
{
public int idSkill;
public int iLevel;
};
/// <summary>
/// Class for Pet Egg(cac loai trung pet(thu cuoi, chien dau, di theo, p2w pet)). This is a part of IvtrPetItem(C++)
/// </summary>
public class EC_IvtrPetEgg : EC_IvtrItem
{
List<PETSKILL> m_aSkills;
IVTR_ESSENCE_PETEGG m_Essence;
string m_strName;
// Data in database
PET_EGG_ESSENCE m_pDBEssence;
PET_ESSENCE m_pPetEssence;
PET_ESSENCE m_pEvoPetEssence;
PET_EVOLVED_SKILL_CONFIG m_pEvoNatureConfig;
_evo_prop m_EvoProp; // ̳
/// <summary>
/// Constructor for Pet Egg(cac loai trung pet(thu cuoi, chien dau, di theo, p2w pet))
/// </summary>
/// <param name="tid">Template id</param>
/// <param name="expire_date">Expire date</param>
public EC_IvtrPetEgg(int tid, int expire_date) : base(tid, expire_date)
{
m_iCID = (int)InventoryClassId.ICID_PETEGG;
// Get database data
elementdataman pDB = ElementDataManProvider.GetElementDataMan();
DATA_TYPE DataType = DATA_TYPE.DT_INVALID;
m_pDBEssence = (PET_EGG_ESSENCE)pDB.get_data_ptr((uint)tid, ID_SPACE.ID_SPACE_ESSENCE, ref DataType);
m_pPetEssence = (PET_ESSENCE)pDB.get_data_ptr((uint)m_pDBEssence.id_pet, ID_SPACE.ID_SPACE_ESSENCE, ref DataType);
// ASSERT(m_pPetEssence);
//struct can't be null
//m_pEvoPetEssence = null;
m_pEvoPetEssence = new PET_ESSENCE();
if (m_pPetEssence.id >=0)
{
object pTempDBEssenceObj = pDB.get_data_ptr((uint)m_pPetEssence.id_pet_egg_evolved, ID_SPACE.ID_SPACE_ESSENCE, ref DataType);
if (pTempDBEssenceObj != null)
{
PET_EGG_ESSENCE pTempDBEssence = (PET_EGG_ESSENCE)pTempDBEssenceObj;
if (pTempDBEssence.id >=0)
{
object pEvoPetEssenceObj = pDB.get_data_ptr((uint)pTempDBEssence.id_pet, ID_SPACE.ID_SPACE_ESSENCE, ref DataType);
if (pEvoPetEssenceObj != null)
m_pEvoPetEssence = (PET_ESSENCE)pEvoPetEssenceObj;
}
}
}
m_iPileLimit = m_pDBEssence.pile_num_max;
m_iPrice = m_pDBEssence.price;
m_iShopPrice = m_pDBEssence.shop_price;
m_iProcType = (int)m_pDBEssence.proc_type;
m_i64EquipMask = 0;
// m_bUseable = true;
// m_dwUseFlags = USE_PERSIST;
m_Essence = new IVTR_ESSENCE_PETEGG();
m_EvoProp = new _evo_prop{
r_attack = 0,
r_defense = 0,
r_hp = 0,
r_atk_lvl = 0,
r_def_lvl = 0,
nature = 0
};
m_pEvoNatureConfig = new PET_EVOLVED_SKILL_CONFIG();
}
public EC_IvtrPetEgg(EC_IvtrPetEgg other) : base(other)
{
m_pDBEssence = other.m_pDBEssence;
m_pPetEssence = other.m_pPetEssence;
m_Essence = other.m_Essence;
m_strName = other.m_strName;
// Copy skills
int i, iNumSkill = other.m_aSkills.Count;
m_aSkills = new List<PETSKILL>(iNumSkill);
for (i=0; i < iNumSkill; i++)
m_aSkills[i] = other.m_aSkills[i];
m_EvoProp = other.m_EvoProp;
m_pEvoNatureConfig = other.m_pEvoNatureConfig;
m_pEvoPetEssence = other.m_pEvoPetEssence;
}
public override bool SetItemInfo(byte[] pInfoData, int iDataLen)
{
base.SetItemInfo(pInfoData, iDataLen);
if (pInfoData == null || iDataLen == 0)
return true;
try {
CECDataReader dr = new CECDataReader(pInfoData, iDataLen);
m_Essence = new IVTR_ESSENCE_PETEGG(dr.ReadData(Marshal.SizeOf<IVTR_ESSENCE_PETEGG>()));
if (m_Essence.name_len != 0)
{
m_strName = ByteToStringUtils.UshortArrayToUnicodeString(m_Essence.name);
EC_Game.GetGameRun().GetUIManager().FilterBadWords(m_strName);
}
m_aSkills = new List<PETSKILL>(m_Essence.skill_count);
for (int i=0; i < m_Essence.skill_count; i++)
{
PETSKILL s = new PETSKILL();
s.idSkill = dr.ReadInt();
s.iLevel = dr.ReadInt();
m_aSkills.Add(s);
}
if (m_Essence.pet_class == (int)GP_PET_TYPE.GP_PET_CLASS_EVOLUTION)
{
m_EvoProp.r_attack = dr.ReadInt();
m_EvoProp.r_defense = dr.ReadInt();
m_EvoProp.r_hp = dr.ReadInt();
m_EvoProp.r_atk_lvl = dr.ReadInt();
m_EvoProp.r_def_lvl = dr.ReadInt();
m_EvoProp.nature = dr.ReadInt();
elementdataman pDB = ElementDataManProvider.GetElementDataMan();
DATA_TYPE DataType = DATA_TYPE.DT_INVALID;
object pDBData = pDB.get_data_ptr((uint)m_EvoProp.nature, ID_SPACE.ID_SPACE_CONFIG, ref DataType);
if (pDBData != null && DataType == DATA_TYPE.DT_PET_EVOLVED_SKILL_CONFIG)
m_pEvoNatureConfig = (PET_EVOLVED_SKILL_CONFIG)pDBData;
}
}
catch (Exception e)
{
Debug.LogError("EC_IvtrPetEgg::SetItemInfo, data read error (" + e.GetType() + e.StackTrace + ")");
return false;
}
return true;
}
public override string GetIconFile()
{
return m_pDBEssence.FileIcon;
}
public override string GetName()
{
// Try Unicode first (for Vietnamese/wide char names), then fallback to CP936
if (m_pDBEssence.name != null && m_pDBEssence.name.Length > 0)
{
string s = ByteToStringUtils.UshortArrayToUnicodeString(m_pDBEssence.name);
if (!string.IsNullOrEmpty(s) && !string.IsNullOrWhiteSpace(s))
return s;
// Fallback to legacy CP936 if Unicode was empty
s = ByteToStringUtils.UshortArrayToCP936String(m_pDBEssence.name);
if (!string.IsNullOrEmpty(s))
return s;
}
return base.GetName(); // Fallback to base class method
}
protected override string GetNormalDesc(bool bRepair)
{
string szDesc = "";
switch (m_Essence.pet_class)
{
case (int)GP_PET_TYPE.GP_PET_CLASS_MOUNT: szDesc = GetRidingPetDesc(bRepair); break;
case (int)GP_PET_TYPE.GP_PET_CLASS_COMBAT: szDesc = GetCombatPetDesc(bRepair); break;
case (int)GP_PET_TYPE.GP_PET_CLASS_FOLLOW: szDesc = GetFollowPetDesc(bRepair); break;
case (int)GP_PET_TYPE.GP_PET_CLASS_EVOLUTION:szDesc = GetEvolutionPetDesc(bRepair); break;
}
return szDesc;
}
private string GetRidingPetDesc(bool bRepair)
{
Debug.Log("GetRidingPetDesc. This is not implemented yet.");
return "";
}
private string GetCombatPetDesc(bool bRepair)
{
if (m_bNeedUpdate)
return "";
m_strDesc = "";
// Try to build item description
CECStringTab pDescTab = EC_Game.GetItemDesc();
CECHostPlayer pHost = EC_Game.GetGameRun().GetHostPlayer();
int white = (int)DescriptipionMsg.ITEMDESC_COL_WHITE;
int red = (int)DescriptipionMsg.ITEMDESC_COL_RED;
int namecol = DecideNameCol();
// Item name: always use the name in template
if (m_iCount > 1)
AddDescText(namecol, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_NAMENUMBER), GetName(), m_iCount);
else
AddDescText(namecol, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_NAME), GetName());
AddIDDescText();
AddBindDescText();
AddExpireTimeDesc();
// Food type requirement
AddFoodTypeDesc();
if (m_pPetEssence.id != 0)
{
// Pet level
AddDescText(white, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_PETLEVEL), m_Essence.level);
// Physical damage
int iVal = (int)(((PET_ESSENCE)m_pPetEssence).damage_a * (((PET_ESSENCE)m_pPetEssence).damage_b * m_Essence.level * m_Essence.level + ((PET_ESSENCE)m_pPetEssence).damage_c * m_Essence.level + ((PET_ESSENCE)m_pPetEssence).damage_d));
AddDescText(-1, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_DAMAGE), iVal);
// Attack speed
AddDescText(-1, false, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_ATKSPEED));
AddDescText(-1, true, " %.2f", 1.0f / ((PET_ESSENCE)m_pPetEssence).attack_speed);
//Attack rating
iVal = (int)(((PET_ESSENCE)m_pPetEssence).attack_a * (m_Essence.level - ((PET_ESSENCE)m_pPetEssence).attack_b * ((PET_ESSENCE)m_pPetEssence).level_require + ((PET_ESSENCE)m_pPetEssence).attack_c));
AddDescText(-1, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_ATTACKRATE), iVal);
// Physical defence
iVal = (int)(((PET_ESSENCE)m_pPetEssence).physic_defence_a * (((PET_ESSENCE)m_pPetEssence).physic_defence_b * (m_Essence.level - ((PET_ESSENCE)m_pPetEssence).physic_defence_c * ((PET_ESSENCE)m_pPetEssence).level_require) + ((PET_ESSENCE)m_pPetEssence).physic_defence_d));
AddDescText(-1, false, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_PHYDEFENCE));
AddDescText(-1, true, " %d", iVal);
// Magic defence
iVal = (int)(((PET_ESSENCE)m_pPetEssence).magic_defence_a * (((PET_ESSENCE)m_pPetEssence).magic_defence_b * (m_Essence.level - ((PET_ESSENCE)m_pPetEssence).magic_defence_c * ((PET_ESSENCE)m_pPetEssence).level_require) + ((PET_ESSENCE)m_pPetEssence).magic_defence_d));
AddDescText(-1, false, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_ALLMAGICDEF));
AddDescText(-1, true, " %d", iVal);
// Dodge
iVal = (int)(((PET_ESSENCE)m_pPetEssence).armor_a * (m_Essence.level - ((PET_ESSENCE)m_pPetEssence).armor_b * ((PET_ESSENCE)m_pPetEssence).level_require + ((PET_ESSENCE)m_pPetEssence).armor_c));
AddDescText(-1, false, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_DODGE));
AddDescText(-1, true, " %d", iVal);
// hp
iVal = (int)(((PET_ESSENCE)m_pPetEssence).hp_a * (m_Essence.level - ((PET_ESSENCE)m_pPetEssence).hp_b * ((PET_ESSENCE)m_pPetEssence).level_require + ((PET_ESSENCE)m_pPetEssence).hp_c));
AddDescText(-1, false, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_ADDHP));
AddDescText(-1, true, " %d", iVal);
// Profession requirement
AddProfReqDesc(((PET_ESSENCE)m_pPetEssence).character_combo_id);
}
// Level requirement
int iLevelReq = Mathf.Max((int)m_Essence.level, m_Essence.req_level);
if (iLevelReq > 0)
{
int col = pHost.GetMaxLevelSofar() >= iLevelReq ? white : red;
AddDescText(col, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_LEVELREQ), iLevelReq);
}
// Skill list
for (int i=0; i < m_aSkills.Count; i++)
{
PETSKILL skill = m_aSkills[i];
string szName = EC_Game.GetSkillDesc().GetWideString(skill.idSkill * 10);
AddDescText((int)DescriptipionMsg.ITEMDESC_COL_YELLOW, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_PETSKILL), szName != null ? szName : "", skill.iLevel);
}
// ɽ
if (m_pEvoPetEssence.id != 0)
{
AddDescText((int)DescriptipionMsg.ITEMDESC_COL_WHITE, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_PET_EVO_NAME), ByteToStringUtils.UshortArrayToUnicodeString(((PET_ESSENCE)m_pEvoPetEssence).name));
}
// Price
AddPriceDesc(white, bRepair);
// Extend description
AddExtDescText();
return m_strDesc;
}
private string GetFollowPetDesc(bool bRepair)
{
Debug.Log("[THN]GetFollowPetDesc. This is not implemented yet.");
return "";
}
private string GetEvolutionPetDesc(bool bRepair)
{
Debug.Log("[THN]GetEvolutionPetDesc. This is not implemented yet.");
return "";
}
private void AddFoodTypeDesc()
{
elementdataman pDB = ElementDataManProvider.GetElementDataMan();
DATA_TYPE DataType = DATA_TYPE.DT_INVALID;
object pPetEssence = pDB.get_data_ptr((uint)m_Essence.pet_tid, ID_SPACE.ID_SPACE_ESSENCE, ref DataType);
if (pPetEssence == null)
return;
CECStringTab pDescTab = EC_Game.GetItemDesc();
AddDescText((int)DescriptipionMsg.ITEMDESC_COL_WHITE, false, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_FOODTYPE));
for (int i=0; i < (int)PetFoodType.MAX_PET_FOOD; i++)
{
if ((((PET_ESSENCE)pPetEssence).food_mask & (1 << i)) != 0)
{
m_strDesc += " ";
AddDescText(-1, false, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_FOOD_GRASS+i));
}
}
m_strDesc += "\\r";
}
// Get item description for booth buying
protected override string GetBoothBuyDesc()
{
m_strDesc = "";
CECStringTab pDescTab = EC_Game.GetItemDesc();
int white = (int)DescriptipionMsg.ITEMDESC_COL_WHITE;
// Item name
AddDescText(white, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_NAME), ByteToStringUtils.UshortArrayToUnicodeString(m_pDBEssence.name));
// Price
AddPriceDesc(white, false);
return m_strDesc;
}
// Get drop model for shown
public override string GetDropModel()
{
return ByteToStringUtils.ByteArrayToCP936String(m_pDBEssence.file_matter);
}
}
}
@@ -3,6 +3,11 @@ namespace PerfectWorld.Scripts.Managers
{
public class EC_IvtrPetFaceTicket : EC_IvtrItem
{
/// <summary>
/// Not create logic yet (add summary later)
/// </summary>
/// <param name="tid">Template id</param>
/// <param name="expire_date">Expire date</param>
public EC_IvtrPetFaceTicket(int tid, int expire_date) : base(tid, expire_date)
{
}
@@ -1,15 +1,152 @@
using System;
using System.Collections.Generic;
using System.Reflection;
using System.IO;
using BrewMonster;
using ModelRenderer.Scripts.Common;
using ModelRenderer.Scripts.GameData;
using UnityEngine;
using PerfectWorld.Scripts.Managers;
using BrewMonster.Network;
using BrewMonster.Scripts.Managers;
using BrewMonster.Scripts;
using CSNetwork.GPDataType;
using System.Runtime.InteropServices;
namespace PerfectWorld.Scripts.Managers
{
public class EC_IvtrPetFood : EC_IvtrItem
{
protected PET_FOOD_ESSENCE m_pDBEssence;
/// <summary>
/// Not create logic yet (add summary later)
/// </summary>
/// <param name="tid">Template id</param>
/// <param name="expire_date">Expire date</param>
public EC_IvtrPetFood(int tid, int expire_date) : base(tid, expire_date)
{
m_iCID = (int)InventoryClassId.ICID_PETFOOD;
// Get database data
elementdataman pDB = ElementDataManProvider.GetElementDataMan();
DATA_TYPE DataType = DATA_TYPE.DT_INVALID;
m_pDBEssence = (PET_FOOD_ESSENCE)pDB.get_data_ptr((uint)tid, ID_SPACE.ID_SPACE_ESSENCE, ref DataType);
m_iPileLimit = m_pDBEssence.pile_num_max;
m_iPrice = m_pDBEssence.price;
m_iShopPrice = m_pDBEssence.shop_price;
m_iProcType = (int)m_pDBEssence.proc_type;
m_i64EquipMask = 0;
m_bUseable = true;
m_bNeedUpdate = false;
}
public EC_IvtrPetFood(EC_IvtrPetFood other) : base(other)
{
m_pDBEssence = other.m_pDBEssence;
}
public override bool SetItemInfo(byte[] pInfoData, int iDataLen)
{
base.SetItemInfo(pInfoData, iDataLen);
return true;
}
// Get item icon file name
public override string GetIconFile()
{
return m_pDBEssence.FileIcon;
}
// Get item name
public override string GetName()
{
// Try Unicode first (for Vietnamese/wide char names), then fallback to CP936
if (m_pDBEssence.name != null && m_pDBEssence.name.Length > 0)
{
string s = ByteToStringUtils.UshortArrayToUnicodeString(m_pDBEssence.name);
if (!string.IsNullOrEmpty(s) && !string.IsNullOrWhiteSpace(s))
return s;
// Fallback to legacy CP936 if Unicode was empty
s = ByteToStringUtils.UshortArrayToCP936String(m_pDBEssence.name);
if (!string.IsNullOrEmpty(s))
return s;
}
return base.GetName(); // Fallback to base class method
}
// Get item cool time
public int GetCoolTime(ref int piMax)
{
CECHostPlayer pHost = EC_Game.GetGameRun().GetHostPlayer();
if (!pHost)
return 0;
int iTime = pHost.GetCoolTime((int)CoolTimeIndex.GP_CT_FEED_PET, ref piMax);
return iTime;
}
// Check item use condition
public override bool CheckUseCondition()
{
CECPetData pPet = EC_Game.GetGameRun().GetHostPlayer().GetPetCorral().GetActivePet();
if (pPet == null)
return false;
DATA_TYPE DataType = DATA_TYPE.DT_INVALID;
object temp = ElementDataManProvider.GetElementDataMan().get_data_ptr((uint)pPet.GetTemplateID(), ID_SPACE.ID_SPACE_ESSENCE, ref DataType);
if (temp == null)
return false;
PET_ESSENCE pPetEssence = (PET_ESSENCE)temp;
return ((m_pDBEssence.food_type & pPetEssence.food_mask) != 0) ? true : false;
}
// Get item description text
protected override string GetNormalDesc(bool bRepair)
{
m_strDesc = "";
// Try to build item description
CECStringTab pDescTab = EC_Game.GetItemDesc();
int white = (int)DescriptipionMsg.ITEMDESC_COL_WHITE;
int namecol = DecideNameCol();
// Item name
if (m_iCount > 1)
AddDescText(namecol, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_NAMENUMBER), GetName(), m_iCount);
else
AddDescText(namecol, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_NAME), GetName());
AddIDDescText();
AddExpireTimeDesc();
// Food type
for (int i=0; i < (int)PetFoodType.MAX_PET_FOOD; i++)
{
if ((m_pDBEssence.food_type & (1 << i)) != 0)
{
AddDescText(white, false, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_FOODTYPE));
m_strDesc += " ";
AddDescText(-1, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_FOOD_GRASS+i));
break;
}
}
// Price
AddPriceDesc(white, bRepair);
// Extend description
AddExtDescText();
return m_strDesc;
}
// Get drop model for shown
public override string GetDropModel()
{
return m_pDBEssence.FileMatter;
}
}
}
@@ -3,6 +3,11 @@ namespace PerfectWorld.Scripts.Managers
{
public class EC_IvtrRecipe : EC_IvtrItem
{
/// <summary>
/// Not create logic yet (add summary later)
/// </summary>
/// <param name="tid">Template id</param>
/// <param name="expire_date">Expire date</param>
public EC_IvtrRecipe(int tid, int expire_date) : base(tid, expire_date)
{
}
@@ -3,6 +3,11 @@ namespace PerfectWorld.Scripts.Managers
{
public class EC_IvtrRefineTicket : EC_IvtrItem
{
/// <summary>
/// Not create logic yet (add summary later)
/// </summary>
/// <param name="tid">Template id</param>
/// <param name="expire_date">Expire date</param>
public EC_IvtrRefineTicket(int tid, int expire_date) : base(tid, expire_date)
{
}
@@ -3,6 +3,11 @@ namespace PerfectWorld.Scripts.Managers
{
public class EC_IvtrRevScroll : EC_IvtrItem
{
/// <summary>
/// Not create logic yet (add summary later)
/// </summary>
/// <param name="tid">Template id</param>
/// <param name="expire_date">Expire date</param>
public EC_IvtrRevScroll(int tid, int expire_date) : base(tid, expire_date)
{
}
@@ -3,6 +3,11 @@ namespace PerfectWorld.Scripts.Managers
{
public class EC_IvtrSharpener : EC_IvtrItem
{
/// <summary>
/// Not create logic yet (add summary later)
/// </summary>
/// <param name="tid">Template id</param>
/// <param name="expire_date">Expire date</param>
public EC_IvtrSharpener(int tid, int expire_date) : base(tid, expire_date)
{
}
@@ -3,6 +3,11 @@ namespace PerfectWorld.Scripts.Managers
{
public class EC_IvtrShopToken : EC_IvtrItem
{
/// <summary>
/// Not create logic yet (add summary later)
/// </summary>
/// <param name="tid">Template id</param>
/// <param name="expire_date">Expire date</param>
public EC_IvtrShopToken(int tid, int expire_date) : base(tid, expire_date)
{
}
@@ -3,6 +3,11 @@ namespace PerfectWorld.Scripts.Managers
{
public class EC_IvtrSkillMat : EC_IvtrItem
{
/// <summary>
/// Not create logic yet (add summary later)
/// </summary>
/// <param name="tid">Template id</param>
/// <param name="expire_date">Expire date</param>
public EC_IvtrSkillMat(int tid, int expire_date) : base(tid, expire_date)
{
}
@@ -1,15 +1,116 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.IO;
using BrewMonster;
using ModelRenderer.Scripts.Common;
using ModelRenderer.Scripts.GameData;
using UnityEngine;
using PerfectWorld.Scripts.Managers;
using BrewMonster.Network;
using BrewMonster.Scripts.Managers;
using BrewMonster.Scripts;
namespace PerfectWorld.Scripts.Managers
{
/// <summary>
/// Skill tome item class(sach ky nang). This is a part of CEC_IvtrScroll(C++)
/// </summary>
public class EC_IvtrSkilltome : EC_IvtrItem
{
protected SKILLTOME_ESSENCE m_pDBEssence;
protected SKILLTOME_SUB_TYPE m_pDBSubType;
/// <summary>
/// Create skill tome item(sach ky nang)
/// </summary>
/// <param name="tid">Template id</param>
/// <param name="expire_date">Expire date</param>
public EC_IvtrSkilltome(int tid, int expire_date) : base(tid, expire_date)
{
m_iCID = (int)InventoryClassId.ICID_SKILLTOME;
// Get database data
elementdataman pDB = ElementDataManProvider.GetElementDataMan();
DATA_TYPE DataType = DATA_TYPE.DT_INVALID;
m_pDBEssence = (SKILLTOME_ESSENCE)pDB.get_data_ptr((uint)tid, ID_SPACE.ID_SPACE_ESSENCE, ref DataType);
m_pDBSubType = (SKILLTOME_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_iProcType = (int)m_pDBEssence.proc_type;
m_i64EquipMask = 0;
m_bNeedUpdate = false;
}
/// <summary>
/// Copy constructor for skill tome item(sach ky nang)
/// </summary>
/// <param name="other">Other skill tome item</param>
public EC_IvtrSkilltome(EC_IvtrSkilltome other) : base(other)
{
m_pDBEssence = other.m_pDBEssence;
m_pDBSubType = other.m_pDBSubType;
}
public override bool SetItemInfo(byte[] pInfoData, int iDataLen)
{
base.SetItemInfo(pInfoData, iDataLen);
return true;
}
public override string GetIconFile()
{
return m_pDBEssence.FileIcon;
}
// Get item name
public override string GetName()
{
// Try Unicode first (for Vietnamese/wide char names), then fallback to CP936
if (m_pDBEssence.name != null && m_pDBEssence.name.Length > 0)
{
string s = ByteToStringUtils.UshortArrayToUnicodeString(m_pDBEssence.name);
if (!string.IsNullOrEmpty(s) && !string.IsNullOrWhiteSpace(s))
return s;
// Fallback to legacy CP936 if Unicode was empty
s = ByteToStringUtils.UshortArrayToCP936String(m_pDBEssence.name);
if (!string.IsNullOrEmpty(s))
return s;
}
return base.GetName(); // Fallback to base class method
}
protected override string GetNormalDesc(bool bRepair)
{
m_strDesc = "";
// Try to build item description
CECStringTab pDescTab = EC_Game.GetItemDesc();
int white = (int)DescriptipionMsg.ITEMDESC_COL_WHITE;
int namecol = DecideNameCol();
if (m_iCount > 1)
AddDescText(namecol, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_NAMENUMBER), GetName(), m_iCount);
else
AddDescText(namecol, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_NAME), GetName());
AddIDDescText();
AddExpireTimeDesc();
// Price
AddPriceDesc(white, bRepair);
// Extend description
AddExtDescText();
return m_strDesc;
}
public override string GetDropModel()
{
return m_pDBEssence.FileMatter;
}
}
}
}
@@ -3,6 +3,11 @@ namespace PerfectWorld.Scripts.Managers
{
public class EC_IvtrSpeaker : EC_IvtrItem
{
/// <summary>
/// Not create logic yet (add summary later)
/// </summary>
/// <param name="tid">Template id</param>
/// <param name="expire_date">Expire date</param>
public EC_IvtrSpeaker(int tid, int expire_date) : base(tid, expire_date)
{
}
@@ -3,6 +3,11 @@ namespace PerfectWorld.Scripts.Managers
{
public class EC_IvtrStone : EC_IvtrItem
{
/// <summary>
/// Not create logic yet (add summary later)
/// </summary>
/// <param name="tid">Template id</param>
/// <param name="expire_date">Expire date</param>
public EC_IvtrStone(int tid, int expire_date) : base(tid, expire_date)
{
}
@@ -3,6 +3,11 @@ namespace PerfectWorld.Scripts.Managers
{
public class EC_IvtrTargetItem : EC_IvtrItem
{
/// <summary>
/// Not create logic yet (add summary later)
/// </summary>
/// <param name="tid">Template id</param>
/// <param name="expire_date">Expire date</param>
public EC_IvtrTargetItem(int tid, int expire_date) : base(tid, expire_date)
{
}
@@ -3,6 +3,11 @@ namespace PerfectWorld.Scripts.Managers
{
public class EC_IvtrTaskDice : EC_IvtrItem
{
/// <summary>
/// Not create logic yet (add summary later)
/// </summary>
/// <param name="tid">Template id</param>
/// <param name="expire_date">Expire date</param>
public EC_IvtrTaskDice(int tid, int expire_date) : base(tid, expire_date)
{
}
@@ -0,0 +1,105 @@
using System;
using System.Collections.Generic;
using System.Reflection;
using System.IO;
using BrewMonster;
using ModelRenderer.Scripts.Common;
using ModelRenderer.Scripts.GameData;
using UnityEngine;
using PerfectWorld.Scripts.Managers;
using BrewMonster.Network;
using BrewMonster.Scripts.Managers;
using BrewMonster.Scripts;
using CSNetwork.GPDataType;
using System.Runtime.InteropServices;
namespace PerfectWorld.Scripts.Managers
{
public class EC_IvtrTaskItem : EC_IvtrItem
{
protected TASKMATTER_ESSENCE m_pDBEssence;
/// <summary>
/// Not create logic yet (add summary later)
/// </summary>
/// <param name="tid">Template id</param>
/// <param name="expire_date">Expire date</param>
public EC_IvtrTaskItem(int tid, int expire_date) : base(tid, expire_date)
{
m_iCID = (int)InventoryClassId.ICID_TASKITEM;
// Get database data
elementdataman pDB = ElementDataManProvider.GetElementDataMan();
DATA_TYPE DataType = DATA_TYPE.DT_INVALID;
m_pDBEssence = (TASKMATTER_ESSENCE)pDB.get_data_ptr((uint)tid, ID_SPACE.ID_SPACE_ESSENCE, ref DataType);
m_iPileLimit = m_pDBEssence.pile_num_max;
m_iPrice = 0;
m_iShopPrice = 0;
m_iProcType = (int)m_pDBEssence.proc_type;
m_i64EquipMask = 0;
m_bNeedUpdate = false;
}
public EC_IvtrTaskItem(EC_IvtrTaskItem other) : base(other)
{
m_pDBEssence = other.m_pDBEssence;
}
public override bool SetItemInfo(byte[] pInfoData, int iDataLen)
{
base.SetItemInfo(pInfoData, iDataLen);
return true;
}
// Get item icon file name
public override string GetIconFile()
{
return m_pDBEssence.FileIcon;
}
// Get item name
public override string GetName()
{
// Try Unicode first (for Vietnamese/wide char names), then fallback to CP936
if (m_pDBEssence.name != null && m_pDBEssence.name.Length > 0)
{
string s = ByteToStringUtils.UshortArrayToUnicodeString(m_pDBEssence.name);
if (!string.IsNullOrEmpty(s) && !string.IsNullOrWhiteSpace(s))
return s;
// Fallback to legacy CP936 if Unicode was empty
s = ByteToStringUtils.UshortArrayToCP936String(m_pDBEssence.name);
if (!string.IsNullOrEmpty(s))
return s;
}
return base.GetName(); // Fallback to base class method
}
// Get item description text
protected override string GetNormalDesc(bool bRepair)
{
m_strDesc = string.Empty;
// Try to build item description
CECStringTab pDescTab = EC_Game.GetItemDesc();
int white = (int)DescriptipionMsg.ITEMDESC_COL_WHITE;
int namecol = DecideNameCol();
if (m_iCount > 1)
AddDescText(namecol, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_NAMENUMBER), GetName(), m_iCount);
else
AddDescText(namecol, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_NAME), GetName());
AddIDDescText();
AddExpireTimeDesc();
// Task item
AddDescText(white, false, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_TASKITEM));
// Extend description
AddExtDescText();
return m_strDesc;
}
}
}
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: ec738837a1a3f40e38926d3365da3df5
@@ -1,15 +1,93 @@
using System;
using System.Collections.Generic;
using System.Reflection;
using System.IO;
using BrewMonster;
using ModelRenderer.Scripts.Common;
using ModelRenderer.Scripts.GameData;
using UnityEngine;
using PerfectWorld.Scripts.Managers;
using BrewMonster.Network;
using BrewMonster.Scripts.Managers;
using BrewMonster.Scripts;
using CSNetwork.GPDataType;
using System.Runtime.InteropServices;
namespace PerfectWorld.Scripts.Managers
{
/// <summary>
/// Task Normal Matter Item.(non interactable quest item). it is a part of IvtrTaskItem(C++)
/// </summary>
public class EC_IvtrTaskNmMatter : EC_IvtrItem
{
protected TASKNORMALMATTER_ESSENCE m_pDBEssence;
/// <summary>
/// Constructor for Task Normal Matter Item.
/// </summary>
/// <param name="tid">Template id</param>
/// <param name="expire_date">Expire date</param>
public EC_IvtrTaskNmMatter(int tid, int expire_date) : base(tid, expire_date)
{
m_iCID = (int)InventoryClassId.ICID_TASKNMMATTER;
// Get database data
elementdataman pDB = ElementDataManProvider.GetElementDataMan();
DATA_TYPE DataType = DATA_TYPE.DT_INVALID;
m_pDBEssence = (TASKNORMALMATTER_ESSENCE)pDB.get_data_ptr((uint)tid, ID_SPACE.ID_SPACE_ESSENCE, ref DataType);
m_iPileLimit = m_pDBEssence.pile_num_max;
m_iPrice = m_pDBEssence.price;
m_iShopPrice = m_pDBEssence.shop_price;
m_iProcType = (int)m_pDBEssence.proc_type;
m_bNeedUpdate = false;
}
public EC_IvtrTaskNmMatter(EC_IvtrTaskNmMatter other) : base(other)
{
m_pDBEssence = other.m_pDBEssence;
}
public override bool SetItemInfo(byte[] pInfoData, int iDataLen)
{
base.SetItemInfo(pInfoData, iDataLen);
return true;
}
// Get item icon file name
public override string GetIconFile()
{
return m_pDBEssence.FileIcon;
}
// Get item description text
protected override string GetNormalDesc(bool bRepair)
{
m_strDesc = string.Empty;
// Try to build item description
CECStringTab pDescTab = EC_Game.GetItemDesc();
int white = (int)DescriptipionMsg.ITEMDESC_COL_WHITE;
int namecol = DecideNameCol();
if (m_iCount > 1)
AddDescText(namecol, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_NAMENUMBER), GetName(), m_iCount);
else
AddDescText(namecol, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_NAME), GetName());
AddIDDescText();
AddExpireTimeDesc();
// Price
AddPriceDesc(white, bRepair);
// Extend description
AddExtDescText();
return m_strDesc;
}
public override string GetDropModel()
{
return m_pDBEssence.FileMatter;
}
}
}
@@ -1,15 +0,0 @@
using BrewMonster.Scripts.Managers;
namespace PerfectWorld.Scripts.Managers
{
public class EC_IvtrTaskmatter : EC_IvtrItem
{
public EC_IvtrTaskmatter(int tid, int expire_date) : base(tid, expire_date)
{
}
public EC_IvtrTaskmatter(EC_IvtrTaskmatter other) : base(other)
{
}
}
}
@@ -1,2 +0,0 @@
fileFormatVersion: 2
guid: ee5181c9a0786409fb452d21d947eab7
@@ -3,6 +3,11 @@ namespace PerfectWorld.Scripts.Managers
{
public class EC_IvtrTossMat : EC_IvtrItem
{
/// <summary>
/// Not create logic yet (add summary later)
/// </summary>
/// <param name="tid">Template id</param>
/// <param name="expire_date">Expire date</param>
public EC_IvtrTossMat(int tid, int expire_date) : base(tid, expire_date)
{
}
@@ -1,15 +1,95 @@
using BrewMonster;
using ModelRenderer.Scripts.GameData;
using BrewMonster.Network;
using BrewMonster.Scripts.Managers;
using BrewMonster.Scripts;
using CSNetwork.GPDataType;
namespace PerfectWorld.Scripts.Managers
{
public class EC_IvtrTownscroll : EC_IvtrItem
/// <summary>
/// Town scroll item class (hoi thanh phu). It is a part of EC_IvtrScroll(c++)
/// TownScroll allow player to teleport to towns inside one map.
/// </summary>
public class EC_IvtrTownScroll : EC_IvtrItem
{
public EC_IvtrTownscroll(int tid, int expire_date) : base(tid, expire_date)
protected TOWNSCROLL_ESSENCE m_pDBEssence;
/// <summary>
/// Constructor for Town Scroll
/// </summary>
/// <param name="tid">Template id</param>
/// <param name="expire_date">Expire date</param>
public EC_IvtrTownScroll(int tid, int expire_date) : base(tid, expire_date)
{
m_iCID = (int)InventoryClassId.ICID_TOWNSCROLL;
// Get database data
elementdataman pDB = ElementDataManProvider.GetElementDataMan();
DATA_TYPE DataType = DATA_TYPE.DT_INVALID;
m_pDBEssence = (TOWNSCROLL_ESSENCE)pDB.get_data_ptr((uint)tid, ID_SPACE.ID_SPACE_ESSENCE, ref DataType);
m_iPileLimit = m_pDBEssence.pile_num_max;
m_iPrice = m_pDBEssence.price;
m_iShopPrice = m_pDBEssence.shop_price;
m_iProcType = (int)m_pDBEssence.proc_type;
m_i64EquipMask = 0;
m_bUseable = true;
m_dwUseFlags = (uint)UseCondition.USE_PERSIST;
m_bNeedUpdate = false;
}
public EC_IvtrTownscroll(EC_IvtrTownscroll other) : base(other)
public EC_IvtrTownScroll(EC_IvtrTownScroll other) : base(other)
{
m_pDBEssence = other.m_pDBEssence;
}
public override bool SetItemInfo(byte[] pInfoData, int iDataLen)
{
base.SetItemInfo(pInfoData, iDataLen);
return true;
}
public override string GetIconFile()
{
return m_pDBEssence.FileIcon;
}
// Get item cool time
public int GetCoolTime(ref int piMax)
{
CECHostPlayer pHost = EC_Game.GetGameRun().GetHostPlayer();
return pHost ? pHost.GetCoolTime((int)CoolTimeIndex.GP_CT_TOWNSCROLL, ref piMax) : 0;
}
protected override string GetNormalDesc(bool bRepair)
{
m_strDesc = string.Empty;
// Try to build item description
CECStringTab pDescTab = EC_Game.GetItemDesc();
int white = (int)DescriptipionMsg.ITEMDESC_COL_WHITE;
int namecol = DecideNameCol();
if (m_iCount > 1)
AddDescText(namecol, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_NAMENUMBER), GetName(), m_iCount);
else
AddDescText(namecol, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_NAME), GetName());
AddIDDescText();
AddExpireTimeDesc();
// Price
AddPriceDesc(white, bRepair);
// Extend description
AddExtDescText();
return m_strDesc;
}
// Get drop model for shown
public override string GetDropModel()
{
return m_pDBEssence.FileMatter;
}
}
}
@@ -1,14 +1,104 @@
using BrewMonster;
using ModelRenderer.Scripts.GameData;
using BrewMonster.Network;
using BrewMonster.Scripts.Managers;
using BrewMonster.Scripts;
using CSNetwork.GPDataType;
namespace PerfectWorld.Scripts.Managers
{
/// <summary>
/// Transmit scroll item(Da dich chuyen). It is a part of EC_IvtrConsume(c++)
/// TransmitScroll allow player to teleport to other maps' towns.
/// </summary>
public class EC_IvtrTransmitScroll : EC_IvtrItem
{
protected TRANSMITSCROLL_ESSENCE m_pDBEssence;
/// <summary>
/// Constructor for Transmit Scroll
/// </summary>
/// <param name="tid">Template id</param>
/// <param name="expire_date">Expire date</param>
public EC_IvtrTransmitScroll(int tid, int expire_date) : base(tid, expire_date)
{
m_iCID = (int)InventoryClassId.ICID_TRANSMITSCROLL;
// Get database data
elementdataman pDB = ElementDataManProvider.GetElementDataMan();
DATA_TYPE DataType = DATA_TYPE.DT_INVALID;
m_pDBEssence = (TRANSMITSCROLL_ESSENCE)pDB.get_data_ptr((uint)tid, ID_SPACE.ID_SPACE_ESSENCE, ref DataType);
m_iPileLimit = m_pDBEssence.pile_num_max;
m_iPrice = m_pDBEssence.price;
m_iShopPrice = m_pDBEssence.shop_price;
m_iProcType = (int)m_pDBEssence.proc_type;
m_i64EquipMask = 0;
m_bUseable = true;
m_dwUseFlags = (uint)UseCondition.USE_PERSIST;
m_bNeedUpdate = false;
}
public EC_IvtrTransmitScroll(EC_IvtrTransmitScroll other) : base(other)
{
m_pDBEssence = other.m_pDBEssence;
}
public override bool SetItemInfo(byte[] pInfoData, int iDataLen)
{
base.SetItemInfo(pInfoData, iDataLen);
return true;
}
public override string GetIconFile()
{
return m_pDBEssence.FileIcon;
}
public int GetCoolTime(ref int piMax)
{
CECHostPlayer pHost = EC_Game.GetGameRun().GetHostPlayer();
if (!pHost)
return 0;
int iTime = pHost.GetCoolTime((int)CoolTimeIndex.GP_CT_TOWNSCROLL, ref piMax);
return iTime;
}
protected override string GetNormalDesc(bool bRepair)
{
m_strDesc = string.Empty;
// Try to build item description
CECStringTab pDescTab = EC_Game.GetItemDesc();
int white = (int)DescriptipionMsg.ITEMDESC_COL_WHITE;
int namecol = DecideNameCol();
if (m_iCount > 1)
AddDescText(namecol, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_NAMENUMBER), GetName(), m_iCount);
else
AddDescText(namecol, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_NAME), GetName());
AddIDDescText();
AddExpireTimeDesc();
// Price
AddPriceDesc(white, bRepair);
// Extend description
AddExtDescText();
return m_strDesc;
}
// Get drop model for shown
public override string GetDropModel()
{
return m_pDBEssence.FileMatter;
}
// Check item use condition
public override bool CheckUseCondition()
{
if( EC_Game.GetGameRun().GetHostPlayer().IsFighting() )
return false;
return true;
}
}
}
@@ -1,4 +1,5 @@
using System;
using System.Runtime.InteropServices;
using UnityEngine;
using ModelRenderer.Scripts.GameData;
using BrewMonster;
@@ -68,7 +69,6 @@ namespace BrewMonster.Scripts.Managers
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();
@@ -86,23 +86,30 @@ namespace BrewMonster.Scripts.Managers
};
public struct IVTR_ESSENCE_ARROW
{
// TODO : implement data later
// DWORD dwBowMask;
// int iDamage;
// int iDamageScale;
// int iWeaponReqLow;
// int iWeaponReqHigh;
public int dwBowMask;
public int iDamage;
public int iDamageScale;
public int iWeaponReqLow;
public int iWeaponReqHigh;
public IVTR_ESSENCE_ARROW(byte[] data)
{
CECDataReader dr = new (data, data.Length);
dwBowMask = dr.ReadInt();
iDamage = dr.ReadInt();
iDamageScale = dr.ReadInt();
iWeaponReqLow = dr.ReadInt();
iWeaponReqHigh = dr.ReadInt();
}
};
public struct IVTR_ESSENCE_DECORATION
{
int damage;
int magic_damage;
int defense;
int armor;
int[] resistance;
public int damage;
public int magic_damage;
public int defense;
public int armor;
public int[] resistance;
public IVTR_ESSENCE_DECORATION(byte[] data)
{
Debug.Log("IVTR_ESSENCE_DECORATION: data.Length: " + data.Length);
CECDataReader dr = new (data, data.Length);
damage = dr.ReadInt();
magic_damage = dr.ReadInt();
@@ -140,10 +147,16 @@ namespace BrewMonster.Scripts.Managers
};
public struct IVTR_ESSENCE_FASHION
{
// TODO : implement data later
// int require_level;
// unsigned short color;
// unsigned short gender;
public int require_level;
public ushort color;
public ushort gender;
public IVTR_ESSENCE_FASHION(byte[] data)
{
CECDataReader dr = new (data, data.Length);
require_level = dr.ReadInt();
color = dr.ReadUShort();
gender = dr.ReadUShort();
}
};
public struct IVTR_ESSENCE_FLYSWORD
{
@@ -168,33 +181,65 @@ namespace BrewMonster.Scripts.Managers
};
public struct IVTR_ESSENCE_AUTOHP
{
// TODO : implement data later
// int hp_left;
// float trigger;
public int hp_left;
public float trigger;
public IVTR_ESSENCE_AUTOHP(byte[] data)
{
CECDataReader dr = new (data, data.Length);
hp_left = dr.ReadInt();
trigger = dr.ReadFloat();
}
};
public struct IVTR_ESSENCE_AUTOMP
{
// TODO : implement data later
// int mp_left;
// float trigger;
public int mp_left;
public float trigger;
public IVTR_ESSENCE_AUTOMP(byte[] data)
{
CECDataReader dr = new (data, data.Length);
mp_left = dr.ReadInt();
trigger = dr.ReadFloat();
}
};
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 int req_level;
public int req_class;
public int honor_point;
public int pet_tid;
public int pet_vis_tid;
public int pet_egg_tid;
public int pet_class;
public short level;
public ushort color;
public int exp;
public int skill_point;
public ushort name_len;
public ushort skill_count;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
public ushort[] name;
public IVTR_ESSENCE_PETEGG(byte[] data)
{
CECDataReader dr = new (data, data.Length);
req_level = dr.ReadInt();
req_class = dr.ReadInt();
honor_point = dr.ReadInt();
pet_tid = dr.ReadInt();
pet_vis_tid = dr.ReadInt();
pet_egg_tid = dr.ReadInt();
pet_class = dr.ReadInt();
level = dr.ReadShort();
color = dr.ReadUShort();
exp = dr.ReadInt();
skill_point = dr.ReadInt();
name_len = dr.ReadUShort();
skill_count = dr.ReadUShort();
name = new ushort[8];
for(int i = 0; i < 8; i++)
{
name[i] = dr.ReadUShort();
}
}
};
public struct IVTR_ESSENCE_DESTROYING
{
@@ -203,22 +248,54 @@ namespace BrewMonster.Scripts.Managers
};
public struct IVTR_ESSENCE_GOBLIN
{
struct _GOBLIN_DATA
public 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;
};
public uint exp;
public short level;
public short total_attribute;
public short strength;
public short agility;
public short vitality;
public short energy;
public short total_genius;
public short[] genius ;
public short refine_level;
public int stamina;
public int status_value;
public _GOBLIN_DATA(byte[] data)
{
CECDataReader dr = new (data, data.Length);
exp = dr.ReadUInt();
level = dr.ReadShort();
total_attribute = dr.ReadShort();
strength = dr.ReadShort();
agility = dr.ReadShort();
vitality = dr.ReadShort();
energy = dr.ReadShort();
total_genius = dr.ReadShort();
genius = new short[5];
for(int i = 0; i < 5; i++)
{
genius[i] = dr.ReadShort();
}
refine_level = dr.ReadShort();
stamina = dr.ReadInt();
status_value = dr.ReadInt();
}
}
public _GOBLIN_DATA data;
public int equip_cnt;
public int skill_cnt;
public IVTR_ESSENCE_GOBLIN(byte[] data)
{
CECDataReader dr = new (data, data.Length);
// Calculate size manually: uint(4) + 7*short(14) + short[5](10) + short(2) + 2*int(8) = 40 bytes
const int GOBLIN_DATA_SIZE = 40;
this.data = new _GOBLIN_DATA(dr.ReadData(GOBLIN_DATA_SIZE));
equip_cnt = dr.ReadInt();
skill_cnt = dr.ReadInt();
}
// TODO : implement data later
// _GOBLIN_DATA data;
@@ -3,6 +3,11 @@ namespace PerfectWorld.Scripts.Managers
{
public class EC_IvtrUnionscroll : EC_IvtrItem
{
/// <summary>
/// Not create logic yet (add summary later)
/// </summary>
/// <param name="tid">Template id</param>
/// <param name="expire_date">Expire date</param>
public EC_IvtrUnionscroll(int tid, int expire_date) : base(tid, expire_date)
{
}
@@ -3,6 +3,11 @@ namespace PerfectWorld.Scripts.Managers
{
public class EC_IvtrUniversalToken : EC_IvtrItem
{
/// <summary>
/// Not create logic yet (add summary later)
/// </summary>
/// <param name="tid">Template id</param>
/// <param name="expire_date">Expire date</param>
public EC_IvtrUniversalToken(int tid, int expire_date) : base(tid, expire_date)
{
}
@@ -3,6 +3,11 @@ namespace PerfectWorld.Scripts.Managers
{
public class EC_IvtrUnknown : EC_IvtrItem
{
/// <summary>
/// Not create logic yet (add summary later)
/// </summary>
/// <param name="tid">Template id</param>
/// <param name="expire_date">Expire date</param>
public EC_IvtrUnknown(int tid, int expire_date) : base(tid, expire_date)
{
}
@@ -3,6 +3,11 @@ namespace PerfectWorld.Scripts.Managers
{
public class EC_IvtrWarTankCallin : EC_IvtrItem
{
/// <summary>
/// Not create logic yet (add summary later)
/// </summary>
/// <param name="tid">Template id</param>
/// <param name="expire_date">Expire date</param>
public EC_IvtrWarTankCallin(int tid, int expire_date) : base(tid, expire_date)
{
}
@@ -64,7 +64,9 @@ using BrewMonster.Scripts;
namespace PerfectWorld.Scripts.Managers
{
/// <summary>
/// Weapon item class (cac loai vu khi)
/// </summary>
public class EC_IvtrWeapon : EC_IvtrEquip
{
//Attributes
@@ -75,6 +77,10 @@ namespace PerfectWorld.Scripts.Managers
protected WEAPON_SUB_TYPE m_pDBSubType;
protected WEAPON_ESSENCE m_pDBEssence;
/// <summary>
/// Constructor for weapon item (cac loai vu khi)
/// </summary>
/// <param name="tid">Template id</param>
public EC_IvtrWeapon(int tid, int expire_date) : base(tid, expire_date)
{
m_iCID = (int)InventoryClassId.ICID_WEAPON;
@@ -126,7 +132,6 @@ namespace PerfectWorld.Scripts.Managers
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)
{
@@ -206,7 +211,6 @@ namespace PerfectWorld.Scripts.Managers
// 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
@@ -293,7 +297,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_pDBSubType.name.ToString());
AddDescText(white, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_CLASSNAME), m_pDBSubType.Name);
// Weapon level
AddDescText(-1, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_LEVEL), m_Essence.weapon_level);
// Attack speed
@@ -3,6 +3,11 @@ namespace PerfectWorld.Scripts.Managers
{
public class EC_IvtrWeddingBookCard : EC_IvtrEquip
{
/// <summary>
/// Not create logic yet (add summary later)
/// </summary>
/// <param name="tid">Template id</param>
/// <param name="expire_date">Expire date</param>
public EC_IvtrWeddingBookCard(int tid, int expire_date) : base(tid, expire_date)
{
}
@@ -3,6 +3,11 @@ namespace PerfectWorld.Scripts.Managers
{
public class EC_IvtrWeddingInviteCard : EC_IvtrEquip
{
/// <summary>
/// Not create logic yet (add summary later)
/// </summary>
/// <param name="tid">Template id</param>
/// <param name="expire_date">Expire date</param>
public EC_IvtrWeddingInviteCard(int tid, int expire_date) : base(tid, expire_date)
{
}
@@ -3,6 +3,11 @@ namespace PerfectWorld.Scripts.Managers
{
public class EC_IvtrWing : EC_IvtrEquip
{
/// <summary>
/// Not create logic yet (add summary later)
/// </summary>
/// <param name="tid">Template id</param>
/// <param name="expire_date">Expire date</param>
public EC_IvtrWing(int tid, int expire_date) : base(tid, expire_date)
{
}
@@ -0,0 +1,121 @@
using CSNetwork.GPDataType;
using PerfectWorld.Scripts;
using BrewMonster;
using BrewMonster.Scripts;
public struct PETSKILL
{
public int idSkill;
public int iLevel;
public int iCoolCnt;
public int iCoolMax;
};
public enum SkillType
{
EM_SKILL_DEFAULT = 0, // Ը
EM_SKILL_NORMAL, // ͨ
EM_SKILL_NATURE, // Ը
EM_SKILL_SPECIAL, // ר
}
public class EC_PetCorral
{
public enum MaxSlotNum
{
MAX_SLOTNUM = 20, // ͨ
MAX_SLOTNUM2 = 21, // г
};
// Moving mode
public enum MoveMode
{
MOVE_FOLLOW = 0,
MOVE_STAND,
};
// Attacking mode
public enum AttackMode
{
ATK_DEFENSE = 0,
ATK_POSITIVE,
ATK_PASSIVE,
};
protected int m_iIntimacy; // øж
protected int m_iHunger; //
protected int m_tid; // ģID
protected int m_tidVis; // ģIDΪ0ʾɼID
protected int m_idEgg; // ID
protected int m_iClass; // սͳ
protected float m_fHPFactor; // Ѫջʱʹã 0Ϊ
protected float m_fMPFactor; // MPջʱʹã 0Ϊ
protected int m_iLevel; //
protected bool m_isBind; // Ƿ˺һ
protected bool m_canWebTrade; // ǷѰɽ
protected ushort m_color; // ȾɫɫλΪ1ʱЧ
protected int m_iExp; // ﵱǰ
protected int m_iSkillPt; // ʣܵ
protected string m_strName;
protected int m_iHP; // Only fight pets have this
protected int m_iMP;
protected PETSKILL[] m_aSkills = new PETSKILL[(int)GP_PET_SKILL_NUM.GP_PET_SKILL_NUM];
protected int[] m_vecNorSkillIndex; // ֹԸܺͨ˳ҵ m_aSkills
protected int[] m_vecDynSkillIndex;
protected int m_iSpecialSkillIndex; // רm_aSkillsţֻнһ˼
protected CECCounter m_cntAutoSkill;
protected int[] m_aAutoSkills;
protected ROLEEXTPROP m_ExtProps;
protected PET_ESSENCE m_pDBEssence = new PET_ESSENCE();
protected int m_iAtkRation;
protected int m_iDefRation;
protected int m_iHpRation;
protected int m_iAtkLvlRation;
protected int m_iDefLvlRation;
protected int m_iNature;
public CECPetData GetActivePet()
{
//Place holder for ivtrPetFood
return null;
}
}
public class CECPetData
{
#region enum
public enum HungerLevel
{
HUNGER_LEVEL_0, // ʳ
HUNGER_LEVEL_1, //
HUNGER_LEVEL_2, // ̶һ
HUNGER_LEVEL_3,
HUNGER_LEVEL_4, // ̶ȶ
HUNGER_LEVEL_5,
HUNGER_LEVEL_6,
HUNGER_LEVEL_7, // ̶
HUNGER_LEVEL_8,
HUNGER_LEVEL_9,
HUNGER_LEVEL_10,
HUNGER_LEVEL_11, // ̶ļ
HUNGER_LEVEL_COUNT,
};
// Intimacy level
public enum IntimacyLevel
{
INTIMACY_LEVEL_0, // Ұѱ, 0-50
INTIMACY_LEVEL_1, // ޳, 51-150
INTIMACY_LEVEL_2, // , 151-500
INTIMACY_LEVEL_3, // Ĺ, 501-999
INTIMACY_LEVEL_COUNT,
INTIMACY_POINT_MAX = 999,
};
#endregion
public int GetTemplateID()
{
//Place holder for ivtrPetFood
return -1;
}
}
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: c41c880dbc2344f819944899348d5124
@@ -1891,4 +1891,18 @@ namespace BrewMonster
public static byte SKIN_FASHION_FOOT_INDEX = 9;
public static byte NUM_SKIN_INDEX = 10;
}
public enum enumSkinShow
{
enumSkinShowNone = 0,
enumSkinShowUpperBody,
enumSkinShowWrist,
enumSkinShowLowerBody,
enumSkinShowFoot,
enumSkinShowUpperAndLower,
enumSkinShowUpperAndWrist,
enumSkinShowLowerAndFoot,
enumSkinShowUpperLowerAndWrist,
enumSkinShowArmet,
enumSkinShowHand,
};
}
+56 -1
View File
@@ -53,7 +53,6 @@ public class CECNPC : CECObject
[SerializeField] protected NPCVisual npcVisual;
protected static CECStringTab m_ActionNames;
/* public string NameNPC => m_strName;
public string ROLEBASICPROP => m_strName;*/
@@ -69,6 +68,54 @@ public class CECNPC : CECObject
m_pNPCModelPolicy = new CECNPCModelDefaultPolicy(this);
}
// Add this field to CECNPC class
private bool m_bHasRelatedTask = false;
private float _timerCheckTask = 0;
public void UpdateTaskIcon()
{
// Check if npcUI is assigned
if (m_npcUI == null)
{
m_npcUI = GetComponentInChildren<UINPC>();
if (m_npcUI == null) return;
}
// 2. Get Host Player & Interface
var host = CECGameRun.Instance.GetHostPlayer();
if (host == null) return;
var taskInterface = host.GetTaskInterface();
if (taskInterface == null)
{
if (m_bHasRelatedTask) // only update if state changed
{
m_npcUI.SetTaskIconMain(false);
m_bHasRelatedTask = false;
}
return;
}
// Get NPC Template ID
int npcTemplateID = m_NPCInfo.tid;
// Check if there are tasks related to this NPC
bool hasTask = taskInterface.HasTaskRelatedToNPC(npcTemplateID);
// Update icon only if state changed
if (m_bHasRelatedTask != hasTask)
{
m_bHasRelatedTask = hasTask;
m_npcUI.SetTaskIconMain(hasTask);
if (hasTask)
{
Debug.Log($"[Icon] NPC {m_strName} (TID: {npcTemplateID})");
}
}
}
public string GetName()
{
return m_strName;
@@ -180,6 +227,7 @@ public class CECNPC : CECObject
new Vector2(pHost.transform.position.x, pHost.transform.position.z));
}
UpdateTaskIcon();
return true;
}
@@ -513,6 +561,13 @@ public class CECNPC : CECObject
{
StartAdjustTransparency(-1.0f, GetTransparentLimit(), 500);
}
_timerCheckTask += Time.deltaTime;
if (_timerCheckTask > 1.0f)
{
_timerCheckTask = 0;
UpdateTaskIcon();
}
}
private void TickWork_Dead(float deltaTime)
@@ -57,6 +57,8 @@ public class CECNPCServer : CECNPC
transform.position = EC_Utility.ToVector3(info.pos);
StartWork((int)WorkType.WT_NOTHING, (int)WorkID.WORK_STAND);
UpdateTaskIcon();
return true;
}
@@ -1574,11 +1574,15 @@ namespace CSNetwork.S2CCommand
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct cmd_embed_item
{
// unsigned char chip_idx;
// unsigned char equip_idx;
public uint chip_idx;
public uint equip_idx;
};
public int chip_idx;
public int equip_idx;
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct cmd_get_item_info
{
public byte byPackage;
public int bySlot;
}
}
// Player and NPC state
@@ -910,5 +910,12 @@ namespace CSNetwork.C2SCommand
content
);
}
public static Octets CreateGetItemInfoCmd(byte byPackage, int bySlot)
{
cmd_get_item_info pCmd = new cmd_get_item_info();
pCmd.byPackage = byPackage;
pCmd.bySlot = bySlot;
return SerializeCommand(CommandID.QUERY_MAFIA_PVP_INFO, pCmd);
}
}
}
@@ -2195,5 +2195,89 @@ namespace CSNetwork.GPDataType
return buf_size >= sz;
}
};
// Pet type
public enum GP_PET_TYPE
{
GP_PET_CLASS_INVALID = -1,
GP_PET_CLASS_MOUNT = 0, //
GP_PET_CLASS_COMBAT, // ս
GP_PET_CLASS_FOLLOW, //
GP_PET_CLASS_SUMMON, // ٻ
GP_PET_CLASS_PLANT, // ֲֻΪ˺ͷֵһ£ͻûõ
GP_PET_CLASS_EVOLUTION, //
GP_PET_CLASS_MAX,
};
public struct PetSkill
{
public int skill;
public int level;
}
public struct _evo_prop
{
public int r_attack;
public int r_defense;
public int r_hp;
public int r_atk_lvl;
public int r_def_lvl;
public int nature;
}
public enum GP_PET_SKILL_NUM
{
GP_PET_SKILL_NUM = 8
};
public struct info_pet
{
public int honor_point; // øж
public int hunger; //
public int feed_time; // ϴιڵʱ
public int pet_tid; // ģID
public int pet_vis_tid; // ĿɼIDΪ0ʾɼID
public int pet_egg_tid; // ID
public int pet_class; // սͳ
public float hp_factor; // Ѫջʱʹã 0Ϊ
public short level; //
public ushort color; // ɫλΪ1ʾЧĿǰЧ
public int exp; // ﵱǰ
public int skill_point; // ʣܵ
public char is_bind; // Ƿ˺һһMask0x01 ˺һ0x02 Ѱɽ
public char unused; // ĿǰЧ
public ushort name_len; // ֳ ĿǰЧΪ߻
public char[] name; //
public PetSkill[] skills;
public _evo_prop evo_prop;
public int[] reserved; // δ
public info_pet(bool isDefault = true)
{
honor_point = 0;
hunger = 0;
feed_time = 0;
pet_tid = 0;
pet_vis_tid = 0;
pet_egg_tid = 0;
pet_class = 0;
hp_factor = 0;
level = 0;
color = 0;
exp = 0;
skill_point = 0;
is_bind = (char)0x00;
unused = (char)0x00;
name_len = 0;
name = new char[16];
skills = new PetSkill[(int)GP_PET_SKILL_NUM.GP_PET_SKILL_NUM];
evo_prop = new _evo_prop{
r_attack = 0,
r_defense = 0,
r_hp = 0,
r_atk_lvl = 0,
r_def_lvl = 0,
nature = 0
};
reserved = new int[10];
}
};
}
@@ -842,6 +842,9 @@ namespace CSNetwork
BMLogger.LogError("### GameDataSend: LEARN_SKILL");
EC_ManMessage.PostMessage(EC_MsgDef.MSG_HST_LEARNSKILL, MANAGER_INDEX.MAN_PLAYER, 0, pDataBuf, pCmdHeader);
break;
case CommandID.EMBED_ITEM:
EC_ManMessage.PostMessage(EC_MsgDef.MSG_HST_EMBEDITEM, MANAGER_INDEX.MAN_PLAYER, 0, pDataBuf, pCmdHeader);
break;
default:
#if UNITY_EDITOR
if (isDebug)
@@ -1523,5 +1526,11 @@ namespace CSNetwork
gamedatasend.Data = C2SCommandFactory.CreateNPCSevEmbedCmd(wStoneIdx, wEquipIdx, tidStone, tidEquip);
SendProtocol(gamedatasend);
}
public void c2s_SendCmdGetItemInfo(byte byPackage, int bySlot)
{
gamedatasend gamedatasend = new gamedatasend();
gamedatasend.Data = C2SCommandFactory.CreateGetItemInfoCmd(byPackage, bySlot);
SendProtocol(gamedatasend);
}
}
}
@@ -445,5 +445,9 @@ namespace BrewMonster.Network
{
Instance._gameSession.c2s_SendCmdNPCSevEmbed(wStoneIdx, wEquipIdx, tidStone, tidEquip);
}
public static void c2s_CmdGetItemInfo(byte byPackage, int bySlot)
{
Instance._gameSession.c2s_SendCmdGetItemInfo(byPackage, bySlot);
}
}
}
@@ -187,7 +187,7 @@ namespace BrewMonster.Scripts.Skills
{
s = SkillStub.GetStub(id);
if (s != null)
return s.GetName();
return s.GetIcon();
return "";
}
// ˵
@@ -425,5 +425,59 @@ namespace BrewMonster.Scripts.Skills
return ret;
}
// 0:ɹ 1:SP 2:
// 3: 4:ܸ 5:ID
// 6:Ǯ 7:С 8:ûм
// 9:ȼ 10:޲ 11:ְҵƥ
// 12:޲ְҵƥ
public static int GoblinLearn(uint id, GoblinRequirement info, int level)
{
Skill s = Skill.Create(id, level);
if(s == null)
return 5;
if(level<1 || level> s.GetMaxLevel())
return 3;
if(s.GetCls() != 258)
return 7;
int ret = 0;
int[] iReqGen = new int[5] {0, 0, 0, 0, 0};
int iReqLevel = s.GetRequiredLevel();
// iReqLevelΪ7λλΪȼǰ5λΪλΪ
int iLevelRequirement = iReqLevel%100;
if(info.level < iLevelRequirement)
return 9;
iReqLevel /= 100;
int i;
for(i=0;i<5;i++)
{
iReqGen[4-i] = iReqLevel%10;
iReqLevel /= 10;
}
for(i=0;i<5;i++)
{
if(info.genius[i] < iReqGen[4-i])
return 2;
}
if(info.sp < s.GetRequiredSp())
ret = 1;
//else if(info.money<s->GetRequiredMoney(id, level))
// ret = 6;
if(info.mp < s.GetMpCost() &&
((s.GetCls() != 0) && (((1 << info.profession) & s.GetCls()) == 0)))
ret = 12;
else if(info.mp < s.GetMpCost())
ret = 10;
else if((s.GetCls() != 0) && (((1 << info.profession) & s.GetCls()) == 0))
ret = 11;
return ret;
}
}
}
@@ -300,6 +300,97 @@ namespace BrewMonster.Scripts.Task
return tasks;
}
// Add this method to ATaskTemplMan class if not exists
public List<ATaskTempl> GetAllTopTasks()
{
List<ATaskTempl> topTasks = new List<ATaskTempl>();
// Iterate through all task templates and collect top-level tasks
// Assuming you have a dictionary or collection of all tasks
foreach (var kvp in m_TaskTemplMap) // Replace with your actual collection name
{
var templ = kvp.Value;
if (templ != null && templ.m_pParent == null) // Top-level task has no parent
{
topTasks.Add(templ);
}
}
return topTasks;
}
// Alternative method if you want to check by NPC ID directly
public List<ATaskTempl> GetAvailableTasksForNPC(int npcID)
{
List<ATaskTempl> availableTasks = new List<ATaskTempl>();
foreach (var kvp in m_TaskTemplMap) // Replace with your actual collection name
{
var templ = kvp.Value;
if (templ != null &&
templ.m_pParent == null &&
templ.m_FixedData.m_ulDelvNPC == npcID)
{
availableTasks.Add(templ);
}
}
return availableTasks;
}
// Add this method to ATaskTemplMan class
/// <summary>
/// Get all task templates (for iterating to find available tasks)
/// Lấy tất cả task templates (để duyệt tìm nhiệm vụ có thể nhận)
/// </summary>
public List<ATaskTempl> GetAllTaskTemplates()
{
List<ATaskTempl> allTasks = new List<ATaskTempl>();
// Assuming you have a collection storing all task templates
// Replace m_TaskMap with your actual collection name
if (m_TaskTemplMap != null)
{
foreach (var kvp in m_TaskTemplMap)
{
if (kvp.Value != null)
{
allTasks.Add(kvp.Value);
}
}
}
return allTasks;
}
/// <summary>
/// Get list of tasks delivered by a specific NPC
/// </summary>
public List<ATaskTempl> GetTasksFromNPC(int npcID)
{
var result = new List<ATaskTempl>();
// Check if NPC info map is available
if (m_NPCInfoMap != null && m_NPCInfoMap.TryGetValue((uint)npcID, out var npcInfo))
{
return new List<ATaskTempl>();
}
else
{
// Fallback
foreach (var kvp in m_TaskTemplMap)
{
var templ = kvp.Value;
if (templ != null && templ.m_FixedData.m_ulDelvNPC == npcID)
{
result.Add(templ);
}
}
}
return result;
}
// General method to read a struct from a FileStream
private T ReadStruct<T>(FileStream stream) where T : struct
@@ -1,17 +1,19 @@
using BrewMonster.Managers;
using BrewMonster.Network;
using BrewMonster.Scripts; // For CECNavigateCtrl
using BrewMonster.UI;
using CSNetwork;
using CSNetwork.GPDataType;
using Cysharp.Threading.Tasks;
using PerfectWorld.Scripts.Task;
using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.InteropServices;
using System.Threading;
using BrewMonster.UI;
using CSNetwork;
using Cysharp.Threading.Tasks;
using UnityEngine;
using UnityEngine.Networking;
using System;
using BrewMonster.Scripts; // For CECNavigateCtrl
using static BrewMonster.TASKDICE_ESSENCE;
namespace BrewMonster.Scripts.Task
{
@@ -528,85 +530,164 @@ namespace BrewMonster.Scripts.Task
{
return m_pActiveListBuf;
}
// private void InitActiveTaskList()
// {
// ActiveTaskList pLst = GetActiveTaskList();
// if (pLst == null) return;
//
// ATaskTemplMan pMan = GetTaskTemplMan();
// if (pMan == null) return;
//
// // reset counters
// pLst.m_uTopShowTaskCount = 0;
// pLst.m_uTopHideTaskCount = 0;
// pLst.m_uTitleTaskCount = 0;
//
// byte i = 0;
// while (i < pLst.m_uTaskCount)
// {
// ActiveTaskEntry entry = pLst.m_TaskEntries[i];
// if (entry == null)
// {
// i++;
// continue;
// }
//
// // repair sibling linkage
// if (entry.m_NextSblIndex != (char)0xff)
// {
// ActiveTaskEntry entryNextSbl = pLst.m_TaskEntries[entry.m_NextSblIndex];
// if (entryNextSbl == null || entryNextSbl.m_PrevSblIndex != (char)i)
// {
// entry.m_NextSblIndex = (char)0xff;
// }
// }
//
// // resolve template for top-level entries; children left unresolved in C#
// if (entry.m_ParentIndex == (char)0xff)
// {
// // entry.m_ulTemplAddr = 0u;
// entry.m_ulTemplAddr = pMan.GetTopTaskByID(entry.m_ID) != null ? 1u : 0u;
//
// ATaskTempl topTempl = pMan.GetTopTaskByID(entry.m_ID);
// if (topTempl != null)
// {
// if (topTempl.m_FixedData.m_bHidden)
// pLst.m_uTopHideTaskCount++;
// else if (topTempl.m_FixedData.m_bDisplayInTitleTaskUI)
// pLst.m_uTitleTaskCount++;
// else
// pLst.m_uTopShowTaskCount++;
// }
// }
// else
// {
// entry.m_ulTemplAddr = 0u;
// }
//
// // cap template best-effort (no pointer in managed)
// if (entry.m_uCapTaskId != 0)
// {
// ATaskTempl cap = pMan.GetTopTaskByID(entry.m_uCapTaskId);
// entry.m_ulCapTemplAddr = 0u;
// if (cap == null)
// {
// entry.m_uCapTaskId = 0;
// }
// }
// else
// {
// entry.m_ulCapTemplAddr = 0u;
// }
//
// i++;
// }
//
// // approximate used count
// pLst.m_uUsedCount = pLst.m_uTaskCount;
// }
public void InitActiveTaskList()
// Trong file CECTaskInterface.cs
public bool HasTaskRelatedToNPC(int npcID)
{
// Check tasks is active
ActiveTaskList activeList = GetActiveTaskList();
if (activeList != null && activeList.m_TaskEntries != null)
{
for (int i = 0; i < activeList.m_uTaskCount; i++)
{
var entry = activeList.m_TaskEntries[i];
if (entry == null) continue;
ATaskTempl templ = entry.GetTempl();
if (templ == null) continue;
// Check if this NPC is the target of the task
if (IsNPCTargetOfTask(templ, entry, npcID))
{
return true;
}
}
}
// Check tasks new
ATaskTemplMan taskMan = GetTaskTemplMan();
if (taskMan != null)
{
List<ATaskTempl> npcTasks = taskMan.GetTasksFromNPC(npcID);
if (npcTasks != null)
{
uint ulCurTime = GetCurTime();
foreach (var templ in npcTasks)
{
// Check prerequisite
if (templ.CheckPrerequisite(this, activeList, ulCurTime) == 0)
{
return true;
}
}
}
}
return false;
}
// Check NPC is target of the task
private bool IsNPCTargetOfTask(ATaskTempl templ, ActiveTaskEntry entry, int npcID)
{
var data = templ.m_FixedData;
// Task completed case
if (entry.IsFinished())
{
if (data.m_ulAwardNPC == npcID) return true;
}
else
{
// NPC target
if (data.m_ulNPCMoving == npcID) return true;
// Pos target
if (data.m_ulNPCDestSite == npcID) return true;
// Security target
if (data.m_ulNPCToProtect == npcID) return true;
if (data.m_enumMethod == (ulong)TaskCompletionMethod.enumTMTalkToNPC)
{
if (data.m_ulNPCMoving == 0 && data.m_ulAwardNPC == npcID)
{
return true;
}
}
}
return false;
}
// private void InitActiveTaskList()
// {
// ActiveTaskList pLst = GetActiveTaskList();
// if (pLst == null) return;
//
// ATaskTemplMan pMan = GetTaskTemplMan();
// if (pMan == null) return;
//
// // reset counters
// pLst.m_uTopShowTaskCount = 0;
// pLst.m_uTopHideTaskCount = 0;
// pLst.m_uTitleTaskCount = 0;
//
// byte i = 0;
// while (i < pLst.m_uTaskCount)
// {
// ActiveTaskEntry entry = pLst.m_TaskEntries[i];
// if (entry == null)
// {
// i++;
// continue;
// }
//
// // repair sibling linkage
// if (entry.m_NextSblIndex != (char)0xff)
// {
// ActiveTaskEntry entryNextSbl = pLst.m_TaskEntries[entry.m_NextSblIndex];
// if (entryNextSbl == null || entryNextSbl.m_PrevSblIndex != (char)i)
// {
// entry.m_NextSblIndex = (char)0xff;
// }
// }
//
// // resolve template for top-level entries; children left unresolved in C#
// if (entry.m_ParentIndex == (char)0xff)
// {
// // entry.m_ulTemplAddr = 0u;
// entry.m_ulTemplAddr = pMan.GetTopTaskByID(entry.m_ID) != null ? 1u : 0u;
//
// ATaskTempl topTempl = pMan.GetTopTaskByID(entry.m_ID);
// if (topTempl != null)
// {
// if (topTempl.m_FixedData.m_bHidden)
// pLst.m_uTopHideTaskCount++;
// else if (topTempl.m_FixedData.m_bDisplayInTitleTaskUI)
// pLst.m_uTitleTaskCount++;
// else
// pLst.m_uTopShowTaskCount++;
// }
// }
// else
// {
// entry.m_ulTemplAddr = 0u;
// }
//
// // cap template best-effort (no pointer in managed)
// if (entry.m_uCapTaskId != 0)
// {
// ATaskTempl cap = pMan.GetTopTaskByID(entry.m_uCapTaskId);
// entry.m_ulCapTemplAddr = 0u;
// if (cap == null)
// {
// entry.m_uCapTaskId = 0;
// }
// }
// else
// {
// entry.m_ulCapTemplAddr = 0u;
// }
//
// i++;
// }
//
// // approximate used count
// pLst.m_uUsedCount = pLst.m_uTaskCount;
// }
public void InitActiveTaskList()
{
ActiveTaskList pLst = GetActiveTaskList();
FinishedTaskList pFnsh = GetFinishedTaskList();
@@ -1058,10 +1139,11 @@ namespace BrewMonster.Scripts.Task
// TODO: Expose account total cash on host/session
return 0u;
}
#if _TASK_CLIENT
// Prepare award preview based on task and state
public void GetTaskAwardPreview(uint ulTaskId, ref Task_Award_Preview p, bool bActiveTask=true)
// Prepare award preview based on task and state
public void GetTaskAwardPreview(uint ulTaskId, ref Task_Award_Preview p, bool bActiveTask=true)
{
// Zero and init output
p = default;
@@ -1644,7 +1726,7 @@ namespace BrewMonster.Scripts.Task
{
UnityEngine.Debug.Log($"[CECTaskInterface] OnNewTask: Task {iTaskID} is not a force navigate task (pTempl={pTempl != null}, method={pTempl?.m_FixedData.m_enumMethod})");
}
}
}
public void OnTaskConfirmUpdate()
{
@@ -1676,7 +1758,7 @@ namespace BrewMonster.Scripts.Task
{
UnityEngine.Debug.Log($"[CECTaskInterface] OnCompleteTask: Task {iTaskID} is not a force navigate task");
}
}
}
public void TakeAwayCommonItem(uint ulTemplId, uint ulNum) {}
@@ -1699,7 +1781,7 @@ namespace BrewMonster.Scripts.Task
{
UnityEngine.Debug.Log($"[CECTaskInterface] OnGiveupTask: Task {iTaskID} is not a force navigate task");
}
}
}
// Handle task text click in UI - trigger navigation if it's a force navigate task // 处理任务UI文本点击 - 如果是强制导航任务则触发导航
// This is called when user clicks on task name/link in the task UI // 当用户在任务UI中点击任务名称/链接时调用
@@ -0,0 +1,322 @@
using BrewMonster.Network;
using BrewMonster.Scripts.Managers;
using BrewMonster.Scripts.Task;
using BrewMonster.UI;
using CSNetwork;
using ModelRenderer.Scripts.Common;
using PerfectWorld.Scripts.Managers;
using PerfectWorld.Scripts.Task;
using System;
using System.Collections.Generic;
using System.Text;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
namespace BrewMonster
{
public class DlgInstall : AUIDialog
{
[Header("Slot First")]
[SerializeField] private Transform m_SlotFirstParent;
[SerializeField] private TextMeshProUGUI m_TxtFirstName;
[Header("Slot Second")]
[SerializeField] private Transform m_SlotSecondlParent;
[SerializeField] private TextMeshProUGUI m_TxtSecondName;
[Header("Buttons and Money")]
[SerializeField] private TextMeshProUGUI m_TxtMoney;
[SerializeField] private Button m_BtnInstall;
[SerializeField] private Button m_BtnCancel;
[SerializeField] private Sprite khung_item;
private EC_IvtrItem m_SelectedEquip;
private EC_IvtrItem m_SelectedMaterial;
private int m_FirstInvSlot = -1;
private int m_SecondInvSlot = -1;
public override void Awake()
{
base.Awake();
RegisterDrop(m_SlotFirstParent, OnDropEquip);
RegisterDrop(m_SlotSecondlParent, OnDropMaterial);
RegisterClick(m_SlotFirstParent, OnClickEquipSlot);
RegisterClick(m_SlotSecondlParent, OnClickMaterialSlot);
}
public void OnpenInstall(uint npcId)
{
}
public void CloseInstall()
{
gameObject.SetActive(false);
RestoreInventoryColors();
}
private void RestoreInventoryColors()
{
var canvas = FindFirstObjectByType<Canvas>();
if (canvas == null)
return;
if (m_FirstInvSlot >= 0)
{
var btn = FindInventoryButtonBySlot(m_FirstInvSlot);
SetInventorySlotGray(btn, false);
m_FirstInvSlot = -1;
}
if (m_SecondInvSlot >= 0)
{
var btn = FindInventoryButtonBySlot(m_SecondInvSlot);
SetInventorySlotGray(btn, false);
m_SecondInvSlot = -1;
}
}
private Button FindInventoryButtonBySlot(int slot)
{
var inventoryUI = FindFirstObjectByType<EC_InventoryUI>();
if (inventoryUI == null)
return null;
var field = typeof(EC_InventoryUI)
.GetField("inventoryPackButtons", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
if (field == null)
return null;
var list = field.GetValue(inventoryUI) as List<Button>;
if (list == null || slot < 0 || slot >= list.Count)
return null;
return list[slot];
}
private void RegisterDrop(Transform target, Action<PointerEventData> callback)
{
var trigger = target.GetComponent<EventTrigger>();
if (trigger == null)
trigger = target.gameObject.AddComponent<EventTrigger>();
trigger.triggers.Clear();
var entry = new EventTrigger.Entry
{
eventID = EventTriggerType.Drop
};
entry.callback.AddListener((data) =>
{
callback((PointerEventData)data);
});
trigger.triggers.Add(entry);
}
private void RegisterClick(Transform target, Action<PointerEventData> callback)
{
var trigger = target.GetComponent<EventTrigger>();
if (trigger == null)
trigger = target.gameObject.AddComponent<EventTrigger>();
var entry = new EventTrigger.Entry
{
eventID = EventTriggerType.PointerClick
};
entry.callback.AddListener((data) =>
{
callback((PointerEventData)data);
});
trigger.triggers.Add(entry);
}
private void OnClickEquipSlot(PointerEventData eventData)
{
if (m_SelectedEquip != null)
{
ReturnItemToInventory(m_FirstInvSlot);
ClearEquipSlot();
}
}
private void OnClickMaterialSlot(PointerEventData eventData)
{
if (m_SelectedMaterial != null)
{
ReturnItemToInventory(m_SecondInvSlot);
ClearMaterialSlot();
}
}
private EC_IvtrItem GetItemFromDrag(PointerEventData eventData)
{
if (eventData.pointerDrag == null)
return null;
var btn = eventData.pointerDrag.GetComponent<Button>();
if (btn == null)
return null;
// Slot index
int slotIndex = btn.transform.GetSiblingIndex();
// Inventory package = 0
var host = CECGameRun.Instance?.GetHostPlayer();
if (host == null)
return null;
var inv = host.GetInventory(0);
if (inv == null)
return null;
return inv.GetItem(slotIndex, false);
}
private void OnDropEquip(PointerEventData eventData)
{
if (eventData.pointerDrag == null)
return;
var btn = eventData.pointerDrag.GetComponent<Button>();
if (btn == null)
return;
int slotIndex = btn.transform.GetSiblingIndex();
var item = GetItemFromDrag(eventData);
if (item == null)
return;
EC_IvtrItem detailedItem = EC_IvtrItem.CreateItem(item.m_tid, item.m_expire_date, item.m_iCount);
if (item.Content != null && item.Content.Length > 0)
detailedItem.SetItemInfo(item.Content, item.Content.Length);
else
detailedItem.GetDetailDataFromLocal();
m_SelectedEquip = detailedItem;
m_FirstInvSlot = slotIndex;
m_TxtFirstName.text = detailedItem.GetName();
SetSlotIcon(m_SlotFirstParent, detailedItem);
SetInventorySlotGray(btn, true);
Debug.Log($"[Install] Equipment: {detailedItem.m_tid} from slot {slotIndex}");
}
private void OnDropMaterial(PointerEventData eventData)
{
if (eventData.pointerDrag == null)
return;
var btn = eventData.pointerDrag.GetComponent<Button>();
if (btn == null)
return;
int slotIndex = btn.transform.GetSiblingIndex();
var item = GetItemFromDrag(eventData);
if (item == null)
return;
EC_IvtrItem detailedItem = EC_IvtrItem.CreateItem(item.m_tid, item.m_expire_date, item.m_iCount);
if (item.Content != null && item.Content.Length > 0)
detailedItem.SetItemInfo(item.Content, item.Content.Length);
else
detailedItem.GetDetailDataFromLocal();
m_SelectedMaterial = detailedItem;
m_SecondInvSlot = slotIndex;
m_TxtSecondName.text = detailedItem.GetName();
SetSlotIcon(m_SlotSecondlParent, detailedItem);
SetInventorySlotGray(btn, true);
Debug.Log($"[Install] Material: {detailedItem.m_tid} from slot {slotIndex}");
}
private void SetInventorySlotGray(Button btn, bool gray)
{
if (btn == null)
return;
var img = btn.GetComponent<Image>();
if (img == null)
return;
img.color = gray
? new Color(0.3f, 0.3f, 0.3f, 1f)
: Color.white;
}
private void SetSlotIcon(Transform slot, EC_IvtrItem item)
{
if (slot == null || item == null)
return;
var img = slot.GetComponentInChildren<Image>(true);
if (img == null)
return;
img.sprite = EC_IvtrItemUtils.Instance.ResolveItemIconSprite(item.m_tid);
img.enabled = img.sprite != null;
img.color = Color.white;
img.SetNativeSize();
}
private void ReturnItemToInventory(int slotIndex)
{
if (slotIndex < 0)
return;
var btn = FindInventoryButtonBySlot(slotIndex);
SetInventorySlotGray(btn, false);
}
private void ClearEquipSlot()
{
m_SelectedEquip = null;
m_FirstInvSlot = -1;
m_TxtFirstName.text = "___";
ClearSlotIcon(m_SlotFirstParent);
Debug.Log("[Install] Equipment slot cleared");
}
private void ClearMaterialSlot()
{
m_SelectedMaterial = null;
m_SecondInvSlot = -1;
m_TxtSecondName.text = "___";
ClearSlotIcon(m_SlotSecondlParent);
Debug.Log("[Install] Material slot cleared");
}
private void ClearSlotIcon(Transform slot)
{
if (slot == null)
return;
var img = slot.GetComponentInChildren<Image>(true);
if (img == null)
return;
img.sprite = khung_item;
}
}
}
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 0785d9ccbdc425a44b6ae1f4a3afad06
@@ -3403,8 +3403,33 @@ namespace BrewMonster.UI
}
else if (idFunction == (int)SERVICE_TYPE.NPC_INSTALL)
{
pShow1 = m_pAUIManager.GetDialog("Win_Enchase");
pShow2 = m_pAUIManager.GetDialog("Win_Inventory");
if (pCurNPCEssence.HasValue)
{
uint npcID = pCurNPCEssence.Value.id;
DlgInstall dlgInstall = FindFirstObjectByType<DlgInstall>();
if (dlgInstall == null)
{
CECGameUIMan gameUIMan = GetGameUIMan();
DialogScriptTableObject dialogResource = gameUIMan.GetDialogResource();
Canvas canvas = gameUIMan.GetCanvas();
if(dialogResource != null && canvas != null)
{
GameObject ob = dialogResource.GetPrefabDialog("Win_Enchase");
if (ob != null)
{
dlgInstall = GameObject.Instantiate(ob, canvas.transform).GetComponent<DlgInstall>();
}
}
}
if(dlgInstall != null)
{
dlgInstall.OnpenInstall(npcID);
}
}
//pShow1 = m_pAUIManager.GetDialog("Win_Enchase");
//pShow2 = m_pAUIManager.GetDialog("Win_Inventory");
}
else if (idFunction == (int)SERVICE_TYPE.NPC_UNINSTALL)
{
@@ -19,6 +19,10 @@ namespace BrewMonster
int m_nCurPanel1 = 1;
int m_nCurPanel2 = 1;
/// <summary>
/// Apply for a license remove later
/// </summary>
/// <returns></returns>
public bool UpdateShortcuts()
{
CECShortcut pSC;
@@ -46,10 +50,10 @@ namespace BrewMonster
/*CDlgQuickBar* pQuickBar = dynamic_cast<CDlgQuickBar*>(GetGameUIMan()->GetDialog(a_pszPanel[i]));
if (!pQuickBar || !pQuickBar->IsShow()) continue;*/
for (int j = 0; j < AUIImagePictureList.Count; j++)
int slotIndex = 0;
for (int j = 0; j < a_pSCS.Count; j++)
{
pCell = AUIImagePictureList[j];
pCell = AUIImagePictureList[slotIndex];
pSC = a_pSCS[i].GetShortcut(j);
pClock = pCell.GetClockIcon();
pClock.SetProgressRange(0, 1);
@@ -203,7 +207,7 @@ namespace BrewMonster
{
if (pSkill != null)
{
pCell.gameObject.SetActive(true);
slotIndex++;
//BMLogger.Log("HoangDev: QuickBar Set Skill Icon: " + (uint)pSkill.GetSkillID() + " : " + ElementSkill.GetIcon((uint)pSkill.GetSkillID()));
var nameskill = ElementSkill.GetIcon((uint)pSkill.GetSkillID());
GetGameUIMan().SetCover(pCell, nameskill, EC_GAMEUI_ICONS.ICONS_SKILL);
@@ -226,6 +230,213 @@ namespace BrewMonster
}
return true;
}
/* public bool UpdateShortcuts()
{
CECShortcut pSC;
Image skillImage;
CECSCSkill pSCSkill;
int iIconFile, nMax;
AUIImagePicture pCell;
CECSkill pSkill = new CECSkill(-1, -1);
AUIClockIcon pClock;
int nCurPanel9 = GetCurPanel1();
int nCurPanel8 = GetCurPanel2();
CECHostPlayer pHost = EC_Game.GetGameRun().GetHostPlayer();
if (pHost == null) return false;
var a_pSCS = new List<CECShortcutSet>();
var a_pszPanel = new List<string>();
GetQuickBarNameAndSC(pHost, a_pszPanel, a_pSCS, nCurPanel9, nCurPanel8);
for (int i = 0; i <= 1*//*(int)a_pSCS.Count*//*; i++)
{
if (a_pSCS[i] == null)
continue;
*//*CDlgQuickBar* pQuickBar = dynamic_cast<CDlgQuickBar*>(GetGameUIMan()->GetDialog(a_pszPanel[i]));
if (!pQuickBar || !pQuickBar->IsShow()) continue;*//*
for (int j = 0; j < AUIImagePictureList.Count; j++)
{
pCell = AUIImagePictureList[j];
pSC = a_pSCS[i].GetShortcut(j);
pClock = pCell.GetClockIcon();
pClock.SetProgressRange(0, 1);
pClock.SetProgressPos(1);
if (pSC != null)
{
if (pSC.GetType() == (int)CECShortcut.ShortcutType.SCT_SKILL)
{
iIconFile = (int)EC_GAMEUI_ICONS.ICONS_SKILL;
pSCSkill = (CECSCSkill)pSC;
pSkill = pSCSkill.GetSkill();
if (false*//*m_bDelGoblinSkillSC && GNET::ElementSkill::IsGoblinSkill(pSkill->GetSkillID())*//*)
{
*//* a_pSCS[i]->SetShortcut(j, NULL);
pSC = NULL;*//*
}
else
{
if (pSkill != null && pSkill.ReadyToCast() && pHost.GetPrepSkill() != pSkill)
{
if (ElementSkill.IsGoblinSkill((uint)pSkill.GetSkillID()))
{
*//* if (pHostGoblin && !pHostGoblin->CheckSkillCastCondition(pSkill))
{
pCell->SetColor(A3DCOLORRGB(255, 255, 255));
}
else
{
pCell->SetColor(A3DCOLORRGB(128, 128, 128));
}*//*
}
else
{
if (pHost.CheckSkillCastCondition(pSkill) == 0)
{
//pCell.SetColor(A3DCOLORRGB(255, 255, 255));
}
else
{
//pCell.SetColor(A3DCOLORRGB(128, 128, 128));
}
}
}
*//* else
pClock.SetColor(A3DCOLORRGBA(0, 0, 0, 128));*//*
if (pSkill != null && (pSkill.GetCoolingTime() > 0 ||
pHost.GetPrepSkill() == pSkill))
{
pClock.SetProgressRange(0, pSkill.GetCoolingTime());
if (pHost.GetPrepSkill() == pSkill)
{
pClock.SetProgressPos(0);
}
else
{
pClock.SetProgressPos(pSkill.GetCoolingTime() - pSkill.GetCoolingCnt());
}
}
}
}
*//*else if (pSC->GetType() == CECShortcut::SCT_ITEM)
{
iIconFile = CECGameUIMan::ICONS_INVENTORY;
pCell->SetColor(A3DCOLORRGB(255, 255, 255));
pSCItem = (CECSCItem*)pSC;
pIvtr = GetHostPlayer()->GetPack(pSCItem->GetInventory());
pItem = pIvtr->GetItem(pSCItem->GetIvtrSlot());
if (pItem && pItem->GetCoolTime(&nMax) > 0)
{
pClock->SetProgressRange(0, nMax);
pClock->SetProgressPos(nMax - pItem->GetCoolTime());
pClock->SetColor(A3DCOLORRGBA(0, 0, 0, 128));
}
if (pSCItem->GetInventory() == IVTRTYPE_EQUIPPACK)
pCell->SetColor(A3DCOLORRGBA(128, 128, 255, 128));
}
else if (pSC->GetType() == CECShortcut::SCT_PET)
{
pSCPet = (CECSCPet*)pSC;
CECPetData* pPet = pPetCorral->GetPetData(pSCPet->GetPetIndex());
iIconFile = CECGameUIMan::ICONS_INVENTORY;
pCell->SetColor(A3DCOLORRGB(255, 255, 255));
if (pPet)
{
// dead combat pet
if ((pPet->GetClass() == GP_PET_CLASS_COMBAT || pPet->GetClass() == GP_PET_CLASS_EVOLUTION) && pPet->GetHPFactor() == 0.0f)
{
pCell->SetColor(A3DCOLORRGB(128, 128, 128));
}
// current active pet
else if (pSCPet->IsActivePet())
{
pCell->SetColor(A3DCOLORRGB(255, 255, 0));
}
}
}
else if (pSC->GetType() == CECShortcut::SCT_AUTOFASHION)
{
iIconFile = CECGameUIMan::ICONS_SUITE;
fashionCoolTime = pHost->GetCoolTime(GP_CT_EQUIP_FASHION_ITEM, &fashionCoolTimeMax);
pCell->SetColor(A3DCOLORRGB(255, 255, 255));
if (fashionCoolTimeMax > 0)
{
pClock->SetProgressRange(0, fashionCoolTimeMax);
pClock->SetProgressPos(fashionCoolTimeMax - fashionCoolTime);
pClock->SetColor(A3DCOLORRGBA(0, 0, 0, 175));
}
}
else
{
iIconFile = CECGameUIMan::ICONS_ACTION;
if (pSC->GetType() == CECShortcut::SCT_COMMAND)
{
CECSCCommand* pCommandSC = (CECSCCommand*)pSC;
if (GetHostPlayer()->IsInvisible())
{
if (pCommandSC->GetCommandID() == CECSCCommand::CMD_STARTTRADE ||
pCommandSC->GetCommandID() == CECSCCommand::CMD_SELLBOOTH ||
pCommandSC->GetCommandID() == CECSCCommand::CMD_BINDBUDDY)
{
pCell->SetColor(A3DCOLORRGB(128, 128, 128));
}
else
{
pCell->SetColor(A3DCOLORRGB(255, 255, 255));
}
}
else
{
pCell->SetColor(A3DCOLORRGB(255, 255, 255));
}
}
if (pSC->GetCoolTime(&nMax) > 0)
{
pClock->SetProgressRange(0, nMax);
pClock->SetProgressPos(nMax - pSC->GetCoolTime());
pClock->SetColor(A3DCOLORRGBA(0, 0, 0, 128));
}
}*//*
if (pSC != null)
{
pCell.SetDataPtr(pSC, "ptr_CECShortcut");
if (pSC.GetType() == (int)CECShortcut.ShortcutType.SCT_SKILLGRP)
{
*//* EC_VIDEO_SETTING setting = GetGame()->GetConfigs()->GetVideoSettings();
pCell->SetCover(GetGameUIMan()->m_pA2DSpriteIcons[CECGameUIMan::ICONS_SKILLGRP],
setting.comboSkill[((CECSCSkillGrp*)pSC)->GetGroupIndex()].nIcon + 1);*//*
}
else
{
if (pSkill != null)
{
pCell.gameObject.SetActive(true);
//BMLogger.Log("HoangDev: QuickBar Set Skill Icon: " + (uint)pSkill.GetSkillID() + " : " + ElementSkill.GetIcon((uint)pSkill.GetSkillID()));
var nameskill = ElementSkill.GetIcon((uint)pSkill.GetSkillID());
GetGameUIMan().SetCover(pCell, nameskill, EC_GAMEUI_ICONS.ICONS_SKILL);
}
*//*af_GetFileTitle(pSC->GetIconFile(), strFile);
strFile.MakeLower();
pCell->SetCover(GetGameUIMan()->m_pA2DSpriteIcons[iIconFile],
GetGameUIMan()->m_IconMap[iIconFile][strFile]);*//*
}
}
}
else
{
*//* pCell->SetCover(NULL, -1);
pCell->SetText(_AL(""));
pCell->SetDataPtr(NULL);
pCell->SetColor(A3DCOLORRGB(255, 255, 255));*//*
}
}
}
return true;
}*/
private void GetQuickBarNameAndSC(CECHostPlayer pHost, List<string> pszPanel, List<CECShortcutSet> pSCS, int panel9, int panel8)
{
string dlgName;
@@ -131,7 +131,6 @@ namespace BrewMonster.UI
{
return m_dialogResouce;
}
public Canvas GetCanvas()
{
return m_canvas;
@@ -8,6 +8,7 @@ namespace BrewMonster
{
[Header("LearnedSkillUI")]
[SerializeField] Button learnedSkillbutton;
[SerializeField] private DoubleTapButton wButton;
private void Awake()
{
@@ -15,15 +16,24 @@ namespace BrewMonster
{
Debug.LogError("Learned Skill Button is not assigned in LearnedSkillUI");
}
learnedSkillbutton.onClick.RemoveAllListeners();
learnedSkillbutton.onClick.AddListener(AddShortCutSkill);
wButton.DoubleTapped += OpenSetShortCutSkillUI;
}
private void AddShortCutSkill()
{
learnedSkillbutton.onClick.AddListener(OpenSetShortCutSkillUI);
}
private void OpenSetShortCutSkillUI()
{
}
}
/*public struct OpenSetShortCutSkillUIEvent
{
public OpenSetShortCutSkillUIEvent()
{
}
}*/
}
@@ -1,3 +1,4 @@
using System.Collections.Generic;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
@@ -9,6 +10,10 @@ namespace BrewMonster
[SerializeField] private TextMeshProUGUI _nameText;
[SerializeField] private TextMeshProUGUI _healthText;
[SerializeField] private Image _healthImage;
[Header("List Icon Task")]
[SerializeField] private GameObject _iconTaskMain;
// Start is called once before the first execution of Update after the MonoBehaviour is created
public void SetName(string name)
{
@@ -24,5 +29,11 @@ namespace BrewMonster
if(_healthText != null)
_healthText.text = healthText;
}
public void SetTaskIconMain(bool isShow)
{
if(_iconTaskMain != null)
_iconTaskMain.SetActive(isShow);
}
}
}
@@ -0,0 +1,67 @@
using System;
using UnityEngine;
using UnityEngine.EventSystems;
public class DoubleTapButton : MonoBehaviour, IPointerClickHandler
{
[SerializeField] private float doubleTapThreshold = 0.25f;
// Subscribe bằng code: doubleTapButton.DoubleTapped += () => ...
public event Action SingleTapped;
public event Action DoubleTapped;
private float _lastTapTime = -999f;
private bool _waitingSingle;
private int _tapCount;
private Coroutine _singleRoutine;
public void OnPointerClick(PointerEventData eventData)
{
if (eventData.button != PointerEventData.InputButton.Left) return;
float now = Time.unscaledTime;
if (now - _lastTapTime <= doubleTapThreshold) _tapCount++;
else _tapCount = 1;
_lastTapTime = now;
if (_tapCount == 2)
{
_tapCount = 0;
// huỷ single đang chờ
_waitingSingle = false;
if (_singleRoutine != null)
{
StopCoroutine(_singleRoutine);
_singleRoutine = null;
}
DoubleTapped?.Invoke();
}
else
{
// chờ 1 khoảng để xem có tap lần 2 không, rồi mới fire single
if (!_waitingSingle)
{
_waitingSingle = true;
_singleRoutine = StartCoroutine(WaitThenSingle());
}
}
}
private System.Collections.IEnumerator WaitThenSingle()
{
float start = Time.unscaledTime;
while (Time.unscaledTime - start < doubleTapThreshold)
{
if (!_waitingSingle) yield break; // đã double-tap
yield return null;
}
_waitingSingle = false;
_singleRoutine = null;
SingleTapped?.Invoke();
}
}
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 106e019fdd0d35744a1cf51aa2ea4b01
@@ -64,6 +64,23 @@ namespace BrewMonster
m_pCur += sizeof(short);
return value;
}
public ushort ReadUShort()
{
BoundCheck(sizeof(ushort));
ushort value = System.BitConverter.ToUInt16(data, m_pCur);
m_pCur += sizeof(ushort);
return value;
}
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 uint ReadUInt()
{
BoundCheck(sizeof(uint));
+2 -3
View File
@@ -11582,13 +11582,12 @@ MonoBehaviour:
detailPanelRoot: {fileID: 1753167144210994885}
detailPanelOffset: {x: 20, y: 0}
hideDetailOnStart: 1
itemInfoRoot: {fileID: 0}
nameText:
legacy: {fileID: 0}
tmp: {fileID: 4926468606842631984}
tmp: {fileID: 7304082661431364846}
descriptionText:
legacy: {fileID: 0}
tmp: {fileID: 0}
tmp: {fileID: 4926468606842631984}
extendedDescText:
legacy: {fileID: 0}
tmp: {fileID: 0}
+8
View File
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: dcaa1adabe1192947a68c7e0f4edece4
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

Some files were not shown because too many files have changed in this diff Show More