314 lines
No EOL
9.9 KiB
Lua
314 lines
No EOL
9.9 KiB
Lua
local XRLGuildDormRole = require("XEntity/XGuildDorm/Role/XRLGuildDormRole")
|
||
local XGDMoveComponent = require("XEntity/XGuildDorm/Components/XGDMoveComponent")
|
||
local XGuildDormRoleFSMFactory = require("XEntity/XGuildDorm/Role/FSM/XGuildDormRoleFSMFactory")
|
||
local XGuildDormRole = XClass(nil, "XGuildDormRole")
|
||
|
||
function XGuildDormRole:Ctor(id)
|
||
self.Id = id
|
||
self.PlayerId = nil
|
||
-- 角色表现数据
|
||
self.RLGuildDormRole = nil
|
||
-- 服务器数据
|
||
self.ServerData = nil
|
||
-- 组件 XGDComponet
|
||
self.Componets = nil
|
||
self.ComponetDic = nil
|
||
-- 行为代理
|
||
self.Agent = nil
|
||
-- 移动代理
|
||
self.MoveAgent = nil
|
||
-- 状态机 XHomeCharFSM
|
||
self.StateMachine = nil
|
||
-- 当前交互状态
|
||
self.InteractStatus = XGuildDormConfig.InteractStatus.End
|
||
-- 当前交互信息
|
||
self.CurrentInteractInfo = nil
|
||
self.PlayActionId = -1
|
||
self.SyncState = XGuildDormConfig.SyncState.None
|
||
-- 上一次结束交互的时间
|
||
self.LastEndInteractTime = 0
|
||
self:_InitDefaultComponets()
|
||
end
|
||
|
||
function XGuildDormRole:Dispose()
|
||
self.ComponetDic = nil
|
||
self.Componets = nil
|
||
self.Agent = nil
|
||
self.MoveAgent = nil
|
||
self.StateMachine = nil
|
||
self.CurrentInteractInfo = nil
|
||
self.RLGuildDormRole:Dispose()
|
||
end
|
||
|
||
function XGuildDormRole:UpdateWithServerData(data)
|
||
self.ServerData = data
|
||
self.PlayerId = data.PlayerId
|
||
self:GetRLRole():UpdatePlayerId(self.PlayerId)
|
||
end
|
||
|
||
function XGuildDormRole:UpdatePlayActionId(value)
|
||
self.PlayActionId = value
|
||
end
|
||
|
||
function XGuildDormRole:GetPlayActionId()
|
||
return self.PlayActionId
|
||
end
|
||
|
||
function XGuildDormRole:GetIsPlayingAction()
|
||
return self.PlayActionId > 0
|
||
end
|
||
|
||
function XGuildDormRole:UpdateRoleId(roleId)
|
||
if roleId == self.Id then return end
|
||
self.Id = roleId
|
||
self.Agent = nil
|
||
self.MoveAgent = nil
|
||
local rlRole = self:GetRLRole()
|
||
rlRole:UpdateRoleId(roleId)
|
||
-- 更新组件的依赖
|
||
for _, com in ipairs(self.Componets) do
|
||
if com.UpdateRoleDependence then
|
||
com.UpdateRoleDependence(com)
|
||
end
|
||
end
|
||
-- 更新摄像机追随
|
||
if self:CheckIsSelfPlayer() then
|
||
rlRole:UpdateCameraFollow()
|
||
else -- 不是自己玩家要禁用碰撞
|
||
rlRole:DisableColliders()
|
||
end
|
||
rlRole:GetGameObject():LoadPrefab(XGuildDormConfig.GetSwitchRoleEffect())
|
||
end
|
||
|
||
function XGuildDormRole:GetId()
|
||
return self.Id
|
||
end
|
||
|
||
function XGuildDormRole:GetPlayerId()
|
||
return self.PlayerId
|
||
end
|
||
|
||
function XGuildDormRole:GetRLRole()
|
||
if self.RLGuildDormRole == nil then
|
||
self.RLGuildDormRole = XRLGuildDormRole.New(self.Id)
|
||
end
|
||
return self.RLGuildDormRole
|
||
end
|
||
|
||
function XGuildDormRole:GetAgent()
|
||
if self.Agent == nil then
|
||
local gameObject = self:GetRLRole():GetGameObject()
|
||
if XTool.UObjIsNil(gameObject) then return end
|
||
self.Agent = gameObject:GetComponent(typeof(CS.BehaviorTree.XAgent))
|
||
if XTool.UObjIsNil(self.Agent) then
|
||
self.Agent = gameObject:AddComponent(typeof(CS.BehaviorTree.XAgent))
|
||
self.Agent.ProxyType = "XGuildDormCharAgent"
|
||
self.Agent:InitProxy()
|
||
self.Agent.Proxy.LuaAgentProxy:SetRole(self)
|
||
end
|
||
end
|
||
return self.Agent
|
||
end
|
||
|
||
function XGuildDormRole:GetMoveAgent()
|
||
if self.MoveAgent == nil then
|
||
local gameObject = self:GetRLRole():GetGameObject()
|
||
self.MoveAgent = CS.XNavMeshUtility.AddMoveAgent(gameObject)
|
||
self.MoveAgent.Radius = 0.35
|
||
self.MoveAgent.IsObstacle = false
|
||
self.MoveAgent.IsIgnoreCollide = true
|
||
self.MoveAgent.CeilSize = 0.3
|
||
self.MoveAgent.Speed = XGuildDormConfig.GetRoleMoveSpeed()
|
||
end
|
||
return self.MoveAgent
|
||
end
|
||
|
||
function XGuildDormRole:GetCurrentMoveDirection()
|
||
return self:GetComponent("XGDInputCompoent"):GetMoveDirection()
|
||
end
|
||
|
||
function XGuildDormRole:GetCurrentMoveDirectionIsZero()
|
||
local x, y = self:GetCurrentMoveDirection()
|
||
return (x == 0 and y == 0)
|
||
end
|
||
|
||
function XGuildDormRole:GetIsInteracting()
|
||
return self.InteractStatus == XGuildDormConfig.InteractStatus.Begin
|
||
or self.InteractStatus == XGuildDormConfig.InteractStatus.Playing
|
||
end
|
||
|
||
function XGuildDormRole:GetInteractStatus()
|
||
return self.InteractStatus
|
||
end
|
||
|
||
function XGuildDormRole:UpdateInteractStatus(value)
|
||
self.InteractStatus = value
|
||
if value == XGuildDormConfig.InteractStatus.End then
|
||
if self:CheckIsSelfPlayer() then
|
||
local currentRoom = XDataCenter.GuildDormManager.GetCurrentRoom()
|
||
if currentRoom and currentRoom:CheckPlayerIsInteract(self.PlayerId) then
|
||
XDataCenter.GuildDormManager.RequestFurnitureInteract(-1)
|
||
end
|
||
else
|
||
local com = self:GetComponent("XGDSyncToClientComponent")
|
||
if com == nil then return end
|
||
-- 交互结束后自己更新一次,避免因为上次快速插值
|
||
local transform = self:GetRLRole():GetTransform()
|
||
com:UpdateCurrentSyncData(transform.position, transform.rotation
|
||
, XGuildDormConfig.SyncState.None)
|
||
end
|
||
-- 记录上一次交互时间
|
||
self.LastEndInteractTime = XTime.GetServerNowTimestamp()
|
||
XEventManager.DispatchEvent(XEventId.EVENT_GUILD_DORM_ROLE_INTERACT_STOP, self.PlayerId)
|
||
end
|
||
end
|
||
|
||
function XGuildDormRole:GetIsOverLastEndInteractTime()
|
||
return XTime.GetServerNowTimestamp() - self.LastEndInteractTime
|
||
>= XGuildDormConfig.GetInteractIntervalTime()
|
||
end
|
||
|
||
function XGuildDormRole:EnableCharacterController(value)
|
||
if self:GetRLRole():GetCharacterController() == nil then
|
||
return
|
||
end
|
||
self:GetRLRole():GetCharacterController().enabled = value
|
||
end
|
||
|
||
function XGuildDormRole:GetCurrentInteractInfo()
|
||
return self.CurrentInteractInfo
|
||
end
|
||
|
||
function XGuildDormRole:UpdateCurrentInteractInfo(value)
|
||
self.CurrentInteractInfo = value
|
||
end
|
||
|
||
function XGuildDormRole:AddComponent(compoent, pos)
|
||
if pos == nil then
|
||
table.insert(self.Componets, compoent)
|
||
else
|
||
table.insert(self.Componets, pos, compoent)
|
||
end
|
||
self.ComponetDic[compoent.__cname] = compoent
|
||
compoent:Init()
|
||
end
|
||
|
||
function XGuildDormRole:GetComponent(className)
|
||
return self.ComponetDic[className]
|
||
end
|
||
|
||
function XGuildDormRole:PlayBehavior(id)
|
||
self:GetAgent():PlayBehavior(id)
|
||
end
|
||
|
||
function XGuildDormRole:PlayBehaviorByType(behaviorType)
|
||
self:PlayBehavior(self:GetBehaviorIdByType(behaviorType))
|
||
end
|
||
|
||
function XGuildDormRole:GetBehaviorIdByType(behaviorType)
|
||
local behaviorId = XGuildDormConfig.GetRoleBehaviorIdByState(self.Id, behaviorType)
|
||
if not behaviorId then
|
||
XLog.Error("获取角色行为树失败,角色id=".. tostring(self.Id) .. ", state=" .. tostring(behaviorType))
|
||
return
|
||
end
|
||
return behaviorId
|
||
end
|
||
|
||
function XGuildDormRole:Update(dt)
|
||
for _, component in ipairs(self.Componets) do
|
||
if component.Update then
|
||
if component:CheckCanUpdate(dt) then
|
||
component:Update(dt)
|
||
end
|
||
end
|
||
end
|
||
end
|
||
|
||
local MoveWallState = {
|
||
BEGIN = 0,
|
||
MOVING = 1,
|
||
END = 2,
|
||
}
|
||
|
||
-- 检查是否需要同步给服务器
|
||
function XGuildDormRole:SyncToServer()
|
||
local transform = self:GetRLRole():GetTransform()
|
||
local isZeroDirection = self:GetCurrentMoveDirectionIsZero()
|
||
self.SyncState = XDataCenter.GuildDormManager.GetGuildDormNetwork():GetCsNetwork():SyncToServer(transform, isZeroDirection, self.SyncState)
|
||
end
|
||
|
||
function XGuildDormRole:ChangeStateMachine(state, isForce)
|
||
if not XGuildDormRoleFSMFactory.CheckHasState(state) then
|
||
XLog.Error("guild dorm role 切换不存在的状态", state)
|
||
return
|
||
end
|
||
if self.StateMachine and self.StateMachine.name == state and not isForce then
|
||
return
|
||
end
|
||
if self.StateMachine then
|
||
self.StateMachine:Exit()
|
||
end
|
||
self.StateMachine = XGuildDormRoleFSMFactory.New(state, self)
|
||
self.StateMachine:Enter()
|
||
self.StateMachine:Execute()
|
||
end
|
||
|
||
function XGuildDormRole:CheckIsInStateMachine(state)
|
||
if self.StateMachine and self.StateMachine.name == state then
|
||
return true
|
||
end
|
||
return false
|
||
end
|
||
|
||
function XGuildDormRole:StopPlayAction()
|
||
self:UpdatePlayActionId(-1)
|
||
self:ChangeStateMachine(XGuildDormConfig.RoleFSMType.IDLE)
|
||
local com = self:GetComponent("XGDActionPlayComponent")
|
||
if com then
|
||
com:StopPlayAction()
|
||
end
|
||
end
|
||
|
||
function XGuildDormRole:BeginInteract(id, isDirectInteract)
|
||
if isDirectInteract == nil then isDirectInteract = false end
|
||
local currentRoom = XDataCenter.GuildDormManager.GetCurrentRoom()
|
||
local currentInteractInfo = currentRoom:GetInteractInfoByFurnitureId(id)
|
||
if currentInteractInfo == nil then return end
|
||
self:UpdateCurrentInteractInfo(currentInteractInfo)
|
||
self:UpdateInteractStatus(XGuildDormConfig.InteractStatus.Begin)
|
||
local com = self:GetComponent("XGDFurnitureInteractComponent")
|
||
if com == nil then return end
|
||
com:BeginInteract(currentInteractInfo, isDirectInteract)
|
||
self:GetAgent():SetVarDicByKey("IsDirectInteract", isDirectInteract)
|
||
end
|
||
|
||
function XGuildDormRole:StopInteract()
|
||
CsXGameEventManager.Instance:Notify(XEventId.EVENT_DORM_INTERACT_STOP
|
||
, self:GetPlayerId())
|
||
-- 这里是为了特殊处理玩家进入后,其他玩家重复检查停止交互的逻辑
|
||
XScheduleManager.ScheduleOnce(function()
|
||
local agent = self:GetAgent()
|
||
if agent == nil then return end
|
||
local isSuccess = agent:GetVarDicByKey("InteractStopSuccess")
|
||
if not isSuccess and self:GetIsInteracting() then
|
||
self:StopInteract()
|
||
end
|
||
agent:SetVarDicByKey("InteractStopSuccess", nil)
|
||
end, 1)
|
||
end
|
||
|
||
function XGuildDormRole:CheckIsSelfPlayer()
|
||
return self.PlayerId == XPlayer.Id
|
||
end
|
||
|
||
--######################## 私有方法 ########################
|
||
|
||
-- 初始化默认的components
|
||
function XGuildDormRole:_InitDefaultComponets()
|
||
self.Componets = nil
|
||
self.Componets = {}
|
||
self.ComponetDic = nil
|
||
self.ComponetDic = {}
|
||
end
|
||
|
||
return XGuildDormRole |