mirror of
https://github.com/FlightControl-Master/MOOSE_Demos.git
synced 2025-08-15 10:37:47 +00:00
Updated Moose.lua
This commit is contained in:
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,87 +1,87 @@
|
||||
---
|
||||
-- Author: FlightControl
|
||||
-- Created: 07.04.2021
|
||||
-- Contributors: kaltokri
|
||||
-- Modified: 18.05.2024
|
||||
--
|
||||
-- # Documentation:
|
||||
-- https://flightcontrol-master.github.io/MOOSE_DOCS_DEVELOP/Documentation/Core.Menu.html
|
||||
--
|
||||
-- # Description:
|
||||
--
|
||||
-- This demo creates a menu structure to dynamically add menus for different groups of planes and coalition.
|
||||
-- It shows how to create a flexible menu structure and how to remove or add entries to it.
|
||||
--
|
||||
-- # Guide:
|
||||
--
|
||||
-- To test this mission join the planes, look at the radio menus (option F10).
|
||||
-- Call all "Generate ... Menus" multiple times.
|
||||
-- Switch planes and coalition to check the menu.
|
||||
-- And test also the Remove menu options.
|
||||
|
||||
|
||||
-- Create a table to save each menu entry in it.
|
||||
-- This will allow us to remove them easily later on.
|
||||
TestMenus = {}
|
||||
|
||||
-- A table to transform the coalition.side from object to text.
|
||||
local CoalitionText = {
|
||||
[coalition.side.BLUE] = "BLUE",
|
||||
[coalition.side.RED] = "RED",
|
||||
}
|
||||
|
||||
-- Simple function to show a message.
|
||||
-- This is a placeholder to start the real mission.
|
||||
local function MenuMessage( Text, Parameter )
|
||||
MESSAGE:NewType( Text .. Parameter, MESSAGE.Type.Information ):ToAll()
|
||||
end
|
||||
|
||||
-- Function to remove a menu entry.
|
||||
local function MenuRemove(m)
|
||||
TestMenus[m]:Remove()
|
||||
end
|
||||
|
||||
-- Function to generate a mission menu, visible for both sides
|
||||
local function GenerateMissionMenu()
|
||||
|
||||
-- Get number of table entries and increase it to append new ones.
|
||||
local m = #TestMenus+1
|
||||
|
||||
-- Add top menu entry
|
||||
TestMenus[m] = MENU_MISSION:New( "Menu Mission "..m )
|
||||
|
||||
-- Generate sub menu entries for 8 sub mission.
|
||||
for n = 1, 8 do
|
||||
local MenuMissionCommand = MENU_MISSION_COMMAND:New( "Show Mission "..m.."."..n, TestMenus[m], MenuMessage, "Mission ", m.."."..n)
|
||||
end
|
||||
|
||||
-- Add an entry to remove the this sub menu entries.
|
||||
local MenuMissionRemoveCommand = MENU_MISSION_COMMAND:New( "Remove Mission "..m, TestMenus[m], MenuRemove, m)
|
||||
end
|
||||
|
||||
-- Function to generate a Coalition menu, visible for one sides, given as paramenter
|
||||
local function GenerateCoalitionMenu( Coalition )
|
||||
|
||||
-- Get number of table entries and increase it to append new ones.
|
||||
local m = #TestMenus+1
|
||||
|
||||
-- Add top menu entry
|
||||
TestMenus[m] = MENU_COALITION:New( Coalition, "Menu Coalition "..CoalitionText[Coalition].." ".. m )
|
||||
|
||||
-- Generate sub menu entries for 8 sub mission.
|
||||
for n = 1, 8 do
|
||||
local MenuMissionCommand = MENU_COALITION_COMMAND:New( Coalition, "Show Coalition "..CoalitionText[Coalition].." "..m.."."..n, TestMenus[m], MenuMessage, "Coalition ", CoalitionText[Coalition].." "..m.."."..n)
|
||||
end
|
||||
|
||||
-- Add an entry to remove the this sub menu entries.
|
||||
local MenuMissionRemoveCommand = MENU_COALITION_COMMAND:New( Coalition, "Remove Coalition "..CoalitionText[Coalition].." "..m, TestMenus[m], MenuRemove, m)
|
||||
end
|
||||
|
||||
-- Create a MENU_MISSION root entry
|
||||
Menu = MENU_MISSION:New( "Generate Menus" )
|
||||
|
||||
-- First entry will generate a top level menu entry of type mission menu, which is visible for all.
|
||||
-- Second and third will generate coalition specific entries.
|
||||
local MenuMission = MENU_MISSION_COMMAND:New( "Generate Mission Menus", Menu, GenerateMissionMenu )
|
||||
local MenuCoalitionBlue = MENU_MISSION_COMMAND:New( "Generate Blue Coalition Menus", Menu, GenerateCoalitionMenu, coalition.side.BLUE )
|
||||
local MenucoalitionRed = MENU_MISSION_COMMAND:New( "Generate Red Coalition Menus", Menu, GenerateCoalitionMenu, coalition.side.RED )
|
||||
---
|
||||
-- Author: FlightControl
|
||||
-- Created: 07.04.2021
|
||||
-- Contributors: kaltokri
|
||||
-- Modified: 18.05.2024
|
||||
--
|
||||
-- # Documentation:
|
||||
-- https://flightcontrol-master.github.io/MOOSE_DOCS_DEVELOP/Documentation/Core.Menu.html
|
||||
--
|
||||
-- # Description:
|
||||
--
|
||||
-- This demo creates a menu structure to dynamically add menus for different groups of planes and coalition.
|
||||
-- It shows how to create a flexible menu structure and how to remove or add entries to it.
|
||||
--
|
||||
-- # Guide:
|
||||
--
|
||||
-- To test this mission join the planes, look at the radio menus (option F10).
|
||||
-- Call all "Generate ... Menus" multiple times.
|
||||
-- Switch planes and coalition to check the menu.
|
||||
-- And test also the Remove menu options.
|
||||
|
||||
|
||||
-- Create a table to save each menu entry in it.
|
||||
-- This will allow us to remove them easily later on.
|
||||
TestMenus = {}
|
||||
|
||||
-- A table to transform the coalition.side from object to text.
|
||||
local CoalitionText = {
|
||||
[coalition.side.BLUE] = "BLUE",
|
||||
[coalition.side.RED] = "RED",
|
||||
}
|
||||
|
||||
-- Simple function to show a message.
|
||||
-- This is a placeholder to start the real mission.
|
||||
local function MenuMessage( Text, Parameter )
|
||||
MESSAGE:NewType( Text .. Parameter, MESSAGE.Type.Information ):ToAll()
|
||||
end
|
||||
|
||||
-- Function to remove a menu entry.
|
||||
local function MenuRemove(m)
|
||||
TestMenus[m]:Remove()
|
||||
end
|
||||
|
||||
-- Function to generate a mission menu, visible for both sides
|
||||
local function GenerateMissionMenu()
|
||||
|
||||
-- Get number of table entries and increase it to append new ones.
|
||||
local m = #TestMenus+1
|
||||
|
||||
-- Add top menu entry
|
||||
TestMenus[m] = MENU_MISSION:New( "Menu Mission "..m )
|
||||
|
||||
-- Generate sub menu entries for 8 sub mission.
|
||||
for n = 1, 8 do
|
||||
local MenuMissionCommand = MENU_MISSION_COMMAND:New( "Show Mission "..m.."."..n, TestMenus[m], MenuMessage, "Mission ", m.."."..n)
|
||||
end
|
||||
|
||||
-- Add an entry to remove the this sub menu entries.
|
||||
local MenuMissionRemoveCommand = MENU_MISSION_COMMAND:New( "Remove Mission "..m, TestMenus[m], MenuRemove, m)
|
||||
end
|
||||
|
||||
-- Function to generate a Coalition menu, visible for one sides, given as paramenter
|
||||
local function GenerateCoalitionMenu( Coalition )
|
||||
|
||||
-- Get number of table entries and increase it to append new ones.
|
||||
local m = #TestMenus+1
|
||||
|
||||
-- Add top menu entry
|
||||
TestMenus[m] = MENU_COALITION:New( Coalition, "Menu Coalition "..CoalitionText[Coalition].." ".. m )
|
||||
|
||||
-- Generate sub menu entries for 8 sub mission.
|
||||
for n = 1, 8 do
|
||||
local MenuMissionCommand = MENU_COALITION_COMMAND:New( Coalition, "Show Coalition "..CoalitionText[Coalition].." "..m.."."..n, TestMenus[m], MenuMessage, "Coalition ", CoalitionText[Coalition].." "..m.."."..n)
|
||||
end
|
||||
|
||||
-- Add an entry to remove the this sub menu entries.
|
||||
local MenuMissionRemoveCommand = MENU_COALITION_COMMAND:New( Coalition, "Remove Coalition "..CoalitionText[Coalition].." "..m, TestMenus[m], MenuRemove, m)
|
||||
end
|
||||
|
||||
-- Create a MENU_MISSION root entry
|
||||
Menu = MENU_MISSION:New( "Generate Menus" )
|
||||
|
||||
-- First entry will generate a top level menu entry of type mission menu, which is visible for all.
|
||||
-- Second and third will generate coalition specific entries.
|
||||
local MenuMission = MENU_MISSION_COMMAND:New( "Generate Mission Menus", Menu, GenerateMissionMenu )
|
||||
local MenuCoalitionBlue = MENU_MISSION_COMMAND:New( "Generate Blue Coalition Menus", Menu, GenerateCoalitionMenu, coalition.side.BLUE )
|
||||
local MenucoalitionRed = MENU_MISSION_COMMAND:New( "Generate Red Coalition Menus", Menu, GenerateCoalitionMenu, coalition.side.RED )
|
||||
|
||||
Binary file not shown.
@@ -1,179 +1,179 @@
|
||||
---
|
||||
-- Author: Saint185
|
||||
-- Created: 21.11.2020
|
||||
-- Contributors: kaltokri
|
||||
-- Modified: 18.05.2024
|
||||
--
|
||||
-- # Documentation:
|
||||
-- https://flightcontrol-master.github.io/MOOSE_DOCS_DEVELOP/Documentation/Core.Menu.html
|
||||
-- https://flightcontrol-master.github.io/MOOSE_DOCS_DEVELOP/Documentation/Wrapper.Static.html
|
||||
-- https://flightcontrol-master.github.io/MOOSE_DOCS_DEVELOP/Documentation/Core.Point.html
|
||||
-- https://flightcontrol-master.github.io/MOOSE_DOCS_DEVELOP/Documentation/Core.Zone.html
|
||||
-- https://flightcontrol-master.github.io/MOOSE_DOCS_DEVELOP/Documentation/Utilities.Utils.html
|
||||
--
|
||||
-- # Description:
|
||||
--
|
||||
-- This demo creates a menu structure to send messages with coordinates of targets to all players.
|
||||
-- The code can be optimized a lot. But it is an working example create by a moose user.
|
||||
--
|
||||
-- # Guide:
|
||||
-- - Enter the slot TACTICAL CMDR.
|
||||
-- - Open radio menu F10 Other...
|
||||
-- - F1 TARGETCOORDS...
|
||||
-- - Choose target category and target.
|
||||
-- - See Message with the coordinates on the screen.
|
||||
|
||||
|
||||
_SETTINGS:SetPlayerMenuOff()
|
||||
|
||||
-- Find the static EastAmmoDump defined in the Mission Editor.
|
||||
-- Get it's coordinate and save it for later use.
|
||||
-- Determine it's height and save it for later use.
|
||||
local AmmoDumpEast = STATIC:FindByName( "AmmoDumpEast" )
|
||||
local AmmoDumpEastCOORD = AmmoDumpEast:GetCoordinate() --contains the LLDMS coordinates for JDAM
|
||||
local AmmoDumpEastHeight = AmmoDumpEastCOORD:GetLandHeight() --gets the land height Bridge 32 from T1COORD
|
||||
|
||||
-- Do the same for AmmoDumpWest.
|
||||
local AmmoDumpWest = STATIC:FindByName( "AmmoDumpWest" )
|
||||
local AmmoDumpWestCOORD = AmmoDumpWest:GetCoordinate()
|
||||
local AmmoDumpWestHeight = AmmoDumpWestCOORD:GetLandHeight()
|
||||
|
||||
-- Do the same for AmmoDumpSouth.
|
||||
local AmmoDumpSouth = STATIC:FindByName( "AmmoDumpSouth" )
|
||||
local AmmoDumpSouthCOORD = AmmoDumpSouth:GetCoordinate()
|
||||
local AmmoDumpSouthHeight = AmmoDumpSouthCOORD:GetLandHeight()
|
||||
|
||||
-- Do the same for AmmoDumpNorth.
|
||||
local AmmoDumpNorth = STATIC:FindByName( "AmmoDumpNorth" )
|
||||
local AmmoDumpNorthCOORD = AmmoDumpNorth:GetCoordinate()
|
||||
local AmmoDumpNorthHeight = AmmoDumpNorthCOORD:GetLandHeight()
|
||||
|
||||
-- Zone placed on Bridges in ME.
|
||||
-- Get and safe it's data.
|
||||
local Target_1 = ZONE:New( "Bridge32" )
|
||||
local T1COORD = Target_1:GetCoordinate() -- Contains the LLDMS coordinates for JDAM
|
||||
local T1Height = T1COORD:GetLandHeight() -- Gets the land height Bridge 32 from T1COORD
|
||||
|
||||
local Target_2 = ZONE:New( "Bridge33" )
|
||||
local T2COORD = Target_2:GetCoordinate()
|
||||
local T2Height = T2COORD:GetLandHeight()
|
||||
|
||||
-- Do the same for Zones placed on some shelters.
|
||||
local Target_3 = ZONE:New( "HardenedHanger33" )
|
||||
local T3COORD = Target_3:GetCoordinate()
|
||||
local T3Height = T3COORD:GetLandHeight()
|
||||
|
||||
local Target_4 = ZONE:New( "HardenedHanger34" )
|
||||
local T4COORD = Target_4:GetCoordinate()
|
||||
local T4Height = T4COORD:GetLandHeight()
|
||||
|
||||
-- Gets LLDMS coord from Target 1(Bridge32p) using T1COORD:ToStringLLDMS() then assigns sections of the string to coordXy.
|
||||
local function TARGET1(T1LLDMS)
|
||||
local T1LLDMS = T1COORD:ToStringLLDMS()
|
||||
local coordN1 = string.sub(T1LLDMS,9,10) -- Extracts a block of text from String T4LLDMS starting at location 9 ending at location 10
|
||||
local coordN2 = string.sub(T1LLDMS,13,20) -- Extracts a block of text from String T4LLDMS starting at location 13 ending at location 20
|
||||
local coordE1 = string.sub(T1LLDMS,26,27) -- Extracts a block of text from String T4LLDMS starting at location 26 ending at location 27
|
||||
local coordE2 = string.sub(T1LLDMS,30,37) -- Extracts a block of text from String T4LLDMS starting at location 30 ending at location 37
|
||||
local Heightft = UTILS.MetersToFeet(T1Height) -- Converts height in meters to feet
|
||||
local T1Heightft = UTILS.Round(Heightft) -- Rounds the value to a whole number
|
||||
MESSAGE:New("Bridge 32".."\n".. ("N"..coordN1.."'"..coordN2.."\n".."E"..coordE1.."'"..coordE2.."\n".."ALT "..T1Heightft.." ft"), 50):ToAll()
|
||||
return T1LLDMS -- Returns the argument for function TARGET1
|
||||
end
|
||||
|
||||
local function TARGET2(T2LLDMS)
|
||||
local T2LLDMS = T2COORD:ToStringLLDMS()
|
||||
local coordN1 = string.sub(T2LLDMS,9,10)
|
||||
local coordN2 = string.sub(T2LLDMS,13,20)
|
||||
local coordE1 = string.sub(T2LLDMS,26,27)
|
||||
local coordE2 = string.sub(T2LLDMS,30,37)
|
||||
local Heightft = UTILS.MetersToFeet(T2Height)
|
||||
local T2Heightft = UTILS.Round(Heightft)
|
||||
MESSAGE:New("Bridge 33".."\n".. ("N"..coordN1.."'"..coordN2.."\n".."E"..coordE1.."'"..coordE2.."\n".."ALT "..T2Heightft.." ft"), 50):ToAll()
|
||||
return T2LLDMS
|
||||
end
|
||||
|
||||
local function TARGET3(T3LLDMS)
|
||||
local T3LLDMS = T3COORD:ToStringLLDMS()
|
||||
local coordN1 = string.sub(T3LLDMS,9,10)
|
||||
local coordN2 = string.sub(T3LLDMS,13,20)
|
||||
local coordE1 = string.sub(T3LLDMS,26,27)
|
||||
local coordE2 = string.sub(T3LLDMS,30,37)
|
||||
local Heightft = UTILS.MetersToFeet(T3Height)
|
||||
local T3Heightft = UTILS.Round(Heightft)
|
||||
MESSAGE:New("HardenedHanger 33".."\n".. ("N"..coordN1.."'"..coordN2.."\n".."E"..coordE1.."'"..coordE2.."\n".."ALT "..T3Heightft.." ft"), 50):ToAll()
|
||||
return T3LLDMS
|
||||
end
|
||||
|
||||
local function TARGET4(T4LLDMS)
|
||||
local T4LLDMS = T4COORD:ToStringLLDMS()
|
||||
local coordN1 = string.sub(T4LLDMS,9,10)
|
||||
local coordN2 = string.sub(T4LLDMS,13,20)
|
||||
local coordE1 = string.sub(T4LLDMS,26,27)
|
||||
local coordE2 = string.sub(T4LLDMS,30,37)
|
||||
local Heightft = UTILS.MetersToFeet(T4Height)
|
||||
local T4Heightft = UTILS.Round(Heightft)
|
||||
MESSAGE:New("HardenedHanger 34".."\n".. ("N"..coordN1.."'"..coordN2.."\n".."E"..coordE1.."'"..coordE2.."\n".."ALT "..T4Heightft.." ft"), 50):ToAll()
|
||||
return T4LLDMS
|
||||
end
|
||||
|
||||
local function TARGET5(T1LLDMS)
|
||||
local T1LLDMS = AmmoDumpEastCOORD:ToStringLLDMS()
|
||||
local coordN1 = string.sub(T1LLDMS,9,10)
|
||||
local coordN2 = string.sub(T1LLDMS,13,20)
|
||||
local coordE1 = string.sub(T1LLDMS,26,27)
|
||||
local coordE2 = string.sub(T1LLDMS,30,37)
|
||||
local Heightft = UTILS.MetersToFeet(AmmoDumpEastHeight)
|
||||
local T1Heightft = UTILS.Round(Heightft)
|
||||
MESSAGE:New("EastAmmoDump".."\n".. ("N"..coordN1.."'"..coordN2.."\n".."E"..coordE1.."'"..coordE2.."\n".."ALT "..T1Heightft.." ft"), 50):ToAll()
|
||||
return T1LLDMS
|
||||
end
|
||||
|
||||
local function TARGET6(T2LLDMS)
|
||||
local T2LLDMS = AmmoDumpWestCOORD:ToStringLLDMS()
|
||||
local coordN1 = string.sub(T2LLDMS,9,10)
|
||||
local coordN2 = string.sub(T2LLDMS,13,20)
|
||||
local coordE1 = string.sub(T2LLDMS,26,27)
|
||||
local coordE2 = string.sub(T2LLDMS,30,37)
|
||||
local Heightft = UTILS.MetersToFeet(AmmoDumpWestHeight)
|
||||
local T2Heightft = UTILS.Round(Heightft)
|
||||
MESSAGE:New("WestAmmoDump".."\n".. ("N"..coordN1.."'"..coordN2.."\n".."E"..coordE1.."'"..coordE2.."\n".."ALT "..T2Heightft.." ft"), 50):ToAll()
|
||||
return T2LLDMS
|
||||
end
|
||||
|
||||
local function TARGET7(T3LLDMS)
|
||||
local T3LLDMS = AmmoDumpSouthCOORD:ToStringLLDMS()
|
||||
local coordN1 = string.sub(T3LLDMS,9,10)
|
||||
local coordN2 = string.sub(T3LLDMS,13,20)
|
||||
local coordE1 = string.sub(T3LLDMS,26,27)
|
||||
local coordE2 = string.sub(T3LLDMS,30,37)
|
||||
local Heightft = UTILS.MetersToFeet(AmmoDumpSouthHeight)
|
||||
local T3Heightft = UTILS.Round(Heightft)
|
||||
MESSAGE:New("SouthAmmoDump".."\n".. ("N"..coordN1.."'"..coordN2.."\n".."E"..coordE1.."'"..coordE2.."\n".."ALT "..T3Heightft.." ft"), 50):ToAll()
|
||||
return T3LLDMS
|
||||
end
|
||||
|
||||
local function TARGET8(T4LLDMS)
|
||||
local T4LLDMS = AmmoDumpNorthCOORD:ToStringLLDMS()
|
||||
local coordN1 = string.sub(T4LLDMS,9,10) -- Extracts text from String T4LLDMS at location 9 to 10
|
||||
local coordN2 = string.sub(T4LLDMS,13,20) -- Extracts text from String T4LLDMS at location 13 to 20
|
||||
local coordE1 = string.sub(T4LLDMS,26,27) -- Extracts text from String T4LLDMS at location 26 to 27
|
||||
local coordE2 = string.sub(T4LLDMS,30,37) -- Extracts text from String T4LLDMS at location 30 to 37
|
||||
local Heightft = UTILS.MetersToFeet(AmmoDumpNorthHeight) -- Coverts height in meters to feet
|
||||
local T4Heightft = UTILS.Round(Heightft) -- Rounds the value to a whole number
|
||||
MESSAGE:New("NorthAmmoDump".."\n".. ("N"..coordN1.."'"..coordN2.."\n".."E"..coordE1.."'"..coordE2.."\n".."ALT "..T4Heightft.." ft"), 50):ToAll()
|
||||
return T4LLDMS
|
||||
end
|
||||
|
||||
--Coordinates Menu
|
||||
Level1 = MENU_MISSION:New( "TARGETCOORDS" ) -- Top level Menu all targets are assigned to this master menu
|
||||
Level2_1 = MENU_MISSION:New( "BRIDGE", Level1 ) -- Level 2 Contains Target groups
|
||||
Level2_2 = MENU_MISSION:New( "AMMO DUMP", Level1 )
|
||||
Level2_3 = MENU_MISSION:New( "HARDENED SHELTER", Level1 )
|
||||
Menu1 = MENU_MISSION_COMMAND:New("Bridge 32", Level2_1, TARGET1) -- Level 3 contains Target group coordinates
|
||||
Menu2 = MENU_MISSION_COMMAND:New("Bridge 33", Level2_1, TARGET2)
|
||||
Menu3 = MENU_MISSION_COMMAND:New("HardenedHanger 33", Level2_3, TARGET3) -- Text displayed HardenedHanger 33, select Menu position, function to call(local function TARGET3(T3LLDMS))
|
||||
Menu4 = MENU_MISSION_COMMAND:New("HardenedHanger 34", Level2_3, TARGET4)
|
||||
Menu5 = MENU_MISSION_COMMAND:New("AmmoDumpEast", Level2_2, TARGET5)
|
||||
Menu6 = MENU_MISSION_COMMAND:New("AmmoDumpWest", Level2_2, TARGET6)
|
||||
Menu7 = MENU_MISSION_COMMAND:New("AmmoDumpSouth", Level2_2, TARGET7)
|
||||
Menu8 = MENU_MISSION_COMMAND:New("AmmoDumpNorth", Level2_2, TARGET8)
|
||||
---
|
||||
-- Author: Saint185
|
||||
-- Created: 21.11.2020
|
||||
-- Contributors: kaltokri
|
||||
-- Modified: 18.05.2024
|
||||
--
|
||||
-- # Documentation:
|
||||
-- https://flightcontrol-master.github.io/MOOSE_DOCS_DEVELOP/Documentation/Core.Menu.html
|
||||
-- https://flightcontrol-master.github.io/MOOSE_DOCS_DEVELOP/Documentation/Wrapper.Static.html
|
||||
-- https://flightcontrol-master.github.io/MOOSE_DOCS_DEVELOP/Documentation/Core.Point.html
|
||||
-- https://flightcontrol-master.github.io/MOOSE_DOCS_DEVELOP/Documentation/Core.Zone.html
|
||||
-- https://flightcontrol-master.github.io/MOOSE_DOCS_DEVELOP/Documentation/Utilities.Utils.html
|
||||
--
|
||||
-- # Description:
|
||||
--
|
||||
-- This demo creates a menu structure to send messages with coordinates of targets to all players.
|
||||
-- The code can be optimized a lot. But it is an working example create by a moose user.
|
||||
--
|
||||
-- # Guide:
|
||||
-- - Enter the slot TACTICAL CMDR.
|
||||
-- - Open radio menu F10 Other...
|
||||
-- - F1 TARGETCOORDS...
|
||||
-- - Choose target category and target.
|
||||
-- - See Message with the coordinates on the screen.
|
||||
|
||||
|
||||
_SETTINGS:SetPlayerMenuOff()
|
||||
|
||||
-- Find the static EastAmmoDump defined in the Mission Editor.
|
||||
-- Get it's coordinate and save it for later use.
|
||||
-- Determine it's height and save it for later use.
|
||||
local AmmoDumpEast = STATIC:FindByName( "AmmoDumpEast" )
|
||||
local AmmoDumpEastCOORD = AmmoDumpEast:GetCoordinate() --contains the LLDMS coordinates for JDAM
|
||||
local AmmoDumpEastHeight = AmmoDumpEastCOORD:GetLandHeight() --gets the land height Bridge 32 from T1COORD
|
||||
|
||||
-- Do the same for AmmoDumpWest.
|
||||
local AmmoDumpWest = STATIC:FindByName( "AmmoDumpWest" )
|
||||
local AmmoDumpWestCOORD = AmmoDumpWest:GetCoordinate()
|
||||
local AmmoDumpWestHeight = AmmoDumpWestCOORD:GetLandHeight()
|
||||
|
||||
-- Do the same for AmmoDumpSouth.
|
||||
local AmmoDumpSouth = STATIC:FindByName( "AmmoDumpSouth" )
|
||||
local AmmoDumpSouthCOORD = AmmoDumpSouth:GetCoordinate()
|
||||
local AmmoDumpSouthHeight = AmmoDumpSouthCOORD:GetLandHeight()
|
||||
|
||||
-- Do the same for AmmoDumpNorth.
|
||||
local AmmoDumpNorth = STATIC:FindByName( "AmmoDumpNorth" )
|
||||
local AmmoDumpNorthCOORD = AmmoDumpNorth:GetCoordinate()
|
||||
local AmmoDumpNorthHeight = AmmoDumpNorthCOORD:GetLandHeight()
|
||||
|
||||
-- Zone placed on Bridges in ME.
|
||||
-- Get and safe it's data.
|
||||
local Target_1 = ZONE:New( "Bridge32" )
|
||||
local T1COORD = Target_1:GetCoordinate() -- Contains the LLDMS coordinates for JDAM
|
||||
local T1Height = T1COORD:GetLandHeight() -- Gets the land height Bridge 32 from T1COORD
|
||||
|
||||
local Target_2 = ZONE:New( "Bridge33" )
|
||||
local T2COORD = Target_2:GetCoordinate()
|
||||
local T2Height = T2COORD:GetLandHeight()
|
||||
|
||||
-- Do the same for Zones placed on some shelters.
|
||||
local Target_3 = ZONE:New( "HardenedHanger33" )
|
||||
local T3COORD = Target_3:GetCoordinate()
|
||||
local T3Height = T3COORD:GetLandHeight()
|
||||
|
||||
local Target_4 = ZONE:New( "HardenedHanger34" )
|
||||
local T4COORD = Target_4:GetCoordinate()
|
||||
local T4Height = T4COORD:GetLandHeight()
|
||||
|
||||
-- Gets LLDMS coord from Target 1(Bridge32p) using T1COORD:ToStringLLDMS() then assigns sections of the string to coordXy.
|
||||
local function TARGET1(T1LLDMS)
|
||||
local T1LLDMS = T1COORD:ToStringLLDMS()
|
||||
local coordN1 = string.sub(T1LLDMS,9,10) -- Extracts a block of text from String T4LLDMS starting at location 9 ending at location 10
|
||||
local coordN2 = string.sub(T1LLDMS,13,20) -- Extracts a block of text from String T4LLDMS starting at location 13 ending at location 20
|
||||
local coordE1 = string.sub(T1LLDMS,26,27) -- Extracts a block of text from String T4LLDMS starting at location 26 ending at location 27
|
||||
local coordE2 = string.sub(T1LLDMS,30,37) -- Extracts a block of text from String T4LLDMS starting at location 30 ending at location 37
|
||||
local Heightft = UTILS.MetersToFeet(T1Height) -- Converts height in meters to feet
|
||||
local T1Heightft = UTILS.Round(Heightft) -- Rounds the value to a whole number
|
||||
MESSAGE:New("Bridge 32".."\n".. ("N"..coordN1.."'"..coordN2.."\n".."E"..coordE1.."'"..coordE2.."\n".."ALT "..T1Heightft.." ft"), 50):ToAll()
|
||||
return T1LLDMS -- Returns the argument for function TARGET1
|
||||
end
|
||||
|
||||
local function TARGET2(T2LLDMS)
|
||||
local T2LLDMS = T2COORD:ToStringLLDMS()
|
||||
local coordN1 = string.sub(T2LLDMS,9,10)
|
||||
local coordN2 = string.sub(T2LLDMS,13,20)
|
||||
local coordE1 = string.sub(T2LLDMS,26,27)
|
||||
local coordE2 = string.sub(T2LLDMS,30,37)
|
||||
local Heightft = UTILS.MetersToFeet(T2Height)
|
||||
local T2Heightft = UTILS.Round(Heightft)
|
||||
MESSAGE:New("Bridge 33".."\n".. ("N"..coordN1.."'"..coordN2.."\n".."E"..coordE1.."'"..coordE2.."\n".."ALT "..T2Heightft.." ft"), 50):ToAll()
|
||||
return T2LLDMS
|
||||
end
|
||||
|
||||
local function TARGET3(T3LLDMS)
|
||||
local T3LLDMS = T3COORD:ToStringLLDMS()
|
||||
local coordN1 = string.sub(T3LLDMS,9,10)
|
||||
local coordN2 = string.sub(T3LLDMS,13,20)
|
||||
local coordE1 = string.sub(T3LLDMS,26,27)
|
||||
local coordE2 = string.sub(T3LLDMS,30,37)
|
||||
local Heightft = UTILS.MetersToFeet(T3Height)
|
||||
local T3Heightft = UTILS.Round(Heightft)
|
||||
MESSAGE:New("HardenedHanger 33".."\n".. ("N"..coordN1.."'"..coordN2.."\n".."E"..coordE1.."'"..coordE2.."\n".."ALT "..T3Heightft.." ft"), 50):ToAll()
|
||||
return T3LLDMS
|
||||
end
|
||||
|
||||
local function TARGET4(T4LLDMS)
|
||||
local T4LLDMS = T4COORD:ToStringLLDMS()
|
||||
local coordN1 = string.sub(T4LLDMS,9,10)
|
||||
local coordN2 = string.sub(T4LLDMS,13,20)
|
||||
local coordE1 = string.sub(T4LLDMS,26,27)
|
||||
local coordE2 = string.sub(T4LLDMS,30,37)
|
||||
local Heightft = UTILS.MetersToFeet(T4Height)
|
||||
local T4Heightft = UTILS.Round(Heightft)
|
||||
MESSAGE:New("HardenedHanger 34".."\n".. ("N"..coordN1.."'"..coordN2.."\n".."E"..coordE1.."'"..coordE2.."\n".."ALT "..T4Heightft.." ft"), 50):ToAll()
|
||||
return T4LLDMS
|
||||
end
|
||||
|
||||
local function TARGET5(T1LLDMS)
|
||||
local T1LLDMS = AmmoDumpEastCOORD:ToStringLLDMS()
|
||||
local coordN1 = string.sub(T1LLDMS,9,10)
|
||||
local coordN2 = string.sub(T1LLDMS,13,20)
|
||||
local coordE1 = string.sub(T1LLDMS,26,27)
|
||||
local coordE2 = string.sub(T1LLDMS,30,37)
|
||||
local Heightft = UTILS.MetersToFeet(AmmoDumpEastHeight)
|
||||
local T1Heightft = UTILS.Round(Heightft)
|
||||
MESSAGE:New("EastAmmoDump".."\n".. ("N"..coordN1.."'"..coordN2.."\n".."E"..coordE1.."'"..coordE2.."\n".."ALT "..T1Heightft.." ft"), 50):ToAll()
|
||||
return T1LLDMS
|
||||
end
|
||||
|
||||
local function TARGET6(T2LLDMS)
|
||||
local T2LLDMS = AmmoDumpWestCOORD:ToStringLLDMS()
|
||||
local coordN1 = string.sub(T2LLDMS,9,10)
|
||||
local coordN2 = string.sub(T2LLDMS,13,20)
|
||||
local coordE1 = string.sub(T2LLDMS,26,27)
|
||||
local coordE2 = string.sub(T2LLDMS,30,37)
|
||||
local Heightft = UTILS.MetersToFeet(AmmoDumpWestHeight)
|
||||
local T2Heightft = UTILS.Round(Heightft)
|
||||
MESSAGE:New("WestAmmoDump".."\n".. ("N"..coordN1.."'"..coordN2.."\n".."E"..coordE1.."'"..coordE2.."\n".."ALT "..T2Heightft.." ft"), 50):ToAll()
|
||||
return T2LLDMS
|
||||
end
|
||||
|
||||
local function TARGET7(T3LLDMS)
|
||||
local T3LLDMS = AmmoDumpSouthCOORD:ToStringLLDMS()
|
||||
local coordN1 = string.sub(T3LLDMS,9,10)
|
||||
local coordN2 = string.sub(T3LLDMS,13,20)
|
||||
local coordE1 = string.sub(T3LLDMS,26,27)
|
||||
local coordE2 = string.sub(T3LLDMS,30,37)
|
||||
local Heightft = UTILS.MetersToFeet(AmmoDumpSouthHeight)
|
||||
local T3Heightft = UTILS.Round(Heightft)
|
||||
MESSAGE:New("SouthAmmoDump".."\n".. ("N"..coordN1.."'"..coordN2.."\n".."E"..coordE1.."'"..coordE2.."\n".."ALT "..T3Heightft.." ft"), 50):ToAll()
|
||||
return T3LLDMS
|
||||
end
|
||||
|
||||
local function TARGET8(T4LLDMS)
|
||||
local T4LLDMS = AmmoDumpNorthCOORD:ToStringLLDMS()
|
||||
local coordN1 = string.sub(T4LLDMS,9,10) -- Extracts text from String T4LLDMS at location 9 to 10
|
||||
local coordN2 = string.sub(T4LLDMS,13,20) -- Extracts text from String T4LLDMS at location 13 to 20
|
||||
local coordE1 = string.sub(T4LLDMS,26,27) -- Extracts text from String T4LLDMS at location 26 to 27
|
||||
local coordE2 = string.sub(T4LLDMS,30,37) -- Extracts text from String T4LLDMS at location 30 to 37
|
||||
local Heightft = UTILS.MetersToFeet(AmmoDumpNorthHeight) -- Coverts height in meters to feet
|
||||
local T4Heightft = UTILS.Round(Heightft) -- Rounds the value to a whole number
|
||||
MESSAGE:New("NorthAmmoDump".."\n".. ("N"..coordN1.."'"..coordN2.."\n".."E"..coordE1.."'"..coordE2.."\n".."ALT "..T4Heightft.." ft"), 50):ToAll()
|
||||
return T4LLDMS
|
||||
end
|
||||
|
||||
--Coordinates Menu
|
||||
Level1 = MENU_MISSION:New( "TARGETCOORDS" ) -- Top level Menu all targets are assigned to this master menu
|
||||
Level2_1 = MENU_MISSION:New( "BRIDGE", Level1 ) -- Level 2 Contains Target groups
|
||||
Level2_2 = MENU_MISSION:New( "AMMO DUMP", Level1 )
|
||||
Level2_3 = MENU_MISSION:New( "HARDENED SHELTER", Level1 )
|
||||
Menu1 = MENU_MISSION_COMMAND:New("Bridge 32", Level2_1, TARGET1) -- Level 3 contains Target group coordinates
|
||||
Menu2 = MENU_MISSION_COMMAND:New("Bridge 33", Level2_1, TARGET2)
|
||||
Menu3 = MENU_MISSION_COMMAND:New("HardenedHanger 33", Level2_3, TARGET3) -- Text displayed HardenedHanger 33, select Menu position, function to call(local function TARGET3(T3LLDMS))
|
||||
Menu4 = MENU_MISSION_COMMAND:New("HardenedHanger 34", Level2_3, TARGET4)
|
||||
Menu5 = MENU_MISSION_COMMAND:New("AmmoDumpEast", Level2_2, TARGET5)
|
||||
Menu6 = MENU_MISSION_COMMAND:New("AmmoDumpWest", Level2_2, TARGET6)
|
||||
Menu7 = MENU_MISSION_COMMAND:New("AmmoDumpSouth", Level2_2, TARGET7)
|
||||
Menu8 = MENU_MISSION_COMMAND:New("AmmoDumpNorth", Level2_2, TARGET8)
|
||||
|
||||
Binary file not shown.
@@ -1,126 +1,126 @@
|
||||
---
|
||||
-- Author: Wingthor and Saint185
|
||||
-- Created: 15.01.2021
|
||||
-- Contributors: kaltokri
|
||||
-- Modified: 18.05.2024
|
||||
--
|
||||
-- # Documentation:
|
||||
-- https://flightcontrol-master.github.io/MOOSE_DOCS_DEVELOP/Documentation/Core.Menu.html
|
||||
--
|
||||
-- # Description:
|
||||
--
|
||||
-- A squad with four Su-25T is placed. One player with 3 AI.
|
||||
-- After a few seconds a menu is added to check loadout of the AI.
|
||||
--
|
||||
-- Check the code on how to create a dynamic menu with a for-iteration and a table.
|
||||
-- A forward declaration of a function is used in this example.
|
||||
-- The logic of this script is universal. It will work with any human flyable plane.
|
||||
-- No matter of coalition RED or BLUE. Just name your GROUP "Player".
|
||||
-- Under the Skill box select "client" as your own plane.
|
||||
--
|
||||
-- # Guide:
|
||||
-- - Start the mission, choose coalition BLUE and Pilot slot.
|
||||
-- - Wait a few seconds and open radio menu F10 Others...
|
||||
-- - Choose loadout to print.
|
||||
|
||||
|
||||
BASE:TraceOnOff(true)
|
||||
BASE:TraceAll(true)
|
||||
|
||||
------------------------------------ GLOBALS For easy mission tweaking -------------------------------------------------
|
||||
CASZone = "Zone Charlie"
|
||||
PlayersGroupName = "Player"
|
||||
BuildMenu = function() end -- Forward declaration
|
||||
------------------------------------ END GLOBALS -----------------------------------------------------------------------
|
||||
|
||||
env.info ("------------------------- STARING SCRIPT ---------------------------------")
|
||||
|
||||
--Create TASK Zone
|
||||
local zoneCharlie = ZONE:New(CASZone)
|
||||
|
||||
-- Add scheduled command, now holds the BuildMenu Call.
|
||||
local start = SCHEDULER:New(nil,
|
||||
function()
|
||||
-- Create a flight group.
|
||||
flightgroup = FLIGHTGROUP:New(PlayersGroupName)
|
||||
flightgroup:SetDetection(true)
|
||||
|
||||
--- Function called when the group detects a previously unknown unit.
|
||||
function flightgroup:OnAfterDetectedUnitNew(From, Event, To, Unit)
|
||||
local unit = Unit --Wrapper.Unit#UNIT
|
||||
-- Message to everybody and in the DCS log file.
|
||||
local text = string.format("Detected unit %s", unit:GetName())
|
||||
MESSAGE:New(text, 20,flightgroup:GetName()):ToAll()
|
||||
env.info(text)
|
||||
end
|
||||
|
||||
-- Create a CAS mission.
|
||||
local mission = AUFTRAG:NewCAS(zoneCharlie)
|
||||
mission:SetEngageAltitude(10000)
|
||||
mission:SetWeaponExpend(AI.Task.WeaponExpend.ONE)
|
||||
|
||||
-- Assign mission to pilot.
|
||||
flightgroup:AddMission(mission)
|
||||
-- Build Menu for ammo check.
|
||||
BuildMenu()
|
||||
end,
|
||||
{},1,30000 )
|
||||
|
||||
--- Function to check ammo for a give wingman.
|
||||
-- @param Wingman number
|
||||
local function AmmoCheck(Wingman)
|
||||
-- Gets the ammo for each unit and dumps it into unittable TABLE.
|
||||
local unitsAmmoTable = units[Wingman]:GetAmmo()
|
||||
|
||||
-- Gets the callsign for each unit and dumps it into callsign TABLE.
|
||||
local callsign = units[Wingman]:GetCallsign()
|
||||
|
||||
-- This logic splits out each ammo type and name and inserts it into the message.
|
||||
local count = {}
|
||||
local desc = {}
|
||||
-- local ammoUnits = ammo[2]
|
||||
local WepMessage = " "
|
||||
for i = 1, #unitsAmmoTable do
|
||||
local ammocount = unitsAmmoTable[i].count
|
||||
local ammodesc = unitsAmmoTable[i].desc.displayName
|
||||
table.insert (count, ammocount)
|
||||
table.insert (desc, ammodesc)
|
||||
WepMessage = WepMessage .. desc[i] .. ": " .. count[i] .. "\n "
|
||||
end
|
||||
MESSAGE:New( callsign ..":\n------------------------------------\n" .. WepMessage, 10):ToAll()
|
||||
end
|
||||
|
||||
local function CheckAll()
|
||||
-- Gets the number of units in the group
|
||||
units = GROUP:FindByName( PlayersGroupName ):GetUnits()
|
||||
for i = 2, #units do
|
||||
AmmoCheck(i)
|
||||
end
|
||||
end
|
||||
|
||||
BuildMenu = function()
|
||||
BASE:I("--- Info: Building menu ---")
|
||||
|
||||
-- Gets the number of units in the group
|
||||
units = GROUP:FindByName( PlayersGroupName ):GetUnits()
|
||||
|
||||
-- AmmoCheckMainMenu
|
||||
Level1 = MENU_MISSION:New( "Flight Ammo Check" )
|
||||
LevelMenues = {}
|
||||
CommandMenues = {}
|
||||
for i = 2, #units do
|
||||
LevelMenues[i] = MENU_MISSION:New( "Wingman " .. i, Level1 )
|
||||
CommandMenues[i] = MENU_MISSION_COMMAND:New("AmmoStatus " .. i, LevelMenues[i], AmmoCheck, i)
|
||||
end
|
||||
CommandMenuesAll = MENU_MISSION_COMMAND:New("AmmoStatus All", Level1, CheckAll)
|
||||
end
|
||||
|
||||
-- BASE:ScheduleOnce(10,BuildMenu) If you prefer a scheduled command
|
||||
|
||||
HandleDeath = EVENTHANDLER:New():HandleEvent(EVENTS.Dead)
|
||||
|
||||
function HandleDeath:OnEventDead(EventData)
|
||||
if EventData.IniGroupName == PlayersGroupName then
|
||||
BuildMenu()
|
||||
end
|
||||
end
|
||||
---
|
||||
-- Author: Wingthor and Saint185
|
||||
-- Created: 15.01.2021
|
||||
-- Contributors: kaltokri
|
||||
-- Modified: 18.05.2024
|
||||
--
|
||||
-- # Documentation:
|
||||
-- https://flightcontrol-master.github.io/MOOSE_DOCS_DEVELOP/Documentation/Core.Menu.html
|
||||
--
|
||||
-- # Description:
|
||||
--
|
||||
-- A squad with four Su-25T is placed. One player with 3 AI.
|
||||
-- After a few seconds a menu is added to check loadout of the AI.
|
||||
--
|
||||
-- Check the code on how to create a dynamic menu with a for-iteration and a table.
|
||||
-- A forward declaration of a function is used in this example.
|
||||
-- The logic of this script is universal. It will work with any human flyable plane.
|
||||
-- No matter of coalition RED or BLUE. Just name your GROUP "Player".
|
||||
-- Under the Skill box select "client" as your own plane.
|
||||
--
|
||||
-- # Guide:
|
||||
-- - Start the mission, choose coalition BLUE and Pilot slot.
|
||||
-- - Wait a few seconds and open radio menu F10 Others...
|
||||
-- - Choose loadout to print.
|
||||
|
||||
|
||||
BASE:TraceOnOff(true)
|
||||
BASE:TraceAll(true)
|
||||
|
||||
------------------------------------ GLOBALS For easy mission tweaking -------------------------------------------------
|
||||
CASZone = "Zone Charlie"
|
||||
PlayersGroupName = "Player"
|
||||
BuildMenu = function() end -- Forward declaration
|
||||
------------------------------------ END GLOBALS -----------------------------------------------------------------------
|
||||
|
||||
env.info ("------------------------- STARING SCRIPT ---------------------------------")
|
||||
|
||||
--Create TASK Zone
|
||||
local zoneCharlie = ZONE:New(CASZone)
|
||||
|
||||
-- Add scheduled command, now holds the BuildMenu Call.
|
||||
local start = SCHEDULER:New(nil,
|
||||
function()
|
||||
-- Create a flight group.
|
||||
flightgroup = FLIGHTGROUP:New(PlayersGroupName)
|
||||
flightgroup:SetDetection(true)
|
||||
|
||||
--- Function called when the group detects a previously unknown unit.
|
||||
function flightgroup:OnAfterDetectedUnitNew(From, Event, To, Unit)
|
||||
local unit = Unit --Wrapper.Unit#UNIT
|
||||
-- Message to everybody and in the DCS log file.
|
||||
local text = string.format("Detected unit %s", unit:GetName())
|
||||
MESSAGE:New(text, 20,flightgroup:GetName()):ToAll()
|
||||
env.info(text)
|
||||
end
|
||||
|
||||
-- Create a CAS mission.
|
||||
local mission = AUFTRAG:NewCAS(zoneCharlie)
|
||||
mission:SetEngageAltitude(10000)
|
||||
mission:SetWeaponExpend(AI.Task.WeaponExpend.ONE)
|
||||
|
||||
-- Assign mission to pilot.
|
||||
flightgroup:AddMission(mission)
|
||||
-- Build Menu for ammo check.
|
||||
BuildMenu()
|
||||
end,
|
||||
{},1,30000 )
|
||||
|
||||
--- Function to check ammo for a give wingman.
|
||||
-- @param Wingman number
|
||||
local function AmmoCheck(Wingman)
|
||||
-- Gets the ammo for each unit and dumps it into unittable TABLE.
|
||||
local unitsAmmoTable = units[Wingman]:GetAmmo()
|
||||
|
||||
-- Gets the callsign for each unit and dumps it into callsign TABLE.
|
||||
local callsign = units[Wingman]:GetCallsign()
|
||||
|
||||
-- This logic splits out each ammo type and name and inserts it into the message.
|
||||
local count = {}
|
||||
local desc = {}
|
||||
-- local ammoUnits = ammo[2]
|
||||
local WepMessage = " "
|
||||
for i = 1, #unitsAmmoTable do
|
||||
local ammocount = unitsAmmoTable[i].count
|
||||
local ammodesc = unitsAmmoTable[i].desc.displayName
|
||||
table.insert (count, ammocount)
|
||||
table.insert (desc, ammodesc)
|
||||
WepMessage = WepMessage .. desc[i] .. ": " .. count[i] .. "\n "
|
||||
end
|
||||
MESSAGE:New( callsign ..":\n------------------------------------\n" .. WepMessage, 10):ToAll()
|
||||
end
|
||||
|
||||
local function CheckAll()
|
||||
-- Gets the number of units in the group
|
||||
units = GROUP:FindByName( PlayersGroupName ):GetUnits()
|
||||
for i = 2, #units do
|
||||
AmmoCheck(i)
|
||||
end
|
||||
end
|
||||
|
||||
BuildMenu = function()
|
||||
BASE:I("--- Info: Building menu ---")
|
||||
|
||||
-- Gets the number of units in the group
|
||||
units = GROUP:FindByName( PlayersGroupName ):GetUnits()
|
||||
|
||||
-- AmmoCheckMainMenu
|
||||
Level1 = MENU_MISSION:New( "Flight Ammo Check" )
|
||||
LevelMenues = {}
|
||||
CommandMenues = {}
|
||||
for i = 2, #units do
|
||||
LevelMenues[i] = MENU_MISSION:New( "Wingman " .. i, Level1 )
|
||||
CommandMenues[i] = MENU_MISSION_COMMAND:New("AmmoStatus " .. i, LevelMenues[i], AmmoCheck, i)
|
||||
end
|
||||
CommandMenuesAll = MENU_MISSION_COMMAND:New("AmmoStatus All", Level1, CheckAll)
|
||||
end
|
||||
|
||||
-- BASE:ScheduleOnce(10,BuildMenu) If you prefer a scheduled command
|
||||
|
||||
HandleDeath = EVENTHANDLER:New():HandleEvent(EVENTS.Dead)
|
||||
|
||||
function HandleDeath:OnEventDead(EventData)
|
||||
if EventData.IniGroupName == PlayersGroupName then
|
||||
BuildMenu()
|
||||
end
|
||||
end
|
||||
|
||||
Binary file not shown.
Reference in New Issue
Block a user