Files
test/Assets/Scripts/CECHostPlayer.Inventory.cs
T
2026-02-27 10:06:24 +07:00

1434 lines
57 KiB
C#

using BrewMonster.Managers;
using BrewMonster.Network;
using BrewMonster.Scripts;
using BrewMonster.Scripts.Managers;
using BrewMonster.Scripts.Skills;
using CSNetwork;
using CSNetwork.GPDataType;
using CSNetwork.S2CCommand;
using System;
using BrewMonster.UI;
using PerfectWorld.Scripts.Managers;
using UnityEngine;
using static BrewMonster.Scripts.CECHPWork;
using static BrewMonster.Scripts.Managers.EC_Inventory;
namespace BrewMonster
{
public partial class CECHostPlayer
{
public void OnMsgHstIvtrInfo(ECMSG Msg)
{
var data = Msg.dwParam1 as byte[];
int cmd = Convert.ToInt32(Msg.dwParam2);
int hostId = Convert.ToInt32(Msg.dwParam3);
switch (cmd)
{
case CommandID.OWN_IVTR_DATA:
{
LogInventoryPacket("OWN_IVTR_DATA", data, hostId);
break;
}
case CommandID.OWN_IVTR_DETAIL_DATA:
{
// EC_Inventory.LogInventoryPacket("OWN_IVTR_DETAIL_DATA", data, hostId);
// Parse and store
if (data != null && data.Length >= 6)
{
byte byPackage = data[0];
byte ivtrSize = data[1];
if (EC_IvtrItemUtils.Instance.TryParseInventoryDetail(data, out var pkg,
out var size, out var items))
{
var inv = GetInventory(pkg);
if (inv != null)
{
inv.Resize(size);
inv.RemoveAllItems();
if (items != null)
{
foreach (var it in items)
{
if (it != null && it.Slot >= 0 && it.Slot < size)
{
if (it.Content != null && it.Content.Length > 0)
it.SetItemInfo(it.Content, it.Content.Length);
inv.SetItem(it.Slot, it);
}
}
}
}
}
// check if we got the item from the Equipment Pack. If so, we have to load the equipment items
if (byPackage == InventoryConst.IVTRTYPE_EQUIPPACK)
{
UpdateEquipSkins();
}
}
break;
}
case CommandID.GET_OWN_MONEY:
{
if (data != null)
{
try
{
var money = GPDataTypeHelper.FromBytes<CSNetwork.GPDataType.cmd_get_own_money>(data);
SetMoneyAmount(money.amount);
var ui = GameObject.FindFirstObjectByType<BrewMonster.Scripts.Managers.EC_InventoryUI>();
if (ui == null)
{
var all = Resources.FindObjectsOfTypeAll<BrewMonster.Scripts.Managers.EC_InventoryUI>();
if (all != null)
{
for (int i = 0; i < all.Length; i++)
{
var candidate = all[i];
if (candidate != null && candidate.gameObject.scene.IsValid())
{
ui = candidate;
break;
}
}
}
}
if (ui != null)
{
ui.UpdateMoney(money.amount, money.max_amount);
}
else
{
BrewMonster.Scripts.Managers.EC_InventoryUI.CacheMoney(money.amount, money.max_amount);
}
}
catch (Exception ex)
{
Debug.LogWarning($"[Inventory] Failed to parse GET_OWN_MONEY: {ex.Message}");
}
}
break;
}
case CommandID.PLAYER_CASH:
{
if (data != null)
{
try
{
var cash = GPDataTypeHelper.FromBytes<CSNetwork.GPDataType.player_cash>(data);
var ui = GameObject.FindFirstObjectByType<BrewMonster.Scripts.Managers.EC_InventoryUI>();
if (ui == null)
{
var all = Resources.FindObjectsOfTypeAll<BrewMonster.Scripts.Managers.EC_InventoryUI>();
if (all != null)
{
for (int i = 0; i < all.Length; i++)
{
var candidate = all[i];
if (candidate != null && candidate.gameObject.scene.IsValid())
{
ui = candidate;
break;
}
}
}
}
if (ui != null)
{
ui.UpdateCash(cash.cash_amount);
}
else
{
BrewMonster.Scripts.Managers.EC_InventoryUI.CacheCash(cash.cash_amount);
}
}
catch (Exception ex)
{
Debug.LogWarning($"[Inventory] Failed to parse PLAYER_CASH: {ex.Message}");
}
}
break;
}
}
}
public void OnMsgHstOwnItemInfo(ECMSG Msg)
{
int cmd = Convert.ToInt32(Msg.dwParam2);
switch (cmd)
{
case CommandID.OWN_ITEM_INFO:
{
//Debug.Log("[Inventory] OWN_ITEM_INFO received");
//var data = Msg.dwParam1 as byte[];
//int hostId = Convert.ToInt32(Msg.dwParam3);
//LogInventoryPacket("OWN_ITEM_INFO", data, hostId);
//Handmade
var data = Msg.dwParam1 as byte[];
if (data == null || data.Length == 0)
return;
byte byPackage = data[0];
byte bySlot = data[1];
int type = BitConverter.ToInt32(data, 2);
int expire_date = BitConverter.ToInt32(data, 6);
int state = BitConverter.ToInt32(data, 10);
uint count = BitConverter.ToUInt32(data, 14);
ushort crc = BitConverter.ToUInt16(data, 18);
ushort content_length = BitConverter.ToUInt16(data, 20);
byte[] content = null;
if (content_length > 0 && 22 + content_length <= data.Length)
{
content = new byte[content_length];
Buffer.BlockCopy(data, 22, content, 0, content_length);
string hexDebug = BitConverter.ToString(content);
//Debug.Log($"[OWN_ITEM_INFO] Full Content Hex ({content_length} bytes): {hexDebug}");
}
//Debug.Log($"[OWN_ITEM_INFO] Parsed: package={byPackage}, slot={bySlot}, tid={type}, count={count}, content_len={content_length}");
EC_Inventory pInventory = GetInventory(byPackage);
EC_IvtrItem newItem = EC_IvtrItem.CreateItem(type, expire_date, (int)count);
if (newItem != null)
{
newItem.SetProcType(state);
newItem.GetDetailDataFromLocal();
if (content != null && content.Length > 0)
{
newItem.SetItemInfo(content, content_length);
}
pInventory.SetItem(bySlot, newItem);
//Debug.Log($"[OWN_ITEM_INFO] Fixed Update: Pack {byPackage} Slot {bySlot} - Type {type}");
}
if (byPackage == InventoryConst.IVTRTYPE_EQUIPPACK)
{
UpdateEquipSkins();
}
else if (byPackage == InventoryConst.IVTRTYPE_PACK)
{
if (newItem.IsEquipment())
{
// TODO
}
}
var ui = GameObject.FindFirstObjectByType<EC_InventoryUI>();
if (ui != null)
{
ui.RefreshAll();
//Debug.Log($"[OWN_ITEM_INFO] Refreshed inventory UI after updating item at package={byPackage}, slot={bySlot}");
}
break;
}
case CommandID.EMPTY_ITEM_SLOT:
{
var data = Msg.dwParam1 as byte[];
cmd_empty_item_slot pCmd = GPDataTypeHelper.FromBytes<cmd_empty_item_slot>(data);
EC_Inventory pInventory = GetPack(pCmd.byPackage);
if (pInventory == null)
return;
EC_IvtrItem pItem = pInventory.GetItem(pCmd.bySlot);
if (pItem != null)
{
//UpdateRemovedItemSC(pItem->GetTemplateID(), pCmd->byPackage, pCmd->bySlot);
}
pInventory.SetItem(pCmd.bySlot, null);
var ui = GameObject.FindFirstObjectByType<EC_InventoryUI>();
if (ui != null)
{
ui.RefreshAll();
}
break;
}
}
}
public void OnMsgHstItemOperation(ECMSG Msg)
{
var data = Msg.dwParam1 as byte[];
int cmd = Convert.ToInt32(Msg.dwParam2);
switch (cmd)
{
case CommandID.PLAYER_DROP_ITEM:
{
// Parse the drop item data from the server response
if (data != null && data.Length >= 6)
{
byte byPackage = data[0];
byte bySlot = data[1];
int count = BitConverter.ToInt32(data, 2);
int tid = BitConverter.ToInt32(data, 6);
byte reason = data[10];
Debug.Log(
$"[Inventory] PLAYER_DROP_ITEM: package={byPackage}, slot={bySlot}, count={count}, tid={tid}, reason={reason}");
// Update the inventory by removing the item
var inv = GetInventory(byPackage);
bool success = inv != null && inv.RemoveItem(bySlot, count);
if (success)
{
Debug.Log(
$"[Inventory] Successfully removed {count} items from package {byPackage}, slot {bySlot}");
// Trigger UI refresh if an EC_InventoryUI is present in scene
var ui = GameObject.FindFirstObjectByType<EC_InventoryUI>();
if (ui != null)
{
ui.RefreshAll();
}
}
else
{
Debug.LogWarning(
$"[Inventory] Failed to remove items from package {byPackage}, slot {bySlot}");
}
}
else
{
Debug.LogWarning("[Inventory] PLAYER_DROP_ITEM: Invalid data length");
}
break;
}
case CommandID.EQUIP_ITEM:
{
byte index_inv = data[0];
byte index_equip = data[1];
// Update client-side data: move item between PACK_INVENTORY and PACK_EQUIPMENT
var packInv = GetInventory(InventoryConst.IVTRTYPE_PACK);
var equipInv = GetInventory(InventoryConst.IVTRTYPE_EQUIPPACK);
var invItem = packInv?.GetItem(index_inv, true);
var equipItem = equipInv?.GetItem(index_equip, true);
UpdateEquipSkins();
if (invItem != null)
{
invItem.Package = InventoryConst.IVTRTYPE_EQUIPPACK;
invItem.Slot = index_equip;
equipInv?.SetItem(index_equip, invItem);
}
if (equipItem != null)
{
equipItem.Package = InventoryConst.IVTRTYPE_PACK;
equipItem.Slot = index_inv;
packInv?.SetItem(index_inv, equipItem);
}
// Trigger UI refresh if an EC_InventoryUI is present in scene
var ui = GameObject.FindObjectOfType<EC_InventoryUI>();
if (ui != null)
{
ui.RefreshAll();
}
UpdateEquipSkins();
break;
}
}
}
public void OnMsgHstPickupItem(in ECMSG Msg)
{
var data = Msg.dwParam1 as byte[];
int cmd = Convert.ToInt32(Msg.dwParam2);
bool bDoOther = false;
int idItem, iExpireDate = 0, iAmount, iCmdLastSlot, iCmdSlotAmount, iPack, iMsg = -1;
switch (cmd)
{
case CommandID.HOST_OBTAIN_ITEM:
{
// Parse cmd_host_obtain_item struct data
int type = BitConverter.ToInt32(data, 0);
int expire_date = BitConverter.ToInt32(data, 4);
uint amount = BitConverter.ToUInt32(data, 8);
uint slot_amount = BitConverter.ToUInt32(data, 12);
byte where = data[16]; // Package index
byte index = data[17]; // Slot index in that package
var newItem = EC_IvtrItem.CreateItem(type, expire_date, (int)amount);
// Add item to inventory
var ivt = GetInventory(where);
ivt.SetItem(index, newItem);
Debug.Log(
$"[HOST_OBTAIN_ITEM] Successfully added item {type} to package {where}, slot {index} with count {amount}");
// Trigger UI refresh if an EC_InventoryUI is present in scene
var ui = GameObject.FindFirstObjectByType<EC_InventoryUI>();
if (ui != null)
{
ui.RefreshAll();
}
UpdateEquipSkins();
}
break;
case CommandID.PICKUP_ITEM:
{
int tid = BitConverter.ToInt32(data, 0);
int expire_date = BitConverter.ToInt32(data, 4);
iAmount = (int)BitConverter.ToUInt32(data, 8);
uint iSlotAmount = BitConverter.ToUInt32(data, 12);
byte byPackage = data[16];
byte bySlot = data[17];
//Debug.Log($"[Inventory] PICKUP_ITEM: tid={tid}, expire_date={expire_date}, iAmount={iAmount}, iSlotAmount={iSlotAmount}, byPackage={byPackage}, bySlot={bySlot}");
// Notify pickupItem script about successful pickup
pickupItem pickupScript = pickupItem.Instance;
if (pickupScript != null)
{
//Debug.Log($"[Inventory] PICKUP_ITEM: tid={tid}, expire_date={expire_date}, iAmount={iAmount}, iSlotAmount={iSlotAmount}, byPackage={byPackage}, bySlot={bySlot}");
// Notify pickupItem script about successful pickup
pickupScript = UnityEngine.Object.FindFirstObjectByType<pickupItem>();
if (pickupScript != null)
{
pickupScript.OnPickupSuccess(tid);
}
// Create new inventory item data
var newItem = EC_IvtrItem.CreateItem(tid, expire_date, (int)iAmount);
// Add item to inventory
var ivt = GetInventory(byPackage);
ivt.SetItem(bySlot, newItem);
//Debug.Log($"[Inventory] Successfully added item {tid} to package {byPackage}, slot {bySlot} with count {iAmount}");
// Trigger UI refresh if an EC_InventoryUI is present in scene
var ui = GameObject.FindFirstObjectByType<EC_InventoryUI>();
if (ui != null)
{
ui.RefreshAll();
}
}
else
{
Debug.LogWarning("[Inventory] PICKUP_ITEM: Invalid data length");
}
break;
}
case CommandID.TASK_DELIVER_ITEM:
cmd_task_deliver_item pCmd = GPDataTypeHelper.FromBytes<cmd_task_deliver_item>(data);
// ASSERT(pCmd);
idItem = pCmd.type;
iExpireDate = pCmd.expire_date;
iAmount = (int)pCmd.amount;
iCmdLastSlot = pCmd.index;
iCmdSlotAmount = (int)pCmd.slot_amount;
iPack = pCmd.where;
iMsg = (int)FixedMsg.FIXMSG_GAINITEM;
bDoOther = true;
// Create new inventory item data
var taskNewItem = EC_IvtrItem.CreateItem(idItem, iExpireDate, (int)iAmount);
// Add item to inventory
var task_ivt = GetInventory((byte)iPack);
if (!task_ivt.MergeItem(idItem, iExpireDate, iAmount, out var iLastSlot, out var iSlotNum) ||
iLastSlot != iCmdLastSlot || iSlotNum != iCmdSlotAmount)
{
return;
}
task_ivt.SetItem(iCmdLastSlot, taskNewItem);
//Debug.Log($"[Inventory] Successfully added item {tid} to package {byPackage}, slot {bySlot} with count {iAmount}");
// Trigger UI refresh if an EC_InventoryUI is present in scene
var task_ui = GameObject.FindFirstObjectByType<EC_InventoryUI>();
if (task_ui != null)
{
task_ui.RefreshAll();
}
break;
case CommandID.PRODUCE_ONCE:
{
// Parse cmd_produce_once struct data
cmd_produce_once produceCmd = GPDataTypeHelper.FromBytes<cmd_produce_once>(data);
int produceItemId = produceCmd.type;
int produceExpireDate = 0;
uint produceAmount = produceCmd.amount;
byte producePack = produceCmd.where;
byte produceSlot = produceCmd.index;
Debug.Log(
$"[PRODUCE_ONCE] Received: itemId={produceItemId}, amount={produceAmount}, pack={producePack}, slot={produceSlot}");
// Get inventory
var produce_ivt = GetInventory(producePack);
if (produce_ivt == null)
{
Debug.LogWarning($"[PRODUCE_ONCE] Invalid inventory package {producePack}");
return;
}
// Check if the slot already has an item
var existingItem = produce_ivt.GetItem(produceSlot, false);
if (existingItem != null)
{
if (existingItem.m_tid == produceItemId)
{
existingItem.m_iCount = (int)produceAmount;
Debug.Log(
$"[PRODUCE_ONCE] Updated existing item count at slot {produceSlot} to {produceAmount}");
}
else
{
Debug.LogWarning(
$"[PRODUCE_ONCE] Slot {produceSlot} already has different item (tid={existingItem.m_tid}), not overwriting with {produceItemId}");
return;
}
}
else
{
var produceNewItem = new EC_IvtrItem
{
Package = producePack,
Slot = produceSlot,
m_tid = produceItemId,
m_expire_date = produceExpireDate,
State = 0,
m_iCount = (int)produceAmount,
Crc = 0,
Content = null
};
produce_ivt.SetItem(produceSlot, produceNewItem);
Debug.Log($"[PRODUCE_ONCE] Created new item at slot {produceSlot} with count {produceAmount}");
}
// Trigger UI refresh
var produce_ui = GameObject.FindFirstObjectByType<EC_InventoryUI>();
if (produce_ui != null)
{
produce_ui.RefreshAll();
}
UpdateEquipSkins();
// Notify DlgProduce
var dlgProduce = GameObject.FindFirstObjectByType<DlgProduce>();
if (dlgProduce != null)
{
dlgProduce.OnProduceOnce(produceCmd);
}
}
break;
}
}
private void OnMsgHstUseItem(ECMSG Msg)
{
cmd_host_use_item pCmd = GPDataTypeHelper.FromBytes<cmd_host_use_item>((byte[])Msg.dwParam1);
EC_Inventory pPack = GetPack(pCmd.byPackage);
if (pPack == null)
{
return;
}
EC_IvtrItem pItem = pPack.GetItem(pCmd.bySlot, false);
if (pItem == null || pItem.GetTemplateID() != pCmd.item_id)
{
return;
}
pItem.Use();
if (pCmd.use_count > 0)
{
bool removed = pPack.RemoveItem(pCmd.bySlot, pCmd.use_count);
if (removed)
{
if (pPack.GetItem(pCmd.bySlot, false) == null)
{
//Debug.Log($"[OnMsgHstUseItem] Item {pCmd.item_id} removed from slot {pCmd.bySlot}");
}
}
else
{
//Debug.LogError($"[OnMsgHstUseItem] Failed to remove item {pCmd.item_id} from slot {pCmd.bySlot}");
}
var ui = GameObject.FindFirstObjectByType<EC_InventoryUI>();
if (ui != null)
{
ui.RefreshAll();
ui.UpdateCooldownOverlays();
}
else
{
//Debug.LogError("[OnMsgHstUseItem] EC_InventoryUI not found, UI may not update");
}
}
if (m_pWorkMan != null)
{
CECHPWork pWork = m_pWorkMan.GetRunningWork(Host_work_ID.WORK_USEITEM);
if (pWork is CECHPWorkUse useWork)
{
if (useWork.GetItem() == pCmd.item_id)
{
m_pWorkMan.FinishRunningWork(Host_work_ID.WORK_USEITEM);
}
}
}
}
public void OnMsgHstProduceItem(in ECMSG Msg)
{
var data = Msg.dwParam1 as byte[];
int cmd = Convert.ToInt32(Msg.dwParam2);
// Get DlgProduce to notify
var dlgProduce = GameObject.FindFirstObjectByType<DlgProduce>();
if (dlgProduce == null)
{
Debug.LogWarning("[OnMsgHstProduceItem] DlgProduce not found");
return;
}
switch (cmd)
{
case CommandID.PRODUCE_START:
{
cmd_produce_start pCmd = GPDataTypeHelper.FromBytes<cmd_produce_start>(data);
Debug.Log($"[PRODUCE_START] type={pCmd.type}, use_time={pCmd.use_time}, count={pCmd.count}");
dlgProduce.OnProduceStart(pCmd);
}
break;
case CommandID.PRODUCE_END:
{
Debug.Log("[PRODUCE_END] Production ended");
dlgProduce.OnProduceEnd();
}
break;
case CommandID.PRODUCE_NULL:
{
cmd_produce_null pCmd = GPDataTypeHelper.FromBytes<cmd_produce_null>(data);
Debug.Log($"[PRODUCE_NULL] type={pCmd.type}");
dlgProduce.OnProduceNull(pCmd);
}
break;
default:
Debug.LogWarning($"[OnMsgHstProduceItem] Unknown command: {cmd}");
break;
}
}
public void OnMsgHstEmbedItem(ECMSG Msg)
{
cmd_embed_item pCmd = GPDataTypeHelper.FromBytes<cmd_embed_item>((byte[])Msg.dwParam1);
EC_IvtrItem pEquip = m_pPack.GetItem(pCmd.equip_idx);
EC_IvtrItem pTessera = m_pPack.GetItem(pCmd.chip_idx);
if (pEquip == null || pTessera == null)
{
return;
}
m_pPack.RemoveItem(pCmd.chip_idx, 1);
// Refresh equip's data
// todo make receive request
UnityGameSession.c2s_CmdGetItemInfo(Inventory_type.IVTRTYPE_PACK, pCmd.equip_idx);
}
private void OnMsgEnchantResult(ECMSG msg)
{
// 从消息中获取cmd_enchant_result结构 // Get cmd_enchant_result structure from message
cmd_enchant_result pCmd = GPDataTypeHelper.FromBytes<cmd_enchant_result>((byte[])msg.dwParam1);
// 初始化掩码为全1 // Initialize mask to all 1s
uint mask = 0xFFFFFFFF;
// 如果目标不是主机玩家且当前不是主机玩家,则过滤会引起气泡文本的修饰符
// We should filter out these things that will cause bubble texts
CECHostPlayer pHost = EC_ManMessageMono.Instance.GetECManPlayer.GetHostPlayer();
if (pCmd.target != pHost.GetCharacterID() && !IsHostPlayer())
{
mask &= (uint)(MOD.MOD_PHYSIC_ATTACK_RUNE | MOD.MOD_MAGIC_ATTACK_RUNE |
MOD.MOD_CRITICAL_STRIKE | MOD.MOD_ENCHANT_FAILED);
}
// 获取修饰符 // Get modifier
uint dwModifier = (uint)pCmd.attack_flag;
// 获取技能类型 // Get skill type
int nDamage = -2; // 默认为-2,不会引起受伤动作 // Default to -2, will not cause wounded action
if (ElementSkill.GetType((uint)pCmd.skill) == (byte)skill_type.TYPE_ATTACK)
{
// 只有攻击技能会引起受伤动作,伤害值为-1 // Only attack skill will cause wounded action, when damage is -1
nDamage = -1;
}
else
{
// 其他技能不会引起受伤动作,伤害值设为-2 // Other skills will not cause wounded action, so we set damage to -2
nDamage = -2;
}
// 播放攻击效果 // Play attack effect
int attackTime = 0;
PlayAttackEffect(pCmd.target, pCmd.skill, pCmd.level, nDamage,
dwModifier & mask, 0, ref attackTime, pCmd.section);
}
public void OnMsgHstClearTessera(ECMSG Msg)
{
cmd_clear_tessera pCmd = GPDataTypeHelper.FromBytes<cmd_clear_tessera>((byte[])Msg.dwParam1);
AddMoneyAmount(-(int)pCmd.cost);
// Refresh equip's data
UnityGameSession.c2s_CmdGetItemInfo(Inventory_type.IVTRTYPE_PACK, (byte)pCmd.equip_idx);
}
// Add money amount
private int AddMoneyAmount(int iAmount)
{
m_iMoneyCnt += (uint)iAmount;
return (int)m_iMoneyCnt;
}
public bool HaveHealthStones()
{
var pPack = GetPack();
var items = new int[] { 36764, 36765, 36766, 36767 };
for (int i = 0; i < items.Length; ++i)
{
if (pPack.FindItem(items[i]) >= 0)
return true;
}
return false;
}
public bool UseItemInPack(int iPack, int iSlot, bool showMsg = true)
{
if (!CanDo(ActionCanDo.CANDO_USEITEM))
return false;
EC_Inventory pPack = GetPack(iPack);
if (pPack == null)
return false;
EC_IvtrItem pItem = pPack.GetItem(iSlot);
if (pItem == null || pItem.IsFrozen())
return false;
if (pItem.Use_Persist() && (IsJumping() || IsFalling()))
return false;
CECGameRun pGameRun = EC_Game.GetGameRun();
//CECGameSession pSession = g_pGame.GetGameSession();
if (pItem.GetClassID() == (int)EC_IvtrItem.InventoryClassId.ICID_FIREWORK)
{
if (GetProfession() == (int)PROFESSION.PROF_GHOST && IsInvisible())
{
if (showMsg)
pGameRun.AddFixedMessage((int)FixedMsg.FIXMSG_CANNOT_USE_WHEN_INVISIBLE);
return false;
}
}
if (pItem.GetClassID() == (int)EC_IvtrItem.InventoryClassId.ICID_INCSKILLABILITY)
{
EC_IvtrIncSkillAbility pIncSkill = pItem as EC_IvtrIncSkillAbility;
//if (pIncSkill != null)
//{
// var pDBEssence = pIncSkill.GetDBEssence();
// CECSkill pSkill = GetNormalSkill(pDBEssence.id_skill);
// if (pSkill != null)
// {
// if (pSkill.GetSkillLevel() != pDBEssence.level_required)
// {
// if (showMsg)
// pGameRun.AddFixedMessage((int)FixedMsg.FIXMSG_PRODUCE_LEVEL_INVALID);
// return false;
// }
// if (GetSkillAbilityPercent(pDBEssence.id_skill) >= 100)
// {
// if (showMsg)
// pGameRun.AddFixedMessage((int)FixedMsg.FIXMSG_PRODUCE_ABILITY_FULL);
// return false;
// }
// }
//}
}
if (pItem.GetClassID() == (int)EC_IvtrItem.InventoryClassId.ICID_TRANSMITSCROLL)
{
CECGameUIMan pGameUI = pGameRun.GetUIManager().GetInGameUIMan();
if (pGameUI != null && !IsFighting())
{
// TODO: Implement travel map dialog
//CDlgWorldMap* pMap = (CDlgWorldMap*)pGameUI->GetDialog("Win_WorldMapTravel");
//pMap->BuildTravelMap(DT_TRANSMITSCROLL_ESSENCE, (void*)iSlot);
//pMap->Show(true);
}
return true;
}
if (pItem.GetClassID() == (int)EC_IvtrItem.InventoryClassId.ICID_SHOPTOKEN)
{
CECGameUIMan pGameUI = pGameRun.GetUIManager().GetInGameUIMan();
if (pGameUI != null && !IsFighting())
{
//CDlgTokenShop* pDlg = dynamic_cast<CDlgTokenShop*>(pGameUI->GetDialog("Win_TokenShop"));
//if (pDlg)
//{
// pDlg->InitTokenShopItem(pItem->GetTemplateID());
// pDlg->Show(!pDlg->IsShow());
//}
}
return true;
}
if (pItem.GetClassID() == (int)EC_IvtrItem.InventoryClassId.ICID_UNIVERSAL_TOKEN)
{
// TODO: Implement universal token when available
EC_IvtrUniversalToken pUniversalToken = pItem as EC_IvtrUniversalToken;
//if (pUniversalToken != null && pUniversalToken.HasAnyUsage())
//{
// CECUseUniversalTokenCommandManager.Instance.Use(pUniversalToken, pUniversalToken.UsageIndexAt(0));
// return true;
//}
}
if (pItem.GetClassID() == (int)EC_IvtrItem.InventoryClassId.ICID_TASKDICE)
{
EC_IvtrTaskDice pTaskDice = pItem as EC_IvtrTaskDice;
if (pTaskDice != null)
{
if (pTaskDice != null)
{
if (IsFlying() && pTaskDice.GetDBEssence().no_use_in_combat == 1)
{
if (showMsg)
pGameRun.AddFixedMessage((int)FixedMsg.FIXMSG_CANNOT_USE_IN_BATTLE);
return false;
}
}
}
}
if (pItem.GetClassID() == (int)EC_IvtrItem.InventoryClassId.ICID_TARGETITEM)
{
EC_IvtrTargetItem pTargetItem = pItem as EC_IvtrTargetItem;
if (pTargetItem == null)
return false;
var essence = pTargetItem.GetDBEssence();
if (!pTargetItem.IsEssenceLoaded())
return false;
if (IsFighting() && essence.use_in_combat == 0)
{
if (showMsg)
if (showMsg)
pGameRun.AddFixedMessage((int)FixedMsg.FIXMSG_CANNOT_USE_IN_BATTLE);
return false;
}
if (essence.use_in_sanctuary_only != 0 && !IsInSanctuary())
{
if (showMsg)
pGameRun.AddFixedMessage((int)FixedMsg.FIXMSG_USE_IN_SANCTUARY_ONLY);
return false;
}
int iCurrMap = pGameRun.GetWorld().GetInstanceID();
if (pTargetItem.GetDBEssence().num_area != 0)
{
bool found = false;
for (int i = 0; i < pTargetItem.GetDBEssence().num_area; i++)
{
if (pTargetItem.GetDBEssence().area_id[i] == iCurrMap)
{
found = true;
break;
}
}
if (!found)
{
if (showMsg)
pGameRun.AddFixedMessage((int)FixedMsg.FIXMSG_CANNOT_USE_IN_CURR_MAP);
return false;
}
}
if (!CanDo(ActionCanDo.CANDO_SPELLMAGIC))
return false;
if (InSlidingState())
return false;
if (m_idSelTarget == 0)
return false;
CECSkill pSkill = pTargetItem.GetTargetSkill();
if (pSkill == null)
return false;
if (IsSpellingMagic() && m_pCurSkill != null && m_pCurSkill.IsCharging() &&
m_pCurSkill.GetSkillID() == pSkill.GetSkillID())
{
m_pCurSkill.EndCharging();
UnityGameSession.c2s_SendCmdContinueAction();
return true;
}
int iCon = CheckSkillCastCondition(pSkill);
if (iCon != 0)
{
if (showMsg)
ProcessSkillCondition(iCon);
return false;
}
bool bForceAttack = glb_GetForceAttackFlag(0);
if (pSkill.GetType() == (int)CECSkill.SkillType.TYPE_ATTACK ||
pSkill.GetType() == (int)CECSkill.SkillType.TYPE_CURSE)
{
if (m_idSelTarget == m_PlayerInfo.cid)
{
if (showMsg)
pGameRun.AddFixedChannelMsg((int)FixedMsg.FIXMSG_TARGETWRONG,
(int)ChatChannel.GP_CHAT_FIGHT);
return false;
}
else if (m_idSelTarget != 0)
{
if (AttackableJudge(m_idSelTarget, bForceAttack) != 1)
return false;
}
}
int idCastTarget = m_idSelTarget;
int iTargetType = pSkill.GetTargetType();
if (pSkill.GetType() == (int)CECSkill.SkillType.TYPE_BLESS ||
pSkill.GetType() == (int)CECSkill.SkillType.TYPE_NEUTRALBLESS)
{
if (iTargetType == 0 || !GPDataTypeHelper.ISPLAYERID(m_idSelTarget))
idCastTarget = m_PlayerInfo.cid;
if (GPDataTypeHelper.ISPLAYERID(idCastTarget) && idCastTarget != m_PlayerInfo.cid)
{
byte byBLSMask = EC_Utility.glb_BuildBLSMask();
if (pSkill.GetRangeType() == (int)CECSkill.RangeType.RANGE_POINT)
{
if (!IsTeamMember(idCastTarget))
{
if ((byBLSMask & (byte)PVPMask.GP_BLSMASK_SELF) != 0)
{
idCastTarget = m_PlayerInfo.cid;
}
else
{
EC_ElsePlayer pPlayer =
EC_ManMessageMono.Instance.GetECManPlayer.GetElsePlayer(idCastTarget) as
EC_ElsePlayer;
if (pPlayer == null)
return false;
if (pPlayer.IsInvader() || pPlayer.IsPariah())
{
if ((byBLSMask & (byte)PVPMask.GP_BLSMASK_NORED) != 0)
idCastTarget = m_PlayerInfo.cid;
}
if (!IsFactionMember(pPlayer.GetFactionID()))
{
if ((byBLSMask & (byte)PVPMask.GP_BLSMASK_NOMAFIA) != 0)
idCastTarget = m_PlayerInfo.cid;
}
if (!IsFactionAllianceMember(pPlayer.GetFactionID()))
{
if ((byBLSMask & (byte)PVPMask.GP_BLSMASK_NOALLIANCE) != 0)
idCastTarget = m_PlayerInfo.cid;
}
if (GetForce() != pPlayer.GetForce())
{
if ((byBLSMask & (byte)PVPMask.GP_BLSMASK_NOFORCE) != 0)
idCastTarget = m_PlayerInfo.cid;
}
}
}
}
// If host is in dule
if (IsInDuel() && m_idSelTarget == m_pvp.idDuelOpp)
idCastTarget = m_PlayerInfo.cid;
// If host is in battle
if (IsInBattle())
{
EC_ElsePlayer pPlayer =
EC_ManMessageMono.Instance.GetECManPlayer.GetElsePlayer(idCastTarget);
if (!InSameBattleCamp(pPlayer))
idCastTarget = m_PlayerInfo.cid;
}
}
}
else if (pSkill.GetType() == (int)CECSkill.SkillType.TYPE_BLESS)
{
// TODO: Implement pet blessing when petsystem is available
//CECSCPet pPet = EC_Game.GetGameRun().GetWorld().GetPetByID(m_idSelTarget);
//if (pPet == null || pPet.GetMasterID() == GetCharacterID())
//{
// CECPetData pPetData = m_pPetCorral.GetActivePet();
// if (pPetData == null ||
// pPetData.GetClass() != GP_PET_TYPE.GP_PET_CLASS_COMBAT &&
// pPetData.GetClass() != GP_PET_TYPE.GP_PET_CLASS_SUMMON &&
// pPetData.GetClass() != GP_PET_TYPE.GP_PET_CLASS_EVOLUTION)
// return false;
// idCastTarget = m_pPetCorral.GetActivePetNPCID();
//}
//if(iTargetType != 0 && idCastTarget == 0)
// return false;
}
if (iTargetType != 0)
{
int iAliveFlag = 0;
if (iTargetType == 1)
iTargetType = 1;
else if (iTargetType == 2)
iTargetType = 2;
CECObject pObject = EC_ManMessageMono.Instance.GetObject(idCastTarget, iAliveFlag);
if (pObject == null)
return false;
}
if (!IsMeleeing() && !IsSpellingMagic() &&
(iTargetType == 0 || idCastTarget == m_PlayerInfo.cid))
{
if (!pSkill.ReadyToCast())
return false;
if (!pSkill.IsInstant() && pSkill.GetType() != (int)CECSkill.SkillType.TYPE_FLASHMOVE)
{
if (!NaturallyStopMoving())
return false;
}
else if (pSkill.GetType() == (int)CECSkill.SkillType.TYPE_FLASHMOVE)
{
if (!CanDo(ActionCanDo.CANDO_FLASHMOVE))
return false;
}
m_pPrepSkill = pSkill;
}
else if (IsSpellingMagic() && m_pCurSkill == pSkill && !pSkill.ReadyToCast())
{
return false;
}
}
if (pItem.IsEquipment())
{
if (iPack == Inventory_type.IVTRTYPE_EQUIPPACK)
{
// Take off equipment
int iEmpty = m_pPack.SearchEmpty();
if (iEmpty < 0)
return false;
UnityGameSession.RequestEquipItemAsync((byte)iEmpty, (byte)iSlot, null);
return true;
}
EC_IvtrEquip pEquip = pItem as EC_IvtrEquip;
if (pEquip == null)
return false;
int iReason = 0;
if (!CanUseEquipment(pEquip, ref iReason))
return false;
int iFirstFree = -1, iFirstCan = -1;
for (int i = 0; i < InventoryConst.SIZE_ALL_EQUIPIVTR; i++)
{
if (pItem.CanEquippedTo(i))
{
if (iFirstCan < 0)
iFirstCan = i;
if (m_pEquipPack.GetItem(i) == null && iFirstFree < 0)
{
iFirstFree = i;
break;
}
}
}
int iDst;
if (iFirstFree >= 0)
iDst = iFirstFree;
else if (iFirstCan >= 0)
iDst = iFirstCan;
else
{
Debug.Assert(false);
return false;
}
if (pItem.GetClassID() == (int)EC_IvtrItem.InventoryClassId.ICID_DYNSKILLEQUIP)
{
int iSameIDPos = m_pEquipPack.FindItem(pItem.GetTemplateID());
if (iSameIDPos >= 0)
{
iDst = iSameIDPos;
}
}
if (pItem.GetClassID() == (int)EC_IvtrItem.InventoryClassId.ICID_ARROW ||
pItem.GetClassID() == (int)EC_IvtrItem.InventoryClassId.ICID_DYNSKILLEQUIP)
{
EC_IvtrItem pDstItem = m_pEquipPack.GetItem(iDst);
if (pDstItem == null || pItem.GetTemplateID() != pDstItem.GetTemplateID())
UnityGameSession.RequestEquipItemAsync((byte)iSlot, (byte)iDst, null);
else
{
// TODO: Implement c2s_CmdMoveItemToEquip when available
//UnityGameSession.c2s_CmdMoveItemToEquip((byte)iSlot, (byte)iDst);
}
}
else
{
if (pItem.GetClassID() == (int)EC_IvtrItem.InventoryClassId.ICID_GENERALCARD)
{
//TODO: Add general card equip request
EC_IvtrGeneralCard pCard = pItem as EC_IvtrGeneralCard;
if (pCard != null)
{
iDst = InventoryConst.EQUIPIVTR_GENERALCARD1 + pCard.GetEssence().type;
}
}
UnityGameSession.RequestEquipItemAsync((byte)iSlot, (byte)iDst, null);
}
return true;
}
if (iPack != Inventory_type.IVTRTYPE_PACK)
return false;
if (!pItem.CheckUseCondition())
{
if (showMsg)
pGameRun.AddFixedMessage((int)FixedMsg.FIXMSG_ITEM_CANNOTUSE);
return false;
}
int piMax = -1;
if (pItem.GetCoolTime(out piMax) > 0)
{
if (showMsg)
pGameRun.AddFixedMessage((int)FixedMsg.FIXMSG_ITEM_INCOOLTIME);
return false;
}
if (pItem.Use_AtkTarget() || pItem.Use_Target())
{
if (pItem.Use_AtkTarget() && CannotAttack())
return false;
if (m_idSelTarget == 0 || m_idSelTarget == m_PlayerInfo.cid)
{
if (showMsg)
{
CECStringTab pStrTab = EC_Game.GetFixedMsgs();
pGameRun.AddChatMessage(pStrTab.GetWideString((int)FixedMsg.FIXMSG_NOTARGET),
(int)ChatChannel.GP_CHAT_SYSTEM);
}
return false;
}
float fAattackRange = 10000.0f;
if (pItem.GetClassID() == (int)EC_IvtrItem.InventoryClassId.ICID_TOSSMAT)
{
EC_IvtrTossMat pTossMat = pItem as EC_IvtrTossMat;
if (pTossMat != null)
fAattackRange = pTossMat.GetDBEssence().attack_range;
}
else if (pItem.GetClassID() == (int)EC_IvtrItem.InventoryClassId.ICID_TANKCALLIN)
{
fAattackRange = 5.0f;
}
else if (pItem.GetClassID() == (int)EC_IvtrItem.InventoryClassId.ICID_TARGETITEM)
{
EC_IvtrTargetItem pTargetItem = pItem as EC_IvtrTargetItem;
if (pTargetItem != null && pTargetItem.GetTargetSkill() != null)
{
fAattackRange = pTargetItem.GetTargetSkill()
.GetCastRange(m_ExtProps.ak.AttackRange, GetPrayDistancePlus());
}
}
float fDist = 0, fTargetRag = 0;
CECObject pObject = null;
if (CalcDist(m_idSelTarget, out fDist, out pObject))
{
return false;
}
if (GPDataTypeHelper.ISNPCID(m_idSelTarget))
{
pObject = EC_ManMessageMono.Instance.CECNPCMan.GetNPC(m_idSelTarget);
CECNPC pNPC = pObject as CECNPC;
if (pNPC != null)
fTargetRag = pNPC.GetTouchRadius();
}
else if (GPDataTypeHelper.ISPLAYERID(m_idSelTarget))
{
pObject = EC_ManMessageMono.Instance.GetECManPlayer.GetElsePlayer(m_idSelTarget);
EC_ElsePlayer pPlayer = pObject as EC_ElsePlayer;
if (pPlayer != null)
fTargetRag = pPlayer.GetTouchRadius();
}
if (fDist - fTargetRag > fAattackRange * 0.8f)
{
if (showMsg)
{
CECStringTab pStrTab = EC_Game.GetFixedMsgs();
pGameRun.AddChatMessage(pStrTab.GetWideString((int)FixedMsg.FIXMSG_TARGETISFAR),
(int)ChatChannel.GP_CHAT_SYSTEM);
}
return false;
}
byte byPVPMask = glb_BuildPVPMask(glb_GetForceAttackFlag(0));
UnityGameSession.c2s_SendCmdUseItemWithTarget((byte)iPack, (byte)iSlot, pItem.GetTemplateID(),
byPVPMask);
}
else
{
if (pItem.GetClassID() == (int)EC_IvtrItem.InventoryClassId.ICID_DOUBLEEXP)
{
EC_IvtrDoubleExp pDoubleExp = pItem as EC_IvtrDoubleExp;
if (pDoubleExp != null)
{
if (pDoubleExp.GetDBEssence().double_exp_time + pGameRun.GetRemainDblExpTime() > 3600 * 4)
{
if (showMsg)
{
CECGameUIMan pGameUI = pGameRun.GetUIManager().GetInGameUIMan();
//pGameUI.MessageBox("", pGameUI.GetStringFromTable(828), MB_OK, new Color32(1, 1, 1, 0.6));
}
return false;
}
}
}
if (pItem.GetClassID() == (int)EC_IvtrItem.InventoryClassId.ICID_SHARPENER)
{
if (showMsg)
pGameRun.AddFixedMessage((int)FixedMsg.FIXMSG_SHARPEN_ON_DRAG);
return false;
}
UnityGameSession.c2s_SendCmdUseItem((byte)iPack, (byte)iSlot, pItem.GetTemplateID(), 1);
}
return true;
}
public EC_Inventory GetPack(int iPack)
{
EC_Inventory pInventory = null;
switch (iPack)
{
case Inventory_type.IVTRTYPE_PACK: pInventory = m_pPack; break;
case Inventory_type.IVTRTYPE_EQUIPPACK: pInventory = m_pEquipPack; break;
case Inventory_type.IVTRTYPE_TASKPACK: pInventory = m_pTaskPack; break;
//case Inventory_type.IVTRTYPE_TRASHBOX: pInventory = m_pTrashBoxPack; break;
//case Inventory_type.IVTRTYPE_TRASHBOX2: pInventory = m_pTrashBoxPack2; break;
//case Inventory_type.IVTRTYPE_TRASHBOX3: pInventory = m_pTrashBoxPack3; break;
//case Inventory_type.IVTRTYPE_ACCOUNT_BOX: pInventory = m_pAccountBoxPack; break;
//case Inventory_type.IVTRTYPE_GENERALCARD_BOX: pInventory = m_pGeneralCardPack; break;
//case IVTRTYPE_PACK_CLIENT_GENERALCAR.IVTRTYPE_CLIENT_GENERALCARD_PACK: pInventory = m_pClientGenCardPack; break;
default:
return null;
}
return pInventory;
}
public int GetEquippedSuiteItem(int idSuite, ref int[] aItems)
{
int i, iItemCnt = 0;
for (i = 0; i < m_pEquipPack.GetSize(); i++)
{
var pItem = m_pEquipPack.GetItem(i);
if (pItem == null)
{
continue;
}
EC_IvtrEquip pEquip = (EC_IvtrEquip)pItem;
if (pEquip == null)
{
continue;
}
if (pEquip.GetSuiteID() != idSuite)
{
continue;
}
int iReason = 0;
if (!CanUseEquipment(pEquip, ref iReason))
{
continue;
}
if (pEquip.CID == (int)EC_IvtrEquip.EQUIP_CLASS_ID.ICID_GENERALCARD)
{
//TODO: Add general card Suite
}
if (aItems.Length > 0)
{
aItems[iItemCnt] = pEquip.GetTemplateID();
}
iItemCnt++;
}
return iItemCnt;
}
public bool CanUseEquipment(EC_IvtrEquip pEquip, ref int piReason)
{
int iReason = 0;
if (pEquip == null)
{
iReason = 1;
goto End;
}
if (GetMaxLevelSofar() < pEquip.LevelReq ||
m_ExtProps.bs.strength < pEquip.StrengthReq ||
m_ExtProps.bs.agility < pEquip.AgilityReq ||
m_ExtProps.bs.vitality < pEquip.VitalityReq ||
m_ExtProps.bs.energy < pEquip.EnergyReq /*||
Reputation < pEquip.ReputationReq*/) //todo Add reputation check
{
iReason = 2;
goto End;
}
switch (pEquip.CID) //class id
{
case (int)EC_IvtrEquip.EQUIP_CLASS_ID.ICID_ARROW:
break;
case (int)EC_IvtrEquip.EQUIP_CLASS_ID.ICID_WING:
if (m_iProfession != (int)PROFESSION.PROF_ARCHOR && m_iProfession != (int)PROFESSION.PROF_ANGEL)
iReason = 3;
break;
case (int)EC_IvtrEquip.EQUIP_CLASS_ID.ICID_FLYSWORD:
//TODO: Add flysword check
break;
case (int)EC_IvtrEquip.EQUIP_CLASS_ID.ICID_FASHION:
//TODO: Add fashion check
break;
case (int)EC_IvtrEquip.EQUIP_CLASS_ID.ICID_ARMOR:
case (int)EC_IvtrEquip.EQUIP_CLASS_ID.ICID_DECORATION:
if ((pEquip.ProfReq & (1 << m_iProfession)) == 0)
iReason = 3;
break;
case (int)EC_IvtrEquip.EQUIP_CLASS_ID.ICID_WEAPON:
if ((pEquip.ProfReq & (1 << m_iProfession)) == 0)
iReason = 3;
else
{
//TODO: check range weapon arrow
}
break;
case (int)EC_IvtrEquip.EQUIP_CLASS_ID.ICID_GENERALCARD:
// TODO: Add general card check
break;
default:
break;
}
End:
if (piReason > 0)
{
piReason = iReason;
}
return iReason == 0 ? true : false;
}
public bool CanTakeItem(int idItem, int iAmount)
{
bool bCanPick = false;
if (GPDataTypeHelper.ISMONEYTID(idItem))
{
if (GetMoneyAmount() < GetMaxMoneyAmount())
bCanPick = true;
}
else
{
if (IvtrPack.CanAddItem(idItem, iAmount, false) >= 0)
bCanPick = true;
}
return bCanPick;
}
}
}