1438 lines
58 KiB
C#
1438 lines
58 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);
|
|
if (newItem.Content != null && newItem.Content.Length > 0)
|
|
{
|
|
newItem.SetItemInfo(newItem.Content, newItem.Content.Length);
|
|
}
|
|
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;
|
|
}
|
|
}
|
|
} |