Merge branch 'develop' into feature/hp_pet
# Conflicts: # Assets/PerfectWorld/Prefab/UIManager.prefab # Assets/PerfectWorld/Resources/UI/DialogScriptTableObject.asset # Assets/PerfectWorld/Scripts/Network/CSNetwork/GameSession.cs # Assets/PerfectWorld/Scripts/Network/UnityGameSession.cs # Assets/PerfectWorld/Scripts/Players/EC_HostMsg.cs # Assets/Scripts/CECHostPlayer.cs
This commit is contained in:
@@ -107,15 +107,11 @@ public partial class CECGameRun
|
||||
private static void Dispose()
|
||||
{
|
||||
instance = null;
|
||||
AddressableManager.Instance.ReleaseAsset(AddressResourceConfig.PlayerPrefab);
|
||||
AddressableManager.Instance.ReleaseAsset(AddressResourceConfig.MonsterPrefab);
|
||||
AddressableManager.Instance.ReleaseAsset(AddressResourceConfig.NpcServerPrefab);
|
||||
//AddressableManager.Instance.ReleaseAsset(AddressResourceConfig.PetServerPrefab);
|
||||
//AddressableManager.Instance.ReleaseAsset(AddressResourceConfig.PetMountServerPrefab);
|
||||
}
|
||||
|
||||
private void LoadPrefabs()
|
||||
{
|
||||
BMLogger.LogError("CECGameRun::LoadPrefabs, Loading prefabs from Resources. Consider using Addressables for better performance and memory management.");
|
||||
_playerPrefab = Resources.Load<GameObject>(AddressResourceConfig.PlayerPrefab);
|
||||
_monsterPrefab = Resources.Load<GameObject>(AddressResourceConfig.MonsterPrefab);
|
||||
_npcServerPrefab = Resources.Load<GameObject>(AddressResourceConfig.NpcServerPrefab);
|
||||
@@ -209,6 +205,13 @@ public partial class CECGameRun
|
||||
CECPlayer.InitStaticRes();
|
||||
hostPlayer = ObjectSpawner.Instance.InstantiateObject(_playerPrefab, setThisAsParent: true).AddComponent<CECHostPlayer>();
|
||||
hostPlayer.InitCharacter(info);
|
||||
|
||||
if (hostPlayer != null)
|
||||
{
|
||||
var t = Type.GetType("BrewMonster.UI.SelectedTargetHUDController, Assembly-CSharp");
|
||||
if (t != null && hostPlayer.GetComponent(t) == null)
|
||||
hostPlayer.gameObject.AddComponent(t);
|
||||
}
|
||||
}
|
||||
public CECMonster GetMonster()
|
||||
{
|
||||
|
||||
@@ -0,0 +1,906 @@
|
||||
using BrewMonster.Managers;
|
||||
using BrewMonster.Network;
|
||||
using BrewMonster.Scripts;
|
||||
using BrewMonster.Scripts.World;
|
||||
using CSNetwork;
|
||||
using CSNetwork.GPDataType;
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using static BrewMonster.Scripts.CECHPWork;
|
||||
using static CECPlayerWrapper;
|
||||
|
||||
namespace BrewMonster
|
||||
{
|
||||
public partial class CECHostPlayer
|
||||
{
|
||||
public void OnMsgHstAttackResult(ECMSG Msg)
|
||||
{
|
||||
byte[] data = Msg.dwParam1 as byte[];
|
||||
cmd_host_attack_result pCmd = EC_Utility.ByteArrayToStructure<cmd_host_attack_result>(data);
|
||||
|
||||
int iAttackTime = 0;
|
||||
TurnFaceTo(pCmd.idTarget);
|
||||
|
||||
PlayAttackEffect(pCmd.idTarget, 0, 0, pCmd.iDamage, (uint)pCmd.attack_flag, pCmd.attack_speed * 50,
|
||||
ref iAttackTime);
|
||||
|
||||
if (iAttackTime != 0)
|
||||
{
|
||||
if (m_pWorkMan.GetRunningWork(CECHPWork.Host_work_ID.WORK_HACKOBJECT) is CECHPWorkMelee pCurWork)
|
||||
{
|
||||
pCurWork.SetIdleTime(iAttackTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void OnMsgHstAttacked(ECMSG Msg)
|
||||
{
|
||||
var m_pPlayerMan = EC_ManMessageMono.Instance.EC_ManPlayer;
|
||||
cmd_host_attacked pCmd = GPDataTypeHelper.FromBytes<cmd_host_attacked>(Msg.dwParam1 as byte[]);
|
||||
|
||||
if (pCmd.iDamage != 0 && (pCmd.cEquipment & 0x7f) != 0x7f)
|
||||
{
|
||||
/* char cEquip = (char)(pCmd.cEquipment & 0x7f);
|
||||
CECIvtrEquip pEquip = (CECIvtrEquip)m_pEquipPack.GetItem(cEquip);
|
||||
if (pEquip)
|
||||
pEquip.AddCurEndurance(ARMOR_RUIN_SPEED);*/
|
||||
}
|
||||
|
||||
// The host player is attacked, we should make an effect here
|
||||
if (GPDataTypeHelper.ISPLAYERID(pCmd.idAttacker))
|
||||
{
|
||||
EC_ElsePlayer pAttacker = m_pPlayerMan.GetElsePlayer(pCmd.idAttacker);
|
||||
if (pAttacker)
|
||||
{
|
||||
if (!pAttacker.IsDead())
|
||||
{
|
||||
// Face to target
|
||||
pAttacker.TurnFaceTo(GetPlayerInfo().cid);
|
||||
}
|
||||
|
||||
int useless_attacktime = 0;
|
||||
pAttacker.PlayAttackEffect(GetCharacterID(), 0, 0, pCmd.iDamage, (uint)pCmd.attack_flag,
|
||||
pCmd.speed * 50, ref useless_attacktime);
|
||||
pAttacker.EnterFightState();
|
||||
}
|
||||
}
|
||||
else if (GPDataTypeHelper.ISNPCID(pCmd.idAttacker))
|
||||
{
|
||||
CECNPC pAttacker = EC_ManMessageMono.Instance.CECNPCMan.GetNPC(pCmd.idAttacker);
|
||||
if (pAttacker)
|
||||
{
|
||||
pAttacker.OnMsgAttackHostResult(GetCharacterID(), pCmd.iDamage, pCmd.attack_flag, pCmd.speed);
|
||||
}
|
||||
}
|
||||
|
||||
//CECAutoPolicy::GetInstance().SendEvent_BeHurt(pCmd.idAttacker);
|
||||
}
|
||||
|
||||
private void OnMsgHstHurtResult(ECMSG Msg)
|
||||
{
|
||||
//BMLogger.LogError("HoangDev : OnMsgHstHurtResult");
|
||||
/* int cmd = Convert.ToInt32(Msg.dwParam2);
|
||||
if (cmd == CommandID.BE_HURT)
|
||||
{
|
||||
cmd_be_hurt pCmd = (cmd_be_hurt)Msg.dwParam1;
|
||||
if (pCmd.damage != 0)
|
||||
Damaged(pCmd.damage);
|
||||
}
|
||||
else if (cmd == CommandID.HURT_RESULT)
|
||||
{
|
||||
cmd_hurt_result pCmd = (cmd_hurt_result)Msg.dwParam1;
|
||||
if (pCmd.target_id == m_PlayerInfo.cid)
|
||||
return; // Host himself will receive BE_HURT, so ignore this.
|
||||
|
||||
if (UnityGameSession.Instance.GameSession.ISPLAYERID(pCmd.target_id))
|
||||
{
|
||||
CECElsePlayer pTarget = m_pPlayerMan.GetElsePlayer(pCmd.target_id);
|
||||
if (pTarget)
|
||||
pTarget.Damaged(pCmd.damage);
|
||||
}
|
||||
else if (UnityGameSession.Instance.GameSession.ISNPCID(pCmd.target_id))
|
||||
{
|
||||
CECNPC pTarget = EC_ManMessageMono.Instance._CECNPCMan.GetNPC(pCmd.target_id);
|
||||
if (pTarget)
|
||||
pTarget.Damaged(pCmd.damage);
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
private void OnMsgHstStartAttack(in ECMSG Msg)
|
||||
{
|
||||
cmd_host_start_attack pCmd = GPDataTypeHelper.FromBytes<cmd_host_start_attack>((byte[])Msg.dwParam1);
|
||||
|
||||
// ASSERT(pCmd);
|
||||
|
||||
// test code...
|
||||
// g_pGame.GetRTDebug().OutputNotifyMessage(RTDCOL_WARNING, _AL("start attack !"));
|
||||
|
||||
// Check whether target is the one that we have selected
|
||||
if (m_idSelTarget != pCmd.idTarget)
|
||||
// g_pGame.RuntimeDebugInfo(RTDCOL_WARNING, _AL("Target has changed !"));
|
||||
|
||||
// If target turn to be un-attackable, cancel action
|
||||
if (AttackableJudge(pCmd.idTarget, true) == 0)
|
||||
{
|
||||
UnityGameSession.c2s_CmdCancelAction();
|
||||
// g_pGame.RuntimeDebugInfo(RTDCOL_WARNING, _AL("Cannel attacking !"));
|
||||
return;
|
||||
}
|
||||
|
||||
// Synchronize ammo amount
|
||||
// CECIvtrItem* pItem = m_pEquipPack.GetItem(EQUIPIVTR_PROJECTILE);
|
||||
// if (pItem)
|
||||
// {
|
||||
// if (!pCmd.ammo_remain)
|
||||
// m_pEquipPack.SetItem(EQUIPIVTR_PROJECTILE, NULL);
|
||||
// else
|
||||
// pItem.SetAmount(pCmd.ammo_remain);
|
||||
// }
|
||||
|
||||
CECHPWorkMelee pWork = (CECHPWorkMelee)m_pWorkMan.CreateWork(Host_work_ID.WORK_HACKOBJECT);
|
||||
m_pWorkMan.StartWork_p1(pWork);
|
||||
|
||||
m_bMelee = true;
|
||||
// AP_ActionEvent(AP_EVENT_STARTMELEE);
|
||||
}
|
||||
|
||||
private void OnMsgHstStopAttack(in ECMSG Msg)
|
||||
{
|
||||
// using namespace S2C;
|
||||
//
|
||||
m_bMelee = false;
|
||||
//
|
||||
// // if there is an attack event currently, we should let it fire now.
|
||||
ClearComActFlagAllRankNodes(true);
|
||||
|
||||
cmd_host_stop_attack pCmd = GPDataTypeHelper.FromBytes<cmd_host_stop_attack>((byte[])Msg.dwParam1);
|
||||
// ASSERT(pCmd);
|
||||
|
||||
/* If attack stopped for target is leave too far, trace it and continue
|
||||
attacking. Stop reason defined as below:
|
||||
|
||||
0x00: attack is canceled or host want to do some other things.
|
||||
0x01: unable to attack anymore (no ammo, weapon is broken etc.)
|
||||
0x02: invalid target (target missed or died)
|
||||
0x04: target is out of range
|
||||
*/
|
||||
if ((pCmd.iReason & 0x04) != 0)
|
||||
{
|
||||
if (!m_pWorkMan.IsMovingToPosition() &&
|
||||
!m_pWorkMan.IsTracing())
|
||||
{
|
||||
if (CmdNormalAttack(false, false, 0, -1)) //m_pComboSkill != NULL
|
||||
{
|
||||
// AP_ActionEvent(AP_EVENT_MELEEOUTOFRANGE, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pWorkMan.FinishRunningWork(Host_work_ID.WORK_HACKOBJECT);
|
||||
// AP_ActionEvent(AP_EVENT_STOPMELEE);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// AP_ActionEvent(AP_EVENT_STOPMELEE);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pWorkMan.FinishRunningWork(Host_work_ID.WORK_HACKOBJECT);
|
||||
// AP_ActionEvent(AP_EVENT_STOPMELEE);
|
||||
}
|
||||
|
||||
// #ifdef _SHOW_AUTOPOLICY_DEBUG
|
||||
// a_LogOutput(1, "Stop Attack, Reason = %d", pCmd.iReason);
|
||||
// #endif
|
||||
}
|
||||
|
||||
private void OnMsgHstSkillResult(ECMSG Msg)
|
||||
{
|
||||
cmd_host_skill_attack_result pCmd =
|
||||
GPDataTypeHelper.FromBytes<cmd_host_skill_attack_result>((byte[])Msg.dwParam1);
|
||||
int refFake = 0;
|
||||
PlayAttackEffect(pCmd.idTarget, pCmd.idSkill, 0, pCmd.iDamage, (uint)pCmd.attack_flag,
|
||||
pCmd.attack_speed * 50, ref refFake, pCmd.section);
|
||||
}
|
||||
|
||||
private void OnMsgPlayerCastSkill(ECMSG Msg)
|
||||
{
|
||||
bool bDoOtherThing = false;
|
||||
int idTarget = 0;
|
||||
|
||||
bool bActionStartSkill = false;
|
||||
int iActionTime = 1000;
|
||||
CECPlayerWrapper pWrapper = CECAutoPolicy.GetInstance().GetPlayerWrapper();
|
||||
|
||||
switch (Convert.ToInt32(Msg.dwParam2))
|
||||
{
|
||||
case CommandID.OBJECT_CAST_SKILL:
|
||||
{
|
||||
cmd_object_cast_skill pCmd =
|
||||
GPDataTypeHelper.FromBytes<cmd_object_cast_skill>((byte[])Msg.dwParam1);
|
||||
|
||||
if (m_pCurSkill != null)
|
||||
{
|
||||
m_pCurSkill.EndCharging();
|
||||
}
|
||||
|
||||
m_pCurSkill = GetPositiveSkillByID(pCmd.skill);
|
||||
if (m_pCurSkill == null) m_pCurSkill = GetEquipSkillByID(pCmd.skill);
|
||||
if (m_pCurSkill == null)
|
||||
m_pCurSkill = CECComboSkillState.Instance.GetInherentSkillByID((uint)pCmd.skill);
|
||||
if (m_pCurSkill == null)
|
||||
{
|
||||
Debug.Assert(m_pCurSkill != null, "Current skill should not be null");
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_pCurSkill.IsChargeable())
|
||||
m_pCurSkill.StartCharging(pCmd.time);
|
||||
|
||||
int iWaitTime = -1;
|
||||
if (m_pCurSkill.GetExecuteTime() >= 0)
|
||||
iWaitTime = pCmd.time + m_pCurSkill.GetExecuteTime();
|
||||
|
||||
CECHPWorkSpell pWork = (CECHPWorkSpell)m_pWorkMan.CreateWork(Host_work_ID.WORK_SPELLOBJECT);
|
||||
|
||||
pWork.PrepareCast(pCmd.target, m_pCurSkill, iWaitTime);
|
||||
m_pWorkMan.StartWork_p1(pWork);
|
||||
|
||||
// Start time counter for some type skill
|
||||
// 为某些类型的技能启动时间计数器
|
||||
if (!m_pCurSkill.IsChargeable())
|
||||
{
|
||||
int iTime = pCmd.time;
|
||||
if (iTime < 10) iTime = 10; // a_ClampFloor
|
||||
m_IncantCnt.SetPeriod(iTime);
|
||||
m_IncantCnt.Reset();
|
||||
}
|
||||
else
|
||||
{
|
||||
// make sure the counter is correct shown
|
||||
// 确保计数器正确显示
|
||||
m_IncantCnt.Reset(true);
|
||||
}
|
||||
|
||||
m_bSpellDSkill = false;
|
||||
|
||||
TurnFaceTo(pCmd.target);
|
||||
|
||||
m_idCurSkillTarget = pCmd.target;
|
||||
PlaySkillCastAction(m_pCurSkill.GetSkillID());
|
||||
|
||||
bActionStartSkill = true;
|
||||
iActionTime = iWaitTime;
|
||||
|
||||
// Special logging for return-to-town skill (167)
|
||||
// 回城技能(167)的特殊日志
|
||||
if (m_pCurSkill.GetSkillID() == ID_RETURNTOWN_SKILL)
|
||||
{
|
||||
Debug.Log(
|
||||
$"Return-to-town skill (167) cast - State2 should trigger SetReturntown(1) on server");
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case CommandID.SKILL_PERFORM:
|
||||
{
|
||||
// Skill perform
|
||||
// 技能执行
|
||||
m_pPrepSkill = null;
|
||||
|
||||
if (m_pCurSkill != null && m_pCurSkill.IsDurative())
|
||||
m_bSpellDSkill = true;
|
||||
|
||||
// Special handling for return-to-town skill (167)
|
||||
// 回城技能(167)的特殊处理
|
||||
// When skill 167 reaches State2, server calls SetReturntown(1) which should trigger MSG_HST_GOTO
|
||||
// 当技能167到达State2时,服务器调用SetReturntown(1),这应该触发MSG_HST_GOTO
|
||||
if (m_pCurSkill != null && m_pCurSkill.GetSkillID() == ID_RETURNTOWN_SKILL)
|
||||
{
|
||||
Debug.Log($"Skill 167 (Return to Town) performed - waiting for MSG_HST_GOTO from server");
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case CommandID.HOST_STOP_SKILL:
|
||||
{
|
||||
m_pPrepSkill = null;
|
||||
|
||||
CECSkill pSkillToMatch = m_pCurSkill;
|
||||
if (m_pCurSkill != null)
|
||||
{
|
||||
ClearComActFlagAllRankNodes(true);
|
||||
|
||||
if (((m_pComboSkill != null && !m_pComboSkill.IsStop()) ||
|
||||
m_pCurSkill.ChangeToMelee()) && !m_pWorkMan.HasDelayedWork())
|
||||
{
|
||||
bDoOtherThing = true;
|
||||
idTarget = m_idCurSkillTarget;
|
||||
}
|
||||
|
||||
m_pCurSkill.EndCharging();
|
||||
m_pCurSkill = null;
|
||||
}
|
||||
|
||||
AP.AP_ActionEvent((int)AP_EVENT.AP_EVENT_STOPSKILL);
|
||||
if (pSkillToMatch != null)
|
||||
{
|
||||
// m_pWorkMan中的当前任何Work为最高优先级或、或 CECHPWorkSpell 处于最高优先级且队列中有Delay时间
|
||||
// 此时此处无法准确匹配,而导致的 CECHPWorkSpell 执行时将落后于其它 CECHPWorkSpell 执行期间将无法响应
|
||||
// 在这种方法执行完成后,我们使用回城机制来
|
||||
// If the current Work in m_pWorkMan is the highest priority or CECHPWorkSpell is at the highest priority and there is Delay time in the queue
|
||||
// At this point, it cannot be accurately matched, causing the CECHPWorkSpell execution to lag behind other CECHPWorkSpell execution and cannot respond
|
||||
// After this method is executed, we use the return to city mechanism
|
||||
m_pWorkMan.FinishWork(new CECHPWorkSpellMatcher(pSkillToMatch));
|
||||
}
|
||||
|
||||
StopSkillAttackAction();
|
||||
|
||||
m_idCurSkillTarget = 0;
|
||||
break;
|
||||
}
|
||||
case CommandID.SELF_SKILL_INTERRUPTED:
|
||||
{
|
||||
// Skill interrupted
|
||||
// 技能被打断
|
||||
int skill_id = 0;
|
||||
m_pPrepSkill = null;
|
||||
|
||||
CECSkill
|
||||
pSkillToMatch = m_pCurSkill; // 保存指针值,用在后面函数调用中 | Save pointer value for later function call
|
||||
if (m_pCurSkill != null)
|
||||
{
|
||||
skill_id = m_pCurSkill.GetSkillID();
|
||||
|
||||
ClearComActFlagAllRankNodes(false);
|
||||
|
||||
if (((m_pComboSkill != null && !m_pComboSkill.IsStop()) ||
|
||||
m_pCurSkill.ChangeToMelee()) && !m_pWorkMan.HasDelayedWork())
|
||||
{
|
||||
bDoOtherThing = true;
|
||||
idTarget = m_idCurSkillTarget;
|
||||
}
|
||||
|
||||
m_pCurSkill.EndCharging();
|
||||
m_pCurSkill = null;
|
||||
}
|
||||
|
||||
m_idCurSkillTarget = 0;
|
||||
|
||||
|
||||
if (pSkillToMatch != null)
|
||||
{
|
||||
// 逻辑同 HOST_STOP_SKILL 分支处理 | Logic same as HOST_STOP_SKILL branch
|
||||
m_pWorkMan.FinishWork(new CECHPWorkSpellMatcher(pSkillToMatch));
|
||||
}
|
||||
|
||||
StopSkillCastAction();
|
||||
|
||||
// Print a notify message
|
||||
// 打印提示消息
|
||||
//EC_Game.GetGameRun().AddFixedMessage(FIXMSG_SKILLINTERRUPT);
|
||||
|
||||
AP.AP_ActionEvent((int)AP_EVENT.AP_EVENT_STOPSKILL);
|
||||
|
||||
// 通知策略技能被打断 | Notify policy that skill is interrupted
|
||||
CECAutoPolicy.GetInstance().SendEvent_SkillInterrupt(skill_id);
|
||||
break;
|
||||
}
|
||||
case CommandID.OBJECT_CAST_INSTANT_SKILL:
|
||||
{
|
||||
// Cast instant skill
|
||||
// 施放即时技能
|
||||
cmd_object_cast_instant_skill pCmd =
|
||||
GPDataTypeHelper.FromBytes<cmd_object_cast_instant_skill>((byte[])Msg.dwParam1);
|
||||
Debug.Assert(pCmd.caster == m_PlayerInfo.cid);
|
||||
|
||||
CECSkill pSkill = GetPositiveSkillByID(pCmd.skill);
|
||||
if (pSkill == null) pSkill = GetEquipSkillByID(pCmd.skill);
|
||||
if (pSkill == null)
|
||||
{
|
||||
Debug.Assert(pSkill != null, "Skill should not be null");
|
||||
return;
|
||||
}
|
||||
|
||||
if (pCmd.target != 0 && pCmd.target != m_PlayerInfo.cid)
|
||||
TurnFaceTo(pCmd.target);
|
||||
|
||||
PlaySkillCastAction(pSkill.GetSkillID());
|
||||
bActionStartSkill = true;
|
||||
break;
|
||||
}
|
||||
case CommandID.OBJECT_CAST_POS_SKILL:
|
||||
{
|
||||
// Cast position skill (target position instead of target object)
|
||||
// 施放位置技能(目标位置而不是目标对象)
|
||||
cmd_object_cast_pos_skill pCmd =
|
||||
GPDataTypeHelper.FromBytes<cmd_object_cast_pos_skill>((byte[])Msg.dwParam1);
|
||||
Debug.Assert(pCmd.caster == m_PlayerInfo.cid);
|
||||
|
||||
CECSkill pSkill = GetNormalSkill(pCmd.skill);
|
||||
if (pSkill == null) pSkill = GetEquipSkillByID(pCmd.skill);
|
||||
if (pSkill == null)
|
||||
{
|
||||
Debug.Assert(pSkill != null, "Skill should not be null");
|
||||
break;
|
||||
}
|
||||
|
||||
TurnFaceTo(pCmd.target);
|
||||
|
||||
if (pSkill.GetRangeType() != (int)CECSkill.RangeType.RANGE_SLEF &&
|
||||
pSkill.GetRangeType() != (int)CECSkill.RangeType.RANGE_SELFSPHERE &&
|
||||
(pSkill.GetSkillID() == 1095 || // 瞬影瞬斩 | Shadow instant slash
|
||||
pSkill.GetSkillID() == 1278 || // 魔·瞬影瞬斩 | Demon Shadow instant slash
|
||||
pSkill.GetSkillID() == 1279 || // 妖瞬影瞬斩 | Monster Shadow instant slash
|
||||
pSkill.GetSkillID() == 2313))
|
||||
{
|
||||
A3DVECTOR3 vPos = pCmd.pos;
|
||||
if (!IsPosCollideFree(vPos))
|
||||
{
|
||||
// Add a little height to ensure player's AABB won't embed with building
|
||||
// 添加一点高度以确保玩家的AABB不会嵌入建筑物
|
||||
vPos += new A3DVECTOR3(0, 1, 0) * 0.1f;
|
||||
}
|
||||
|
||||
// Ensure we are not under ground
|
||||
// 确保我们不在地下
|
||||
A3DVECTOR3 vNormal = new A3DVECTOR3();
|
||||
float vTerrainHeight = CECWorld.Instance.GetTerrainHeight(vPos, ref vNormal);
|
||||
if (vPos.y < vTerrainHeight)
|
||||
vPos.y = vTerrainHeight;
|
||||
|
||||
SetPos(EC_Utility.ToVector3(vPos));
|
||||
|
||||
m_CDRInfo.vTPNormal = vPos.y <= vTerrainHeight + 0.1f ? vNormal : new A3DVECTOR3(0);
|
||||
m_CDRInfo.fYVel = 0.0f;
|
||||
m_CDRInfo.vAbsVelocity = new A3DVECTOR3(0);
|
||||
ResetJump();
|
||||
|
||||
m_MoveCtrl.SetHostLastPos(vPos);
|
||||
m_MoveCtrl.SetLastSevPos(vPos);
|
||||
|
||||
// Update camera
|
||||
// 更新相机
|
||||
//UpdateFollowCamera(false, 10);
|
||||
}
|
||||
else
|
||||
{
|
||||
CECHPWorkFMove pWork =
|
||||
(CECHPWorkFMove)m_pWorkMan.CreateWork(CECHPWork.Host_work_ID.WORK_FLASHMOVE);
|
||||
|
||||
// 检查技能执行时间,防止出现浮点数0,出现错误 | Check skill execute time to prevent float 0 error
|
||||
int nExecuteTime = pSkill.GetExecuteTime();
|
||||
if (nExecuteTime < 50) nExecuteTime = 50; // a_ClampFloor
|
||||
|
||||
if (pSkill.GetSkillID() == 1145 || // 刺客的瞬移技能,需要增加地面效果1145:百步穿杨瞬斩 | Assassin teleport skill
|
||||
pSkill.GetSkillID() == 1314 || // 魔·百步穿杨瞬斩 | Demon hundred steps instant slash
|
||||
pSkill.GetSkillID() == 1315 || // 妖·百步穿杨瞬斩 | Monster hundred steps instant slash
|
||||
pSkill.GetSkillID() == 1362 || // 影遁回杨 | Shadow escape return
|
||||
pSkill.GetSkillID() == 1690 || // 影遁魔·回杨 | Shadow escape demon return
|
||||
pSkill.GetSkillID() == 1691 || // 影遁妖回杨 | Shadow escape monster return
|
||||
pSkill.GetSkillID() == 1845 || // 星湖之狐·瞬移技能 | Star Lake Fox teleport
|
||||
pSkill.GetSkillID() == 1844 || // 星湖之狐·瞬移技能 | Star Lake Fox teleport
|
||||
pSkill.GetSkillID() == 1815 || // 妖精 飞 | Fairy fly
|
||||
pSkill.GetSkillID() == 2272 || // 一步登天 | One step to heaven
|
||||
pSkill.GetSkillID() == 2315 || // 百步穿杨瞬斩 | Hundred steps instant slash
|
||||
pSkill.GetSkillID() == 2285 || // 回杨 | Return
|
||||
pSkill.GetSkillID() == 2340 || // 突袭 | Raid
|
||||
pSkill.GetSkillID() == 2341 || // 突袭 | Raid
|
||||
pSkill.GetSkillID() == 2342 || // 突袭 | Raid
|
||||
pSkill.GetSkillID() == 2553 || // 飞箭雨 | Arrow rain
|
||||
pSkill.GetSkillID() == 2740 || // 魔·飞箭雨 | Demon arrow rain
|
||||
pSkill.GetSkillID() == 2741 || // 妖飞箭雨 | Monster arrow rain
|
||||
pSkill.GetSkillID() == 2559 || // 闪电 | Lightning
|
||||
pSkill.GetSkillID() == 2752 || // 魔·闪电 | Demon lightning
|
||||
pSkill.GetSkillID() == 2753) // 妖闪电 | Monster lightning
|
||||
{
|
||||
A3DVECTOR3 vPos = pCmd.pos;
|
||||
if (!IsPosCollideFree(vPos))
|
||||
{
|
||||
// Add a little height to ensure player's AABB won't embed with building
|
||||
// 添加一点高度以确保玩家的AABB不会嵌入建筑物
|
||||
vPos += new A3DVECTOR3(0, 1, 0) * 0.1f;
|
||||
}
|
||||
|
||||
// Ensure we are not under ground
|
||||
// 确保我们不在地下
|
||||
A3DVECTOR3 vNormal = new A3DVECTOR3();
|
||||
float vTerrainHeight = CECWorld.Instance.GetTerrainHeight(vPos, ref vNormal);
|
||||
if (vPos.y < vTerrainHeight)
|
||||
vPos.y = vTerrainHeight;
|
||||
|
||||
m_CDRInfo.vTPNormal = vPos.y <= vTerrainHeight + 0.1f ? vNormal : new A3DVECTOR3(0);
|
||||
m_CDRInfo.fYVel = 0.0f;
|
||||
m_CDRInfo.vAbsVelocity = new A3DVECTOR3(0);
|
||||
ResetJump();
|
||||
|
||||
pWork.PrepareMove(pCmd.pos, nExecuteTime * 0.001f, pSkill.GetSkillID());
|
||||
}
|
||||
else
|
||||
{
|
||||
if (pSkill.GetRangeType() == (int)CECSkill.RangeType.RANGE_SLEF ||
|
||||
pSkill.GetRangeType() == (int)CECSkill.RangeType.RANGE_SELFSPHERE)
|
||||
{
|
||||
m_CDRInfo.vTPNormal = m_MoveCtrl.m_vFlashTPNormal;
|
||||
}
|
||||
|
||||
pWork.PrepareMove(pCmd.pos, nExecuteTime * 0.001f, 0);
|
||||
}
|
||||
|
||||
m_pWorkMan.StartWork_p2(pWork);
|
||||
iActionTime = nExecuteTime;
|
||||
}
|
||||
|
||||
bActionStartSkill = true;
|
||||
break;
|
||||
}
|
||||
case CommandID.PLAYER_CAST_RUNE_SKILL:
|
||||
{
|
||||
// Cast rune skill (item skill)
|
||||
// 施放符文技能(物品技能)
|
||||
cmd_player_cast_rune_skill pCmd =
|
||||
GPDataTypeHelper.FromBytes<cmd_player_cast_rune_skill>((byte[])Msg.dwParam1);
|
||||
Debug.Assert(pCmd.caster == m_PlayerInfo.cid);
|
||||
|
||||
if (m_pTargetItemSkill != null)
|
||||
{
|
||||
// Delete old target item skill
|
||||
m_pTargetItemSkill = null;
|
||||
}
|
||||
|
||||
m_pTargetItemSkill = new CECSkill(pCmd.skill, pCmd.level);
|
||||
if (m_pTargetItemSkill == null)
|
||||
{
|
||||
Debug.Assert(m_pTargetItemSkill != null, "Target item skill should not be null");
|
||||
return;
|
||||
}
|
||||
|
||||
m_pCurSkill = m_pTargetItemSkill;
|
||||
|
||||
if (m_pCurSkill.IsChargeable())
|
||||
m_pCurSkill.StartCharging(pCmd.time);
|
||||
|
||||
int iWaitTime = -1;
|
||||
if (m_pCurSkill.GetExecuteTime() >= 0)
|
||||
iWaitTime = pCmd.time + m_pCurSkill.GetExecuteTime();
|
||||
|
||||
CECHPWorkSpell pWork =
|
||||
(CECHPWorkSpell)m_pWorkMan.CreateWork(CECHPWork.Host_work_ID.WORK_SPELLOBJECT);
|
||||
pWork.PrepareCast(pCmd.target, m_pCurSkill, iWaitTime);
|
||||
m_pWorkMan.StartWork_p1(pWork);
|
||||
|
||||
// Start time counter for some type skill
|
||||
// 为某些类型的技能启动时间计数器
|
||||
if (!m_pCurSkill.IsChargeable())
|
||||
{
|
||||
int iTime = pCmd.time;
|
||||
if (iTime < 10) iTime = 10; // a_ClampFloor
|
||||
m_IncantCnt.SetPeriod(iTime);
|
||||
m_IncantCnt.Reset();
|
||||
}
|
||||
else
|
||||
{
|
||||
// make sure the counter is correct shown
|
||||
// 确保计数器正确显示
|
||||
m_IncantCnt.Reset(true);
|
||||
}
|
||||
|
||||
m_bSpellDSkill = false;
|
||||
|
||||
TurnFaceTo(pCmd.target);
|
||||
|
||||
m_idCurSkillTarget = pCmd.target;
|
||||
PlaySkillCastAction(m_pCurSkill.GetSkillID());
|
||||
|
||||
bActionStartSkill = true;
|
||||
iActionTime = iWaitTime;
|
||||
Debug.Log($"Cast rune skill({m_pCurSkill.GetSkillID()})");
|
||||
break;
|
||||
}
|
||||
case CommandID.PLAYER_CAST_RUNE_INSTANT_SKILL:
|
||||
{
|
||||
// Cast instant rune skill
|
||||
// 施放即时符文技能
|
||||
cmd_player_cast_rune_instant_skill pCmd =
|
||||
GPDataTypeHelper.FromBytes<cmd_player_cast_rune_instant_skill>((byte[])Msg.dwParam1);
|
||||
Debug.Assert(pCmd.caster == m_PlayerInfo.cid);
|
||||
|
||||
if (m_pTargetItemSkill != null)
|
||||
{
|
||||
// Delete old target item skill
|
||||
m_pTargetItemSkill = null;
|
||||
}
|
||||
|
||||
m_pTargetItemSkill = new CECSkill(pCmd.skill, pCmd.level);
|
||||
if (m_pTargetItemSkill == null)
|
||||
{
|
||||
Debug.Assert(m_pTargetItemSkill != null, "Target item skill should not be null");
|
||||
return;
|
||||
}
|
||||
|
||||
if (pCmd.target != 0 && pCmd.target != m_PlayerInfo.cid)
|
||||
TurnFaceTo(pCmd.target);
|
||||
|
||||
PlaySkillCastAction(m_pTargetItemSkill.GetSkillID());
|
||||
bActionStartSkill = true;
|
||||
break;
|
||||
}
|
||||
case CommandID.ERROR_MESSAGE:
|
||||
bDoOtherThing = true;
|
||||
break;
|
||||
|
||||
default:
|
||||
Debug.Assert(false, "Unknown message type in OnMsgPlayerCastSkill");
|
||||
break;
|
||||
}
|
||||
|
||||
if (bActionStartSkill)
|
||||
AP.AP_ActionEvent((int)AP_EVENT.AP_EVENT_STARTSKILL, iActionTime);
|
||||
|
||||
if (bDoOtherThing)
|
||||
{
|
||||
if (m_pComboSkill != null && !m_pComboSkill.IsStop())
|
||||
{
|
||||
// Continue combo skill
|
||||
// 继续连击技能
|
||||
if (CECAutoPolicy.GetInstance().IsAutoPolicyEnabled())
|
||||
EC_ManMessage.PostMessage(EC_MsgDef.MSG_HST_CONTINUECOMBOSKILL, MANAGER_INDEX.MAN_PLAYER, 0, 0,
|
||||
m_pComboSkill.GetGroupIndex());
|
||||
else
|
||||
m_pComboSkill.Continue(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (idTarget != 0 && idTarget != m_PlayerInfo.cid)
|
||||
NormalAttackObject(idTarget, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void OnMsgHstTargetIsFar(ECMSG Msg)
|
||||
{
|
||||
// TO DO: fix later
|
||||
//if(CmdNormalAttack(true, m_pComboSkill != null, 0, -1) )
|
||||
// AP_ActionEvent(AP_EVENT_MELEEOUTOFRANGE, 1);
|
||||
|
||||
if (CmdNormalAttack(true, false, 0, -1))
|
||||
{
|
||||
//AP_ActionEvent(AP_EVENT_MELEEOUTOFRANGE, 1);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnMsgHstDied(in ECMSG msg)
|
||||
{
|
||||
// Mark host player as corpse so CECPlayer.IsDead() returns true
|
||||
m_dwStates |= (uint)PlayerNPCState.GP_STATE_CORPSE;
|
||||
|
||||
EventBus.PublishChannel(GetCharacterID(), new ClearComActFlagAllRankNodesEvent(true));
|
||||
PlayAction((int)PLAYER_ACTION_TYPE.ACT_GROUNDDIE);
|
||||
if (PopupManager.Instance != null)
|
||||
{
|
||||
PopupManager.Instance.OnPlayerDied();
|
||||
}
|
||||
}
|
||||
|
||||
private bool NormalAttackObject(int idTarget, bool bForceAttack, bool bMoreClose = false)
|
||||
{
|
||||
if (idTarget == 0 || idTarget == m_PlayerInfo.cid)
|
||||
{
|
||||
// We should have check target isn't dead
|
||||
return false;
|
||||
}
|
||||
|
||||
//if (!EC_Game.GetGameRun().GetWorld().GetObject(idTarget, 1))
|
||||
// return false;
|
||||
bool bStartNewWork = false;
|
||||
|
||||
bool bUseAutoPF = false;
|
||||
//CECPlayerWrapper* pWrapper = CECAutoPolicy::GetInstance().GetPlayerWrapper();
|
||||
//if (CECAutoPolicy::GetInstance().IsAutoPolicyEnabled() && pWrapper.GetAttackError() >= 2)
|
||||
//bUseAutoPF = true;
|
||||
|
||||
CECHPWorkTrace pWorkTrace = null;
|
||||
CECHPWork pWork = null;
|
||||
if ((pWork = m_pWorkMan.GetWork(CECHPWork.Host_work_ID.WORK_TRACEOBJECT)) != null)
|
||||
{
|
||||
pWorkTrace = pWork as CECHPWorkTrace;
|
||||
}
|
||||
else if ((pWork = m_pWorkMan.GetWork(CECHPWork.Host_work_ID.WORK_HACKOBJECT)) != null)
|
||||
{
|
||||
if ((pWork as CECHPWorkMelee).GetTarget() == idTarget)
|
||||
return false; // Host is attacking the target
|
||||
|
||||
pWorkTrace = (CECHPWorkTrace)m_pWorkMan.CreateWork(CECHPWork.Host_work_ID.WORK_TRACEOBJECT);
|
||||
bStartNewWork = true;
|
||||
}
|
||||
else if (m_pWorkMan.CanStartWork(CECHPWork.Host_work_ID.WORK_TRACEOBJECT))
|
||||
{
|
||||
pWorkTrace = (CECHPWorkTrace)m_pWorkMan.CreateWork(CECHPWork.Host_work_ID.WORK_TRACEOBJECT);
|
||||
bStartNewWork = true;
|
||||
}
|
||||
|
||||
if (pWorkTrace != null)
|
||||
{
|
||||
pWorkTrace.SetTraceTarget(
|
||||
pWorkTrace.CreatTraceTarget(idTarget, CECHPWorkTrace.Trace_reason.TRACE_ATTACK, bForceAttack),
|
||||
bUseAutoPF);
|
||||
pWorkTrace.SetMoveCloseFlag(bMoreClose);
|
||||
|
||||
if (bStartNewWork)
|
||||
m_pWorkMan.StartWork_p1(pWorkTrace);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public int AttackableJudge(int idTarget, bool bForceAttack)
|
||||
{
|
||||
if (CannotAttack())
|
||||
return 0;
|
||||
|
||||
//if (CDlgAutoHelp::IsAutoHelp())
|
||||
// return 0;
|
||||
|
||||
if (idTarget == 0 || idTarget == m_PlayerInfo.cid)
|
||||
return -1;
|
||||
|
||||
CECObject pObject = EC_ManMessageMono.Instance.GetObject(idTarget, 1);
|
||||
if (!pObject)
|
||||
return -1;
|
||||
|
||||
// If target is pet, it's attacked possibility depends on it's monster
|
||||
if (GPDataTypeHelper.ISNPCID(idTarget))
|
||||
{
|
||||
CECNPC pNPC = (CECNPC)pObject;
|
||||
int idMaster = pNPC.GetMasterID();
|
||||
if (idMaster != 0)
|
||||
{
|
||||
// master¿ÉÄÜÊÇhostplayer
|
||||
if (idMaster == m_PlayerInfo.cid)
|
||||
return 0;
|
||||
|
||||
//// Follow pet cannot be attacked
|
||||
//if (pNPC.IsPetNPC() && ((CECPet)pNPC).IsFollowPet())
|
||||
// return 0;
|
||||
|
||||
idTarget = idMaster;
|
||||
pObject = EC_ManMessageMono.Instance.GetObject(idTarget, 1);
|
||||
if (!pObject)
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
int iRet = 0;
|
||||
|
||||
if (GPDataTypeHelper.ISNPCID(idTarget))
|
||||
{
|
||||
CECNPC pNPC = (CECNPC)pObject;
|
||||
|
||||
// If this npc is host's pet, cannot be attacked
|
||||
if (pNPC.GetMasterID() == m_PlayerInfo.cid)
|
||||
return 0;
|
||||
|
||||
// If it's a pet and can not be attacked, pet can be attacked only if it's a fighting pet
|
||||
//if (pNPC.IsPetNPC() && !((CECPet)pNPC).CanBeAttacked())
|
||||
// return 0;
|
||||
|
||||
if (IsInBattle()) // Host is in battle
|
||||
{
|
||||
if (InSameBattleCamp(pNPC))
|
||||
iRet = 0;
|
||||
else
|
||||
{
|
||||
if (pNPC.IsMonsterNPC())
|
||||
iRet = 1;
|
||||
else if (pNPC.IsServerNPC() &&
|
||||
(IsInFortress() ||
|
||||
pNPC.GetRoleInBattle() == 8)) // ¶Ô·þÎñÐÍNPCµÄ¹¥»÷£¬°ïÅÉ»ùµØ»ò³Çսʱ¿ÉÓÃ
|
||||
iRet = 1;
|
||||
else
|
||||
iRet = 0;
|
||||
}
|
||||
}
|
||||
else if (pNPC.IsServerNPC())
|
||||
{
|
||||
// In sanctuary we cannot attack NPCs
|
||||
if (!IsPVPOpen() || m_bInSanctuary || !bForceAttack)
|
||||
iRet = 0;
|
||||
else
|
||||
iRet = 1;
|
||||
}
|
||||
else // Is monster
|
||||
{
|
||||
iRet = 1;
|
||||
}
|
||||
|
||||
if (iRet == 1 && pNPC.GetOwnerFaction() > 0)
|
||||
{
|
||||
// Õë¶Ô°ïÅÉ PVP Õ½ÕùÖнûÖ¹²¿·Ö¹¥»÷
|
||||
if (GetFactionID() == pNPC.GetOwnerFaction() || // ²»¹¥»÷ͬ°ï¹Ö
|
||||
pNPC.IsFactionPVPMineCar() && !CanAttackFactionPVPMineCar() || // ÎÞ·¨ÔÙ¹¥»÷Ëû°ï¿ó³µÇé¿ö
|
||||
pNPC.IsFactionPVPMineBase() && !CanAttackFactionPVPMineBase())
|
||||
{
|
||||
// ÎÞ·¨ÔÙ¹¥»÷Ëû°ï´æ¿óµãÇé¿ö
|
||||
iRet = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (GPDataTypeHelper.ISPLAYERID(idTarget))
|
||||
{
|
||||
// Duel: allow attack only on duel opponent while in duel
|
||||
if (IsInDuel() && m_pvp.idDuelOpp == idTarget)
|
||||
return 1;
|
||||
if (m_pvp.iDuelState == Duel_state.DUEL_ST_STOPPING && m_pvp.idDuelOpp == idTarget)
|
||||
return 0;
|
||||
// Other player PVP not implemented here; treat as not attackable
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
return iRet;
|
||||
}
|
||||
public bool CannotAttack()
|
||||
{
|
||||
return (m_dwLIES & (uint)Logic_Influence_Extned_states.LIES_DISABLEFIGHT) != 0;
|
||||
}
|
||||
public bool glb_GetForceAttackFlag(uint pdwParam)
|
||||
{
|
||||
/*bool bForceAttack = false;
|
||||
CECInputCtrl* pInputCtrl = g_pGame.GetGameRun().GetInputCtrl();
|
||||
|
||||
if (pdwParam)
|
||||
bForceAttack = pInputCtrl.IsCtrlPressed(*pdwParam);
|
||||
else
|
||||
bForceAttack = pInputCtrl.KeyIsBeingPressed(VK_CONTROL);
|
||||
|
||||
return bForceAttack;*/
|
||||
return false;
|
||||
}
|
||||
// Start normal attacking to selected target
|
||||
public bool CmdNormalAttack(bool bMoreClose /* false */, bool bCombo /* false */,
|
||||
int idTarget /* 0 */, int iForceAtk /* -1 */)
|
||||
{
|
||||
// StackChecker::ACTrace(2);
|
||||
|
||||
// first of all see if we need to cancel sitdown work.
|
||||
// if (m_pWorkMan.IsSitting())
|
||||
// {
|
||||
// g_pGame.GetGameSession().c2s_CmdStandUp();
|
||||
// return false;
|
||||
// }
|
||||
|
||||
if (!CanDo(ActionCanDo.CANDO_MELEE))
|
||||
return false;
|
||||
|
||||
// if (InSlidingState())
|
||||
// return false;
|
||||
|
||||
// if (!bCombo)
|
||||
// ClearComboSkill();
|
||||
|
||||
if (idTarget <= 0)
|
||||
idTarget = m_idSelTarget;
|
||||
|
||||
bool bForceAttack;
|
||||
if (iForceAtk < 0)
|
||||
bForceAttack = glb_GetForceAttackFlag(0);
|
||||
else
|
||||
bForceAttack = iForceAtk > 0 ? true : false;
|
||||
|
||||
// Duel: server accepts attack on opponent only with PVP/force mask
|
||||
if (IsInDuel() && idTarget == m_pvp.idDuelOpp)
|
||||
bForceAttack = true;
|
||||
|
||||
if (AttackableJudge(idTarget, bForceAttack) != 1)
|
||||
return false;
|
||||
|
||||
return NormalAttackObject(idTarget, bForceAttack, bMoreClose);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9117c7fe23c427b4781d9dd334c1aba7
|
||||
@@ -0,0 +1,265 @@
|
||||
using BrewMonster.Managers;
|
||||
using BrewMonster.Network;
|
||||
using BrewMonster.Scripts;
|
||||
using BrewMonster.UI;
|
||||
using CSNetwork;
|
||||
using CSNetwork.GPDataType;
|
||||
using ModelRenderer.Scripts.GameData;
|
||||
using PerfectWorld.Scripts;
|
||||
using PerfectWorld.Scripts.Managers;
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using static BrewMonster.Scripts.CECHPWork;
|
||||
|
||||
namespace BrewMonster
|
||||
{
|
||||
public partial class CECHostPlayer
|
||||
{
|
||||
private void OnMsgHstNPCGreeting(ECMSG Msg)
|
||||
{
|
||||
cmd_npc_greeting pCmd = GPDataTypeHelper.FromBytes<cmd_npc_greeting>((byte[])Msg.dwParam1);
|
||||
|
||||
if (GPDataTypeHelper.ISNPCID(pCmd.idObject))
|
||||
{
|
||||
// ר�Ŵ���ѧϰ���ܵ�����NPC
|
||||
//if (CECHostSkillModel::Instance().IsSkillLearnNPC(pCmd.idObject))
|
||||
//{
|
||||
// CECGameUIMan* pGameUI = g_pGame.GetGameRun().GetUIManager().GetInGameUIMan();
|
||||
// //m_idSevNPC = pCmd.idObject;
|
||||
// //m_bTalkWithNPC = true;
|
||||
// //pGameUI.GetDialog("Win_SkillAction").Show(true);
|
||||
// //CDlgSkillAction* dlg = dynamic_cast<CDlgSkillAction*>(pGameUI.GetDialog("Win_SkillAction"));
|
||||
// //dlg.ForceShowDialog();
|
||||
// CDlgSkillAction* dlg = dynamic_cast<CDlgSkillAction*>(pGameUI.GetDialog("Win_SkillAction"));
|
||||
// dlg.SetReceivedNPCGreeting(true);
|
||||
// return;
|
||||
//}
|
||||
|
||||
CECNPC pNPC = EC_ManMessageMono.Instance.CECNPCMan.GetNPC(pCmd.idObject);
|
||||
if (!pNPC || !pNPC.IsServerNPC())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Check distance again
|
||||
if (!CanTouchTarget(pNPC.GetPos(), pNPC.GetTouchRadius(), 3))
|
||||
return;
|
||||
|
||||
m_idSevNPC = pCmd.idObject;
|
||||
m_bTalkWithNPC = true;
|
||||
|
||||
// Check way point service on NPC
|
||||
//TODO: Fix later
|
||||
//var dwID = (pNPC as CECNPCServer).GetWayPointID();
|
||||
//if (dwID != null && !HasWayPoint(dwID))
|
||||
//UnityGameSession.c2s_CmdNPCSevWaypoint();
|
||||
//g_pGame.GetGameSession().c2s_CmdNPCSevWaypoint();
|
||||
|
||||
var pGameUI = EC_Game.GetGameRun().GetUIManager().GetInGameUIMan();
|
||||
NPC_ESSENCE? result = (pNPC as CECNPCServer).GetDBEssence();
|
||||
if (result != null)
|
||||
{
|
||||
pGameUI.PopupNPCDialog(result.Value);
|
||||
}
|
||||
}
|
||||
//else if (GPDataTypeHelper.ISPLAYERID(pCmd.idObject))
|
||||
//{
|
||||
// EC_ElsePlayer pPlayer = m_pPlayerMan.GetElsePlayer(pCmd.idObject);
|
||||
|
||||
// // Check distance again
|
||||
// if (!pPlayer || !CanTouchTarget(pPlayer.GetPos(), 0.0f, 3))
|
||||
// return;
|
||||
|
||||
// m_idSevNPC = pCmd.idObject;
|
||||
// m_bTalkWithNPC = true;
|
||||
// m_iBoothState = 3;
|
||||
|
||||
// g_pGame.GetGameSession().c2s_CmdNPCSevGetContent(GP_NPCSEV_BOOTHSELL);
|
||||
|
||||
// m_pBuyPack.RemoveAllItems();
|
||||
// m_pSellPack.RemoveAllItems();
|
||||
// m_pEPBoothBPack.RemoveAllItems();
|
||||
// m_pEPBoothSPack.RemoveAllItems();
|
||||
|
||||
// CECGameUIMan* pGameUI = g_pGame.GetGameRun().GetUIManager().GetInGameUIMan();
|
||||
// pGameUI.PopupBoothDialog(true, false, pCmd.idObject);
|
||||
//}
|
||||
else
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
private void OnMsgPlayerDoEmote(ECMSG Msg)
|
||||
{
|
||||
if (!m_pWorkMan.IsStanding() &&
|
||||
!m_pWorkMan.IsBeingBound())
|
||||
return;
|
||||
|
||||
int cmd = Convert.ToInt32(Msg.dwParam2);
|
||||
if (cmd == CommandID.OBJECT_DO_EMOTE)
|
||||
{
|
||||
cmd_object_do_emote pCmd = GPDataTypeHelper.FromBytes<cmd_object_do_emote>((byte[])Msg.dwParam1);
|
||||
|
||||
DoEmote(pCmd.emotion);
|
||||
|
||||
// if( m_iBuddyId )
|
||||
// {
|
||||
// CECPlayer pBuddy = m_pPlayerMan.GetPlayer(m_iBuddyId);
|
||||
// if (pBuddy)
|
||||
// pBuddy.DoEmote(pCmd.emotion);
|
||||
// }
|
||||
|
||||
GetTaskInterface().SetEmotion(pCmd.emotion);
|
||||
}
|
||||
else if (cmd == CommandID.OBJECT_EMOTE_RESTORE)
|
||||
{
|
||||
CECHPWork pWork = m_pWorkMan.GetRunningWork((int)WorkID.WORK_STAND);
|
||||
if (pWork != null)
|
||||
{
|
||||
((CECHPWorkStand)pWork).SetPoseAction((int)PLAYER_ACTION_TYPE.ACT_STAND, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Do emote action
|
||||
private bool DoEmote(int idEmote)
|
||||
{
|
||||
if (!m_pWorkMan.IsStanding())
|
||||
return false;
|
||||
|
||||
CECHPWorkStand pWork = m_pWorkMan.GetRunningWork(Host_work_ID.WORK_STAND) as CECHPWorkStand;
|
||||
if (pWork == null)
|
||||
{
|
||||
Debug.LogError("Null CECHPWorkStand");
|
||||
}
|
||||
|
||||
int iAction = (int)PLAYER_ACTION_TYPE.ACT_STAND;
|
||||
bool bSession = false;
|
||||
|
||||
// Select action according to pose
|
||||
switch (idEmote)
|
||||
{
|
||||
case (int)RoleExpression.ROLEEXP_WAVE: iAction = (int)PLAYER_ACTION_TYPE.ACT_EXP_WAVE; break;
|
||||
case (int)RoleExpression.ROLEEXP_NOD: iAction = (int)PLAYER_ACTION_TYPE.ACT_EXP_NOD; break;
|
||||
case (int)RoleExpression.ROLEEXP_SHAKEHEAD: iAction = (int)PLAYER_ACTION_TYPE.ACT_EXP_SHAKEHEAD; break;
|
||||
case (int)RoleExpression.ROLEEXP_SHRUG: iAction = (int)PLAYER_ACTION_TYPE.ACT_EXP_SHRUG; break;
|
||||
case (int)RoleExpression.ROLEEXP_LAUGH: iAction = (int)PLAYER_ACTION_TYPE.ACT_EXP_LAUGH; break;
|
||||
case (int)RoleExpression.ROLEEXP_ANGRY: iAction = (int)PLAYER_ACTION_TYPE.ACT_EXP_ANGRY; break;
|
||||
case (int)RoleExpression.ROLEEXP_STUN: iAction = (int)PLAYER_ACTION_TYPE.ACT_EXP_STUN; break;
|
||||
case (int)RoleExpression.ROLEEXP_DEPRESSED: iAction = (int)PLAYER_ACTION_TYPE.ACT_EXP_DEPRESSED; break;
|
||||
case (int)RoleExpression.ROLEEXP_KISSHAND: iAction = (int)PLAYER_ACTION_TYPE.ACT_EXP_KISSHAND; break;
|
||||
case (int)RoleExpression.ROLEEXP_SHY: iAction = (int)PLAYER_ACTION_TYPE.ACT_EXP_SHY; break;
|
||||
case (int)RoleExpression.ROLEEXP_SALUTE: iAction = (int)PLAYER_ACTION_TYPE.ACT_EXP_SALUTE; break;
|
||||
|
||||
case (int)RoleExpression.ROLEEXP_SITDOWN:
|
||||
|
||||
iAction = (int)PLAYER_ACTION_TYPE.ACT_EXP_SITDOWN;
|
||||
bSession = true;
|
||||
break;
|
||||
|
||||
case (int)RoleExpression.ROLEEXP_ASSAULT: iAction = (int)PLAYER_ACTION_TYPE.ACT_EXP_ASSAULT; break;
|
||||
case (int)RoleExpression.ROLEEXP_THINK: iAction = (int)PLAYER_ACTION_TYPE.ACT_EXP_THINK; break;
|
||||
case (int)RoleExpression.ROLEEXP_DEFIANCE: iAction = (int)PLAYER_ACTION_TYPE.ACT_EXP_DEFIANCE; break;
|
||||
case (int)RoleExpression.ROLEEXP_VICTORY: iAction = (int)PLAYER_ACTION_TYPE.ACT_EXP_VICTORY; break;
|
||||
case (int)RoleExpression.ROLEEXP_GAPE: iAction = (int)PLAYER_ACTION_TYPE.ACT_GAPE; break;
|
||||
case (int)RoleExpression.ROLEEXP_KISS: iAction = (int)PLAYER_ACTION_TYPE.ACT_EXP_KISS; break;
|
||||
case (int)RoleExpression.ROLEEXP_FIGHT: iAction = (int)PLAYER_ACTION_TYPE.ACT_EXP_FIGHT; break;
|
||||
case (int)RoleExpression.ROLEEXP_ATTACK1: iAction = (int)PLAYER_ACTION_TYPE.ACT_EXP_ATTACK1; break;
|
||||
case (int)RoleExpression.ROLEEXP_ATTACK2: iAction = (int)PLAYER_ACTION_TYPE.ACT_EXP_ATTACK2; break;
|
||||
case (int)RoleExpression.ROLEEXP_ATTACK3: iAction = (int)PLAYER_ACTION_TYPE.ACT_EXP_ATTACK3; break;
|
||||
case (int)RoleExpression.ROLEEXP_ATTACK4: iAction = (int)PLAYER_ACTION_TYPE.ACT_EXP_ATTACK4; break;
|
||||
case (int)RoleExpression.ROLEEXP_DEFENCE: iAction = (int)PLAYER_ACTION_TYPE.ACT_EXP_DEFENCE; break;
|
||||
case (int)RoleExpression.ROLEEXP_FALL: iAction = (int)PLAYER_ACTION_TYPE.ACT_EXP_FALL; break;
|
||||
case (int)RoleExpression.ROLEEXP_FALLONGROUND:
|
||||
iAction = (int)PLAYER_ACTION_TYPE.ACT_EXP_FALLONGROUND; break;
|
||||
case (int)RoleExpression.ROLEEXP_LOOKAROUND:
|
||||
iAction = (int)PLAYER_ACTION_TYPE.ACT_EXP_LOOKAROUND; break;
|
||||
case (int)RoleExpression.ROLEEXP_DANCE: iAction = (int)PLAYER_ACTION_TYPE.ACT_EXP_DANCE; break;
|
||||
case (int)RoleExpression.ROLEEXP_FASHIONWEAPON:
|
||||
iAction = (int)PLAYER_ACTION_TYPE.ACT_EXP_FASHIONWEAPON; break;
|
||||
case (int)RoleExpression.ROLEEXP_TWO_KISS: iAction = (int)PLAYER_ACTION_TYPE.ACT_TWO_KISS; break;
|
||||
case (int)RoleExpression.ROLEEXP_FIREWORK: iAction = (int)PLAYER_ACTION_TYPE.ACT_ATTACK_TOSS; break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
pWork.SetPoseAction(iAction, bSession);
|
||||
|
||||
return true;
|
||||
}
|
||||
void OnMsgPlayerGather(ECMSG Msg)
|
||||
{
|
||||
int cmd = Convert.ToInt32(Msg.dwParam2);
|
||||
if (cmd == CommandID.PLAYER_GATHER_START)
|
||||
{
|
||||
cmd_player_gather_start pCmd = GPDataTypeHelper.FromBytes<cmd_player_gather_start>((byte[])Msg.dwParam1);
|
||||
|
||||
EC_ManMatter pMatterMan = EC_ManMessageMono.Instance.GetECManMatter;//g_pGame.GetGameRun().GetWorld().GetMatterMan();
|
||||
CECMatter pMatter = pMatterMan.GetMatter(pCmd.mid);
|
||||
// if (pMatter && pMatter.IsMonsterSpiritMine()) {
|
||||
// CECHPWorkUse* pWork = (CECHPWorkUse*)m_pWorkMan.CreateWork(CECHPWork::WORK_USEITEM);
|
||||
// if (pWork) {
|
||||
// pWork.SetParams(pCmd.mid, pCmd.use_time * 1000, pCmd.mid, true);
|
||||
// m_pWorkMan.StartWork_p1(pWork);
|
||||
// }
|
||||
// StartMonsterSpiritConnectGfx(pCmd.mid, pMatter.GetPos());
|
||||
// } else {
|
||||
EC_HPWorkPick pWork = (EC_HPWorkPick)m_pWorkMan.CreateWork(Host_work_ID.WORK_PICKUP);
|
||||
if (pWork != null)
|
||||
{
|
||||
pWork.SetGather(true, pMatter ? pMatter.GetTemplateID() : 0);
|
||||
m_pWorkMan.StartWork_p1(pWork);
|
||||
}
|
||||
// }
|
||||
|
||||
// Start time counter
|
||||
m_GatherCnt.SetPeriod(pCmd.use_time * 1000);
|
||||
m_GatherCnt.Reset();
|
||||
}
|
||||
else if (cmd == CommandID.PLAYER_GATHER_STOP)
|
||||
{
|
||||
cmd_player_gather_stop pCmd = GPDataTypeHelper.FromBytes<cmd_player_gather_stop>((byte[])Msg.dwParam1);
|
||||
m_pWorkMan.FinishRunningWork(Host_work_ID.WORK_PICKUP);
|
||||
m_pWorkMan.FinishRunningWork(Host_work_ID.WORK_USEITEM);
|
||||
// StopMonsterSpiritConnectGfx();
|
||||
var pDlg = EC_Game.GetGameRun().GetUIManager().GetInGameUIMan().GetDialog("Win_Prgs2");
|
||||
if (pDlg == null)
|
||||
{
|
||||
BMLogger.LogError("Null Win_Prgs2");
|
||||
return;
|
||||
}
|
||||
|
||||
if (pDlg is not DlgWinPrgs2 dlgWinPrgs)
|
||||
{
|
||||
BMLogger.LogError("Can not cast Win_Prgs2");
|
||||
return;
|
||||
}
|
||||
dlgWinPrgs.SetActiveProgress(false);
|
||||
}
|
||||
else if (cmd == CommandID.MINE_GATHERED)
|
||||
{
|
||||
cmd_mine_gathered pCmd = GPDataTypeHelper.FromBytes<cmd_mine_gathered>((byte[])Msg.dwParam1);
|
||||
// ASSERT(pCmd && pCmd.player_id == m_PlayerInfo.cid);
|
||||
elementdataman pDataMan = EC_Game.GetElementDataMan();
|
||||
DATA_TYPE DataType = pDataMan.get_data_type((uint)pCmd.item_type, ID_SPACE.ID_SPACE_ESSENCE);
|
||||
if (DataType == DATA_TYPE.DT_MONSTER_SPIRIT_ESSENCE)
|
||||
{
|
||||
// StartMonsterSpiritBallGfx();
|
||||
// m_CardHolder.gain_times++;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Is doing session pose ?
|
||||
private bool DoingSessionPose()
|
||||
{
|
||||
var pCurWork = m_pWorkMan.GetRunningWork(Host_work_ID.WORK_STAND);
|
||||
if (pCurWork != null)
|
||||
{
|
||||
if (((CECHPWorkStand)pCurWork).DoingSessionPose())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e28dd00d9a790bb4eb9e05f52c4e6aba
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9c5087cf8a535ec4db0686ae8fba0ecf
|
||||
@@ -0,0 +1,69 @@
|
||||
using BrewMonster.Managers;
|
||||
using BrewMonster.Network;
|
||||
using CSNetwork;
|
||||
using CSNetwork.GPDataType;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace BrewMonster
|
||||
{
|
||||
public partial class CECHostPlayer
|
||||
{
|
||||
private void OnMsgHstJoinTeam(ECMSG Msg)
|
||||
{
|
||||
var data = (byte[])Msg.dwParam1;
|
||||
if (data == null || data.Length < Marshal.SizeOf<cmd_team_join_team>()) return;
|
||||
var pCmd = GPDataTypeHelper.FromBytes<cmd_team_join_team>(data);
|
||||
var pTeamMan = CECGameRun.Instance?.GetTeamMan();
|
||||
if (pTeamMan == null) return;
|
||||
var pTeam = pTeamMan.GetTeam(pCmd.idLeader);
|
||||
if (pTeam == null)
|
||||
pTeam = pTeamMan.CreateTeam(pCmd.idLeader);
|
||||
if (pTeam == null) return;
|
||||
if (pCmd.idLeader == m_PlayerInfo.cid)
|
||||
pTeam.AddMember(pCmd.idLeader);
|
||||
pTeam.SetPickupFlag(pCmd.wPickFlag);
|
||||
SetTeam(pTeam);
|
||||
NotifyUIUpdateTeam();
|
||||
}
|
||||
|
||||
private void OnMsgHstLeaveTeam(ECMSG Msg)
|
||||
{
|
||||
var data = (byte[])Msg.dwParam1;
|
||||
if (data == null || data.Length < Marshal.SizeOf<cmd_team_leave_party>()) return;
|
||||
var pCmd = GPDataTypeHelper.FromBytes<cmd_team_leave_party>(data);
|
||||
if (m_pTeam == null) return;
|
||||
var pTeamMan = CECGameRun.Instance?.GetTeamMan();
|
||||
if (pTeamMan != null)
|
||||
pTeamMan.ReleaseTeam(pCmd.idLeader);
|
||||
SetTeam(null);
|
||||
NotifyUIUpdateTeam();
|
||||
}
|
||||
|
||||
private void OnMsgHstNewTeamMem(ECMSG Msg)
|
||||
{
|
||||
var data = (byte[])Msg.dwParam1;
|
||||
if (data == null || data.Length < Marshal.SizeOf<cmd_team_new_member>()) return;
|
||||
var pCmd = GPDataTypeHelper.FromBytes<cmd_team_new_member>(data);
|
||||
if (m_pTeam == null) return;
|
||||
int cid = pCmd.idMember;
|
||||
m_pTeam.AddMember(cid);
|
||||
m_pTeam.AddUnknownID(cid);
|
||||
if (EC_ManMessageMono.Instance?.GetECManPlayer?.GetPlayer(cid, 0) == null && UnityGameSession.Instance != null)
|
||||
UnityGameSession.c2s_CmdTeamMemberPos(1, new[] { cid });
|
||||
NotifyUIUpdateTeam();
|
||||
}
|
||||
private void OnMsgHstTeamMemberData(ECMSG Msg)
|
||||
{
|
||||
var data = (byte[])Msg.dwParam1;
|
||||
if (data == null) return;
|
||||
try
|
||||
{
|
||||
var (header, members) = GPDataTypeHelper.ParseTeamMemberData(data);
|
||||
if (m_pTeam == null || header.idLeader != m_pTeam.GetLeaderID()) return;
|
||||
m_pTeam.UpdateTeamData(header, members);
|
||||
NotifyUIUpdateTeam();
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2c86a928789ee0f47861a6e0948ad971
|
||||
@@ -0,0 +1,170 @@
|
||||
using BrewMonster.Network;
|
||||
using BrewMonster.Scripts;
|
||||
using BrewMonster.Scripts.Pet;
|
||||
using BrewMonster.UI;
|
||||
using CSNetwork;
|
||||
using CSNetwork.GPDataType;
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using BrewMonster.Assets.PerfectWorld.Scripts.Players;
|
||||
using UnityEngine;
|
||||
using static BrewMonster.Scripts.Pet.CECPetData;
|
||||
|
||||
namespace BrewMonster
|
||||
{
|
||||
public partial class CECHostPlayer
|
||||
{
|
||||
private void OnMsgPlayerFly(ECMSG Msg)
|
||||
{
|
||||
if (Convert.ToInt32(Msg.dwParam2) == CommandID.OBJECT_TAKEOFF)
|
||||
{
|
||||
if ((m_dwStates & PlayerNPCState.GP_STATE_FLY) == 0)
|
||||
{
|
||||
m_dwStates |= PlayerNPCState.GP_STATE_FLY;
|
||||
m_bRushFly = false;
|
||||
|
||||
CECHPWorkFly pWork = (CECHPWorkFly)m_pWorkMan.CreateWork(CECHPWork.Host_work_ID.WORK_FLYOFF);
|
||||
if (m_pWorkMan.IsFreeFalling())
|
||||
{
|
||||
pWork.m_bContinueFly = true;
|
||||
m_pWorkMan.StartWork_p1(pWork);
|
||||
}
|
||||
else
|
||||
{
|
||||
pWork.m_bContinueFly = false;
|
||||
m_pWorkMan.StartWork_p2(pWork);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (Convert.ToInt32(Msg.dwParam2) == CommandID.OBJECT_LANDING)
|
||||
{
|
||||
if ((m_dwStates & PlayerNPCState.GP_STATE_FLY) != 0)
|
||||
{
|
||||
m_dwStates &= ~(uint)PlayerNPCState.GP_STATE_FLY;
|
||||
|
||||
if (IsDead() || m_bCandHangerOn || IsHangerOn())
|
||||
ShowWing(false);
|
||||
else
|
||||
{
|
||||
CECHPWorkFall pWork =
|
||||
(CECHPWorkFall)m_pWorkMan.CreateWork(CECHPWork.Host_work_ID.WORK_FREEFALL);
|
||||
pWork.SetFallType(CECHPWorkFall.Fall_type.TYPE_FLYFALL);
|
||||
m_pWorkMan.StartWork_p1(pWork);
|
||||
}
|
||||
|
||||
// Below two lines will fix the "host stand in air" bug.
|
||||
m_iMoveEnv = Move_environment.MOVEENV_GROUND;
|
||||
m_CDRInfo.vTPNormal.Clear();
|
||||
}
|
||||
}
|
||||
else // HOST_RUSH_FLY
|
||||
{
|
||||
cmd_host_rush_fly pCmd = GPDataTypeHelper.FromBytes<cmd_host_rush_fly>((byte[])Msg.dwParam1);
|
||||
m_bRushFly = pCmd.is_active != 0 ? true : false;
|
||||
}
|
||||
}
|
||||
|
||||
/* Is host operating pet ?
|
||||
return value:
|
||||
|
||||
0: host doesn't operating pet.
|
||||
1: host is summoning pet.
|
||||
2: host is recalling pet.
|
||||
3: host is banishing pet.
|
||||
*/
|
||||
public int IsOperatingPet()
|
||||
{
|
||||
if (m_pWorkMan == null)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
CECHPWorkConcentrate pWork = (m_pWorkMan.GetRunningWork(CECHPWork.Host_work_ID.WORK_CONCENTRATE)) as CECHPWorkConcentrate;
|
||||
if (pWork != null)
|
||||
{
|
||||
if (pWork.GetDoWhat() == (int)CECHPWorkConcentrate.eDO_PET.DO_SUMMONPET)
|
||||
return 1;
|
||||
else if (pWork.GetDoWhat() == (int)CECHPWorkConcentrate.eDO_PET.DO_RECALLPET)
|
||||
return 2;
|
||||
else if (pWork.GetDoWhat() == (int)CECHPWorkConcentrate.eDO_PET.DO_BANISHPET)
|
||||
return 3;
|
||||
else if (pWork.GetDoWhat() == (int)CECHPWorkConcentrate.eDO_PET.DO_RESTOREPET)
|
||||
return 4;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Summon pet
|
||||
public bool SummonPet(int iPetIdx)
|
||||
{
|
||||
if (m_pActionSwitcher != null)
|
||||
m_pActionSwitcher.PostMessge((int)EMsgActionSwitcher.MSG_MOUNTPET);
|
||||
|
||||
CECGameRun pGameRun = EC_Game.GetGameRun();
|
||||
CECUIManager pGameUI = pGameRun.GetUIManager();
|
||||
|
||||
CECPetData pPet = m_pPetCorral.GetPetData(iPetIdx);
|
||||
if (pPet == null)
|
||||
return false;
|
||||
|
||||
if (!CanDo(ActionCanDo.CANDO_SUMMONPET))
|
||||
return false;
|
||||
|
||||
// Couldn't summon daed pet
|
||||
if (pPet.IsDead())
|
||||
{
|
||||
//pGameRun.AddFixedMessage(FIXMSG_PET_DEAD);
|
||||
//Debug.LogError("FIXMSG_PET_DEAD");
|
||||
pGameUI.ShowMessageBox("MessageBox", "PET_DEAD", MessageBoxType.YesButton);
|
||||
return false;
|
||||
}
|
||||
|
||||
// If host could't stop naturally, cancel summoning
|
||||
if (!NaturallyStopMoving())
|
||||
return false;
|
||||
|
||||
// ¼ì²éµ±Ç°ÊÇ·ñ½ûÖ¹ÕÙ»½Æï³è
|
||||
if (pPet.IsMountPet() && m_playerLimits[(int)PLAYER_LIMIT.PLAYER_LIMIT_NOMOUNT])
|
||||
return false;
|
||||
|
||||
if (m_ReincarnationCount != 0)
|
||||
{
|
||||
int iLevelRequired = pPet.GetLevel() - 35 - m_ReincarnationCount * 5;
|
||||
if (m_BasicProps.iLevel < iLevelRequired)
|
||||
{
|
||||
if (pGameUI != null)
|
||||
{
|
||||
string strText = "";
|
||||
strText = string.Format(pGameUI.GetInGameUIMan().GetStringFromTable(10787), iLevelRequired);
|
||||
pGameUI.ShowMessageBox("MessageBox", strText, MessageBoxType.YesButton);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
UnityGameSession.c2s_CmdPetSummon(iPetIdx);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Recall pet
|
||||
public bool RecallPet()
|
||||
{
|
||||
if (m_pActionSwitcher != null)
|
||||
m_pActionSwitcher.PostMessge((int)EMsgActionSwitcher.MSG_MOUNTPET);
|
||||
|
||||
// If host could't stop naturally, cancel recalling
|
||||
if (!NaturallyStopMoving())
|
||||
return false;
|
||||
|
||||
UnityGameSession.c2s_CmdPetRecall();
|
||||
return true;
|
||||
}
|
||||
|
||||
// Get pet operation time counter
|
||||
public CECCounter GetPetOptTime() { return m_PetOptCnt; }
|
||||
public CECPetCorral GetPetCorral()
|
||||
{
|
||||
return m_pPetCorral;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 199b19ff05aa30049aca1caf465398f0
|
||||
@@ -0,0 +1,79 @@
|
||||
using CSNetwork;
|
||||
using CSNetwork.GPDataType;
|
||||
|
||||
namespace BrewMonster
|
||||
{
|
||||
public partial class CECHostPlayer
|
||||
{
|
||||
void OnMsgHstExtProp(ECMSG Msg)
|
||||
{
|
||||
cmd_own_ext_prop pCmd = GPDataTypeHelper.FromBytes<cmd_own_ext_prop>((byte[])Msg.dwParam1);
|
||||
m_ExtProps = pCmd.prop;
|
||||
m_BasicProps.iStatusPt = (int)pCmd.status_point;
|
||||
m_BasicProps.iAtkDegree = pCmd.attack_degree;
|
||||
m_BasicProps.iDefDegree = pCmd.defend_degree;
|
||||
m_BasicProps.iCritRate = pCmd.crit_rate;
|
||||
m_BasicProps.iCritDamageBonus = pCmd.crit_damage_bonus;
|
||||
m_BasicProps.iInvisibleDegree = pCmd.invisible_degree;
|
||||
m_BasicProps.iAntiInvisibleDegree = pCmd.anti_invisible_degree;
|
||||
m_BasicProps.iPenetration = pCmd.penetration;
|
||||
m_BasicProps.iResilience = pCmd.resilience;
|
||||
m_BasicProps.iVigour = pCmd.vigour;
|
||||
}
|
||||
|
||||
private void OnMsgHstInfo00(in ECMSG Msg)
|
||||
{
|
||||
cmd_self_info_00 pCmd = GPDataTypeHelper.FromBytes<cmd_self_info_00>((byte[])Msg.dwParam1);
|
||||
|
||||
bool bFirstTime = m_BasicProps.iLevel == 0 ? true : false;
|
||||
if (!bFirstTime)
|
||||
{
|
||||
int iLimit = (int)(pCmd.iMaxHP * 0.3f);
|
||||
if (pCmd.iHP < m_BasicProps.iCurHP && m_BasicProps.iCurHP >= iLimit && pCmd.iHP < iLimit)
|
||||
{
|
||||
/*if (CECUIHelper::GetGameUIMan().IsShowLowHP()) {
|
||||
// ѪÁ¿µÍÓÚÁÙ½çÖµÔò²¥·ÅÌØÐ§
|
||||
const int GfxLastTime = 10000; // ³ÖÐøÊ±¼ä10Ãë
|
||||
CECUIHelper::GetGameUIMan().GetScreenEffectMan().StartEffect(CECScreenEffect::EFFECT_REDSPARK, GfxLastTime);
|
||||
}*/
|
||||
}
|
||||
|
||||
/*if (pCmd.iHP >= iLimit || pCmd.iHP <= 0) {
|
||||
// ѪÁ¿¸ßÓÚÁÙ½çÖµ»òËÀÍö£¬ÔòÍ£Ö¹²¥·ÅÌØÐ§
|
||||
CECUIHelper::GetGameUIMan().GetScreenEffectMan().FinishEffect(CECScreenEffect::EFFECT_REDSPARK);
|
||||
}*/
|
||||
|
||||
/*iLimit = (int)(pCmd.iMaxMP * 0.2f);
|
||||
if (pCmd.iMP < m_BasicProps.iCurMP && m_BasicProps.iCurMP >= iLimit && pCmd.iMP < iLimit)
|
||||
BubbleText(BUBBLE_MPWARN, 0);*/
|
||||
|
||||
/*if (m_ExtProps.max_ap != pCmd.iMaxAP)
|
||||
g_pGame.GetGameRun().AddFixedMessage(FIXMSG_ADDMAXAP, pCmd.iMaxAP - m_ExtProps.max_ap);*/
|
||||
}
|
||||
|
||||
m_BasicProps.iLevel = pCmd.sLevel;
|
||||
SetLevel2(pCmd.Level2, bFirstTime);
|
||||
m_BasicProps.iExp = pCmd.iExp;
|
||||
m_BasicProps.iSP = pCmd.iSP;
|
||||
m_BasicProps.iCurHP = pCmd.iHP;
|
||||
m_BasicProps.iCurMP = pCmd.iMP;
|
||||
m_BasicProps.iCurAP = pCmd.iAP;
|
||||
m_ExtProps.bs.max_hp = pCmd.iMaxHP;
|
||||
m_ExtProps.bs.max_mp = pCmd.iMaxMP;
|
||||
m_ExtProps.max_ap = pCmd.iMaxAP;
|
||||
|
||||
EventBus.Publish(new EXPToUpLevel(GetLevelUpExp(pCmd.sLevel)));
|
||||
EventBus.Publish<cmd_self_info_00>(pCmd);
|
||||
EventBus.PublishChannel<cmd_self_info_00>(GetCharacterID(), pCmd);
|
||||
// if (pCmd.State != 0 && m_bFight == false) PlayEnterBattleGfx();
|
||||
m_bFight = pCmd.State != 0 ? true : false;
|
||||
|
||||
// UpdateGodEvilSprite();
|
||||
|
||||
/*CECGameUIMan* pGameUI = g_pGame.GetGameRun().GetUIManager().GetInGameUIMan();
|
||||
CDlgAutoHelp *pDlgHelp = dynamic_cast<CDlgAutoHelp *>(pGameUI.GetDialog("Win_WikiPop"));*/
|
||||
/*if(pDlgHelp && m_bFight)
|
||||
pDlgHelp.SetAutoHelpState(false);*/
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a19218082b79eef4687286340cd52157
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c8ab82b5b1e1aee45a936ba119de3444
|
||||
@@ -0,0 +1,263 @@
|
||||
using BrewMonster.Network;
|
||||
using BrewMonster.Scripts;
|
||||
using CSNetwork;
|
||||
using CSNetwork.GPDataType;
|
||||
using System.Runtime.InteropServices;
|
||||
using Cysharp.Threading.Tasks;
|
||||
using UnityEngine;
|
||||
using static BrewMonster.Scripts.CECHPWork;
|
||||
|
||||
namespace BrewMonster
|
||||
{
|
||||
public partial class CECHostPlayer
|
||||
{
|
||||
public void OnMsgHstCorrectPos(in ECMSG Msg)
|
||||
{
|
||||
//Debug.LogError("HoangDev : OnMsgHstCorrectPos");
|
||||
byte[] buf = (byte[])Msg.dwParam1; // chỗ bạn lưu pDataBuf
|
||||
GCHandle handle = GCHandle.Alloc(buf, GCHandleType.Pinned);
|
||||
cmd_host_correct_pos pCmd = (cmd_host_correct_pos)Marshal.PtrToStructure(
|
||||
handle.AddrOfPinnedObject(), typeof(cmd_host_correct_pos));
|
||||
handle.Free();
|
||||
//cmd_host_correct_pos pCmd = GPDataTypeHelper.FromBytes<cmd_host_correct_pos>((byte[])Msg.dwParam1);
|
||||
Debug.LogError("HoangDev :pCmd.pos " + pCmd.pos);
|
||||
SetPos(pCmd.pos);
|
||||
m_vVelocity.Clear();
|
||||
m_CDRInfo.vAbsVelocity.Clear();
|
||||
|
||||
m_MoveCtrl.SetMoveStamp(pCmd.stamp);
|
||||
}
|
||||
|
||||
public void OnMsgHstGoto(in ECMSG Msg)
|
||||
{
|
||||
PopupManager.Instance.OnPlayerRevived();
|
||||
// p1 is a byte[] buffer; parse into cmd_notify_hostpos then set position
|
||||
// p1 是一个 byte[] 缓冲区;解析为 cmd_notify_hostpos 然后设置位置
|
||||
byte[] buf = (byte[])Msg.dwParam1;
|
||||
cmd_notify_hostpos pCmd = GPDataTypeHelper.FromBytes<cmd_notify_hostpos>(buf);
|
||||
|
||||
int idInst = pCmd.tag;
|
||||
Vector3 vPos = new Vector3(pCmd.vPos.x, pCmd.vPos.y, pCmd.vPos.z);
|
||||
int iLine = pCmd.line;
|
||||
|
||||
|
||||
// Call Goto method to properly handle teleportation
|
||||
// 调用 Goto 方法来正确处理传送
|
||||
if (!Goto(idInst, vPos, iLine))
|
||||
{
|
||||
BMLogger.LogError($"OnMsgHstGoto: Failed to teleport to instance {idInst}");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void OnMsgHstWayPoint(ECMSG Msg)
|
||||
{
|
||||
//CECGameUIMan pGameUI = EC_Game.GetGameRun().GetUIManager().GetInGameUIMan();
|
||||
|
||||
//if (Convert.ToInt32(Msg.dwParam2) == CommandID.ACTIVATE_WAYPOINT)
|
||||
//{
|
||||
// cmd_activate_waypoint pCmd = GPDataTypeHelper.FromBytes<cmd_activate_waypoint>((byte[])Msg.dwParam1);
|
||||
// m_aWayPoints.Add(pCmd.waypoint);
|
||||
|
||||
// // add to waypoints array
|
||||
// pGameUI.GetMapDlgsMgr().UpdateWayPoints(&pCmd.waypoint, 1, false);
|
||||
|
||||
// // Print a notify message
|
||||
// const CECMapDlgsMgr::PointMap& aWayPoints = pGameUI.GetMapDlgsMgr().GetTransPoint();
|
||||
// CECMapDlgsMgr::PointMap::const_iterator itr = aWayPoints.find(pCmd.waypoint);
|
||||
// if(itr != aWayPoints.end())
|
||||
// {
|
||||
// g_pGame.GetGameRun().AddFixedMessage(FIXMSG_NEWWAYPOINT, (itr.second).strName);
|
||||
|
||||
// bool bCanPopUITips = true;
|
||||
// int count = CECUIConfig::Instance().GetGameUI().GetTaskIDDisableWayPointsUITipsCount();
|
||||
// // ¼ì²éÉíÉÏÊÇ·ñÓнûÖ¹µ¯³ötipsµÄÈÎÎñ
|
||||
// for (int i=0;i<count;i++){
|
||||
// int taskID = CECUIConfig::Instance().GetGameUI().GetTaskIDDisableWayPointsUITips(i);
|
||||
// if(GetTaskInterface() && GetTaskInterface().HasTask(taskID)){
|
||||
// bCanPopUITips = false;
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// // µ¯³ötips
|
||||
// CECScriptMan* pScriptMan = g_pGame.GetGameRun().GetUIManager().GetScriptMan();
|
||||
// if (pScriptMan && bCanPopUITips)
|
||||
// {
|
||||
// pScriptMan.GetContext().GetUI().SetTipDialogTitleAndContent(AC2AS_CP(CP_UTF8, pGameUI.GetStringFromTable(11350)), AC2AS_CP(CP_UTF8, (itr.second).strName));
|
||||
// pScriptMan.GetContext().GetUI().ShowTip(500, 500, 5000, 300);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// else if (Msg.dwParam2 == WAYPOINT_LIST)
|
||||
// {
|
||||
// cmd_waypoint_list* pCmd = (cmd_waypoint_list*)Msg.dwParam1;
|
||||
|
||||
// m_aWayPoints.SetSize(pCmd.count, 16);
|
||||
// for (size_t i = 0; i < pCmd.count; i++)
|
||||
// m_aWayPoints[i] = pCmd.list[i];
|
||||
|
||||
// // update the whole list
|
||||
// pGameUI.GetMapDlgsMgr().UpdateWayPoints(pCmd.list, pCmd.count, true);
|
||||
// }
|
||||
}
|
||||
|
||||
private void OnMsgHstPressCancel(ECMSG Msg)
|
||||
{
|
||||
CECHPWork pCurWork = null;
|
||||
pCurWork = m_pWorkMan.GetRunningWork(Host_work_ID.WORK_TRACEOBJECT);
|
||||
if (pCurWork is CECHPWorkTrace workTrace)
|
||||
{
|
||||
workTrace.PressCancel();
|
||||
return;
|
||||
}
|
||||
|
||||
pCurWork = m_pWorkMan.GetRunningWork(Host_work_ID.WORK_HACKOBJECT);
|
||||
if (pCurWork != null)
|
||||
{
|
||||
UnityGameSession.c2s_CmdCancelAction();
|
||||
return;
|
||||
}
|
||||
|
||||
pCurWork = m_pWorkMan.GetRunningWork(Host_work_ID.WORK_USEITEM);
|
||||
if (pCurWork != null)
|
||||
{
|
||||
UnityGameSession.c2s_CmdCancelAction();
|
||||
return;
|
||||
}
|
||||
|
||||
pCurWork = m_pWorkMan.GetRunningWork(Host_work_ID.WORK_SPELLOBJECT);
|
||||
if (pCurWork != null)
|
||||
{
|
||||
int iState = ((CECHPWorkSpell)pCurWork).GetState();
|
||||
if (iState == CECHPWorkSpell.Spell_magic_state.ST_INCANT)
|
||||
{
|
||||
UnityGameSession.c2s_CmdCancelAction();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
pCurWork = m_pWorkMan.GetRunningWork(Host_work_ID.WORK_PICKUP);
|
||||
if (pCurWork != null)
|
||||
{
|
||||
if (((EC_HPWorkPick)pCurWork).IsGather())
|
||||
{
|
||||
UnityGameSession.c2s_CmdCancelAction();
|
||||
return;
|
||||
}
|
||||
}
|
||||
//todo: handle this part
|
||||
// pCurWork = m_pWorkMan.GetRunningWork(Host_work_ID.WORK_CONCENTRATE);
|
||||
// if (pCurWork !=null){
|
||||
// if (IsOperatingPet()){
|
||||
// UnityGameSession.c2s_CmdCancelAction();
|
||||
// return;
|
||||
// }
|
||||
// }
|
||||
// pCurWork = m_pWorkMan.GetRunningWork(Host_work_ID.WORK_CONGREGATE);
|
||||
// if (pCurWork !=null){
|
||||
// if (IsCongregating()){
|
||||
// UnityGameSession.c2s_CmdCancelAction();
|
||||
// return;
|
||||
// }
|
||||
// }
|
||||
|
||||
if (m_bUsingTrashBox || DoingSessionPose())
|
||||
{
|
||||
UnityGameSession.c2s_CmdCancelAction();
|
||||
return;
|
||||
}
|
||||
|
||||
// Cancel current selection
|
||||
if (m_idSelTarget > 0)
|
||||
{
|
||||
SelectTarget(0);
|
||||
return;
|
||||
}
|
||||
|
||||
// Some work have lower priority
|
||||
pCurWork = m_pWorkMan.GetRunningWork(Host_work_ID.WORK_MOVETOPOS);
|
||||
if (pCurWork != null)
|
||||
{
|
||||
((CECHPWorkMove)pCurWork).PressCancel();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
public void StopMovement()
|
||||
{
|
||||
m_MoveCtrl.SendStopMoveCmd(playerTransform.position, 5f, (int)GPMoveMode.GP_MOVE_WALK);
|
||||
}
|
||||
|
||||
// Return to a target town through skill
|
||||
// 通过技能返回目标城镇
|
||||
// This method implements the Goto logic from the original C++ code
|
||||
// 此方法实现了原始 C++ 代码中的 Goto 逻辑
|
||||
private bool Goto(int idInst, Vector3 vPos, int iParallelWorldID)
|
||||
{
|
||||
// Jump to instance (change world/instance)
|
||||
// 跳转到实例(更改世界/实例)
|
||||
// Note: JumpToInstance is currently a stub in CECGameRun, so we skip the call for now
|
||||
// 注意:JumpToInstance 目前在 CECGameRun 中是一个存根,所以我们现在跳过调用
|
||||
// if (CECGameRun.Instance != null && !CECGameRun.Instance.JumpToInstance(idInst, vPos, iParallelWorldID))
|
||||
// {
|
||||
// Debug.LogError($"CECHostPlayer::Goto, Failed to jump to instance {idInst}");
|
||||
// return false;
|
||||
// }
|
||||
|
||||
// Stop all current work and goto specified position
|
||||
// 停止所有当前工作并转到指定位置
|
||||
if (m_pWorkMan != null)
|
||||
{
|
||||
// Stop auto-moving if active
|
||||
// 如果正在自动移动则停止
|
||||
// Note: IsAutoMoving check would go here if available
|
||||
// 注意:如果可用,IsAutoMoving 检查将放在这里
|
||||
|
||||
// Finish all work
|
||||
// 完成所有工作
|
||||
m_pWorkMan.FinishAllWork(true);
|
||||
}
|
||||
|
||||
// Add a little height to ensure player's AABB won't embed with building
|
||||
// 增加一点高度以确保玩家的 AABB 不会嵌入建筑物
|
||||
vPos.y += 0.1f;
|
||||
|
||||
// Ensure we are not under ground (terrain height check would go here)
|
||||
// 确保我们不会在地下(地形高度检查将放在这里)
|
||||
// Note: Terrain height check is skipped for now as it requires world access
|
||||
// 注意:暂时跳过地形高度检查,因为它需要世界访问
|
||||
|
||||
// Set position
|
||||
// 设置位置
|
||||
SetPos(vPos);
|
||||
|
||||
// Reset jump state if available
|
||||
// 如果可用则重置跳跃状态
|
||||
// ResetJump(); // Uncomment if ResetJump method exists
|
||||
|
||||
// Update camera if available
|
||||
// 如果可用则更新相机
|
||||
// UpdateFollowCamera(false, 10); // Uncomment if UpdateFollowCamera method exists
|
||||
|
||||
LitModelHolder.Instance.LoadAllObjectsNearTargetPosition(vPos).Forget();
|
||||
return true;
|
||||
}
|
||||
|
||||
public void SetStatusRun(bool value)
|
||||
{
|
||||
if (!isGrounded)
|
||||
{
|
||||
Debug.LogError("Player not in ground");
|
||||
return;
|
||||
}
|
||||
|
||||
isRun = value;
|
||||
}
|
||||
|
||||
public bool IsPlayerMoving()
|
||||
{
|
||||
return m_pWorkMan.IsMoving();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 570900be694cc7c4c9c0fc5c399c9a25
|
||||
+123
-4826
File diff suppressed because it is too large
Load Diff
@@ -22,6 +22,7 @@ public class CECUIManager : MonoSingleton<CECUIManager>
|
||||
[SerializeField] private int currentTargetNPCID;
|
||||
CECGameUIMan gameUI;
|
||||
AUIManager aUIManager;
|
||||
AUIDialog _dlgPlayerOptions;
|
||||
[SerializeField] private DialogScriptTableObject dialogResouce;
|
||||
[SerializeField] private Canvas canvasDlg;
|
||||
|
||||
@@ -33,11 +34,16 @@ public class CECUIManager : MonoSingleton<CECUIManager>
|
||||
Sprite[] m_iconlistIvtr;
|
||||
private CDlgInfoTooltip m_pDlgSkillTooltip;
|
||||
|
||||
// Task update timer / 任务更新计时器
|
||||
private float _nextTaskUpdateTime = 0f;
|
||||
private const float TASK_UPDATE_INTERVAL = .1f;
|
||||
|
||||
protected override void Awake()
|
||||
{
|
||||
base.Awake();
|
||||
|
||||
EventBus.Subscribe<CECHostPlayer.NPCINFO>(ShowUINPC);
|
||||
EventBus.Subscribe<CECHostPlayer.TargetHUDClearEvent>(OnTargetHUDClear);
|
||||
EventBus.Subscribe<NPCDiedEvent>(TryHideUINPC);
|
||||
EventBus.Subscribe<MessageBoxEvent>(OnMessageBox);
|
||||
|
||||
@@ -58,22 +64,69 @@ public class CECUIManager : MonoSingleton<CECUIManager>
|
||||
// _fpsText.text = $"{Mathf.RoundToInt(1f / Time.deltaTime)}";
|
||||
if (m_pDlgQuickBar1 != null)
|
||||
{ m_pDlgQuickBar1.UpdateShortcuts(); }
|
||||
|
||||
// Periodically update task UI (DlgTask and DlgTaskTrace) / 定期更新任务UI(DlgTask和DlgTaskTrace)
|
||||
if (Time.unscaledTime >= _nextTaskUpdateTime)
|
||||
{
|
||||
_nextTaskUpdateTime = Time.unscaledTime + TASK_UPDATE_INTERVAL;
|
||||
UpdateTaskUI();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Update task UI from DlgTask and DlgTaskTrace / 从DlgTask和DlgTaskTrace更新任务UI
|
||||
/// </summary>
|
||||
private void UpdateTaskUI()
|
||||
{
|
||||
try
|
||||
{
|
||||
var inGameUIMan = GetInGameUIMan();
|
||||
if (inGameUIMan == null) return;
|
||||
|
||||
var dlgTaskDialog = inGameUIMan.GetDialog("Win_Quest");
|
||||
var dlgTaskTraceDialog = inGameUIMan.GetDialog("Win_QuestMinion");
|
||||
if (dlgTaskDialog != null && dlgTaskDialog is BrewMonster.Scripts.Task.UI.DlgTask dlgTaskForTrace)
|
||||
{
|
||||
if (dlgTaskTraceDialog != null && dlgTaskTraceDialog.IsShow())
|
||||
{
|
||||
dlgTaskForTrace.RefreshTaskTrace();
|
||||
}
|
||||
dlgTaskForTrace.Tick();
|
||||
}
|
||||
|
||||
}
|
||||
catch (System.Exception)
|
||||
{
|
||||
// Silently handle errors to avoid spamming logs / 静默处理错误以避免日志刷屏
|
||||
// Task UI update errors are handled silently / 任务UI更新错误被静默处理
|
||||
}
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
EventBus.Unsubscribe<CECHostPlayer.NPCINFO>(ShowUINPC);
|
||||
EventBus.Unsubscribe<CECHostPlayer.TargetHUDClearEvent>(OnTargetHUDClear);
|
||||
EventBus.Unsubscribe<NPCDiedEvent>(TryHideUINPC);
|
||||
EventBus.Unsubscribe<MessageBoxEvent>(OnMessageBox);
|
||||
}
|
||||
|
||||
private void ShowUINPC(CECHostPlayer.NPCINFO obj)
|
||||
{
|
||||
var host = EC_Game.GetGameRun()?.GetHostPlayer();
|
||||
if (host != null && host.GetSelectedTarget() != obj.IDNPC)
|
||||
return;
|
||||
npsUI.gameObject.SetActive(true);
|
||||
npsUI.SetText($"{obj.CurrentHealth}/{obj.MaxHealth}", obj.Name, "");
|
||||
npsUI.SetHealthImage((float)obj.CurrentHealth / (float)obj.MaxHealth);
|
||||
string hpText = obj.MaxHealth > 0 ? $"{obj.CurrentHealth}/{obj.MaxHealth}" : "-/-";
|
||||
npsUI.SetText(hpText, obj.Name ?? "", "");
|
||||
float fill = obj.MaxHealth > 0 ? (float)obj.CurrentHealth / (float)obj.MaxHealth : 1f;
|
||||
npsUI.SetHealthImage(fill);
|
||||
currentTargetNPCID = obj.IDNPC;
|
||||
}
|
||||
|
||||
private void OnTargetHUDClear(CECHostPlayer.TargetHUDClearEvent _)
|
||||
{
|
||||
npsUI.gameObject.SetActive(false);
|
||||
}
|
||||
public CDlgQuickBar GetCDlgQuickBar()
|
||||
{
|
||||
return m_pDlgQuickBar1;
|
||||
@@ -108,17 +161,12 @@ public class CECUIManager : MonoSingleton<CECUIManager>
|
||||
|
||||
Debug.LogWarning($"Không tìm thấy UI {componentName} đã spawn trong canvasDlg. Type found: {(type != null ? type.FullName : "null")}");
|
||||
}
|
||||
public CDlgMessageBox ShowMessageBox(string title, string message)
|
||||
public CDlgMessageBox ShowMessageBox(MessageBoxData messageBoxData)
|
||||
{
|
||||
var msgBox = GetInGameUIMan().GetDialog("DlgMessageBox") as CDlgMessageBox;
|
||||
if (msgBox != null)
|
||||
{
|
||||
msgBox.ShowMessageBox(new MessageBoxData()
|
||||
{
|
||||
Title = title,
|
||||
Message = message,
|
||||
MessageBoxType = MessageBoxType.YesButton
|
||||
});
|
||||
msgBox.ShowMessageBox(messageBoxData);
|
||||
return msgBox;
|
||||
}
|
||||
else
|
||||
@@ -261,24 +309,19 @@ public class CECUIManager : MonoSingleton<CECUIManager>
|
||||
}
|
||||
|
||||
}
|
||||
else if(string.CompareOrdinal("Game_Disenchase",pDlg.GetName())==0 && DialogBoxCommandIDs.IDOK == iRetVal)
|
||||
{
|
||||
// PAUIDIALOG pMsgBox;
|
||||
var clearEmbeddedChipDlg = GetInGameUIMan().GetDialog("Game_Disenchase");
|
||||
// EC_IvtrItem pIvtr = (EC_IvtrItem)m_pDlgUninstall->m_pItema->GetDataPtr("ptr_CECIvtrItem");
|
||||
//
|
||||
// pSession.c2s_CmdNPCSevClearEmbeddedChip(
|
||||
// (WORD)m_pDlgUninstall->m_pItema->GetData(), pIvtr->GetTemplateID());
|
||||
//
|
||||
// m_pDlgUninstall->Show(false);
|
||||
// pHost->EndNPCService();
|
||||
else if (pDlg is DlgInstall dlgInstall && dlgInstall.GetInstallMode == DlgInstall.InstallMode.Disenchase && DialogBoxCommandIDs.IDOK == iRetVal)
|
||||
{
|
||||
UnityGameSession.c2s_CmdNPCSevClearEmbeddedChip(dlgInstall.FirstSlotIndex, dlgInstall.SelectedEquip.GetTemplateID());
|
||||
|
||||
dlgInstall.Show(false);
|
||||
pHost.EndNPCService();
|
||||
// m_pCurNPCEssence = NULL;
|
||||
// m_pDlgInventory->Show(false);
|
||||
// pHost->GetPack(IVTRTYPE_PACK)->UnfreezeAllItems();
|
||||
//
|
||||
// MessageBox("", GetStringFromTable(228), MB_OK,
|
||||
// A3DCOLORRGBA(255, 255, 255, 160), &pMsgBox);
|
||||
// pMsgBox->SetLife(3);
|
||||
pHost.GetPack((int)InventoryType.IVTRTYPE_PACK).UnfreezeAllItems();
|
||||
ShowMessageBox(new MessageBoxData()
|
||||
{
|
||||
Message = pDlg.GetStringFromTable(228)
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -418,6 +461,16 @@ public class CECUIManager : MonoSingleton<CECUIManager>
|
||||
return gameUI;
|
||||
}
|
||||
|
||||
/// <summary>Shows the player options menu for the given character. Requires a prefab with id "DlgPlayerOptions" in DialogScriptTableObject.</summary>
|
||||
public void ShowPlayerOptionsDialog(int characterId)
|
||||
{
|
||||
if (characterId == 0 || canvasDlg == null) return;
|
||||
var gui = GetInGameUIMan();
|
||||
if (_dlgPlayerOptions == null)
|
||||
_dlgPlayerOptions = gui.GetDialog("DlgPlayerOptions");
|
||||
_dlgPlayerOptions?.ShowForPlayer(characterId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the current target NPC ID (same as stored from NPCINFO event)
|
||||
/// </summary>
|
||||
|
||||
Reference in New Issue
Block a user