剔除不需要的插件依赖,比如Paper2D系列 #8
Paper2D系列还需要,如瓦片地图。提出了对PaperZD的依赖,以及依赖FlipBook组件的Actor
This commit is contained in:
@ -11,7 +11,6 @@
|
|||||||
"AdditionalDependencies": [
|
"AdditionalDependencies": [
|
||||||
"slua_unreal",
|
"slua_unreal",
|
||||||
"Engine",
|
"Engine",
|
||||||
"PaperZD",
|
|
||||||
"CoreUObject",
|
"CoreUObject",
|
||||||
"GameplayAbilities",
|
"GameplayAbilities",
|
||||||
"UMG"
|
"UMG"
|
||||||
@ -26,11 +25,6 @@
|
|||||||
"Editor"
|
"Editor"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"Name": "PaperZD",
|
|
||||||
"Enabled": true,
|
|
||||||
"MarketplaceURL": "com.epicgames.launcher://ue/marketplace/content/c4b43502026047d89296cd7bffd92828"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"Name": "GameplayAbilities",
|
"Name": "GameplayAbilities",
|
||||||
"Enabled": true
|
"Enabled": true
|
||||||
|
|||||||
@ -1,21 +0,0 @@
|
|||||||
local Bonfire = {}
|
|
||||||
local GamePlayUtils = require("GamePlay.Utils")
|
|
||||||
local Utils = require("GamePlay.Utils")
|
|
||||||
|
|
||||||
local item_effect_health_tag = "Change.Role.Health"
|
|
||||||
local item_effect_hunger_tag = "Change.Role.Health"
|
|
||||||
|
|
||||||
|
|
||||||
function Bonfire:ctor()
|
|
||||||
end
|
|
||||||
|
|
||||||
function Bonfire:ReceiveBeginPlay()
|
|
||||||
self.Inventory:SetInventoryCapacity(20)
|
|
||||||
end
|
|
||||||
|
|
||||||
function Bonfire:StoreItem(item_id)
|
|
||||||
return self.Inventory:DepositItems(item_id, 1)
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
return Class(nil, nil, Bonfire)
|
|
||||||
@ -1,108 +0,0 @@
|
|||||||
-- 禁用不必要的if诊断警告
|
|
||||||
---@diagnostic disable: unnecessary-if
|
|
||||||
|
|
||||||
-- 导入基类模块
|
|
||||||
local PWClass = require("Core.PWClass")
|
|
||||||
|
|
||||||
--- @class StorageClass
|
|
||||||
--- @field max_capacity number 最大容量(格子总数)
|
|
||||||
--- @field cur_capacity number 当前已用容量
|
|
||||||
--- @field grids_list table[] 存储格子列表
|
|
||||||
local StorageClass = PWClass.derive("StorageClass")
|
|
||||||
|
|
||||||
--- 创建新物品格子
|
|
||||||
--- @param item_id any 物品唯一标识
|
|
||||||
--- @return table 新创建的物品格子
|
|
||||||
local function CreateGrid(item_id)
|
|
||||||
return {
|
|
||||||
item_id = item_id, -- 物品ID
|
|
||||||
cur_cnt = 0, -- 当前数量
|
|
||||||
max_cnt = 1 -- 最大堆叠数(可扩展为配置项)
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
--- 查找或创建可用物品格子
|
|
||||||
--- @param storage StorageClass 存储实例
|
|
||||||
--- @param item_id any 目标物品ID
|
|
||||||
--- @return table 可用格子(找不到时创建新格子)
|
|
||||||
local function FindOrCreateAvailableGrid(storage, item_id)
|
|
||||||
-- 优先查找同类型且未满的格子
|
|
||||||
for _, grid in ipairs(storage.grids_list) do
|
|
||||||
if grid.item_id == item_id and grid.cur_cnt < grid.max_cnt then
|
|
||||||
return grid
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- 无可用格子时创建新的物品类型格子
|
|
||||||
local new_grid = CreateGrid(item_id)
|
|
||||||
table.insert(storage.grids_list, new_grid)
|
|
||||||
return new_grid
|
|
||||||
end
|
|
||||||
|
|
||||||
--- 构造函数
|
|
||||||
function StorageClass:ctor()
|
|
||||||
self.max_capacity = 10 -- 默认最大容量
|
|
||||||
self.cur_capacity = 0 -- 当前使用容量
|
|
||||||
self.grids_list = {} -- 格子容器
|
|
||||||
end
|
|
||||||
|
|
||||||
--- 设置存储容量上限
|
|
||||||
--- @param capacity number 新的最大容量
|
|
||||||
function StorageClass:SetMaxCapacity(capacity)
|
|
||||||
self.max_capacity = capacity
|
|
||||||
end
|
|
||||||
|
|
||||||
--- 存储物品
|
|
||||||
--- @param item_id any 要存储的物品ID
|
|
||||||
function StorageClass:Store(item_id)
|
|
||||||
-- 容量检查
|
|
||||||
if self.cur_capacity >= self.max_capacity then
|
|
||||||
return false -- 建议返回操作结果
|
|
||||||
end
|
|
||||||
|
|
||||||
local grid = FindOrCreateAvailableGrid(self, item_id)
|
|
||||||
grid.cur_cnt = grid.cur_cnt + 1
|
|
||||||
self.cur_capacity = self.cur_capacity + 1
|
|
||||||
return true -- 建议添加返回值
|
|
||||||
end
|
|
||||||
|
|
||||||
--- 取出物品
|
|
||||||
--- @param item_id any 目标物品ID
|
|
||||||
--- @return boolean 是否成功取出
|
|
||||||
function StorageClass:Withdraw(item_id)
|
|
||||||
-- 逆序遍历提高取出效率(通常新物品在末尾)
|
|
||||||
for i = #self.grids_list, 1, -1 do
|
|
||||||
local grid = self.grids_list[i]
|
|
||||||
if grid ~= nil and grid.item_id == item_id and grid.cur_cnt > 0 then
|
|
||||||
grid.cur_cnt = grid.cur_cnt - 1
|
|
||||||
self.cur_capacity = self.cur_capacity - 1
|
|
||||||
|
|
||||||
-- 清空空格子
|
|
||||||
if grid.cur_cnt == 0 then
|
|
||||||
table.remove(self.grids_list, i)
|
|
||||||
end
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
|
|
||||||
function StorageClass:Visit(vistor)
|
|
||||||
for _, grid in ipairs(self.grids_list) do vistor(_, grid) end
|
|
||||||
end
|
|
||||||
|
|
||||||
--- 查询物品(满足条件的物品及数量)
|
|
||||||
--- @param query_function fun(item_id:any):boolean 物品过滤函数
|
|
||||||
--- @return table 物品ID到数量的映射表
|
|
||||||
function StorageClass:QueryItem(query_function)
|
|
||||||
local items = {}
|
|
||||||
for _, grid in ipairs(self.grids_list) do
|
|
||||||
-- 仅统计有物品且满足查询条件的格子
|
|
||||||
if grid.cur_cnt > 0 and query_function(grid.item_id) then
|
|
||||||
items[grid.item_id] = (items[grid.item_id] or 0) + grid.cur_cnt
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return items
|
|
||||||
end
|
|
||||||
|
|
||||||
return StorageClass
|
|
||||||
@ -1,18 +0,0 @@
|
|||||||
local PlayerState = {}
|
|
||||||
|
|
||||||
function PlayerState:ctor()
|
|
||||||
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
function PlayerState:ReceiveBeginPlay()
|
|
||||||
print(self, "PlayerState:ReceiveBeginPlay")
|
|
||||||
end
|
|
||||||
|
|
||||||
function PlayerState:ReceiveEndPlay()
|
|
||||||
print(self, "PlayerState:ReceiveEndPlay")
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return Class(nil, nil, PlayerState)
|
|
||||||
@ -1,112 +0,0 @@
|
|||||||
local FVector = import "Vector"
|
|
||||||
local Vector2D = require("Utils.Vector2D")
|
|
||||||
local Library = import "BusyGamePlayLibrary"
|
|
||||||
local GameplayStatics = import("GameplayStatics")
|
|
||||||
|
|
||||||
local SubSystem = {}
|
|
||||||
|
|
||||||
local function GetNearestBonfire(system, x, y)
|
|
||||||
local selected_bonfire = nil
|
|
||||||
local selected_distance = nil
|
|
||||||
|
|
||||||
for _, bonfire in ipairs(system.bonfire_list) do
|
|
||||||
local pos = bonfire:K2_GetActorLocation()
|
|
||||||
local distance = (x - pos.X) ^ 2 + (y - pos.Y) ^ 2
|
|
||||||
if selected_distance == nil or distance < selected_distance then
|
|
||||||
selected_distance = distance
|
|
||||||
selected_bonfire = bonfire
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return selected_bonfire
|
|
||||||
end
|
|
||||||
|
|
||||||
function SubSystem:ctor()
|
|
||||||
self.current_role = nil
|
|
||||||
self.bonfire_list = {} -- 所有的篝火列表
|
|
||||||
end
|
|
||||||
|
|
||||||
function SubSystem:ReceiveSubSystemInitialize()
|
|
||||||
self.current_role = nil
|
|
||||||
self.bonfire_list = {}
|
|
||||||
end
|
|
||||||
|
|
||||||
function SubSystem:GetNearestBonfire()
|
|
||||||
if self.current_role then
|
|
||||||
local cur_pos = self.current_role:K2_GetActorLocation()
|
|
||||||
return GetNearestBonfire(self, cur_pos.X, cur_pos.Y)
|
|
||||||
end
|
|
||||||
return nil
|
|
||||||
end
|
|
||||||
|
|
||||||
function SubSystem:SpawnBonfire(position)
|
|
||||||
local pos = FVector()
|
|
||||||
local world = self:K2_GetWorld()
|
|
||||||
local cls = Library.GetGameClass("Bonfire")
|
|
||||||
pos.X, pos.Y, pos.Z = position.X, position.Y, 20
|
|
||||||
local bonfire = world:SpawnActor(cls, pos, nil, nil)
|
|
||||||
table.insert(self.bonfire_list, bonfire)
|
|
||||||
return bonfire
|
|
||||||
end
|
|
||||||
|
|
||||||
function SubSystem:SpawnRole(bonfire)
|
|
||||||
local role_pos = FVector()
|
|
||||||
local world = self:K2_GetWorld()
|
|
||||||
local pos = bonfire:K2_GetActorLocation()
|
|
||||||
local cls = Library.GetGameClass("BusyRole")
|
|
||||||
role_pos.X, role_pos.Y, role_pos.Z = pos.X, pos.Y, pos.Z + 10
|
|
||||||
self.current_role = world:SpawnActor(cls, role_pos, nil, nil)
|
|
||||||
if self.current_role ~= nil then
|
|
||||||
self.current_role:SetRole("Rabbit")
|
|
||||||
return self.current_role
|
|
||||||
else
|
|
||||||
return nil
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function SubSystem:SpawnLevelItem(item_id)
|
|
||||||
-- 随机在角色周围生成
|
|
||||||
|
|
||||||
local distance = math.random(128, 500)
|
|
||||||
local angle = (math.random(0, 360) / 360) * 2 * 3.14;
|
|
||||||
|
|
||||||
local world = self:K2_GetWorld()
|
|
||||||
local item_position = FVector()
|
|
||||||
local center = self.current_role:K2_GetActorLocation()
|
|
||||||
local cls = import("BusyLevelItem")
|
|
||||||
|
|
||||||
item_position.Z = center.Z - 1
|
|
||||||
item_position.X = center.X + math.cos(angle) * distance
|
|
||||||
item_position.Y = center.Y + math.sin(angle) * distance
|
|
||||||
|
|
||||||
local item = world:SpawnActor(cls, item_position, nil, nil)
|
|
||||||
item:SetLevelItemID(item_id)
|
|
||||||
return center
|
|
||||||
end
|
|
||||||
|
|
||||||
function SubSystem:SpawnLevelItemReward(level_item)
|
|
||||||
assert(self.current_role ~= nil)
|
|
||||||
|
|
||||||
local world = self:K2_GetWorld()
|
|
||||||
local cls = Library.GetGameClass("LevelItemReward")
|
|
||||||
|
|
||||||
local random_angle = (math.random() - 0.5) * (math.pi / 2)
|
|
||||||
local direction = Vector2D.Normalize(self.current_role:GetMoveDirection())
|
|
||||||
|
|
||||||
local sin, cos = math.sin(random_angle), math.cos(random_angle)
|
|
||||||
|
|
||||||
-- 应用旋转矩阵
|
|
||||||
direction.X = direction.X * cos - direction.Y * sin
|
|
||||||
direction.Y = direction.X * sin + direction.Y * cos
|
|
||||||
|
|
||||||
local item_location = level_item:K2_GetActorLocation()
|
|
||||||
|
|
||||||
local reward_location = Vector2D.Add(item_location, Vector2D.Mul(direction, 200))
|
|
||||||
|
|
||||||
local item = world:SpawnActor(cls,
|
|
||||||
Vector2D.ToUnrealEngine3D(reward_location, item_location.Z),
|
|
||||||
nil, nil
|
|
||||||
)
|
|
||||||
return item
|
|
||||||
end
|
|
||||||
|
|
||||||
return Class(nil, nil, SubSystem)
|
|
||||||
@ -1,119 +0,0 @@
|
|||||||
---@class ItemGenerator 物品生成器类
|
|
||||||
local ItemGenerator = {
|
|
||||||
item_data = {},
|
|
||||||
period = 100,
|
|
||||||
item_distributions = {}
|
|
||||||
}
|
|
||||||
ItemGenerator.__index = ItemGenerator
|
|
||||||
|
|
||||||
---数组洗牌函数(Fisher-Yates算法)
|
|
||||||
---@param array any[] 需要打乱顺序的数组
|
|
||||||
local function ShuffleArray(array)
|
|
||||||
for i = #array, 2, -1 do -- 从后往前遍历
|
|
||||||
local j = math.random(i) -- 生成1到i的随机数
|
|
||||||
array[i], array[j] = array[j], array[i] -- 交换元素位置
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
---创建物品生成器实例
|
|
||||||
---@param period number 生成周期次数
|
|
||||||
---@param item_data table<number, number> 物品配置表 {物品ID = 总生成数量}
|
|
||||||
---@return ItemGenerator 物品生成器实例
|
|
||||||
local function CreateItemGenerator(period, item_data)
|
|
||||||
local self = setmetatable({}, ItemGenerator)
|
|
||||||
---@type number 存储生成周期
|
|
||||||
self.period = period
|
|
||||||
---@type table<number, number> 原始配置数据
|
|
||||||
self.item_data = item_data
|
|
||||||
---@type number 当前调用次数
|
|
||||||
self.current_call = 0
|
|
||||||
---@type table<number, number[]> 物品分布数据结构
|
|
||||||
self.item_distributions = {}
|
|
||||||
self:InitializeDistributions()
|
|
||||||
return self
|
|
||||||
end
|
|
||||||
|
|
||||||
---初始化物品分布数据
|
|
||||||
function ItemGenerator:InitializeDistributions()
|
|
||||||
-- 遍历所有物品配置
|
|
||||||
for item_id, total in pairs(self.item_data) do
|
|
||||||
-- 计算基础值和余数(保证总数 = 基础值*period + 余数)
|
|
||||||
local base = math.floor(total / self.period)
|
|
||||||
local remainder = total % self.period
|
|
||||||
|
|
||||||
-- 创建初始分布数组(全部填充基础值)
|
|
||||||
local distribution = {}
|
|
||||||
for i = 1, self.period do
|
|
||||||
distribution[i] = base
|
|
||||||
end
|
|
||||||
|
|
||||||
-- 生成索引数组并洗牌(用于随机分配余数)
|
|
||||||
local indices = {}
|
|
||||||
for i = 1, self.period do
|
|
||||||
indices[i] = i
|
|
||||||
end
|
|
||||||
ShuffleArray(indices) -- 打乱索引顺序
|
|
||||||
|
|
||||||
-- 将余数随机分配到前remainder个位置
|
|
||||||
for i = 1, remainder do
|
|
||||||
distribution[indices[i]] = distribution[indices[i]] + 1
|
|
||||||
end
|
|
||||||
|
|
||||||
-- 存储当前物品的分布数组
|
|
||||||
self.item_distributions[item_id] = distribution
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
---重置生成器状态(当调用次数超过N时触发)
|
|
||||||
function ItemGenerator:Reinitialize()
|
|
||||||
self:InitializeDistributions() -- 重新生成分布数据
|
|
||||||
self.current_call = 0 -- 重置调用计数器
|
|
||||||
end
|
|
||||||
|
|
||||||
---生成物品列表(每次调用产生一个周期的结果)
|
|
||||||
---@return number[] 包含物品ID的数组(结果经过随机排序)
|
|
||||||
function ItemGenerator:Generate()
|
|
||||||
-- 当超过周期次数时重置状态
|
|
||||||
if self.current_call >= self.period then
|
|
||||||
self:Reinitialize()
|
|
||||||
end
|
|
||||||
|
|
||||||
local current_step = self.current_call + 1 -- 获取当前步骤(1-based)
|
|
||||||
local result = {} -- 结果收集器
|
|
||||||
|
|
||||||
-- 遍历所有物品的分布数据
|
|
||||||
for item_id, distribution in pairs(self.item_distributions) do
|
|
||||||
local count = distribution[current_step] -- 获取当前步骤应生成数量
|
|
||||||
for _ = 1, count do
|
|
||||||
table.insert(result, item_id) -- 按数量添加物品ID到结果集
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
ShuffleArray(result) -- 打乱结果顺序保证随机性
|
|
||||||
self.current_call = self.current_call + 1 -- 增加调用计数器
|
|
||||||
|
|
||||||
return result
|
|
||||||
end
|
|
||||||
|
|
||||||
---获取当前未生成的物品剩余数量
|
|
||||||
---@return table<number, number> 返回物品ID和剩余数量的映射表
|
|
||||||
function ItemGenerator:GetRemainingItems()
|
|
||||||
local remaining = {}
|
|
||||||
local current_step = self.current_call -- 注意这里使用已调用次数(0-based)
|
|
||||||
|
|
||||||
-- 遍历所有物品的分布数据
|
|
||||||
for item_id, distribution in pairs(self.item_distributions) do
|
|
||||||
local total_remaining = 0
|
|
||||||
|
|
||||||
-- 计算从下一个步骤到周期结束的总数量
|
|
||||||
for step = current_step + 1, self.period do
|
|
||||||
total_remaining = total_remaining + distribution[step]
|
|
||||||
end
|
|
||||||
|
|
||||||
remaining[item_id] = total_remaining
|
|
||||||
end
|
|
||||||
|
|
||||||
return remaining
|
|
||||||
end
|
|
||||||
|
|
||||||
return CreateItemGenerator
|
|
||||||
@ -1,73 +0,0 @@
|
|||||||
local SubSystem = {}
|
|
||||||
local Reactive = require("Core.Reactive")
|
|
||||||
local Library = import("BusyGamePlayLibrary")
|
|
||||||
local GameplayStatics = import("GameplayStatics")
|
|
||||||
local BusyGamePlayLibrary = import("BusyGamePlayLibrary")
|
|
||||||
|
|
||||||
|
|
||||||
local function CreateItemGenerator(level_config_data)
|
|
||||||
local Generator = require("GamePlay.Level.BusyLevelItemGenerator")
|
|
||||||
|
|
||||||
local item_data = {}
|
|
||||||
local period = level_config_data.Period
|
|
||||||
for k, v in pairs(level_config_data.LevelItemIds) do
|
|
||||||
item_data[k] = v.CountOfPeriod
|
|
||||||
end
|
|
||||||
return Generator(period, item_data)
|
|
||||||
end
|
|
||||||
|
|
||||||
function SubSystem:Bp_ShouldCreateSubsystem(world)
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
|
|
||||||
function SubSystem:ReceiveSubSystemInitialize()
|
|
||||||
local world = BusyGamePlayLibrary.K2_GetWorld(self)
|
|
||||||
self.start_time = GameplayStatics.GetTimeSeconds(world)
|
|
||||||
|
|
||||||
self.proxy = Reactive.ReactiveProperty({
|
|
||||||
current_seconds = 0
|
|
||||||
})
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
function SubSystem:ReceiveWorldBeginPlay()
|
|
||||||
local BusyActorManagerSubSystem = import("BusyActorManagerSubSystem").Get(self)
|
|
||||||
|
|
||||||
-- 读取关卡配置
|
|
||||||
local is_suc, row_data = Library.GetLevelBaseConfig("Default", nil)
|
|
||||||
assert(is_suc == true, "Can't find level base config")
|
|
||||||
self.level_base_config = row_data
|
|
||||||
|
|
||||||
-- 创建物品生成器
|
|
||||||
self.generator = CreateItemGenerator(row_data)
|
|
||||||
|
|
||||||
-- 创建初始篝火
|
|
||||||
-- local bonfire = BusyActorManagerSubSystem:SpawnBonfire(row_data.FirstBonfirePosition)
|
|
||||||
|
|
||||||
-- 创建角色
|
|
||||||
-- local role = BusyActorManagerSubSystem:SpawnRole(bonfire)
|
|
||||||
-- GameplayStatics.GetPlayerController(self, 0):Possess(role)
|
|
||||||
end
|
|
||||||
|
|
||||||
function SubSystem:ReceiveSubSystemTick(DeltaTime)
|
|
||||||
-- local proxy = self.proxy
|
|
||||||
-- local world = BusyGamePlayLibrary.K2_GetWorld(self)
|
|
||||||
-- local current_time = GameplayStatics.GetTimeSeconds(world)
|
|
||||||
-- local escapse_time = math.floor(current_time - self.start_time)
|
|
||||||
-- if escapse_time > proxy.current_seconds then
|
|
||||||
-- self:TrySpawnLevelItem()
|
|
||||||
-- proxy.current_seconds = escapse_time
|
|
||||||
-- print(proxy.current_seconds)
|
|
||||||
-- end
|
|
||||||
end
|
|
||||||
|
|
||||||
function SubSystem:TrySpawnLevelItem()
|
|
||||||
local BusyActorManagerSubSystem = import("BusyActorManagerSubSystem").Get(self)
|
|
||||||
local items = self.generator:Generate()
|
|
||||||
for i, item_id in pairs(items) do
|
|
||||||
BusyActorManagerSubSystem:SpawnLevelItem(item_id)
|
|
||||||
print(i, item_id)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
return Class(nil, nil, SubSystem)
|
|
||||||
@ -1,103 +0,0 @@
|
|||||||
--- @class BusyLevelItem
|
|
||||||
local LevelItem = {}
|
|
||||||
local Reactive = require("Core.Reactive")
|
|
||||||
local RoleUtils = require("GamePlay.Utils.RoleUtils")
|
|
||||||
local GameplayUtils = require("GamePlay.Utils")
|
|
||||||
local KismetSystemLibrary = import("KismetSystemLibrary")
|
|
||||||
|
|
||||||
function LevelItem:ReceiveBeginPlay()
|
|
||||||
self:SetLevelItemID(self.CurrentItemID)
|
|
||||||
self.world = self:GetWorld()
|
|
||||||
print("LevelItem:ReceiveBeginPlay")
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
function LevelItem:TempSetting()
|
|
||||||
self:ReceiveBeginPlay()
|
|
||||||
end
|
|
||||||
|
|
||||||
function LevelItem:ReceiveLevelItemSetted(Config)
|
|
||||||
self.config = Config
|
|
||||||
self.PickBar.Widget:BindLevelItem(self)
|
|
||||||
|
|
||||||
print("LevelItem:ReceiveLevelItemSetted", KismetSystemLibrary.IsValid(self))
|
|
||||||
|
|
||||||
|
|
||||||
self.attribute_watcher = Reactive.Watcher(function()
|
|
||||||
if self.LuaLevelItemAttribute.Health <= 0 then
|
|
||||||
self:GenerateDropItems()
|
|
||||||
local location = self:K2_GetActorLocation()
|
|
||||||
location.Z = -1000
|
|
||||||
self:K2_SetActorLocation(location, false, nil, false)
|
|
||||||
self:SetLifeSpan(0.3)
|
|
||||||
self.attribute_watcher:Destroy()
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
function LevelItem:GenerateDropItems()
|
|
||||||
local BusyActorManagerSubSystem = import("BusyActorManagerSubSystem").Get(self.world)
|
|
||||||
local role = RoleUtils.GetRole(self)
|
|
||||||
local role_location = role:K2_GetActorLocation()
|
|
||||||
local curr_location = self:K2_GetActorLocation()
|
|
||||||
|
|
||||||
local collection_config = GameplayUtils.GetItemConfigByID(self.CurrentItemID)
|
|
||||||
|
|
||||||
local generated_dict = {}
|
|
||||||
for _, config in pairs(collection_config.DropConfigs) do
|
|
||||||
local base = 0
|
|
||||||
local seed = math.random()
|
|
||||||
for _, rate in pairs(config.configs) do
|
|
||||||
local min = base
|
|
||||||
local max = base + rate.Rate
|
|
||||||
if seed >= min and seed < max then
|
|
||||||
generated_dict[config.ItemID] = rate.Count
|
|
||||||
break
|
|
||||||
end
|
|
||||||
base = max
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
for item_id, count in pairs(generated_dict) do
|
|
||||||
for _ = 1, count do
|
|
||||||
local reward = BusyActorManagerSubSystem:SpawnLevelItemReward(self)
|
|
||||||
|
|
||||||
reward.Movement.speed = 300.0
|
|
||||||
reward.Movement.accelerate = 600.0
|
|
||||||
reward.Movement.direction = {
|
|
||||||
X = curr_location.X - role_location.X,
|
|
||||||
Y = curr_location.Y - role_location.Y
|
|
||||||
}
|
|
||||||
reward:SetRewardID(item_id)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
-- 接口
|
|
||||||
function LevelItem:GetPickProcess()
|
|
||||||
local process = self.LuaLevelItemAttribute.Health / self.config.PickTimeCost
|
|
||||||
print("current process", process)
|
|
||||||
return process
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
function LevelItem:GetPickCost()
|
|
||||||
return self.LevelItemConfig.PickHungerCost
|
|
||||||
end
|
|
||||||
|
|
||||||
function LevelItem:IsAlive()
|
|
||||||
return self.LuaLevelItemAttribute.Health > 0
|
|
||||||
end
|
|
||||||
|
|
||||||
function LevelItem:GetItemID()
|
|
||||||
return self.CurrentItemID
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
return Class(nil, nil, LevelItem)
|
|
||||||
@ -1,24 +0,0 @@
|
|||||||
local PlayerController = {}
|
|
||||||
local KismetSystemLibrary = import("KismetSystemLibrary")
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function PlayerController:convertCursorToWorldPosition()
|
|
||||||
-- 将当前鼠标的位置转化为世界的位置
|
|
||||||
local FVector = import("Vector")
|
|
||||||
local WorldOrigin, WorldDirection = FVector(), FVector()
|
|
||||||
local _, MouseX, MouseY = self:GetMousePosition(nil, nil)
|
|
||||||
if self:DeprojectScreenPositionToWorld(
|
|
||||||
MouseX, MouseY, WorldOrigin, WorldDirection
|
|
||||||
)then
|
|
||||||
return WorldOrigin.X, WorldOrigin.Y
|
|
||||||
else
|
|
||||||
return nil, nil
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function PlayerController:QuitGame()
|
|
||||||
KismetSystemLibrary.QuitGame(self, self, 0, false)
|
|
||||||
end
|
|
||||||
|
|
||||||
return Class(nil, nil, PlayerController)
|
|
||||||
@ -1,203 +0,0 @@
|
|||||||
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)
|
|
||||||
@ -55,14 +55,6 @@ bool UBusyGameplayLibrary::GetLevelItemConfig(const FName& RowName, FBusyLevelIt
|
|||||||
return GetTableConfig<FBusyLevelItemConfig>(TEXT("LevelItems"), RowName, RowData);
|
return GetTableConfig<FBusyLevelItemConfig>(TEXT("LevelItems"), RowName, RowData);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool UBusyGameplayLibrary::GetRoleConfig(const FName& RowName, FBusyRoleConfig& RowData){
|
|
||||||
return GetTableConfig<FBusyRoleConfig>(TEXT("RoleConfig"), RowName, RowData);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool UBusyGameplayLibrary::GetItemResourceConfig(const FName& RowName, FBusyLevelItemResourceConfig& RowData){
|
|
||||||
return GetTableConfig<FBusyLevelItemResourceConfig>(TEXT("LevelItemResource"), RowName, RowData);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool UBusyGameplayLibrary::GetLevelItemDescription(const FName& RowName, FBusyLevelItemDescription& RowData){
|
bool UBusyGameplayLibrary::GetLevelItemDescription(const FName& RowName, FBusyLevelItemDescription& RowData){
|
||||||
return GetTableConfig<FBusyLevelItemDescription>(TEXT("LevelItemDesc"), RowName, RowData);
|
return GetTableConfig<FBusyLevelItemDescription>(TEXT("LevelItemDesc"), RowName, RowData);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -118,7 +118,7 @@ void UPW_TableSwitcher::RebuildSwitcher(const TMap<FName, FTableSwitcherInfo>& I
|
|||||||
Widget = CreateWidget<UPW_TableSwitcherWidget>(this, Info.SwitcherWidget);
|
Widget = CreateWidget<UPW_TableSwitcherWidget>(this, Info.SwitcherWidget);
|
||||||
UHorizontalBoxSlot *WidgetSlot = SwitcherBar->AddChildToHorizontalBox(Widget);
|
UHorizontalBoxSlot *WidgetSlot = SwitcherBar->AddChildToHorizontalBox(Widget);
|
||||||
if (WidgetSlot) {
|
if (WidgetSlot) {
|
||||||
WidgetSlot->VerticalAlignment = VAlign_Fill;
|
WidgetSlot->SetVerticalAlignment(VAlign_Fill);
|
||||||
}
|
}
|
||||||
Widget->SetSwitcherName(PageName);
|
Widget->SetSwitcherName(PageName);
|
||||||
Widget->SetSwitcherTitle(Info.TableSwitcherName);
|
Widget->SetSwitcherTitle(Info.TableSwitcherName);
|
||||||
|
|||||||
@ -1,117 +0,0 @@
|
|||||||
// Fill out your copyright notice in the Description page of Project Settings.
|
|
||||||
|
|
||||||
|
|
||||||
#include "Level/BusyLevelItem.h"
|
|
||||||
#include "Components/CapsuleComponent.h"
|
|
||||||
#include "Components/WidgetComponent.h"
|
|
||||||
#include "BusyGameplayLibrary.h"
|
|
||||||
|
|
||||||
ABusyLevelItem::ABusyLevelItem(): CurrentItemID("100001") {
|
|
||||||
LuaFilePath = TEXT("GamePlay.LevelItem.LevelItem");
|
|
||||||
|
|
||||||
SceneComp = CreateDefaultSubobject<USceneComponent>(TEXT("RootScene"));
|
|
||||||
CapsuleComp = CreateDefaultSubobject<UCapsuleComponent>(TEXT("LevelItemCapsule"));
|
|
||||||
Sprite = CreateDefaultSubobject<UPaperFlipbookComponent>(TEXT("Sprite"));
|
|
||||||
|
|
||||||
PickBar = CreateDefaultSubobject<UWidgetComponent>(TEXT("PickBar"));
|
|
||||||
LevelItemAttribute = CreateDefaultSubobject<UBusyLevelItemAttributeSet>("LevelItemAttribute");
|
|
||||||
|
|
||||||
InitSprite();
|
|
||||||
InitCapsule();
|
|
||||||
InitPickBar();
|
|
||||||
|
|
||||||
PickBar->SetupAttachment(CapsuleComp);
|
|
||||||
Sprite->SetupAttachment(CapsuleComp);
|
|
||||||
CapsuleComp->SetupAttachment(SceneComp);
|
|
||||||
this->RootComponent = SceneComp;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ABusyLevelItem::OnConstruction(const FTransform& Transform){
|
|
||||||
Super::OnConstruction(Transform);
|
|
||||||
SetItemDisplay(CurrentItemID);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ABusyLevelItem::BeginPlay(){
|
|
||||||
UClass* cls = UBusyGameplayLibrary::GetGameUIClass("PickBar");
|
|
||||||
if (cls != nullptr) {
|
|
||||||
PickBar->SetWidgetClass(cls);
|
|
||||||
}
|
|
||||||
Super::BeginPlay();
|
|
||||||
bIsBeginPlay = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ABusyLevelItem::EndPlay(const EEndPlayReason::Type EndPlayReason){
|
|
||||||
Super::EndPlay(EndPlayReason);
|
|
||||||
bIsBeginPlay = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ABusyLevelItem::PostLuaHook(){
|
|
||||||
if (bIsBeginPlay) {
|
|
||||||
CallLuaFunctionIfExist("TempSetting");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ABusyLevelItem::InitCapsule(){
|
|
||||||
|
|
||||||
CapsuleComp->SetCollisionProfileName(TEXT("Custom"));
|
|
||||||
CapsuleComp->SetNotifyRigidBodyCollision(false);
|
|
||||||
CapsuleComp->SetSimulatePhysics(false);
|
|
||||||
CapsuleComp->SetEnableGravity(false);
|
|
||||||
|
|
||||||
CapsuleComp->SetCollisionObjectType(ECC_WorldStatic); // 设置对象类型
|
|
||||||
|
|
||||||
// 逐个通道设置响应
|
|
||||||
CapsuleComp->SetCollisionEnabled(ECollisionEnabled::QueryAndPhysics);
|
|
||||||
//CapsuleComp->SetCollisionResponseToAllChannels(ECR_Ignore);
|
|
||||||
CapsuleComp->SetCollisionResponseToChannel(ECC_Pawn, ECR_Overlap);
|
|
||||||
CapsuleComp->SetCollisionResponseToChannel(ECC_WorldStatic, ECR_Ignore);
|
|
||||||
|
|
||||||
CapsuleComp->SetCapsuleRadius(10);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ABusyLevelItem::InitSprite(){
|
|
||||||
Sprite->SetRelativeRotation(FRotator(0.0, 0.0, -90.0));
|
|
||||||
}
|
|
||||||
|
|
||||||
void ABusyLevelItem::InitPickBar(){
|
|
||||||
PickBar->SetRelativeRotation(FRotator(90.0, 0.0, -90.0));
|
|
||||||
PickBar->SetRelativeLocation(FVector(0.0, -180.0, 0.0));
|
|
||||||
PickBar->SetGenerateOverlapEvents(false);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void ABusyLevelItem::SetItemDisplay(const FName& ItemID){
|
|
||||||
UDataTable* Resource = UBusyGameplayLibrary::GetGameDataTable(TEXT("LevelItemResource"));
|
|
||||||
|
|
||||||
// 查物品信息
|
|
||||||
FBusyLevelItemResourceConfig* ResourceConfig = Resource->FindRow<FBusyLevelItemResourceConfig>(
|
|
||||||
ItemID, TEXT("ABusyLevelItem::SetLevelItemID"), true
|
|
||||||
);
|
|
||||||
|
|
||||||
// 设置资源
|
|
||||||
if (ResourceConfig != nullptr && ResourceConfig->StaticResource) {
|
|
||||||
this->Sprite->SetFlipbook(ResourceConfig->StaticResource);
|
|
||||||
this->CurrentItemID = ItemID;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ABusyLevelItem::SetLevelItemID(const FName& ItemID){
|
|
||||||
// 取物品资源表
|
|
||||||
UDataTable* ConfigTable = UBusyGameplayLibrary::GetGameDataTable(TEXT("LevelItems"));
|
|
||||||
// 查物品信息
|
|
||||||
FBusyLevelItemConfig* ItemConfig = ConfigTable->FindRow<FBusyLevelItemConfig>(
|
|
||||||
ItemID, TEXT("ABusyLevelItem::SetLevelItemID"), true
|
|
||||||
);
|
|
||||||
SetItemDisplay(ItemID);
|
|
||||||
|
|
||||||
// 设置配置属性
|
|
||||||
if (ItemConfig == nullptr) return;
|
|
||||||
|
|
||||||
// 初始化Attribute
|
|
||||||
LevelItemAttribute->InitHealth(ItemConfig->PickTimeCost);
|
|
||||||
LevelItemAttribute->RegisterCustomAttribute();
|
|
||||||
|
|
||||||
CurrentItemID = ItemID;
|
|
||||||
LevelItemConfig = *ItemConfig;
|
|
||||||
ReceiveLevelItemSetted(LevelItemConfig);
|
|
||||||
}
|
|
||||||
@ -1,33 +0,0 @@
|
|||||||
// Fill out your copyright notice in the Description page of Project Settings.
|
|
||||||
|
|
||||||
|
|
||||||
#include "Level/LevelItemReward.h"
|
|
||||||
#include "Components/CapsuleComponent.h"
|
|
||||||
#include "Components/SceneComponent.h"
|
|
||||||
#include "PaperFlipbook.h"
|
|
||||||
#include "PaperFlipbookComponent.h"
|
|
||||||
#include "BusyGameplayLibrary.h"
|
|
||||||
|
|
||||||
|
|
||||||
ALevelItemReward::ALevelItemReward(){
|
|
||||||
SceneComp = CreateDefaultSubobject<USceneComponent>(TEXT("RootScene"));
|
|
||||||
CapsuleComp = CreateDefaultSubobject<UCapsuleComponent>(TEXT("RoleCapsule"));
|
|
||||||
Sprite = CreateDefaultSubobject<UPaperFlipbookComponent>(TEXT("Sprite"));
|
|
||||||
CapsuleComp->SetupAttachment(SceneComp);
|
|
||||||
Sprite->SetupAttachment(CapsuleComp);
|
|
||||||
this->RootComponent = SceneComp;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ALevelItemReward::OnConstruction(const FTransform& Transform){
|
|
||||||
SetRewardID(RewardID);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ALevelItemReward::SetRewardID(const FName& CurrentRewardID){
|
|
||||||
bool bIsFind = false;
|
|
||||||
FBusyLevelItemDescription Desc;
|
|
||||||
if (CurrentRewardID.IsNone()) return;
|
|
||||||
bIsFind = UBusyGameplayLibrary::GetLevelItemDescription(CurrentRewardID, Desc);
|
|
||||||
if (!bIsFind) return;
|
|
||||||
this->RewardID = CurrentRewardID;
|
|
||||||
this->Sprite->SetFlipbook(Desc.LevelResource.LoadSynchronous());
|
|
||||||
}
|
|
||||||
@ -1,110 +0,0 @@
|
|||||||
// Fill out your copyright notice in the Description page of Project Settings.
|
|
||||||
|
|
||||||
|
|
||||||
#include "Role/BusyRole.h"
|
|
||||||
#include "GameFramework/SpringArmComponent.h"
|
|
||||||
#include "Components/CapsuleComponent.h"
|
|
||||||
#include "Components/SceneComponent.h"
|
|
||||||
#include "BusyCameraComponent.h"
|
|
||||||
#include "PaperFlipbookComponent.h"
|
|
||||||
#include "Role/BusyRoleMovement.h"
|
|
||||||
#include "Role/RoleAnimation.h"
|
|
||||||
#include "BusyGameplayLibrary.h"
|
|
||||||
#include "Components/InventoryComponent.h"
|
|
||||||
#include "Core/PW_AbilitySystemComponent.h"
|
|
||||||
#include "EnhancedInputComponent.h"
|
|
||||||
#include "EnhancedInputSubsystems.h"
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
ABusyRole::ABusyRole(){
|
|
||||||
SceneComp = CreateDefaultSubobject<USceneComponent>(TEXT("RootScene"));
|
|
||||||
CapsuleComp = CreateDefaultSubobject<UCapsuleComponent>(TEXT("RoleCapsule"));
|
|
||||||
SpringArmComp = CreateDefaultSubobject<USpringArmComponent>(TEXT("SpringArm"));
|
|
||||||
CameraComp = CreateDefaultSubobject<UBusyCameraComponent>(TEXT("RoleCamera"));
|
|
||||||
Sprite = CreateDefaultSubobject<UPaperFlipbookComponent>(TEXT("Sprite"));
|
|
||||||
|
|
||||||
Movement = CreateDefaultSubobject<UBusyRoleMovement>(TEXT("Movement"));
|
|
||||||
RoleAnimation = CreateDefaultSubobject<URoleAnimation>(TEXT("RoleAnimation"));
|
|
||||||
Inventory = CreateDefaultSubobject<UInventoryComponent>(TEXT("Inventory"));
|
|
||||||
|
|
||||||
RoleAbility = CreateDefaultSubobject<UPW_AbilitySystemComponent>("RoleAbility");
|
|
||||||
RoleAttribute = CreateDefaultSubobject<UBusyRoleAttributeSet>(TEXT("RoleAttributeSet"));
|
|
||||||
|
|
||||||
SpringArmComp->SetRelativeRotation(FRotator(-90.0, -90.0, 0.0));
|
|
||||||
this->InitCapsule();
|
|
||||||
|
|
||||||
Sprite->SetupAttachment(CapsuleComp);
|
|
||||||
CapsuleComp->SetupAttachment(SceneComp);
|
|
||||||
SpringArmComp->SetupAttachment(CapsuleComp);
|
|
||||||
CameraComp->SetupAttachment(SpringArmComp);
|
|
||||||
|
|
||||||
PrimaryActorTick.bCanEverTick = true;
|
|
||||||
this->RootComponent = SceneComp;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ABusyRole::BeginPlay(){
|
|
||||||
Super::BeginPlay();
|
|
||||||
|
|
||||||
if (APlayerController* PlayerController = Cast<APlayerController>(GetController())) {
|
|
||||||
if (UEnhancedInputLocalPlayerSubsystem* Subsystem = ULocalPlayer::GetSubsystem<UEnhancedInputLocalPlayerSubsystem>(PlayerController->GetLocalPlayer())) {
|
|
||||||
Subsystem->AddMappingContext(InputMapping, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void ABusyRole::Tick(float InDeltaSeconds){
|
|
||||||
Super::Tick(InDeltaSeconds);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ABusyRole::SetRole(const FName& Name){
|
|
||||||
UDataTable* Table = UBusyGameplayLibrary::GetGameDataTable("RoleConfig");
|
|
||||||
if (Table == nullptr) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
FBusyRoleConfig *Row = Table->FindRow<FBusyRoleConfig>(Name, TEXT("ABusyRole::SetRole"));
|
|
||||||
if (Row == nullptr) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
RoleName = Name;
|
|
||||||
RoleConfig = *Row;
|
|
||||||
|
|
||||||
// <20><><EFBFBD>û<EFBFBD><C3BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
||||||
if (RoleAttribute) {
|
|
||||||
RoleAttribute->InitHealth(Row->Health);
|
|
||||||
RoleAttribute->InitHunger(Row->Hunger);
|
|
||||||
RoleAttribute->InitMoveSpeed(Row->MoveSpeed);
|
|
||||||
RoleAttribute->RegisterCustomAttribute();
|
|
||||||
}
|
|
||||||
|
|
||||||
// <20><><EFBFBD>ü<EFBFBD><C3BC><EFBFBD>
|
|
||||||
for (UClass* AbilityClass : Row->DefaultAbilities) {
|
|
||||||
if (AbilityClass) {
|
|
||||||
RoleAbility->GiveAbility(FGameplayAbilitySpec(AbilityClass));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ReceiveSetRole(RoleConfig);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ABusyRole::TryActiveAbility(const FName& TagName,const FGameplayEventData& EventData){
|
|
||||||
RoleAbility->HandleGameplayEvent(FGameplayTag::RequestGameplayTag(TagName), &EventData);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ABusyRole::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent){
|
|
||||||
Super::SetupPlayerInputComponent(PlayerInputComponent);
|
|
||||||
|
|
||||||
if (UEnhancedInputComponent* EnhancedInput = CastChecked<UEnhancedInputComponent>(PlayerInputComponent)) {
|
|
||||||
EnhancedInput->BindAction(TouchAction, ETriggerEvent::Triggered, this, FName("OnTouch"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ABusyRole::InitCapsule(){
|
|
||||||
FScriptDelegate OverlapDelegate;
|
|
||||||
CapsuleComp->SetCollisionProfileName(TEXT("Pawn"));
|
|
||||||
CapsuleComp->SetNotifyRigidBodyCollision(false);
|
|
||||||
OverlapDelegate.BindUFunction(this, "OnOverlapBegin");
|
|
||||||
CapsuleComp->OnComponentBeginOverlap.Add(OverlapDelegate);
|
|
||||||
|
|
||||||
CapsuleComp->SetCapsuleRadius(10);
|
|
||||||
}
|
|
||||||
@ -1,25 +0,0 @@
|
|||||||
// Fill out your copyright notice in the Description page of Project Settings.
|
|
||||||
|
|
||||||
|
|
||||||
#include "Role/BusyRoleMovement.h"
|
|
||||||
#include "PaperFlipbookComponent.h"
|
|
||||||
|
|
||||||
UBusyRoleMovement::UBusyRoleMovement(){
|
|
||||||
LuaFilePath = TEXT("GamePlay/BusyRole/Movement");
|
|
||||||
this->PrimaryComponentTick.bCanEverTick = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void UBusyRoleMovement::BeginPlay(){
|
|
||||||
Super::BeginPlay();
|
|
||||||
ReceiveComponentBeginPlay();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void UBusyRoleMovement::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)
|
|
||||||
{
|
|
||||||
Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
|
|
||||||
const AActor* Owner = GetOwner();
|
|
||||||
if (!Owner) return;
|
|
||||||
this->ReceiveComponentTick(DeltaTime);
|
|
||||||
}
|
|
||||||
|
|
||||||
@ -1,115 +0,0 @@
|
|||||||
// Fill out your copyright notice in the Description page of Project Settings.
|
|
||||||
|
|
||||||
|
|
||||||
#include "Role/RoleAnimation.h"
|
|
||||||
#include "Role/BusyRole.h"
|
|
||||||
#include "BusyGameplayLibrary.h"
|
|
||||||
|
|
||||||
DEFINE_LOG_CATEGORY(LogRoleAnimation);
|
|
||||||
|
|
||||||
|
|
||||||
URoleAnimation::URoleAnimation(){
|
|
||||||
LuaFilePath = TEXT("GamePlay.BusyRole.Animation");
|
|
||||||
}
|
|
||||||
|
|
||||||
void URoleAnimation::SetMoveAnimation(ERoleMoveDirection direction){
|
|
||||||
FBusyRoleAnimationData* Config;
|
|
||||||
UPaperFlipbookComponent* Sprite;
|
|
||||||
|
|
||||||
if (!GetOwnerRoleInfo(Sprite, Config)) {
|
|
||||||
UE_LOG(LogRoleAnimation, Error, TEXT("URoleAnimation::SetMoveAnimation, Can't get owner info"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
SetRoleAnimation(Sprite, Config->MoveAnimations.Find(direction));
|
|
||||||
}
|
|
||||||
|
|
||||||
void URoleAnimation::SetIdleAnimation(ERoleMoveDirection direction){
|
|
||||||
FBusyRoleAnimationData* Config;
|
|
||||||
UPaperFlipbookComponent* Sprite;
|
|
||||||
|
|
||||||
if (!GetOwnerRoleInfo(Sprite, Config)) {
|
|
||||||
UE_LOG(LogRoleAnimation, Error, TEXT("URoleAnimation::SetMoveAnimation, Can't get owner info"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
SetRoleAnimation(Sprite, Config->IdleAnimations.Find(direction));
|
|
||||||
}
|
|
||||||
|
|
||||||
void URoleAnimation::PlayPickAnimation(const FName& ItemName, ERoleMoveDirection Direction, EBusyAnimationPhase Phase, float PlayRate){
|
|
||||||
FBusyRoleAnimationData* Config;
|
|
||||||
UPaperFlipbookComponent* Sprite;
|
|
||||||
|
|
||||||
if (!GetOwnerRoleInfo(Sprite, Config)) {
|
|
||||||
UE_LOG(LogRoleAnimation, Error, TEXT("URoleAnimation::SetPickAnimation, Can't get owner info"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
FBusyRolePickingAnimationData *Directions = Config->PickingAnimations.Find(ItemName);
|
|
||||||
if (Directions == nullptr) {
|
|
||||||
UE_LOG(LogRoleAnimation, Error, TEXT("URoleAnimation::SetPickAnimation, Can't get Directions Animation"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
FBusyAnimationPhaseData *PhaseData = Directions->DirectionAnimations.Find(Direction);
|
|
||||||
if (PhaseData == nullptr) {
|
|
||||||
UE_LOG(LogRoleAnimation, Error, TEXT("URoleAnimation::SetPickAnimation, Can't get PhaseData Animation"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
UPaperFlipbook **Animation = PhaseData->PhaseAnimation.Find(Phase);
|
|
||||||
if (Animation == nullptr) {
|
|
||||||
UE_LOG(LogRoleAnimation, Error, TEXT("URoleAnimation::SetPickAnimation, Can't get Animation"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
PlayAnimationOnce(Sprite, Animation, PlayRate);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool URoleAnimation::GetOwnerRoleInfo(UPaperFlipbookComponent*& Sprite, FBusyRoleAnimationData*& AnimationData){
|
|
||||||
ABusyRole* Role = Cast<ABusyRole>(this->GetOwner());
|
|
||||||
if (Role == nullptr) {
|
|
||||||
UE_LOG(LogRoleAnimation, Error, TEXT("URoleAnimation::GetPaperFilpBookComponent, Can't get Role"));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
UDataTable* DataTable = UBusyGameplayLibrary::GetGameDataTable("RoleAnimation");
|
|
||||||
if (DataTable == nullptr) {
|
|
||||||
UE_LOG(LogRoleAnimation, Error, TEXT("URoleAnimation::GetOwnerRoleInfo, Can't get Animation DataTable"))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
FBusyRoleAnimationData* Config = DataTable->FindRow<FBusyRoleAnimationData>(
|
|
||||||
Role->RoleName, TEXT("URoleAnimation::GetOwnerRoleInfo")
|
|
||||||
);
|
|
||||||
|
|
||||||
if (Config == nullptr) {
|
|
||||||
UE_LOG(LogRoleAnimation, Error, TEXT("URoleAnimation::GetOwnerRoleInfo, Can't get role info from table"))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
Sprite = Role->Sprite;
|
|
||||||
AnimationData = Config;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void URoleAnimation::SetRoleAnimation(UPaperFlipbookComponent* Sprite, UPaperFlipbook** Anim){
|
|
||||||
if (Anim && *Anim) {
|
|
||||||
Sprite->Stop();
|
|
||||||
Sprite->SetLooping(true);
|
|
||||||
Sprite->SetPlayRate(1.0);
|
|
||||||
Sprite->SetFlipbook(*Anim);
|
|
||||||
Sprite->PlayFromStart();
|
|
||||||
} else {
|
|
||||||
UE_LOG(LogRoleAnimation, Error, TEXT("URoleAnimation::SetRoleAnimation, Can't set role animation"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void URoleAnimation::PlayAnimationOnce(UPaperFlipbookComponent* Sprite, UPaperFlipbook** Anim, float PlayRate){
|
|
||||||
if (Anim && *Anim) {
|
|
||||||
Sprite->Stop();
|
|
||||||
Sprite->SetLooping(false);
|
|
||||||
Sprite->SetPlayRate(PlayRate);
|
|
||||||
Sprite->SetFlipbook(*Anim);
|
|
||||||
Sprite->PlayFromStart();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
UE_LOG(LogRoleAnimation, Error, TEXT("URoleAnimation::PlayAnimationOnce failed"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -3,9 +3,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "CoreMinimal.h"
|
#include "CoreMinimal.h"
|
||||||
#include "Role/BusyRole.h"
|
|
||||||
#include "Engine/World.h"
|
#include "Engine/World.h"
|
||||||
#include "Level/BusyLevelItem.h"
|
|
||||||
#include "Engine/DataTable.h"
|
#include "Engine/DataTable.h"
|
||||||
#include "Kismet/BlueprintFunctionLibrary.h"
|
#include "Kismet/BlueprintFunctionLibrary.h"
|
||||||
#include "GameAsset/BusyItem.h"
|
#include "GameAsset/BusyItem.h"
|
||||||
@ -35,12 +33,6 @@ public:
|
|||||||
UFUNCTION(BlueprintPure)
|
UFUNCTION(BlueprintPure)
|
||||||
static bool GetLevelItemConfig(const FName& RowName, FBusyLevelItemConfig& RowData);
|
static bool GetLevelItemConfig(const FName& RowName, FBusyLevelItemConfig& RowData);
|
||||||
|
|
||||||
UFUNCTION(BlueprintPure)
|
|
||||||
static bool GetRoleConfig(const FName& RowName, FBusyRoleConfig& RowData);
|
|
||||||
|
|
||||||
UFUNCTION(BlueprintPure)
|
|
||||||
static bool GetItemResourceConfig(const FName& RowName, FBusyLevelItemResourceConfig& RowData);
|
|
||||||
|
|
||||||
UFUNCTION(BlueprintPure)
|
UFUNCTION(BlueprintPure)
|
||||||
static bool GetLevelItemDescription(const FName& RowName, FBusyLevelItemDescription& RowData);
|
static bool GetLevelItemDescription(const FName& RowName, FBusyLevelItemDescription& RowData);
|
||||||
|
|
||||||
|
|||||||
@ -1,7 +1,10 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "CoreMinimal.h"
|
#include "CoreMinimal.h"
|
||||||
|
#include "GameplayTagContainer.h"
|
||||||
#include "BusyItem.generated.h"
|
#include "BusyItem.generated.h"
|
||||||
|
|
||||||
|
class UPaperFlipbook;
|
||||||
|
|
||||||
UENUM(BlueprintType) // 烹饪火候
|
UENUM(BlueprintType) // 烹饪火候
|
||||||
enum class ECookingHeat : uint8 {
|
enum class ECookingHeat : uint8 {
|
||||||
LOW_HEAT, // 小火
|
LOW_HEAT, // 小火
|
||||||
|
|||||||
@ -1,21 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include "LuaOverriderInterface.h"
|
|
||||||
#include "GameplayModMagnitudeCalculation.h"
|
|
||||||
#include "BusyMagnitudeCalculation.generated.h"
|
|
||||||
|
|
||||||
UCLASS()
|
|
||||||
class UBusyMagnitudeCalculation : public UGameplayModMagnitudeCalculation, public ILuaOverriderInterface
|
|
||||||
{
|
|
||||||
GENERATED_BODY()
|
|
||||||
public:
|
|
||||||
virtual FString GetLuaFilePath_Implementation();
|
|
||||||
|
|
||||||
protected:
|
|
||||||
UPROPERTY(EditDefaultsOnly)
|
|
||||||
FString LuaFilePath;
|
|
||||||
};
|
|
||||||
|
|
||||||
inline FString UBusyMagnitudeCalculation::GetLuaFilePath_Implementation()
|
|
||||||
{
|
|
||||||
return LuaFilePath;
|
|
||||||
}
|
|
||||||
@ -1,116 +0,0 @@
|
|||||||
// Fill out your copyright notice in the Description page of Project Settings.
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "CoreMinimal.h"
|
|
||||||
#include "LuaActor.h"
|
|
||||||
#include "Engine/Datatable.h"
|
|
||||||
#include "PaperFlipbookComponent.h"
|
|
||||||
#include "Gas/BusyAttributeSet.h"
|
|
||||||
#include "GameplayTagContainer.h"
|
|
||||||
#include "GameAsset/BusyItem.h"
|
|
||||||
#include "BusyLevelItem.generated.h"
|
|
||||||
|
|
||||||
UENUM(BlueprintType)
|
|
||||||
enum class EBusyItemEffectType: uint8 {
|
|
||||||
Health = 0,
|
|
||||||
Hunger = 1,
|
|
||||||
Speed = 2,
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
UENUM(BlueprintType)
|
|
||||||
enum class EBusyLevelItemType : uint8 {
|
|
||||||
None = 0,
|
|
||||||
Collection = 1,
|
|
||||||
Building = 2,
|
|
||||||
Reward= 3,
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
USTRUCT(BlueprintType)
|
|
||||||
struct FBusyLevelItemResourceConfig : public FTableRowBase { // 物品资源表
|
|
||||||
GENERATED_BODY()
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, DisplayName = "物品图标资源")
|
|
||||||
TObjectPtr<UTexture2D> IconResource;
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, DisplayName = "物品静态资源")
|
|
||||||
TObjectPtr<UPaperFlipbook> StaticResource;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
USTRUCT(BlueprintType)
|
|
||||||
struct FBusyLevelItemGenerateConfig {
|
|
||||||
GENERATED_BODY()
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, DisplayName = "每个周期生成物品的数量")
|
|
||||||
int CountOfPeriod;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
UCLASS()
|
|
||||||
class BUSYRABBIT_API ABusyLevelItem : public ALuaActor
|
|
||||||
{
|
|
||||||
GENERATED_BODY()
|
|
||||||
public:
|
|
||||||
ABusyLevelItem();
|
|
||||||
|
|
||||||
public:
|
|
||||||
virtual void OnConstruction(const FTransform& Transform) override;
|
|
||||||
|
|
||||||
virtual void BeginPlay() override;
|
|
||||||
|
|
||||||
virtual void EndPlay(const EEndPlayReason::Type EndPlayReason)override;
|
|
||||||
|
|
||||||
virtual void PostLuaHook() override;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void InitCapsule();
|
|
||||||
void InitSprite();
|
|
||||||
void InitPickBar();
|
|
||||||
|
|
||||||
void SetItemDisplay(const FName &ItemID);
|
|
||||||
|
|
||||||
|
|
||||||
public:
|
|
||||||
UPROPERTY(EditDefaultsOnly, BlueprintReadWrite)
|
|
||||||
TObjectPtr<class UCapsuleComponent> CapsuleComp;
|
|
||||||
|
|
||||||
UPROPERTY(EditDefaultsOnly, BlueprintReadWrite)
|
|
||||||
TObjectPtr<class USceneComponent> SceneComp;
|
|
||||||
|
|
||||||
UPROPERTY(EditDefaultsOnly, BlueprintReadWrite)
|
|
||||||
TObjectPtr<class UPaperFlipbookComponent> Sprite;
|
|
||||||
|
|
||||||
UPROPERTY(EditDefaultsOnly, BlueprintReadWrite)
|
|
||||||
TObjectPtr<class UBusyAbilitySystemComponent> AbilityComponent; // 技能组件
|
|
||||||
|
|
||||||
UPROPERTY(EditDefaultsOnly, BlueprintReadWrite)
|
|
||||||
TObjectPtr<class UWidgetComponent> PickBar;
|
|
||||||
|
|
||||||
public:
|
|
||||||
UPROPERTY(EditAnyWhere, BlueprintReadOnly)
|
|
||||||
FName CurrentItemID;
|
|
||||||
|
|
||||||
public: // 提供给蓝图的接口
|
|
||||||
UFUNCTION(BlueprintCallable)
|
|
||||||
void SetLevelItemID(const FName& ItemID);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
UPROPERTY(BlueprintReadOnly)
|
|
||||||
FBusyLevelItemConfig LevelItemConfig;
|
|
||||||
|
|
||||||
UPROPERTY()
|
|
||||||
TObjectPtr<UBusyLevelItemAttributeSet> LevelItemAttribute;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
bool bIsBeginPlay;
|
|
||||||
|
|
||||||
public: // 需要蓝图实现的函数
|
|
||||||
// LevelItem被设置时的回调
|
|
||||||
UFUNCTION(BlueprintImplementableEvent)
|
|
||||||
void ReceiveLevelItemSetted(const FBusyLevelItemConfig& Config);
|
|
||||||
};
|
|
||||||
@ -1,57 +0,0 @@
|
|||||||
// Fill out your copyright notice in the Description page of Project Settings.
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "CoreMinimal.h"
|
|
||||||
#include "LuaActor.h"
|
|
||||||
#include "Engine/Datatable.h"
|
|
||||||
#include "GameplayTagContainer.h"
|
|
||||||
#include "Core/BusyLuaActorComponent.h"
|
|
||||||
#include "LevelItemReward.generated.h"
|
|
||||||
|
|
||||||
|
|
||||||
USTRUCT(BlueprintType)
|
|
||||||
struct FLevelItemRewardConfig : public FTableRowBase {
|
|
||||||
GENERATED_BODY()
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, DisplayName = "道具备注")
|
|
||||||
FString Comment;
|
|
||||||
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, DisplayName = "物品标签列表")
|
|
||||||
FGameplayTagContainer TypeTagContainer;
|
|
||||||
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, DisplayName = "使用后能带来的效果")
|
|
||||||
TMap<FGameplayTag, float> GameplayEffects;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
UCLASS()
|
|
||||||
class BUSYRABBIT_API ALevelItemReward : public ALuaActor
|
|
||||||
{
|
|
||||||
GENERATED_BODY()
|
|
||||||
public:
|
|
||||||
ALevelItemReward();
|
|
||||||
|
|
||||||
public:
|
|
||||||
virtual void OnConstruction(const FTransform& Transform) override;
|
|
||||||
|
|
||||||
|
|
||||||
protected:
|
|
||||||
UPROPERTY(EditDefaultsOnly, BlueprintReadWrite)
|
|
||||||
TObjectPtr<class UCapsuleComponent> CapsuleComp;
|
|
||||||
|
|
||||||
UPROPERTY(EditDefaultsOnly, BlueprintReadWrite)
|
|
||||||
TObjectPtr<class USceneComponent> SceneComp;
|
|
||||||
|
|
||||||
UPROPERTY(EditDefaultsOnly, BlueprintReadWrite)
|
|
||||||
TObjectPtr<class UPaperFlipbookComponent> Sprite;
|
|
||||||
|
|
||||||
public:
|
|
||||||
UFUNCTION(BlueprintCallable)
|
|
||||||
void SetRewardID(const FName& CurrentRewardID);
|
|
||||||
|
|
||||||
public:
|
|
||||||
UPROPERTY(EditAnyWhere, BlueprintReadOnly)
|
|
||||||
FName RewardID;
|
|
||||||
};
|
|
||||||
@ -1,148 +0,0 @@
|
|||||||
// Fill out your copyright notice in the Description page of Project Settings.
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "slua.h"
|
|
||||||
#include "CoreMinimal.h"
|
|
||||||
#include "LuaPawn.h"
|
|
||||||
#include "Engine/Datatable.h"
|
|
||||||
#include "Gas/BusyAttributeSet.h"
|
|
||||||
#include "AbilitySystemComponent.h"
|
|
||||||
#include "BusyRole.generated.h"
|
|
||||||
|
|
||||||
|
|
||||||
UENUM(BlueprintType)
|
|
||||||
enum class EBusyRoleState : uint8{
|
|
||||||
BonfireIdle, // 篝火旁闲置
|
|
||||||
Searching, // 外出搜索物品
|
|
||||||
Picking, // 正在与物品交互
|
|
||||||
PickFinished, // 与物品交互完毕
|
|
||||||
BackBonfire, // 返回篝火
|
|
||||||
};
|
|
||||||
|
|
||||||
USTRUCT(BlueprintType)
|
|
||||||
struct FBusyRoleConfig: public FTableRowBase {
|
|
||||||
GENERATED_BODY()
|
|
||||||
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, DisplayName = "角色的生命值")
|
|
||||||
int32 Health;
|
|
||||||
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, DisplayName = "角色的饥饿值")
|
|
||||||
int32 Hunger;
|
|
||||||
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, DisplayName = "角色饥饿值消耗速度")
|
|
||||||
int HungerConsumeSpeed;
|
|
||||||
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, DisplayName = "角色生命值消耗速度")
|
|
||||||
int HealthConsumeSpeed;
|
|
||||||
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, DisplayName = "角色的采集效率")
|
|
||||||
int PickEffect;
|
|
||||||
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, DisplayName = "角色的移动速度")
|
|
||||||
int MoveSpeed;
|
|
||||||
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, DisplayName = "角色的技能列表")
|
|
||||||
TArray<TSubclassOf<UGameplayAbility>> DefaultAbilities;
|
|
||||||
};
|
|
||||||
|
|
||||||
USTRUCT(BlueprintType)
|
|
||||||
struct FBusyRoleResourceConfig : public FTableRowBase {
|
|
||||||
GENERATED_BODY()
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, DisplayName = "角色头像图标")
|
|
||||||
int32 Health;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
UCLASS()
|
|
||||||
class BUSYRABBIT_API ABusyRole : public ALuaPawn{
|
|
||||||
GENERATED_BODY()
|
|
||||||
public:
|
|
||||||
ABusyRole();
|
|
||||||
virtual void BeginPlay()override;
|
|
||||||
virtual void Tick(float InDeltaSeconds)override;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
UPROPERTY(EditDefaultsOnly, BlueprintReadWrite)
|
|
||||||
TObjectPtr<class USceneComponent> SceneComp;
|
|
||||||
|
|
||||||
UPROPERTY(EditDefaultsOnly, BlueprintReadWrite)
|
|
||||||
TObjectPtr<class USpringArmComponent> SpringArmComp;
|
|
||||||
|
|
||||||
UPROPERTY(EditDefaultsOnly, BlueprintReadWrite)
|
|
||||||
TObjectPtr<class UCapsuleComponent> CapsuleComp;
|
|
||||||
|
|
||||||
UPROPERTY(EditDefaultsOnly, BlueprintReadWrite)
|
|
||||||
TObjectPtr<class UBusyCameraComponent> CameraComp;
|
|
||||||
|
|
||||||
UPROPERTY(EditDefaultsOnly, BlueprintReadWrite)
|
|
||||||
TObjectPtr<class UPaperFlipbookComponent> Sprite;
|
|
||||||
|
|
||||||
UPROPERTY(EditDefaultsOnly, BlueprintReadWrite)
|
|
||||||
TObjectPtr<class UBusyRoleMovement> Movement; // 移动组件
|
|
||||||
|
|
||||||
UPROPERTY(EditDefaultsOnly, BlueprintReadWrite)
|
|
||||||
TObjectPtr<class UPW_AbilitySystemComponent> RoleAbility; // 技能组件
|
|
||||||
|
|
||||||
UPROPERTY(EditDefaultsOnly, BlueprintReadWrite)
|
|
||||||
TObjectPtr<class UInventoryComponent> Inventory; // 仓库组件
|
|
||||||
|
|
||||||
UPROPERTY(BlueprintReadWrite)
|
|
||||||
TObjectPtr<class URoleAnimation> RoleAnimation;
|
|
||||||
|
|
||||||
public: // 蓝图接口
|
|
||||||
UFUNCTION(BlueprintCallable)
|
|
||||||
void SetRole(const FName& Name);
|
|
||||||
|
|
||||||
UFUNCTION(BlueprintCallable)
|
|
||||||
void TryActiveAbility(const FName& TagName, const FGameplayEventData& EventData);
|
|
||||||
|
|
||||||
public:
|
|
||||||
// 输入相关
|
|
||||||
UPROPERTY(EditDefaultsOnly, Category = "Input")
|
|
||||||
TObjectPtr<class UInputMappingContext> InputMapping;
|
|
||||||
|
|
||||||
UPROPERTY(EditDefaultsOnly, Category = "Input")
|
|
||||||
TObjectPtr<class UInputAction> TouchAction;
|
|
||||||
|
|
||||||
virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent)override;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void InitCapsule();
|
|
||||||
|
|
||||||
public: // 蓝图实现
|
|
||||||
UFUNCTION(BlueprintImplementableEvent)
|
|
||||||
void OnTouch(const FInputActionValue& Value) const;
|
|
||||||
|
|
||||||
UFUNCTION(BlueprintImplementableEvent)
|
|
||||||
void OnOverlapBegin(
|
|
||||||
UPrimitiveComponent* OverlappedComp,
|
|
||||||
AActor* OtherActor,
|
|
||||||
UPrimitiveComponent* OtherComp,
|
|
||||||
int32 OtherBodyIndex,
|
|
||||||
bool bFromSweep,
|
|
||||||
const FHitResult& SweepResult
|
|
||||||
);
|
|
||||||
|
|
||||||
UFUNCTION(BlueprintImplementableEvent)
|
|
||||||
void ReceiveSetRole(const FBusyRoleConfig& RoleTableConfig);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
FTimerHandle TimerHandle;
|
|
||||||
|
|
||||||
public: // 角色属性
|
|
||||||
UPROPERTY(BlueprintReadOnly)
|
|
||||||
FName RoleName;
|
|
||||||
UPROPERTY(BlueprintReadOnly, Category = "Value")
|
|
||||||
FBusyRoleConfig RoleConfig;
|
|
||||||
|
|
||||||
private:
|
|
||||||
UPROPERTY()
|
|
||||||
TObjectPtr<UBusyRoleAttributeSet> RoleAttribute;
|
|
||||||
|
|
||||||
public: // 不暴露给蓝图的属性
|
|
||||||
|
|
||||||
};
|
|
||||||
@ -1,43 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "CoreMinimal.h"
|
|
||||||
#include "LuaOverriderInterface.h"
|
|
||||||
#include "LuaActorComponent.h"
|
|
||||||
#include "GameFramework/MovementComponent.h"
|
|
||||||
#include "BusyRoleMovement.generated.h"
|
|
||||||
|
|
||||||
|
|
||||||
UENUM(BlueprintType)
|
|
||||||
enum class ERoleMoveDirection: uint8 {
|
|
||||||
Move_Right,
|
|
||||||
Move_Left,
|
|
||||||
Move_All_Cnt
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
UCLASS()
|
|
||||||
class BUSYRABBIT_API UBusyRoleMovement : public ULuaActorComponent
|
|
||||||
{
|
|
||||||
GENERATED_BODY()
|
|
||||||
|
|
||||||
public:
|
|
||||||
UBusyRoleMovement();
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
public:
|
|
||||||
virtual void BeginPlay()override;
|
|
||||||
|
|
||||||
UFUNCTION(BlueprintImplementableEvent)
|
|
||||||
void ReceiveComponentTick(float DeltaTime);
|
|
||||||
|
|
||||||
UFUNCTION(BlueprintImplementableEvent)
|
|
||||||
void ReceiveComponentBeginPlay();
|
|
||||||
|
|
||||||
virtual void TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)override;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
FVector MovementDirection;
|
|
||||||
};
|
|
||||||
@ -1,77 +0,0 @@
|
|||||||
// Fill out your copyright notice in the Description page of Project Settings.
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "CoreMinimal.h"
|
|
||||||
#include "LuaActorComponent.h"
|
|
||||||
#include "Engine/Datatable.h"
|
|
||||||
#include "PaperFlipbookComponent.h"
|
|
||||||
#include "BusyRoleMovement.h"
|
|
||||||
#include "../Core/BusyLuaActorComponent.h"
|
|
||||||
#include "RoleAnimation.generated.h"
|
|
||||||
|
|
||||||
DECLARE_LOG_CATEGORY_EXTERN(LogRoleAnimation, Log, All);
|
|
||||||
|
|
||||||
UENUM(BlueprintType)
|
|
||||||
enum class EBusyAnimationPhase : uint8{
|
|
||||||
PrepareCast, // 动作前摇阶段
|
|
||||||
Casting, // 动作释放阶段
|
|
||||||
PostCast, // 动作后摇阶段
|
|
||||||
};
|
|
||||||
|
|
||||||
USTRUCT(BlueprintType)
|
|
||||||
struct FBusyAnimationPhaseData : public FTableRowBase {
|
|
||||||
GENERATED_BODY()
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, DisplayName = "各个阶段的动作")
|
|
||||||
TMap<EBusyAnimationPhase, UPaperFlipbook*> PhaseAnimation;
|
|
||||||
};
|
|
||||||
|
|
||||||
USTRUCT(BlueprintType)
|
|
||||||
struct FBusyRolePickingAnimationData : public FTableRowBase {
|
|
||||||
GENERATED_BODY()
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, DisplayName = "各个方向的采集动作")
|
|
||||||
TMap<ERoleMoveDirection, FBusyAnimationPhaseData> DirectionAnimations;
|
|
||||||
};
|
|
||||||
|
|
||||||
USTRUCT(BlueprintType)
|
|
||||||
struct FBusyRoleAnimationData : public FTableRowBase {
|
|
||||||
GENERATED_BODY()
|
|
||||||
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, DisplayName = "移动时的动作")
|
|
||||||
TMap<ERoleMoveDirection, UPaperFlipbook*> MoveAnimations;
|
|
||||||
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, DisplayName = "静止时的动作")
|
|
||||||
TMap<ERoleMoveDirection, UPaperFlipbook*> IdleAnimations;
|
|
||||||
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, DisplayName = "采集物品时的动作")
|
|
||||||
TMap<FName, FBusyRolePickingAnimationData> PickingAnimations;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
UCLASS()
|
|
||||||
class BUSYRABBIT_API URoleAnimation : public UBusyLuaActorComponent
|
|
||||||
{
|
|
||||||
GENERATED_BODY()
|
|
||||||
public:
|
|
||||||
URoleAnimation();
|
|
||||||
|
|
||||||
public:
|
|
||||||
UFUNCTION(BlueprintCallable)
|
|
||||||
void SetMoveAnimation(ERoleMoveDirection direction);
|
|
||||||
|
|
||||||
UFUNCTION(BlueprintCallable)
|
|
||||||
void SetIdleAnimation(ERoleMoveDirection direction);
|
|
||||||
|
|
||||||
UFUNCTION(BlueprintCallable)
|
|
||||||
void PlayPickAnimation(const FName& ItemName, ERoleMoveDirection Direction, EBusyAnimationPhase Phase, float PlayRate);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
bool GetOwnerRoleInfo(UPaperFlipbookComponent* &Sprite, FBusyRoleAnimationData* &AnimationData);
|
|
||||||
|
|
||||||
// 设置表格里面的动作
|
|
||||||
void SetRoleAnimation(UPaperFlipbookComponent* Sprite, UPaperFlipbook** Anim);
|
|
||||||
|
|
||||||
void PlayAnimationOnce(UPaperFlipbookComponent* Sprite, UPaperFlipbook** Anim, float PlayRate);
|
|
||||||
};
|
|
||||||
Reference in New Issue
Block a user