203 lines
6.2 KiB
Lua
203 lines
6.2 KiB
Lua
local UIUtils = require("UI.Utils")
|
||
local Reactive = require("Core.Reactive")
|
||
local ERoleState = import("EBusyRoleState")
|
||
local EBusyItemEffectType = import("EBusyItemEffectType")
|
||
local GameplayStatics = import ("GameplayStatics")
|
||
local GetGameplayTag = require("GamePlay.Utils").GetGameplayTag
|
||
local BusyActorManagerSubSystem = import("BusyActorManagerSubSystem")
|
||
local GamePlayUtils = require("GamePlay.Utils")
|
||
local KismetMathLibrary = import("KismetMathLibrary")
|
||
|
||
local LevelItemRewardClass = import("LevelItemReward")
|
||
|
||
--- @class BusyRole
|
||
local Role={
|
||
movement_watcher = nil,
|
||
interacte_item = nil
|
||
}
|
||
|
||
local PickAbilityTag = "Ability.Role.Pick"
|
||
local RecoverAbilityTag = "Ability.Role.Recover"
|
||
local ConsumeAbilityTag = "Ability.Role.AttributeConsume"
|
||
local RollAbilityTag = "Ability.Role.Roll"
|
||
|
||
-- 私有函数
|
||
|
||
-- 采集相关
|
||
|
||
--- @param role BusyRole
|
||
--- @param pick_targer BusyLevelItem
|
||
local function ResetPickWatcher(role, pick_targer)
|
||
if role.pick_watcher ~= nil then
|
||
role.pick_watcher:Destroy()
|
||
end
|
||
role.pick_watcher = Reactive.Watcher(function()
|
||
if not pick_targer:IsAlive() then
|
||
role.pick_watcher:Destroy()
|
||
role.pick_watcher = nil
|
||
role.carried_item_id = pick_targer:GetItemID()
|
||
end
|
||
end)
|
||
end
|
||
|
||
--- 存储正在搬运的物品
|
||
local function StoreCarriedItem(role)
|
||
-- if not role.carried_item_id then return end
|
||
-- local sub_system = BusyActorManagerSubSystem.Get(role)
|
||
-- local bonfire = sub_system:GetNearestBonfire()
|
||
-- if bonfire:StoreItem(role.carried_item_id) then
|
||
-- role.carried_item_id = nil
|
||
-- end
|
||
end
|
||
|
||
function Role:ctor()
|
||
self.pick_timer = nil
|
||
self.carried_item_id = nil
|
||
self.time_limited_tags = {}
|
||
self.pick_watcher = nil -- 监听正在采集物品的状态
|
||
self.proxy = Reactive.ReactiveProperty({
|
||
state = ERoleState.BonfireIdle,
|
||
is_alive = true,
|
||
})
|
||
end
|
||
|
||
function Role:ReceiveBeginPlay()
|
||
self.bCanEverTick = false
|
||
self.Inventory:DepositItems(200001, 2)
|
||
self.movement_watcher = Reactive.Watcher(function()
|
||
self:UpdateRoleState()
|
||
end)
|
||
end
|
||
|
||
function Role:ReceiveEndPlay()
|
||
print(self, "Role:ReceiveEndPlay")
|
||
|
||
end
|
||
|
||
function Role:ReceiveSetRole(_)
|
||
self:TryActiveAbility(ConsumeAbilityTag, nil)
|
||
UIUtils.ShowWidget(self, "RoleState", {role=self})
|
||
end
|
||
|
||
function Role:UpdateRoleState()
|
||
-- 在auto run中访问Reactive Property的值,会导致多次调用,有性能隐患
|
||
local role_state = Reactive.RawGet(self.proxy, "state")
|
||
local move_proxy = self.Movement.proxy
|
||
if move_proxy.isIdle then
|
||
if role_state == ERoleState.Searching or role_state == ERoleState.PickFinished then
|
||
self.proxy.state = ERoleState.BackBonfire
|
||
self.Movement:BackBonfire()
|
||
elseif role_state == ERoleState.BackBonfire then
|
||
-- StoreCarriedItem(self)
|
||
self.proxy.state = ERoleState.BonfireIdle
|
||
end
|
||
else
|
||
if role_state == ERoleState.BonfireIdle then
|
||
self.proxy.state = ERoleState.Searching
|
||
end
|
||
end
|
||
print("old", role_state, "new", Reactive.RawGet(self.proxy, "state"), move_proxy.isIdle)
|
||
end
|
||
|
||
function Role:StartPick(level_item)
|
||
local GameplayEventData = import("GameplayEventData")
|
||
local EventData = GameplayEventData()
|
||
EventData.Instigator = self
|
||
EventData.Target = level_item
|
||
self.proxy.state = ERoleState.Picking
|
||
self:TryActiveAbility(PickAbilityTag, EventData)
|
||
-- ResetPickWatcher(self, level_item)
|
||
end
|
||
|
||
function Role:OnTouch(_)
|
||
local role_proxy = self.proxy
|
||
if role_proxy.state == ERoleState.BonfireIdle then
|
||
local pc = GameplayStatics.GetPlayerController(self:GetWorld(), 0)
|
||
local world_x, world_y = pc:convertCursorToWorldPosition()
|
||
role_proxy.state = ERoleState.Searching
|
||
self.Movement:SetDestination(world_x, world_y)
|
||
else
|
||
print("nothing")
|
||
end
|
||
end
|
||
|
||
function Role:OnOverlapBegin(OverlappedComp, OtherActor, OtherComp, OtherBodyIndex, bFromSweep, SweepResult)
|
||
if KismetMathLibrary.ClassIsChildOf(OtherActor:GetClass(), LevelItemRewardClass) then
|
||
self.Inventory:DepositItems(OtherActor.RewardID, 1)
|
||
OtherActor:ConditionalBeginDestroy()
|
||
else
|
||
if self.proxy.state ~= ERoleState.Searching then return end
|
||
self.proxy.state = ERoleState.Picking
|
||
self.Movement:Stop()
|
||
self:StartPick(OtherActor)
|
||
end
|
||
|
||
end
|
||
|
||
|
||
--- 使用翻滚技能
|
||
function Role:UseRollSkill()
|
||
self:TryActiveAbility(RollAbilityTag, nil)
|
||
end
|
||
|
||
|
||
|
||
-- 接口
|
||
function Role:GetPickEffect()
|
||
return self.RoleConfig.PickEffect
|
||
end
|
||
|
||
function Role:GetHealthPercent()
|
||
local current_health = self.LuaRoleAttribute.Health or 0
|
||
return current_health / self.RoleConfig.Health
|
||
end
|
||
|
||
function Role:GetHungerPercent()
|
||
return self.LuaRoleAttribute.Hunger / self.RoleConfig.Hunger
|
||
end
|
||
|
||
function Role:GetHungerConsumeSpeed()
|
||
if self.time_limited_tags["SkillRole"] ~= nil then
|
||
return self.RoleConfig.HungerConsumeSpeed * 8
|
||
else
|
||
return self.RoleConfig.HungerConsumeSpeed
|
||
end
|
||
end
|
||
|
||
function Role:GetSpeed()
|
||
return self.LuaRoleAttribute.MoveSpeed
|
||
end
|
||
|
||
function Role:GetMoveDirection()
|
||
return self.Movement.proxy.direction
|
||
end
|
||
|
||
|
||
--- 返回即将消耗的饥饿值和生命值
|
||
function Role:CalcRealChangeByHunger(value)
|
||
local config = self.RoleConfig
|
||
local fixed_change, extra_health_need = 0, 0
|
||
local cost_rate = config.HealthConsumeSpeed / config.HungerConsumeSpeed
|
||
local remain_hunger = self.LuaRoleAttribute.Hunger + value
|
||
if remain_hunger < 0 then
|
||
fixed_change = remain_hunger
|
||
extra_health_need = remain_hunger * cost_rate
|
||
elseif remain_hunger > self.RoleConfig.Hunger then
|
||
fixed_change = remain_hunger - self.RoleConfig.Hunger
|
||
end
|
||
return value - fixed_change, self:CalcRealChangeByHealth(extra_health_need)
|
||
end
|
||
|
||
function Role:CalcRealChangeByHealth(value)
|
||
if value == 0 then return 0 end
|
||
local fixed_change = 0
|
||
local remain_health = self.LuaRoleAttribute.Health + value
|
||
if remain_health < 0 then
|
||
fixed_change = remain_health
|
||
elseif remain_health > self.RoleConfig.Health then
|
||
fixed_change = remain_health - self.RoleConfig.Health
|
||
end
|
||
return value - fixed_change
|
||
end
|
||
|
||
return Class(nil, nil, Role) |