PGRData/Script/matrix/xentity/xguilddorm/role/XGuildDormRole.lua

314 lines
No EOL
9.9 KiB
Lua
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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