11/13
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 75a0cc0fd8902794a883916febf9855b
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,33 @@
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace BrewMonster
|
||||
{
|
||||
public static class ResetStaticUtilityEditor
|
||||
{
|
||||
[MenuItem("Tools/Reset Static Fields/Run Now", priority = 10)]
|
||||
public static void RunNow()
|
||||
{
|
||||
int count = ResetStaticUtility.ResetAll(logEach: true);
|
||||
EditorUtility.DisplayDialog("Reset Static Fields", $"Reset completed.\nFields processed: {count}", "OK");
|
||||
}
|
||||
|
||||
private const string AutoRunPath = "Tools/Reset Static Fields/Auto Reset On Play";
|
||||
|
||||
[MenuItem(AutoRunPath, priority = 11)]
|
||||
public static void ToggleAutoRunOnPlay()
|
||||
{
|
||||
bool enabled = ResetStaticUtility.GetAutoRunOnPlay();
|
||||
ResetStaticUtility.SetAutoRunOnPlay(!enabled);
|
||||
}
|
||||
|
||||
[MenuItem(AutoRunPath, validate = true)]
|
||||
public static bool ToggleAutoRunOnPlayValidate()
|
||||
{
|
||||
Menu.SetChecked(AutoRunPath, ResetStaticUtility.GetAutoRunOnPlay());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4f472ae43a592b64cb9876ad7a36eb3a
|
||||
@@ -1,25 +1,26 @@
|
||||
using BrewMonster;
|
||||
using BrewMonster.Assets.PerfectWorld.Scripts.Common;
|
||||
using BrewMonster.Managers;
|
||||
using CSNetwork.GPDataType;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Unity.VisualScripting;
|
||||
using UnityEngine;
|
||||
using static CECAttacksMan;
|
||||
|
||||
public class CECAttacksMan : MonoSingleton<CECAttacksMan>
|
||||
public class CECAttacksMan : Singleton<CECAttacksMan>
|
||||
{
|
||||
private readonly LinkedList<CECAttackEvent> m_AttackLinkedList = new LinkedList<CECAttackEvent>();
|
||||
private CECMultiSectionSkillMan m_pMultiSkillGfxComposerMan;
|
||||
|
||||
#if UNITY_EDITOR
|
||||
public List<CECAttackEvent> m_AttackList = new List<CECAttackEvent>();
|
||||
public List<CECAttackEvent> m_AttackList = new List<CECAttackEvent>();
|
||||
#endif
|
||||
|
||||
|
||||
private void Update()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
m_AttackList = m_AttackLinkedList.ToList();
|
||||
m_AttackList = m_AttackLinkedList.ToList();
|
||||
#endif
|
||||
var node = m_AttackLinkedList.First;
|
||||
while (node != null)
|
||||
@@ -68,7 +69,22 @@ public class CECAttacksMan : MonoSingleton<CECAttacksMan>
|
||||
newEvent.UpdateTargetFlag();
|
||||
return m_AttackLinkedList.Last.Value;
|
||||
}
|
||||
|
||||
public bool GetSkillSectionActionSuffix(int skill, int section, out string suffix)
|
||||
{
|
||||
// TODO: Implement multi-section skill logic
|
||||
// 待实现:多段技能逻辑
|
||||
if (m_pMultiSkillGfxComposerMan != null)
|
||||
{
|
||||
CECMultiSectionSkillMan::SectionInfo info = m_pMultiSkillGfxComposerMan.GetSecionInfo(skill, section);
|
||||
if (info && info->action_suffix != "0") // 0 表示技能没有后缀
|
||||
{
|
||||
suffix = info->action_suffix;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
suffix = null;
|
||||
return false;
|
||||
}
|
||||
public CECAttackEvent AddSkillAttack(int idHost, int idCastTarget, int idTarget, int idWeapon, int idSkill, int nSkillLevel, uint dwModifier, int nDamage)
|
||||
{
|
||||
var newEvent = new CECAttackEvent(
|
||||
@@ -104,6 +120,207 @@ public class CECAttacksMan : MonoSingleton<CECAttacksMan>
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Manager for multi-section skills
|
||||
/// 多段技能管理器
|
||||
/// </summary>
|
||||
public class CECMultiSectionSkillMan
|
||||
{
|
||||
/// <summary>
|
||||
/// Section information for multi-section skills
|
||||
/// 多段技能的段信息
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class SectionInfo
|
||||
{
|
||||
public int skill_id; // 技能ID / Skill ID
|
||||
public byte section; // 段号 / Section number
|
||||
public string action_suffix; // 动作后缀 / Action suffix
|
||||
public A3DSkillGfxComposer pComposer; // 技能特效组合器 / Skill GFX composer
|
||||
|
||||
public SectionInfo()
|
||||
{
|
||||
skill_id = 0;
|
||||
section = 1;
|
||||
action_suffix = string.Empty;
|
||||
pComposer = null;
|
||||
}
|
||||
}
|
||||
|
||||
// 用于多段技能的sgc映射 / Map for multi-section skill SGC files
|
||||
private readonly Dictionary<string, A3DSkillGfxComposer> m_SgcName2ComposerMap = new Dictionary<string, A3DSkillGfxComposer>();
|
||||
|
||||
// 多段技能组合器列表 / Multi-section skill composer list
|
||||
private readonly List<SectionInfo> m_MultiSectionSkillComposerVec = new List<SectionInfo>();
|
||||
|
||||
public CECMultiSectionSkillMan()
|
||||
{
|
||||
}
|
||||
|
||||
~CECMultiSectionSkillMan()
|
||||
{
|
||||
Release();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Release resources
|
||||
/// 释放资源
|
||||
/// </summary>
|
||||
public void Release()
|
||||
{
|
||||
m_MultiSectionSkillComposerVec.Clear();
|
||||
|
||||
foreach (var kvp in m_SgcName2ComposerMap)
|
||||
{
|
||||
if (kvp.Value != null)
|
||||
{
|
||||
// TODO: Implement proper disposal if A3DSkillGfxComposer has cleanup
|
||||
// kvp.Value.Release();
|
||||
}
|
||||
}
|
||||
|
||||
m_SgcName2ComposerMap.Clear();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Load configuration from file
|
||||
/// 从文件加载配置
|
||||
/// </summary>
|
||||
/// <param name="szFile">Configuration file path / 配置文件路径</param>
|
||||
/// <returns>Success / 是否成功</returns>
|
||||
public bool LoadConfig(string szFile)
|
||||
{
|
||||
// TODO: Implement file loading using Unity's file system
|
||||
// This would require porting AScriptFile functionality or using Unity's TextAsset
|
||||
BMLogger.LogWarning($"CECMultiSectionSkillMan.LoadConfig: Not yet implemented for {szFile}");
|
||||
|
||||
/*
|
||||
// Original C++ logic:
|
||||
// 1. Open script file
|
||||
// 2. Parse skill ID followed by { }
|
||||
// 3. Inside braces, parse comma-separated values: section,suffix,sgc
|
||||
// 4. Load or reuse A3DSkillGfxComposer for each SGC file
|
||||
// 5. Store SectionInfo in vector
|
||||
|
||||
// Example file format:
|
||||
// skill_id
|
||||
// {
|
||||
// section,suffix,sgc_file
|
||||
// section,suffix,sgc_file
|
||||
// }
|
||||
*/
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Play multi-section skill effect
|
||||
/// 播放多段技能特效
|
||||
/// </summary>
|
||||
/// <param name="nSkillID">Skill ID / 技能ID</param>
|
||||
/// <param name="section">Skill section / 技能段数</param>
|
||||
/// <param name="nHostID">Host character ID / 施法者ID</param>
|
||||
/// <param name="nCastTargetID">Cast target ID / 施法目标ID</param>
|
||||
/// <param name="Targets">Target data list / 目标数据列表</param>
|
||||
/// <param name="bIsGoblinSkill">Is goblin skill / 是否为精灵技能</param>
|
||||
public void Play(int nSkillID, int section, int nHostID, int nCastTargetID,
|
||||
List<TARGET_DATA> Targets, bool bIsGoblinSkill = false)
|
||||
{
|
||||
foreach (var info in m_MultiSectionSkillComposerVec)
|
||||
{
|
||||
if (nSkillID == info.skill_id && section == info.section && info.pComposer != null)
|
||||
{
|
||||
// TODO: Implement A3DSkillGfxComposer.Play method
|
||||
// info.pComposer.Play(nHostID, nCastTargetID, Targets, bIsGoblinSkill);
|
||||
BMLogger.Log($"CECMultiSectionSkillMan.Play: Skill {nSkillID}, Section {section}");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get skill GFX composer for specific skill and section
|
||||
/// 获取指定技能和段数的特效组合器
|
||||
/// </summary>
|
||||
/// <param name="skill">Skill ID / 技能ID</param>
|
||||
/// <param name="section">Section number / 段号</param>
|
||||
/// <returns>Skill GFX composer or null / 技能特效组合器或null</returns>
|
||||
public A3DSkillGfxComposer GetSkillGfxComposer(int skill, int section)
|
||||
{
|
||||
foreach (var info in m_MultiSectionSkillComposerVec)
|
||||
{
|
||||
if (skill == info.skill_id && section == info.section && info.pComposer != null)
|
||||
{
|
||||
return info.pComposer;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get section information for specific skill and section
|
||||
/// 获取指定技能和段数的段信息
|
||||
/// </summary>
|
||||
/// <param name="skill">Skill ID / 技能ID</param>
|
||||
/// <param name="section">Section number / 段号</param>
|
||||
/// <returns>Section info or null / 段信息或null</returns>
|
||||
public SectionInfo GetSecionInfo(int skill, int section)
|
||||
{
|
||||
foreach (var info in m_MultiSectionSkillComposerVec)
|
||||
{
|
||||
if (skill == info.skill_id && section == info.section)
|
||||
{
|
||||
return info;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Placeholder class for A3DSkillGfxComposer
|
||||
/// A3DSkillGfxComposer的占位类
|
||||
/// </summary>
|
||||
public class A3DSkillGfxComposer
|
||||
{
|
||||
public uint m_dwFlyTime; // 飞行时间 / Fly time in milliseconds
|
||||
|
||||
public A3DSkillGfxComposer()
|
||||
{
|
||||
m_dwFlyTime = 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Load composer from file
|
||||
/// 从文件加载组合器
|
||||
/// </summary>
|
||||
public bool Load(string sgcFile)
|
||||
{
|
||||
// TODO: Implement SGC file loading
|
||||
BMLogger.LogWarning($"A3DSkillGfxComposer.Load: Not yet implemented for {sgcFile}");
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initialize composer
|
||||
/// 初始化组合器
|
||||
/// </summary>
|
||||
public void Init(object pSkillGfxMan)
|
||||
{
|
||||
// TODO: Implement initialization
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Play skill effect
|
||||
/// 播放技能特效
|
||||
/// </summary>
|
||||
/* public void Play(int nHostID, int nCastTargetID, List<TARGET_DATA> targets, bool bIsGoblinSkill = false)
|
||||
{
|
||||
// TODO: Implement skill effect playback
|
||||
BMLogger.Log($"A3DSkillGfxComposer.Play: Host {nHostID}, Target {nCastTargetID}");
|
||||
}*/
|
||||
}
|
||||
[Serializable]
|
||||
public class CECAttackEvent
|
||||
{
|
||||
@@ -194,241 +411,242 @@ public class CECAttackEvent
|
||||
|
||||
return true;
|
||||
}
|
||||
bool DoFire()
|
||||
{
|
||||
float vFlyScale = 1.0f;
|
||||
float vHitScale = 1.0f;
|
||||
public void SetSkillSection(int nSection) { m_nSkillSection = nSection; }
|
||||
bool DoFire()
|
||||
{
|
||||
float vFlyScale = 1.0f;
|
||||
float vHitScale = 1.0f;
|
||||
|
||||
m_bDoFired = true;
|
||||
m_bDoFired = true;
|
||||
|
||||
if( GPDataTypeHelper.ISPLAYERID(m_idHost) )
|
||||
{
|
||||
if( m_idSkill != 0 )
|
||||
{
|
||||
// const A3DSkillGfxComposer* pComposer = NULL;
|
||||
//
|
||||
// // we use skill composed gfx to present the skill effect
|
||||
// if (m_nSkillSection>0) // ¶à¶Î¼¼ÄÜ
|
||||
// {
|
||||
// CECMultiSectionSkillMan pMan = m_pManager.GetMultiSkillGfxComposerMan();
|
||||
// if(pMan)
|
||||
// {
|
||||
// pMan->Play(m_idSkill, m_nSkillSection,m_idHost, m_idCastTarget, m_targets,GNET::ElementSkill::IsGoblinSkill(m_idSkill));
|
||||
// pComposer = pMan->GetSkillGfxComposer(m_idSkill, m_nSkillSection);
|
||||
// }
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// if(GNET::ElementSkill::IsGoblinSkill(m_idSkill))
|
||||
// m_pManager->GetSkillGfxComposerMan()->Play(m_idSkill, m_idHost, m_idCastTarget, m_targets, true);
|
||||
// else
|
||||
// m_pManager->GetSkillGfxComposerMan()->Play(m_idSkill, m_idHost, m_idCastTarget, m_targets);
|
||||
// pComposer = m_pManager->GetSkillGfxComposerMan()->GetSkillGfxComposer(m_idSkill);
|
||||
// }
|
||||
//
|
||||
// if (pComposer && pComposer->m_dwFlyTime == 0) // ¼¼ÄÜgfxûÓзÉÐÐʵ¼Ê£¬ÔòÂíÉÏÍ·¶¥Ã°×Ö
|
||||
// {
|
||||
// m_timeToDoDamage = 1;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// A3DVECTOR3 vecHost, vecTarget;
|
||||
// // now we estimated a time to do damage
|
||||
// if( m_targets.size() && _get_pos_by_id(m_idHost, vecHost) && _get_pos_by_id(m_targets[0].idTarget, vecTarget) )
|
||||
// {
|
||||
// m_timeToDoDamage = int(Magnitude(vecHost - vecTarget) / 20.0f * 1000.0f);
|
||||
// a_ClampFloor(m_timeToDoDamage, 10ul);
|
||||
// }
|
||||
// }
|
||||
}
|
||||
else if( m_idWeapon != 0 )
|
||||
{
|
||||
// first determine gfx used
|
||||
// const char * szFlyGFX = NULL;
|
||||
// const char * szHitGFX = NULL;
|
||||
//
|
||||
// // using weapon gfx
|
||||
// DATA_TYPE dt;
|
||||
// const void * pData = g_pGame->GetElementDataMan()->get_data_ptr(
|
||||
// m_idWeapon, ID_SPACE_ESSENCE, dt);
|
||||
// ASSERT(dt == DT_WEAPON_ESSENCE || dt == DT_PROJECTILE_ESSENCE);
|
||||
//
|
||||
// if( dt == DT_PROJECTILE_ESSENCE )
|
||||
// {
|
||||
// // Ô¶³ÌÎäÆ÷£¬Ê¹Óõ¯Ò©µÄЧ¹û
|
||||
// PROJECTILE_ESSENCE * pProjectile = (PROJECTILE_ESSENCE *) pData;
|
||||
//
|
||||
// szFlyGFX = pProjectile->file_firegfx + 4; // skip gfx/
|
||||
// szHitGFX = pProjectile->file_hitgfx + 4; // skip gfx/
|
||||
// }
|
||||
// else if (dt == DT_WEAPON_ESSENCE)
|
||||
// {
|
||||
// // ½ü³ÌÎïÀí¹¥»÷£¬Ê¹ÓÃÎäÆ÷µÄЧ¹û
|
||||
// WEAPON_ESSENCE * pWeapon = (WEAPON_ESSENCE *) pData;
|
||||
// WEAPON_SUB_TYPE * pWeaponType = (WEAPON_SUB_TYPE*) g_pGame->GetElementDataMan()->get_data_ptr(pWeapon->id_sub_type, ID_SPACE_ESSENCE, dt);
|
||||
// ASSERT(dt == DT_WEAPON_SUB_TYPE);
|
||||
// szFlyGFX = NULL;
|
||||
// szHitGFX = pWeaponType->file_hitgfx + 4; // skip gfx/
|
||||
// }
|
||||
//
|
||||
// bool bHideFlyGfx = !CECOptimize::Instance().GetGFX().CanShowFly(m_idHost);
|
||||
// bool bHideHitGfx = !CECOptimize::Instance().GetGFX().CanShowHit(m_idHost);
|
||||
// int nNumTargets = m_targets.size();
|
||||
// for(int i=0; i<nNumTargets; i++)
|
||||
// {
|
||||
// const TARGET_DATA& data = m_targets[i];
|
||||
//
|
||||
// const char * pszFlyGFX = szFlyGFX;
|
||||
// const char * pszHitGFX = szHitGFX;
|
||||
//
|
||||
// if( data.dwModifier & MOD_NULLITY )
|
||||
// pszHitGFX = "³ÌÐòÁªÈë\\»÷ÖÐ\\ÎÞЧ¹¥»÷»÷ÖÐ.gfx";
|
||||
//
|
||||
// if (bHideFlyGfx) pszFlyGFX = NULL;
|
||||
// if (bHideHitGfx) pszHitGFX = NULL;
|
||||
//
|
||||
// g_pGame->GetGameRun()->GetWorld()->GetSkillGfxMan()->AddSkillGfxEvent(m_idHost, data.idTarget,
|
||||
// pszFlyGFX, pszHitGFX, m_timeToDoDamage, false, enumLinearMove, 1, 0, NULL, vFlyScale, vHitScale, data.dwModifier);
|
||||
// }
|
||||
}
|
||||
else
|
||||
{
|
||||
// without weapon
|
||||
// ʹÓÃÈÌ×ÀàµÄ»÷ÖÐЧ¹û
|
||||
DATA_TYPE dt = DATA_TYPE.DT_INVALID;
|
||||
var pData = ElementDataManProvider.GetElementDataMan().get_data_ptr(183, ID_SPACE.ID_SPACE_ESSENCE, ref dt);
|
||||
WEAPON_SUB_TYPE pWeaponType = (WEAPON_SUB_TYPE) pData;
|
||||
if (GPDataTypeHelper.ISPLAYERID(m_idHost))
|
||||
{
|
||||
if (m_idSkill != 0)
|
||||
{
|
||||
// const A3DSkillGfxComposer* pComposer = NULL;
|
||||
//
|
||||
// // we use skill composed gfx to present the skill effect
|
||||
// if (m_nSkillSection>0) // ¶à¶Î¼¼ÄÜ
|
||||
// {
|
||||
// CECMultiSectionSkillMan pMan = m_pManager.GetMultiSkillGfxComposerMan();
|
||||
// if(pMan)
|
||||
// {
|
||||
// pMan->Play(m_idSkill, m_nSkillSection,m_idHost, m_idCastTarget, m_targets,GNET::ElementSkill::IsGoblinSkill(m_idSkill));
|
||||
// pComposer = pMan->GetSkillGfxComposer(m_idSkill, m_nSkillSection);
|
||||
// }
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// if(GNET::ElementSkill::IsGoblinSkill(m_idSkill))
|
||||
// m_pManager->GetSkillGfxComposerMan()->Play(m_idSkill, m_idHost, m_idCastTarget, m_targets, true);
|
||||
// else
|
||||
// m_pManager->GetSkillGfxComposerMan()->Play(m_idSkill, m_idHost, m_idCastTarget, m_targets);
|
||||
// pComposer = m_pManager->GetSkillGfxComposerMan()->GetSkillGfxComposer(m_idSkill);
|
||||
// }
|
||||
//
|
||||
// if (pComposer && pComposer->m_dwFlyTime == 0) // ¼¼ÄÜgfxûÓзÉÐÐʵ¼Ê£¬ÔòÂíÉÏÍ·¶¥Ã°×Ö
|
||||
// {
|
||||
// m_timeToDoDamage = 1;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// A3DVECTOR3 vecHost, vecTarget;
|
||||
// // now we estimated a time to do damage
|
||||
// if( m_targets.size() && _get_pos_by_id(m_idHost, vecHost) && _get_pos_by_id(m_targets[0].idTarget, vecTarget) )
|
||||
// {
|
||||
// m_timeToDoDamage = int(Magnitude(vecHost - vecTarget) / 20.0f * 1000.0f);
|
||||
// a_ClampFloor(m_timeToDoDamage, 10ul);
|
||||
// }
|
||||
// }
|
||||
}
|
||||
else if (m_idWeapon != 0)
|
||||
{
|
||||
// first determine gfx used
|
||||
// const char * szFlyGFX = NULL;
|
||||
// const char * szHitGFX = NULL;
|
||||
//
|
||||
// // using weapon gfx
|
||||
// DATA_TYPE dt;
|
||||
// const void * pData = g_pGame->GetElementDataMan()->get_data_ptr(
|
||||
// m_idWeapon, ID_SPACE_ESSENCE, dt);
|
||||
// ASSERT(dt == DT_WEAPON_ESSENCE || dt == DT_PROJECTILE_ESSENCE);
|
||||
//
|
||||
// if( dt == DT_PROJECTILE_ESSENCE )
|
||||
// {
|
||||
// // Ô¶³ÌÎäÆ÷£¬Ê¹Óõ¯Ò©µÄЧ¹û
|
||||
// PROJECTILE_ESSENCE * pProjectile = (PROJECTILE_ESSENCE *) pData;
|
||||
//
|
||||
// szFlyGFX = pProjectile->file_firegfx + 4; // skip gfx/
|
||||
// szHitGFX = pProjectile->file_hitgfx + 4; // skip gfx/
|
||||
// }
|
||||
// else if (dt == DT_WEAPON_ESSENCE)
|
||||
// {
|
||||
// // ½ü³ÌÎïÀí¹¥»÷£¬Ê¹ÓÃÎäÆ÷µÄЧ¹û
|
||||
// WEAPON_ESSENCE * pWeapon = (WEAPON_ESSENCE *) pData;
|
||||
// WEAPON_SUB_TYPE * pWeaponType = (WEAPON_SUB_TYPE*) g_pGame->GetElementDataMan()->get_data_ptr(pWeapon->id_sub_type, ID_SPACE_ESSENCE, dt);
|
||||
// ASSERT(dt == DT_WEAPON_SUB_TYPE);
|
||||
// szFlyGFX = NULL;
|
||||
// szHitGFX = pWeaponType->file_hitgfx + 4; // skip gfx/
|
||||
// }
|
||||
//
|
||||
// bool bHideFlyGfx = !CECOptimize::Instance().GetGFX().CanShowFly(m_idHost);
|
||||
// bool bHideHitGfx = !CECOptimize::Instance().GetGFX().CanShowHit(m_idHost);
|
||||
// int nNumTargets = m_targets.size();
|
||||
// for(int i=0; i<nNumTargets; i++)
|
||||
// {
|
||||
// const TARGET_DATA& data = m_targets[i];
|
||||
//
|
||||
// const char * pszFlyGFX = szFlyGFX;
|
||||
// const char * pszHitGFX = szHitGFX;
|
||||
//
|
||||
// if( data.dwModifier & MOD_NULLITY )
|
||||
// pszHitGFX = "³ÌÐòÁªÈë\\»÷ÖÐ\\ÎÞЧ¹¥»÷»÷ÖÐ.gfx";
|
||||
//
|
||||
// if (bHideFlyGfx) pszFlyGFX = NULL;
|
||||
// if (bHideHitGfx) pszHitGFX = NULL;
|
||||
//
|
||||
// g_pGame->GetGameRun()->GetWorld()->GetSkillGfxMan()->AddSkillGfxEvent(m_idHost, data.idTarget,
|
||||
// pszFlyGFX, pszHitGFX, m_timeToDoDamage, false, enumLinearMove, 1, 0, NULL, vFlyScale, vHitScale, data.dwModifier);
|
||||
// }
|
||||
}
|
||||
else
|
||||
{
|
||||
// without weapon
|
||||
// ʹÓÃÈÌ×ÀàµÄ»÷ÖÐЧ¹û
|
||||
DATA_TYPE dt = DATA_TYPE.DT_INVALID;
|
||||
var pData = ElementDataManProvider.GetElementDataMan().get_data_ptr(183, ID_SPACE.ID_SPACE_ESSENCE, ref dt);
|
||||
WEAPON_SUB_TYPE pWeaponType = (WEAPON_SUB_TYPE)pData;
|
||||
|
||||
bool bHideHitGfx = false;//!CECOptimize::Instance().GetGFX().CanShowHit(m_idHost);
|
||||
string szGFX= null;
|
||||
int nNumTargets = m_targets.Count();
|
||||
for(int i=0; i<nNumTargets; i++)
|
||||
{
|
||||
TARGET_DATA data = m_targets[i];
|
||||
|
||||
// szGFX = pWeaponType->file_hitgfx + 4; // skip gfx/
|
||||
string fullGfx = pWeaponType.GetFileHitGfx();
|
||||
szGFX = fullGfx.Length > 4 ? fullGfx.Substring(4) : string.Empty;
|
||||
if ((data.dwModifier & (int)MOD.MOD_NULLITY) != 0)
|
||||
szGFX = "程序联入\\击中\\无效攻击击中.gfx";//Program link\Hit\InvalidAttackHit.gfx
|
||||
if (bHideHitGfx) szGFX = null;
|
||||
|
||||
// g_pGame->GetGameRun()->GetWorld()->GetSkillGfxMan()->AddSkillGfxEvent(m_idHost, data.idTarget, NULL,
|
||||
// szGFX, m_timeToDoDamage, false, GfxMoveMode.enumLinearMove, 1, 0, NULL, vFlyScale, vHitScale, data.dwModifier);
|
||||
var target = EC_ManMessageMono.Instance?.GetObject(data.idTarget, 0)?.gameObject.transform;
|
||||
if (target == null)
|
||||
{
|
||||
BMLogger.LogError("Target is null!");
|
||||
return false;
|
||||
}
|
||||
var vfx = CECGameRun.Instance.GetTestVfx();
|
||||
vfx.transform.position = target.position;
|
||||
CECGameRun.Instance.DestroyTestVfx(vfx, 1f);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if( GPDataTypeHelper.ISNPCID(m_idHost) )
|
||||
{
|
||||
// if( m_idSkill != 0 )
|
||||
// {
|
||||
// const A3DSkillGfxComposer* pComposer = NULL;
|
||||
// // we use skill composed gfx to present the skill effect
|
||||
// if (m_nSkillSection>0) // ¶à¶Î¼¼ÄÜ
|
||||
// {
|
||||
// CECMultiSectionSkillMan* pMan = m_pManager->GetMultiSkillGfxComposerMan();
|
||||
// if(pMan)
|
||||
// {
|
||||
// pMan->Play(m_idSkill, m_nSkillSection,m_idHost, m_idCastTarget, m_targets);
|
||||
// pComposer = pMan->GetSkillGfxComposer(m_idSkill, m_nSkillSection);
|
||||
// }
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// m_pManager->GetSkillGfxComposerMan()->Play(m_idSkill, m_idHost, m_idCastTarget, m_targets);
|
||||
// pComposer = m_pManager->GetSkillGfxComposerMan()->GetSkillGfxComposer(m_idSkill);
|
||||
// }
|
||||
//
|
||||
// if (pComposer && pComposer->m_dwFlyTime == 0) // ¼¼ÄÜûÓзÉÐÐʱ¼ä£¬ÔòÖ±½ÓÍ·¶¥Ã°×Ö
|
||||
// {
|
||||
// m_timeToDoDamage = 1;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// A3DVECTOR3 vecHost, vecTarget;
|
||||
// // now we estimated a time to do damage
|
||||
// if( m_targets.size() && _get_pos_by_id(m_idHost, vecHost) && _get_pos_by_id(m_targets[0].idTarget, vecTarget) )
|
||||
// {
|
||||
// m_timeToDoDamage = int(Magnitude(vecHost - vecTarget) / 20.0f * 1000.0f);
|
||||
// a_ClampFloor(m_timeToDoDamage, 10ul);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// CECNPC * pNPC = g_pGame->GetGameRun()->GetWorld()->GetNPCMan()->GetNPC(m_idHost);
|
||||
// if (!pNPC)
|
||||
// return true;
|
||||
//
|
||||
// const char * szFlyGFX = NULL;
|
||||
// const char * szHitGFX = NULL;
|
||||
//
|
||||
// if (pNPC->IsMonsterNPC())
|
||||
// {
|
||||
// const MONSTER_ESSENCE * pEssence = ((CECMonster *)pNPC)->GetDBEssence();
|
||||
//
|
||||
// szFlyGFX = pEssence->file_gfx_short + 4; // skip gfx/
|
||||
// szHitGFX = pEssence->file_gfx_short_hit + 4; // skip gfx/
|
||||
// }
|
||||
// else if (pNPC->IsPetNPC())
|
||||
// {
|
||||
// //szFlyGFX = "";
|
||||
// const PET_ESSENCE* pEssence = ((CECPet*)pNPC)->GetDBEssence();
|
||||
//
|
||||
// szFlyGFX = pEssence->file_gfx_short + 4; //"²ß»®ÁªÈë\\ͨÓ÷ÉÐÐ\\¹¼ý·ÉÐÐ.gfx";
|
||||
//
|
||||
// szHitGFX = "²ß»®ÁªÈë\\¹ÖÎï»÷ÖÐ\\¹ÖÎïÈⲫ»÷ÖÐ.gfx";
|
||||
// }
|
||||
// else
|
||||
// return false;
|
||||
//
|
||||
// if( !szFlyGFX[0] )
|
||||
// szFlyGFX = NULL;
|
||||
//
|
||||
// if( !szHitGFX[0] )
|
||||
// szHitGFX = NULL;
|
||||
//
|
||||
// bool bHideFlyGfx = !CECOptimize::Instance().GetGFX().CanShowFly(m_idHost);
|
||||
// bool bHideHitGfx = !CECOptimize::Instance().GetGFX().CanShowHit(m_idHost);
|
||||
// int nNumTargets = m_targets.size();
|
||||
// for(int i=0; i<nNumTargets; i++)
|
||||
// {
|
||||
// const TARGET_DATA& data = m_targets[i];
|
||||
//
|
||||
// const char * pszFlyGFX = szFlyGFX;
|
||||
// const char * pszHitGFX = szHitGFX;
|
||||
// if( data.nDamage <= 0 )
|
||||
// {
|
||||
// pszHitGFX = NULL;
|
||||
// }
|
||||
// else if( data.dwModifier & MOD_NULLITY )
|
||||
// {
|
||||
// pszHitGFX = "³ÌÐòÁªÈë\\»÷ÖÐ\\ÎÞЧ¹¥»÷»÷ÖÐ.gfx";
|
||||
// }
|
||||
//
|
||||
// if (bHideFlyGfx) pszFlyGFX = NULL;
|
||||
// if (bHideHitGfx) pszHitGFX = NULL;
|
||||
//
|
||||
// g_pGame->GetGameRun()->GetWorld()->GetSkillGfxMan()->AddSkillGfxEvent(m_idHost, data.idTarget,
|
||||
// pszFlyGFX, pszHitGFX, m_timeToDoDamage, false, enumLinearMove, 1,
|
||||
// 0, NULL, vFlyScale, vHitScale, data.dwModifier);
|
||||
// }
|
||||
// }
|
||||
}
|
||||
else
|
||||
return true;
|
||||
|
||||
return true;
|
||||
}
|
||||
bool bHideHitGfx = false;//!CECOptimize::Instance().GetGFX().CanShowHit(m_idHost);
|
||||
string szGFX = null;
|
||||
int nNumTargets = m_targets.Count();
|
||||
for (int i = 0; i < nNumTargets; i++)
|
||||
{
|
||||
TARGET_DATA data = m_targets[i];
|
||||
|
||||
// szGFX = pWeaponType->file_hitgfx + 4; // skip gfx/
|
||||
string fullGfx = pWeaponType.GetFileHitGfx();
|
||||
szGFX = fullGfx.Length > 4 ? fullGfx.Substring(4) : string.Empty;
|
||||
if ((data.dwModifier & (int)MOD.MOD_NULLITY) != 0)
|
||||
szGFX = "程序联入\\击中\\无效攻击击中.gfx";//Program link\Hit\InvalidAttackHit.gfx
|
||||
if (bHideHitGfx) szGFX = null;
|
||||
|
||||
// g_pGame->GetGameRun()->GetWorld()->GetSkillGfxMan()->AddSkillGfxEvent(m_idHost, data.idTarget, NULL,
|
||||
// szGFX, m_timeToDoDamage, false, GfxMoveMode.enumLinearMove, 1, 0, NULL, vFlyScale, vHitScale, data.dwModifier);
|
||||
var target = EC_ManMessageMono.Instance?.GetObject(data.idTarget, 0)?.gameObject.transform;
|
||||
if (target == null)
|
||||
{
|
||||
BMLogger.LogError("Target is null!");
|
||||
return false;
|
||||
}
|
||||
var vfx = CECGameRun.Instance.GetTestVfx();
|
||||
vfx.transform.position = target.position;
|
||||
CECGameRun.Instance.DestroyTestVfx(vfx, 1f);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (GPDataTypeHelper.ISNPCID(m_idHost))
|
||||
{
|
||||
// if( m_idSkill != 0 )
|
||||
// {
|
||||
// const A3DSkillGfxComposer* pComposer = NULL;
|
||||
// // we use skill composed gfx to present the skill effect
|
||||
// if (m_nSkillSection>0) // ¶à¶Î¼¼ÄÜ
|
||||
// {
|
||||
// CECMultiSectionSkillMan* pMan = m_pManager->GetMultiSkillGfxComposerMan();
|
||||
// if(pMan)
|
||||
// {
|
||||
// pMan->Play(m_idSkill, m_nSkillSection,m_idHost, m_idCastTarget, m_targets);
|
||||
// pComposer = pMan->GetSkillGfxComposer(m_idSkill, m_nSkillSection);
|
||||
// }
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// m_pManager->GetSkillGfxComposerMan()->Play(m_idSkill, m_idHost, m_idCastTarget, m_targets);
|
||||
// pComposer = m_pManager->GetSkillGfxComposerMan()->GetSkillGfxComposer(m_idSkill);
|
||||
// }
|
||||
//
|
||||
// if (pComposer && pComposer->m_dwFlyTime == 0) // ¼¼ÄÜûÓзÉÐÐʱ¼ä£¬ÔòÖ±½ÓÍ·¶¥Ã°×Ö
|
||||
// {
|
||||
// m_timeToDoDamage = 1;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// A3DVECTOR3 vecHost, vecTarget;
|
||||
// // now we estimated a time to do damage
|
||||
// if( m_targets.size() && _get_pos_by_id(m_idHost, vecHost) && _get_pos_by_id(m_targets[0].idTarget, vecTarget) )
|
||||
// {
|
||||
// m_timeToDoDamage = int(Magnitude(vecHost - vecTarget) / 20.0f * 1000.0f);
|
||||
// a_ClampFloor(m_timeToDoDamage, 10ul);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// CECNPC * pNPC = g_pGame->GetGameRun()->GetWorld()->GetNPCMan()->GetNPC(m_idHost);
|
||||
// if (!pNPC)
|
||||
// return true;
|
||||
//
|
||||
// const char * szFlyGFX = NULL;
|
||||
// const char * szHitGFX = NULL;
|
||||
//
|
||||
// if (pNPC->IsMonsterNPC())
|
||||
// {
|
||||
// const MONSTER_ESSENCE * pEssence = ((CECMonster *)pNPC)->GetDBEssence();
|
||||
//
|
||||
// szFlyGFX = pEssence->file_gfx_short + 4; // skip gfx/
|
||||
// szHitGFX = pEssence->file_gfx_short_hit + 4; // skip gfx/
|
||||
// }
|
||||
// else if (pNPC->IsPetNPC())
|
||||
// {
|
||||
// //szFlyGFX = "";
|
||||
// const PET_ESSENCE* pEssence = ((CECPet*)pNPC)->GetDBEssence();
|
||||
//
|
||||
// szFlyGFX = pEssence->file_gfx_short + 4; //"²ß»®ÁªÈë\\ͨÓ÷ÉÐÐ\\¹¼ý·ÉÐÐ.gfx";
|
||||
//
|
||||
// szHitGFX = "²ß»®ÁªÈë\\¹ÖÎï»÷ÖÐ\\¹ÖÎïÈⲫ»÷ÖÐ.gfx";
|
||||
// }
|
||||
// else
|
||||
// return false;
|
||||
//
|
||||
// if( !szFlyGFX[0] )
|
||||
// szFlyGFX = NULL;
|
||||
//
|
||||
// if( !szHitGFX[0] )
|
||||
// szHitGFX = NULL;
|
||||
//
|
||||
// bool bHideFlyGfx = !CECOptimize::Instance().GetGFX().CanShowFly(m_idHost);
|
||||
// bool bHideHitGfx = !CECOptimize::Instance().GetGFX().CanShowHit(m_idHost);
|
||||
// int nNumTargets = m_targets.size();
|
||||
// for(int i=0; i<nNumTargets; i++)
|
||||
// {
|
||||
// const TARGET_DATA& data = m_targets[i];
|
||||
//
|
||||
// const char * pszFlyGFX = szFlyGFX;
|
||||
// const char * pszHitGFX = szHitGFX;
|
||||
// if( data.nDamage <= 0 )
|
||||
// {
|
||||
// pszHitGFX = NULL;
|
||||
// }
|
||||
// else if( data.dwModifier & MOD_NULLITY )
|
||||
// {
|
||||
// pszHitGFX = "³ÌÐòÁªÈë\\»÷ÖÐ\\ÎÞЧ¹¥»÷»÷ÖÐ.gfx";
|
||||
// }
|
||||
//
|
||||
// if (bHideFlyGfx) pszFlyGFX = NULL;
|
||||
// if (bHideHitGfx) pszHitGFX = NULL;
|
||||
//
|
||||
// g_pGame->GetGameRun()->GetWorld()->GetSkillGfxMan()->AddSkillGfxEvent(m_idHost, data.idTarget,
|
||||
// pszFlyGFX, pszHitGFX, m_timeToDoDamage, false, enumLinearMove, 1,
|
||||
// 0, NULL, vFlyScale, vHitScale, data.dwModifier);
|
||||
// }
|
||||
// }
|
||||
}
|
||||
else
|
||||
return true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool DoDamage()
|
||||
{
|
||||
@@ -477,7 +695,7 @@ bool DoFire()
|
||||
else if (GPDataTypeHelper.ISPLAYERID(idTarget))
|
||||
{
|
||||
|
||||
CECPlayer pPlayer = EC_ManMessageMono.Instance.GetECManPlayer.GetPlayer(idTarget);
|
||||
CECPlayer pPlayer = EC_ManMessageMono.Instance.GetECManPlayer.GetPlayer(idTarget);
|
||||
//BMLogger.LogError("HoangDev: CECPlayer pPlayer = " + pPlayer );
|
||||
|
||||
if (!pPlayer)
|
||||
@@ -606,15 +824,15 @@ enum MOD
|
||||
};
|
||||
enum GfxMoveMode
|
||||
{
|
||||
enumLinearMove = 0, // Linear
|
||||
enumParabolicMove, // Parabolic
|
||||
enumMissileMove, // Missile
|
||||
enumMeteoricMove, // Meteoric (shooting star)
|
||||
enumHelixMove, // Helix (spiral)
|
||||
enumCurvedMove, // Curved
|
||||
enumAccMove, // Accelerated
|
||||
enumOnTarget, // Targeted
|
||||
enumLink, // Linked
|
||||
enumRandMove, // Random movement
|
||||
enumMoveModeNum
|
||||
enumLinearMove = 0, // Linear
|
||||
enumParabolicMove, // Parabolic
|
||||
enumMissileMove, // Missile
|
||||
enumMeteoricMove, // Meteoric (shooting star)
|
||||
enumHelixMove, // Helix (spiral)
|
||||
enumCurvedMove, // Curved
|
||||
enumAccMove, // Accelerated
|
||||
enumOnTarget, // Targeted
|
||||
enumLink, // Linked
|
||||
enumRandMove, // Random movement
|
||||
enumMoveModeNum
|
||||
};
|
||||
@@ -66,6 +66,9 @@ namespace PerfectWorld.Scripts.Managers
|
||||
case int value when value == EC_MsgDef.MSG_PM_PLAYERRUNOUT:
|
||||
OnMsgPlayerRunOut(Msg);
|
||||
break;
|
||||
case int value when value == EC_MsgDef.MSG_PM_CASTSKILL:
|
||||
TransmitMessage(Msg);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -496,12 +499,12 @@ namespace PerfectWorld.Scripts.Managers
|
||||
{
|
||||
|
||||
}
|
||||
public bool TransmitMessage(ECMSG msg)
|
||||
public bool TransmitMessage(ECMSG Msg)
|
||||
{
|
||||
int cid = 0;
|
||||
var host = CECGameRun.Instance.GetHostPlayer();
|
||||
|
||||
switch (msg.dwMsg)
|
||||
switch (Msg.dwMsg)
|
||||
{
|
||||
/*case long value when value == EC_MsgDef.MSG_PM_PLAYEREQUIPDATA:
|
||||
if (msg.dwParam2 == S2C.EQUIP_DATA)
|
||||
@@ -511,7 +514,7 @@ namespace PerfectWorld.Scripts.Managers
|
||||
break;*/
|
||||
|
||||
case long value when value == EC_MsgDef.MSG_PM_PLAYERBASEINFO:
|
||||
cid = (int)((playerbaseinfo_re)msg.dwParam1).Player.id;
|
||||
cid = (int)((playerbaseinfo_re)Msg.dwParam1).Player.id;
|
||||
// Xoá khỏi cache
|
||||
//g_pGame.GetGameSession().GetC2SCmdCache().RemovePlayerBaseInfo(cid);
|
||||
break;
|
||||
@@ -527,8 +530,20 @@ namespace PerfectWorld.Scripts.Managers
|
||||
cid = ((cmd_object_landing)msg.dwParam1).object_id;
|
||||
break;*/
|
||||
case long value when value == EC_MsgDef.MSG_PM_PLAYERATKRESULT:
|
||||
cmd_object_atk_result pCmdAtk = GPDataTypeHelper.FromBytes<cmd_object_atk_result>((byte[])msg.dwParam1);
|
||||
cmd_object_atk_result pCmdAtk = GPDataTypeHelper.FromBytes<cmd_object_atk_result>((byte[])Msg.dwParam1);
|
||||
cid = pCmdAtk.attacker_id;
|
||||
break;
|
||||
case long value when value == EC_MsgDef.MSG_PM_CASTSKILL:
|
||||
switch (Convert.ToInt32(Msg.dwParam2))
|
||||
{
|
||||
case int value2 when value2 == CommandID.OBJECT_CAST_SKILL: cid = (GPDataTypeHelper.FromBytes<cmd_object_cast_skill>((byte[]) Msg.dwParam1)).caster; break;
|
||||
/* case CommandID.OBJECT_CAST_INSTANT_SKILL: cid = ((cmd_object_cast_instant_skill*)Msg.dwParam1)->caster; break;
|
||||
case CommandID.OBJECT_CAST_POS_SKILL: cid = ((cmd_object_cast_pos_skill*)Msg.dwParam1)->caster; break;
|
||||
case CommandID.SKILL_INTERRUPTED: cid = ((cmd_skill_interrupted*)Msg.dwParam1)->caster; break;
|
||||
case CommandID.PLAYER_CAST_RUNE_SKILL: cid = ((cmd_player_cast_rune_skill*)Msg.dwParam1)->caster; break;
|
||||
case CommandID.PLAYER_CAST_RUNE_INSTANT_SKILL: cid = ((cmd_player_cast_rune_instant_skill*)Msg.dwParam1)->caster; break;*/
|
||||
}
|
||||
|
||||
break;
|
||||
// ⚠️ Các case khác cũng tương tự, chỉ việc lấy ra đúng trường id / caster / user ...
|
||||
// Do quá dài nên bạn có thể copy dần từng case từ C++ sang.
|
||||
@@ -546,13 +561,13 @@ namespace PerfectWorld.Scripts.Managers
|
||||
|
||||
if (host != null && cid == host.GetCharacterID())
|
||||
{
|
||||
host.ProcessMessage(msg);
|
||||
host.ProcessMessage(Msg);
|
||||
}
|
||||
else
|
||||
{
|
||||
var elsePlayer = SeekOutElsePlayer(cid);
|
||||
if (elsePlayer != null)
|
||||
elsePlayer.ProcessMessage(msg);
|
||||
elsePlayer.ProcessMessage(Msg);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
@@ -21,8 +21,9 @@ public abstract class CECPlayer : CECObject
|
||||
{
|
||||
[SerializeField] protected Transform parentModel;
|
||||
[SerializeField] protected TextMeshProUGUI txtName;
|
||||
|
||||
[ResetStatic]
|
||||
private static PLAYER_ACTION[] _default_actions;
|
||||
[ResetStatic]
|
||||
private static PLAYER_ACTION[] _turning_actions;
|
||||
PLAYER_ACTION[] m_PlayerActions;
|
||||
[SerializeField] internal INFO m_PlayerInfo;
|
||||
@@ -56,6 +57,8 @@ public abstract class CECPlayer : CECObject
|
||||
protected static PLAYER_LEVELEXP_CONFIG _player_levelup_exp;
|
||||
private CECPlayerActionController m_pActionController;
|
||||
private enumWingType m_wingType;
|
||||
private int m_idCurSkillTarget;
|
||||
protected CECSkill m_pCurSkill;
|
||||
|
||||
protected int NUM_WEAPON_TYPE = 15;
|
||||
public static readonly int[] m_sciStateIDForStateAction = { 117 };
|
||||
@@ -158,6 +161,7 @@ public abstract class CECPlayer : CECObject
|
||||
m_iFashionWeaponType = -1;
|
||||
m_uAttackType = DEFAULT_ACTION_TYPE;
|
||||
|
||||
|
||||
AttachWeapon();
|
||||
}
|
||||
|
||||
@@ -182,6 +186,7 @@ public abstract class CECPlayer : CECObject
|
||||
|
||||
public static void InitStaticRes()
|
||||
{
|
||||
BMLogger.LogError("HoangDev: InitStaticRes");
|
||||
BuildActionList();
|
||||
DATA_TYPE dt = default;
|
||||
_player_levelup_exp = (PLAYER_LEVELEXP_CONFIG)ElementDataManProvider.GetElementDataMan()
|
||||
@@ -208,7 +213,7 @@ public abstract class CECPlayer : CECObject
|
||||
{
|
||||
if (_default_actions == null)
|
||||
{
|
||||
// thay cho hashtab trong C++
|
||||
|
||||
Dictionary<string, PLAYER_ACTION_INFO_CONFIG> actionMap =
|
||||
new Dictionary<string, PLAYER_ACTION_INFO_CONFIG>(100);
|
||||
|
||||
@@ -234,10 +239,18 @@ public abstract class CECPlayer : CECObject
|
||||
{
|
||||
if (!actionMap.TryAdd(data.ActionName, data))
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
if (!string.IsNullOrEmpty(data.ActionName) && data.ActionName[0] != '0')
|
||||
{
|
||||
if (!skillActionMap.TryAdd(data.Name, data))
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
CECStringTab actionNames = new CECStringTab();
|
||||
actionNames.Init("actions_player", false);
|
||||
|
||||
@@ -542,89 +555,88 @@ public abstract class CECPlayer : CECObject
|
||||
|
||||
if (CECAttacksMan.Instance.FindAttackByAttacker(GetPlayerInfo().cid))
|
||||
{
|
||||
BMLogger.LogError("CECAttacksMan::FindAttackByAttacker != NULL");
|
||||
ClearComActFlagAllRankNodes(true);
|
||||
}
|
||||
|
||||
// melee attack
|
||||
CECAttackEvent pAttack = CECAttacksMan.Instance.AddMeleeAttack(
|
||||
CECAttackEvent pAttack1 = CECAttacksMan.Instance.AddMeleeAttack(
|
||||
GetPlayerInfo().cid, idTarget, idWeapon, dwModifier, nDamage, nTimeFly);
|
||||
|
||||
if (pAttack != null)
|
||||
if (pAttack1 != null)
|
||||
{
|
||||
if (!IsDead() && (dwModifier & (uint)MOD.MOD_RETORT) == 0
|
||||
&& (dwModifier & (uint)MOD.MOD_ATTACK_AURA) == 0
|
||||
&& PlayAttackAction(nAttackSpeed, ref piAttackTime, pAttack)
|
||||
&& PlayAttackAction(nAttackSpeed, ref piAttackTime, pAttack1)
|
||||
&& (dwModifier & (uint)MOD.MOD_BEAT_BACK) == 0)
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
pAttack1.m_bSignaled = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (skillLevel == 0)
|
||||
{
|
||||
if (m_pCurSkill != null)
|
||||
skillLevel = m_pCurSkill.GetSkillLevel();
|
||||
else
|
||||
skillLevel = 1;
|
||||
}
|
||||
|
||||
CECAttackEvent pAttack = null;
|
||||
|
||||
// first try to find if there is already a skill attack event in attackman
|
||||
CECAttackerEvents attackerEvents = CECAttacksMan.Instance.FindAttackByAttacker(GetPlayerInfo().cid);
|
||||
if (attackerEvents)
|
||||
{
|
||||
CECAttackEvent pAttack1 = attackerEvents.Find(idSkill, nSection);
|
||||
if (pAttack1 != null)
|
||||
{
|
||||
// Ãæ¹¥»÷µÄ·ÇµÚÒ»´ÎÉ˺¦ÏûÏ¢
|
||||
pAttack1.AddTarget(idTarget, dwModifier, nDamage);
|
||||
goto EXIT;
|
||||
}
|
||||
else
|
||||
{
|
||||
attackerEvents.Signal();
|
||||
}
|
||||
}
|
||||
if (ElementSkill.IsGoblinSkill((uint)idSkill) &&
|
||||
ElementSkill.GetType((uint)idSkill) == 2)
|
||||
{
|
||||
pAttack = CECAttacksMan.Instance.AddSkillAttack(
|
||||
GetPlayerInfo().cid, GetPlayerInfo().cid, idTarget, GetWeaponID(), idSkill, skillLevel, dwModifier, nDamage);
|
||||
}
|
||||
else
|
||||
{
|
||||
// begin a skill attack
|
||||
pAttack = CECAttacksMan.Instance.AddSkillAttack(
|
||||
GetPlayerInfo().cid, m_idCurSkillTarget, idTarget, GetWeaponID(), idSkill, skillLevel, dwModifier, nDamage);
|
||||
}
|
||||
|
||||
if (pAttack != null)
|
||||
{
|
||||
pAttack.SetSkillSection(nSection);
|
||||
if (!IsDead() && (dwModifier & (uint)MOD.MOD_RETORT) == 0
|
||||
&& (dwModifier & (uint)MOD.MOD_ATTACK_AURA) == 0
|
||||
&& PlaySkillAttackAction(idSkill, nAttackSpeed, null, nSection, &pAttack.m_bSignaled)
|
||||
&& (dwModifier & (uint)MOD.MOD_BEAT_BACK) == 0)
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
pAttack.m_bSignaled = true;
|
||||
}
|
||||
}
|
||||
|
||||
EXIT:
|
||||
// // For skill attacking, time is always set to 0
|
||||
if (piAttackTime != 0)
|
||||
piAttackTime = 0;
|
||||
}
|
||||
//else
|
||||
//{
|
||||
// if (skillLevel == 0)
|
||||
// {
|
||||
// if (m_pCurSkill)
|
||||
// skillLevel = m_pCurSkill.GetSkillLevel();
|
||||
// else
|
||||
// skillLevel = 1;
|
||||
// }
|
||||
|
||||
// CECAttackEvent pAttack1 = null;
|
||||
|
||||
// // first try to find if there is already a skill attack event in attackman
|
||||
// CECAttackerEvents attackerEvents = g_pGame.GetGameRun().GetWorld().GetAttacksMan().FindAttackByAttacker(GetPlayerInfo().cid);
|
||||
// if (attackerEvents)
|
||||
// {
|
||||
// CECAttackEvent pAttack1 = attackerEvents.Find(idSkill, nSection);
|
||||
// if (pAttack1 != null)
|
||||
// {
|
||||
// // Ãæ¹¥»÷µÄ·ÇµÚÒ»´ÎÉ˺¦ÏûÏ¢
|
||||
// pAttack1.AddTarget(idTarget, dwModifier, nDamage);
|
||||
// goto EXIT;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// attackerEvents.Signal();
|
||||
// }
|
||||
// }
|
||||
// if (ElementSkill::IsGoblinSkill(idSkill) &&
|
||||
// GNET::ElementSkill::GetType(idSkill) == 2)
|
||||
// {
|
||||
// pAttack = g_pGame.GetGameRun().GetWorld().GetAttacksMan().AddSkillAttack(
|
||||
// GetPlayerInfo().cid, GetPlayerInfo().cid, idTarget, GetWeaponID(), idSkill, skillLevel, dwModifier, nDamage);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// // begin a skill attack
|
||||
// pAttack = g_pGame.GetGameRun().GetWorld().GetAttacksMan().AddSkillAttack(
|
||||
// GetPlayerInfo().cid, m_idCurSkillTarget, idTarget, GetWeaponID(), idSkill, skillLevel, dwModifier, nDamage);
|
||||
// }
|
||||
|
||||
// if (pAttack)
|
||||
// {
|
||||
// pAttack.SetSkillSection(nSection);
|
||||
// if (!IsDead() && (dwModifier & CECAttackEvent::MOD_RETORT) == 0
|
||||
// && (dwModifier & CECAttackEvent::MOD_ATTACK_AURA) == 0
|
||||
// && PlaySkillAttackAction(idSkill, nAttackSpeed, NULL, nSection, &pAttack.m_bSignaled)
|
||||
// && (dwModifier & CECAttackEvent::MOD_BEAT_BACK) == 0)
|
||||
// {
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// pAttack.m_bSignaled = true;
|
||||
// }
|
||||
// }
|
||||
|
||||
//EXIT:
|
||||
// // For skill attacking, time is always set to 0
|
||||
// if (piAttackTime)
|
||||
// *piAttackTime = 0;
|
||||
//}
|
||||
}
|
||||
|
||||
private void ClearComActFlagAllRankNodes(bool v)
|
||||
@@ -1135,9 +1147,7 @@ public abstract class CECPlayer : CECObject
|
||||
|
||||
int weapon_type = GetShowingWeaponType();
|
||||
|
||||
PLAYER_ACTION_INFO_CONFIG data = _default_skill_actions[(uint)idSkill];
|
||||
|
||||
if (data.action_prefix == null || data.action_prefix.Length == 0 || data.action_prefix[0] == 0)
|
||||
if (!_default_skill_actions.TryGetValue((uint)idSkill, out PLAYER_ACTION_INFO_CONFIG data) || data.action_prefix == null || data.action_prefix.Length == 0 || data.action_prefix[0] == 0)
|
||||
{
|
||||
// Check if it's a target item skill
|
||||
if (ElementSkill.GetCommonCoolDown((uint)idSkill) > 1 << 4)
|
||||
@@ -1154,6 +1164,7 @@ public abstract class CECPlayer : CECObject
|
||||
if (GetMoveEnv() == (int)MoveEnvironment.MOVEENV_GROUND)
|
||||
{
|
||||
szAct = EC_Utility.BuildActionName(data, weapon_type, "_Ò÷³ª_");
|
||||
BMLogger.LogError($"HoangDev: PlaySkillCastAction szAct={szAct} ");
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1197,6 +1208,171 @@ public abstract class CECPlayer : CECObject
|
||||
return m_pActionController != null
|
||||
&& m_pActionController.PlaySkillCastActionWithName(idSkill, szActName, bNoFX);
|
||||
}
|
||||
|
||||
public bool PlaySkillAttackAction(int idSkill, int nAttackSpeed, ref int piAttackTime, int nSection = 0, CECAttackEvent attackEvent = null)
|
||||
{
|
||||
if (_pPlayerModel == null)
|
||||
return false;
|
||||
|
||||
string szAct = "";
|
||||
|
||||
int weapon_type = GetShowingWeaponType();
|
||||
|
||||
if (!_default_skill_actions.TryGetValue((uint)idSkill, out PLAYER_ACTION_INFO_CONFIG data) ||
|
||||
data.action_prefix == null || data.action_prefix.Length == 0 || data.action_prefix[0] == 0)
|
||||
{
|
||||
// Check if it's a target item skill / 检查是否为目标道具技能
|
||||
// if (GNET::ElementSkill::GetCommonCoolDown(idSkill) > 1 << 4)
|
||||
// {
|
||||
// data = m_PlayerActions[(int)PLAYER_ACTION_TYPE.ACT_USING_TARGET_ITEM].data;
|
||||
// if (data == null || data.action_prefix == null || data.action_prefix.Length == 0 || data.action_prefix[0] == 0)
|
||||
// return false;
|
||||
// }
|
||||
// else
|
||||
return false;
|
||||
}
|
||||
|
||||
int nTime1, nTime2;
|
||||
bool bInfinite = false;
|
||||
// CECModel pRightHandWeapon = GetRightHandWeapon(); // 获取右手武器 / Get right hand weapon
|
||||
bool bHideFX = false; // !CECOptimize::Instance().GetGFX().CanShowAttack(GetCharacterID(), GetClassID());
|
||||
|
||||
var atkMan = CECAttacksMan.Instance;
|
||||
|
||||
if (GetMoveEnv() == (int)MoveEnvironment.MOVEENV_GROUND)
|
||||
{
|
||||
// 地面动作 / Ground action
|
||||
|
||||
szAct = EC_Utility.BuildActionName(data, weapon_type, "_施法行_");
|
||||
GetSkillSectionActionName(ref szAct, idSkill, nSection);
|
||||
|
||||
if (!PlaySkillAttackActionWithName(idSkill, szAct, bHideFX, attackEvent))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// nTime1 = m_pPlayerModel->GetComActTimeSpanByName(szAct); // 获取动作时长 / Get action time span
|
||||
// pAct = m_pPlayerModel->GetComActByName(szAct);
|
||||
// if (pAct) bInfinite |= pAct->IsInfinite();
|
||||
nTime1 = 1000; // 临时值 / Temporary value
|
||||
|
||||
szAct = $"{data.action_prefix}_施法行_{data.action_weapon_suffix[weapon_type].suffix}";
|
||||
GetSkillSectionActionName(ref szAct, idSkill, nSection);
|
||||
QueueSkillAttackActionWithName(idSkill, szAct, 0, bHideFX);
|
||||
|
||||
// nTime2 = m_pPlayerModel->GetComActTimeSpanByName(szAct);
|
||||
// pAct = m_pPlayerModel->GetComActByName(szAct);
|
||||
// if (pAct) bInfinite |= pAct->IsInfinite();
|
||||
nTime2 = 1000; // 临时值 / Temporary value
|
||||
}
|
||||
else
|
||||
{
|
||||
// 空中动作 / Air action
|
||||
string szActionMiddleName = null;
|
||||
if ((m_wingType == enumWingType.WINGTYPE_WING && IsFlying()) ||
|
||||
(m_iProfession == PROFESSION.PROF_ANGEL) ||
|
||||
(m_iProfession == PROFESSION.PROF_ARCHOR) ||
|
||||
(m_iProfession == PROFESSION.PROF_MONK) ||
|
||||
(m_iProfession == PROFESSION.PROF_GHOST))
|
||||
{
|
||||
szActionMiddleName = "空中翅膀"; // Air with wings / 空中翅膀
|
||||
}
|
||||
else
|
||||
{
|
||||
szActionMiddleName = "空中飞剑"; // Air with sword / 空中飞剑
|
||||
}
|
||||
|
||||
szAct = $"{data.action_prefix}_{szActionMiddleName}_施法行_{data.action_weapon_suffix[weapon_type].suffix}";
|
||||
GetSkillSectionActionName(ref szAct, idSkill, nSection);
|
||||
|
||||
if (!PlaySkillAttackActionWithName(idSkill, szAct, bHideFX, attackEvent))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// if (pRightHandWeapon && IsUsingMagicWeapon())
|
||||
// pRightHandWeapon->PlayActionByName(_GenWeaponActionName(szAct, m_iGender), 1.0f, true, 200, true, ACT_CASTSKILL, bHideFX);
|
||||
|
||||
// nTime1 = m_pPlayerModel->GetComActTimeSpanByName(szAct);
|
||||
// pAct = m_pPlayerModel->GetComActByName(szAct);
|
||||
// if (pAct) bInfinite |= pAct->IsInfinite();
|
||||
nTime1 = 1000; // 临时值 / Temporary value
|
||||
|
||||
szAct = $"{data.action_prefix}_{szActionMiddleName}_施法行_{data.action_weapon_suffix[weapon_type].suffix}";
|
||||
GetSkillSectionActionName(ref szAct, idSkill, nSection);
|
||||
QueueSkillAttackActionWithName(idSkill, szAct, 0, bHideFX);
|
||||
|
||||
// if (pRightHandWeapon && IsUsingMagicWeapon())
|
||||
// pRightHandWeapon->QueueAction(_GenWeaponActionName(szAct, m_iGender), 0, ACT_CASTSKILL, false, false, bHideFX);
|
||||
|
||||
// nTime2 = m_pPlayerModel->GetComActTimeSpanByName(szAct);
|
||||
// pAct = m_pPlayerModel->GetComActByName(szAct);
|
||||
// if (pAct) bInfinite |= pAct->IsInfinite();
|
||||
nTime2 = 1000; // 临时值 / Temporary value
|
||||
}
|
||||
|
||||
// int nExecuteTime = GNET::ElementSkill::GetExecuteTime(idSkill, 0); // 获取技能执行时间 / Get skill execute time
|
||||
int nExecuteTime = 2000; // 临时值 / Temporary value
|
||||
|
||||
// 调整动画速度以匹配攻击速度 / Adjust animation speed to match attack speed
|
||||
if (!bInfinite)
|
||||
{
|
||||
if (nExecuteTime > 0)
|
||||
{
|
||||
float vScale = (nTime1 + nTime2) / (float)nExecuteTime;
|
||||
// m_pPlayerModel->SetPlaySpeed(vScale * 1.2f);
|
||||
|
||||
// if (pRightHandWeapon && IsUsingMagicWeapon())
|
||||
// pRightHandWeapon->SetPlaySpeed(vScale * 1.2f);
|
||||
}
|
||||
|
||||
piAttackTime = nTime1 + nTime2;
|
||||
}
|
||||
else
|
||||
{
|
||||
// 动作循环,返回技能决定的执行时间 / Action loops, return skill-determined execute time
|
||||
piAttackTime = nExecuteTime;
|
||||
}
|
||||
|
||||
ShowWeaponByConfig(data);
|
||||
// UpdateWeaponHangerPosBySkillAction(idSkill); // 根据技能播放的动作,更改武器悬挂位置 / Update weapon hanger position based on skill action
|
||||
return true;
|
||||
}
|
||||
|
||||
// 播放技能攻击动作(带名称)/ Play skill attack action with name
|
||||
public bool PlaySkillAttackActionWithName(int idSkill, string szActName, bool bNoFX = false, CECAttackEvent attackEvent = null)
|
||||
{
|
||||
return m_pActionController != null
|
||||
&& m_pActionController.PlaySkillAttackActionWithName(idSkill, szActName, bNoFX, attackEvent != null ? new bool[] { attackEvent.m_bSignaled } : null, 0);
|
||||
}
|
||||
|
||||
// 队列播放技能攻击动作(带名称)/ Queue skill attack action with name
|
||||
public bool QueueSkillAttackActionWithName(int idSkill, string szActName, int nTransTime = 200, bool bNoFX = false, bool bResetSpeed = false, bool bResetActFlag = false, bool[] pNewActFlag = null, uint dwNewFlagMode = 0)
|
||||
{
|
||||
return m_pActionController != null
|
||||
&& m_pActionController.QueueSkillAttackActionWithName(idSkill, szActName, nTransTime, bNoFX, bResetSpeed, bResetActFlag, pNewActFlag, dwNewFlagMode);
|
||||
}
|
||||
|
||||
// 获取技能段动作名称 / Get skill section action name
|
||||
private void GetSkillSectionActionName(ref string szAct, int idSkill, int nSection)
|
||||
{
|
||||
if (nSection != 0)
|
||||
{
|
||||
var pAtkMan = CECAttacksMan.Instance;
|
||||
if (pAtkMan != null && pAtkMan.GetSkillSectionActionSuffix(idSkill, nSection, out string suffix))
|
||||
{
|
||||
szAct += "_" + suffix;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 判断是否在飞行 / Check if flying
|
||||
public bool IsFlying()
|
||||
{
|
||||
// 临时实现 / Temporary implementation
|
||||
return m_iMoveEnv == (int)MoveEnvironment.MOVEENV_AIR;
|
||||
}
|
||||
|
||||
bool GetSkillStateActionName(int skill, int state, string name1, string name2)
|
||||
{
|
||||
/* for (int i = 0; i < (int)m_SkillStateActionVec.size(); i++)
|
||||
|
||||
@@ -203,7 +203,13 @@ namespace BrewMonster.Scripts.Skills
|
||||
public virtual int SetLevel(int level) { return 0; }
|
||||
// �������?
|
||||
public virtual int GetMaxLevel() { return 0; }
|
||||
|
||||
public static byte GetType(uint id)
|
||||
{
|
||||
SkillStub s = SkillStub.GetStub(id);
|
||||
if (s != null)
|
||||
return s.GetType();
|
||||
return 0;
|
||||
}
|
||||
// �Ƿ���������
|
||||
public virtual bool IsWarmup() { return false; }
|
||||
// ʹ�ú��Ƿ��Զ�����
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
using System;
|
||||
|
||||
namespace BrewMonster
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Field, Inherited = false, AllowMultiple = false)]
|
||||
public sealed class ResetStaticAttribute : Attribute
|
||||
{
|
||||
public bool ClearCollection { get; }
|
||||
|
||||
public ResetStaticAttribute(bool clearCollection = false)
|
||||
{
|
||||
ClearCollection = clearCollection;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c3a0cdab3c60efe4c922639dc31fd198
|
||||
@@ -0,0 +1,181 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using UnityEngine;
|
||||
|
||||
namespace BrewMonster
|
||||
{
|
||||
public static class ResetStaticUtility
|
||||
{
|
||||
private const string AutoRunOnPlayPrefsKey = "ResetStaticUtility.AutoRunOnPlay";
|
||||
|
||||
public static int ResetAll(bool logEach = false, Func<Assembly, bool> assemblyFilter = null)
|
||||
{
|
||||
int resetCount = 0;
|
||||
var assemblies = AppDomain.CurrentDomain.GetAssemblies();
|
||||
|
||||
foreach (var assembly in assemblies)
|
||||
{
|
||||
if (assembly.IsDynamic)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (assemblyFilter == null)
|
||||
{
|
||||
string name = assembly.GetName().Name;
|
||||
if (!(name == "Assembly-CSharp" || name == "Assembly-CSharp-firstpass" || name.StartsWith("Assembly-CSharp-")))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else if (!assemblyFilter(assembly))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
Type[] types;
|
||||
try
|
||||
{
|
||||
types = assembly.GetTypes();
|
||||
}
|
||||
catch (ReflectionTypeLoadException ex)
|
||||
{
|
||||
types = ex.Types.Where(t => t != null).ToArray();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.LogWarning($"[ResetStatic] Failed to enumerate types for assembly {assembly.FullName}: {ex}");
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach (var type in types)
|
||||
{
|
||||
if (type == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
FieldInfo[] fields = type.GetFields(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy);
|
||||
foreach (var field in fields)
|
||||
{
|
||||
if (field.IsLiteral || field.IsInitOnly)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var attr = field.GetCustomAttribute<ResetStaticAttribute>(false);
|
||||
if (attr == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
object newValue = null;
|
||||
object currentValue = field.GetValue(null);
|
||||
|
||||
if (field.FieldType.IsValueType)
|
||||
{
|
||||
newValue = Activator.CreateInstance(field.FieldType);
|
||||
field.SetValue(null, newValue);
|
||||
resetCount++;
|
||||
if (logEach)
|
||||
{
|
||||
Debug.Log($"[ResetStatic] {type.FullName}.{field.Name} set to default({field.FieldType.Name}).");
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (attr.ClearCollection && currentValue != null)
|
||||
{
|
||||
bool cleared = TryClearCollection(currentValue);
|
||||
if (cleared)
|
||||
{
|
||||
resetCount++;
|
||||
if (logEach)
|
||||
{
|
||||
Debug.Log($"[ResetStatic] {type.FullName}.{field.Name} collection cleared.");
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
field.SetValue(null, null);
|
||||
resetCount++;
|
||||
if (logEach)
|
||||
{
|
||||
Debug.Log($"[ResetStatic] {type.FullName}.{field.Name} set to null.");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.LogWarning($"[ResetStatic] Failed to reset {type.FullName}.{field.Name}: {ex}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return resetCount;
|
||||
}
|
||||
|
||||
private static bool TryClearCollection(object instance)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (instance is System.Collections.IDictionary dictionary)
|
||||
{
|
||||
dictionary.Clear();
|
||||
return true;
|
||||
}
|
||||
|
||||
if (instance is System.Collections.IList list)
|
||||
{
|
||||
list.Clear();
|
||||
return true;
|
||||
}
|
||||
|
||||
// Try generic ICollection<T>.Clear()
|
||||
var clearMethod = instance.GetType().GetMethod("Clear", BindingFlags.Instance | BindingFlags.Public, null, Type.EmptyTypes, null);
|
||||
if (clearMethod != null)
|
||||
{
|
||||
clearMethod.Invoke(instance, null);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.LogWarning($"[ResetStatic] Failed to clear collection of type {instance.GetType().FullName}: {ex}");
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
|
||||
private static void AutoResetOnPlay()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
bool enabled = UnityEditor.EditorPrefs.GetBool(AutoRunOnPlayPrefsKey, true);
|
||||
if (!enabled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
ResetAll(logEach: false);
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
public static bool GetAutoRunOnPlay()
|
||||
{
|
||||
return UnityEditor.EditorPrefs.GetBool(AutoRunOnPlayPrefsKey, true);
|
||||
}
|
||||
|
||||
public static void SetAutoRunOnPlay(bool enabled)
|
||||
{
|
||||
UnityEditor.EditorPrefs.SetBool(AutoRunOnPlayPrefsKey, enabled);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1e3ede496bb135a4da6506adbcb7bbf2
|
||||
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:951300c91d8eb0444ef6f6d4231547c757908cba80c036bc743d186711fca527
|
||||
size 33032375
|
||||
oid sha256:37b57414ce51a79ba81ede1be7122f4a6b5b4fc856e9bb741aba9e533fd8d64c
|
||||
size 33032374
|
||||
|
||||
@@ -61,7 +61,6 @@ public partial class CECHostPlayer : CECPlayer
|
||||
private int m_iRoleCreateTime;
|
||||
private int m_iRoleLastLoginTime; // Role last login time
|
||||
private int m_iAccountTotalCash;
|
||||
private int m_idCurSkillTarget;
|
||||
|
||||
private List<CECObject> m_aTabSels = new List<CECObject>();
|
||||
private List<CECSkill> m_aPtSkills = new List<CECSkill>();
|
||||
@@ -409,7 +408,6 @@ public partial class CECHostPlayer : CECPlayer
|
||||
case int value when value == EC_MsgDef.MSG_HST_DIED: OnMsgHstDied(Msg); break;
|
||||
case int value when value == EC_MsgDef.MSG_HST_GOTO: OnMsgHstGoto(Msg); break;
|
||||
case int value when value == EC_MsgDef.MSG_PM_CASTSKILL: OnMsgPlayerCastSkill(Msg); break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -422,8 +420,7 @@ public partial class CECHostPlayer : CECPlayer
|
||||
bool bActionStartSkill = false;
|
||||
int iActionTime = 1000;
|
||||
//CECPlayerWrapper pWrapper = CECAutoPolicy.GetInstance().GetPlayerWrapper();
|
||||
BMLogger.LogError("HoangDev OnMsgPlayerCastSkill Msg.dwParam2 " + (int)Msg.dwParam2);
|
||||
switch ((int)Msg.dwParam2)
|
||||
switch (Convert.ToInt32(Msg.dwParam2))
|
||||
{
|
||||
case CommandID.OBJECT_CAST_SKILL:
|
||||
{
|
||||
@@ -781,7 +778,7 @@ public partial class CECHostPlayer : CECPlayer
|
||||
break;*/
|
||||
}
|
||||
|
||||
if (bActionStartSkill)
|
||||
/* if (bActionStartSkill)
|
||||
AP_ActionEvent(AP_EVENT_STARTSKILL, iActionTime);
|
||||
|
||||
if (bDoOtherThing)
|
||||
@@ -798,7 +795,7 @@ public partial class CECHostPlayer : CECPlayer
|
||||
if (idTarget != 0 && idTarget != m_PlayerInfo.cid)
|
||||
NormalAttackObject(idTarget, true);
|
||||
}
|
||||
}
|
||||
}*/
|
||||
}
|
||||
private void OnMsgHstSkillData(ECMSG Msg)
|
||||
{
|
||||
@@ -1452,7 +1449,14 @@ public partial class CECHostPlayer : CECPlayer
|
||||
|
||||
isRun = value;
|
||||
}
|
||||
public override void SetUpPlayer()
|
||||
{
|
||||
base.SetUpPlayer();
|
||||
|
||||
m_IncantCnt = new CECCounter();
|
||||
m_IncantCnt.SetPeriod(1000);
|
||||
m_IncantCnt.Reset(true);
|
||||
}
|
||||
public void InitCharacter(cmd_self_info_1 role)
|
||||
{
|
||||
SetUpPlayer();
|
||||
|
||||
Reference in New Issue
Block a user