Merge remote-tracking branch 'origin/develop' into feature/Addessable_CDN
This commit is contained in:
@@ -876,11 +876,33 @@ namespace BrewMonster
|
||||
// Mark host player as corpse so CECPlayer.IsDead() returns true
|
||||
m_dwStates |= (uint)PlayerNPCState.GP_STATE_CORPSE;
|
||||
|
||||
// Mobile joystick keeps input while held; stop move work immediately (mirror HOST_NOTIFY_ROOT).
|
||||
StopHostMovementOnDeath();
|
||||
|
||||
EventBus.PublishChannel(GetCharacterID(), new ClearComActFlagAllRankNodesEvent(true));
|
||||
PlayAction((int)PLAYER_ACTION_TYPE.ACT_GROUNDDIE);
|
||||
PopupManager.NotifyPlayerDied();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Cancel active locomotion when host dies. Push-move reads joystick directly in GetPushDir,
|
||||
/// so finishing WORK_MOVETOPOS alone is not enough until m_dwMoveRelDir is cleared.
|
||||
/// </summary>
|
||||
private void StopHostMovementOnDeath()
|
||||
{
|
||||
m_dwMoveRelDir = 0;
|
||||
|
||||
if (m_pWorkMan == null)
|
||||
return;
|
||||
|
||||
if (m_pWorkMan.IsFollowing())
|
||||
m_pWorkMan.FinishRunningWork(Host_work_ID.WORK_FOLLOW);
|
||||
if (m_pWorkMan.IsMovingToPosition())
|
||||
m_pWorkMan.FinishRunningWork(Host_work_ID.WORK_MOVETOPOS);
|
||||
if (m_pWorkMan.IsTracing())
|
||||
m_pWorkMan.FinishRunningWork(Host_work_ID.WORK_TRACEOBJECT);
|
||||
}
|
||||
|
||||
private bool NormalAttackObject(int idTarget, bool bForceAttack, bool bMoreClose = false)
|
||||
{
|
||||
if (idTarget == 0 || idTarget == m_PlayerInfo.cid)
|
||||
|
||||
@@ -137,12 +137,15 @@ namespace BrewMonster
|
||||
}
|
||||
case CommandID.CHANGE_IVTR_SIZE:
|
||||
{
|
||||
// C++: resize pack (normal inventory)
|
||||
// C++ EC_HostMsg.cpp: m_pPack->Resize + FIXMSG_NEW_INVENTORY_SIZE
|
||||
if (data != null && data.Length >= 4)
|
||||
{
|
||||
int newSize = BitConverter.ToInt32(data, 0);
|
||||
if (m_pPack != null)
|
||||
m_pPack.Resize(newSize);
|
||||
|
||||
EC_Game.GetGameRun()?.AddFixedMessage((int)FixedMsg.FIXMSG_NEW_INVENTORY_SIZE, newSize);
|
||||
|
||||
var ui = GameObject.FindFirstObjectByType<EC_InventoryUI>();
|
||||
ui?.RefreshAll();
|
||||
}
|
||||
|
||||
@@ -235,6 +235,119 @@ namespace BrewMonster
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// DEBUG ONLY — bypasses the server skill message by loading skills from SkillStub.map
|
||||
/// (populated at startup from config) that belong to the player's current profession
|
||||
/// (or are general skills, cls == 255). Safe to call before server data arrives.
|
||||
///
|
||||
/// 仅调试用 — 从 SkillStub.map 注入属于当前职业(或通用职业 cls==255)的技能,
|
||||
/// 绕过服务端消息,可在服务端数据到达前调用。
|
||||
/// </summary>
|
||||
public void InjectDebugSkillsFromConfig(int level = 1)
|
||||
{
|
||||
m_aPtSkills.Clear();
|
||||
m_aPsSkills.Clear();
|
||||
|
||||
var stubMap = SkillStub.GetMap();
|
||||
if (stubMap.Count == 0)
|
||||
{
|
||||
BMLogger.LogWarning("InjectDebugSkillsFromConfig: SkillStub.map is empty — config not loaded yet.");
|
||||
return;
|
||||
}
|
||||
|
||||
int playerCls = m_iProfession; // current role's profession ID
|
||||
int injected = 0;
|
||||
foreach (var kvp in stubMap)
|
||||
{
|
||||
int stubCls = kvp.Value.cls;
|
||||
// Keep only skills for this profession or universal skills (cls 255).
|
||||
// Same rule used by EC_HostSkillModel when listing learnable skills.
|
||||
// 仅保留当前职业技能或通用技能(cls==255),与 EC_HostSkillModel 的过滤规则相同。
|
||||
if (stubCls != playerCls && stubCls != 255)
|
||||
continue;
|
||||
|
||||
uint skillId = kvp.Key;
|
||||
CECSkill skill = new CECSkill((int)skillId, level);
|
||||
if (skill.SkillCore == null)
|
||||
continue;
|
||||
|
||||
int type = skill.GetType();
|
||||
if (type != (int)CECSkill.SkillType.TYPE_PASSIVE &&
|
||||
type != (int)CECSkill.SkillType.TYPE_PRODUCE &&
|
||||
type != (int)CECSkill.SkillType.TYPE_LIVE)
|
||||
m_aPtSkills.Add(skill);
|
||||
else
|
||||
m_aPsSkills.Add(skill);
|
||||
|
||||
injected++;
|
||||
}
|
||||
|
||||
BMLogger.Log($"InjectDebugSkillsFromConfig: profession={playerCls}, injected {injected} skills " +
|
||||
$"({m_aPtSkills.Count} active, {m_aPsSkills.Count} passive) at level {level}.");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Animation test / offline: populate skill lists from <see cref="CECHostSkillModel"/> catalog
|
||||
/// (same source and filters as CDlgSkillSubList).
|
||||
/// Call <see cref="CECHostSkillModel.Initialize"/> before this so the catalog matches the current profession.
|
||||
///
|
||||
/// 动画测试 / 离线:从 CECHostSkillModel 目录填充技能列表(与 CDlgSkillSubList 相同来源与过滤)。
|
||||
/// </summary>
|
||||
public void InjectSkillsFromSkillModel(int level = 1, bool isEvil = false)
|
||||
{
|
||||
m_aPtSkills.Clear();
|
||||
m_aPsSkills.Clear();
|
||||
|
||||
List<int> skillIds = CECHostSkillModel.Instance?.CollectSkillSubListSkillIds(isEvil);
|
||||
if (skillIds == null || skillIds.Count == 0)
|
||||
{
|
||||
BMLogger.LogWarning(
|
||||
"InjectSkillsFromSkillModel: CECHostSkillModel catalog is empty — call CECHostSkillModel.Initialize() first.");
|
||||
return;
|
||||
}
|
||||
|
||||
int injected = 0;
|
||||
foreach (int skillId in skillIds)
|
||||
{
|
||||
CECSkill skill = new CECSkill(skillId, level);
|
||||
|
||||
int type = (int)ElementSkill.GetType((uint)skillId);
|
||||
if (skill.SkillCore != null)
|
||||
type = skill.GetType();
|
||||
|
||||
if (type != (int)CECSkill.SkillType.TYPE_PASSIVE &&
|
||||
type != (int)CECSkill.SkillType.TYPE_PRODUCE &&
|
||||
type != (int)CECSkill.SkillType.TYPE_LIVE)
|
||||
m_aPtSkills.Add(skill);
|
||||
else
|
||||
m_aPsSkills.Add(skill);
|
||||
|
||||
injected++;
|
||||
}
|
||||
|
||||
BMLogger.Log($"InjectSkillsFromSkillModel: profession={m_iProfession}, isEvil={isEvil}, " +
|
||||
$"catalog={skillIds.Count}, injected={injected} " +
|
||||
$"({m_aPtSkills.Count} active, {m_aPsSkills.Count} passive) at level {level}.");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Build <see cref="CECSkill"/> instances for every ID returned by
|
||||
/// <see cref="CECHostSkillModel.CollectSkillSubListSkillIds"/> — includes passive skills shown in the skill tree UI.
|
||||
/// 构建与 CDlgSkillSubList 完全一致的技能列表(含被动)。
|
||||
/// </summary>
|
||||
public List<CECSkill> BuildSkillSubListSkills(int level = 1, bool isEvil = false)
|
||||
{
|
||||
var skills = new List<CECSkill>();
|
||||
List<int> skillIds = CECHostSkillModel.Instance?.CollectSkillSubListSkillIds(isEvil);
|
||||
if (skillIds == null)
|
||||
return skills;
|
||||
|
||||
foreach (int skillId in skillIds)
|
||||
skills.Add(new CECSkill(skillId, level));
|
||||
|
||||
return skills;
|
||||
}
|
||||
|
||||
private void OnMsgHstLearnSkill(ECMSG Msg)
|
||||
{
|
||||
cmd_learn_skill pCmd = GPDataTypeHelper.FromBytes<cmd_learn_skill>((byte[])Msg.dwParam1);
|
||||
|
||||
@@ -0,0 +1,208 @@
|
||||
using BrewMonster.Network;
|
||||
using BrewMonster.Scripts;
|
||||
using CSNetwork.GPDataType;
|
||||
using System.Collections.Generic;
|
||||
using static BrewMonster.Scripts.EC_Inventory;
|
||||
|
||||
namespace BrewMonster
|
||||
{
|
||||
public partial class CECHostPlayer
|
||||
{
|
||||
/// <summary>
|
||||
/// C++ CECHostPlayer::SortPack — reorder pack via MULTI_EXCHANGE_ITEM (DlgInventory OnCommand_arrange).
|
||||
/// </summary>
|
||||
public void SortPack(int iPack)
|
||||
{
|
||||
EC_Inventory pInventory = GetPack(iPack);
|
||||
if (pInventory == null)
|
||||
return;
|
||||
|
||||
int nIvtrSize = pInventory.GetSize();
|
||||
if (nIvtrSize <= 0)
|
||||
return;
|
||||
|
||||
if (pInventory.GetEmptySlotNum() == nIvtrSize)
|
||||
return;
|
||||
|
||||
for (int i = 0; i < nIvtrSize; i++)
|
||||
{
|
||||
var pItem = pInventory.GetItem(i, false);
|
||||
if (pItem != null && pItem.IsFrozen())
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < nIvtrSize; i++)
|
||||
{
|
||||
var pItem = pInventory.GetItem(i, false);
|
||||
pItem?.Freeze(true);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var vecItem = new List<int>(nIvtrSize);
|
||||
for (int i = 0; i < nIvtrSize; i++)
|
||||
vecItem.Add(i);
|
||||
|
||||
vecItem.Sort((a, b) => ComparePackSortIndices(pInventory, a, b));
|
||||
|
||||
var vecExchange = new List<int>();
|
||||
int pos = 0;
|
||||
while (pos < nIvtrSize)
|
||||
{
|
||||
int j = vecItem[pos];
|
||||
if (j == pos)
|
||||
{
|
||||
pos++;
|
||||
continue;
|
||||
}
|
||||
|
||||
int k = vecItem[j];
|
||||
if (pInventory.GetItem(j, false) != null || pInventory.GetItem(k, false) != null)
|
||||
{
|
||||
vecExchange.Add(pos);
|
||||
vecExchange.Add(j);
|
||||
}
|
||||
|
||||
int tmp = vecItem[pos];
|
||||
vecItem[pos] = vecItem[j];
|
||||
vecItem[j] = tmp;
|
||||
}
|
||||
|
||||
if (vecExchange.Count > 0)
|
||||
{
|
||||
int pairCount = vecExchange.Count / 2;
|
||||
for (int i = 0, j = vecExchange.Count - 1; i < j; i++, j--)
|
||||
{
|
||||
int t = vecExchange[i];
|
||||
vecExchange[i] = vecExchange[j];
|
||||
vecExchange[j] = t;
|
||||
}
|
||||
|
||||
UnityGameSession.RequestMultiExchangeItem((byte)iPack, pairCount, vecExchange.ToArray());
|
||||
}
|
||||
else
|
||||
{
|
||||
var pGameRun = EC_Game.GetGameRun();
|
||||
pGameRun?.AddChatMessage("Không cần sắp xếp kho đồ.", (int)ChatChannel.GP_CHAT_SYSTEM);
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
for (int i = 0; i < nIvtrSize; i++)
|
||||
{
|
||||
var pItem = pInventory.GetItem(i, false);
|
||||
pItem?.Freeze(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static int ComparePackSortIndices(EC_Inventory pInventory, int index1, int index2)
|
||||
{
|
||||
if (DefaultPackSortLess(pInventory, index1, index2))
|
||||
return -1;
|
||||
if (DefaultPackSortLess(pInventory, index2, index1))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// <summary>Returns true when slot <paramref name="index1"/> should appear before <paramref name="index2"/>.</summary>
|
||||
private static bool DefaultPackSortLess(EC_Inventory pInventory, int index1, int index2)
|
||||
{
|
||||
if (pInventory == null)
|
||||
return false;
|
||||
|
||||
EC_IvtrItem pItem1 = pInventory.GetItem(index1, false);
|
||||
EC_IvtrItem pItem2 = pInventory.GetItem(index2, false);
|
||||
|
||||
if (pItem1 == null)
|
||||
return false;
|
||||
if (pItem2 == null)
|
||||
return true;
|
||||
|
||||
int cid1 = pItem1.GetClassID();
|
||||
int tid1 = pItem1.GetTemplateID();
|
||||
int cid2 = pItem2.GetClassID();
|
||||
int tid2 = pItem2.GetTemplateID();
|
||||
|
||||
if (cid1 != cid2)
|
||||
{
|
||||
int cidOrder1 = GetPackSortClassOrder(cid1);
|
||||
int cidOrder2 = GetPackSortClassOrder(cid2);
|
||||
if (cidOrder1 != cidOrder2)
|
||||
return cidOrder1 > cidOrder2;
|
||||
return cid1 < cid2;
|
||||
}
|
||||
|
||||
if (cid1 == (int)EC_IvtrItem.InventoryClassId.ICID_WEAPON)
|
||||
{
|
||||
if (pItem1 is CECIvtrWeapon w1 && pItem2 is CECIvtrWeapon w2)
|
||||
{
|
||||
var e1 = w1.GetDBEssence();
|
||||
var e2 = w2.GetDBEssence();
|
||||
if (e1.level != e2.level)
|
||||
return e1.level > e2.level;
|
||||
}
|
||||
}
|
||||
else if (cid1 == (int)EC_IvtrItem.InventoryClassId.ICID_ARMOR)
|
||||
{
|
||||
if (pItem1 is EC_IvtrArmor a1 && pItem2 is EC_IvtrArmor a2)
|
||||
{
|
||||
var e1 = a1.GetDBEssence();
|
||||
var e2 = a2.GetDBEssence();
|
||||
if (e1.level != e2.level)
|
||||
return e1.level > e2.level;
|
||||
}
|
||||
}
|
||||
else if (cid1 == (int)EC_IvtrItem.InventoryClassId.ICID_GENERALCARD)
|
||||
{
|
||||
if (pItem1 is EC_IvtrGeneralCard c1 && pItem2 is EC_IvtrGeneralCard c2)
|
||||
{
|
||||
int t1 = c1.GetEssence().type;
|
||||
int t2 = c2.GetEssence().type;
|
||||
if (t1 != t2)
|
||||
return t1 < t2;
|
||||
}
|
||||
}
|
||||
|
||||
return tid1 < tid2;
|
||||
}
|
||||
|
||||
private static int GetPackSortClassOrder(int cid)
|
||||
{
|
||||
int[] s_CIDs =
|
||||
{
|
||||
(int)EC_IvtrItem.InventoryClassId.ICID_WEAPON,
|
||||
(int)EC_IvtrItem.InventoryClassId.ICID_ARROW,
|
||||
(int)EC_IvtrItem.InventoryClassId.ICID_TOSSMAT,
|
||||
(int)EC_IvtrItem.InventoryClassId.ICID_ARMOR,
|
||||
(int)EC_IvtrItem.InventoryClassId.ICID_DECORATION,
|
||||
(int)EC_IvtrItem.InventoryClassId.ICID_BIBLE,
|
||||
(int)EC_IvtrItem.InventoryClassId.ICID_FLYSWORD,
|
||||
(int)EC_IvtrItem.InventoryClassId.ICID_WING,
|
||||
(int)EC_IvtrItem.InventoryClassId.ICID_GOBLIN,
|
||||
(int)EC_IvtrItem.InventoryClassId.ICID_GOBLIN_EQUIP,
|
||||
(int)EC_IvtrItem.InventoryClassId.ICID_FASHION,
|
||||
(int)EC_IvtrItem.InventoryClassId.ICID_AUTOHP,
|
||||
(int)EC_IvtrItem.InventoryClassId.ICID_AUTOMP,
|
||||
(int)EC_IvtrItem.InventoryClassId.ICID_MEDICINE,
|
||||
(int)EC_IvtrItem.InventoryClassId.ICID_SKILLMATTER,
|
||||
(int)EC_IvtrItem.InventoryClassId.ICID_TARGETITEM,
|
||||
(int)EC_IvtrItem.InventoryClassId.ICID_STONE,
|
||||
(int)EC_IvtrItem.InventoryClassId.ICID_PETEGG,
|
||||
(int)EC_IvtrItem.InventoryClassId.ICID_REFINETICKET,
|
||||
(int)EC_IvtrItem.InventoryClassId.ICID_DYETICKET,
|
||||
(int)EC_IvtrItem.InventoryClassId.ICID_GOBLIN_EXPPILL,
|
||||
(int)EC_IvtrItem.InventoryClassId.ICID_GENERALCARD,
|
||||
(int)EC_IvtrItem.InventoryClassId.ICID_GENERALCARD_DICE,
|
||||
};
|
||||
|
||||
for (int i = 0; i < s_CIDs.Length; i++)
|
||||
{
|
||||
if (cid == s_CIDs[i])
|
||||
return s_CIDs.Length - i;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 22d7c6cd009100d44956b805ed093795
|
||||
@@ -2384,7 +2384,10 @@ namespace BrewMonster
|
||||
public bool GetPushDir(ref Vector3 vPushDir, uint dwMask, float deltaTime)
|
||||
{
|
||||
vPushDir = Vector3.zero;
|
||||
if (joystick.Horizontal == 0 && joystick.Vertical == 0)
|
||||
if (IsDead())
|
||||
return false;
|
||||
|
||||
if (joystick == null || (joystick.Horizontal == 0 && joystick.Vertical == 0))
|
||||
{
|
||||
if (isPressMoveUp)
|
||||
{
|
||||
|
||||
@@ -417,11 +417,20 @@ namespace BrewMonster
|
||||
if(pflySwordPrefab != null)
|
||||
{
|
||||
var pflySwordObject = Instantiate(pflySwordPrefab).transform;
|
||||
pflySwordObject.parent = m_pPlayerCECModel.m_skeletonBuilder.GetHook("HH_feijian").transform;
|
||||
Transform HH_feijian = m_pPlayerCECModel.m_skeletonBuilder.GetHook("HH_feijian").transform;
|
||||
Transform CC_feijian = FindChildRecursive(pflySwordObject, "CC_feijian");
|
||||
var posHH_feijian = HH_feijian.localPosition;
|
||||
if (posHH_feijian.z < 0)
|
||||
{
|
||||
posHH_feijian.z *= -1f;
|
||||
}
|
||||
posHH_feijian.y += CC_feijian.localPosition.y;
|
||||
HH_feijian.localPosition = posHH_feijian;
|
||||
pflySwordObject.parent = HH_feijian;
|
||||
pflySwordObject.localPosition = Vector3.zero;
|
||||
pflySwordObject.localRotation = Quaternion.identity;
|
||||
pflySwordObject.localScale = Vector3.one;
|
||||
|
||||
//HH_feijian.transform.position = CC_feijian.transform.position;
|
||||
m_Wing = pflySwordObject.transform;
|
||||
|
||||
m_Wing.gameObject.SetActive(false);
|
||||
|
||||
@@ -79,8 +79,16 @@ public class CECUIManager : MonoSingleton<CECUIManager>
|
||||
|
||||
ShowUI("Win_Hpmpxp");
|
||||
#if UNITY_EDITOR
|
||||
if(ChangeSkillShortcutButton == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
ChangeSkillShortcutButton.SetActive(true);
|
||||
#else
|
||||
if(ChangeSkillShortcutButton == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
ChangeSkillShortcutButton.SetActive(false);
|
||||
#endif
|
||||
}
|
||||
@@ -507,6 +515,8 @@ public class CECUIManager : MonoSingleton<CECUIManager>
|
||||
if (m_pDlgQuickBar1)
|
||||
m_pDlgQuickBar1.UpdateShortcuts();
|
||||
|
||||
SkillTriggerPanel.Instance?.Refresh();
|
||||
|
||||
/* if (m_pDlgSkillEdit != null && m_pDlgSkillEdit->IsShow())
|
||||
{
|
||||
// ¼¼Äܱ༽çÃæÖ»ÔÚ Show(true) µÄʱºò²ÅÄܸüÐÂ
|
||||
|
||||
@@ -360,6 +360,20 @@ public partial class CECGameRun : ITickable
|
||||
{
|
||||
return m_pHostPlayer;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Animation / offline test scenes: scene-placed host is not spawned via <see cref="InitCharacter"/>.
|
||||
/// Registers the in-scene <see cref="CECHostPlayer"/> so <see cref="EC_ManPlayer.GetPlayer"/> and skill GFX resolve host position.
|
||||
/// </summary>
|
||||
public void RegisterAnimSceneHostPlayer(CECHostPlayer host)
|
||||
{
|
||||
if (host == null)
|
||||
return;
|
||||
|
||||
m_pHostPlayer = host;
|
||||
BMLogger.Log($"[AnimSceneBootstrap] CECGameRun.RegisterAnimSceneHostPlayer cid={host.GetCharacterID()}");
|
||||
}
|
||||
|
||||
public void InitCharacter(cmd_self_info_1 info)
|
||||
{
|
||||
if (_playerPrefab == null)
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
using System;
|
||||
using Animancer;
|
||||
using BrewMonster;
|
||||
using System.Collections.Generic;
|
||||
@@ -12,10 +11,10 @@ namespace BrewMonster
|
||||
public string AnimationName;
|
||||
public bool IsForceStopPrevious;
|
||||
public int ITransTime;
|
||||
public CECAttackEvent AttackEvent;
|
||||
public bool IsLoop;
|
||||
public ChannelAct ChannelAct;
|
||||
public int Rank;
|
||||
public float PlaySpeed;
|
||||
}
|
||||
public class PlayerVisual : MonoBehaviour
|
||||
{
|
||||
@@ -26,7 +25,6 @@ namespace BrewMonster
|
||||
[SerializeField] private AnimancerState _currentState;
|
||||
[SerializeField] private Queue<AnimationQueue> _animationQueue = new Queue<AnimationQueue>();
|
||||
[SerializeField] private List<string> _animationList = new List<string>();
|
||||
[SerializeField] private bool isHit;
|
||||
[SerializeField] private int id;
|
||||
[SerializeField] private bool isDebug;
|
||||
[SerializeField] private bool debugNamePlateBounds;
|
||||
@@ -34,7 +32,6 @@ namespace BrewMonster
|
||||
|
||||
private const float FadeTime = 100;
|
||||
private const FadeMode FadeMode = Animancer.FadeMode.FixedDuration;
|
||||
QueueActionEvent queueActionEvent;
|
||||
private string previousAnimationName;
|
||||
private void PlayActionEventHandler(PlayActionEvent @event)
|
||||
{
|
||||
@@ -56,24 +53,25 @@ namespace BrewMonster
|
||||
{
|
||||
AnimationName = @event.AnimationName,
|
||||
IsForceStopPrevious = @event.IsForceStopPrevious,
|
||||
AttackEvent = @event.AttackEvent,
|
||||
ITransTime = @event.ITransTime,
|
||||
ChannelAct = @event.ChannelAct,
|
||||
Rank = @event.Rank
|
||||
Rank = @event.Rank,
|
||||
PlaySpeed = @event.PlaySpeed
|
||||
});
|
||||
_animationList = _animationQueue.Select(q => q.AnimationName).ToList();
|
||||
return;
|
||||
}
|
||||
}
|
||||
previousAnimationName = @event.AnimationName;
|
||||
InternalPlayAnimation(@event.AnimationName, @event.ITransTime, FadeMode);
|
||||
ApplyAnimationEndCallbacks(@event.AttackEvent, @event.ChannelAct, @event.Rank, @event.AnimationName, @event.IsLoop);
|
||||
InternalPlayAnimation(@event.AnimationName, @event.ITransTime, FadeMode, @event.PlaySpeed);
|
||||
ApplyAnimationEndCallbacks(@event.AnimationName, @event.IsLoop);
|
||||
}
|
||||
public void InitPlayerEventDoneHandler()
|
||||
{
|
||||
namedAnimancer = GetComponentInChildren<NamedAnimancerComponent>();
|
||||
if (namedAnimancer == null)
|
||||
{
|
||||
BrewMonster.BMLogger.LogWarning("InitPlayerEventDoneHandler animancer == null");
|
||||
BMLogger.LogWarning("InitPlayerEventDoneHandler animancer == null");
|
||||
return;
|
||||
}
|
||||
var player = GetComponentInParent<CECPlayer>();
|
||||
@@ -89,7 +87,6 @@ namespace BrewMonster
|
||||
_playerInfo = player.GetPlayInfo();
|
||||
id = _playerInfo.cid;
|
||||
EventBus.SubscribeChannel<PlayActionEvent>(_playerInfo.cid, PlayActionEventHandler);
|
||||
EventBus.SubscribeChannelClass<QueueActionEvent>(_playerInfo.cid, QueueActionEventHandler);
|
||||
EventBus.SubscribeChannel<ClearComActFlagAllRankNodesEvent>(_playerInfo.cid, ClearComActFlagAllRankNodesEventHandler);
|
||||
_eventBusSubscribed = true;
|
||||
}
|
||||
@@ -102,7 +99,6 @@ namespace BrewMonster
|
||||
if (!_eventBusSubscribed)
|
||||
return;
|
||||
EventBus.UnsubscribeChannel<PlayActionEvent>(_playerInfo.cid, PlayActionEventHandler);
|
||||
EventBus.UnsubscribeChannelClass<QueueActionEvent>(_playerInfo.cid, QueueActionEventHandler);
|
||||
EventBus.UnsubscribeChannel<ClearComActFlagAllRankNodesEvent>(_playerInfo.cid, ClearComActFlagAllRankNodesEventHandler);
|
||||
_eventBusSubscribed = false;
|
||||
}
|
||||
@@ -131,54 +127,14 @@ namespace BrewMonster
|
||||
{
|
||||
_animationQueue.Clear();
|
||||
_animationList = _animationQueue.Select(q => q.AnimationName).ToList();
|
||||
if (isHit)
|
||||
{
|
||||
ApplyDamage();
|
||||
}
|
||||
//todo: this is dummy to force change to idle state
|
||||
// EventBus.PublishChannel(_playerInfo.cid, new PlayActionEvent("站立_通用"));
|
||||
}
|
||||
|
||||
private void QueueActionEventHandler(QueueActionEvent @event)
|
||||
{
|
||||
if (!EnqueueAnimation(@event))
|
||||
{
|
||||
BMLogger.LogError("HoangDev : EnqueueAnimation Failed");
|
||||
}
|
||||
}
|
||||
private void Update()
|
||||
{
|
||||
PlayNext();
|
||||
}
|
||||
public bool EnqueueAnimation(QueueActionEvent @event)
|
||||
{
|
||||
if (namedAnimancer == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if(previousAnimationName == @event.AnimationName)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
previousAnimationName = @event.AnimationName;
|
||||
_animationQueue.Enqueue(new AnimationQueue
|
||||
{
|
||||
AnimationName = @event.AnimationName,
|
||||
IsForceStopPrevious = @event.IsForceStopPrevious,
|
||||
ITransTime = @event.ITransTime,
|
||||
AttackEvent = @event.AttackEvent,
|
||||
IsLoop = @event.IsLoop,
|
||||
ChannelAct = @event.ChannelAct,
|
||||
Rank = @event.Rank
|
||||
});
|
||||
_animationList = _animationQueue.Select(q => q.AnimationName).ToList();
|
||||
if (!isHit)
|
||||
{
|
||||
queueActionEvent = @event;
|
||||
isHit = @event.IsHitAnim;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
/// <summary>
|
||||
/// This function is used to enqueue an animation for looping when the animancer is not set to looping
|
||||
/// </summary>
|
||||
@@ -199,7 +155,6 @@ namespace BrewMonster
|
||||
{
|
||||
AnimationName = animationName,
|
||||
IsForceStopPrevious = false,
|
||||
AttackEvent = null,
|
||||
IsLoop = true
|
||||
});
|
||||
_animationList = _animationQueue.Select(q => q.AnimationName).ToList();
|
||||
@@ -219,45 +174,24 @@ namespace BrewMonster
|
||||
_currentState = null;
|
||||
}
|
||||
if (_currentState != null && _currentState.NormalizedTime < 1f) return;
|
||||
if (isHit)// have it relative to check _currentState == null?
|
||||
{
|
||||
ApplyDamage();
|
||||
}
|
||||
var animationQueue = _animationQueue.Dequeue();
|
||||
_animationList = _animationQueue.Select(q => q.AnimationName).ToList();
|
||||
previousAnimationName = animationQueue.AnimationName;
|
||||
InternalPlayAnimation(animationQueue.AnimationName, animationQueue.ITransTime, FadeMode);
|
||||
ApplyAnimationEndCallbacks(animationQueue.AttackEvent, animationQueue.ChannelAct, animationQueue.Rank, animationQueue.AnimationName,animationQueue.IsLoop);
|
||||
InternalPlayAnimation(animationQueue.AnimationName, animationQueue.ITransTime, FadeMode, animationQueue.PlaySpeed);
|
||||
ApplyAnimationEndCallbacks(animationQueue.AnimationName, animationQueue.IsLoop);
|
||||
}
|
||||
|
||||
private void ApplyAnimationEndCallbacks(CECAttackEvent attackEvent, ChannelAct channelAct, int rank, string animationName, bool isLoop)
|
||||
private void ApplyAnimationEndCallbacks( string animationName, bool isLoop)
|
||||
{
|
||||
if (_currentState == null) return;
|
||||
_currentState.Events.OnEnd = () =>
|
||||
{
|
||||
if (attackEvent != null)
|
||||
attackEvent.m_bSignaled = true;
|
||||
if(isLoop)
|
||||
{
|
||||
EnqueueAnimationForLooping(animationName);
|
||||
}
|
||||
if (channelAct == null || string.IsNullOrEmpty(animationName))
|
||||
return;
|
||||
var node = channelAct.GetNodeByRank((byte)rank);
|
||||
node?.m_pActive?.m_ActionNames?.Remove(animationName);
|
||||
|
||||
};
|
||||
}
|
||||
void ApplyDamage()
|
||||
{
|
||||
if (queueActionEvent == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
isHit = false;
|
||||
queueActionEvent.SetFlag(true, queueActionEvent.AttackEvent);
|
||||
queueActionEvent = null;
|
||||
}
|
||||
private void OnDestroy()
|
||||
{
|
||||
UnregisterPlayerEventHandlers();
|
||||
@@ -281,7 +215,7 @@ namespace BrewMonster
|
||||
/// <param name="animationName"></param>
|
||||
/// <param name="duration"></param>
|
||||
/// <param name="fadeMode"></param>
|
||||
private void InternalPlayAnimation(string animationName, float duration = FadeTime, FadeMode fadeMode = FadeMode)
|
||||
private void InternalPlayAnimation(string animationName, float duration = FadeTime, FadeMode fadeMode = FadeMode, float playSpeed = 1.0f)
|
||||
{
|
||||
if (namedAnimancer == null)
|
||||
{
|
||||
@@ -292,6 +226,7 @@ namespace BrewMonster
|
||||
{
|
||||
_currentState = namedAnimancer.TryPlay(animationName, duration / 1000, fadeMode);
|
||||
_currentState.Time = 0;
|
||||
_currentState.Speed = playSpeed > 0f ? playSpeed : 1.0f;
|
||||
_currentAnimationName = animationName;
|
||||
return;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user