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