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