add more handle protocol
This commit is contained in:
@@ -100,3 +100,6 @@ InitTestScene*.unity*
|
||||
# Auto-generated scenes by play mode tests
|
||||
/[Aa]ssets/[Ii]nit[Tt]est[Ss]cene*.unity*
|
||||
.idea
|
||||
|
||||
# AI Context
|
||||
claude.md
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:d381b291f0b51a7d9440c9129ad3176acc9c4e8a8ade93205cd8c87875c5b5db
|
||||
size 309973
|
||||
oid sha256:37a9988776424c6f09366178d3b6f3a06cfeaebb9be7f1386f1da7f5b6d16e8d
|
||||
size 311771
|
||||
|
||||
@@ -1524,3 +1524,4 @@ public enum GfxSkillValType
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@ using System.Runtime.InteropServices;
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
using UnityEngine.SceneManagement;
|
||||
using static Unity.Burst.Intrinsics.X86.Avx;
|
||||
|
||||
namespace PerfectWorld.Scripts.Managers
|
||||
{
|
||||
@@ -102,6 +103,8 @@ namespace PerfectWorld.Scripts.Managers
|
||||
case EC_MsgDef.MSG_PM_PLAYEREXIT:
|
||||
OnMsgPlayerExit(Msg);
|
||||
break;
|
||||
case EC_MsgDef.MSG_PM_PLAYEREXTSTATE: OnMsgPlayerExtState(Msg); break;
|
||||
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -110,7 +113,55 @@ namespace PerfectWorld.Scripts.Managers
|
||||
}
|
||||
return true;
|
||||
}
|
||||
public bool OnMsgPlayerExtState(ECMSG Msg)
|
||||
{
|
||||
int cid = 0;
|
||||
cmd_icon_state_notify cmd = new cmd_icon_state_notify();
|
||||
|
||||
if (Convert.ToInt32(Msg.dwParam2) == CommandID.UPDATE_EXT_STATE)
|
||||
{
|
||||
var pCmd = GPDataTypeHelper.FromBytes<cmd_update_ext_state>((byte[])Msg.dwParam1);
|
||||
cid = pCmd.id;
|
||||
}
|
||||
else if (Convert.ToInt32(Msg.dwParam2) == CommandID.ICON_STATE_NOTIFY)
|
||||
{
|
||||
if (!cmd.Initialize((byte[])Msg.dwParam1))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
cid = cmd.id;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
CECHostPlayer host = GetHostPlayer();
|
||||
|
||||
if (host != null && cid == host.GetCharacterID())
|
||||
{
|
||||
host.ProcessMessage(Msg);
|
||||
}
|
||||
else
|
||||
{
|
||||
EC_ElsePlayer elsePlayer = SeekOutElsePlayer(cid);
|
||||
if (elsePlayer != null)
|
||||
{
|
||||
elsePlayer.ProcessMessage(Msg);
|
||||
}
|
||||
|
||||
if (Convert.ToInt32(Msg.dwParam2) == CommandID.ICON_STATE_NOTIFY && host != null && host.GetTeam() != null)
|
||||
{
|
||||
// TODO: Update host's team member's icon state
|
||||
// CECTeam pTeam = host.GetTeam();
|
||||
// CECTeamMember pMember = pTeam.GetMemberByID(cid);
|
||||
// if (pMember != null)
|
||||
// pMember.ResetIconStates(cmd.states);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
private void OnMsgPlayerDied(ECMSG Msg)
|
||||
{
|
||||
cmd_player_died pCmd = GPDataTypeHelper.FromBytes<cmd_player_died>((byte[])Msg.dwParam1);
|
||||
@@ -813,7 +864,7 @@ namespace PerfectWorld.Scripts.Managers
|
||||
|
||||
float fDist = pPlayer.GetDistToHost();
|
||||
if (fDist > EC_RoleTypes.EC_TABSEL_DIST || !pHost.CanSafelySelectWith(fDist))
|
||||
continue; // Target is too far
|
||||
continue; // Target is too far
|
||||
|
||||
aCands.Add(pPlayer);
|
||||
}
|
||||
|
||||
@@ -96,6 +96,7 @@ namespace BrewMonster
|
||||
public bool m_bPetInSanctuary = false; // true, the pet pet of the player is in sanctuary
|
||||
//The ID of the currently summoned pet
|
||||
protected int m_idCurPet = 0;
|
||||
public List<IconState> m_aIconStates = new List<IconState>();
|
||||
protected byte m_byPariahLvl = 0; // Pariah level
|
||||
|
||||
public RIDINGPET m_RidingPet; // Riding pet information
|
||||
@@ -702,6 +703,45 @@ namespace BrewMonster
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void OnMsgPlayerExtState(ECMSG Msg)
|
||||
{
|
||||
if (Convert.ToInt32(Msg.dwParam2) == CommandID.UPDATE_EXT_STATE)
|
||||
{
|
||||
cmd_update_ext_state pCmd = GPDataTypeHelper.FromBytes<cmd_update_ext_state>((byte[])Msg.dwParam1);
|
||||
if (pCmd.id == m_PlayerInfo.cid)
|
||||
{
|
||||
SetNewExtendStates(0, pCmd.states, (int)OBJECT_EXT_STATE.OBJECT_EXT_STATE_COUNT);
|
||||
}
|
||||
}
|
||||
else if (Convert.ToInt32(Msg.dwParam2) == CommandID.ICON_STATE_NOTIFY)
|
||||
{
|
||||
cmd_icon_state_notify cmd = new cmd_icon_state_notify();
|
||||
if (!cmd.Initialize((byte[])Msg.dwParam1))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (cmd.id == m_PlayerInfo.cid)
|
||||
{
|
||||
m_aIconStates = cmd.states;
|
||||
if (m_aIconStates.Count > 1)
|
||||
{
|
||||
m_aIconStates.Sort((a, b) =>
|
||||
{
|
||||
if (a.id < b.id) return -1;
|
||||
if (a.id > b.id) return 1;
|
||||
return 0;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void SetNewExtendStates(int unknown, uint[] states, int count)
|
||||
{
|
||||
// TODO: Implement appearance or physics change
|
||||
}
|
||||
|
||||
public virtual void SetUpPlayer()
|
||||
{
|
||||
m_dwResFlags = 0;
|
||||
|
||||
@@ -221,7 +221,7 @@ namespace CSNetwork.GPDataType
|
||||
public const int TEAM_ASK_TO_JOIN = 148;
|
||||
public const int OBJECT_EMOTE_RESTORE = 149;
|
||||
|
||||
public const int CON_EMOTE_REQUEST = 150; // concurrent emote request
|
||||
public const int CON_EMOTE_REQUEST = 150;
|
||||
public const int DO_CONCURRENT_EMOTE = 151;
|
||||
public const int MATTER_PICKUP = 152;
|
||||
public const int MAFIA_INFO_NOTIFY = 153;
|
||||
@@ -284,7 +284,7 @@ namespace CSNetwork.GPDataType
|
||||
public const int EXIT_INSTANCE = 200;
|
||||
public const int CHANGE_FACE_START = 201;
|
||||
public const int CHANGE_FACE_END = 202;
|
||||
public const int PLAYER_CHG_FACE = 203; // Player change face completed
|
||||
public const int PLAYER_CHG_FACE = 203;
|
||||
public const int OBJECT_CAST_POS_SKILL = 204;
|
||||
|
||||
public const int SET_MOVE_STAMP = 205;
|
||||
@@ -403,7 +403,7 @@ namespace CSNetwork.GPDataType
|
||||
|
||||
public const int FACTION_RELATION_NOTIFY = 300;
|
||||
public const int PLAYER_EQUIP_DISABLED = 301;
|
||||
public const int PLAYER_SPEC_ITEM_LIST = 302; // return value of GM_QUERY_SPEC_ITEM
|
||||
public const int PLAYER_SPEC_ITEM_LIST = 302;
|
||||
public const int OBJECT_START_PLAY_ACTION = 303;
|
||||
public const int OBJECT_STOP_PLAY_ACTION = 304;
|
||||
|
||||
@@ -2684,7 +2684,86 @@ namespace CSNetwork.GPDataType
|
||||
public ushort equip_idx;
|
||||
public uint cost;
|
||||
};
|
||||
public struct cmd_icon_state_notify
|
||||
{
|
||||
public int id;
|
||||
public List<IconState> states;
|
||||
|
||||
public bool Initialize(byte[] buffer)
|
||||
{
|
||||
if (buffer == null || buffer.Length < 4) return false;
|
||||
int offset = 0;
|
||||
|
||||
// Extract id
|
||||
id = BitConverter.ToInt32(buffer, offset);
|
||||
offset += sizeof(int);
|
||||
|
||||
// Extract scount
|
||||
if (offset + sizeof(ushort) > buffer.Length) return false;
|
||||
ushort scount = BitConverter.ToUInt16(buffer, offset);
|
||||
offset += sizeof(ushort);
|
||||
|
||||
// Extract state array
|
||||
ushort[] stateArray = new ushort[scount];
|
||||
for (int i = 0; i < scount; i++)
|
||||
{
|
||||
if (offset + sizeof(ushort) > buffer.Length) return false;
|
||||
stateArray[i] = BitConverter.ToUInt16(buffer, offset);
|
||||
offset += sizeof(ushort);
|
||||
}
|
||||
|
||||
// Extract pcount
|
||||
if (offset + sizeof(ushort) > buffer.Length) return false;
|
||||
ushort pcount = BitConverter.ToUInt16(buffer, offset);
|
||||
offset += sizeof(ushort);
|
||||
|
||||
// Extract param array
|
||||
int[] paramArray = new int[pcount];
|
||||
for (int i = 0; i < pcount; i++)
|
||||
{
|
||||
if (offset + sizeof(int) > buffer.Length) return false;
|
||||
paramArray[i] = BitConverter.ToInt32(buffer, offset);
|
||||
offset += sizeof(int);
|
||||
}
|
||||
|
||||
// Build states
|
||||
states = new List<IconState>(scount);
|
||||
int param_offset = 0;
|
||||
for (int i = 0; i < scount; i++)
|
||||
{
|
||||
ushort s = stateArray[i];
|
||||
IconState dummy = new IconState();
|
||||
dummy.id = (ushort)(s & 0x3fff);
|
||||
dummy.pcount = (s >> 14) & 0x3;
|
||||
dummy.param = new int[3];
|
||||
|
||||
if (dummy.pcount > 0)
|
||||
{
|
||||
if (param_offset + dummy.pcount <= pcount)
|
||||
{
|
||||
for (int k = 0; k < dummy.pcount; k++)
|
||||
{
|
||||
dummy.param[k] = paramArray[param_offset++];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Not enough parameters decoded
|
||||
return false;
|
||||
}
|
||||
}
|
||||
states.Add(dummy);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
public struct IconState
|
||||
{
|
||||
public ushort id;
|
||||
public int pcount;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
|
||||
public int[] param;
|
||||
};
|
||||
// player leaves the world
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct cmd_player_leave_world
|
||||
|
||||
@@ -1283,6 +1283,15 @@ namespace CSNetwork
|
||||
|
||||
EC_ManMessage.PostMessage(EC_MsgDef.MSG_HST_SETMOVESTAMP, MANAGER_INDEX.MAN_PLAYER, 0, pDataBuf, pCmdHeader);
|
||||
break;
|
||||
case CommandID.UPDATE_EXT_STATE:
|
||||
{
|
||||
cmd_update_ext_state pCmd = GPDataTypeHelper.FromBytes<cmd_update_ext_state>((byte[])pDataBuf);
|
||||
if (ISPLAYERID(pCmd.id))
|
||||
EC_ManMessage.PostMessage(EC_MsgDef.MSG_PM_PLAYEREXTSTATE, MANAGER_INDEX.MAN_PLAYER, -1, pDataBuf, pCmdHeader);
|
||||
else if (ISNPCID(pCmd.id))
|
||||
EC_ManMessage.PostMessage(EC_MsgDef.MSG_NM_NPCEXTSTATE, MANAGER_INDEX.MAN_NPC, 0, pDataBuf, pCmdHeader);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
#if UNITY_EDITOR
|
||||
if (isDebug)
|
||||
|
||||
@@ -14,13 +14,13 @@ namespace BrewMonster
|
||||
public partial class CECHostPlayer
|
||||
{
|
||||
|
||||
// 服务器控制的额外操作限制
|
||||
// 服务器控制的额外操作限制
|
||||
public enum PLAYER_LIMIT
|
||||
{
|
||||
PLAYER_LIMIT_NOFLY, // 禁止"飞行/取消飞行"
|
||||
PLAYER_LIMIT_NOCHANGESELECT, // 禁止"选中/取消选中/协助攻击"
|
||||
PLAYER_LIMIT_NOMOUNT, // 禁止召唤骑宠
|
||||
PLAYER_LIMIT_NOBIND, // 禁止"发起/接收相依相偎"
|
||||
PLAYER_LIMIT_NOFLY, // 禁止"飞行/取消飞行"
|
||||
PLAYER_LIMIT_NOCHANGESELECT, // 禁止"选中/取消选中/协助攻击"
|
||||
PLAYER_LIMIT_NOMOUNT, // 禁止召唤骑宠
|
||||
PLAYER_LIMIT_NOBIND, // 禁止"发起/接收相依相偎"
|
||||
PLAYER_LIMIT_MAX,
|
||||
};
|
||||
|
||||
@@ -88,6 +88,24 @@ namespace BrewMonster
|
||||
return 0;
|
||||
}
|
||||
|
||||
public override void OnMsgPlayerExtState(ECMSG Msg)
|
||||
{
|
||||
base.OnMsgPlayerExtState(Msg);
|
||||
if (m_aIconStates != null && m_aIconStates.Count > 0)
|
||||
{
|
||||
foreach (var state in m_aIconStates)
|
||||
{
|
||||
if (state.id == 287) // Thunder ball logic
|
||||
{
|
||||
// TODO: Implement UI logic for Ice Thunder Ball
|
||||
// bool bHideIceThunderBall = CECUIHelper.GetGame().GetConfigs().GetGameSettings().bHideIceThunderBall;
|
||||
// if (!bHideIceThunderBall) ...
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void OnMsgHstPetOpt(ECMSG Msg)
|
||||
{
|
||||
CECGameRun pGameRun = EC_Game.GetGameRun();
|
||||
@@ -178,7 +196,7 @@ namespace BrewMonster
|
||||
int tid = pCmd.pet_id;
|
||||
int nid = m_pPetCorral.GetActivePetNPCID();
|
||||
|
||||
// 宠物有话说
|
||||
// 宠物有话说
|
||||
switch (pCmd.reason)
|
||||
{
|
||||
case (char)PET_RECALL_REASON.PET_RECALL_DEFAULT:
|
||||
@@ -362,7 +380,7 @@ namespace BrewMonster
|
||||
{
|
||||
cmd_pet_ai_state pCmd = GPDataTypeHelper.FromBytes<cmd_pet_ai_state>((byte[])Msg.dwParam1);
|
||||
|
||||
// 宠物有话说
|
||||
// 宠物有话说
|
||||
CECPetData pPetData = m_pPetCorral.GetActivePet();
|
||||
if (pPetData != null)
|
||||
{
|
||||
|
||||
@@ -1817,9 +1817,9 @@ namespace BrewMonster
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Cycles through learned skills by removing all shortcuts and adding 2 new skills to slots 0 and 1.
|
||||
/// If m_startingSkillID is set (>0), uses that specific skill ID and the next one (ID+1).
|
||||
/// Otherwise, cycles through all learned skills in pairs.
|
||||
/// Cycles through learned skills by removing all shortcuts and adding 8 new skills to slots 0-7.
|
||||
/// If m_startingSkillID is set (>0), uses that specific skill ID and the next 7 (ID+1 to ID+7).
|
||||
/// Otherwise, cycles through all learned skills in groups of 8.
|
||||
/// </summary>
|
||||
public void CycleSkillShortcuts()
|
||||
{
|
||||
@@ -1833,74 +1833,51 @@ namespace BrewMonster
|
||||
|
||||
// Remove all shortcuts
|
||||
pSCS.RemoveAllShortcuts();
|
||||
const int skillsPerCycle = 8;
|
||||
|
||||
// If starting skill ID is configured, cycle through pairs starting from that ID
|
||||
// If starting skill ID is configured, cycle through groups of 8 starting from that ID
|
||||
if (m_startingSkillID > 0)
|
||||
{
|
||||
// Calculate the current skill IDs based on cycle index
|
||||
// First press: startingID + 0, startingID + 1 (e.g., 5, 6)
|
||||
// Second press: startingID + 2, startingID + 3 (e.g., 7, 8)
|
||||
// Third press: startingID + 4, startingID + 5 (e.g., 9, 10)
|
||||
int currentSkillID1 = m_startingSkillID + (m_currentSkillCycleIndex * 2);
|
||||
int currentSkillID2 = currentSkillID1 + 1;
|
||||
BMLogger.LogError($"CycleSkillShortcuts: Trying to add skills {currentSkillID1} and {currentSkillID2}");
|
||||
// First press: startingID + 0 to startingID + 7 (e.g., 5-12)
|
||||
// Second press: startingID + 8 to startingID + 15 (e.g., 13-20)
|
||||
// Third press: startingID + 16 to startingID + 23 (e.g., 21-28)
|
||||
int baseSkillID = m_startingSkillID + (m_currentSkillCycleIndex * skillsPerCycle);
|
||||
BMLogger.LogError($"CycleSkillShortcuts: Trying to add skills {baseSkillID} to {baseSkillID + skillsPerCycle - 1}");
|
||||
|
||||
CECSkill pSkill1 = GetPositiveSkillByID(currentSkillID1);
|
||||
if (pSkill1 != null)
|
||||
// Add 8 skills to slots 0-7
|
||||
for (int slot = 0; slot < skillsPerCycle; slot++)
|
||||
{
|
||||
pSCS.CreateSkillShortcut(0, pSkill1);
|
||||
Debug.LogError($"CycleSkillShortcuts: Added skill ID {currentSkillID1} to slot 0");
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogError($"CycleSkillShortcuts: Skill with ID {currentSkillID1} not found in learned skills");
|
||||
int find = 1;
|
||||
while (pSkill1 == null && find < 100)
|
||||
int currentSkillID = baseSkillID + slot;
|
||||
CECSkill pSkill = GetPositiveSkillByID(currentSkillID);
|
||||
|
||||
if (pSkill != null)
|
||||
{
|
||||
m_startingSkillID++;
|
||||
Debug.LogError($"CycleSkillShortcuts: m_startingSkillID {m_startingSkillID} ");
|
||||
currentSkillID1 = m_startingSkillID + (m_currentSkillCycleIndex * 2);
|
||||
pSkill1 = GetPositiveSkillByID(currentSkillID1);
|
||||
find++;
|
||||
}
|
||||
|
||||
if (pSkill1 != null)
|
||||
{
|
||||
pSCS.CreateSkillShortcut(0, pSkill1);
|
||||
pSCS.CreateSkillShortcut(slot, pSkill);
|
||||
Debug.LogError($"CycleSkillShortcuts: Added skill ID {currentSkillID} to slot {slot}");
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogError($"CycleSkillShortcuts: Failed to find skill after {find} attempts");
|
||||
}
|
||||
}
|
||||
Debug.LogError($"CycleSkillShortcuts: Skill with ID {currentSkillID} not found in learned skills");
|
||||
// Try to find a valid skill by incrementing starting ID
|
||||
int find = 1;
|
||||
while (pSkill == null && find < 100)
|
||||
{
|
||||
m_startingSkillID++;
|
||||
Debug.LogError($"CycleSkillShortcuts: m_startingSkillID {m_startingSkillID}");
|
||||
currentSkillID = m_startingSkillID + (m_currentSkillCycleIndex * skillsPerCycle) + slot;
|
||||
pSkill = GetPositiveSkillByID(currentSkillID);
|
||||
find++;
|
||||
}
|
||||
|
||||
// Find and add second skill
|
||||
CECSkill pSkill2 = GetPositiveSkillByID(currentSkillID2);
|
||||
if (pSkill2 != null)
|
||||
{
|
||||
pSCS.CreateSkillShortcut(1, pSkill2);
|
||||
Debug.LogError($"CycleSkillShortcuts: Added skill ID {currentSkillID2} to slot 1");
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogError($"CycleSkillShortcuts: Skill with ID {currentSkillID2} not found in learned skills");
|
||||
int find = 1;
|
||||
while (pSkill2 == null && find < 100)
|
||||
{
|
||||
m_startingSkillID++;
|
||||
Debug.LogError($"CycleSkillShortcuts: m_startingSkillID {m_startingSkillID} ");
|
||||
currentSkillID2 = m_startingSkillID + (m_currentSkillCycleIndex * 2) + 1;
|
||||
pSkill2 = GetPositiveSkillByID(currentSkillID2);
|
||||
find++;
|
||||
}
|
||||
|
||||
if (pSkill2 != null)
|
||||
{
|
||||
pSCS.CreateSkillShortcut(1, pSkill2);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogError($"CycleSkillShortcuts: Failed to find skill after {find} attempts");
|
||||
if (pSkill != null)
|
||||
{
|
||||
pSCS.CreateSkillShortcut(slot, pSkill);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogError($"CycleSkillShortcuts: Failed to find skill for slot {slot} after {find} attempts");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1926,36 +1903,29 @@ namespace BrewMonster
|
||||
return;
|
||||
}
|
||||
|
||||
// Calculate how many pairs we can make
|
||||
int maxPairs = (skillCount + 1) / 2; // Round up division
|
||||
// Calculate how many groups of 8 we can make
|
||||
int maxGroups = (skillCount + skillsPerCycle - 1) / skillsPerCycle; // Round up division
|
||||
|
||||
// Wrap around if we've reached the end
|
||||
if (m_currentSkillCycleIndex >= maxPairs)
|
||||
if (m_currentSkillCycleIndex >= maxGroups)
|
||||
{
|
||||
m_currentSkillCycleIndex = 0;
|
||||
}
|
||||
|
||||
// Calculate skill indices for this cycle
|
||||
int skillIndex1 = m_currentSkillCycleIndex * 2;
|
||||
int skillIndex2 = skillIndex1 + 1;
|
||||
int baseSkillIndex = m_currentSkillCycleIndex * skillsPerCycle;
|
||||
|
||||
// Add first skill to slot 0
|
||||
if (skillIndex1 < skillCount)
|
||||
// Add up to 8 skills to slots 0-7
|
||||
for (int slot = 0; slot < skillsPerCycle; slot++)
|
||||
{
|
||||
CECSkill pSkill1 = GetPositiveSkillByIndex(skillIndex1);
|
||||
if (pSkill1 != null)
|
||||
int skillIndex = baseSkillIndex + slot;
|
||||
if (skillIndex < skillCount)
|
||||
{
|
||||
pSCS.CreateSkillShortcut(0, pSkill1);
|
||||
}
|
||||
}
|
||||
|
||||
// Add second skill to slot 1 (if available)
|
||||
if (skillIndex2 < skillCount)
|
||||
{
|
||||
CECSkill pSkill2 = GetPositiveSkillByIndex(skillIndex2);
|
||||
if (pSkill2 != null)
|
||||
{
|
||||
pSCS.CreateSkillShortcut(1, pSkill2);
|
||||
CECSkill pSkill = GetPositiveSkillByIndex(skillIndex);
|
||||
if (pSkill != null)
|
||||
{
|
||||
pSCS.CreateSkillShortcut(slot, pSkill);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+36
-9
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user