mirror of
https://github.com/FlightControl-Master/MOOSE.git
synced 2025-10-29 16:58:06 +00:00
Warehouse and other things
This commit is contained in:
@@ -51,34 +51,41 @@ function AI_CARGO_AIRPLANE:New( Airplane, CargoSet )
|
||||
--- Pickup Handler OnBefore for AI_CARGO_AIRPLANE
|
||||
-- @function [parent=#AI_CARGO_AIRPLANE] OnBeforePickup
|
||||
-- @param #AI_CARGO_AIRPLANE self
|
||||
-- @param #string From
|
||||
-- @param #string Event
|
||||
-- @param #string To
|
||||
-- @param Wrapper.Group#GROUP Airplane Cargo transport plane.
|
||||
-- @param #string From From state.
|
||||
-- @param #string Event Event.
|
||||
-- @param #string To To state.
|
||||
-- @param Wrapper.Airbase#AIRBASE Airbase Airbase where troops are picked up.
|
||||
-- @param #number Speed in km/h for travelling to pickup base.
|
||||
-- @return #boolean
|
||||
|
||||
--- Pickup Handler OnAfter for AI_CARGO_AIRPLANE
|
||||
-- @function [parent=#AI_CARGO_AIRPLANE] OnAfterPickup
|
||||
-- @param #AI_CARGO_AIRPLANE self
|
||||
-- @param Wrapper.Group#GROUP Airplane Cargo plane.
|
||||
-- @param #string From
|
||||
-- @param #string Event
|
||||
-- @param #string To
|
||||
-- @param Wrapper.Airbase#AIRBASE Airbase Airbase where troops are picked up.
|
||||
-- @param #number Speed in km/h for travelling to pickup base.
|
||||
|
||||
--- Pickup Trigger for AI_CARGO_AIRPLANE
|
||||
-- @function [parent=#AI_CARGO_AIRPLANE] Pickup
|
||||
-- @param #AI_CARGO_AIRPLANE self
|
||||
-- @param Wrapper.Airbase#AIRBASE Airbase Airbase where troops are picked up.
|
||||
-- @param #number Speed in km/h for travelling to pickup base.
|
||||
|
||||
--- Pickup Asynchronous Trigger for AI_CARGO_AIRPLANE
|
||||
-- @function [parent=#AI_CARGO_AIRPLANE] __Pickup
|
||||
-- @param #AI_CARGO_AIRPLANE self
|
||||
-- @param #number Delay Delay in seconds.
|
||||
-- @param Wrapper.Airbase#AIRBASE Airbase Airbase where troops are picked up.
|
||||
-- @param #number Speed in km/h for travelling to pickup base.
|
||||
|
||||
--- Deploy Handler OnBefore for AI_CARGO_AIRPLANE
|
||||
-- @function [parent=#AI_CARGO_AIRPLANE] OnBeforeDeploy
|
||||
-- @param #AI_CARGO_AIRPLANE self
|
||||
-- @param Wrapper.Group#GROUP Airplane Cargo plane.
|
||||
-- @param #string From
|
||||
-- @param #string Event
|
||||
-- @param #string To
|
||||
@@ -89,6 +96,7 @@ function AI_CARGO_AIRPLANE:New( Airplane, CargoSet )
|
||||
--- Deploy Handler OnAfter for AI_CARGO_AIRPLANE
|
||||
-- @function [parent=#AI_CARGO_AIRPLANE] OnAfterDeploy
|
||||
-- @param #AI_CARGO_AIRPLANE self
|
||||
-- @param Wrapper.Group#GROUP Airplane Cargo plane.
|
||||
-- @param #string From
|
||||
-- @param #string Event
|
||||
-- @param #string To
|
||||
@@ -107,7 +115,16 @@ function AI_CARGO_AIRPLANE:New( Airplane, CargoSet )
|
||||
-- @param #number Delay Delay in seconds.
|
||||
-- @param Wrapper.Airbase#AIRBASE Airbase Destination airbase where troops are deployed.
|
||||
-- @param #number Speed Speed in km/h for travelling to deploy base.
|
||||
|
||||
--- On after Loaded event, i.e. triggered when the cargo is inside the carrier.
|
||||
-- @function [parent=#AI_CARGO_AIRPLANE] OnAfterLoaded
|
||||
-- @param #AI_CARGO_AIRPLANE self
|
||||
-- @param Wrapper.Group#GROUP Airplane Cargo plane.
|
||||
-- @param From
|
||||
-- @param Event
|
||||
-- @param To
|
||||
|
||||
-- Set carrier.
|
||||
self:SetCarrier( Airplane )
|
||||
|
||||
return self
|
||||
@@ -126,10 +143,10 @@ end
|
||||
|
||||
|
||||
|
||||
--- Set the Carrier.
|
||||
--- Set the Carrier (controllable). Also initializes events for carrier and defines the coalition.
|
||||
-- @param #AI_CARGO_AIRPLANE self
|
||||
-- @param Wrapper.Group#GROUP Airplane
|
||||
-- @return #AI_CARGO_AIRPLANE
|
||||
-- @param Wrapper.Group#GROUP Airplane Transport plane.
|
||||
-- @return #AI_CARGO_AIRPLANE self
|
||||
function AI_CARGO_AIRPLANE:SetCarrier( Airplane )
|
||||
|
||||
local AICargo = self
|
||||
@@ -184,7 +201,7 @@ end
|
||||
|
||||
--- Find a free Carrier within a range.
|
||||
-- @param #AI_CARGO_AIRPLANE self
|
||||
-- @param Wrapper.Airbase#AIRBASE Airbase
|
||||
-- @param Wrapper.Airbase#AIRBASE Airbase
|
||||
-- @param #number Radius
|
||||
-- @return Wrapper.Group#GROUP NewCarrier
|
||||
function AI_CARGO_AIRPLANE:FindCarrier( Coordinate, Radius )
|
||||
@@ -206,9 +223,9 @@ function AI_CARGO_AIRPLANE:FindCarrier( Coordinate, Radius )
|
||||
|
||||
end
|
||||
|
||||
--- On after "Landed" event. Called on engine shutdown.
|
||||
--- On after "Landed" event. Called on engine shutdown and initiates the pickup mission or unloading event.
|
||||
-- @param #AI_CARGO_AIRPLANE self
|
||||
-- @param Wrapper.Group#GROUP Airplane Transport plane.
|
||||
-- @param Wrapper.Group#GROUP Airplane Cargo transport plane.
|
||||
-- @param From
|
||||
-- @param Event
|
||||
-- @param To
|
||||
@@ -220,11 +237,13 @@ function AI_CARGO_AIRPLANE:onafterLanded( Airplane, From, Event, To )
|
||||
|
||||
if Airplane and Airplane:IsAlive() then
|
||||
|
||||
-- Aircraft was sent to this airbase to pickup troops. Initiate loadling.
|
||||
if self.RoutePickup == true then
|
||||
self:Load( Airplane:GetPointVec2() )
|
||||
self.RoutePickup = false
|
||||
end
|
||||
|
||||
-- Aircraft was send to this airbase to deploy troops. Initiate unloading.
|
||||
if self.RouteDeploy == true then
|
||||
self:Unload()
|
||||
self.RouteDeploy = false
|
||||
@@ -237,48 +256,66 @@ end
|
||||
|
||||
--- On after "Pickup" event. Routes transport to pickup airbase.
|
||||
-- @param #AI_CARGO_AIRPLANE self
|
||||
-- @param Wrapper.Group#GROUP Airplane
|
||||
-- @param From
|
||||
-- @param Event
|
||||
-- @param To
|
||||
-- @param Wrapper.Airbase#AIRBASE Airbase
|
||||
-- @param #number Speed
|
||||
-- @param Wrapper.Group#GROUP Airplane Cargo transport plane.
|
||||
-- @param #string From From state.
|
||||
-- @param #string Event Event.
|
||||
-- @param #string To To state.
|
||||
-- @param Wrapper.Airbase#AIRBASE Airbase Airbase where the troops as picked up.
|
||||
-- @param #number Speed in km/h for travelling to pickup base.
|
||||
function AI_CARGO_AIRPLANE:onafterPickup( Airplane, From, Event, To, Airbase, Speed )
|
||||
|
||||
if Airplane and Airplane:IsAlive() then
|
||||
|
||||
-- Aircraft might be on the ground of the pickup airbase already.
|
||||
-- Two cases. Aircraft spawned in air or at an airbase.
|
||||
if Airplane:InAir() then
|
||||
self:Route( Airplane, Airbase, Speed )
|
||||
self.Airbase=nil
|
||||
else
|
||||
self.Airbase=Airplane:GetCoordinate():GetClosestAirbase()
|
||||
end
|
||||
-- TODO: Improve :Route() so that the aircraft can be routed from another airbase to the pickup airbase.
|
||||
|
||||
self.RoutePickup = true
|
||||
|
||||
-- Route aircraft to pickup airbase.
|
||||
self:Route( Airplane, Airbase, Speed )
|
||||
|
||||
-- Set airbase as starting point in the next Route() call.
|
||||
self.Airbase = Airbase
|
||||
|
||||
-- Aircraft is on a pickup mission.
|
||||
self.RoutePickup = true
|
||||
|
||||
-- Unclear!?
|
||||
self.Transporting = true
|
||||
self.Relocating = false
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
--- On after Depoly event. Routes plane to deploy airbase.
|
||||
--- On after Depoly event. Routes plane to the airbase where the troops are deployed.
|
||||
-- @param #AI_CARGO_AIRPLANE self
|
||||
-- @param Wrapper.Group#GROUP Airplane
|
||||
-- @param From
|
||||
-- @param Event
|
||||
-- @param To
|
||||
-- @param Wrapper.Group#GROUP Airplane Cargo transport plane.
|
||||
-- @param #string From From state.
|
||||
-- @param #string Event Event.
|
||||
-- @param #string To To state.
|
||||
-- @param Wrapper.Airbase#AIRBASE Airbase Airbase where troups should be deployed.
|
||||
-- @param #number Speed Speed in km/h for travelling to deploy base.
|
||||
function AI_CARGO_AIRPLANE:onafterDeploy( Airplane, From, Event, To, Airbase, Speed )
|
||||
|
||||
if Airplane and Airplane:IsAlive() then
|
||||
|
||||
-- Route to
|
||||
if Airplane and Airplane:IsAlive()~=nil then
|
||||
|
||||
-- Activate uncontrolled airplane.
|
||||
if Airplane:IsAlive()==false then
|
||||
Airplane:SetCommand({id = 'Start', params = {}})
|
||||
end
|
||||
|
||||
-- Route to destination airbase.
|
||||
self:Route( Airplane, Airbase, Speed )
|
||||
|
||||
-- Aircraft is on a depoly mission.
|
||||
self.RouteDeploy = true
|
||||
|
||||
-- Set destination airbase for next :Route() command.
|
||||
self.Airbase = Airbase
|
||||
|
||||
-- Unclear?!
|
||||
self.Transporting = false
|
||||
self.Relocating = false
|
||||
end
|
||||
@@ -286,17 +323,16 @@ function AI_CARGO_AIRPLANE:onafterDeploy( Airplane, From, Event, To, Airbase, Sp
|
||||
end
|
||||
|
||||
|
||||
--- On after Load event.
|
||||
--- On after Load event. Checks if cargo is inside the load radius and if so starts the boarding process.
|
||||
-- @param #AI_CARGO_AIRPLANE self
|
||||
-- @param Wrapper.Group#GROUP Airplane Transport plane.
|
||||
-- @param From
|
||||
-- @param Event
|
||||
-- @param To
|
||||
-- @param Wrapper.Point#COORDINATE Coordinate
|
||||
-- @param #string From From state.
|
||||
-- @param #string Event Event.
|
||||
-- @param #string To To state.
|
||||
-- @param Wrapper.Point#COORDINATE Coordinate Place where the cargo is guided to if it is inside the load radius.
|
||||
function AI_CARGO_AIRPLANE:onafterLoad( Airplane, From, Event, To, Coordinate )
|
||||
|
||||
if Airplane and Airplane:IsAlive()==true or Airplane:IsAlive()==false then
|
||||
--if Airplane then
|
||||
if Airplane and Airplane:IsAlive()~=nil then
|
||||
|
||||
for _, Cargo in pairs( self.CargoSet:GetSet() ) do
|
||||
self:F({Cargo:GetName()})
|
||||
@@ -313,12 +349,12 @@ function AI_CARGO_AIRPLANE:onafterLoad( Airplane, From, Event, To, Coordinate )
|
||||
|
||||
end
|
||||
|
||||
--- On after Board event.
|
||||
--- On after Board event. Cargo is inside the load radius and boarding is performed.
|
||||
-- @param #AI_CARGO_AIRPLANE self
|
||||
-- @param Wrapper.Group#GROUP Airplane Cargo plane.
|
||||
-- @param From
|
||||
-- @param Event
|
||||
-- @param To
|
||||
-- @param Wrapper.Group#GROUP Airplane Cargo transport plane.
|
||||
-- @param #string From From state.
|
||||
-- @param #string Event Event.
|
||||
-- @param #string To To state.
|
||||
function AI_CARGO_AIRPLANE:onafterBoard( Airplane, From, Event, To )
|
||||
|
||||
if Airplane and Airplane:IsAlive() then
|
||||
@@ -332,26 +368,28 @@ function AI_CARGO_AIRPLANE:onafterBoard( Airplane, From, Event, To )
|
||||
|
||||
end
|
||||
|
||||
--- On after Loaded event.
|
||||
--- On after Loaded event. Cargo is inside the carrier and ready to be transported.
|
||||
-- @param #AI_CARGO_AIRPLANE self
|
||||
-- @param Wrapper.Group#GROUP Airplane Cargo plane.
|
||||
-- @param From
|
||||
-- @param Event
|
||||
-- @param To
|
||||
-- @param Wrapper.Group#GROUP Airplane Cargo transport plane.
|
||||
-- @param #string From From state.
|
||||
-- @param #string Event Event.
|
||||
-- @param #string To To state.
|
||||
function AI_CARGO_AIRPLANE:onafterLoaded( Airplane, From, Event, To )
|
||||
|
||||
env.info("FF troops loaded into cargo plane")
|
||||
|
||||
if Airplane and Airplane:IsAlive() then
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
--- On after Unload event.
|
||||
--- On after Unload event. Cargo is beeing unloaded, i.e. the unboarding process is started.
|
||||
-- @param #AI_CARGO_AIRPLANE self
|
||||
-- @param Wrapper.Group#GROUP Airplane Cargo plane.
|
||||
-- @param From
|
||||
-- @param Event
|
||||
-- @param To
|
||||
-- @param Wrapper.Group#GROUP Airplane Cargo transport plane.
|
||||
-- @param #string From From state.
|
||||
-- @param #string Event Event.
|
||||
-- @param #string To To state.
|
||||
function AI_CARGO_AIRPLANE:onafterUnload( Airplane, From, Event, To )
|
||||
|
||||
if Airplane and Airplane:IsAlive() then
|
||||
@@ -361,12 +399,12 @@ function AI_CARGO_AIRPLANE:onafterUnload( Airplane, From, Event, To )
|
||||
|
||||
end
|
||||
|
||||
--- On after Unboard event.
|
||||
--- On after Unboard event. Checks if unboarding process is finished.
|
||||
-- @param #AI_CARGO_AIRPLANE self
|
||||
-- @param Wrapper.Group#GROUP Airplane Cargo plane.
|
||||
-- @param From
|
||||
-- @param Event
|
||||
-- @param To
|
||||
-- @param Wrapper.Group#GROUP Airplane Cargo transport plane.
|
||||
-- @param #string From From state.
|
||||
-- @param #string Event Event.
|
||||
-- @param #string To To state.
|
||||
function AI_CARGO_AIRPLANE:onafterUnboard( Airplane, From, Event, To )
|
||||
|
||||
if Airplane and Airplane:IsAlive() then
|
||||
@@ -379,12 +417,12 @@ function AI_CARGO_AIRPLANE:onafterUnboard( Airplane, From, Event, To )
|
||||
|
||||
end
|
||||
|
||||
--- On after Unloaded event.
|
||||
--- On after Unloaded event. Cargo has been unloaded, i.e. the unboarding process is finished.
|
||||
-- @param #AI_CARGO_AIRPLANE self
|
||||
-- @param Wrapper.Group#GROUP Airplane Cargo plane.
|
||||
-- @param From
|
||||
-- @param Event
|
||||
-- @param To
|
||||
-- @param Wrapper.Group#GROUP Airplane Cargo transport plane.
|
||||
-- @param #string From From state.
|
||||
-- @param #string Event Event.
|
||||
-- @param #string To To state.
|
||||
function AI_CARGO_AIRPLANE:onafterUnloaded( Airplane, From, Event, To )
|
||||
|
||||
if Airplane and Airplane:IsAlive() then
|
||||
@@ -393,119 +431,75 @@ function AI_CARGO_AIRPLANE:onafterUnloaded( Airplane, From, Event, To )
|
||||
|
||||
end
|
||||
|
||||
--- Route the airplane from one airport or it's current position to another airbase.
|
||||
-- @param #AI_CARGO_AIRPLANE self
|
||||
-- @param Wrapper.Group#GROUP Airplane Airplane group to be routed.
|
||||
-- @param Wrapper.Airbase#AIRBASE Airbase Destination airbase.
|
||||
-- @param #number Speed Speed in km/h. Default is 80% of max possible speed the group can do.
|
||||
-- @param #boolean Uncontrolled If true, spawn group in uncontrolled state.
|
||||
function AI_CARGO_AIRPLANE:Route( Airplane, Airbase, Speed, Uncontrolled )
|
||||
|
||||
--- @param #AI_CARGO_AIRPLANE self
|
||||
-- @param Wrapper.Group#GROUP Airplane
|
||||
-- @param Wrapper.Airbase#AIRBASE Airbase
|
||||
-- @param #number Speed
|
||||
function AI_CARGO_AIRPLANE:Route( Airplane, Airbase, Speed )
|
||||
if Airplane and Airplane:IsAlive()~=nil then
|
||||
|
||||
if Airplane and Airplane:IsAlive() then
|
||||
|
||||
local PointVec3 = Airplane:GetPointVec3()
|
||||
|
||||
local Takeoff = SPAWN.Takeoff.Hot
|
||||
-- Set takeoff type.
|
||||
local Takeoff = SPAWN.Takeoff.Cold
|
||||
|
||||
-- Get template of group.
|
||||
local Template = Airplane:GetTemplate()
|
||||
|
||||
if Template then
|
||||
|
||||
local Points = {}
|
||||
|
||||
if self.Airbase then
|
||||
|
||||
local FromWaypoint = Template.route.points[1]
|
||||
|
||||
-- These are only for ships.
|
||||
FromWaypoint.linkUnit = nil
|
||||
FromWaypoint.helipadId = nil
|
||||
FromWaypoint.airdromeId = nil
|
||||
|
||||
local ParkingSpots = self.Airbase:FindFreeParkingSpotForAircraft( Airplane, AIRBASE.TerminalType.OpenBig )
|
||||
local AirbaseID = self.Airbase:GetID()
|
||||
local AirbaseCategory = self.Airbase:GetDesc().category
|
||||
|
||||
FromWaypoint.airdromeId = AirbaseID
|
||||
|
||||
FromWaypoint.alt = 0
|
||||
|
||||
FromWaypoint.type = GROUPTEMPLATE.Takeoff[Takeoff][1] -- type
|
||||
FromWaypoint.action = GROUPTEMPLATE.Takeoff[Takeoff][2] -- action
|
||||
|
||||
|
||||
-- Translate the position of the Group Template to the Vec3.
|
||||
for UnitID = 1, #Template.units do
|
||||
self:T( 'Before Translation SpawnTemplate.units['..UnitID..'].x = ' .. Template.units[UnitID].x .. ', SpawnTemplate.units['..UnitID..'].y = ' .. Template.units[UnitID].y )
|
||||
|
||||
-- These cause a lot of confusion.
|
||||
local UnitTemplate = Template.units[UnitID]
|
||||
|
||||
UnitTemplate.parking = nil
|
||||
UnitTemplate.parking_id = nil
|
||||
UnitTemplate.alt = 0
|
||||
|
||||
local SX = UnitTemplate.x
|
||||
local SY = UnitTemplate.y
|
||||
local BX = FromWaypoint.x
|
||||
local BY = FromWaypoint.y
|
||||
local TX = PointVec3.x + ( SX - BX )
|
||||
local TY = PointVec3.z + ( SY - BY )
|
||||
|
||||
UnitTemplate.x = TX
|
||||
UnitTemplate.y = TY
|
||||
|
||||
self:T( 'After Translation SpawnTemplate.units['..UnitID..'].x = ' .. UnitTemplate.x .. ', SpawnTemplate.units['..UnitID..'].y = ' .. UnitTemplate.y )
|
||||
end
|
||||
|
||||
FromWaypoint.x = PointVec3.x
|
||||
FromWaypoint.y = PointVec3.z
|
||||
|
||||
Points[#Points+1] = FromWaypoint
|
||||
else
|
||||
|
||||
local GroupPoint = Airplane:GetVec2()
|
||||
local GroupVelocity = Airplane:GetUnit(1):GetDesc().speedMax
|
||||
|
||||
local FromWaypoint = {}
|
||||
FromWaypoint.x = GroupPoint.x
|
||||
FromWaypoint.y = GroupPoint.y
|
||||
FromWaypoint.type = "Turning Point"
|
||||
FromWaypoint.action = "Turning Point"
|
||||
FromWaypoint.speed = GroupVelocity
|
||||
|
||||
Points[#Points+1] = FromWaypoint
|
||||
end
|
||||
|
||||
local AirbasePointVec2 = Airbase:GetPointVec2()
|
||||
local ToWaypoint = AirbasePointVec2:WaypointAir(
|
||||
POINT_VEC3.RoutePointAltType.BARO,
|
||||
"Land",
|
||||
"Landing",
|
||||
Speed or Airplane:GetUnit(1):GetDesc().speedMax
|
||||
)
|
||||
|
||||
ToWaypoint["airdromeId"] = Airbase:GetID()
|
||||
ToWaypoint["speed_locked"] = true,
|
||||
|
||||
self:F( ToWaypoint )
|
||||
|
||||
Points[#Points+1] = ToWaypoint
|
||||
|
||||
Template.x = PointVec3.x
|
||||
Template.y = PointVec3.z
|
||||
|
||||
self:T3( Points )
|
||||
Template.route.points = Points
|
||||
|
||||
Template.uncontrolled=false
|
||||
|
||||
--self:Respawn( Template )
|
||||
|
||||
local GroupSpawned = Airplane:Respawn( Template )
|
||||
|
||||
return GroupSpawned
|
||||
-- Nil check
|
||||
if Template==nil then
|
||||
return
|
||||
end
|
||||
|
||||
end
|
||||
-- Waypoints of the route.
|
||||
local Points={}
|
||||
|
||||
-- To point.
|
||||
local AirbasePointVec2 = Airbase:GetPointVec2()
|
||||
local ToWaypoint = AirbasePointVec2:WaypointAir(
|
||||
POINT_VEC3.RoutePointAltType.BARO,
|
||||
"Land",
|
||||
"Landing",
|
||||
Speed or Airplane:GetSpeedMax()*0.8
|
||||
)
|
||||
ToWaypoint["airdromeId"] = Airbase:GetID()
|
||||
ToWaypoint["speed_locked"] = true
|
||||
|
||||
|
||||
-- If self.Airbase~=nil then group is currently at an airbase, where it should be respawned.
|
||||
if self.Airbase then
|
||||
|
||||
-- Second point of the route. First point is done in RespawnAtCurrentAirbase() routine.
|
||||
Template.route.points[2] = ToWaypoint
|
||||
|
||||
-- Respawn group at the current airbase.
|
||||
Airplane:RespawnAtCurrentAirbase(Template, Takeoff, Uncontrolled)
|
||||
|
||||
else
|
||||
|
||||
-- From point.
|
||||
local GroupPoint = Airplane:GetVec2()
|
||||
local FromWaypoint = {}
|
||||
FromWaypoint.x = GroupPoint.x
|
||||
FromWaypoint.y = GroupPoint.y
|
||||
FromWaypoint.type = "Turning Point"
|
||||
FromWaypoint.action = "Turning Point"
|
||||
FromWaypoint.speed = Airplane:GetSpeedMax()*0.8
|
||||
|
||||
-- The two route points.
|
||||
Points[1] = FromWaypoint
|
||||
Points[2] = ToWaypoint
|
||||
|
||||
local PointVec3 = Airplane:GetPointVec3()
|
||||
Template.x = PointVec3.x
|
||||
Template.y = PointVec3.z
|
||||
|
||||
Template.route.points = Points
|
||||
|
||||
local GroupSpawned = Airplane:Respawn(Template)
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
Reference in New Issue
Block a user