113 lines
3.4 KiB
Lua
113 lines
3.4 KiB
Lua
|
|
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)
|