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