Files
test/Assets/PerfectWorld/Scripts/Objet/Shortcut/CECShortcutSet.cs
T
2026-03-23 16:26:40 +07:00

1281 lines
52 KiB
C#

/*
* FILE: CECShortcutSet.cs
*
* DESCRIPTION: Shortcut set management
*
* CREATED BY: Duyuxin, 2005/1/5
* CONVERTED TO C#: 2025
*
* HISTORY:
*
* Copyright (c) 2005 Archosaur Studio, All Rights Reserved.
*/
using static BrewMonster.CECSCCommand.CommandID;
using static BrewMonster.Scripts.RoleExpression;
using static BrewMonster.Scripts.DescriptipionMsg;
using BrewMonster.Assets.PerfectWorld.Scripts.Skills;
using BrewMonster.Network;
using BrewMonster.Scripts;
using BrewMonster.Scripts.Skills;
using CSNetwork.C2SCommand;
using CSNetwork.GPDataType;
using CSNetwork.S2CCommand;
using System;
using System.Collections.Generic;
using UnityEngine;
using static BrewMonster.EC_Resource;
using static BrewMonster.IconResourceType;
namespace BrewMonster
{
/// <summary>
/// Manages a set of shortcuts for quick access to items, skills, commands, etc.
/// </summary>
public class CECShortcutSet
{
#region Fields
private List<CECShortcut> m_aShortcuts; // Shortcut array
#endregion
#region Constructor and Destructor
public CECShortcutSet()
{
m_aShortcuts = new List<CECShortcut>();
}
#endregion
#region Initialization and Release
/// <summary>
/// Initialize the shortcut set with a specified size
/// </summary>
/// <param name="iSize">Number of shortcut slots</param>
/// <returns>True if successful</returns>
public bool Init(int iSize)
{
m_aShortcuts = new List<CECShortcut>(iSize);
for (int i = 0; i < iSize; i++)
{
m_aShortcuts.Add(null);
}
return true;
}
public CECShortcutSet Clone()
{
var temp = new CECShortcutSet();
temp.m_aShortcuts = new List<CECShortcut>(m_aShortcuts);
return temp;
}
/// <summary>
/// Release all shortcuts and clear the set
/// </summary>
public void Release()
{
// Clear all shortcuts
for (int i = 0; i < m_aShortcuts.Count; i++)
{
if (m_aShortcuts[i] != null)
{
// In C#, we don't need explicit deletion, just clear references
m_aShortcuts[i] = null;
}
}
m_aShortcuts.Clear();
}
#endregion
#region Shortcut Creation Methods
/// <summary>
/// Create an item shortcut at specified position
/// </summary>
/* public bool CreateItemShortcut(int iSlot, int iIvtr, int iIvtrSlot, CECIvtrItem pItem)
{
CECSCItem pItemSC = new CECSCItem();
if (pItemSC == null)
return false;
if (!pItemSC.Init(iIvtr, iIvtrSlot, pItem))
{
Debug.LogError("CECShortcutSet::CreateItemShortcut, Failed to initialize item shortcut");
return false;
}
SetShortcut(iSlot, pItemSC);
return true;
}*/
/// <summary>
/// Create a skill shortcut at specified position
/// </summary>
public bool CreateSkillShortcut(int iSlot, CECSkill pSkill)
{
CECSCSkill pSkillSC = new CECSCSkill();
if (pSkillSC == null)
return false;
if (!pSkillSC.Init(pSkill))
{
Debug.LogError("CECShortcutSet::CreateSkillShortcut, Failed to initialize skill shortcut");
return false;
}
SetShortcut(iSlot, pSkillSC);
return true;
}
/// <summary>
/// Create a skill group shortcut at specified position
/// </summary>
public bool CreateSkillGroupShortcut(int iSlot, int iGroupIdx)
{
CECSCSkillGrp pSkillGrpSC = new CECSCSkillGrp();
if (pSkillGrpSC == null)
return false;
if (!pSkillGrpSC.Init(iGroupIdx))
{
Debug.LogError("CECShortcutSet::CreateSkillGroupShortcut, Failed to initialize skill group shortcut");
return false;
}
SetShortcut(iSlot, pSkillGrpSC);
return true;
}
/// <summary>
/// Create a pet shortcut at specified position
/// </summary>
/* public bool CreatePetShortcut(int iSlot, int iPetIndex)
{
CECSCPet pPetSC = new CECSCPet();
if (pPetSC == null)
return false;
if (!pPetSC.Init(iPetIndex))
{
Debug.LogError("CECShortcutSet::CreatePetShortcut, Failed to initialize pet shortcut");
return false;
}
SetShortcut(iSlot, pPetSC);
return true;
}*/
/// <summary>
/// Create an auto fashion shortcut at specified position
/// </summary>
// public bool CreateAutoFashionShortcut(int iSlot, int iFashionIdx)
// {
// CECSCAutoFashion pAutoFashionSC = new CECSCAutoFashion();
// if (pAutoFashionSC == null)
// return false;
//
// if (!pAutoFashionSC.Init(iFashionIdx))
// {
// Debug.LogError("CECShortcutSet::CreateAutoFashionShortcut, Failed to initialize auto fashion shortcut");
// return false;
// }
//
// SetShortcut(iSlot, pAutoFashionSC);
// return true;
// }
/// <summary>
/// Create a system module shortcut at specified position
/// </summary>
public bool CreateSystemModuleShortcut(int iSlot, int iSys)
{
CECSCSysModule pSysModule = new CECSCSysModule();
if (pSysModule == null)
return false;
if (!pSysModule.Init(iSys))
{
Debug.LogError("CECShortcutSet::CreateSystemModuleShortcut, Failed to initialize system module shortcut");
return false;
}
SetShortcut(iSlot, pSysModule);
return true;
}
/// <summary>
/// Duplicate a shortcut to specified position
/// </summary>
/* public bool CreateClonedShortcut(int iSlot, CECShortcut pShortcut)
{
CECShortcut pDest = pShortcut.Clone();
if (pDest == null)
return false;
SetShortcut(iSlot, pDest);
return true;
}*/
#endregion
#region Shortcut Management
/// <summary>
/// Put a shortcut into set and return the old shortcut at that position
/// </summary>
/// <param name="iSlot">Slot index</param>
/// <param name="pShortcut">Shortcut to place</param>
/// <returns>Previous shortcut at that position</returns>
public CECShortcut PutShortcut(int iSlot, CECShortcut pShortcut)
{
if (iSlot < 0 || iSlot >= m_aShortcuts.Count)
return null;
CECShortcut pOldShortcut = m_aShortcuts[iSlot];
m_aShortcuts[iSlot] = pShortcut;
return pOldShortcut;
}
/// <summary>
/// Get a shortcut from set
/// </summary>
/// <param name="iSlot">Slot index</param>
/// <param name="bRemove">If true, remove the shortcut from the set</param>
/// <returns>Shortcut at the specified position</returns>
public CECShortcut GetShortcut(int iSlot, bool bRemove = false)
{
if (iSlot < 0 || iSlot >= m_aShortcuts.Count)
return null;
CECShortcut pShortcut = m_aShortcuts[iSlot];
if (bRemove)
m_aShortcuts[iSlot] = null;
return pShortcut;
}
/// <summary>
/// Set a shortcut into set and release old shortcut at this position automatically
/// </summary>
public void SetShortcut(int iSlot, CECShortcut pShortcut)
{
if (iSlot < 0 || iSlot >= m_aShortcuts.Count)
return;
// Clear old shortcut (C# garbage collection will handle cleanup)
if (m_aShortcuts[iSlot] != null)
{
m_aShortcuts[iSlot] = null;
}
// BMLogger.LogError("SetShortcut iSlot= " + iSlot);
m_aShortcuts[iSlot] = pShortcut;
}
/// <summary>
/// Exchange shortcuts in two slots
/// </summary>
public void ExchangeShortcut(int iSlot1, int iSlot2)
{
if (iSlot1 < 0 || iSlot1 >= m_aShortcuts.Count ||
iSlot2 < 0 || iSlot2 >= m_aShortcuts.Count)
return;
if (iSlot1 != iSlot2)
{
CECShortcut pShortcut = m_aShortcuts[iSlot1];
m_aShortcuts[iSlot1] = m_aShortcuts[iSlot2];
m_aShortcuts[iSlot2] = pShortcut;
}
}
/// <summary>
/// Remove all shortcuts
/// </summary>
public void RemoveAllShortcuts()
{
for (int i = 0; i < m_aShortcuts.Count; i++)
{
if (m_aShortcuts[i] != null)
{
m_aShortcuts[i] = null;
}
}
}
/// <summary>
/// Remove skill and skill group shortcuts
/// </summary>
public void RemoveSkillShortcuts()
{
for (int i = 0; i < m_aShortcuts.Count; i++)
{
CECShortcut pSC = m_aShortcuts[i];
if (pSC == null)
continue;
if (pSC.GetType() == (int)CECShortcut.ShortcutType.SCT_SKILL ||
pSC.GetType() == (int)CECShortcut.ShortcutType.SCT_SKILLGRP)
{
m_aShortcuts[i] = null;
}
}
}
#endregion
#region Update Methods
/// <summary>
/// Update item shortcut when item position changed
/// </summary>
/* public void UpdateMovedItemSC(int tidItem, int iSrcIvtr, int iSrcSlot, int iDstIvtr, int iDstSlot)
{
for (int i = 0; i < m_aShortcuts.Count; i++)
{
CECShortcut pSC = m_aShortcuts[i];
if (pSC == null || pSC.GetType() != CECShortcut.ShortcutType.SCT_ITEM)
continue;
CECSCItem pItemSC = (CECSCItem)pSC;
if (pItemSC.GetInventory() == iSrcIvtr && pItemSC.GetIvtrSlot() == iSrcSlot)
{
Debug.Assert(pItemSC.GetItemTID() == tidItem);
pItemSC.MoveItem(iDstIvtr, iDstSlot);
}
}
}*/
/// <summary>
/// Update item shortcut when item removed
/// </summary>
/* public void UpdateRemovedItemSC(int tidItem, int iIvtr, int iSlot, int iSameItem)
{
for (int i = 0; i < m_aShortcuts.Count; i++)
{
CECShortcut pSC = m_aShortcuts[i];
if (pSC == null || pSC.GetType() != CECShortcut.ShortcutType.SCT_ITEM)
continue;
CECSCItem pItemSC = (CECSCItem)pSC;
if (pItemSC.GetInventory() == iIvtr && pItemSC.GetIvtrSlot() == iSlot)
{
Debug.Assert(pItemSC.GetItemTID() == tidItem);
if (pItemSC.GetAutoFindFlag() && iSameItem >= 0)
pItemSC.MoveItem(iIvtr, iSameItem);
else
SetShortcut(i, null);
}
}
}*/
/// <summary>
/// Update item shortcut when two items exchanged
/// </summary>
/*public void UpdateExchangedItemSC(int tidItem1, int iIvtr1, int iSlot1,
int tidItem2, int iIvtr2, int iSlot2)
{
for (int i = 0; i < m_aShortcuts.Count; i++)
{
CECShortcut pSC = m_aShortcuts[i];
if (pSC == null || pSC.GetType() != CECShortcut.ShortcutType.SCT_ITEM)
continue;
CECSCItem pItemSC = (CECSCItem)pSC;
if (pItemSC.GetInventory() == iIvtr1 && pItemSC.GetIvtrSlot() == iSlot1)
{
Debug.Assert(pItemSC.GetItemTID() == tidItem1);
pItemSC.MoveItem(iIvtr2, iSlot2);
}
else if (pItemSC.GetInventory() == iIvtr2 && pItemSC.GetIvtrSlot() == iSlot2)
{
Debug.Assert(pItemSC.GetItemTID() == tidItem2);
pItemSC.MoveItem(iIvtr1, iSlot1);
}
}
}
/// <summary>
/// Update pet shortcut when pet freed
/// </summary>
public void UpdateFreedPetSC(int iPetIndex)
{
for (int i = 0; i < m_aShortcuts.Count; i++)
{
CECShortcut pSC = m_aShortcuts[i];
if (pSC == null || pSC.GetType() != CECShortcut.ShortcutType.SCT_PET)
continue;
CECSCPet pPetSC = (CECSCPet)pSC;
if (pPetSC.GetPetIndex() == iPetIndex)
SetShortcut(i, null);
}
}*/
#endregion
#region Skill Management
/// <summary>
/// Replace skill id in skill shortcuts
/// </summary>
public void ReplaceSkillID(int idOld, CECSkill pNewSkill)
{
for (int i = 0; i < m_aShortcuts.Count; i++)
{
CECShortcut pSC = m_aShortcuts[i];
if (pSC == null || pSC.GetType() != (int)CECShortcut.ShortcutType.SCT_SKILL)
continue;
// Replace skill
CECSCSkill pSkillSC = (CECSCSkill)pSC;
CECSkill pSkill = pSkillSC.GetSkill();
if (pSkill.GetSkillID() == idOld)
pSkillSC.SetSkill(pNewSkill);
}
}
/// <summary>
/// Replace skill id in skill shortcuts using skill array
/// </summary>
public void ReplaceSkillID(SkillArrayWrapper skillArray, CECSkill pNewSkill)
{
for (int i = 0; i < skillArray.Count(); i++)
{
ReplaceSkillID((int)skillArray[i], pNewSkill);
}
}
/// <summary>
/// Remove skill shortcut by skill ID
/// </summary>
public bool RemoveSkillShortcut(int idSkill)
{
bool bRemove = false;
for (int i = 0; i < GetShortcutNum(); i++)
{
CECShortcut pSC = GetShortcut(i);
if (pSC == null)
continue;
if (pSC.GetType() == (int)CECShortcut.ShortcutType.SCT_SKILL)
{
CECSCSkill pSkillSC = (CECSCSkill)pSC;
CECSkill pSkill = pSkillSC.GetSkill();
if (pSkill != null && pSkill.GetSkillID() == idSkill)
{
SetShortcut(i, null);
bRemove = true;
continue;
}
}
}
return bRemove;
}
#endregion
#region Serialization
/// <summary>
/// Save shortcut configs to specified buffer
/// </summary>
public bool SaveConfigData(out byte[] dataBuffer)
{
List<byte> data = new List<byte>();
for (int i = 0; i < m_aShortcuts.Count; i++)
{
CECShortcut pSC = m_aShortcuts[i];
if (pSC == null)
continue;
// Record shortcut's position and type
data.AddRange(BitConverter.GetBytes(i));
data.AddRange(BitConverter.GetBytes((int)pSC.GetType()));
BMLogger.Log($"[MH] Saving shortcut slot: {i} Type: {pSC.GetType()}");
// TODO: implement other shortcut types
switch ((CECShortcut.ShortcutType)pSC.GetType())
{
/* case CECShortcut.ShortcutType.SCT_COMMAND:
{
CECSCCommand cmdSC = (CECSCCommand)pSC;
data.AddRange(BitConverter.GetBytes(cmdSC.GetCommandID()));
data.AddRange(BitConverter.GetBytes((int)cmdSC.GetParam()));
break;
}
*/
case CECShortcut.ShortcutType.SCT_SKILL:
{
CECSCSkill skillSC = (CECSCSkill)pSC;
data.AddRange(BitConverter.GetBytes(skillSC.GetSkill().GetSkillID()));
break;
}
// case CECShortcut.ShortcutType.SCT_ITEM:
// {
// CECSCItem itemSC = (CECSCItem)pSC;
// data.AddRange(BitConverter.GetBytes(itemSC.GetInventory()));
// data.AddRange(BitConverter.GetBytes(itemSC.GetIvtrSlot()));
// data.AddRange(BitConverter.GetBytes(itemSC.GetItemTID()));
// break;
// }
case CECShortcut.ShortcutType.SCT_SKILLGRP:
{
CECSCSkillGrp skillGrpSC = (CECSCSkillGrp)pSC;
data.AddRange(BitConverter.GetBytes(skillGrpSC.GetGroupIndex()));
break;
}
// case CECShortcut.ShortcutType.SCT_PET:
// {
// CECSCPet petSC = (CECSCPet)pSC;
// data.AddRange(BitConverter.GetBytes(petSC.GetPetIndex()));
// break;
// }
//
// case CECShortcut.ShortcutType.SCT_AUTOFASHION:
// {
// CECSCAutoFashion fashionSC = (CECSCAutoFashion)pSC;
// data.AddRange(BitConverter.GetBytes(fashionSC.GetAutoFashionIndex()));
// break;
// }
case CECShortcut.ShortcutType.SCT_SYSMODULE:
{
CECSCSysModule sysSC = (CECSCSysModule)pSC;
data.AddRange(BitConverter.GetBytes(sysSC.GetSysModID()));
break;
}
default:
Debug.LogError($"CECShortcutSet::SaveConfigData - Unknown shortcut type = { pSC.GetType()}");
break;
}
}
// Add the end flag
data.AddRange(BitConverter.GetBytes(-1));
dataBuffer = data.ToArray();
return true;
}
/// <summary>
/// Load shortcut configs from specified buffer
/// </summary>
public bool LoadConfigData(byte[] pDataBuf, uint dwVer, ref int offset)
{
if (pDataBuf == null || pDataBuf.Length == 0)
{
return false;
}
CECGameRun pGameRun = EC_Game.GetGameRun();
CECHostPlayer pHost = pGameRun.GetHostPlayer();
Debug.Assert(pHost != null);
while (offset < pDataBuf.Length)
{
int iSlot = GPDataTypeHelper.FromBytes<int>(pDataBuf, offset);
offset += sizeof(int);
if (iSlot < 0)
break; // Meet end flag
int iSCType = GPDataTypeHelper.FromBytes<int>(pDataBuf, offset);
offset += sizeof(int);
//BMLogger.Log("[MH] Loading shortcut slot: " + iSlot + " Type: " + iSCType);
switch ((CECShortcut.ShortcutType)iSCType)
{
/*case CECShortcut.ShortcutType.SCT_COMMAND:
{
int iCommand = BitConverter.ToInt32(pDataBuf, offset);
offset += sizeof(int);
int iParam = 0;
if (dwVer >= 2)
{
iParam = BitConverter.ToInt32(pDataBuf, offset);
offset += sizeof(int);
}
CECSCCommand pCmdSC = null;
if (iCommand == CECSCCommand.CMD_PLAYPOSE)
pCmdSC = pGameRun.GetPoseCmdShortcut(iParam);
else
pCmdSC = pGameRun.GetCmdShortcut(iCommand);
if (pCmdSC != null)
CreateClonedShortcut(iSlot, pCmdSC);
break;
}*/
case CECShortcut.ShortcutType.SCT_SKILL:
{
int idSkill = BitConverter.ToInt32(pDataBuf, offset);
offset += sizeof(int);
CECSkill pSkill = pHost.GetPositiveSkillByID(idSkill, true);
if (pSkill == null)
pSkill = pHost.GetEquipSkillByID(idSkill);
CECSkill pSkill2 = null;
/* CECHostGoblin pGoblin = (CECHostGoblin)pHost.GetGoblinModel();
if (pGoblin != null)
{
pSkill2 = pGoblin.GetSkillByID(idSkill);
}*/
if (pSkill != null)
CreateSkillShortcut(iSlot, pSkill);
else if (pSkill2 != null)
CreateSkillShortcut(iSlot, pSkill2);
break;
}
/* case CECShortcut.ShortcutType.SCT_ITEM:
{
int iPack = BitConverter.ToInt32(pDataBuf, offset);
offset += sizeof(int);
int iIvtrSlot = BitConverter.ToInt32(pDataBuf, offset);
offset += sizeof(int);
int idItem = BitConverter.ToInt32(pDataBuf, offset);
offset += sizeof(int);
CECInventory pPack = pHost.GetPack(iPack);
if (pPack == null)
{
Debug.LogError("CECShortcutSet::LoadConfigData - Invalid inventory");
return false;
}
CECIvtrItem pItem = pPack.GetItem(iIvtrSlot);
if (pItem != null)
CreateItemShortcut(iSlot, iPack, iIvtrSlot, pItem);
break;
}*/
case CECShortcut.ShortcutType.SCT_SKILLGRP:
{
if (dwVer >= 3)
{
int iGroupIdx = BitConverter.ToInt32(pDataBuf, offset);
offset += sizeof(int);
if (iGroupIdx >= 0)
CreateSkillGroupShortcut(iSlot, iGroupIdx);
}
else
{
Debug.LogError("CECShortcutSet::LoadConfigData - Invalid version for skill group");
return false;
}
break;
}
// case CECShortcut.ShortcutType.SCT_PET:
// {
// if (dwVer >= 4)
// {
// int iPetIndex = BitConverter.ToInt32(pDataBuf, offset);
// offset += sizeof(int);
//
// if (iPetIndex >= 0)
// CreatePetShortcut(iSlot, iPetIndex);
// }
// else
// {
// Debug.LogError("CECShortcutSet::LoadConfigData - Invalid version for pet");
// return false;
// }
// break;
// }
//
// case CECShortcut.ShortcutType.SCT_AUTOFASHION:
// {
// if (dwVer >= 5)
// {
// int iAutoFashionIndex = BitConverter.ToInt32(pDataBuf, offset);
// offset += sizeof(int);
//
// if (iAutoFashionIndex >= 0)
// CreateAutoFashionShortcut(iSlot, iAutoFashionIndex);
// }
// else
// {
// Debug.LogError("CECShortcutSet::LoadConfigData - Invalid version for auto fashion");
// return false;
// }
// break;
// }
case CECShortcut.ShortcutType.SCT_SYSMODULE:
{
if (dwVer > 10)
{
int iSys = BitConverter.ToInt32(pDataBuf, offset);
offset += sizeof(int);
if (iSys >= 0)
CreateSystemModuleShortcut(iSlot, iSys);
}
else
{
Debug.LogError("CECShortcutSet::LoadConfigData - Invalid version for system module");
return false;
}
break;
}
/* default:
//TODO: uncomment
//BMLogger.LogError("CECShortcutSet::LoadConfigData - Unknown shortcut type");
return false;*/
}
}
return true;
}
#endregion
#region Properties
/// <summary>
/// Get the number of shortcuts in the set
/// </summary>
public int GetShortcutNum()
{
if(m_aShortcuts == null || m_aShortcuts.Count == 0)
{
return 0;
}
return m_aShortcuts.Count;
}
#endregion
}
#region Placeholder Classes
// These classes are referenced but not defined in the provided files
// They should be implemented separately based on EC_Shortcut.h/cpp
[Serializable]
public class CECShortcut
{
protected int m_iSCType;
public CECShortcut() { m_iSCType = (int)ShortcutType.SCT_UNKNOWN; }
public enum ShortcutType
{
SCT_UNKNOWN = -1,
SCT_SKILL = 0,
SCT_ITEM,
SCT_COMMAND,
SCT_SKILLGRP,
SCT_PET,
SCT_AUTOFASHION,
SCT_SYSMODULE,
}
public virtual int GetType()
{
return m_iSCType;
}
public virtual string GetDesc() { return ""; }
public virtual CECShortcut Clone()
{
return new CECShortcut();
}
public virtual bool Execute() { return true; }
public virtual int GetCoolTime(ref int piMax)
{
piMax = 0;
return 0;
}
public virtual string GetIconFile()
{
// Return a default icon file name
return "unknown";
}
}
// Shortcut type
public enum ShortcutType
{
SCT_UNKNOWN = -1,
SCT_SKILL = 0,
SCT_ITEM,
SCT_COMMAND,
SCT_SKILLGRP,
SCT_PET,
SCT_AUTOFASHION,
SCT_SYSMODULE,
};
public class CECSCCommand : CECShortcut
{
private int m_iCommand; // Command ID
private uint m_dwParam; // Parameter
public enum CommandID
{
CMD_UNKNOWN = -1,
CMD_SITDOWN = 0,
CMD_WALKRUN,
CMD_NORMALATTACK,
CMD_FINDTARGET,
CMD_ASSISTATTACK,
CMD_INVITETOTEAM,
CMD_LEAVETEAM,
CMD_KICKTEAMMEM,
CMD_FINDTEAM,
CMD_STARTTRADE,
CMD_SELLBOOTH,
CMD_BUYBOOTH,
CMD_PLAYPOSE,
CMD_INVITETOFACTION,
CMD_FLY,
CMD_PICKUP,
CMD_GATHER,
CMD_RUSHFLY,
CMD_BINDBUDDY,
}
public CECSCCommand(int iCommand)
{
m_iSCType = (int)ShortcutType.SCT_COMMAND;
m_iCommand = iCommand;
m_dwParam = 0;
}
public override string GetDesc()
{
CECStringTab pDescTab = EC_Game.GetItemDesc();
string szDesc = ("");
switch ((CommandID)m_iCommand)
{
case CMD_SITDOWN: szDesc = pDescTab.GetWideString((int)CMDDESC_SITDOWN); break;
case CMD_WALKRUN: szDesc = pDescTab.GetWideString((int)CMDDESC_WALKRUN); break;
case CMD_NORMALATTACK: szDesc = pDescTab.GetWideString((int)CMDDESC_NORMALATTACK); break;
case CMD_FINDTARGET: szDesc = pDescTab.GetWideString((int)CMDDESC_FINDTARGET); break;
case CMD_ASSISTATTACK: szDesc = pDescTab.GetWideString((int)CMDDESC_ASSISTATTACK); break;
case CMD_INVITETOTEAM: szDesc = pDescTab.GetWideString((int)CMDDESC_INVITETOTEAM); break;
case CMD_LEAVETEAM: szDesc = pDescTab.GetWideString((int)CMDDESC_LEAVETEAM); break;
case CMD_KICKTEAMMEM: szDesc = pDescTab.GetWideString((int)CMDDESC_KICKTEAMMEM); break;
case CMD_FINDTEAM: szDesc = pDescTab.GetWideString((int)CMDDESC_FINDTEAM); break;
case CMD_STARTTRADE: szDesc = pDescTab.GetWideString((int)CMDDESC_STARTTRADE); break;
case CMD_SELLBOOTH: szDesc = pDescTab.GetWideString((int)CMDDESC_SELLBOOTH); break;
case CMD_BUYBOOTH: szDesc = pDescTab.GetWideString((int)CMDDESC_BUYBOOTH); break;
case CMD_INVITETOFACTION: szDesc = pDescTab.GetWideString((int)CMDDESC_INVITETOFACTION); break;
case CMD_FLY: szDesc = pDescTab.GetWideString((int)CMDDESC_FLY); break;
case CMD_PICKUP: szDesc = pDescTab.GetWideString((int)CMDDESC_PICKUP); break;
case CMD_GATHER: szDesc = pDescTab.GetWideString((int)CMDDESC_GATHER); break;
case CMD_RUSHFLY: szDesc = pDescTab.GetWideString((int)CMDDESC_RUSHFLY); break;
case CMD_BINDBUDDY: szDesc = pDescTab.GetWideString((int)CMDDESC_BINDBUDDY); break;
case CMD_PLAYPOSE:
{
switch ((RoleExpression)m_dwParam)
{
case ROLEEXP_WAVE: szDesc = pDescTab.GetWideString((int)FACEDESC_WAVEHAND); break;
case ROLEEXP_NOD: szDesc = pDescTab.GetWideString((int)FACEDESC_NOD); break;
case ROLEEXP_SHAKEHEAD: szDesc = pDescTab.GetWideString((int)FACEDESC_SHADEHEAD); break;
case ROLEEXP_SHRUG: szDesc = pDescTab.GetWideString((int)FACEDESC_SHRUG); break;
case ROLEEXP_LAUGH: szDesc = pDescTab.GetWideString((int)FACEDESC_LAUGH); break;
case ROLEEXP_ANGRY: szDesc = pDescTab.GetWideString((int)FACEDESC_ANGRY); break;
case ROLEEXP_STUN: szDesc = pDescTab.GetWideString((int)FACEDESC_FAINT); break;
case ROLEEXP_DEPRESSED: szDesc = pDescTab.GetWideString((int)FACEDESC_SAD); break;
case ROLEEXP_KISSHAND: szDesc = pDescTab.GetWideString((int)FACEDESC_KISSHAND); break;
case ROLEEXP_SHY: szDesc = pDescTab.GetWideString((int)FACEDESC_SHY); break;
case ROLEEXP_SALUTE: szDesc = pDescTab.GetWideString((int)FACEDESC_SALUTE); break;
case ROLEEXP_SITDOWN: szDesc = pDescTab.GetWideString((int)FACEDESC_SITDOWN); break;
case ROLEEXP_ASSAULT: szDesc = pDescTab.GetWideString((int)FACEDESC_CHARGE); break;
case ROLEEXP_THINK: szDesc = pDescTab.GetWideString((int)FACEDESC_THINK); break;
case ROLEEXP_DEFIANCE: szDesc = pDescTab.GetWideString((int)FACEDESC_CHALLENGE); break;
case ROLEEXP_VICTORY: szDesc = pDescTab.GetWideString((int)FACEDESC_WIN); break;
case ROLEEXP_GAPE: szDesc = pDescTab.GetWideString((int)FACEDESC_GAPE); break;
case ROLEEXP_KISS: szDesc = pDescTab.GetWideString((int)FACEDESC_KISS); break;
case ROLEEXP_FIGHT: szDesc = pDescTab.GetWideString((int)FACEDESC_FIGHT); break;
case ROLEEXP_ATTACK1: szDesc = pDescTab.GetWideString((int)FACEDESC_ATTACK1); break;
case ROLEEXP_ATTACK2: szDesc = pDescTab.GetWideString((int)FACEDESC_ATTACK2); break;
case ROLEEXP_ATTACK3: szDesc = pDescTab.GetWideString((int)FACEDESC_ATTACK3); break;
case ROLEEXP_ATTACK4: szDesc = pDescTab.GetWideString((int)FACEDESC_ATTACK4); break;
case ROLEEXP_DEFENCE: szDesc = pDescTab.GetWideString((int)FACEDESC_DEFENCE); break;
case ROLEEXP_FALL: szDesc = pDescTab.GetWideString((int)FACEDESC_FALL); break;
case ROLEEXP_FALLONGROUND: szDesc = pDescTab.GetWideString((int)FACEDESC_FALLONGROUND); break;
case ROLEEXP_LOOKAROUND: szDesc = pDescTab.GetWideString((int)FACEDESC_LOOKAROUND); break;
case ROLEEXP_DANCE: szDesc = pDescTab.GetWideString((int)FACEDESC_DANCE); break;
case ROLEEXP_FASHIONWEAPON: szDesc = pDescTab.GetWideString((int)FACEDESC_FASHIONWEAPON); break;
default:
break;
}
break;
}
default:
return ("");
}
return szDesc;
}
public CECSCCommand(CECSCCommand src)
{
m_iCommand = src.m_iCommand;
m_dwParam = src.m_dwParam;
}
public override CECShortcut Clone() => new CECSCCommand(this);
public int GetCommandID() => m_iCommand;
public int GetParam() => (int)m_dwParam;
// Set / Get command parameter
public void SetParam(uint dwParam) { m_dwParam = dwParam; }
// Execute shortcut
public override bool Execute()
{
CECHostPlayer pHost = CECGameRun.Instance.GetHostPlayer();
if (!pHost || !pHost.IsAllResReady())
return false;
// if (GetCoolTime(0)>0)
// {
// bool bForbidCmd = true;
// if (m_iCommand == CMD_RUSHFLY && pHost.GetRushFlyFlag())
// bForbidCmd = false;
//
// if (bForbidCmd)
// {
// g_pGame.GetGameRun().AddFixedMessage(FIXMSG_CMD_INCOOLTIME);
// return false;
// }
// }
switch (m_iCommand)
{
// case CMD_SITDOWN: pHost.CmdSitDown(!pHost.IsSitting()); break;
// case CMD_WALKRUN: pHost.CmdWalkRun(!pHost.GetWalkRunFlag()); break;
// case CMD_NORMALATTACK: pHost.CmdNormalAttack(); break;
// case CMD_FINDTARGET: pHost.CmdFindTarget(); break;
// case CMD_ASSISTATTACK: pHost.CmdAssistAttack(); break;
// case CMD_INVITETOTEAM: pHost.CmdInviteToTeam(); break;
// case CMD_LEAVETEAM: pHost.CmdLeaveTeam(); break;
// case CMD_KICKTEAMMEM: pHost.CmdKickTeamMember(); break;
// case CMD_FINDTEAM: pHost.CmdFindTeam(); break;
// case CMD_STARTTRADE: pHost.CmdStartTrade(); break;
// case CMD_SELLBOOTH: pHost.CmdSellBooth(); break;
// case CMD_BUYBOOTH: pHost.CmdBuyBooth(); break;
case (int)CommandID.CMD_PLAYPOSE: pHost.CmdStartPose((int)m_dwParam); break;
// case CMD_INVITETOFACTION: pHost.CmdInviteToFaction(); break;
case (int)CommandID.CMD_FLY:
{
// 如果骑乘要飞行,则这些 action switcher,否则 CmdFly
// If riding wants to fly, then these action switcher, otherwise CmdFly
// Call CmdFly(true) to match F4 key behavior
pHost.CmdFly(true);
break;
}
// case CMD_PICKUP: pHost.CmdPickup(); break;
// case CMD_GATHER: pHost.CmdGather(); break;
// case CMD_RUSHFLY: pHost.CmdRushFly(); break;
// case CMD_BINDBUDDY: pHost.CmdBindBuddy(pHost.GetSelectedTarget()); break;
default:
return false;
}
return true;
}
public override string GetIconFile()
{
string szIconFile = "";
switch ((CommandID)m_iCommand)
{
case CommandID.CMD_SITDOWN: szIconFile = res_IconFile((int)IconResourceType.RES_ICON_CMD_SITDOWN); break;
case CommandID.CMD_WALKRUN: szIconFile = res_IconFile((int)IconResourceType.RES_ICON_CMD_WALKRUN); break;
case CommandID.CMD_NORMALATTACK: szIconFile = res_IconFile((int)IconResourceType.RES_ICON_CMD_NORMALATTACK); break;
case CommandID.CMD_FINDTARGET: szIconFile = res_IconFile((int)IconResourceType.RES_ICON_CMD_FINDTARGET); break;
case CommandID.CMD_ASSISTATTACK: szIconFile = res_IconFile((int)IconResourceType.RES_ICON_CMD_ASSISTATTACK); break;
case CommandID.CMD_INVITETOTEAM: szIconFile = res_IconFile((int)IconResourceType.RES_ICON_CMD_INVITETOTEAM); break;
case CommandID.CMD_LEAVETEAM: szIconFile = res_IconFile((int)IconResourceType.RES_ICON_CMD_LEAVETEAM); break;
case CommandID.CMD_KICKTEAMMEM: szIconFile = res_IconFile((int)IconResourceType.RES_ICON_CMD_KICKTEAMMEM); break;
case CommandID.CMD_FINDTEAM: szIconFile = res_IconFile((int)IconResourceType.RES_ICON_CMD_FINDTEAM); break;
case CommandID.CMD_STARTTRADE: szIconFile = res_IconFile((int)IconResourceType.RES_ICON_CMD_STARTTRADE); break;
case CommandID.CMD_SELLBOOTH: szIconFile = res_IconFile((int)IconResourceType.RES_ICON_CMD_SELLBOOTH); break;
case CommandID.CMD_BUYBOOTH: szIconFile = res_IconFile((int)IconResourceType.RES_ICON_CMD_BUYBOOTH); break;
case CommandID.CMD_INVITETOFACTION: szIconFile = res_IconFile((int)IconResourceType.RES_ICON_CMD_INVITETOFACTION); break;
case CommandID.CMD_FLY: szIconFile = res_IconFile((int)IconResourceType.RES_ICON_CMD_FLY); break;
case CommandID.CMD_PICKUP: szIconFile = res_IconFile((int)IconResourceType.RES_ICON_CMD_PICKUP); break;
case CommandID.CMD_GATHER: szIconFile = res_IconFile((int)IconResourceType.RES_ICON_CMD_GATHER); break;
case CommandID.CMD_RUSHFLY: szIconFile = res_IconFile((int)IconResourceType.RES_ICON_CMD_RUSHFLY); break;
case CommandID.CMD_BINDBUDDY: szIconFile = res_IconFile((int)IconResourceType.RES_ICON_CMD_BINDBUDDY); break;
case CommandID.CMD_PLAYPOSE:
{
switch ((RoleExpression)m_dwParam)
{
case RoleExpression.ROLEEXP_WAVE: szIconFile = res_IconFile((int)IconResourceType.RES_ICON_CMD_EXP_WAVE); break;
case RoleExpression.ROLEEXP_NOD: szIconFile = res_IconFile((int)IconResourceType.RES_ICON_CMD_EXP_NOD); break;
case RoleExpression.ROLEEXP_SHAKEHEAD: szIconFile = res_IconFile((int)IconResourceType.RES_ICON_CMD_EXP_SHAKEHEAD); break;
case RoleExpression.ROLEEXP_SHRUG: szIconFile = res_IconFile((int)IconResourceType.RES_ICON_CMD_EXP_SHRUG); break;
case RoleExpression.ROLEEXP_LAUGH: szIconFile = res_IconFile((int)IconResourceType.RES_ICON_CMD_EXP_LAUGH); break;
case RoleExpression.ROLEEXP_ANGRY: szIconFile = res_IconFile((int)IconResourceType.RES_ICON_CMD_EXP_ANGRY); break;
case RoleExpression.ROLEEXP_STUN: szIconFile = res_IconFile((int)IconResourceType.RES_ICON_CMD_EXP_STUN); break;
case RoleExpression.ROLEEXP_DEPRESSED: szIconFile = res_IconFile((int)IconResourceType.RES_ICON_CMD_EXP_DEPRESSED); break;
case RoleExpression.ROLEEXP_KISSHAND: szIconFile = res_IconFile((int)IconResourceType.RES_ICON_CMD_EXP_KISSHAND); break;
case RoleExpression.ROLEEXP_SHY: szIconFile = res_IconFile((int)IconResourceType.RES_ICON_CMD_EXP_SHY); break;
case RoleExpression.ROLEEXP_SALUTE: szIconFile = res_IconFile((int)IconResourceType.RES_ICON_CMD_EXP_SALUTE); break;
case RoleExpression.ROLEEXP_SITDOWN: szIconFile = res_IconFile((int)IconResourceType.RES_ICON_CMD_EXP_SITDOWN); break;
case RoleExpression.ROLEEXP_ASSAULT: szIconFile = res_IconFile((int)IconResourceType.RES_ICON_CMD_EXP_ASSAULT); break;
case RoleExpression.ROLEEXP_THINK: szIconFile = res_IconFile((int)IconResourceType.RES_ICON_CMD_EXP_THINK); break;
case RoleExpression.ROLEEXP_DEFIANCE: szIconFile = res_IconFile((int)IconResourceType.RES_ICON_CMD_EXP_DEFIANCE); break;
case RoleExpression.ROLEEXP_VICTORY: szIconFile = res_IconFile((int)IconResourceType.RES_ICON_CMD_EXP_VICTORY); break;
case RoleExpression.ROLEEXP_GAPE: szIconFile = res_IconFile((int)IconResourceType.RES_ICON_CMD_EXP_GAPE); break;
case RoleExpression.ROLEEXP_KISS: szIconFile = res_IconFile((int)IconResourceType.RES_ICON_CMD_EXP_KISS); break;
case RoleExpression.ROLEEXP_FIGHT: szIconFile = res_IconFile((int)IconResourceType.RES_ICON_CMD_EXP_FIGHT); break;
case RoleExpression.ROLEEXP_ATTACK1: szIconFile = res_IconFile((int)IconResourceType.RES_ICON_CMD_EXP_ATTACK1); break;
case RoleExpression.ROLEEXP_ATTACK2: szIconFile = res_IconFile((int)IconResourceType.RES_ICON_CMD_EXP_ATTACK2); break;
case RoleExpression.ROLEEXP_ATTACK3: szIconFile = res_IconFile((int)IconResourceType.RES_ICON_CMD_EXP_ATTACK3); break;
case RoleExpression.ROLEEXP_ATTACK4: szIconFile = res_IconFile((int)IconResourceType.RES_ICON_CMD_EXP_ATTACK4); break;
case RoleExpression.ROLEEXP_DEFENCE: szIconFile = res_IconFile((int)IconResourceType.RES_ICON_CMD_EXP_DEFENCE); break;
case RoleExpression.ROLEEXP_FALL: szIconFile = res_IconFile((int)IconResourceType.RES_ICON_CMD_EXP_FALL); break;
case RoleExpression.ROLEEXP_FALLONGROUND: szIconFile = res_IconFile((int)IconResourceType.RES_ICON_CMD_EXP_FALLONGROUND); break;
case RoleExpression.ROLEEXP_LOOKAROUND: szIconFile = res_IconFile((int)IconResourceType.RES_ICON_CMD_EXP_LOOKAROUND); break;
case RoleExpression.ROLEEXP_DANCE: szIconFile = res_IconFile((int)IconResourceType.RES_ICON_CMD_EXP_DANCE); break;
case RoleExpression.ROLEEXP_FASHIONWEAPON: szIconFile = res_IconFile((int)IconResourceType.RES_ICON_CMD_EXP_FASHIONWEAPON); break;
default:
break;
}
break;
}
default:
return "";
}
return szIconFile;
}
// Get item cool time
int GetCoolTime(ref int piMax/* NULL */)
{
CECHostPlayer pHost = CECGameRun.Instance.GetHostPlayer();
int iTime = 0;
switch ((CommandID)m_iCommand)
{
case CommandID.CMD_RUSHFLY:
// iTime = pHost.GetCoolTime(GP_CT_FLY_RUSH, piMax);
break;
case CommandID.CMD_PLAYPOSE:
// todo need to get cooldown here
// iTime = pHost.GetCoolTime(GP_CT_EMOTE, piMax);
break;
case CommandID.CMD_BINDBUDDY:
{
// CECCounter& cnt = pHost.GetBindCmdCoolCnt();
// iTime = cnt.GetPeriod() - cnt.GetCounter();
//
// if (piMax)
// *piMax = cnt.GetPeriod();
break;
}
default:
// if (piMax) *piMax = 0;
break;
}
return iTime;
}
}
/* public class CECSCSkill : CECShortcut
{
private CECSkill m_pSkill;
public override ShortcutType GetType() => ShortcutType.SCT_SKILL;
public override CECShortcut Clone() => null;
public bool Init(CECSkill pSkill) { m_pSkill = pSkill; return true; }
public CECSkill GetSkill() => m_pSkill;
public void SetSkill(CECSkill pSkill) { m_pSkill = pSkill; }
}
public class CECSCItem : CECShortcut
{
private int m_iInventory;
private int m_iIvtrSlot;
private int m_iItemTID;
private bool m_bAutoFind;
public override ShortcutType GetType() => ShortcutType.SCT_ITEM;
public override CECShortcut Clone() => null;
public bool Init(int iIvtr, int iSlot, CECIvtrItem pItem)
{
m_iInventory = iIvtr;
m_iIvtrSlot = iSlot;
return true;
}
public int GetInventory() => m_iInventory;
public int GetIvtrSlot() => m_iIvtrSlot;
public int GetItemTID() => m_iItemTID;
public bool GetAutoFindFlag() => m_bAutoFind;
public void MoveItem(int iIvtr, int iSlot) { m_iInventory = iIvtr; m_iIvtrSlot = iSlot; }
}*/
/* public class CECSCSkillGrp : CECShortcut
{
private int m_iGroupIdx;
public override ShortcutType GetType() => ShortcutType.SCT_SKILLGRP;
public override CECShortcut Clone() => null;
public bool Init(int iGroupIdx) { m_iGroupIdx = iGroupIdx; return true; }
public int GetGroupIndex() => m_iGroupIdx;
}
public class CECSCPet : CECShortcut
{
private int m_iPetIndex;
public override ShortcutType GetType() => ShortcutType.SCT_PET;
public override CECShortcut Clone() => null;
public bool Init(int iPetIndex) { m_iPetIndex = iPetIndex; return true; }
public int GetPetIndex() => m_iPetIndex;
}
public class CECSCAutoFashion : CECShortcut
{
private int m_iFashionIdx;
public override ShortcutType GetType() => ShortcutType.SCT_AUTOFASHION;
public override CECShortcut Clone() => null;
public bool Init(int iFashionIdx) { m_iFashionIdx = iFashionIdx; return true; }
public int GetAutoFashionIndex() => m_iFashionIdx;
}
public class CECSCSysModule : CECShortcut
{
private int m_iSysModID;
public override ShortcutType GetType() => ShortcutType.SCT_SYSMODULE;
public override CECShortcut Clone() => null;
public bool Init(int iSys) { m_iSysModID = iSys; return true; }
public int GetSysModID() => m_iSysModID;
}
// Placeholder classes for dependencies
public class CECIvtrItem { }
public class CECInventory
{
public CECIvtrItem GetItem(int slot) => null;
}
public class CECHostGoblin
{
public CECSkill GetSkillByID(int id) => null;
}*/
// class CECSCSysModule : public CECShortcut
public class CECSCSysModule : CECShortcut
{
// public: // Types
// enum { FM_NONE = -1, FM_GT, FM_TOUCH, ... FM_NUM, };
public enum SysModuleType
{
FM_NONE = -1,
FM_GT,
FM_TOUCH,
FM_ROBOT, // 帮派系统 (Faction / Guild system)
FM_WIKI,
FM_OFFLINESHOP, // 摆摊 (Offline shop / Stall)
FM_BORADCAST, // 广播系统 (Broadcast system)
FM_MATCH, // 边缘系统 (Match system)
FM_ADDEXP, // 帮会系统 (Guild / Add exp system)
FM_AUTOHPMP, // 辅助功能,自动加药 (Auxiliary function, auto potion)
FM_NUM,
}
// public: // Attributes
// static const int g_SysIndexMap[FM_NUM];
public static readonly int[] g_SysIndexMap = new int[(int)SysModuleType.FM_NUM];
// protected: // Attributes
// ACString m_strDesc;
protected string m_strDesc;
// char m_IconFile[256];
protected string m_IconFile;
// int m_iSystem; // system ID
protected int m_iSystem;
// public: // Constructor and Destructor
// CECSCSysModule();
public CECSCSysModule()
{
m_iSCType = (int)ShortcutType.SCT_SYSMODULE;
m_strDesc = string.Empty;
m_IconFile = string.Empty;
m_iSystem = (int)SysModuleType.FM_NONE;
}
// CECSCSysModule(const CECSCSysModule& src);
public CECSCSysModule(CECSCSysModule src)
{
m_iSCType = src.m_iSCType;
m_strDesc = src.m_strDesc;
m_IconFile = src.m_IconFile;
m_iSystem = src.m_iSystem;
}
// virtual ~CECSCSysModule() {}
// (no destructor in C#)
// bool Init(int iSys);
public bool Init(int iSys)
{
m_iSystem = iSys;
// TODO: load m_strDesc and m_IconFile from config/table by iSys if needed
return true;
}
// virtual CECShortcut* Clone();
public override CECShortcut Clone()
{
return new CECSCSysModule(this);
}
// virtual bool Execute();
public override bool Execute()
{
// TODO: open corresponding system UI by m_iSystem (e.g. GT, Touch, Robot, Wiki, OfflineShop, Broadcast, Match, AddExp, AutoHpMp)
return true;
}
// int GetSysModID() const { return m_iSystem; }
public int GetSysModID() { return m_iSystem; }
// virtual const wchar_t* GetDesc();
public override string GetDesc()
{
return m_strDesc ?? string.Empty;
}
public override string GetIconFile()
{
return string.IsNullOrEmpty(m_IconFile) ? "unknown" : m_IconFile;
}
}
#endregion
}