Add configurable crash-site salvage; record Workshop 0.0.146
continuous-integration/drone/push Build is passing
continuous-integration/drone/push Build is passing
This commit is contained in:
@@ -0,0 +1,9 @@
|
||||
GenericEntity : "{B90E5414AB7C325B}Prefabs/Props/Wrecks/BTR70_Wreck/BTR70_wreck_static.et" {
|
||||
ID "9EA3A65E039FDAC0"
|
||||
components {
|
||||
Hierarchy "{BD920DE465D04435}" {}
|
||||
RplComponent "{7E4852E4567E49D6}" { Streamable Disabled }
|
||||
}
|
||||
coords 0 0 0
|
||||
angles 0 0 0
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
MetaFileClass {
|
||||
Name "{56C7BD958478A96D}Prefabs/ERR/CrashArmorWreck.et"
|
||||
Configurations {
|
||||
ResourceClass PC {}
|
||||
ResourceClass HEADLESS : PC {}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
GenericEntity : "{EBBC859CCD94D96D}Prefabs/Props/EmptyStorages/USSR_AmmoBox_empty.et" {
|
||||
ID "A2DD3ADFFC0219D9"
|
||||
components {
|
||||
RplComponent "{6530845A09302A0A}" { Streamable Disabled }
|
||||
MeshObject "{6530845A09309E37}" {
|
||||
Object "{819ED3266EE5113B}Assets/Props/Military/AmmoBox/EquipmentBoxWooden_01/EquipmentBoxWooden_Weapon_01.xob"
|
||||
Materials {
|
||||
MaterialAssignClass "{6530845A093091BB}" {
|
||||
SourceMaterial "EquipmentBoxWooden_Weapon_01"
|
||||
AssignedMaterial "{7D2E831AFA5CF50D}Assets/Props/Military/AmmoBox/EquipmentBoxWooden_01/Data/EquipmentBoxWooden_Weapon_01_USSR.emat"
|
||||
}
|
||||
MaterialAssignClass "{6530845A093091B2}" {
|
||||
SourceMaterial "EquipmentBoxWooden_Weapon_01_Decal"
|
||||
}
|
||||
}
|
||||
}
|
||||
SCR_UniversalInventoryStorageComponent "{6530845A09302DE0}" {
|
||||
MaxCumulativeVolume 1000000
|
||||
MaxItemSize 200 100 100
|
||||
m_fMaxWeight 400
|
||||
Attributes SCR_ItemAttributeCollection "{6530845A09302DFF}" {
|
||||
ItemDisplayName SCR_InventoryUIInfo "{6530845A09302D03}" {
|
||||
Name "Crash-site weapons"
|
||||
Description "Salvaged weapons and ammunition. This crate does not refill."
|
||||
}
|
||||
}
|
||||
}
|
||||
InventoryStorageManagerComponent "{18A1D42A468F584F}" {}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
MetaFileClass {
|
||||
Name "{CD7E33406E1ACA1D}Prefabs/ERR/CrashLootCrate.et"
|
||||
Configurations {
|
||||
ResourceClass PC {}
|
||||
ResourceClass HEADLESS : PC {}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
ReplicatedParticleEffectEntity {
|
||||
ID "3B6ACA9A82472A27"
|
||||
components {
|
||||
Hierarchy "{666ECA1B7BACEF74}" {}
|
||||
RplComponent "{7E4852E4567E49D6}" { Streamable Disabled }
|
||||
}
|
||||
UseFrameEvent 1
|
||||
EffectPath "{6EE3295AC363E562}Particles/Enviroment/Smoke_Smokestack_Big.ptc"
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
MetaFileClass {
|
||||
Name "{2608501780FEE1EA}Prefabs/ERR/CrashLootSmoke.et"
|
||||
Configurations {
|
||||
ResourceClass PC {}
|
||||
ResourceClass HEADLESS : PC {}
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,7 @@ class ERR_AdminMenuFields
|
||||
{
|
||||
static array<string> Keys()
|
||||
{
|
||||
return {"aiDoctrine", "aiShadow", "automaticEquipmentChancePercent", "sarkaAngerPerCar", "motorbikeCount", "droneReconCount", "droneCooldownSeconds", "planeAltitudeMetres", "planeReplacementSeconds", "planeSectorSeconds", "fieldCampCount", "fieldHospitalCount", "startWeaponCount", "startMagazineCount", "objectGuardCount", "objectGuardEvery", "objectGuardHQMode", "hunterSpawnDistanceMetres", "roadblockCount", "largeRoadblockCount", "mainRoadWidthMetres", "civilianTrafficCount", "garageVehicleCount", "garageChancePercent", "garageRadiusMetres", "garageSpawnIntervalSeconds", "emptyRestartHours", "startMode", "radioDefenceSeconds", "aiIntelChancePercent", "intelRevealChancePercent", "radioIntelSiteCount", "startTimeMinutes", "timeMultiplier", "startDateCode", "weatherProfile", "viewDistanceMetres", "reportIntervalSeconds", "supportSquadLimit", "responseRadiusMetres", "convoyCount", "antiAirChancePercent", "antiPersonnelMineChancePercent", "heliTimerMinutes"};
|
||||
return {"crashLootMode", "crashSiteCount", "crashHelicopterChancePercent", "crashRifleCount", "crashMagazineCount", "crashAntiAirChancePercent", "crashRocketChancePercent", "aiDoctrine", "aiShadow", "automaticEquipmentChancePercent", "sarkaAngerPerCar", "motorbikeCount", "droneReconCount", "droneCooldownSeconds", "planeAltitudeMetres", "planeReplacementSeconds", "planeSectorSeconds", "fieldCampCount", "fieldHospitalCount", "startWeaponCount", "startMagazineCount", "objectGuardCount", "objectGuardEvery", "objectGuardHQMode", "hunterSpawnDistanceMetres", "roadblockCount", "largeRoadblockCount", "mainRoadWidthMetres", "civilianTrafficCount", "garageVehicleCount", "garageChancePercent", "garageRadiusMetres", "garageSpawnIntervalSeconds", "emptyRestartHours", "startMode", "radioDefenceSeconds", "aiIntelChancePercent", "intelRevealChancePercent", "radioIntelSiteCount", "startTimeMinutes", "timeMultiplier", "startDateCode", "weatherProfile", "viewDistanceMetres", "reportIntervalSeconds", "supportSquadLimit", "responseRadiusMetres", "convoyCount", "antiAirChancePercent", "antiPersonnelMineChancePercent", "heliTimerMinutes"};
|
||||
}
|
||||
static bool Available(string key, bool hq, bool intel)
|
||||
{
|
||||
@@ -26,6 +26,7 @@ class ERR_AdminMenuFields
|
||||
}
|
||||
static string Display(string key, string value)
|
||||
{
|
||||
if (key == "crashLootMode") { if (value == "1") return "Random"; return "Custom"; }
|
||||
if (key == "aiDoctrine") { if (value == "1") return "Coordinated"; return "Current"; }
|
||||
if (key == "aiShadow") { if (value == "1") return "On"; return "Off"; }
|
||||
if (value == "-1" || value == "-2") return ERR_Settings.SelectionText(value.ToInt());
|
||||
@@ -60,6 +61,13 @@ class ERR_AdminMenuFields
|
||||
else if (key == "objectGuardHQMode") prefix = "mission objecthq";
|
||||
else if (key == "objectGuardCount") prefix = "mission objectguards";
|
||||
else if (key == "hunterSpawnDistanceMetres") prefix = "mission hunterdistance";
|
||||
else if (key == "crashLootMode") prefix = "mission crashloot";
|
||||
else if (key == "crashSiteCount") prefix = "mission crashsites";
|
||||
else if (key == "crashHelicopterChancePercent") prefix = "mission crashhelis";
|
||||
else if (key == "crashRifleCount") prefix = "mission crashrifles";
|
||||
else if (key == "crashMagazineCount") prefix = "mission crashammo";
|
||||
else if (key == "crashAntiAirChancePercent") prefix = "mission crashaa";
|
||||
else if (key == "crashRocketChancePercent") prefix = "mission crashrockets";
|
||||
else if (key == "fieldCampCount") prefix = "mission camps";
|
||||
else if (key == "fieldHospitalCount") prefix = "mission hospitals";
|
||||
else if (key == "roadblockCount") prefix = "mission roadblocks";
|
||||
|
||||
@@ -30,17 +30,18 @@ enum ERR_AdminPage
|
||||
CHECKPOINTS = 26,
|
||||
VEHICLE_POOL = 27,
|
||||
PACKS = 28,
|
||||
CRASH_SITES = 29,
|
||||
}
|
||||
|
||||
class ERR_AdminMenuPages
|
||||
{
|
||||
static array<string> Pages() { return {"SettingsPage", "HQPage", "JournalPage", "ModsPage", "FactionsPage", "WorldPage", "IntelPage", "StatusPage", "TerrainsPage", "ItemsPage", "TTSPage", "ForcesPage", "GuardsPage", "SitesPage", "PlanePage", "RecommendationsPage", "WeightsPage", "AllowedItemsPage", "ItemPresetsPage", "AIPage", "StarterPage", "SarkaPage", "DronesPage", "RadioIntelPage", "TelemetryPage", "VehiclesPage", "CheckpointsPage", "VehiclePoolPage", "PacksPage"}; }
|
||||
static array<string> Navigation() { return {"OpenSettings", "OpenHQ", "OpenJournal", "OpenMods", "OpenFactions", "OpenWorld", "OpenIntel", "OpenStatus", "OpenTerrains", "OpenItems", "OpenTTS", "OpenForces", "OpenGuards", "OpenSites", "OpenPlane", "OpenRecommendations", "OpenWeights", "OpenAllowedItems", "OpenItemPresets", "OpenAI", "OpenStarter", "OpenSarka", "OpenDrones", "OpenRadioIntel", "OpenTelemetry", "OpenVehicles", "OpenCheckpoints", "OpenVehiclePool", "OpenPacks"}; }
|
||||
static array<string> Pages() { return {"SettingsPage", "HQPage", "JournalPage", "ModsPage", "FactionsPage", "WorldPage", "IntelPage", "StatusPage", "TerrainsPage", "ItemsPage", "TTSPage", "ForcesPage", "GuardsPage", "SitesPage", "PlanePage", "RecommendationsPage", "WeightsPage", "AllowedItemsPage", "ItemPresetsPage", "AIPage", "StarterPage", "SarkaPage", "DronesPage", "RadioIntelPage", "TelemetryPage", "VehiclesPage", "CheckpointsPage", "VehiclePoolPage", "PacksPage", "CrashSitesPage"}; }
|
||||
static array<string> Navigation() { return {"OpenSettings", "OpenHQ", "OpenJournal", "OpenMods", "OpenFactions", "OpenWorld", "OpenIntel", "OpenStatus", "OpenTerrains", "OpenItems", "OpenTTS", "OpenForces", "OpenGuards", "OpenSites", "OpenPlane", "OpenRecommendations", "OpenWeights", "OpenAllowedItems", "OpenItemPresets", "OpenAI", "OpenStarter", "OpenSarka", "OpenDrones", "OpenRadioIntel", "OpenTelemetry", "OpenVehicles", "OpenCheckpoints", "OpenVehiclePool", "OpenPacks", "OpenCrashSites"}; }
|
||||
static array<string> MainButtons() { return {"Main_Mission", "Main_Forces", "Main_HQ", "Main_Intel", "Main_Content", "Main_Audio", "Main_Status"}; }
|
||||
static array<string> Sidebars() { return {"Sidebar_Mission", "Sidebar_Forces", "Sidebar_HQ", "Sidebar_Intel", "Sidebar_Content", "Sidebar_Audio", "Sidebar_Status"}; }
|
||||
static int Group(int page)
|
||||
{
|
||||
array<int> groups = {0, 2, 6, 4, 1, 0, 3, 6, 0, 4, 5, 1, 1, 1, 2, 0, 4, 4, 4, 2, 4, 1, 2, 3, 0, 4, 1, 4, 1};
|
||||
array<int> groups = {0, 2, 6, 4, 1, 0, 3, 6, 0, 4, 5, 1, 1, 1, 2, 0, 4, 4, 4, 2, 4, 1, 2, 3, 0, 4, 1, 4, 1, 1};
|
||||
if (page < 0 || page >= groups.Count()) return -1;
|
||||
return groups[page];
|
||||
}
|
||||
|
||||
@@ -16,6 +16,13 @@ class ERR_CommandArguments
|
||||
if (section == "mission" && option == "dronecooldown") return "droneCooldownSeconds";
|
||||
if (section == "mission" && option == "plane") return "planeReconEnabled";
|
||||
if (section == "mission" && option == "camps") return "fieldCampCount";
|
||||
if (section == "mission" && option == "crashloot") return "crashLootMode";
|
||||
if (section == "mission" && option == "crashsites") return "crashSiteCount";
|
||||
if (section == "mission" && option == "crashhelis") return "crashHelicopterChancePercent";
|
||||
if (section == "mission" && option == "crashrifles") return "crashRifleCount";
|
||||
if (section == "mission" && option == "crashammo") return "crashMagazineCount";
|
||||
if (section == "mission" && option == "crashaa") return "crashAntiAirChancePercent";
|
||||
if (section == "mission" && option == "crashrockets") return "crashRocketChancePercent";
|
||||
if (section == "mission" && option == "hospitals") return "fieldHospitalCount";
|
||||
if (section == "mission" && option == "startweapons") return "startWeaponCount";
|
||||
if (section == "mission" && option == "startammo") return "startMagazineCount";
|
||||
@@ -44,6 +51,8 @@ class ERR_CommandArguments
|
||||
}
|
||||
static bool Selection(string key, string text, out int value)
|
||||
{
|
||||
if (key == "crashLootMode" && text == "random") { value = 1; return true; }
|
||||
if (key == "crashLootMode" && text == "custom") { value = 0; return true; }
|
||||
if (key == "aiDoctrine" && text == "current") { value = 0; return true; }
|
||||
if (key == "aiDoctrine" && text == "coordinated") { value = 1; return true; }
|
||||
if ((key == "aiShadow" || key == "restartOnEmpty" || key == "showAllSites") && text == "off") { value = 0; return true; }
|
||||
@@ -191,6 +200,13 @@ class ERR_AdminService
|
||||
if (key == "planeSectorSeconds") return "30-600; default 120. Applies next round.";
|
||||
if (key == "planeReconEnabled") return "0 disabled, 1 enabled if Cessna 172 and Propeller Flight Core are loaded. Applies next round. A clear airport departure area is required.";
|
||||
if (key == "fieldCampCount") return "1..16 field camps; default 12. Applies next round. Counts are requested: unsafe optional sites may be omitted.";
|
||||
if (key == "crashLootMode") return "Random (1, default): each crate rolls independently from poor pistol supplies to rich scoped-rifle/launcher loot. Custom (0): use configured rifle, ammo and launcher values. Next round.";
|
||||
if (key == "crashSiteCount") return "0..12; default 3. 0 disables sites. Finite wrecks and loot; no refills. Applies next round.";
|
||||
if (key == "crashHelicopterChancePercent") return "0..100; default 50. 0 = armored wrecks; 100 = helicopters. Applies next round.";
|
||||
if (key == "crashRifleCount") return "1..6; default 3. Random M21 / SVD rifles with fitted scopes. Custom loot mode only; next round.";
|
||||
if (key == "crashMagazineCount") return "1..8; default 4. Matching ammunition for each selected rifle. Custom loot mode only; next round.";
|
||||
if (key == "crashAntiAirChancePercent") return "0..100; default 25. One loaded Stinger, if installed and enabled. Custom loot mode only; next round.";
|
||||
if (key == "crashRocketChancePercent") return "0..100; default 50. One scoped RPG-7 with two matching rockets. Custom loot mode only; next round.";
|
||||
if (key == "fieldHospitalCount") return "1..8 field hospitals; default 6. Applies next round. The required radio-clue hospital is retained.";
|
||||
if (key == "objectGuardEvery") return "Guard every 1st, 2nd, 3rd or 4th eligible site; default every third. Nearby buildings share one site. Next round.";
|
||||
if (key == "objectGuardHQMode") return "0: all hold their posts; 1: half hold, half respond to HQ; 2: all may respond to HQ. All report contacts. Next round.";
|
||||
@@ -219,7 +235,7 @@ class ERR_AdminService
|
||||
}
|
||||
protected string RoadblockTiming(string key)
|
||||
{
|
||||
if (key == "radioIntelSiteCount" || key == "garageVehicleCount" || key == "garageChancePercent" || key == "garageRadiusMetres" || key == "garageSpawnIntervalSeconds") return " for next round";
|
||||
if (key == "crashLootMode" || key == "crashSiteCount" || key == "crashHelicopterChancePercent" || key == "crashRifleCount" || key == "crashMagazineCount" || key == "crashAntiAirChancePercent" || key == "crashRocketChancePercent" || key == "radioIntelSiteCount" || key == "garageVehicleCount" || key == "garageChancePercent" || key == "garageRadiusMetres" || key == "garageSpawnIntervalSeconds") return " for next round";
|
||||
if (key == "aiDoctrine" || key == "aiShadow" || key == "droneReconCount" || key == "droneCooldownSeconds") return " for next round";
|
||||
if (key == "motorbikeCount" || key == "planeAltitudeMetres" || key == "planeReplacementSeconds" || key == "planeSectorSeconds" || key == "planeReconEnabled" || key == "fieldCampCount" || key == "fieldHospitalCount" || key == "startWeaponCount" || key == "startMagazineCount" || key == "objectGuardCount" || key == "objectGuardEvery" || key == "objectGuardHQMode" || key == "hunterSpawnDistanceMetres" || key == "roadblockCount" || key == "largeRoadblockCount" || key == "mainRoadWidthMetres") return " for next round";
|
||||
return "";
|
||||
|
||||
@@ -184,6 +184,7 @@ class ERR_AdminSession
|
||||
GetGame().ERR_ServerVehicles().Snapshot(values, m_VehicleAddon, m_VehiclePage, m_VehicleFilter, m_VehicleQuery, m_VehicleRole);
|
||||
GetGame().ERR_StartingSupplies().Snapshot(values);
|
||||
m_Mode.Admin().Execute(m_Mode, true, "status", status);
|
||||
if (m_Mode.CrashSites()) status.Insert(m_Mode.CrashSites().Status());
|
||||
m_Controller.ERR_AdminDeliverSnapshot(m_Token, true, values, status);
|
||||
}
|
||||
void Log(int cursor, bool latest)
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
// Curated compatible weapon/ammunition pairs. No dependency is added for AA.
|
||||
class ERR_CrashLoot
|
||||
{
|
||||
static ResourceName Rifle(bool west)
|
||||
{
|
||||
if (west) return "{81EB948E6414BD6F}Prefabs/Weapons/Rifles/M14/Rifle_M21_ARTII.et";
|
||||
return "{6415B7923DE28C1B}Prefabs/Weapons/Rifles/SVD/Rifle_SVD_PSO.et";
|
||||
}
|
||||
static ResourceName Magazine(bool west)
|
||||
{
|
||||
if (west) return "{627255315038152A}Prefabs/Weapons/Magazines/Magazine_762x51_M14_20rnd_SpecialBall.et";
|
||||
return "{9CCB46C6EE632C1A}Prefabs/Weapons/Magazines/Magazine_762x54_SVD_10rnd_Sniper.et";
|
||||
}
|
||||
static ResourceName Scope(bool west)
|
||||
{
|
||||
if (west) return "{D2018EDB1BBF4C88}Prefabs/Weapons/Attachments/Optics/Optic_ARTII/Optic_ARTII.et";
|
||||
return "{C850A33226B8F9C1}Prefabs/Weapons/Attachments/Optics/Optic_PSO1/Optic_PSO1.et";
|
||||
}
|
||||
static ResourceName RPG() { return "{E8A55396050E1762}Prefabs/Weapons/Launchers/RPG7/Launcher_RPG7_PGO7.et"; }
|
||||
static ResourceName Rocket() { return "{609E216CBF8D0B68}Prefabs/Weapons/Ammo/Ammo_Rocket_PG7VL.et"; }
|
||||
static bool Allowed(ResourceName prefab)
|
||||
{
|
||||
if (!GetGame().ERR_ItemSelections().Allows(prefab)) return false;
|
||||
Resource resource = Resource.Load(prefab);
|
||||
return resource && resource.IsValid();
|
||||
}
|
||||
static bool RifleAllowed(bool west) { return Allowed(Rifle(west)) && Allowed(Magazine(west)) && Allowed(Scope(west)); }
|
||||
// Roll quality once per site, then quantities within that quality. Never reroll on opening.
|
||||
static void RandomPlan(array<ResourceName> items)
|
||||
{
|
||||
QualityPlan(Math.RandomInt(0, 100), items);
|
||||
}
|
||||
static void QualityPlan(int quality, array<ResourceName> items)
|
||||
{
|
||||
items.Clear();
|
||||
if (quality < 30)
|
||||
{
|
||||
// Poor salvage can be only a few pistol magazines, without a weapon.
|
||||
if (!Allowed(ERR_Supplies.Magazine())) return;
|
||||
if (Math.RandomInt(0, 2) == 1 && Allowed(ERR_Supplies.Pistol())) items.Insert(ERR_Supplies.Pistol());
|
||||
int magazines = Math.RandomInt(1, 4);
|
||||
for (int i = 0; i < magazines; i++) items.Insert(ERR_Supplies.Magazine());
|
||||
return;
|
||||
}
|
||||
if (quality < 65) { Plan(1, Math.RandomInt(1, 4), 0, 0, items); return; }
|
||||
if (quality < 90) { Plan(Math.RandomInt(2, 4), Math.RandomInt(2, 6), 15, 35, items); return; }
|
||||
Plan(Math.RandomInt(4, 7), Math.RandomInt(4, 9), 50, 75, items);
|
||||
}
|
||||
static void Plan(int rifles, int magazines, int aaChance, int rocketChance, array<ResourceName> items)
|
||||
{
|
||||
items.Clear();
|
||||
bool west = RifleAllowed(true), east = RifleAllowed(false);
|
||||
for (int i = 0; i < rifles && (west || east); i++)
|
||||
{
|
||||
bool useWest = west && (!east || Math.RandomInt(0, 2) == 0);
|
||||
items.Insert(Rifle(useWest));
|
||||
for (int j = 0; j < magazines; j++) items.Insert(Magazine(useWest));
|
||||
}
|
||||
if (Math.RandomInt(0, 100) < rocketChance && Allowed(RPG()) && Allowed(Rocket())
|
||||
&& Allowed("{E5E9DBBF3BFB88C6}Prefabs/Weapons/Attachments/Optics/Optic_PGO7/Optic_PGO7V3.et"))
|
||||
{
|
||||
items.Insert(RPG()); items.Insert(Rocket()); items.Insert(Rocket());
|
||||
}
|
||||
// The inspected WCS Stinger is disposable and already contains one missile.
|
||||
if (Math.RandomInt(0, 100) < aaChance && Allowed(ERR_EnemyLoadoutCatalog.FIM)
|
||||
&& Allowed("{517333DE6AADE624}Prefabs/Weapons/Ammo/WCS/Ammo_Missile_FIM92.et")) items.Insert(ERR_EnemyLoadoutCatalog.FIM);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,200 @@
|
||||
class ERR_CrashSite
|
||||
{
|
||||
vector Position;
|
||||
IEntity Wreck;
|
||||
IEntity Smoke;
|
||||
IEntity Crate;
|
||||
ref array<IEntity> Stock = {};
|
||||
bool Ready;
|
||||
}
|
||||
|
||||
// Finite server-owned scenery. Small bounded steps never block mission preparation.
|
||||
class ERR_CrashSites
|
||||
{
|
||||
protected ERR_GameMode m_Mode;
|
||||
protected ref array<ref ERR_CrashSite> m_Sites = {};
|
||||
protected ref ERR_CampTerrain m_Terrain = new ERR_CampTerrain();
|
||||
protected ref array<ResourceName> m_Loot = {};
|
||||
protected ERR_CrashSite m_Pending;
|
||||
protected InventoryStorageManagerComponent m_Inventory;
|
||||
protected IEntity m_Item;
|
||||
protected bool m_Accepted, m_ItemIssued, m_Started, m_Stopped;
|
||||
protected int m_Target, m_Consumed, m_Attempts, m_HeliChance, m_LootMode, m_Rifles, m_Magazines, m_AA, m_Rockets;
|
||||
protected int m_ItemIndex, m_ItemTicks, m_Skipped;
|
||||
void ERR_CrashSites(ERR_GameMode mode) { m_Mode = mode; }
|
||||
int Count() { return m_Sites.Count(); }
|
||||
ERR_CrashSite At(int index) { return m_Sites[index]; }
|
||||
string Status()
|
||||
{
|
||||
return string.Format("Crash sites: %1/%2 created; %3 unsuitable slots skipped. Finite loot; no refills.", Count(), m_Target, m_Skipped);
|
||||
}
|
||||
void Start()
|
||||
{
|
||||
if (m_Started || m_Stopped || !Replication.IsServer() || !m_Mode) return;
|
||||
m_Started = true;
|
||||
ERR_Settings settings = m_Mode.Settings();
|
||||
m_LootMode = settings.Get("crashLootMode");
|
||||
m_Target = settings.Get("crashSiteCount"); m_HeliChance = settings.Get("crashHelicopterChancePercent");
|
||||
m_Rifles = settings.Get("crashRifleCount"); m_Magazines = settings.Get("crashMagazineCount");
|
||||
m_AA = settings.Get("crashAntiAirChancePercent"); m_Rockets = settings.Get("crashRocketChancePercent");
|
||||
if (m_Target > 0) GetGame().GetCallqueue().CallLater(Step, 250, true);
|
||||
}
|
||||
protected bool Ready()
|
||||
{
|
||||
if (!m_Mode.Sites() || !GetGame().GetWorldEntity()) return false;
|
||||
ERR_ScenarioComponent scenario = ERR_ScenarioComponent.Cast(m_Mode.FindComponent(ERR_ScenarioComponent));
|
||||
return scenario && !scenario.BackgroundPending();
|
||||
}
|
||||
protected bool Separated(vector point)
|
||||
{
|
||||
foreach (ERR_CrashSite site : m_Sites) if (vector.DistanceXZ(site.Position, point) < 600) return false;
|
||||
if (m_Mode.Sites())
|
||||
for (int i = 0; i < m_Mode.Sites().Count(); i++)
|
||||
{
|
||||
ERR_SiteRuntime other = m_Mode.Sites().At(i);
|
||||
if (other && other.Definition && vector.DistanceXZ(other.Definition.Position, point) < 250) return false;
|
||||
}
|
||||
array<int> players = {}; GetGame().GetPlayerManager().GetPlayers(players);
|
||||
foreach (int id : players)
|
||||
{
|
||||
IEntity actor = GetGame().GetPlayerManager().GetPlayerControlledEntity(id);
|
||||
if (actor && vector.DistanceXZ(actor.GetOrigin(), point) < 400) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
protected bool Survey(out vector point, out float heading)
|
||||
{
|
||||
vector low, high; GetGame().GetWorldEntity().GetWorldBounds(low, high);
|
||||
point = Vector(Math.RandomFloat(low[0], high[0]), 0, Math.RandomFloat(low[2], high[2]));
|
||||
heading = Math.RandomFloat(0, 360);
|
||||
if (!Separated(point)) return false;
|
||||
SCR_AIWorld ai = SCR_AIWorld.Cast(GetGame().GetAIWorld());
|
||||
if (!ai || !ai.GetRoadNetworkManager()) return false;
|
||||
BaseRoad road; float distance;
|
||||
ai.GetRoadNetworkManager().GetClosestRoad(point, road, distance, skipNavlinks: true);
|
||||
if (road && distance < 20) return false;
|
||||
float floor;
|
||||
// Includes UH-1 tail (-8.8m), armor, smoke and the crate at x=6m plus access.
|
||||
if (!m_Terrain.Clear(point, heading, 11, 0.6, floor, 5)) return false;
|
||||
point = ERR_Actors.Ground(point);
|
||||
return true;
|
||||
}
|
||||
protected IEntity Spawn(ResourceName resource, vector position, vector angles)
|
||||
{
|
||||
IEntity entity = ERR_Actors.Spawn(resource, position, angles);
|
||||
if (entity) m_Mode.Own(entity);
|
||||
return entity;
|
||||
}
|
||||
protected bool Create(vector point, float heading)
|
||||
{
|
||||
if (m_LootMode == 1) ERR_CrashLoot.RandomPlan(m_Loot);
|
||||
else ERR_CrashLoot.Plan(m_Rifles, m_Magazines, m_AA, m_Rockets, m_Loot);
|
||||
if (m_Loot.IsEmpty() && m_LootMode == 0) return false;
|
||||
ERR_CrashSite site = new ERR_CrashSite(); site.Position = point;
|
||||
ResourceName wreck = "{56C7BD958478A96D}Prefabs/ERR/CrashArmorWreck.et";
|
||||
if (Math.RandomInt(0, 100) < m_HeliChance) wreck = ERR_CrashSiteResources.WreckPrefab();
|
||||
vector wreckPoint = point;
|
||||
if (wreck == ERR_CrashSiteResources.WreckPrefab())
|
||||
{
|
||||
vector minimum, maximum;
|
||||
if (ERR_CrashSiteResources.Bounds(minimum, maximum)) wreckPoint[1] = wreckPoint[1] - minimum[1];
|
||||
}
|
||||
site.Wreck = Spawn(wreck, wreckPoint, Vector(heading, 0, 0));
|
||||
vector cratePoint = ERR_Actors.Ground(point + ERR_CampTerrain.Rotate("6 0 0", heading));
|
||||
site.Crate = Spawn("{CD7E33406E1ACA1D}Prefabs/ERR/CrashLootCrate.et", cratePoint + "0 0.1 0", Vector(heading, 0, 0));
|
||||
site.Smoke = Spawn("{2608501780FEE1EA}Prefabs/ERR/CrashLootSmoke.et", point + "0 1 0", "0 0 0");
|
||||
if (site.Crate) m_Inventory = InventoryStorageManagerComponent.Cast(site.Crate.FindComponent(InventoryStorageManagerComponent));
|
||||
BaseInventoryStorageComponent storage;
|
||||
if (site.Crate) storage = BaseInventoryStorageComponent.Cast(site.Crate.FindComponent(BaseInventoryStorageComponent));
|
||||
if (!site.Wreck || !site.Crate || !site.Smoke || !m_Inventory || !storage)
|
||||
{
|
||||
ERR_Actors.DeleteSpawned(site.Smoke); ERR_Actors.DeleteSpawned(site.Crate); ERR_Actors.DeleteSpawned(site.Wreck);
|
||||
m_Inventory = null; return false;
|
||||
}
|
||||
ParticleEffectEntity smoke = ParticleEffectEntity.Cast(site.Smoke);
|
||||
if (smoke) { smoke.SetDeleteWhenStopped(false); smoke.Play(); }
|
||||
m_Inventory.AddStorage(storage);
|
||||
m_Sites.Insert(site); m_Pending = site; m_ItemIndex = 0;
|
||||
SCR_AIWorld ai = SCR_AIWorld.Cast(GetGame().GetAIWorld());
|
||||
if (ai) ai.RequestNavmeshRebuildEntity(site.Wreck);
|
||||
return true;
|
||||
}
|
||||
protected void Fill()
|
||||
{
|
||||
if (!m_Pending.Crate || !m_Inventory) { Finish(); return; }
|
||||
if (m_Item)
|
||||
{
|
||||
array<IEntity> items = {}; m_Inventory.GetItems(items);
|
||||
InventoryItemComponent itemComponent = InventoryItemComponent.Cast(m_Item.FindComponent(InventoryItemComponent));
|
||||
// A player may take the item between insertion and this confirmation tick.
|
||||
// Any attached inventory slot consumes the grant; never steal it back.
|
||||
if (items.Contains(m_Item) || (itemComponent && itemComponent.GetParentSlot()))
|
||||
{
|
||||
m_Pending.Stock.Insert(m_Item); m_Item = null; m_ItemIssued = false; m_ItemIndex++; m_ItemTicks = 0; m_Accepted = false;
|
||||
return;
|
||||
}
|
||||
m_ItemTicks++;
|
||||
if (m_ItemTicks > 12)
|
||||
{
|
||||
Print("Reintroduced [crash sites]: inventory rejected " + m_Loot[m_ItemIndex], LogLevel.WARNING);
|
||||
ERR_Actors.DeleteSpawned(m_Item); m_Item = null; m_ItemIssued = false; m_ItemIndex++; m_ItemTicks = 0; m_Accepted = false; return;
|
||||
}
|
||||
if (!m_Accepted) m_Accepted = m_Inventory.TryInsertItem(m_Item);
|
||||
return;
|
||||
}
|
||||
// A destroyed/consumed entity is still a spent grant, not a spawn retry.
|
||||
if (m_ItemIssued) { m_ItemIssued = false; m_ItemIndex++; m_ItemTicks = 0; m_Accepted = false; return; }
|
||||
if (m_ItemIndex >= m_Loot.Count()) { Finish(); return; }
|
||||
ResourceName resource = m_Loot[m_ItemIndex];
|
||||
if (!ERR_CrashLoot.Allowed(resource)) { m_ItemIndex++; return; }
|
||||
m_ItemIssued = true;
|
||||
m_Item = Spawn(resource, m_Pending.Crate.GetOrigin() + "0 0.4 0", "0 0 0");
|
||||
if (!m_Item) { m_ItemIssued = false; m_ItemIndex++; }
|
||||
}
|
||||
protected void Finish()
|
||||
{
|
||||
if (m_Item)
|
||||
{
|
||||
InventoryItemComponent itemComponent = InventoryItemComponent.Cast(m_Item.FindComponent(InventoryItemComponent));
|
||||
if (!itemComponent || !itemComponent.GetParentSlot()) ERR_Actors.DeleteSpawned(m_Item);
|
||||
}
|
||||
m_Item = null; m_ItemIssued = false;
|
||||
if (m_Pending) m_Pending.Ready = true;
|
||||
m_Pending = null; m_Inventory = null; m_Loot.Clear();
|
||||
}
|
||||
protected void Step()
|
||||
{
|
||||
if (m_Stopped || !Replication.IsServer() || !m_Mode || m_Mode != ERR_GameMode.Get() || ERR_MissionRules.Terminal(m_Mode.Phase())) { Stop(); return; }
|
||||
if (!m_Mode.Active()) return;
|
||||
if (m_Pending) { Fill(); return; }
|
||||
if (m_Consumed >= m_Target) { Stop(); return; }
|
||||
if (!Ready()) return;
|
||||
int began = System.GetTickCount();
|
||||
for (int sample = 0; sample < 8; sample++)
|
||||
{
|
||||
vector point; float heading;
|
||||
m_Attempts++;
|
||||
if (Survey(point, heading))
|
||||
{
|
||||
m_Consumed++; m_Attempts = 0;
|
||||
if (!Create(point, heading)) m_Skipped++;
|
||||
return;
|
||||
}
|
||||
if (m_Attempts >= 2000)
|
||||
{
|
||||
m_Consumed++; m_Skipped++; m_Attempts = 0;
|
||||
Print("Reintroduced [crash sites]: skipped slot after bounded terrain search", LogLevel.WARNING);
|
||||
return;
|
||||
}
|
||||
if (System.GetTickCount() - began >= 4) return;
|
||||
}
|
||||
}
|
||||
void Stop()
|
||||
{
|
||||
if (m_Stopped) return;
|
||||
m_Stopped = true;
|
||||
if (GetGame()) GetGame().GetCallqueue().Remove(Step);
|
||||
Finish();
|
||||
// All scenery and issued stock remain in the round's owned-entity cleanup.
|
||||
}
|
||||
}
|
||||
@@ -66,6 +66,7 @@ class ERR_GameMode : SCR_BaseGameMode
|
||||
ERR_Performance Performance() { return m_Performance; }
|
||||
protected ref ERR_CivilianTraffic m_CivilianTraffic;
|
||||
protected ref ERR_GarageVehicles m_GarageVehicles;
|
||||
protected ref ERR_CrashSites m_CrashSites;
|
||||
protected ref ERR_ForceLedger m_Forces = new ERR_ForceLedger();
|
||||
protected ref ERR_ForceSimulation m_ForceSimulation;
|
||||
protected ref array<AIAgent> m_ForceAgents = {};
|
||||
@@ -145,6 +146,7 @@ class ERR_GameMode : SCR_BaseGameMode
|
||||
ERR_CommandService Command() { return m_Command; }
|
||||
ERR_CivilianTraffic CivilianTraffic() { return m_CivilianTraffic; }
|
||||
ERR_GarageVehicles GarageVehicles() { return m_GarageVehicles; }
|
||||
ERR_CrashSites CrashSites() { return m_CrashSites; }
|
||||
ERR_Objectives Objectives() { return m_Objectives; }
|
||||
ERR_ExtractionService Extraction() { return m_Extraction; }
|
||||
string EndReason() { return m_EndReason; }
|
||||
@@ -551,6 +553,9 @@ class ERR_GameMode : SCR_BaseGameMode
|
||||
m_GarageVehicles = new ERR_GarageVehicles(this);
|
||||
OnStop().Insert(m_GarageVehicles.Stop);
|
||||
m_GarageVehicles.Start();
|
||||
m_CrashSites = new ERR_CrashSites(this);
|
||||
OnStop().Insert(m_CrashSites.Stop);
|
||||
m_CrashSites.Start();
|
||||
GetGame().GetCallqueue().CallLater(ServerTick, 1000, true);
|
||||
GetGame().GetCallqueue().CallLater(StartScenario, 1500, false);
|
||||
}
|
||||
|
||||
@@ -9,11 +9,18 @@ class ERR_Settings
|
||||
|
||||
static array<string> Keys()
|
||||
{
|
||||
return {"telemetryEnabled", "aiDoctrine", "aiShadow", "sarkaAngerPerCar", "motorbikeCount", "planeAltitudeMetres", "planeReplacementSeconds", "planeSectorSeconds", "planeReconEnabled", "droneReconCount", "droneCooldownSeconds", "fieldCampCount", "fieldHospitalCount", "startWeaponCount", "startMagazineCount", "objectGuardCount", "objectGuardEvery", "objectGuardHQMode", "hunterSpawnDistanceMetres", "roadblockCount", "largeRoadblockCount", "mainRoadWidthMetres", "civilianTrafficCount", "garageVehicleCount", "garageChancePercent", "garageRadiusMetres", "garageSpawnIntervalSeconds", "startMode", "keepWeaponOnUnconscious", "selfEpinephrine", "restartOnEmpty", "emptyRestartHours", "reportIntervalSeconds", "supportSquadLimit", "responseRadiusMetres", "aiIntelChancePercent", "intelRevealChancePercent", "radioIntelSiteCount", "showAllSites", "radioDefenceSeconds", "startTimeMinutes", "timeMultiplier", "startDateCode", "weatherProfile", "viewDistanceMetres", "antiAirChancePercent", "antiPersonnelMineChancePercent", "automaticEquipmentChancePercent", "automaticConvoyEnabled", "convoyCount", "heliTimerMinutes"};
|
||||
return {"crashLootMode", "crashSiteCount", "crashHelicopterChancePercent", "crashRifleCount", "crashMagazineCount", "crashAntiAirChancePercent", "crashRocketChancePercent", "telemetryEnabled", "aiDoctrine", "aiShadow", "sarkaAngerPerCar", "motorbikeCount", "planeAltitudeMetres", "planeReplacementSeconds", "planeSectorSeconds", "planeReconEnabled", "droneReconCount", "droneCooldownSeconds", "fieldCampCount", "fieldHospitalCount", "startWeaponCount", "startMagazineCount", "objectGuardCount", "objectGuardEvery", "objectGuardHQMode", "hunterSpawnDistanceMetres", "roadblockCount", "largeRoadblockCount", "mainRoadWidthMetres", "civilianTrafficCount", "garageVehicleCount", "garageChancePercent", "garageRadiusMetres", "garageSpawnIntervalSeconds", "startMode", "keepWeaponOnUnconscious", "selfEpinephrine", "restartOnEmpty", "emptyRestartHours", "reportIntervalSeconds", "supportSquadLimit", "responseRadiusMetres", "aiIntelChancePercent", "intelRevealChancePercent", "radioIntelSiteCount", "showAllSites", "radioDefenceSeconds", "startTimeMinutes", "timeMultiplier", "startDateCode", "weatherProfile", "viewDistanceMetres", "antiAirChancePercent", "antiPersonnelMineChancePercent", "automaticEquipmentChancePercent", "automaticConvoyEnabled", "convoyCount", "heliTimerMinutes"};
|
||||
}
|
||||
|
||||
static bool Valid(string key, int value)
|
||||
{
|
||||
if (key == "crashLootMode") return value == 0 || value == 1;
|
||||
if (key == "crashSiteCount") return value >= 0 && value <= 12;
|
||||
if (key == "crashHelicopterChancePercent") return value >= 0 && value <= 100;
|
||||
if (key == "crashRifleCount") return value >= 1 && value <= 6;
|
||||
if (key == "crashMagazineCount") return value >= 1 && value <= 8;
|
||||
if (key == "crashAntiAirChancePercent") return value >= 0 && value <= 100;
|
||||
if (key == "crashRocketChancePercent") return value >= 0 && value <= 100;
|
||||
if (key == "telemetryEnabled" || key == "aiDoctrine" || key == "aiShadow") return value == 0 || value == 1;
|
||||
if (key == "radioIntelSiteCount") return value >= 0 && value <= 20;
|
||||
if (key == "sarkaAngerPerCar") return value >= 0 && value <= 30;
|
||||
@@ -127,6 +134,13 @@ class ERR_Settings
|
||||
|
||||
static int AddedDefault(string key)
|
||||
{
|
||||
if (key == "crashLootMode") return 1;
|
||||
if (key == "crashSiteCount") return 3;
|
||||
if (key == "crashHelicopterChancePercent") return 50;
|
||||
if (key == "crashRifleCount") return 3;
|
||||
if (key == "crashMagazineCount") return 4;
|
||||
if (key == "crashAntiAirChancePercent") return 25;
|
||||
if (key == "crashRocketChancePercent") return 50;
|
||||
if (key == "aiDoctrine" || key == "aiShadow") return 0;
|
||||
if (key == "radioIntelSiteCount") return 5;
|
||||
if (key == "sarkaAngerPerCar") return 3;
|
||||
@@ -172,6 +186,13 @@ class ERR_Settings
|
||||
void ERR_Settings(string path = PATH)
|
||||
{
|
||||
m_Path = path;
|
||||
m_Values.Set("crashLootMode", AddedDefault("crashLootMode"));
|
||||
m_Values.Set("crashSiteCount", AddedDefault("crashSiteCount"));
|
||||
m_Values.Set("crashHelicopterChancePercent", AddedDefault("crashHelicopterChancePercent"));
|
||||
m_Values.Set("crashRifleCount", AddedDefault("crashRifleCount"));
|
||||
m_Values.Set("crashMagazineCount", AddedDefault("crashMagazineCount"));
|
||||
m_Values.Set("crashAntiAirChancePercent", AddedDefault("crashAntiAirChancePercent"));
|
||||
m_Values.Set("crashRocketChancePercent", AddedDefault("crashRocketChancePercent"));
|
||||
m_Values.Set("telemetryEnabled", AddedDefault("telemetryEnabled"));
|
||||
m_Values.Set("aiDoctrine", AddedDefault("aiDoctrine"));
|
||||
m_Values.Set("aiShadow", AddedDefault("aiShadow"));
|
||||
|
||||
@@ -44,10 +44,12 @@ ButtonWidgetClass : "{75C912A1C89BE6C2}UI/layouts/WidgetLibrary/Buttons/WLib_But
|
||||
ImageWidgetClass { "Is Visible" 0 Name "Selected_OpenGuards" Slot FrameWidgetSlot { Anchor 0 0 0 0 PositionX 0 OffsetLeft 0 PositionY 206 OffsetTop 206 SizeX 180 OffsetRight -180 SizeY 3 OffsetBottom -209 } Color 0.9 0.66 0.25 1 }
|
||||
ButtonWidgetClass : "{75C912A1C89BE6C2}UI/layouts/WidgetLibrary/Buttons/WLib_ButtonText.layout" { Name "OpenSites" Slot FrameWidgetSlot { Anchor 0 0 0 0 PositionX 0 OffsetLeft 0 PositionY 216 OffsetTop 216 SizeX 180 OffsetRight -180 SizeY 42 OffsetBottom -258 } components { SCR_ButtonTextComponent "{5548F0143AE99095}" { m_sText "Field sites" } } }
|
||||
ImageWidgetClass { "Is Visible" 0 Name "Selected_OpenSites" Slot FrameWidgetSlot { Anchor 0 0 0 0 PositionX 0 OffsetLeft 0 PositionY 260 OffsetTop 260 SizeX 180 OffsetRight -180 SizeY 3 OffsetBottom -263 } Color 0.9 0.66 0.25 1 }
|
||||
ButtonWidgetClass : "{75C912A1C89BE6C2}UI/layouts/WidgetLibrary/Buttons/WLib_ButtonText.layout" { Name "OpenSarka" Slot FrameWidgetSlot { Anchor 0 0 0 0 PositionX 0 OffsetLeft 0 PositionY 270 OffsetTop 270 SizeX 180 OffsetRight -180 SizeY 42 OffsetBottom -312 } components { SCR_ButtonTextComponent "{5548F0143AE99095}" { m_sText "Šárka hunters" } } }
|
||||
ImageWidgetClass { "Is Visible" 0 Name "Selected_OpenSarka" Slot FrameWidgetSlot { Anchor 0 0 0 0 PositionX 0 OffsetLeft 0 PositionY 314 OffsetTop 314 SizeX 180 OffsetRight -180 SizeY 3 OffsetBottom -317 } Color 0.9 0.66 0.25 1 }
|
||||
ButtonWidgetClass : "{75C912A1C89BE6C2}UI/layouts/WidgetLibrary/Buttons/WLib_ButtonText.layout" { Name "OpenPacks" Slot FrameWidgetSlot { Anchor 0 0 0 0 PositionX 0 OffsetLeft 0 PositionY 324 OffsetTop 324 SizeX 180 OffsetRight -180 SizeY 42 OffsetBottom -366 } components { SCR_ButtonTextComponent "{5548F0143AE99095}" { m_sText "Enemy packs" } } }
|
||||
ImageWidgetClass { "Is Visible" 0 Name "Selected_OpenPacks" Slot FrameWidgetSlot { Anchor 0 0 0 0 PositionX 0 OffsetLeft 0 PositionY 368 OffsetTop 368 SizeX 180 OffsetRight -180 SizeY 3 OffsetBottom -371 } Color 0.9 0.66 0.25 1 }
|
||||
ButtonWidgetClass : "{75C912A1C89BE6C2}UI/layouts/WidgetLibrary/Buttons/WLib_ButtonText.layout" { Name "OpenCrashSites" Slot FrameWidgetSlot { Anchor 0 0 0 0 PositionX 0 OffsetLeft 0 PositionY 270 OffsetTop 270 SizeX 180 OffsetRight -180 SizeY 42 OffsetBottom -312 } components { SCR_ButtonTextComponent "{5548F0143AE99095}" { m_sText "Crash sites" } } }
|
||||
ImageWidgetClass { "Is Visible" 0 Name "Selected_OpenCrashSites" Slot FrameWidgetSlot { Anchor 0 0 0 0 PositionX 0 OffsetLeft 0 PositionY 314 OffsetTop 314 SizeX 180 OffsetRight -180 SizeY 3 OffsetBottom -317 } Color 0.9 0.66 0.25 1 }
|
||||
ButtonWidgetClass : "{75C912A1C89BE6C2}UI/layouts/WidgetLibrary/Buttons/WLib_ButtonText.layout" { Name "OpenSarka" Slot FrameWidgetSlot { Anchor 0 0 0 0 PositionX 0 OffsetLeft 0 PositionY 324 OffsetTop 324 SizeX 180 OffsetRight -180 SizeY 42 OffsetBottom -366 } components { SCR_ButtonTextComponent "{5548F0143AE99095}" { m_sText "Šárka hunters" } } }
|
||||
ImageWidgetClass { "Is Visible" 0 Name "Selected_OpenSarka" Slot FrameWidgetSlot { Anchor 0 0 0 0 PositionX 0 OffsetLeft 0 PositionY 368 OffsetTop 368 SizeX 180 OffsetRight -180 SizeY 3 OffsetBottom -371 } Color 0.9 0.66 0.25 1 }
|
||||
ButtonWidgetClass : "{75C912A1C89BE6C2}UI/layouts/WidgetLibrary/Buttons/WLib_ButtonText.layout" { Name "OpenPacks" Slot FrameWidgetSlot { Anchor 0 0 0 0 PositionX 0 OffsetLeft 0 PositionY 378 OffsetTop 378 SizeX 180 OffsetRight -180 SizeY 42 OffsetBottom -420 } components { SCR_ButtonTextComponent "{5548F0143AE99095}" { m_sText "Enemy packs" } } }
|
||||
ImageWidgetClass { "Is Visible" 0 Name "Selected_OpenPacks" Slot FrameWidgetSlot { Anchor 0 0 0 0 PositionX 0 OffsetLeft 0 PositionY 422 OffsetTop 422 SizeX 180 OffsetRight -180 SizeY 3 OffsetBottom -425 } Color 0.9 0.66 0.25 1 }
|
||||
} }
|
||||
ButtonWidgetClass : "{75C912A1C89BE6C2}UI/layouts/WidgetLibrary/Buttons/WLib_ButtonText.layout" { Name "Main_HQ" Slot FrameWidgetSlot { Anchor 0 0 0 0 PositionX 320 OffsetLeft 320 PositionY 106 OffsetTop 106 SizeX 138 OffsetRight -458 SizeY 42 OffsetBottom -148 } components { SCR_ButtonTextComponent "{5548F0143AE99095}" { m_sText "HQ" } } }
|
||||
ImageWidgetClass { "Is Visible" 0 Name "Selected_Main_HQ" Slot FrameWidgetSlot { Anchor 0 0 0 0 PositionX 320 OffsetLeft 320 PositionY 150 OffsetTop 150 SizeX 138 OffsetRight -458 SizeY 3 OffsetBottom -153 } Color 0.9 0.66 0.25 1 }
|
||||
@@ -1131,6 +1133,46 @@ TextWidgetClass { Name "Saved_fieldHospitalCount" Slot FrameWidgetSlot { Anchor
|
||||
TextWidgetClass { Name "Help_fieldHospitalCount" Slot FrameWidgetSlot { Anchor 0 0 0 0 PositionX 508 OffsetLeft 508 PositionY 226 OffsetTop 226 SizeX 456 OffsetRight -964 SizeY 54 OffsetBottom -280 } Color 0.9 0.92 0.94 1 Text "Medical supplies and guards. The radio-clue site is retained." "Font Size" 16 "Min Font Size" 16 Wrap 1 FontProperties FontProperties { Font "{3E7733BAC8C831F6}UI/Fonts/RobotoCondensed/RobotoCondensed_Regular.fnt" } }
|
||||
TextWidgetClass { Name "SitesObjectives" Slot FrameWidgetSlot { Anchor 0 0 0 0 PositionX 28 OffsetLeft 28 PositionY 318 OffsetTop 318 SizeX 936 OffsetRight -964 SizeY 90 OffsetBottom -408 } Color 0.9 0.92 0.94 1 Text "The prison, radio, extraction, supply cache and four mortar sites are unchanged. Defaults request 26 sites. More sites share the existing field guard budget. Discover them through intel or exploration." "Font Size" 18 "Min Font Size" 18 Wrap 1 FontProperties FontProperties { Font "{3E7733BAC8C831F6}UI/Fonts/RobotoCondensed/RobotoCondensed_Regular.fnt" } }
|
||||
} }
|
||||
FrameWidgetClass { "Is Visible" 0 Name "CrashSitesPage" Slot FrameWidgetSlot { Anchor 0 0 0 0 PositionX 220 OffsetLeft 220 PositionY 160 OffsetTop 160 SizeX 1000 OffsetRight -1220 SizeY 532 OffsetBottom -692 } {
|
||||
TextWidgetClass { Name "CrashHeading" Slot FrameWidgetSlot { Anchor 0 0 0 0 PositionX 28 OffsetLeft 28 PositionY 4 OffsetTop 4 SizeX 936 OffsetRight -964 SizeY 30 OffsetBottom -34 } Color 0.9 0.92 0.94 1 Text "Crash sites - next round" "Font Size" 22 "Min Font Size" 22 Wrap 1 FontProperties FontProperties { Font "{3E7733BAC8C831F6}UI/Fonts/RobotoCondensed/RobotoCondensed_Regular.fnt" } }
|
||||
TextWidgetClass { Name "CrashHelp" Slot FrameWidgetSlot { Anchor 0 0 0 0 PositionX 28 OffsetLeft 28 PositionY 40 OffsetTop 40 SizeX 936 OffsetRight -964 SizeY 40 OffsetBottom -80 } Color 0.9 0.92 0.94 1 Text "Default loot is random for each crate: poor pistol supplies, a useful rifle, or a rich haul of scoped guns and launchers. No refills." "Font Size" 17 "Min Font Size" 17 Wrap 1 FontProperties FontProperties { Font "{3E7733BAC8C831F6}UI/Fonts/RobotoCondensed/RobotoCondensed_Regular.fnt" } }
|
||||
TextWidgetClass { Name "Label_crashLootMode" Slot FrameWidgetSlot { Anchor 0 0 0 0 PositionX 28 OffsetLeft 28 PositionY 82 OffsetTop 82 SizeX 456 OffsetRight -484 SizeY 26 OffsetBottom -108 } Color 0.9 0.92 0.94 1 Text "Loot mode: Random or Custom" "Font Size" 17 "Min Font Size" 17 Wrap 1 FontProperties FontProperties { Font "{3E7733BAC8C831F6}UI/Fonts/RobotoCondensed/RobotoCondensed_Regular.fnt" } }
|
||||
ButtonWidgetClass : "{DA43C77A0D1E59F8}UI/layouts/ERR/AdminValue.layout" { Name "crashLootMode" Slot FrameWidgetSlot { Anchor 0 0 0 0 PositionX 508 OffsetLeft 508 PositionY 82 OffsetTop 82 SizeX 180 OffsetRight -688 SizeY 32 OffsetBottom -114 } components { SCR_EditBoxComponent "{547290FFBD5B33E9}" { m_sLabel "" } } }
|
||||
ButtonWidgetClass : "{75C912A1C89BE6C2}UI/layouts/WidgetLibrary/Buttons/WLib_ButtonText.layout" { Name "Apply_crashLootMode" Slot FrameWidgetSlot { Anchor 0 0 0 0 PositionX 700 OffsetLeft 700 PositionY 82 OffsetTop 82 SizeX 100 OffsetRight -800 SizeY 32 OffsetBottom -114 } components { SCR_ButtonTextComponent "{5548F0143AE99095}" { m_sText "Apply" } } }
|
||||
TextWidgetClass { Name "Saved_crashLootMode" Slot FrameWidgetSlot { Anchor 0 0 0 0 PositionX 508 OffsetLeft 508 PositionY 118 OffsetTop 118 SizeX 456 OffsetRight -964 SizeY 20 OffsetBottom -138 } Color 0.9 0.92 0.94 1 Text "Waiting for server" "Font Size" 14 "Min Font Size" 14 Wrap 1 FontProperties FontProperties { Font "{3E7733BAC8C831F6}UI/Fonts/RobotoCondensed/RobotoCondensed_Regular.fnt" } }
|
||||
TextWidgetClass { Name "Help_crashLootMode" Slot FrameWidgetSlot { Anchor 0 0 0 0 PositionX 28 OffsetLeft 28 PositionY 112 OffsetTop 112 SizeX 456 OffsetRight -484 SizeY 40 OffsetBottom -152 } Color 0.9 0.92 0.94 1 Text "Random rolls each crate independently. Custom uses the four loot controls below." "Font Size" 14 "Min Font Size" 14 Wrap 1 FontProperties FontProperties { Font "{3E7733BAC8C831F6}UI/Fonts/RobotoCondensed/RobotoCondensed_Regular.fnt" } }
|
||||
TextWidgetClass { Name "Label_crashSiteCount" Slot FrameWidgetSlot { Anchor 0 0 0 0 PositionX 28 OffsetLeft 28 PositionY 160 OffsetTop 160 SizeX 456 OffsetRight -484 SizeY 22 OffsetBottom -182 } Color 0.9 0.92 0.94 1 Text "Crash sites (0-12)" "Font Size" 17 "Min Font Size" 17 Wrap 1 FontProperties FontProperties { Font "{3E7733BAC8C831F6}UI/Fonts/RobotoCondensed/RobotoCondensed_Regular.fnt" } }
|
||||
ButtonWidgetClass : "{DA43C77A0D1E59F8}UI/layouts/ERR/AdminValue.layout" { Name "crashSiteCount" Slot FrameWidgetSlot { Anchor 0 0 0 0 PositionX 28 OffsetLeft 28 PositionY 184 OffsetTop 184 SizeX 180 OffsetRight -208 SizeY 32 OffsetBottom -216 } components { SCR_EditBoxComponent "{547290FFBD5B33E9}" { m_sLabel "" } } }
|
||||
ButtonWidgetClass : "{75C912A1C89BE6C2}UI/layouts/WidgetLibrary/Buttons/WLib_ButtonText.layout" { Name "Apply_crashSiteCount" Slot FrameWidgetSlot { Anchor 0 0 0 0 PositionX 220 OffsetLeft 220 PositionY 184 OffsetTop 184 SizeX 100 OffsetRight -320 SizeY 32 OffsetBottom -216 } components { SCR_ButtonTextComponent "{5548F0143AE99095}" { m_sText "Apply" } } }
|
||||
TextWidgetClass { Name "Saved_crashSiteCount" Slot FrameWidgetSlot { Anchor 0 0 0 0 PositionX 28 OffsetLeft 28 PositionY 220 OffsetTop 220 SizeX 456 OffsetRight -484 SizeY 20 OffsetBottom -240 } Color 0.9 0.92 0.94 1 Text "Waiting for server" "Font Size" 14 "Min Font Size" 14 Wrap 1 FontProperties FontProperties { Font "{3E7733BAC8C831F6}UI/Fonts/RobotoCondensed/RobotoCondensed_Regular.fnt" } }
|
||||
TextWidgetClass { Name "Help_crashSiteCount" Slot FrameWidgetSlot { Anchor 0 0 0 0 PositionX 28 OffsetLeft 28 PositionY 242 OffsetTop 242 SizeX 456 OffsetRight -484 SizeY 26 OffsetBottom -268 } Color 0.9 0.92 0.94 1 Text "0 disables sites. Finite wrecks and loot; no refills." "Font Size" 14 "Min Font Size" 14 Wrap 1 FontProperties FontProperties { Font "{3E7733BAC8C831F6}UI/Fonts/RobotoCondensed/RobotoCondensed_Regular.fnt" } }
|
||||
TextWidgetClass { Name "Label_crashHelicopterChancePercent" Slot FrameWidgetSlot { Anchor 0 0 0 0 PositionX 508 OffsetLeft 508 PositionY 160 OffsetTop 160 SizeX 456 OffsetRight -964 SizeY 22 OffsetBottom -182 } Color 0.9 0.92 0.94 1 Text "Helicopter chance (%)" "Font Size" 17 "Min Font Size" 17 Wrap 1 FontProperties FontProperties { Font "{3E7733BAC8C831F6}UI/Fonts/RobotoCondensed/RobotoCondensed_Regular.fnt" } }
|
||||
ButtonWidgetClass : "{DA43C77A0D1E59F8}UI/layouts/ERR/AdminValue.layout" { Name "crashHelicopterChancePercent" Slot FrameWidgetSlot { Anchor 0 0 0 0 PositionX 508 OffsetLeft 508 PositionY 184 OffsetTop 184 SizeX 180 OffsetRight -688 SizeY 32 OffsetBottom -216 } components { SCR_EditBoxComponent "{547290FFBD5B33E9}" { m_sLabel "" } } }
|
||||
ButtonWidgetClass : "{75C912A1C89BE6C2}UI/layouts/WidgetLibrary/Buttons/WLib_ButtonText.layout" { Name "Apply_crashHelicopterChancePercent" Slot FrameWidgetSlot { Anchor 0 0 0 0 PositionX 700 OffsetLeft 700 PositionY 184 OffsetTop 184 SizeX 100 OffsetRight -800 SizeY 32 OffsetBottom -216 } components { SCR_ButtonTextComponent "{5548F0143AE99095}" { m_sText "Apply" } } }
|
||||
TextWidgetClass { Name "Saved_crashHelicopterChancePercent" Slot FrameWidgetSlot { Anchor 0 0 0 0 PositionX 508 OffsetLeft 508 PositionY 220 OffsetTop 220 SizeX 456 OffsetRight -964 SizeY 20 OffsetBottom -240 } Color 0.9 0.92 0.94 1 Text "Waiting for server" "Font Size" 14 "Min Font Size" 14 Wrap 1 FontProperties FontProperties { Font "{3E7733BAC8C831F6}UI/Fonts/RobotoCondensed/RobotoCondensed_Regular.fnt" } }
|
||||
TextWidgetClass { Name "Help_crashHelicopterChancePercent" Slot FrameWidgetSlot { Anchor 0 0 0 0 PositionX 508 OffsetLeft 508 PositionY 242 OffsetTop 242 SizeX 456 OffsetRight -964 SizeY 26 OffsetBottom -268 } Color 0.9 0.92 0.94 1 Text "0 = armored wrecks; 100 = helicopters." "Font Size" 14 "Min Font Size" 14 Wrap 1 FontProperties FontProperties { Font "{3E7733BAC8C831F6}UI/Fonts/RobotoCondensed/RobotoCondensed_Regular.fnt" } }
|
||||
TextWidgetClass { Name "Label_crashRifleCount" Slot FrameWidgetSlot { Anchor 0 0 0 0 PositionX 28 OffsetLeft 28 PositionY 270 OffsetTop 270 SizeX 456 OffsetRight -484 SizeY 22 OffsetBottom -292 } Color 0.9 0.92 0.94 1 Text "Custom: scoped rifles per crate (1-6)" "Font Size" 17 "Min Font Size" 17 Wrap 1 FontProperties FontProperties { Font "{3E7733BAC8C831F6}UI/Fonts/RobotoCondensed/RobotoCondensed_Regular.fnt" } }
|
||||
ButtonWidgetClass : "{DA43C77A0D1E59F8}UI/layouts/ERR/AdminValue.layout" { Name "crashRifleCount" Slot FrameWidgetSlot { Anchor 0 0 0 0 PositionX 28 OffsetLeft 28 PositionY 294 OffsetTop 294 SizeX 180 OffsetRight -208 SizeY 32 OffsetBottom -326 } components { SCR_EditBoxComponent "{547290FFBD5B33E9}" { m_sLabel "" } } }
|
||||
ButtonWidgetClass : "{75C912A1C89BE6C2}UI/layouts/WidgetLibrary/Buttons/WLib_ButtonText.layout" { Name "Apply_crashRifleCount" Slot FrameWidgetSlot { Anchor 0 0 0 0 PositionX 220 OffsetLeft 220 PositionY 294 OffsetTop 294 SizeX 100 OffsetRight -320 SizeY 32 OffsetBottom -326 } components { SCR_ButtonTextComponent "{5548F0143AE99095}" { m_sText "Apply" } } }
|
||||
TextWidgetClass { Name "Saved_crashRifleCount" Slot FrameWidgetSlot { Anchor 0 0 0 0 PositionX 28 OffsetLeft 28 PositionY 330 OffsetTop 330 SizeX 456 OffsetRight -484 SizeY 20 OffsetBottom -350 } Color 0.9 0.92 0.94 1 Text "Waiting for server" "Font Size" 14 "Min Font Size" 14 Wrap 1 FontProperties FontProperties { Font "{3E7733BAC8C831F6}UI/Fonts/RobotoCondensed/RobotoCondensed_Regular.fnt" } }
|
||||
TextWidgetClass { Name "Help_crashRifleCount" Slot FrameWidgetSlot { Anchor 0 0 0 0 PositionX 28 OffsetLeft 28 PositionY 352 OffsetTop 352 SizeX 456 OffsetRight -484 SizeY 26 OffsetBottom -378 } Color 0.9 0.92 0.94 1 Text "Random M21 / SVD rifles with fitted scopes." "Font Size" 14 "Min Font Size" 14 Wrap 1 FontProperties FontProperties { Font "{3E7733BAC8C831F6}UI/Fonts/RobotoCondensed/RobotoCondensed_Regular.fnt" } }
|
||||
TextWidgetClass { Name "Label_crashMagazineCount" Slot FrameWidgetSlot { Anchor 0 0 0 0 PositionX 508 OffsetLeft 508 PositionY 270 OffsetTop 270 SizeX 456 OffsetRight -964 SizeY 22 OffsetBottom -292 } Color 0.9 0.92 0.94 1 Text "Custom: magazines per rifle (1-8)" "Font Size" 17 "Min Font Size" 17 Wrap 1 FontProperties FontProperties { Font "{3E7733BAC8C831F6}UI/Fonts/RobotoCondensed/RobotoCondensed_Regular.fnt" } }
|
||||
ButtonWidgetClass : "{DA43C77A0D1E59F8}UI/layouts/ERR/AdminValue.layout" { Name "crashMagazineCount" Slot FrameWidgetSlot { Anchor 0 0 0 0 PositionX 508 OffsetLeft 508 PositionY 294 OffsetTop 294 SizeX 180 OffsetRight -688 SizeY 32 OffsetBottom -326 } components { SCR_EditBoxComponent "{547290FFBD5B33E9}" { m_sLabel "" } } }
|
||||
ButtonWidgetClass : "{75C912A1C89BE6C2}UI/layouts/WidgetLibrary/Buttons/WLib_ButtonText.layout" { Name "Apply_crashMagazineCount" Slot FrameWidgetSlot { Anchor 0 0 0 0 PositionX 700 OffsetLeft 700 PositionY 294 OffsetTop 294 SizeX 100 OffsetRight -800 SizeY 32 OffsetBottom -326 } components { SCR_ButtonTextComponent "{5548F0143AE99095}" { m_sText "Apply" } } }
|
||||
TextWidgetClass { Name "Saved_crashMagazineCount" Slot FrameWidgetSlot { Anchor 0 0 0 0 PositionX 508 OffsetLeft 508 PositionY 330 OffsetTop 330 SizeX 456 OffsetRight -964 SizeY 20 OffsetBottom -350 } Color 0.9 0.92 0.94 1 Text "Waiting for server" "Font Size" 14 "Min Font Size" 14 Wrap 1 FontProperties FontProperties { Font "{3E7733BAC8C831F6}UI/Fonts/RobotoCondensed/RobotoCondensed_Regular.fnt" } }
|
||||
TextWidgetClass { Name "Help_crashMagazineCount" Slot FrameWidgetSlot { Anchor 0 0 0 0 PositionX 508 OffsetLeft 508 PositionY 352 OffsetTop 352 SizeX 456 OffsetRight -964 SizeY 26 OffsetBottom -378 } Color 0.9 0.92 0.94 1 Text "Matching ammunition for each selected rifle." "Font Size" 14 "Min Font Size" 14 Wrap 1 FontProperties FontProperties { Font "{3E7733BAC8C831F6}UI/Fonts/RobotoCondensed/RobotoCondensed_Regular.fnt" } }
|
||||
TextWidgetClass { Name "Label_crashAntiAirChancePercent" Slot FrameWidgetSlot { Anchor 0 0 0 0 PositionX 28 OffsetLeft 28 PositionY 380 OffsetTop 380 SizeX 456 OffsetRight -484 SizeY 22 OffsetBottom -402 } Color 0.9 0.92 0.94 1 Text "Custom: anti-air launcher chance (%)" "Font Size" 17 "Min Font Size" 17 Wrap 1 FontProperties FontProperties { Font "{3E7733BAC8C831F6}UI/Fonts/RobotoCondensed/RobotoCondensed_Regular.fnt" } }
|
||||
ButtonWidgetClass : "{DA43C77A0D1E59F8}UI/layouts/ERR/AdminValue.layout" { Name "crashAntiAirChancePercent" Slot FrameWidgetSlot { Anchor 0 0 0 0 PositionX 28 OffsetLeft 28 PositionY 404 OffsetTop 404 SizeX 180 OffsetRight -208 SizeY 32 OffsetBottom -436 } components { SCR_EditBoxComponent "{547290FFBD5B33E9}" { m_sLabel "" } } }
|
||||
ButtonWidgetClass : "{75C912A1C89BE6C2}UI/layouts/WidgetLibrary/Buttons/WLib_ButtonText.layout" { Name "Apply_crashAntiAirChancePercent" Slot FrameWidgetSlot { Anchor 0 0 0 0 PositionX 220 OffsetLeft 220 PositionY 404 OffsetTop 404 SizeX 100 OffsetRight -320 SizeY 32 OffsetBottom -436 } components { SCR_ButtonTextComponent "{5548F0143AE99095}" { m_sText "Apply" } } }
|
||||
TextWidgetClass { Name "Saved_crashAntiAirChancePercent" Slot FrameWidgetSlot { Anchor 0 0 0 0 PositionX 28 OffsetLeft 28 PositionY 440 OffsetTop 440 SizeX 456 OffsetRight -484 SizeY 20 OffsetBottom -460 } Color 0.9 0.92 0.94 1 Text "Waiting for server" "Font Size" 14 "Min Font Size" 14 Wrap 1 FontProperties FontProperties { Font "{3E7733BAC8C831F6}UI/Fonts/RobotoCondensed/RobotoCondensed_Regular.fnt" } }
|
||||
TextWidgetClass { Name "Help_crashAntiAirChancePercent" Slot FrameWidgetSlot { Anchor 0 0 0 0 PositionX 28 OffsetLeft 28 PositionY 462 OffsetTop 462 SizeX 456 OffsetRight -484 SizeY 26 OffsetBottom -488 } Color 0.9 0.92 0.94 1 Text "One loaded Stinger, if installed and enabled." "Font Size" 14 "Min Font Size" 14 Wrap 1 FontProperties FontProperties { Font "{3E7733BAC8C831F6}UI/Fonts/RobotoCondensed/RobotoCondensed_Regular.fnt" } }
|
||||
TextWidgetClass { Name "Label_crashRocketChancePercent" Slot FrameWidgetSlot { Anchor 0 0 0 0 PositionX 508 OffsetLeft 508 PositionY 380 OffsetTop 380 SizeX 456 OffsetRight -964 SizeY 22 OffsetBottom -402 } Color 0.9 0.92 0.94 1 Text "Custom: rPG launcher chance (%)" "Font Size" 17 "Min Font Size" 17 Wrap 1 FontProperties FontProperties { Font "{3E7733BAC8C831F6}UI/Fonts/RobotoCondensed/RobotoCondensed_Regular.fnt" } }
|
||||
ButtonWidgetClass : "{DA43C77A0D1E59F8}UI/layouts/ERR/AdminValue.layout" { Name "crashRocketChancePercent" Slot FrameWidgetSlot { Anchor 0 0 0 0 PositionX 508 OffsetLeft 508 PositionY 404 OffsetTop 404 SizeX 180 OffsetRight -688 SizeY 32 OffsetBottom -436 } components { SCR_EditBoxComponent "{547290FFBD5B33E9}" { m_sLabel "" } } }
|
||||
ButtonWidgetClass : "{75C912A1C89BE6C2}UI/layouts/WidgetLibrary/Buttons/WLib_ButtonText.layout" { Name "Apply_crashRocketChancePercent" Slot FrameWidgetSlot { Anchor 0 0 0 0 PositionX 700 OffsetLeft 700 PositionY 404 OffsetTop 404 SizeX 100 OffsetRight -800 SizeY 32 OffsetBottom -436 } components { SCR_ButtonTextComponent "{5548F0143AE99095}" { m_sText "Apply" } } }
|
||||
TextWidgetClass { Name "Saved_crashRocketChancePercent" Slot FrameWidgetSlot { Anchor 0 0 0 0 PositionX 508 OffsetLeft 508 PositionY 440 OffsetTop 440 SizeX 456 OffsetRight -964 SizeY 20 OffsetBottom -460 } Color 0.9 0.92 0.94 1 Text "Waiting for server" "Font Size" 14 "Min Font Size" 14 Wrap 1 FontProperties FontProperties { Font "{3E7733BAC8C831F6}UI/Fonts/RobotoCondensed/RobotoCondensed_Regular.fnt" } }
|
||||
TextWidgetClass { Name "Help_crashRocketChancePercent" Slot FrameWidgetSlot { Anchor 0 0 0 0 PositionX 508 OffsetLeft 508 PositionY 462 OffsetTop 462 SizeX 456 OffsetRight -964 SizeY 26 OffsetBottom -488 } Color 0.9 0.92 0.94 1 Text "One scoped RPG-7 with two matching rockets." "Font Size" 14 "Min Font Size" 14 Wrap 1 FontProperties FontProperties { Font "{3E7733BAC8C831F6}UI/Fonts/RobotoCondensed/RobotoCondensed_Regular.fnt" } }
|
||||
TextWidgetClass { Name "CrashFooter" Slot FrameWidgetSlot { Anchor 0 0 0 0 PositionX 28 OffsetLeft 28 PositionY 498 OffsetTop 498 SizeX 936 OffsetRight -964 SizeY 28 OffsetBottom -526 } Color 0.9 0.92 0.94 1 Text "Random ignores custom loot amounts and chances. Content blocks still apply. Default: 3 sites, 50% helicopters." "Font Size" 14 "Min Font Size" 14 Wrap 1 FontProperties FontProperties { Font "{3E7733BAC8C831F6}UI/Fonts/RobotoCondensed/RobotoCondensed_Regular.fnt" } }
|
||||
} }
|
||||
FrameWidgetClass { "Is Visible" 0 Name "PlanePage" Slot FrameWidgetSlot { Anchor 0 0 0 0 PositionX 220 OffsetLeft 220 PositionY 160 OffsetTop 160 SizeX 1000 OffsetRight -1220 SizeY 532 OffsetBottom -692 } {
|
||||
TextWidgetClass { Name "PlaneHeading" Slot FrameWidgetSlot { Anchor 0 0 0 0 PositionX 28 OffsetLeft 28 PositionY 6 OffsetTop 6 SizeX 710 OffsetRight -738 SizeY 32 OffsetBottom -38 } Color 0.9 0.92 0.94 1 Text "Cessna patrol - changes apply next round" "Font Size" 22 "Min Font Size" 22 Wrap 1 FontProperties FontProperties { Font "{3E7733BAC8C831F6}UI/Fonts/RobotoCondensed/RobotoCondensed_Regular.fnt" } }
|
||||
|
||||
|
||||
Reference in New Issue
Block a user