mirror of
https://github.com/FlightControl-Master/MOOSE.git
synced 2025-10-29 16:58:06 +00:00
Merge branch 'FF/Ops' into FF/OpsDev
This commit is contained in:
@@ -31,6 +31,7 @@
|
||||
-- * [USS Abraham Lincoln](https://en.wikipedia.org/wiki/USS_Abraham_Lincoln_(CVN-72)) (CVN-72) [Super Carrier Module]
|
||||
-- * [USS George Washington](https://en.wikipedia.org/wiki/USS_George_Washington_(CVN-73)) (CVN-73) [Super Carrier Module]
|
||||
-- * [USS Harry S. Truman](https://en.wikipedia.org/wiki/USS_Harry_S._Truman) (CVN-75) [Super Carrier Module]
|
||||
-- * [USS Forrestal](https://en.wikipedia.org/wiki/USS_Forrestal_(CV-59)) (CV-59) [Heatblur Carrier Module]
|
||||
-- * [USS Tarawa](https://en.wikipedia.org/wiki/USS_Tarawa_(LHA-1)) (LHA-1) [**WIP**]
|
||||
-- * [USS America](https://en.wikipedia.org/wiki/USS_America_(LHA-6)) (LHA-6) [**WIP**]
|
||||
-- * [Juan Carlos I](https://en.wikipedia.org/wiki/Spanish_amphibious_assault_ship_Juan_Carlos_I) (L61) [**WIP**]
|
||||
@@ -1295,6 +1296,7 @@ AIRBOSS.AircraftCarrier={
|
||||
-- @field #string WASHINGTON USS George Washington (CVN-73) [Super Carrier Module]
|
||||
-- @field #string STENNIS USS John C. Stennis (CVN-74)
|
||||
-- @field #string TRUMAN USS Harry S. Truman (CVN-75) [Super Carrier Module]
|
||||
-- @field #string FORRESTAL USS Forrestal (CV-59) [Heatblur Carrier Module]
|
||||
-- @field #string VINSON USS Carl Vinson (CVN-70) [Obsolete]
|
||||
-- @field #string TARAWA USS Tarawa (LHA-1)
|
||||
-- @field #string AMERICA USS America (LHA-6)
|
||||
@@ -1306,6 +1308,7 @@ AIRBOSS.CarrierType={
|
||||
WASHINGTON="CVN_73",
|
||||
TRUMAN="CVN_75",
|
||||
STENNIS="Stennis",
|
||||
FORRESTAL="Forrestal",
|
||||
VINSON="VINSON",
|
||||
TARAWA="LHA_Tarawa",
|
||||
AMERICA="USS America LHA-6",
|
||||
@@ -1723,7 +1726,7 @@ AIRBOSS.MenuF10Root=nil
|
||||
|
||||
--- Airboss class version.
|
||||
-- @field #string version
|
||||
AIRBOSS.version="1.1.6"
|
||||
AIRBOSS.version="1.2.0"
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
-- TODO list
|
||||
@@ -1974,6 +1977,8 @@ function AIRBOSS:New(carriername, alias)
|
||||
self:_InitNimitz()
|
||||
elseif self.carriertype==AIRBOSS.CarrierType.TRUMAN then
|
||||
self:_InitNimitz()
|
||||
elseif self.carriertype==AIRBOSS.CarrierType.FORRESTAL then
|
||||
self:_InitForrestal()
|
||||
elseif self.carriertype==AIRBOSS.CarrierType.VINSON then
|
||||
-- TODO: Carl Vinson parameters.
|
||||
self:_InitStennis()
|
||||
@@ -2041,7 +2046,7 @@ function AIRBOSS:New(carriername, alias)
|
||||
local stern=self:_GetSternCoord()
|
||||
|
||||
-- Bow pos.
|
||||
local bow=stern:Translate(self.carrierparam.totlength, hdg)
|
||||
local bow=stern:Translate(self.carrierparam.totlength, hdg, true)
|
||||
|
||||
-- End of rwy.
|
||||
local rwy=stern:Translate(self.carrierparam.rwylength, FB, true)
|
||||
@@ -2059,31 +2064,31 @@ function AIRBOSS:New(carriername, alias)
|
||||
bow:FlareYellow()
|
||||
|
||||
-- Runway half width = 10 m.
|
||||
local r1=stern:Translate(self.carrierparam.rwywidth*0.5, FB+90)
|
||||
local r2=stern:Translate(self.carrierparam.rwywidth*0.5, FB-90)
|
||||
r1:FlareWhite()
|
||||
r2:FlareWhite()
|
||||
local r1=stern:Translate(self.carrierparam.rwywidth*0.5, FB+90, true)
|
||||
local r2=stern:Translate(self.carrierparam.rwywidth*0.5, FB-90, true)
|
||||
--r1:FlareWhite()
|
||||
--r2:FlareWhite()
|
||||
|
||||
-- End of runway.
|
||||
rwy:FlareRed()
|
||||
|
||||
-- Right 30 meters from stern.
|
||||
local cR=stern:Translate(self.carrierparam.totwidthstarboard, hdg+90)
|
||||
cR:FlareYellow()
|
||||
local cR=stern:Translate(self.carrierparam.totwidthstarboard, hdg+90, true)
|
||||
--cR:FlareYellow()
|
||||
|
||||
-- Left 40 meters from stern.
|
||||
local cL=stern:Translate(self.carrierparam.totwidthport, hdg-90)
|
||||
cL:FlareYellow()
|
||||
local cL=stern:Translate(self.carrierparam.totwidthport, hdg-90, true)
|
||||
--cL:FlareYellow()
|
||||
|
||||
|
||||
-- Carrier specific.
|
||||
if self.carrier:GetTypeName()~=AIRBOSS.CarrierType.TARAWA or self.carrier:GetTypeName()~=AIRBOSS.CarrierType.AMERICA or self.carrier:GetTypeName()~=AIRBOSS.CarrierType.JCARLOS then
|
||||
|
||||
-- Flare wires.
|
||||
local w1=stern:Translate(self.carrierparam.wire1, FB)
|
||||
local w2=stern:Translate(self.carrierparam.wire2, FB)
|
||||
local w3=stern:Translate(self.carrierparam.wire3, FB)
|
||||
local w4=stern:Translate(self.carrierparam.wire4, FB)
|
||||
local w1=stern:Translate(self.carrierparam.wire1, FB, true)
|
||||
local w2=stern:Translate(self.carrierparam.wire2, FB, true)
|
||||
local w3=stern:Translate(self.carrierparam.wire3, FB, true)
|
||||
local w4=stern:Translate(self.carrierparam.wire4, FB, true)
|
||||
w1:FlareWhite()
|
||||
w2:FlareYellow()
|
||||
w3:FlareWhite()
|
||||
@@ -4380,6 +4385,35 @@ function AIRBOSS:_InitNimitz()
|
||||
|
||||
end
|
||||
|
||||
--- Init parameters for Forrestal class super carriers.
|
||||
-- @param #AIRBOSS self
|
||||
function AIRBOSS:_InitForrestal()
|
||||
|
||||
-- Init Nimitz as default.
|
||||
self:_InitNimitz()
|
||||
|
||||
-- Carrier Parameters.
|
||||
self.carrierparam.sterndist =-135.5
|
||||
self.carrierparam.deckheight = 20 --20.1494 --DCS World OpenBeta\CoreMods\tech\USS_Nimitz\Database\USS_CVN_7X.lua
|
||||
|
||||
-- Total size of the carrier (approx as rectangle).
|
||||
self.carrierparam.totlength=315 -- Wiki says 325 meters overall length.
|
||||
self.carrierparam.totwidthport=45 -- Wiki says 73 meters overall beam.
|
||||
self.carrierparam.totwidthstarboard=35
|
||||
|
||||
-- Landing runway.
|
||||
self.carrierparam.rwyangle = -9.1359 --DCS World OpenBeta\CoreMods\tech\USS_Nimitz\scripts\USS_Nimitz_RunwaysAndRoutes.lua
|
||||
self.carrierparam.rwylength = 212
|
||||
self.carrierparam.rwywidth = 25
|
||||
|
||||
-- Wires.
|
||||
self.carrierparam.wire1 = 42 -- Distance from stern to first wire.
|
||||
self.carrierparam.wire2 = 51.5
|
||||
self.carrierparam.wire3 = 62
|
||||
self.carrierparam.wire4 = 72.5
|
||||
|
||||
end
|
||||
|
||||
--- Init parameters for LHA-1 Tarawa carrier.
|
||||
-- @param #AIRBOSS self
|
||||
function AIRBOSS:_InitTarawa()
|
||||
@@ -10549,6 +10583,9 @@ function AIRBOSS:_GetSternCoord()
|
||||
elseif self.carriertype==AIRBOSS.CarrierType.STENNIS then
|
||||
-- Stennis: translate 7 meters starboard wrt Final bearing.
|
||||
self.sterncoord:Translate(self.carrierparam.sterndist, hdg, true, true):Translate(7, FB+90, true, true)
|
||||
elseif self.carriertype==AIRBOSS.CarrierType.FORRESTAL then
|
||||
-- Forrestal
|
||||
self.sterncoord:Translate(self.carrierparam.sterndist, hdg, true, true):Translate(7.5, FB+90, true, true)
|
||||
else
|
||||
-- Nimitz SC: translate 8 meters starboard wrt Final bearing.
|
||||
self.sterncoord:Translate(self.carrierparam.sterndist, hdg, true, true):Translate(9.5, FB+90, true, true)
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
-- @module Ops.CSAR
|
||||
-- @image OPS_CSAR.jpg
|
||||
|
||||
-- Date: Sep 2021
|
||||
-- Date: Oct 2021
|
||||
|
||||
-------------------------------------------------------------------------
|
||||
--- **CSAR** class, extends Core.Base#BASE, Core.Fsm#FSM
|
||||
@@ -97,6 +97,14 @@
|
||||
-- self.pilotmustopendoors = false -- switch to true to enable check of open doors
|
||||
-- -- (added 0.1.9)
|
||||
-- self.suppressmessages = false -- switch off all messaging if you want to do your own
|
||||
-- -- (added 0.1.11)
|
||||
-- self.rescuehoverheight = 20 -- max height for a hovering rescue in meters
|
||||
-- self.rescuehoverdistance = 10 -- max distance for a hovering rescue in meters
|
||||
-- -- (added 0.1.12)
|
||||
-- -- Country codes for spawned pilots
|
||||
-- self.countryblue= country.id.USA
|
||||
-- self.countryred = country.id.RUSSIA
|
||||
-- self.countryneutral = country.id.UN_PEACEKEEPERS
|
||||
--
|
||||
-- ## 2.1 Experimental Features
|
||||
--
|
||||
@@ -233,7 +241,7 @@ CSAR.AircraftType["Mi-24V"] = 8
|
||||
|
||||
--- CSAR class version.
|
||||
-- @field #string version
|
||||
CSAR.version="0.1.10r5"
|
||||
CSAR.version="0.1.11r1"
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
-- ToDo list
|
||||
@@ -362,6 +370,15 @@ function CSAR:New(Coalition, Template, Alias)
|
||||
self.approachdist_near = 3000 -- switch to 5 sec interval approach mode, meters
|
||||
self.pilotmustopendoors = false -- switch to true to enable check on open doors
|
||||
self.suppressmessages = false
|
||||
|
||||
-- added 0.1.11r1
|
||||
self.rescuehoverheight = 20
|
||||
self.rescuehoverdistance = 10
|
||||
|
||||
-- added 0.1.12
|
||||
self.countryblue= country.id.USA
|
||||
self.countryred = country.id.RUSSIA
|
||||
self.countryneutral = country.id.UN_PEACEKEEPERS
|
||||
|
||||
-- WARNING - here\'ll be dragons
|
||||
-- for this to work you need to de-sanitize your mission environment in <DCS root>\Scripts\MissionScripting.lua
|
||||
@@ -549,6 +566,7 @@ function CSAR:_SpawnPilotInField(country,point,frequency)
|
||||
for i=1,10 do
|
||||
math.random(i,10000)
|
||||
end
|
||||
if point:IsSurfaceTypeWater() then point.y = 0 end
|
||||
local template = self.template
|
||||
local alias = string.format("Pilot %.2fkHz-%d", freq, math.random(1,99))
|
||||
local coalition = self.coalition
|
||||
@@ -687,11 +705,11 @@ function CSAR:_SpawnCsarAtZone( _zone, _coalition, _description, _randomPoint, _
|
||||
|
||||
local _country = 0
|
||||
if _coalition == coalition.side.BLUE then
|
||||
_country = country.id.USA
|
||||
_country = self.countryblue
|
||||
elseif _coalition == coalition.side.RED then
|
||||
_country = country.id.RUSSIA
|
||||
_country = self.countryred
|
||||
else
|
||||
_country = country.id.UN_PEACEKEEPERS
|
||||
_country = self.countryneutral
|
||||
end
|
||||
|
||||
self:_AddCsar(_coalition, _country, pos, typename, unitname, _description, freq, _nomessage, _description, forcedesc)
|
||||
@@ -1120,7 +1138,6 @@ end
|
||||
function CSAR:_IsLoadingDoorOpen( unit_name )
|
||||
self:T(self.lid .. " _IsLoadingDoorOpen")
|
||||
return UTILS.IsLoadingDoorOpen(unit_name)
|
||||
|
||||
end
|
||||
|
||||
--- (Internal) Function to check if heli is close to group.
|
||||
@@ -1200,15 +1217,16 @@ function CSAR:_CheckCloseWoundedGroup(_distance, _heliUnit, _heliName, _woundedG
|
||||
end
|
||||
|
||||
if _heliUnit:InAir() and _unitsInHelicopter + 1 <= _maxUnits then
|
||||
|
||||
if _distance < 8.0 then
|
||||
-- TODO - make variable
|
||||
if _distance < self.rescuehoverdistance then
|
||||
|
||||
--check height!
|
||||
local leaderheight = _woundedLeader:GetHeight()
|
||||
if leaderheight < 0 then leaderheight = 0 end
|
||||
local _height = _heliUnit:GetHeight() - leaderheight
|
||||
|
||||
if _height <= 20.0 then
|
||||
|
||||
-- TODO - make variable
|
||||
if _height <= self.rescuehoverheight then
|
||||
|
||||
local _time = self.hoverStatus[_lookupKeyHeli]
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
-- @module Ops.CTLD
|
||||
-- @image OPS_CTLD.jpg
|
||||
|
||||
-- Date: Sep 2021
|
||||
-- Date: Oct 2021
|
||||
|
||||
do
|
||||
------------------------------------------------------
|
||||
@@ -669,6 +669,7 @@ do
|
||||
-- my_ctld.cratecountry = country.id.GERMANY -- ID of crates. Will default to country.id.RUSSIA for RED coalition setups.
|
||||
-- my_ctld.allowcratepickupagain = true -- allow re-pickup crates that were dropped.
|
||||
-- my_ctld.enableslingload = false -- allow cargos to be slingloaded - might not work for all cargo types
|
||||
-- my_ctld.pilotmustopendoors = false -- -- force opening of doors
|
||||
--
|
||||
-- ## 2.1 User functions
|
||||
--
|
||||
@@ -987,7 +988,7 @@ CTLD.UnitTypes = {
|
||||
|
||||
--- CTLD class version.
|
||||
-- @field #string version
|
||||
CTLD.version="0.2.2a4"
|
||||
CTLD.version="0.2.4"
|
||||
|
||||
--- Instantiate a new CTLD.
|
||||
-- @param #CTLD self
|
||||
@@ -1131,6 +1132,9 @@ function CTLD:New(Coalition, Prefixes, Alias)
|
||||
-- country of crates spawned
|
||||
self.cratecountry = country.id.GERMANY
|
||||
|
||||
-- for opening doors
|
||||
self.pilotmustopendoors = false
|
||||
|
||||
if self.coalition == coalition.side.RED then
|
||||
self.cratecountry = country.id.RUSSIA
|
||||
end
|
||||
@@ -1436,6 +1440,7 @@ function CTLD:_LoadTroops(Group, Unit, Cargotype)
|
||||
-- landed or hovering over load zone?
|
||||
local grounded = not self:IsUnitInAir(Unit)
|
||||
local hoverload = self:CanHoverLoad(Unit)
|
||||
--local dooropen = UTILS.IsLoadingDoorOpen(Unit:GetName()) and self.pilotmustopendoors
|
||||
-- check if we are in LOAD zone
|
||||
local inzone, zonename, zone, distance = self:IsUnitInZone(Unit,CTLD.CargoZoneType.LOAD)
|
||||
if not inzone then
|
||||
@@ -1447,6 +1452,9 @@ function CTLD:_LoadTroops(Group, Unit, Cargotype)
|
||||
elseif not grounded and not hoverload then
|
||||
self:_SendMessage("You need to land or hover in position to load!", 10, false, Group)
|
||||
if not self.debug then return self end
|
||||
elseif self.pilotmustopendoors and not UTILS.IsLoadingDoorOpen(Unit:GetName()) then
|
||||
self:_SendMessage("You need to open the door(s) to load troops!", 10, false, Group)
|
||||
if not self.debug then return self end
|
||||
end
|
||||
-- load troops into heli
|
||||
local group = Group -- Wrapper.Group#GROUP
|
||||
@@ -1618,6 +1626,10 @@ end
|
||||
self:_SendMessage("You need to land or hover in position to load!", 10, false, Group)
|
||||
if not self.debug then return self end
|
||||
end
|
||||
if self.pilotmustopendoors and not UTILS.IsLoadingDoorOpen(Unit:GetName()) then
|
||||
self:_SendMessage("You need to open the door(s) to extract troops!", 10, false, Group)
|
||||
if not self.debug then return self end
|
||||
end
|
||||
-- load troops into heli
|
||||
local unit = Unit -- Wrapper.Unit#UNIT
|
||||
local unitname = unit:GetName()
|
||||
@@ -1887,14 +1899,18 @@ function CTLD:_GetCrates(Group, Unit, Cargo, number, drop)
|
||||
return self
|
||||
end
|
||||
|
||||
--- Inject crates and static cargo objects.
|
||||
--- (Internal) Inject crates and static cargo objects.
|
||||
-- @param #CTLD self
|
||||
-- @param Core.Zone#ZONE Zone Zone to spawn in.
|
||||
-- @param #CTLD_CARGO Cargo The cargo type to spawn.
|
||||
-- @param #boolean RandomCoord Randomize coordinate.
|
||||
-- @return #CTLD self
|
||||
function CTLD:InjectStatics(Zone, Cargo)
|
||||
function CTLD:InjectStatics(Zone, Cargo, RandomCoord)
|
||||
self:T(self.lid .. " InjectStatics")
|
||||
local cratecoord = Zone:GetCoordinate()
|
||||
if RandomCoord then
|
||||
cratecoord = Zone:GetRandomCoordinate(5,20)
|
||||
end
|
||||
local surface = cratecoord:GetSurfaceType()
|
||||
if surface == land.SurfaceType.WATER then
|
||||
return self
|
||||
@@ -1930,6 +1946,19 @@ function CTLD:InjectStatics(Zone, Cargo)
|
||||
return self
|
||||
end
|
||||
|
||||
--- (User) Inject static cargo objects.
|
||||
-- @param #CTLD self
|
||||
-- @param Core.Zone#ZONE Zone Zone to spawn in. Will be a somewhat random coordinate.
|
||||
-- @param #string Template Unit(!) name of the static cargo object to be used as template.
|
||||
-- @param #number Mass Mass of the static in kg.
|
||||
-- @return #CTLD self
|
||||
function CTLD:InjectStaticFromTemplate(Zone, Template, Mass)
|
||||
self:T(self.lid .. " InjectStaticFromTemplate")
|
||||
local cargotype = self:GetStaticsCargoFromTemplate(Template,Mass) -- #CTLD_CARGO
|
||||
self:InjectStatics(Zone,cargotype,true)
|
||||
return self
|
||||
end
|
||||
|
||||
--- (Internal) Function to find and list nearby crates.
|
||||
-- @param #CTLD self
|
||||
-- @param Wrapper.Group#GROUP Group
|
||||
@@ -2343,6 +2372,11 @@ function CTLD:_UnloadTroops(Group, Unit)
|
||||
self:T(self.lid .. " _UnloadTroops")
|
||||
-- check if we are in LOAD zone
|
||||
local droppingatbase = false
|
||||
local canunload = true
|
||||
if self.pilotmustopendoors and not UTILS.IsLoadingDoorOpen(Unit:GetName()) then
|
||||
self:_SendMessage("You need to open the door(s) to unload troops!", 10, false, Group)
|
||||
if not self.debug then return self end
|
||||
end
|
||||
local inzone, zonename, zone, distance = self:IsUnitInZone(Unit,CTLD.CargoZoneType.LOAD)
|
||||
if not inzone then
|
||||
inzone, zonename, zone, distance = self:IsUnitInZone(Unit,CTLD.CargoZoneType.SHIP)
|
||||
@@ -2961,7 +2995,7 @@ end
|
||||
|
||||
--- User function - Add *generic* static-type loadable as cargo. This type will create cargo that needs to be loaded, moved and dropped.
|
||||
-- @param #CTLD self
|
||||
-- @param #string Name Unique name of this type of cargo as set in the mission editor (not: UNIT name!), e.g. "Ammunition-1".
|
||||
-- @param #string Name Unique name of this type of cargo as set in the mission editor (note: UNIT name!), e.g. "Ammunition-1".
|
||||
-- @param #number Mass Mass in kg of each static in kg, e.g. 100.
|
||||
-- @param #number Stock Number of groups in stock. Nil for unlimited.
|
||||
function CTLD:AddStaticsCargo(Name,Mass,Stock)
|
||||
@@ -2975,6 +3009,22 @@ function CTLD:AddStaticsCargo(Name,Mass,Stock)
|
||||
return self
|
||||
end
|
||||
|
||||
--- User function - Get a *generic* static-type loadable as #CTLD_CARGO object.
|
||||
-- @param #CTLD self
|
||||
-- @param #string Name Unique Unit(!) name of this type of cargo as set in the mission editor (not: GROUP name!), e.g. "Ammunition-1".
|
||||
-- @param #number Mass Mass in kg of each static in kg, e.g. 100.
|
||||
-- @return #CTLD_CARGO Cargo object
|
||||
function CTLD:GetStaticsCargoFromTemplate(Name,Mass)
|
||||
self:T(self.lid .. " GetStaticsCargoFromTemplate")
|
||||
self.CargoCounter = self.CargoCounter + 1
|
||||
local type = CTLD_CARGO.Enum.STATIC
|
||||
local template = STATIC:FindByName(Name,true):GetTypeName()
|
||||
-- Crates are not directly loadable
|
||||
local cargo = CTLD_CARGO:New(self.CargoCounter,Name,template,type,false,false,1,nil,nil,Mass,1)
|
||||
--table.insert(self.Cargo_Statics,cargo)
|
||||
return cargo
|
||||
end
|
||||
|
||||
--- User function - Add *generic* repair crates loadable as cargo. This type will create crates that need to be loaded, moved, dropped and built.
|
||||
-- @param #CTLD self
|
||||
-- @param #string Name Unique name of this type of cargo. E.g. "Humvee".
|
||||
@@ -3013,7 +3063,7 @@ end
|
||||
--- User function - Activate Name #CTLD.CargoZone.Type ZoneType for this CTLD instance.
|
||||
-- @param #CTLD self
|
||||
-- @param #string Name Name of the zone to change in the ME.
|
||||
-- @param #CTLD.CargoZoneTyp ZoneType Type of zone this belongs to.
|
||||
-- @param #CTLD.CargoZoneType ZoneType Type of zone this belongs to.
|
||||
-- @param #boolean NewState (Optional) Set to true to activate, false to switch off.
|
||||
function CTLD:ActivateZone(Name,ZoneType,NewState)
|
||||
self:T(self.lid .. " AddZone")
|
||||
@@ -3049,7 +3099,7 @@ end
|
||||
--- User function - Deactivate Name #CTLD.CargoZoneType ZoneType for this CTLD instance.
|
||||
-- @param #CTLD self
|
||||
-- @param #string Name Name of the zone to change in the ME.
|
||||
-- @param #CTLD.CargoZoneTyp ZoneType Type of zone this belongs to.
|
||||
-- @param #CTLD.CargoZoneType ZoneType Type of zone this belongs to.
|
||||
function CTLD:DeactivateZone(Name,ZoneType)
|
||||
self:T(self.lid .. " AddZone")
|
||||
self:ActivateZone(Name,ZoneType,false)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user