diff --git a/Assets/PerfectWorld/Scripts/GameData/ExpTypes.cs b/Assets/PerfectWorld/Scripts/GameData/ExpTypes.cs index d2c06bdf3b..a974d8aa54 100644 --- a/Assets/PerfectWorld/Scripts/GameData/ExpTypes.cs +++ b/Assets/PerfectWorld/Scripts/GameData/ExpTypes.cs @@ -1,6 +1,7 @@ using System; using System.IO; using System.Runtime.InteropServices; +using System.Text; using ModelRenderer.Scripts.Common; namespace BrewMonster @@ -67,6 +68,34 @@ namespace BrewMonster public float attack_short_range; // Minimum attack range, for melee weapons = 0.0 public uint action_type; // Action type for attack animation + // ------------------------------ + // Helper methods + // ------------------------------ + + public string GetName() + { + // Convert UTF-16 ushort[] -> string + if (name == null) return string.Empty; + int len = Array.IndexOf(name, (ushort)0); + if (len < 0) len = name.Length; + return Encoding.Unicode.GetString(MemoryMarshal.AsBytes(name.AsSpan(0, len))); + } + + public string GetFileHitGfx() + { + if (file_hitgfx == null) return string.Empty; + int len = Array.IndexOf(file_hitgfx, (byte)0); + if (len < 0) len = file_hitgfx.Length; + return Encoding.ASCII.GetString(file_hitgfx, 0, len); + } + + public string GetFileHitSfx() + { + if (file_hitsfx == null) return string.Empty; + int len = Array.IndexOf(file_hitsfx, (byte)0); + if (len < 0) len = file_hitsfx.Length; + return Encoding.ASCII.GetString(file_hitsfx, 0, len); + } } [StructLayout(LayoutKind.Sequential, Pack = 1)] diff --git a/Assets/PerfectWorld/Scripts/Managers/CECAttacksMan.cs b/Assets/PerfectWorld/Scripts/Managers/CECAttacksMan.cs index 01f531d566..3337bc63f4 100644 --- a/Assets/PerfectWorld/Scripts/Managers/CECAttacksMan.cs +++ b/Assets/PerfectWorld/Scripts/Managers/CECAttacksMan.cs @@ -15,8 +15,7 @@ public class CECAttacksMan : MonoSingleton #if UNITY_EDITOR public List m_AttackList = new List(); #endif - - + private void Update() { #if UNITY_EDITOR @@ -174,7 +173,7 @@ public class CECAttackEvent m_timeToBeFired = 0; // Fire here - //DoFire(); + DoFire(); } else m_timeToBeFired -= dwDeltaTime; @@ -196,6 +195,241 @@ public class CECAttackEvent return true; } +bool DoFire() +{ + float vFlyScale = 1.0f; + float vHitScale = 1.0f; + + 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; iGetGameRun()->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; ifile_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 = GameController.Instance.GetTestVfx(); + vfx.transform.position = target.position; + GameController.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; iGetGameRun()->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() { @@ -371,4 +605,18 @@ enum MOD MOD_ATTACK_AURA = 0x1000, // ¹â»·¹¥»÷ MOD_REBOUND = 0x2000, // ·´µ¯ MOD_BEAT_BACK = 0x4000, // ·´»÷ +}; +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 }; \ No newline at end of file diff --git a/Assets/PerfectWorld/Scripts/Move/CECPlayer.cs b/Assets/PerfectWorld/Scripts/Move/CECPlayer.cs index 03b712fc48..ca43e7c66d 100644 --- a/Assets/PerfectWorld/Scripts/Move/CECPlayer.cs +++ b/Assets/PerfectWorld/Scripts/Move/CECPlayer.cs @@ -601,12 +601,12 @@ public abstract class CECPlayer : CECObject /* var pRightHandWeapon = GetRightHandWeapon(); bool bHideFX = !CECOptimize.Instance.GFX.CanShowAttack(GetCharacterID(), GetClassID());*/ - // ============================== // Ground Attack // ============================== if (GetMoveEnv() == (int)MoveEnvironment.MOVEENV_GROUND) { + // “起” 动作(挥起) szAct = EC_Utility.BuildActionName(action, weapon_type, "Æð"); EventBus.PublishChannel(m_PlayerInfo.cid, new PlayActionEvent(szAct)); @@ -717,6 +717,9 @@ public abstract class CECPlayer : CECObject public int GetShowingWeaponType() { + //todo: mr Hoang should double check it + return 10; + int weapon_type = 0; if (CanShowFashionWeapon((int)m_uAttackType, m_iFashionWeaponType) && m_aEquips[(int)IndexOfIteminEquipmentInventory.EQUIPIVTR_FASHION_WEAPON] != 0) @@ -801,7 +804,7 @@ public abstract class CECPlayer : CECObject BMLogger.LogError("CECPlayer::GetFashionConfig, Failed to load fashion weapon config"); return false; } - + int fashion_weapon_mask = (int)pConfig.Value.action_mask[fashion_weapon_type]; return (fashion_weapon_mask & (1 << GetWeaponType(weapon_type))) != 0; } diff --git a/Assets/PerfectWorld/Scripts/Network/CSNetwork/GameSession.cs b/Assets/PerfectWorld/Scripts/Network/CSNetwork/GameSession.cs index 4826149764..e48f211ab5 100644 --- a/Assets/PerfectWorld/Scripts/Network/CSNetwork/GameSession.cs +++ b/Assets/PerfectWorld/Scripts/Network/CSNetwork/GameSession.cs @@ -505,8 +505,7 @@ namespace CSNetwork EC_ManMessage.PostMessage(EC_MsgDef.MSG_PM_PLAYERATKRESULT, MANAGER_INDEX.MAN_PLAYER, -1, pDataBuf, pCmdHeader); else if (ISNPCID(pCmdAtk.attacker_id)) - EC_ManMessage.PostMessage(EC_MsgDef.MSG_NM_NPCATKRESULT, MANAGER_INDEX.MAN_PLAYER, 0, pDataBuf, - pCmdHeader); + EC_ManMessage.PostMessage(EC_MsgDef.MSG_NM_NPCATKRESULT, MANAGER_INDEX.MAN_NPC, 0, pDataBuf, pCmdHeader); break; case CommandID.HOST_ATTACKRESULT: _logger.Info($"HOST_ATTACKRESULT: " + pCmdHeader); @@ -856,10 +855,7 @@ namespace CSNetwork { return id != 0 && (id & 0x80000000) == 0; } - - public bool ISNPCID(int id) => ((id & unchecked((int)0x80000000)) != 0) - && ((id & 0x40000000) == 0); - + public bool ISNPCID(int id) => ((id & 0x80000000) != 0) && ((id & 0x40000000) == 0); private byte[] GetBytes(byte[] bytes, int length, int index) { byte[] arrByteData = new byte[length]; diff --git a/Assets/Prefabs/TestVfx.prefab b/Assets/Prefabs/TestVfx.prefab new file mode 100644 index 0000000000..1a039a76dd --- /dev/null +++ b/Assets/Prefabs/TestVfx.prefab @@ -0,0 +1,88 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1 &2282869967233380084 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 4793130207391123121} + - component: {fileID: 2444832684984909144} + - component: {fileID: 5574609718764827284} + m_Layer: 0 + m_Name: TestVfx + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &4793130207391123121 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2282869967233380084} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 2, y: 2, z: 2} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 0} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!33 &2444832684984909144 +MeshFilter: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2282869967233380084} + m_Mesh: {fileID: 10207, guid: 0000000000000000e000000000000000, type: 0} +--- !u!23 &5574609718764827284 +MeshRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2282869967233380084} + m_Enabled: 1 + m_CastShadows: 1 + m_ReceiveShadows: 1 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 2 + m_RayTraceProcedural: 0 + m_RayTracingAccelStructBuildFlagsOverride: 0 + m_RayTracingAccelStructBuildFlags: 1 + m_SmallMeshCulling: 1 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: f3479fe588d0d48bdb0958c3d12beaac, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 3 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_AdditionalVertexStreams: {fileID: 0} diff --git a/Assets/Prefabs/TestVfx.prefab.meta b/Assets/Prefabs/TestVfx.prefab.meta new file mode 100644 index 0000000000..3e568061b1 --- /dev/null +++ b/Assets/Prefabs/TestVfx.prefab.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 88e840e5dac12ed4383d994c7fadfef1 +PrefabImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/GameController.cs b/Assets/Scripts/GameController.cs index 6db59647bc..f4f2d14339 100644 --- a/Assets/Scripts/GameController.cs +++ b/Assets/Scripts/GameController.cs @@ -14,6 +14,7 @@ public class GameController : MonoBehaviour [SerializeField] private CECMonster monsterPrefab; [SerializeField] private CECNPCServer npcServerPrefab; [SerializeField] private CinemachineCamera cinemachineCamera; + [SerializeField] private GameObject _testVfxPrefab; //[SerializeField] private Transform ground; CECHostPlayer hostPlayer; @@ -83,6 +84,14 @@ public class GameController : MonoBehaviour { return Instantiate(npcServerPrefab, transform); } + public GameObject GetTestVfx() + { + return Instantiate(_testVfxPrefab, transform); + } + public void DestroyTestVfx(GameObject go, float delayTime) + { + Destroy(go,delayTime); + } public GameObject InitCharacter(info_player_1 info) { if (characterPrefab == null)