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) |