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)