diff --git a/.devfiles/AGM_PMC/stringtable.xml b/.devfiles/AGM_PMC/stringtable.xml index af13592b1..82a6cab2c 100644 --- a/.devfiles/AGM_PMC/stringtable.xml +++ b/.devfiles/AGM_PMC/stringtable.xml @@ -303,7 +303,7 @@ Support Team (Engineer) Podpůrný tým (ženista) Équipe d'appui (sapeur) - Unterstützungstrupp (Ingenieur) + Unterstützungstrupp (Pionier) Squadra di supporto (genieri) Sekcja wsparcia (saper) Equipe de apoio (engenheiro) diff --git a/AGM_Artillery/README.md b/AGM_Artillery/README.md new file mode 100644 index 000000000..8995a60b4 --- /dev/null +++ b/AGM_Artillery/README.md @@ -0,0 +1,28 @@ +#1194 + +Advanced Mortars (Effected by wind, drag, powder temp) + +Adds: +-Vehicles: + `B_AGM_advancedMortar` +-Backpacks: + `B_AGM_Artillery_backpack_tube` + `B_AGM_Artillery_backpack_baseplate` +-Items: + `AGM_RangeTable_81mm` + +Model is the just the A3 Mk6 mortar, but has a completely new HUD and interface e.g.: Actually shows current Charge (amount of propellant which effects muzzle velocity) + +Open range table with AGM self-interaction (under Equipment submenu) + +Mortar has several options changeable by setVariables. (Note the Artillery Computer is completely custom, so this will ignore the enableEngineArtillery setting command) + + `AGM_Artillery_mapComputerEnabled` - BOOL: (default false) controls if a Map Artillery Computer is available. Different, but similar to A3 aComp (click on map OR enter map cords to compute) + + `AGM_Artillery_rangefinderEnabled` - BOOL: (default false) controls if a rangefinder computer is available. Similar to A3 mortar gunner view (hold tab and relase to compute) + + `AGM_Artillery_digialDisplayEnabled` - BOOL: (default true) Simple digital display of elevation and azimuth in MILS. Just makes it easier to quickly read current settings. + +Default key to range is TAB - (WIP on integration with FCS???) + + diff --git a/AGM_Artillery/Research.txt b/AGM_Artillery/Research.txt new file mode 100644 index 000000000..4ae2699ad Binary files /dev/null and b/AGM_Artillery/Research.txt differ diff --git a/AGM_Artillery/Research_table1.jpg b/AGM_Artillery/Research_table1.jpg new file mode 100644 index 000000000..fba83ef8a Binary files /dev/null and b/AGM_Artillery/Research_table1.jpg differ diff --git a/AGM_Artillery/UI/RangeTable_background.paa b/AGM_Artillery/UI/RangeTable_background.paa new file mode 100644 index 000000000..a2a752ce6 Binary files /dev/null and b/AGM_Artillery/UI/RangeTable_background.paa differ diff --git a/AGM_Artillery/UI/icon_rangeTable.paa b/AGM_Artillery/UI/icon_rangeTable.paa new file mode 100644 index 000000000..9273b849d Binary files /dev/null and b/AGM_Artillery/UI/icon_rangeTable.paa differ diff --git a/AGM_Artillery/UI/ui_charges.paa b/AGM_Artillery/UI/ui_charges.paa new file mode 100644 index 000000000..7041c654e Binary files /dev/null and b/AGM_Artillery/UI/ui_charges.paa differ diff --git a/AGM_Artillery/config.cpp b/AGM_Artillery/config.cpp new file mode 100644 index 000000000..a8d6d902b --- /dev/null +++ b/AGM_Artillery/config.cpp @@ -0,0 +1,406 @@ +class CfgPatches{ + class AGM_Artillery { + units[] = {"B_AGM_advancedMortar", "B_AGM_advancedMortar_NoOptics", "B_AGM_Artillery_backpack_tube", "B_AGM_Artillery_backpack_tube_NoOptics", "B_AGM_Artillery_backpack_baseplate"}; + weapons[] = {"AGM_RangeTable_81mm"}; + requiredVersion = 0.6; + //Wind for air density/temp, Vector for the assets (scope view and digital numbers) + requiredAddons[] = {"AGM_Core", "AGM_Wind", "AGM_Vector"}; + version = "0.95"; + versionStr = "0.95"; + versionAr[] = {0,95,0}; + author[] = {"Pabst Mirror"}; + }; +}; + +class RscControlsGroup; +class VScrollbar; +class HScrollbar; +class RscText; +class RscObject; +class RscPicture; +class RscStructuredText; +class RscMapControl; +class RscListbox; +class RscListNBox; +class RscFrame; +class RscEdit; +class RscButton; +class ScrollBar; +class RscActiveText; +class RCWSOptics; + +#include "gui_mapComputer.hpp" +#include "gui_mortarHud.hpp" +#include "gui_rangeTable.hpp" + +class CfgFunctions { + class AGM_Artillery { + class AGM_Artillery { + file = "\AGM_Artillery\functions"; + class createFiringSolution; + class dev_buildTable; + class firedEH; + class formatNumber; + class getPosFromMapCords; + class mapCompEventClickOnMap; + class mapCompEventDrawMap; + class mapCompEventEnterCords; + class mapCompOpen; + class onHudLoad; + class rangerFinderStart; + class rangeTableOpen; + class rangeTablePageChange; + class rangeTablePreCalculatedValues; + class simulateCalcRangeTableLine; + class simulateFindSolution; + class simulateShot; + }; + }; +}; + + +//ToDo: Figure out how to intergrate with the normal fire control / rangefinder button +class AGM_Core_Default_Keys { + class AGM_Artillery_mortarRangefinder { + displayName = "Mortar: RangeFinder"; + condition = "(_player == (gunner _vehicle)) && {_vehicle isKindOf 'AGM_advancedMortar_base'} && {_vehicle getVariable ['AGM_Artillery_mapComputerEnabled', false]}"; + statement = "AGM_Artillery_rangefinderKeyDown = true; [_vehicle] call AGM_Artillery_fnc_rangerFinderStart;"; + conditionUp = "true"; + statementUp = "AGM_Artillery_rangefinderKeyDown = false;"; + key = 15; + shift = 0; + control = 0; + alt = 0; + }; +}; + + +class CfgAmmo { + class SubmunitionBase; + class Sh_82mm_AMOS; + class Smoke_82mm_AMOS_White; + class Flare_82mm_AMOS_White; + + //Ammo + class AGM_81mmShell_AMMO_HE: Sh_82mm_AMOS { + airFriction = 0; + AGM_Artillery_realAirFriction = -0.0001; + // hit = 165; //default is 165 + // indirectHit = 52; //default is 52 + indirectHitRange = 20; //default 18 + }; + class AGM_81mmShell_AMMO_smokeWhite: Smoke_82mm_AMOS_White { + airFriction = 0; + AGM_Artillery_realAirFriction = -0.0001; + }; + class AGM_81mmShell_AMMO_smokeRed: AGM_81mmShell_AMMO_smokeWhite { + submunitionAmmo = "SmokeShellRed"; + }; + // class AGM_81mmShell_AMMO_Incinerate: AGM_81mmShell_AMMO_smokeWhite { //Warcrimes? + // submunitionAmmo = "IncinerateShell"; + // }; + class AGM_81mmShell_AMMO_airburst: AGM_81mmShell_AMMO_smokeWhite { + submunitionAmmo = ""; + AGM_Artillery_carryAmmo = "AGM_81mmShell_AMMO_EJECT_Airburst"; + AGM_Artillery_carryEjectHeight = 10; + }; + class AGM_81mmShell_AMMO_flareWhite: AGM_81mmShell_AMMO_smokeWhite { + submunitionAmmo = ""; + AGM_Artillery_carryAmmo = "AGM_81mmShell_AMMO_EJECT_Flare"; + AGM_Artillery_carryEjectHeight = 475; + }; + + //Helpers-Submunitions + class AGM_81mmShell_AMMO_EJECT_Airburst: AGM_81mmShell_AMMO_HE { + explosionTime = 0.00001; + }; + class AGM_81mmShell_AMMO_EJECT_Flare: Flare_82mm_AMOS_White { + triggerTime = 0.00001; + timeToLive = 60; + intensity = 525000; + }; +}; + +class CfgMagazines { + class 8Rnd_82mm_Mo_shells; + class AGM_8Rnd_81mmShell_HE: 8Rnd_82mm_Mo_shells { + count = 8; + initSpeed = 300; + displayName = "HE Mortar Shells (Fuze: Impact)"; + displayNameShort = "HE-IMPACT"; + ammo = "AGM_81mmShell_AMMO_HE"; + }; + class AGM_8Rnd_81mmShell_airburst: AGM_8Rnd_81mmShell_HE { + displayName = "HE Mortar Shells (Fuze: Airburst)"; + displayNameShort = "HE-AIRBURST"; + ammo = "AGM_81mmShell_AMMO_airburst"; + }; + class AGM_8Rnd_81mmShell_smokeWhite: AGM_8Rnd_81mmShell_HE { + displayName = "Smoke (White)"; + displayNameShort = "SMOKE"; + ammo = "AGM_81mmShell_AMMO_smokeWhite"; + }; + class AGM_8Rnd_81mmShell_smokeRed: AGM_8Rnd_81mmShell_HE { + displayName = "Smoke (Red)"; + displayNameShort = "SMOKE-RED"; + ammo = "AGM_81mmShell_AMMO_smokeRed"; + }; + // class AGM_81mmShell_Incinerate: AGM_8Rnd_81mmShell_HE { + // displayName = "Incinerate"; + // displayNameShort = "BURN"; + // ammo = "AGM_81mmShell_AMMO_Incinerate"; + // }; + class AGM_8Rnd_81mmShell_flareWhite: AGM_8Rnd_81mmShell_HE { + displayName = "Flare (White)"; + displayNameShort = "FLARE-WHITE"; + ammo = "AGM_81mmShell_AMMO_flareWhite"; + }; +}; + +class CfgWeapons { + class AGM_ItemCore; + class InventoryItem_Base_F; + + class AGM_RangeTable_81mm: AGM_ItemCore { + displayName = "AGM_RangeTable_81mm"; + descriptionShort = "AGM_RangeTable_81mm"; + model = "\A3\weapons_F\ammo\mag_univ.p3d"; + picture = "\AGM_Artillery\UI\icon_rangeTable.paa"; + scope = 2; + class ItemInfo: InventoryItem_Base_F { + mass = 1; + }; + }; + + class CannonCore; + class mortar_82mm: CannonCore { + class Single1; + }; + + class AGM_Artillery_81mm: mortar_82mm { + displayname = "Mortar 81mm"; + + magazineReloadTime = 2; //default: 5 + reloadTime = 2; //default: 1.8 + + magazines[] = {"AGM_8Rnd_81mmShell_HE", "AGM_8Rnd_81mmShell_airburst", "AGM_8Rnd_81mmShell_smokeWhite", "AGM_8Rnd_81mmShell_smokeRed", "AGM_8Rnd_81mmShell_flareWhite"}; + modes[] = {"Charge1","Charge2","Charge3","Charge4","Charge5"}; + class Charge1: Single1 { + artilleryDispersion = 1.9; + artilleryCharge = 0.2; + displayName = "Charge 0"; //I think these are just used in the default BIS comp, so no need to translate + }; + class Charge2: Charge1 { + artilleryCharge = 0.4; + displayName = "Charge 1"; + }; + class Charge3: Charge1 { + artilleryCharge = 0.6; + displayName = "Charge 2"; + }; + class Charge4: Charge1 { + artilleryCharge = 0.8; + displayName = "Charge 3"; + }; + class Charge5: Charge1 { + artilleryCharge = 1; + displayName = "Charge 4"; + }; + }; +}; + +//Add Wind/Submunitions Event Handler +class Extended_FiredBIS_EventHandlers { + class AGM_advancedMortar_base { + class AGM_Artillery_fired { + clientFiredBIS = "_this call AGM_Artillery_fnc_firedEH"; + }; + }; +}; + +class CfgVehicles { + //Range Table Actions For Player + class Man; + class CAManBase: Man { + class AGM_SelfActions { + class AGM_Equipment { + class AGM_RangeTable { + displayName = "$STR_AGM_Artillery_Mortar_RangeTable"; + condition = "'AGM_RangeTable_81mm' in (items _player)"; + statement = "['AGM_Artillery_81mm'] call AGM_Artillery_fnc_rangeTableOpen;"; + showDisabled = 0; + priority = 0; + enableInside = 1; + }; + }; + }; + }; + + //Backpacks + class Bag_Base; + class Weapon_Bag_Base: Bag_Base {class assembleInfo;}; + class B_AGM_Artillery_backpack_tube: Weapon_Bag_Base { + author = "Pabst Mirror"; + displayName = "$STR_AGM_Artillery_Mortar_Backpack_Tube"; // (M253) + + faction = "BLU_F"; + scope = 2; + model = "\A3\Drones_F\Weapons_F_Gamma\Ammoboxes\Bags\UAV_backpack_F.p3d"; + hiddenSelectionsTextures[] = {"\A3\Drones_F\Weapons_F_Gamma\Ammoboxes\Bags\data\UAV_backpack_rgr_co.paa"}; + picture = "\A3\Drones_F\Weapons_F_Gamma\ammoboxes\bags\data\ui\icon_B_C_UAV_rgr_ca"; + icon = "iconBackpack"; + mass = 400; // mass = kg x 22.0462 + maximumLoad = 0; + + class assembleInfo: assembleInfo { + displayName = "$STR_AGM_Artillery_Mortar_Assemble"; + assembleTo = "B_AGM_advancedMortar"; + base[] = {"B_AGM_Artillery_backpack_baseplate"}; + }; + }; + class B_AGM_Artillery_backpack_tube_NoOptics: B_AGM_Artillery_backpack_tube { + displayName = "$STR_AGM_Artillery_Mortar_Backpack_Tube_NoOptic"; // (M253) + class assembleInfo: assembleInfo { + assembleTo = "B_AGM_advancedMortar_NoOptics"; + }; + }; + class B_AGM_Artillery_backpack_baseplate: Bag_Base { + author = "Pabst Mirror"; + displayName = "STR_AGM_Artillery_Mortar_Backpack_Base"; // (M177) + + faction = "BLU_F"; + scope = 2; + model = "\A3\Drones_F\Weapons_F_Gamma\Ammoboxes\Bags\UAV_backpack_F.p3d"; + hiddenSelectionsTextures[] = {"\A3\Drones_F\Weapons_F_Gamma\Ammoboxes\Bags\data\UAV_backpack_rgr_co.paa"}; + picture = "\A3\Drones_F\Weapons_F_Gamma\ammoboxes\bags\data\ui\icon_B_C_UAV_rgr_ca"; + icon = "iconBackpack"; + mass = 400; // mass = kg x 22.0462 + maximumLoad = 0; + + class assembleInfo { + primary = 0; + base = ""; + assembleTo = ""; + dissasembleTo[] = {}; + displayName = ""; + }; + }; + + //Mortar Itself + class LandVehicle; + class StaticWeapon: LandVehicle { + class Turrets { + class MainTurret; + }; + }; + class StaticMortar: StaticWeapon { + class Turrets: Turrets { + class MainTurret: MainTurret { + class ViewOptics; + }; + }; + }; + class Mortar_01_base_F: StaticMortar { + class assembleInfo; + }; + + //Define the Mortar's Base Class + class AGM_advancedMortar_base : Mortar_01_base_F { + _generalMacro = "AGM_advancedMortar_base"; + author = "Pabst Mirror"; + displayname = "$STR_AGM_Artillery_Mortar_Name"; + artilleryScanner = 0; //disable BIS's Artillery Computer + hiddenSelectionsTextures[] = {"\AGM_Artillery\data\mortar_01_grey_co.paa"}; //Simple recoloring of the skin + + //add Artillery Computer Action + class UserActions { + class OpenComputer { + displayName = "$STR_AGM_Artillery_ArtilleryComputer"; + position = ""; + radius = 1; + condition = "((gunner this) == AGM_player) && (this getVariable ['AGM_Artillery_mapComputerEnabled', false])"; + statement = "[] spawn AGM_Artillery_fnc_mapCompOpen;"; + onlyForPlayer = true; + }; + }; + + class Library {libTextDesc = "Mortar";}; + + class Turrets: Turrets { + class MainTurret: MainTurret { + weapons[] = {"AGM_Artillery_81mm"}; + magazines[] = {"AGM_8Rnd_81mmShell_HE", "AGM_8Rnd_81mmShell_airburst", "AGM_8Rnd_81mmShell_smokeWhite", "AGM_8Rnd_81mmShell_smokeRed", "AGM_8Rnd_81mmShell_flareWhite"}; + elevationMode = 1; + turretInfoType = "AGM_Artillery_RscWeaponRangeArtilleryCustom"; + class ViewOptics: ViewOptics { + visionMode[] = {"Normal"}; + }; + class OpticsIn { + class Wide: RCWSOptics { + initFov = "0.2"; + minFov = "0.2"; + maxFov = "0.2"; + visionMode[] = {"Normal"}; + thermalMode[] = {}; + gunnerOpticsModel = "\a3\weapons_f\reticle\Optics_Driver_01_F"; + gunnerOpticsEffect[] = {}; + }; + class Medium: Wide { + gunnerOpticsModel = "\AGM_Vector\agm_vector_optics"; + initFov = "0.03"; + minFov = "0.03"; //todo: tweak these values so mil marks match actual values (vector has same problem) + maxFov = "0.03"; + }; + // class Narrow: Wide { + // gunnerOpticsModel = "\A3\Weapons_F\acc\reticle_sniper_z_F"; + // initFov = "0.01"; + // minFov = "0.01"; + // maxFov = "0.01"; + // }; + }; + }; + }; + }; + //Base Class Without super zoom optics + class AGM_advancedMortar_NoOptics_base: AGM_advancedMortar_base { + _generalMacro = "AGM_advancedMortar_NoOptics_base"; + displayname = "$STR_AGM_Artillery_Mortar_Name_NoOptic"; + class Turrets: Turrets { + class MainTurret: MainTurret { + gunnerForceOptics = 0; + class OpticsIn: OpticsIn { + class Wide: Wide {}; + delete Medium; + }; + }; + }; + }; + + //Side specific mortar implementation (are these needed for all sides?) + class B_AGM_advancedMortar : AGM_advancedMortar_base { + author = "Pabst Mirror"; + _generalMacro = "B_AGM_advancedMortar"; + scope = 2; + side = 1; + faction = "BLU_F"; + crew = "B_Soldier_F"; //AI are never going to know how to use this + availableForSupportTypes[] = {"Artillery"}; + + class assembleInfo: assembleInfo { + dissasembleTo[] = {"B_AGM_Artillery_backpack_tube", "B_AGM_Artillery_backpack_baseplate"}; + }; + }; + + class B_AGM_advancedMortar_NoOptics: AGM_advancedMortar_NoOptics_base { + _generalMacro = "B_AGM_advancedMortar"; + scope = 2; + side = 1; + faction = "BLU_F"; + crew = "B_Soldier_F"; + availableForSupportTypes[] = {"Artillery"}; + + class assembleInfo: assembleInfo { + dissasembleTo[] = {"B_AGM_Artillery_backpack_tube_NoOptics", "B_AGM_Artillery_backpack_baseplate"}; + }; + }; +}; diff --git a/AGM_Artillery/data/compass_base.p3d b/AGM_Artillery/data/compass_base.p3d new file mode 100644 index 000000000..d7099884d Binary files /dev/null and b/AGM_Artillery/data/compass_base.p3d differ diff --git a/AGM_Artillery/data/compass_base.paa b/AGM_Artillery/data/compass_base.paa new file mode 100644 index 000000000..da5a572a2 Binary files /dev/null and b/AGM_Artillery/data/compass_base.paa differ diff --git a/AGM_Artillery/data/compass_star.p3d b/AGM_Artillery/data/compass_star.p3d new file mode 100644 index 000000000..a80979209 Binary files /dev/null and b/AGM_Artillery/data/compass_star.p3d differ diff --git a/AGM_Artillery/data/compass_star.rvmat b/AGM_Artillery/data/compass_star.rvmat new file mode 100644 index 000000000..03ad9eff4 --- /dev/null +++ b/AGM_Artillery/data/compass_star.rvmat @@ -0,0 +1,103 @@ +//////////////////////////////////////////////////////////////////// +//DeRap: Produced from mikero's Dos Tools Dll version 4.73 +//Mon Oct 27 04:27:03 2014 : Source 'file' date Mon Oct 27 04:27:03 2014 +//http://dev-heaven.net/projects/list_files/mikero-pbodll +//////////////////////////////////////////////////////////////////// + +#define _ARMA_ + +//Class ui_f : objects\data\compass_base_star.rvmat{ +ambient[] = {1,1,1,1}; +diffuse[] = {0.3,0.3,0.3,1}; +forcedDiffuse[] = {0,0,0,0}; +emmisive[] = {0,0,0,1}; +specular[] = {0.3,0.3,0.3,1}; +specularPower = 170; +PixelShaderID = "Super"; +VertexShaderID = "Super"; +class Stage1 +{ + texture = "a3\ui_f\objects\data\compass_base_star_nohq.paa"; + uvSource = "tex"; + class uvTransform + { + aside[] = {1,0,0}; + up[] = {0,1,0}; + dir[] = {0,0,0}; + pos[] = {0,0,0}; + }; +}; +class Stage2 +{ + texture = "#(argb,8,8,3)color(0.5,0.5,0.5,1,DT)"; + uvSource = "tex"; + class uvTransform + { + aside[] = {1.5,0,0}; + up[] = {0,1.5,0}; + dir[] = {0,0,0}; + pos[] = {0,1,0}; + }; +}; +class Stage3 +{ + texture = "#(argb,8,8,3)color(0,0,0,0,MC)"; + uvSource = "tex"; + class uvTransform + { + aside[] = {1,0,0}; + up[] = {0,1,0}; + dir[] = {0,0,0}; + pos[] = {0,0,0}; + }; +}; +class Stage4 +{ + texture = "#(argb,8,8,3)color(1,1,1,1,AS)"; + uvSource = "tex"; + class uvTransform + { + aside[] = {1,0,0}; + up[] = {0,1,0}; + dir[] = {0,0,0}; + pos[] = {0,0,0}; + }; +}; +class Stage5 +{ + texture = "a3\ui_f\objects\data\compass_base_star_smdi.paa"; + uvSource = "tex"; + class uvTransform + { + aside[] = {1,0,0}; + up[] = {0,1,0}; + dir[] = {0,0,0}; + pos[] = {0,0,0}; + }; +}; +class Stage6 +{ + texture = "#(ai,64,64,1)fresnel(1.2,0.1)"; + uvSource = "tex"; + class uvTransform + { + aside[] = {1,0,0}; + up[] = {0,1,0}; + dir[] = {0,0,0}; + pos[] = {0,0,0}; + }; +}; +class Stage7 +{ + texture = "a3\data_f\env_land_ca.paa"; + useWorldEnvMap = "true"; + uvSource = "tex"; + class uvTransform + { + aside[] = {1.0,0.0,0.0}; + up[] = {0.0,1.0,0.0}; + dir[] = {0.0,0.0,0.0}; + pos[] = {0.0,0.0,0.0}; + }; +}; +//}; diff --git a/AGM_Artillery/data/compass_star2.paa b/AGM_Artillery/data/compass_star2.paa new file mode 100644 index 000000000..6606fe599 Binary files /dev/null and b/AGM_Artillery/data/compass_star2.paa differ diff --git a/AGM_Artillery/data/mortar_01_grey_co.paa b/AGM_Artillery/data/mortar_01_grey_co.paa new file mode 100644 index 000000000..849f3be67 Binary files /dev/null and b/AGM_Artillery/data/mortar_01_grey_co.paa differ diff --git a/AGM_Artillery/functions/fn_createFiringSolution.sqf b/AGM_Artillery/functions/fn_createFiringSolution.sqf new file mode 100644 index 000000000..860a32ce0 --- /dev/null +++ b/AGM_Artillery/functions/fn_createFiringSolution.sqf @@ -0,0 +1,99 @@ +/* +Name: AGM_Artillery_fnc_createFiringSolution + +Author: Pabst Mirror + +Description: + Converts numbers into nicely formated strings. + +Parameters: + 0: OBJECT - Mortar Vehicle + 1: BOOL - Program the solution in (setVariable) or just return it + 2: STRING - Magazine Classname + 3: NUMBER - Charage Number + + (4: ARRAY - position of target) + OR + (4: NUMBER - rotation in degrees + 5: NUMBER: Horizontal Distance (meters) + 6: NUMBER: Height Difference (meters) - "VERTICAL INTERVAL") + +Returns: + ARRAY - [ + solutionElevation (NUMBER - Degrees), + solutionTime (NUMBER - Second) + ] + +Example: + [theMortar, true, "shell", 2, [444, 444, 0]] call AGM_Artillery_fnc_createFiringSolution; +*/ + +#define TIME_STEP (1/50) + +private ["_mortarVeh", "_programSolution", "_magazineClassname", "_chargeNumber", "_rotationDegrees", "_horizontalDistance", "_heightDiff", "_targetPosition", "_mortarPos", "_tubeWeaponName", "_fireModes", "_artilleryCharge", "_ammoMaxSpeed", "_ammoClassname", "_ammoAirfriction", "_muzzleVelocity", "_findSolution", "_solutionElevation", "_solutionTime"]; + +if ((!isNil "AGM_Artillery_computingSolution") && {AGM_Artillery_computingSolution}) exitWith {systemChat "Already Computing Solution";}; + +AGM_Artillery_computingSolution = true; + +_mortarVeh = _this select 0; +_programSolution = _this select 1; //program it in, or just return data +_magazineClassname = _this select 2; +_chargeNumber = _this select 3; + +_rotationDegrees = -1; +_horizontalDistance = -1; +_heightDiff = -1; + +if ((typeName (_this select 4)) == "ARRAY") then { + _targetPosition = _this select 4; + _mortarPos = getPos _mortarVeh; + _rotationDegrees = [_mortarPos, _targetPosition] call BIS_fnc_dirTo; + _heightDiff = ((ATLToASL _targetPosition) select 2) - ((ATLToASL _mortarPos) select 2); + _mortarPos set [2, 0]; + _targetPosition set [2, 0]; + _horizontalDistance = _mortarPos vectorDistance _targetPosition; +} else { + _rotationDegrees = _this select 4; + _horizontalDistance = _this select 5; + _heightDiff = _this select 6; +}; + +_tubeWeaponName = if ((typeName _mortarVeh) == "OBJECT") then { //it's a vehicle object + currentWeapon _mortarVeh; +} else { //it's a weaponName string + _programSolution = false; + _mortarVeh; +}; +_fireModes = getArray (configFile >> "CfgWeapons" >> _tubeWeaponName >> "modes"); +if (_chargeNumber > ((count _fireModes) - 1)) exitWith {systemChat "Error: Bad Fire Mode";}; +_artilleryCharge = getNumber (configFile >> "CfgWeapons" >> _tubeWeaponName >> (_fireModes select _chargeNumber) >> "artilleryCharge"); +_ammoMaxSpeed = getNumber (configFile >> "CfgMagazines" >> (_magazineClassname) >> "initSpeed"); +_ammoClassname = getText (configFile >> "CfgMagazines" >> (_magazineClassname) >> "ammo"); +_ammoAirfriction = getNumber (configFile >> "CfgAmmo" >> _ammoClassname >> "AGM_Artillery_realAirFriction"); + +//Muzzle Velocity is from 2 configs: weapon's artilleryCharge and ammo's initSpeed +_muzzleVelocity = _artilleryCharge * _ammoMaxSpeed; + +//compute the solution +_findSolution = [_horizontalDistance, _heightDiff, _muzzleVelocity, _ammoAirfriction, TIME_STEP] call AGM_Artillery_fnc_simulateFindSolution; + +_solutionElevation = -1; +_solutionTime = -1; +if ((count _findSolution) > 0) then { + _solutionElevation = _findSolution select 0; + _solutionTime = _findSolution select 1; +}; + +if (_programSolution) then { + _mortarVeh setVariable ["AGM_Artillery_targetHorziontalDistance", _horizontalDistance, true]; + _mortarVeh setVariable ["AGM_Artillery_targetHeightDiff", _heightDiff, true]; + _mortarVeh setVariable ["AGM_Artillery_targetAzimuth", _rotationDegrees, true]; + _mortarVeh setVariable ["AGM_Artillery_solutionCharge", _chargeNumber, true]; + _mortarVeh setVariable ["AGM_Artillery_solutionElev", _solutionElevation, true]; + _mortarVeh setVariable ["AGM_Artillery_solutionTime", _solutionTime, true]; +}; + +AGM_Artillery_computingSolution = false; + +[_solutionElevation, _solutionTime] diff --git a/AGM_Artillery/functions/fn_dev_buildTable.sqf b/AGM_Artillery/functions/fn_dev_buildTable.sqf new file mode 100644 index 000000000..f0332b210 --- /dev/null +++ b/AGM_Artillery/functions/fn_dev_buildTable.sqf @@ -0,0 +1,76 @@ +/* +Name: AGM_Artillery_fnc_dev_buildTable + +Author: Pabst Mirror + +Description: + DEV function to build mortar tables, very cpu intensive (never used durring normal gameplay) + +Parameters: (normal BIS "Fired" EH stuff) + 0: NUMBER - Muzzle Velocity + 1: NUMBER - Air Friction + +Returns: + Data in clipboard + +Example: + [100, -0.0001] spawn AGM_Artillery_fnc_dev_buildTable; //spawn (scheduled) is slower + [100, -0.0001] call AGM_Artillery_fnc_dev_buildTable; //faster, but will lock while processing +*/ + +private ["_muzzleVelocity", "_airFriction", "_stillInRange", "_currentRange", "_increasePerRow", "_outputArray", "_rangeToHit", "_lineElevation", "_lineHeightElevation", "_lineTimeOfFlight", "_lineCrosswindDeg", "_lineHeadwindMeters", "_lineTailWindMeters", "_lineTempDec", "_lineTempInc", "_lineAirDensDec", "_lineAirDensInc", "_result", "_outputString"]; + +_muzzleVelocity = _this select 0; +_airFriction = _this select 1; +_stillInRange = true; +_currentRange = 100; +_increasePerRow = 50; +_outputArray = []; + + +//[_rangeToHit, _lineElevation, _lineHeightElevation, _lineTimeOfFlight, _lineCrosswindDeg, _lineHeadwindMeters, _lineTailWindMeters, _lineTempDec, _lineTempInc, _lineAirDensDec, _lineAirDensInc] + +while {_stillInRange} do { + _result = [_muzzleVelocity, _currentRange, _airFriction] call AGM_Artillery_fnc_simulateCalcRangeTableLine; + if (_result isEqualTo []) then { + _stillInRange = false; + } else { + if ((_result select 1) < 86) then { + _outputArray pushBack [ + ([(_result select 0), "meters", false] call AGM_Artillery_fnc_formatNumber), + ([(_result select 1), "mil", true] call AGM_Artillery_fnc_formatNumber), + ([(_result select 2), "mil", true] call AGM_Artillery_fnc_formatNumber), + ([(_result select 3), "sec", false] call AGM_Artillery_fnc_formatNumber), + ([(_result select 4), "milPrecise", true] call AGM_Artillery_fnc_formatNumber), + ([(_result select 5), "metersprecise", false] call AGM_Artillery_fnc_formatNumber), + ([(_result select 6), "metersprecise", false] call AGM_Artillery_fnc_formatNumber), + ([(_result select 7), "metersprecise", false] call AGM_Artillery_fnc_formatNumber), + ([(_result select 8), "metersprecise", false] call AGM_Artillery_fnc_formatNumber), + ([(_result select 9), "metersprecise", false] call AGM_Artillery_fnc_formatNumber), + ([(_result select 10), "metersprecise", false] call AGM_Artillery_fnc_formatNumber) + ]; + }; + _currentRange = _currentRange + _increasePerRow; + }; + hint str _currentRange; +}; + +//handle floating point rounding errors +_outputString = format ["case ((abs(_muzzleVelocity - %1) < 0.00001) && ((abs(_airFriction - %2) < 0.00001))): { +[ +", _muzzleVelocity, _airFriction]; + +{ + if (_forEachIndex < ((count _outputArray) - 1)) then { + _outputString = _outputString + format ["%1, + ", _x]; + } else { + _outputString = _outputString + format ["%1 + ] + };", _x]; + }; +} forEach _outputArray; + +copyToClipboard _outputString; + +hint "done"; \ No newline at end of file diff --git a/AGM_Artillery/functions/fn_firedEH.sqf b/AGM_Artillery/functions/fn_firedEH.sqf new file mode 100644 index 000000000..b7ea7e3aa --- /dev/null +++ b/AGM_Artillery/functions/fn_firedEH.sqf @@ -0,0 +1,83 @@ +/* +Name: AGM_Artillery_fnc_firedEH + +Author: Pabst Mirror (based on AGM_Wind_fnc_firedEH by KoffeinFlummi, esteldunedain) + +Description: + Wind/Submunitions Handling + +Parameters: (normal BIS "Fired" EH stuff) + 0: OBJECT - Mortar Vehicle + 4: STRING - Ammo classname + 6: OBJECT - The shell object + +Returns: + None + +Example: + called from Extended_FiredBIS_EventHandlers +*/ + +private ["_ammoType", "_round", "_dispersion", "_additionalVel"]; + +// _unit = _this select 0; +_ammoType = _this select 4; +_round = _this select 6; + +// Additional dispersion +_dispersion = 0; //getNumber (configFile >> "CfgAmmo" >> _ammoType >> "AGM_Bullet_Dispersion"); + +// Powder temp effect +_additionalVel = (vectorMagnitude (velocity _round)) * ((((AGM_Wind_currentTemperature + 273.13) / 288.13 - 1) / 2.5 + 1 ) - 1); + +// systemChat format ["debug: %1 vel[%2] disp[%3] add[%4]", _ammoType, (vectorMagnitude (velocity _round)), _dispersion, _additionalVel]; + +[_round, ((random 2) - 1) * _dispersion, ((random 2) - 1) * _dispersion, _additionalVel] call AGM_Core_fnc_changeProjectileDirection; + +_this spawn { + private ["_ammoType", "_round", "_airFriction", "_carryAmmo", "_carryEjectHeight", "_markerStringName", "_time", "_deltaTime", "_velocity", "_aparentWind", "_changeInVelocity", "_velocityNew", "_predictedPos", "_linConversion", "_actualEjectPos", "_boom"]; + + _ammoType = _this select 4; + _round = _this select 6; + + _airFriction = getNumber (configFile >> "CfgAmmo" >> _ammoType >> "AGM_Artillery_realAirFriction"); + _carryAmmo = getText (configFile >> "CfgAmmo" >> _ammoType >> "AGM_Artillery_carryAmmo"); + _carryEjectHeight = getNumber (configFile >> "CfgAmmo" >> _ammoType >> "AGM_Artillery_carryEjectHeight"); + + //debug marker + _markerStringName = format ["test%1", _round]; + createMarker [_markerStringName, [0,0,0]]; + _markerStringName setMarkerType "mil_dot"; + _markerStringName setMarkerText str time; + + _time = time; + sleep 0.05; + while {(!isNull _round) && (alive _round)} do { + _markerStringName setMarkerPos position _round;//debug marker + + _deltaTime = time - _time; // Use actual time delay between iterations instead of a set interval to account for ultra-low framerates. + _velocity = velocity _round; + _aparentWind = wind vectorDiff _velocity; + + _changeInVelocity = _aparentWind vectorMultiply ((vectorMagnitude _aparentWind) * AGM_Wind_currentRelativeDensity * -1 * _airFriction * _deltaTime); + + // hintSilent format ["Change\n%1", _changeInVelocity vectorMultiply (1/(_deltaTime max 0.000001))]; + + _velocityNew = _velocity vectorAdd _changeInVelocity; + _round setVelocity _velocityNew; + + if ((_carryAmmo != "") && ((_velocityNew select 2) < 1)) then { //hasSubmunition and after reaching max height (starting downward velocity) + _predictedPos = (getPos _round) vectorAdd (_velocityNew vectorMultiply _deltaTime); //see where it will be next frame + if ((_predictedPos select 2) < _carryEjectHeight) then { + //Calc the actual postion at the given height (Linear interpolation) + _linConversion = linearConversion [((getPos _round) select 2), (_predictedPos select 2), _carryEjectHeight, 0, _deltaTime, true]; + _actualEjectPos = (getPos _round) vectorAdd (_velocityNew vectorMultiply _linConversion); + _boom = _carryAmmo createVehicle _actualEjectPos; + _boom setPos _actualEjectPos; + _carryAmmo = ""; + }; + }; + _time = time; + sleep 0.05; + }; +}; diff --git a/AGM_Artillery/functions/fn_formatNumber.sqf b/AGM_Artillery/functions/fn_formatNumber.sqf new file mode 100644 index 000000000..ee52c6464 --- /dev/null +++ b/AGM_Artillery/functions/fn_formatNumber.sqf @@ -0,0 +1,82 @@ +/* +Name: AGM_Artillery_fnc_formatNumber + +Author: Pabst Mirror + +Description: + Converts numbers into nicely formated strings. + +Parameters: + 0: NUMBER - Input number + 1: STRING - Output type (see case statement) + 2: BOOL - If output type is mil, convert input type from deg->mil + +Returns: + STRING - Formatted number + +Example: + [45, "mil4", true] call AGM_Artillery_fnc_formatNumber = "0800" +*/ + +private ["_theNumber", "_inputType", "_convertToMils", "_decimalPlaces", "_integerPlaces", "_prefix", "_return"]; + +_theNumber = _this select 0; +_inputType = _this select 1; +_convertToMils = _this select 2; + +_decimalPlaces = -1; +_integerPlaces = -1; + +switch (toLower _inputType) do { +case ("meters"): { + _decimalPlaces = 0; + _integerPlaces = 1; + }; +case ("metersprecise"): { + _decimalPlaces = 1; + _integerPlaces = 1; + }; +case ("meters4"): { + _decimalPlaces = 0; + _integerPlaces = 4; + }; +case ("deg3precise"): { + _decimalPlaces = 2; + _integerPlaces = 3; + }; +case ("mil"): { + _decimalPlaces = 0; + _integerPlaces = 1; + if (_convertToMils) then { + _theNumber = _theNumber * (6400 / 360); + }; + }; +case ("mil4"): { + _decimalPlaces = 0; + _integerPlaces = 4; + if (_convertToMils) then { + _theNumber = _theNumber * (6400 / 360); + }; + }; +case ("milprecise"): { + _decimalPlaces = 1; + _integerPlaces = 1; + if (_convertToMils) then { + _theNumber = _theNumber * (6400 / 360); + }; + }; +case ("sec"): { + _decimalPlaces = 1; + _integerPlaces = 1; + }; + default {systemChat format ["badtype %1", _inputType];}; +}; + + +//CBA_fnc_formatNumber is stupid: [-9.58545, 1, 1, false] call CBA_fnc_formatNumber == "-9.-6" + +_prefix = if (_theNumber < 0) then {"-"} else {""}; + +_return = [abs (_theNumber), _integerPlaces, _decimalPlaces, false] call CBA_fnc_formatNumber; + +(_prefix + _return) diff --git a/AGM_Artillery/functions/fn_getPosFromMapCords.sqf b/AGM_Artillery/functions/fn_getPosFromMapCords.sqf new file mode 100644 index 000000000..f9f85f81a --- /dev/null +++ b/AGM_Artillery/functions/fn_getPosFromMapCords.sqf @@ -0,0 +1,67 @@ +/* +Name: AGM_Artillery_fnc_getPosFromMapCords + +Author: Pabst Mirror + +Description: + Converts numbers into nicely formated strings. + Uses dumb, brute force. + CBA has CBA_fnc_mapGridToPos, but it throws errors on some islands + +Parameters: + 0: STRING - Grid Cords (needs to match the world's grid cords length) Usualy Numbers, but can be anything on some islands + +Returns: + ARRAY - Position (height always 0) + +Example: + ["030050"] call AGM_Artillery_fnc_getPosFromMapCords = [3050,5050,0] //stratis + ["Dc65"] call AGM_Artillery_fnc_getPosFromMapCords = [6500,7300,0] //Sarhani (["DC", "65"] call CBA_fnc_mapGridToPos = error) +*/ + +private ["_worldMapGridLength", "_inputString", "_inputStringLen", "_yString", "_xString", "_stepX", "_stepY", "_found", "_xPos", "_yPos"]; + +_worldMapGridLength = count (toArray (mapGridPosition [0,0,0])); +if (_worldMapGridLength == 0) exitWith { + ["Bad mapGridPosition in %1", worldName] call bis_fnc_error; + [0,0,0] +}; + +_inputString = [_this, 0, "", [""]] call bis_fnc_param; +_inputStringLen = count (toArray (_inputString)); + +if (_inputStringLen != _worldMapGridLength) exitWith { + ["Map Cords Length Does Not Match World %1", worldName] call bis_fnc_error; + [0,0,0] +}; + +_yString = _inputString select [(_worldMapGridLength / 2), (_worldMapGridLength / 2)]; +_xString = _inputString select [0, (_worldMapGridLength / 2)]; + +_stepX = getNumber (configfile >> "cfgworlds" >> worldName >> "grid" >> "Zoom1" >> "stepX"); +_stepY = getNumber (configfile >> "cfgworlds" >> worldName >> "grid" >> "Zoom1" >> "stepY"); +if ((_stepX == 0) || (_stepY == 0)) exitWith { + ["Bad step in %1", worldName] call bis_fnc_error; + [0,0,0] +}; + +_found = false; +_xPos = _stepX / 2; +while {!_found} do { + if (((mapGridPosition [_xPos, 0]) select [0, (_worldMapGridLength / 2)]) == _xString) then { + _found = true; + } else { + _xPos = _xPos + abs (_stepX); + }; +}; +_found = false; +_yPos = _stepY / 2; +while {!_found} do { + if (((mapGridPosition [0, _yPos]) select [(_worldMapGridLength / 2), (_worldMapGridLength / 2)]) == _yString) then { + _found = true; + } else { + _yPos = _yPos + abs (_stepY); + }; +}; + +[_xPos, _yPos, 0] diff --git a/AGM_Artillery/functions/fn_mapCompEventClickOnMap.sqf b/AGM_Artillery/functions/fn_mapCompEventClickOnMap.sqf new file mode 100644 index 000000000..b6f8a700e --- /dev/null +++ b/AGM_Artillery/functions/fn_mapCompEventClickOnMap.sqf @@ -0,0 +1,39 @@ +/* +Name: AGM_Artillery_fnc_mapCompEventClickOnMap + +Author: Pabst Mirror + +Description: + Converts numbers into nicely formated strings. + +Parameters: + 0: CONTROL - Map Control + 1: NUMBER - Mouse Button + 2: NUMBER - Mouse X pos + 2: NUMBER - Mouse Y pos + +Returns: + NONE + +Example: + called from "onMouseButtonClick" in gui_mapComputer.hpp +*/ + +#define MAP_CHARGE_LISTBOX (((uiNamespace getVariable ["AGM_Artillery_MapComputer_Dialog", displayNull])) displayCtrl 233232) + +_mapControl = _this select 0; +_button = _this select 1; +_screenX = _this select 2; +_screenY = _this select 3; + +_mortarVeh = (vehicle AGM_player); + +if (_button != 0) exitWith {}; + +_position = _mapControl ctrlMapScreenToWorld [_screenX, _screenY]; +_position set [2, 0]; + +_chargeSelected = lbCurSel MAP_CHARGE_LISTBOX; +if (_chargeSelected < 0) exitWith {systemChat "Error: No Charge Selected";}; + +[_mortarVeh, true, (currentMagazine _mortarVeh), _chargeSelected, _position] spawn AGM_Artillery_fnc_createFiringSolution; diff --git a/AGM_Artillery/functions/fn_mapCompEventDrawMap.sqf b/AGM_Artillery/functions/fn_mapCompEventDrawMap.sqf new file mode 100644 index 000000000..a625f2d24 --- /dev/null +++ b/AGM_Artillery/functions/fn_mapCompEventDrawMap.sqf @@ -0,0 +1,54 @@ +/* +Name: AGM_Artillery_fnc_mapCompEventDrawMap + +Author: Pabst Mirror + +Description: + Draws range circles (from pre-computed range table) + +Parameters: + 0: CONTROL - Map computer Map Control + +Returns: + NONE + +Example: + called from "onDraw" in gui_mapComputer.hpp +*/ + +#define MAP_CHARGE_LISTBOX (((uiNamespace getVariable ["AGM_Artillery_MapComputer_Dialog", displayNull])) displayCtrl 233232) + +_theMap = _this select 0; +_mortarVeh = (vehicle AGM_player); + +//Draw Self? + + +//Calculate Target Pos and Draw +_dist = _mortarVeh getVariable ["AGM_Artillery_targetHorziontalDistance", 0]; +_az = _mortarVeh getVariable ["AGM_Artillery_targetAzimuth", 0]; + +_targetPos = [(getPos _mortarVeh), _dist, _az] call BIS_fnc_relPos; + +_theMap drawEllipse [_targetPos, 30, 30, 0, [1,0,1,1], ""]; +_theMap drawEllipse [_targetPos, 60, 60, 0, [1,0,1,1], ""]; + + +//Draw Min Max Range +_chargeSelected = lbCurSel MAP_CHARGE_LISTBOX; +if (_chargeSelected < 0) exitWith {}; +_listBoxData = MAP_CHARGE_LISTBOX lbData (lbCurSel MAP_CHARGE_LISTBOX); +if (isNil "_listBoxData") exitWith {}; + +_muzzleVelocity = parseNumber _listBoxData; +_airFriction = -0.0001; //todo + +_lookUpTableArray = [_muzzleVelocity, _airFriction] call AGM_Artillery_fnc_rangeTablePreCalculatedValues; + +if (count _lookUpTableArray < 1) exitWith {}; + +_minRange = parseNumber ((_lookUpTableArray select 0) select 0); +_maxRange = parseNumber ((_lookUpTableArray select ((count _lookUpTableArray) - 1)) select 0); + +_theMap drawEllipse [(getpos _mortarVeh), _minRange, _minRange, 0, [1,0,0,1], ""]; +_theMap drawEllipse [(getpos _mortarVeh), _maxRange, _maxRange, 0, [1,0,0,1], ""]; diff --git a/AGM_Artillery/functions/fn_mapCompEventEnterCords.sqf b/AGM_Artillery/functions/fn_mapCompEventEnterCords.sqf new file mode 100644 index 000000000..b3a199a41 --- /dev/null +++ b/AGM_Artillery/functions/fn_mapCompEventEnterCords.sqf @@ -0,0 +1,32 @@ +/* +Name: AGM_Artillery_fnc_mapCompEventEnterCords + +Author: Pabst Mirror + +Description: + Loads the entered cords, gets their position, and computes a firing solution. + +Parameters: + NONE + +Returns: + NONE + +Example: + called from button's "action" in gui_mapComputer.hpp +*/ + +private ["_mortarVeh", "_cordsText", "_position", "_chargeSelected"]; + +#define MAP_CORD_EDIT ((uiNamespace getVariable ["AGM_Artillery_MapComputer_Dialog", displayNull]) displayCtrl 233237) +#define MAP_CHARGE_LISTBOX (((uiNamespace getVariable ["AGM_Artillery_MapComputer_Dialog", displayNull])) displayCtrl 233232) + +_mortarVeh = vehicle AGM_player; + +_cordsText = ctrlText MAP_CORD_EDIT; +_position = [_cordsText] call AGM_Artillery_fnc_getPosFromMapCords; + +_chargeSelected = lbCurSel MAP_CHARGE_LISTBOX; +if (_chargeSelected < 0) exitWith {systemChat "Error: No Charge Selected";}; + +[_mortarVeh, true, (currentMagazine _mortarVeh), _chargeSelected, _position] spawn AGM_Artillery_fnc_createFiringSolution; diff --git a/AGM_Artillery/functions/fn_mapCompOpen.sqf b/AGM_Artillery/functions/fn_mapCompOpen.sqf new file mode 100644 index 000000000..ab33bba3f --- /dev/null +++ b/AGM_Artillery/functions/fn_mapCompOpen.sqf @@ -0,0 +1,57 @@ +/* +Name: AGM_Artillery_fnc_mapCompOpen + +Author: Pabst Mirror + +Description: + Handles opening the map computer dialog. Fills the charge display + +Parameters: + NONE + +Returns: + STRING - Formatted number + +Example: + Called from the Mortars UserActions (action menu) +*/ + +private ["_mortarVeh", "_weaponName", "_fireModes", "_magazines", "_magazineClassname", "_ammoMaxSpeed", "_ammoClassname", "_ammoAirfriction", "_muzzleVelocities", "_showToPlayer", "_artilleryCharge", "_currentFireMode", "_currentChargeMode"]; + +#define MAP_CHARGE_LISTBOX (((uiNamespace getVariable ["AGM_Artillery_MapComputer_Dialog", displayNull])) displayCtrl 233232) + +AGM_Artillery_COMPUTER_chargeRangeArray = []; + +if (dialog) exitWith {systemChat "Error: Dialog Open?"}; +createDialog "AGM_Artillery_MapComputer_Dialog"; +if (isNull (uiNamespace getVariable ["AGM_Artillery_MapComputer_Dialog", displayNull])) exitWith {}; + +_mortarVeh = (vehicle AGM_player); +_weaponName = currentWeapon _mortarVeh; +_fireModes = getArray (configFile >> "CfgWeapons" >> _weaponName >> "modes"); + +//Get Magazine Types +_magazines = getArray (configFile >> "CfgWeapons" >> _weaponName >> "magazines"); + +//For now just get settings from first mag, all rounds have same flight charactoristics: +if ((count _magazines) < 1) exitWith {systemChat "Error: No Magazines for weapon"}; +_magazineClassname = _magazines select 0; +_ammoMaxSpeed = getNumber (configFile >> "CfgMagazines" >> (_magazineClassname) >> "initSpeed"); +_ammoClassname = getText (configFile >> "CfgMagazines" >> (_magazineClassname) >> "ammo"); +_ammoAirfriction = getNumber (configFile >> "CfgMagazines" >> (_ammoClassname) >> "AGM_Artillery_realAirFriction"); + +_muzzleVelocities = []; +{ + _showToPlayer = getNumber (configFile >> "CfgWeapons" >> _weaponName >> _x >> "showToPlayer"); + if (_showToPlayer == 1) then { + _artilleryCharge = getNumber (configFile >> "CfgWeapons" >> _weaponName >> _x >> "artilleryCharge"); + MAP_CHARGE_LISTBOX lbAdd format ["%1: %2 [%3m/s]", (localize "STR_AGM_Artillery_Charge"), (count _muzzleVelocities), (_artilleryCharge * _ammoMaxSpeed)]; + MAP_CHARGE_LISTBOX lbSetData [(count _muzzleVelocities), str (_artilleryCharge * _ammoMaxSpeed)]; + _muzzleVelocities pushBack (_artilleryCharge * _ammoMaxSpeed); + }; +} forEach _fireModes; + +_currentFireMode = (weaponState [_mortarVeh, [0]]) select 2; +_currentChargeMode = _fireModes find _currentFireMode; + +MAP_CHARGE_LISTBOX lbSetCurSel _currentChargeMode; diff --git a/AGM_Artillery/functions/fn_onHudLoad.sqf b/AGM_Artillery/functions/fn_onHudLoad.sqf new file mode 100644 index 000000000..609322e50 --- /dev/null +++ b/AGM_Artillery/functions/fn_onHudLoad.sqf @@ -0,0 +1,153 @@ +/* +Name: AGM_Artillery_fnc_onHudLoad + +Author: Pabst Mirror + +Description: + Called on mortart hud opening, continualy updates the hud (azimuth/elevation) + +Parameters: + 0: DISPLAY - The RscInGameUI->AGM_Artillery_RscWeaponRangeArtilleryCustom display + +Returns: + NONE + +Example: + Called from "onLoad" in gui_mortarHud.hpp +*/ + +//Custom Hud Elements +#define CTRL_SOLUTIONCOMP_STRUCTEXT (_display displayCtrl 800858) +#define CTRL_VECTOR_DOT_PICTURE (_display displayCtrl 800860) +#define CTRL_AMMO_CHARGE_STRUCTEXT (_display displayCtrl 800859) +#define CTRL_ELEVATION_STRUCTEXT (_display displayCtrl 800855) +#define CTRL_AZIMUTH_STRUCTEXT (_display displayCtrl 800856) +#define CTRL_AZIMUTH_OBJECT (_display displayCtrl 800851) +#define CTRL_ELEVATION_OBJECT (_display displayCtrl 800853) + +//BIS (Hidden) Elements +#define CTRL_CA_HEADING (_display displayCtrl 156) +#define CTRL_CA_OPTICSPITCH (_display displayCtrl 182) +#define CTRL_CA_DISTANCE (_display displayCtrl 173) +// #define CTRL_CA_TIME (_display displayCtrl 174) +// #define CTRL_CA_ELEV_NEEDED (_display displayCtrl 176) + + + + +_this spawn { + AGM_Artillery_rangefinderKeyDown = false; + AGM_Artillery_computingSolution = false; + AGM_Artillery_currentWeaponSettings = []; + + disableSerialization; + _display = _this select 0; + + _mortarVeh = vehicle AGM_player; + + if ((count (weapons _mortarVeh)) < 1) exitWith {systemChat "Error: No Tube";};//should never happen + _tubeWeaponName = (weapons _mortarVeh) select 0; + _fireModes = getArray (configFile >> "CfgWeapons" >> _tubeWeaponName >> "modes"); + + //Digital Azimuth/Elevation display + _digialDisplayEnabled = (_mortarVeh getVariable ["AGM_Artillery_digialDisplayEnabled", true]); + + //Solution Display if either rangefinder or map computer + _solutionDisplayShown = (_mortarVeh getVariable ["AGM_Artillery_mapComputerEnabled", false]) || (_mortarVeh getVariable ["AGM_Artillery_rangefinderEnabled", false]); + CTRL_SOLUTIONCOMP_STRUCTEXT ctrlShow _solutionDisplayShown; + + waitUntil { + if ((isNull _display) || {(vehicle AGM_player) != _mortarVeh}) exitWith {true}; + //Compute: Current Tube Settings (from animationPhase) + _elevationDegrees = ((180 / PI) * (_mortarVeh animationPhase "mainGun")) + 75; + _rotationDegrees = ((getDir _mortarVeh) + (((-180 / PI) * (_mortarVeh animationPhase "mainTurret")) + 360)) % 360; + + //Pull Values from 'unseen' ui (from ArmA internals) - IN STRING FORMAT!! + _CA_Heading = ctrlText CTRL_CA_HEADING; + _CA_OpticsPitch = ctrlText CTRL_CA_OPTICSPITCH; + _CA_Distance = ctrlText CTRL_CA_DISTANCE; + + //Compute: Rangefinder gives total range, we want "horizontal distance" and "height" + _numViewPitch = parseNumber _CA_OpticsPitch; + _numHorizontalDistance = round ((cos (parseNumber _CA_OpticsPitch)) * (parseNumber _CA_Distance)); + _numHeightDiff = round ((sin (parseNumber _CA_OpticsPitch)) * (parseNumber _CA_Distance)); + + //Compute: 'charge' from weaponstate + _currentFireMode = (weaponState [_mortarVeh, [0]]) select 2; + _currentChargeMode = _fireModes find _currentFireMode; + + //Set: rangefinder (tab held down) -> show crosshair + CTRL_VECTOR_DOT_PICTURE ctrlShow AGM_Artillery_rangefinderKeyDown; + + //Update: 'charge' text in upper right (default arma - ammo count) + _chargeText = format ["%1: %2", (toUpper localize "STR_AGM_Artillery_Charge"), _currentChargeMode]; + CTRL_AMMO_CHARGE_STRUCTEXT ctrlSetStructuredText parseText _chargeText; + + //Update: Elevation Text + _elevText = format ["%1:
", toUpper (localize "STR_AGM_Artillery_Elevation")]; + if (_digialDisplayEnabled) then { + _elevationString = [_elevationDegrees, "mil4", true] call AGM_Artillery_fnc_formatNumber; + _elevText = _elevText + format ["", (_elevationString select [0, 1])]; + _elevText = _elevText + format ["", (_elevationString select [1, 1])]; + _elevText = _elevText + format ["", (_elevationString select [2, 1])]; + _elevText = _elevText + format ["
", (_elevationString select [3, 1])]; + }; + CTRL_ELEVATION_STRUCTEXT ctrlSetStructuredText parseText _elevText; + + //Update: Azimuth Text + _aziText = format ["%1:
", toUpper (localize "STR_AGM_Artillery_Azimuth")]; + if (_digialDisplayEnabled) then { + _azimuthString = [_rotationDegrees, "mil4", true] call AGM_Artillery_fnc_formatNumber; + _aziText = _aziText + format ["", (_azimuthString select [0, 1])]; + _aziText = _aziText + format ["", (_azimuthString select [1, 1])]; + _aziText = _aziText + format ["", (_azimuthString select [2, 1])]; + _aziText = _aziText + format ["
", (_azimuthString select [3, 1])]; + }; + CTRL_AZIMUTH_STRUCTEXT ctrlSetStructuredText parseText _aziText; + + //Update: Computer Display + if (_solutionDisplayShown) then { + _compDisplayAzimuth = (_mortarVeh getVariable ["AGM_Artillery_targetAzimuth", 0]); + _compDisplayAzimuth = [_compDisplayAzimuth, "mil4", true] call AGM_Artillery_fnc_formatNumber; + _compDisplayDist = (_mortarVeh getVariable ["AGM_Artillery_targetHorziontalDistance", 0]); + _compDisplayDist = [_compDisplayDist, "meters", false] call AGM_Artillery_fnc_formatNumber; + _compDisplayHeight = (_mortarVeh getVariable ["AGM_Artillery_targetHeightDiff", 0]); + _compDisplayHeight = [_compDisplayHeight, "meters", false] call AGM_Artillery_fnc_formatNumber; + _compDisplayCharge = str (_mortarVeh getVariable ["AGM_Artillery_solutionCharge", "--"]); + _compDisplayElev = (_mortarVeh getVariable ["AGM_Artillery_solutionElev", 0]); + _compDisplayElev = [_compDisplayElev, "mil4", true] call AGM_Artillery_fnc_formatNumber; + _compDisplayTime = (_mortarVeh getVariable ["AGM_Artillery_solutionTime", 0]); + _compDisplayTime = [_compDisplayTime, "sec", false] call AGM_Artillery_fnc_formatNumber; + + _compText = format ["%1:", (toUpper localize "STR_AGM_Artillery_Target")]; + _compText = _compText + format ["
-%1%2", toUpper (localize "STR_AGM_Artillery_Azimuth"), _compDisplayAzimuth]; + _compText = _compText + format ["
-%1%2", toUpper (localize "STR_AGM_Artillery_Range"), _compDisplayDist]; + _compText = _compText + format ["
-%1%2", toUpper (localize "STR_AGM_Artillery_Height"), _compDisplayHeight]; + _compText = _compText + format ["

%1:", toUpper (localize "STR_AGM_Artillery_Solution")]; + if (AGM_Artillery_computingSolution) then { + _compText = _compText + format ["
-%1-", toUpper (localize "STR_AGM_Artillery_Computing")]; + } else { + _compText = _compText + format ["
-%1%2", toUpper (localize "STR_AGM_Artillery_Charge"), _compDisplayCharge]; + if ((_mortarVeh getVariable ["AGM_Artillery_solutionTime", -1]) != -1) then { + _compText = _compText + format ["
-%1%2", toUpper (localize "STR_AGM_Artillery_Elevation"), _compDisplayElev]; + _compText = _compText + format ["
-%1%2", toUpper (localize "STR_AGM_Artillery_Time"), _compDisplayTime]; + } else { + _compText = _compText + format ["
--%1--", toUpper (localize "STR_AGM_Artillery_Range")]; + _compText = _compText + format ["
--%1--", toUpper (localize "STR_AGM_Artillery_Range")]; + }; + }; + CTRL_SOLUTIONCOMP_STRUCTEXT ctrlSetStructuredText parseText _compText; + }; + + //Update: Analog Wheels + CTRL_AZIMUTH_OBJECT ctrlSetModelDirAndUp [[0,1,0], [-1 * (sin _rotationDegrees), 0, cos _rotationDegrees]]; + CTRL_ELEVATION_OBJECT ctrlSetModelDirAndUp [[0,1,0], [(cos _elevationDegrees), 0, (sin _elevationDegrees)]]; + + //Set currentSettings: for rangefinder function + AGM_Artillery_currentWeaponSettings = [_mortarVeh, (currentMagazine _mortarVeh), _currentChargeMode, _rotationDegrees, _numHorizontalDistance, _numHeightDiff]; + + false + }; + + AGM_Artillery_currentWeaponSettings = []; +}; diff --git a/AGM_Artillery/functions/fn_rangeTableOpen.sqf b/AGM_Artillery/functions/fn_rangeTableOpen.sqf new file mode 100644 index 000000000..f82e018eb --- /dev/null +++ b/AGM_Artillery/functions/fn_rangeTableOpen.sqf @@ -0,0 +1,51 @@ +/* +Name: AGM_Artillery_fnc_rangeTableOpen + +Author: Pabst Mirror + +Description: + Opens a dialog that shows the range table for a certian weapon + +Parameters: + 0: STRING - Weapon Classname + +Returns: + NONE + +Example: + ["AGM_Artillery_81mm"] call AGM_Artillery_fnc_rangeTableOpen +*/ + +#define LIST_CHARGE ((uiNamespace getVariable "AGM_Artillery_RangeTable_Dialog_display") displayCtrl 1501) + +_weaponName = _this select 0; + +if (dialog) exitWith {}; +createDialog "AGM_Artillery_RangeTable_Dialog"; +if (isNull (uiNamespace getVariable ["AGM_Artillery_RangeTable_Dialog_display", displayNull])) exitWith {}; + +//Get Magazine Types +_magazines = getArray (configFile >> "CfgWeapons" >> _weaponName >> "magazines"); + +//For now just get settings from first mag, all rounds have same flight characteristics: +if ((count _magazines) < 1) exitWith {systemChat "Error: No Magazines for weapon"}; +_initSpeed = getNumber (configFile >> "CfgMagazines" >> (_magazines select 0) >> "initSpeed"); +_ammoClassname = getText (configFile >> "CfgMagazines" >> (_magazines select 0) >> "ammo"); +//still need to pass airFriction to rangeTableChange function +AGM_Artillery_rangeTable_airFriction = getNumber (configFile >> "CfgAmmo" >> _ammoClassname >> "AGM_Artillery_realAirFriction"); + +//Get Charge Modes +_fireModes = getArray (configFile >> "CfgWeapons" >> _weaponName >> "modes"); + +_muzzleVelocities = []; +{ + _showToPlayer = getNumber (configFile >> "CfgWeapons" >> _weaponName >> _x >> "showToPlayer"); + if (_showToPlayer == 1) then { + _artilleryCharge = getNumber (configFile >> "CfgWeapons" >> _weaponName >> _x >> "artilleryCharge"); + LIST_CHARGE lbAdd format ["%1: %2 [%3m/s]", (localize "STR_AGM_Artillery_Charge"), (count _muzzleVelocities), (_initSpeed * _artilleryCharge)]; + LIST_CHARGE lbSetData [(count _muzzleVelocities), str (_artilleryCharge * _initSpeed)]; + _muzzleVelocities pushBack _artilleryCharge; + }; +} forEach _fireModes; + +LIST_CHARGE lbSetCurSel 0; diff --git a/AGM_Artillery/functions/fn_rangeTablePageChange.sqf b/AGM_Artillery/functions/fn_rangeTablePageChange.sqf new file mode 100644 index 000000000..8abd1624b --- /dev/null +++ b/AGM_Artillery/functions/fn_rangeTablePageChange.sqf @@ -0,0 +1,34 @@ +/* +Name: AGM_Artillery_fnc_rangeTablePageChange + +Author: Pabst Mirror + +Description: + Updates the rangeTable when the 'charge' number is changed + +Parameters: + NONE + +Returns: + NONE + +Example: + Called from "onLBSelChanged" in gui_rangeTable.hpp +*/ + +#define RANGE_TABLE ((uiNamespace getVariable "AGM_Artillery_RangeTable_Dialog_display") displayCtrl 20001) +#define LIST_CHARGE ((uiNamespace getVariable "AGM_Artillery_RangeTable_Dialog_display") displayCtrl 1501) + +_listBoxData = LIST_CHARGE lbData (lbCurSel LIST_CHARGE); +if (isNil "_listBoxData" || {_listBoxData == ""}) exitWith {systemChat "Error: lbCurSel out of bounds or no data";}; +_muzzleVelocity = parseNumber _listBoxData; + +_precalcArray = [_muzzleVelocity, AGM_Artillery_rangeTable_airFriction] call AGM_Artillery_fnc_rangeTablePreCalculatedValues; + +lnbClear RANGE_TABLE; +{ + RANGE_TABLE lnbAddRow _x; +} forEach _precalcArray; + +//put dummy line at end because scrolling is fucked and can't see last line +RANGE_TABLE lnbAddRow ["", "", "", "", "", "", "", "", "", "", ""]; diff --git a/AGM_Artillery/functions/fn_rangeTablePreCalculatedValues.sqf b/AGM_Artillery/functions/fn_rangeTablePreCalculatedValues.sqf new file mode 100644 index 000000000..e6b095e32 --- /dev/null +++ b/AGM_Artillery/functions/fn_rangeTablePreCalculatedValues.sqf @@ -0,0 +1,294 @@ +/* +Name: AGM_Artillery_fnc_rangeTablePreCalculatedValues + +Author: Pabst Mirror + +Description: + Simple Lookup Table for various muzzle velocities and air frictions. + Use AGM_Artillery_fnc_dev_buildTable to build + +Parameters: + 0: NUMBER - Muzzle Velocity + 1: NUMBER - Air Friction + +Returns: + ARRAY - Array of Arrays of pre-calculated shots + +Example: + [180, -0.0001] call AGM_Artillery_fnc_rangeTablePreCalculatedValues; +*/ + +private ["_muzzleVelocity", "_airFriction"]; + +_muzzleVelocity = _this select 0; +_airFriction = _this select 1; + +switch (true) do { + +case ((abs(_muzzleVelocity - 60) < 0.00001) && ((abs(_airFriction - -0.0001) < 0.00001))): { + [ + ["100","1455","16","12.0","2.4","0.3","-0.2","0.3","-0.3","-0.0","0.0"], + ["150","1379","26","11.8","1.6","0.3","-0.2","0.4","-0.4","-0.0","0.1"], + ["200","1296","39","11.6","1.2","0.4","-0.3","0.5","-0.5","-0.0","0.1"], + ["250","1204","57","11.2","1.0","0.4","-0.3","0.7","-0.7","-0.1","0.1"], + ["300","1089","88","10.6","0.8","0.4","-0.3","0.8","-0.8","-0.1","0.1"], + ["350","894","187","9.3","0.6","0.4","-0.3","0.9","-0.9","-0.1","0.1"] + ] + }; + +case ((abs(_muzzleVelocity - 120) < 0.00001) && ((abs(_airFriction - -0.0001) < 0.00001))): { + [ + ["200","1523","3","23.6","8.2","1.7","-1.6","0.5","-0.5","-0.2","0.2"], + ["250","1503","3","23.5","6.6","1.8","-1.6","0.6","-0.6","-0.2","0.2"], + ["300","1483","4","23.5","5.5","1.8","-1.6","0.7","-0.8","-0.3","0.3"], + ["350","1463","5","23.4","4.7","1.9","-1.7","0.9","-0.9","-0.4","0.3"], + ["400","1443","5","23.4","4.2","1.9","-1.7","1.0","-1.0","-0.4","0.4"], + ["450","1423","6","23.3","3.7","2.0","-1.7","1.1","-1.1","-0.5","0.4"], + ["500","1402","7","23.2","3.4","2.0","-1.8","1.2","-1.3","-0.5","0.5"], + ["550","1381","8","23.1","3.1","2.1","-1.8","1.4","-1.4","-0.6","0.5"], + ["600","1359","9","23.0","2.8","2.2","-1.9","1.5","-1.5","-0.6","0.6"], + ["650","1337","10","22.9","2.6","2.2","-1.9","1.6","-1.6","-0.7","0.7"], + ["700","1314","11","22.7","2.4","2.3","-2.0","1.7","-1.7","-0.7","0.7"], + ["750","1291","13","22.6","2.3","2.4","-2.0","1.9","-1.9","-0.8","0.8"], + ["800","1267","14","22.4","2.1","2.4","-2.1","2.0","-2.0","-0.8","0.8"], + ["850","1241","16","22.2","2.0","2.5","-2.1","2.1","-2.1","-0.9","0.9"], + ["900","1215","17","22.0","1.9","2.5","-2.2","2.2","-2.2","-0.9","0.9"], + ["950","1187","20","21.7","1.8","2.6","-2.3","2.3","-2.4","-1.0","1.0"], + ["1000","1158","23","21.5","1.7","2.6","-2.3","2.5","-2.5","-1.1","1.0"], + ["1050","1127","26","21.1","1.6","2.7","-2.4","2.6","-2.6","-1.1","1.1"], + ["1100","1092","30","20.8","1.5","2.7","-2.4","2.7","-2.8","-1.2","1.1"], + ["1150","1054","36","20.4","1.4","2.7","-2.4","2.9","-2.9","-1.2","1.2"], + ["1200","1011","45","19.8","1.3","2.7","-2.5","3.0","-3.0","-1.3","1.2"], + ["1250","957","59","19.1","1.2","2.7","-2.4","3.1","-3.1","-1.3","1.3"], + ["1300","876","94","18.0","1.1","2.6","-2.4","3.2","-3.3","-1.3","1.3"] + ] + }; + +case ((abs(_muzzleVelocity - 180) < 0.00001) && ((abs(_airFriction - -0.0001) < 0.00001))): { + [ + ["400","1523","1","34.0","11.7","4.9","-4.6","0.9","-0.9","-0.8","0.8"], + ["450","1513","1","34.0","10.5","4.9","-4.7","1.0","-1.0","-0.9","0.8"], + ["500","1504","2","34.0","9.4","5.0","-4.7","1.1","-1.1","-1.0","0.9"], + ["550","1494","2","33.9","8.6","5.1","-4.7","1.2","-1.2","-1.1","1.0"], + ["600","1484","2","33.9","7.9","5.1","-4.8","1.3","-1.4","-1.2","1.1"], + ["650","1474","2","33.9","7.3","5.2","-4.8","1.5","-1.5","-1.3","1.2"], + ["700","1464","2","33.8","6.8","5.2","-4.9","1.6","-1.6","-1.4","1.3"], + ["750","1454","2","33.8","6.3","5.3","-4.9","1.7","-1.7","-1.5","1.4"], + ["800","1444","3","33.7","6.0","5.4","-5.0","1.8","-1.8","-1.6","1.5"], + ["850","1433","3","33.7","5.6","5.4","-5.0","1.9","-1.9","-1.7","1.6"], + ["900","1423","3","33.6","5.3","5.5","-5.1","2.0","-2.0","-1.8","1.7"], + ["950","1413","3","33.6","5.0","5.6","-5.1","2.1","-2.1","-1.9","1.8"], + ["1000","1402","3","33.5","4.8","5.6","-5.2","2.2","-2.2","-2.0","1.9"], + ["1050","1392","4","33.4","4.6","5.7","-5.3","2.3","-2.4","-2.1","2.0"], + ["1100","1381","4","33.3","4.4","5.8","-5.3","2.5","-2.5","-2.2","2.1"], + ["1150","1370","4","33.3","4.2","5.8","-5.4","2.6","-2.6","-2.3","2.2"], + ["1200","1359","4","33.2","4.0","5.9","-5.5","2.7","-2.7","-2.4","2.3"], + ["1250","1348","5","33.1","3.9","6.0","-5.5","2.8","-2.8","-2.5","2.4"], + ["1300","1337","5","33.0","3.7","6.1","-5.6","2.9","-2.9","-2.6","2.5"], + ["1350","1326","5","32.9","3.6","6.1","-5.6","3.0","-3.0","-2.7","2.6"], + ["1400","1314","5","32.8","3.5","6.2","-5.7","3.1","-3.1","-2.8","2.7"], + ["1450","1302","6","32.7","3.3","6.3","-5.8","3.2","-3.2","-2.9","2.8"], + ["1500","1290","6","32.6","3.2","6.3","-5.9","3.3","-3.4","-3.1","2.9"], + ["1550","1278","6","32.5","3.1","6.4","-5.9","3.4","-3.5","-3.2","3.0"], + ["1600","1266","7","32.3","3.0","6.5","-6.0","3.5","-3.6","-3.3","3.1"], + ["1650","1253","7","32.2","2.9","6.6","-6.1","3.7","-3.7","-3.4","3.2"], + ["1700","1240","8","32.0","2.8","6.6","-6.1","3.8","-3.8","-3.5","3.3"], + ["1750","1227","8","31.9","2.8","6.7","-6.2","3.9","-3.9","-3.6","3.4"], + ["1800","1214","9","31.7","2.7","6.7","-6.3","4.0","-4.0","-3.7","3.5"], + ["1850","1200","9","31.6","2.6","6.8","-6.3","4.1","-4.1","-3.8","3.6"], + ["1900","1186","10","31.4","2.5","6.9","-6.4","4.2","-4.2","-3.9","3.7"], + ["1950","1171","10","31.2","2.4","6.9","-6.5","4.3","-4.3","-4.0","3.8"], + ["2000","1156","11","31.0","2.4","7.0","-6.5","4.4","-4.4","-4.1","3.9"], + ["2050","1141","12","30.8","2.3","7.0","-6.6","4.5","-4.6","-4.2","4.0"], + ["2100","1124","13","30.5","2.2","7.1","-6.6","4.7","-4.7","-4.3","4.1"], + ["2150","1108","14","30.3","2.2","7.1","-6.6","4.8","-4.8","-4.4","4.2"], + ["2200","1090","15","30.0","2.1","7.2","-6.7","4.9","-4.9","-4.5","4.3"], + ["2250","1071","17","29.7","2.0","7.2","-6.7","5.0","-5.0","-4.6","4.4"], + ["2300","1052","18","29.4","2.0","7.2","-6.8","5.1","-5.1","-4.7","4.5"], + ["2350","1030","20","29.0","1.9","7.2","-6.8","5.2","-5.2","-4.8","4.6"], + ["2400","1008","23","28.6","1.9","7.2","-6.8","5.3","-5.3","-4.9","4.7"], + ["2450","983","26","28.2","1.8","7.2","-6.8","5.4","-5.4","-5.0","4.8"], + ["2500","954","31","27.6","1.7","7.1","-6.8","5.6","-5.6","-5.1","4.9"], + ["2550","921","38","27.0","1.6","7.1","-6.7","5.7","-5.7","-5.2","4.9"], + ["2600","878","52","26.1","1.5","6.9","-6.6","5.8","-5.8","-5.2","5.0"] + ] + }; +case ((abs(_muzzleVelocity - 240) < 0.00001) && ((abs(_airFriction - -0.0001) < 0.00001))): { + [ + ["600","1526","1","43.3","15.3","9.5","-9.1","1.2","-1.2","-1.8","1.7"], + ["650","1519","1","43.3","14.1","9.5","-9.2","1.3","-1.3","-1.9","1.8"], + ["700","1513","1","43.3","13.2","9.6","-9.2","1.4","-1.4","-2.1","1.9"], + ["750","1507","1","43.2","12.3","9.6","-9.2","1.5","-1.5","-2.2","2.1"], + ["800","1500","1","43.2","11.5","9.7","-9.3","1.6","-1.6","-2.4","2.2"], + ["850","1494","1","43.2","10.9","9.7","-9.3","1.7","-1.7","-2.5","2.4"], + ["900","1488","1","43.2","10.3","9.8","-9.4","1.8","-1.8","-2.7","2.5"], + ["950","1481","1","43.1","9.8","9.9","-9.4","1.9","-1.9","-2.8","2.7"], + ["1000","1475","1","43.1","9.3","9.9","-9.5","2.0","-2.0","-3.0","2.8"], + ["1050","1468","1","43.1","8.9","10.0","-9.5","2.1","-2.1","-3.1","2.9"], + ["1100","1462","1","43.0","8.5","10.1","-9.6","2.2","-2.2","-3.3","3.1"], + ["1150","1455","1","43.0","8.1","10.1","-9.6","2.3","-2.3","-3.4","3.2"], + ["1200","1449","1","43.0","7.8","10.2","-9.7","2.4","-2.4","-3.6","3.4"], + ["1250","1442","2","42.9","7.5","10.3","-9.8","2.5","-2.5","-3.7","3.5"], + ["1300","1436","2","42.9","7.2","10.3","-9.8","2.6","-2.6","-3.9","3.6"], + ["1350","1429","2","42.8","6.9","10.4","-9.9","2.7","-2.7","-4.0","3.8"], + ["1400","1422","2","42.8","6.7","10.5","-10.0","2.8","-2.8","-4.2","3.9"], + ["1450","1416","2","42.7","6.5","10.5","-10.0","2.9","-2.9","-4.4","4.1"], + ["1500","1409","2","42.7","6.2","10.6","-10.1","3.0","-3.0","-4.5","4.2"], + ["1550","1402","2","42.6","6.0","10.7","-10.2","3.0","-3.1","-4.7","4.4"], + ["1600","1395","2","42.6","5.9","10.8","-10.2","3.1","-3.2","-4.8","4.5"], + ["1650","1388","2","42.5","5.7","10.8","-10.3","3.2","-3.3","-5.0","4.7"], + ["1700","1381","2","42.4","5.5","10.9","-10.4","3.3","-3.3","-5.1","4.8"], + ["1750","1374","2","42.4","5.4","11.0","-10.4","3.4","-3.4","-5.3","4.9"], + ["1800","1367","2","42.3","5.2","11.0","-10.5","3.5","-3.5","-5.4","5.1"], + ["1850","1360","3","42.2","5.1","11.1","-10.6","3.6","-3.6","-5.6","5.2"], + ["1900","1353","3","42.2","5.0","11.2","-10.6","3.7","-3.7","-5.8","5.4"], + ["1950","1346","3","42.1","4.8","11.3","-10.7","3.8","-3.8","-5.9","5.5"], + ["2000","1338","3","42.0","4.7","11.3","-10.8","3.9","-3.9","-6.1","5.7"], + ["2050","1331","3","41.9","4.6","11.4","-10.9","4.0","-4.0","-6.2","5.8"], + ["2100","1323","3","41.9","4.5","11.5","-10.9","4.1","-4.1","-6.4","6.0"], + ["2150","1316","3","41.8","4.4","11.6","-11.0","4.2","-4.2","-6.5","6.1"], + ["2200","1308","3","41.7","4.3","11.6","-11.1","4.3","-4.3","-6.7","6.3"], + ["2250","1301","3","41.6","4.2","11.7","-11.1","4.4","-4.4","-6.9","6.4"], + ["2300","1293","4","41.5","4.1","11.8","-11.2","4.5","-4.5","-7.0","6.6"], + ["2350","1285","4","41.4","4.0","11.9","-11.3","4.6","-4.6","-7.2","6.7"], + ["2400","1277","4","41.3","3.9","11.9","-11.3","4.7","-4.7","-7.3","6.9"], + ["2450","1269","4","41.2","3.8","12.0","-11.4","4.8","-4.8","-7.5","7.0"], + ["2500","1261","4","41.1","3.8","12.1","-11.5","4.9","-4.9","-7.7","7.1"], + ["2550","1253","4","41.0","3.7","12.1","-11.6","5.0","-5.0","-7.8","7.3"], + ["2600","1244","4","40.9","3.6","12.2","-11.6","5.1","-5.1","-8.0","7.4"], + ["2650","1236","5","40.7","3.5","12.3","-11.7","5.2","-5.2","-8.1","7.6"], + ["2700","1227","5","40.6","3.5","12.3","-11.8","5.3","-5.3","-8.3","7.7"], + ["2750","1219","5","40.5","3.4","12.4","-11.8","5.4","-5.4","-8.4","7.9"], + ["2800","1210","5","40.3","3.3","12.5","-11.9","5.5","-5.5","-8.6","8.0"], + ["2850","1201","5","40.2","3.3","12.5","-12.0","5.6","-5.6","-8.8","8.2"], + ["2900","1192","6","40.1","3.2","12.6","-12.0","5.7","-5.7","-8.9","8.3"], + ["2950","1182","6","39.9","3.1","12.6","-12.1","5.8","-5.8","-9.1","8.5"], + ["3000","1173","6","39.7","3.1","12.7","-12.2","5.9","-5.9","-9.2","8.6"], + ["3050","1163","6","39.6","3.0","12.7","-12.2","6.0","-6.0","-9.4","8.8"], + ["3100","1153","7","39.4","3.0","12.8","-12.3","6.1","-6.0","-9.5","8.9"], + ["3150","1143","7","39.2","2.9","12.8","-12.3","6.1","-6.2","-9.7","9.0"], + ["3200","1133","7","39.0","2.9","12.9","-12.4","6.3","-6.2","-9.8","9.2"], + ["3250","1122","8","38.8","2.8","12.9","-12.4","6.4","-6.3","-10.0","9.3"], + ["3300","1111","8","38.6","2.7","13.0","-12.5","6.4","-6.4","-10.2","9.5"], + ["3350","1100","9","38.4","2.7","13.0","-12.5","6.5","-6.5","-10.3","9.6"], + ["3400","1088","9","38.2","2.6","13.0","-12.5","6.6","-6.6","-10.5","9.8"], + ["3450","1076","10","38.0","2.6","13.0","-12.6","6.7","-6.7","-10.6","9.9"], + ["3500","1064","10","37.7","2.5","13.1","-12.6","6.9","-6.8","-10.7","10.0"], + ["3550","1051","11","37.4","2.5","13.1","-12.6","7.0","-6.9","-10.9","10.2"], + ["3600","1038","12","37.2","2.4","13.1","-12.6","7.0","-7.0","-11.0","10.3"], + ["3650","1024","13","36.9","2.4","13.1","-12.6","7.2","-7.1","-11.2","10.4"], + ["3700","1009","14","36.5","2.3","13.1","-12.6","7.2","-7.3","-11.3","10.5"], + ["3750","993","15","36.2","2.3","13.0","-12.6","7.4","-7.3","-11.4","10.7"], + ["3800","977","16","35.8","2.2","13.0","-12.6","7.5","-7.5","-11.6","10.8"], + ["3850","959","18","35.4","2.2","13.0","-12.6","7.6","-7.6","-11.7","10.9"], + ["3900","940","20","34.9","2.1","12.9","-12.5","7.7","-7.7","-11.8","11.0"], + ["3950","918","23","34.4","2.0","12.8","-12.4","7.8","-7.8","-11.9","11.1"], + ["4000","893","28","33.7","2.0","12.7","-12.3","7.9","-7.9","-12.0","11.2"], + ["4050","863","35","32.9","1.9","12.5","-12.1","8.0","-8.0","-12.0","11.2"], + ["4100","821","50","31.8","1.8","12.1","-11.8","8.2","-8.2","-12.0","11.2"] + ] + }; +case ((abs(_muzzleVelocity - 300) < 0.00001) && ((abs(_airFriction - -0.0001) < 0.00001))): { + [ + ["800","1527","0","51.4","18.2","15.0","-14.6","1.4","-1.4","-3.1","2.9"], + ["850","1522","1","51.4","17.2","15.0","-14.6","1.5","-1.5","-3.3","3.0"], + ["900","1517","1","51.4","16.2","15.0","-14.7","1.6","-1.6","-3.5","3.2"], + ["950","1513","1","51.4","15.4","15.1","-14.7","1.7","-1.6","-3.7","3.4"], + ["1000","1508","1","51.4","14.7","15.2","-14.8","1.7","-1.7","-3.9","3.6"], + ["1050","1503","1","51.3","14.0","15.2","-14.8","1.8","-1.8","-4.1","3.8"], + ["1100","1498","1","51.3","13.4","15.3","-14.8","1.9","-1.9","-4.3","3.9"], + ["1150","1494","1","51.3","12.8","15.3","-14.9","2.0","-2.0","-4.5","4.1"], + ["1200","1489","1","51.3","12.3","15.4","-14.9","2.1","-2.1","-4.7","4.3"], + ["1250","1484","1","51.2","11.8","15.5","-15.0","2.2","-2.2","-4.9","4.5"], + ["1300","1479","1","51.2","11.3","15.5","-15.0","2.3","-2.3","-5.1","4.7"], + ["1350","1475","1","51.2","10.9","15.6","-15.1","2.3","-2.3","-5.3","4.8"], + ["1400","1470","1","51.2","10.6","15.6","-15.1","2.4","-2.4","-5.5","5.0"], + ["1450","1465","1","51.1","10.2","15.7","-15.2","2.5","-2.5","-5.7","5.2"], + ["1500","1460","1","51.1","9.9","15.8","-15.3","2.6","-2.6","-5.9","5.4"], + ["1550","1455","1","51.1","9.5","15.8","-15.3","2.7","-2.7","-6.1","5.6"], + ["1600","1451","1","51.0","9.3","15.9","-15.4","2.8","-2.8","-6.3","5.8"], + ["1650","1446","1","51.0","9.0","16.0","-15.4","2.9","-2.9","-6.5","5.9"], + ["1700","1441","1","51.0","8.7","16.0","-15.5","3.0","-2.9","-6.7","6.1"], + ["1750","1436","1","50.9","8.5","16.1","-15.6","3.0","-3.0","-6.9","6.3"], + ["1800","1431","1","50.9","8.2","16.2","-15.6","3.1","-3.1","-7.1","6.5"], + ["1850","1426","1","50.8","8.0","16.2","-15.7","3.2","-3.2","-7.3","6.7"], + ["1900","1421","1","50.8","7.8","16.3","-15.8","3.3","-3.3","-7.5","6.9"], + ["1950","1416","1","50.7","7.6","16.4","-15.8","3.4","-3.4","-7.7","7.1"], + ["2000","1411","1","50.7","7.4","16.4","-15.9","3.5","-3.5","-7.9","7.2"], + ["2050","1406","1","50.7","7.3","16.5","-15.9","3.6","-3.5","-8.1","7.4"], + ["2100","1401","1","50.6","7.1","16.6","-16.0","3.6","-3.6","-8.3","7.6"], + ["2150","1396","1","50.6","6.9","16.6","-16.1","3.7","-3.7","-8.5","7.8"], + ["2200","1390","1","50.5","6.8","16.7","-16.1","3.8","-3.8","-8.7","8.0"], + ["2250","1385","2","50.5","6.6","16.8","-16.2","3.9","-3.9","-8.9","8.2"], + ["2300","1380","2","50.4","6.5","16.9","-16.3","4.0","-4.0","-9.1","8.3"], + ["2350","1375","2","50.3","6.3","16.9","-16.4","4.1","-4.1","-9.3","8.5"], + ["2400","1370","2","50.3","6.2","17.0","-16.4","4.2","-4.1","-9.5","8.7"], + ["2450","1364","2","50.2","6.1","17.1","-16.5","4.2","-4.2","-9.7","8.9"], + ["2500","1359","2","50.2","6.0","17.1","-16.6","4.3","-4.3","-9.9","9.1"], + ["2550","1354","2","50.1","5.8","17.2","-16.6","4.4","-4.4","-10.1","9.3"], + ["2600","1348","2","50.0","5.7","17.3","-16.7","4.5","-4.5","-10.3","9.5"], + ["2650","1343","2","50.0","5.6","17.3","-16.8","4.6","-4.6","-10.5","9.6"], + ["2700","1337","2","49.9","5.5","17.4","-16.8","4.7","-4.7","-10.7","9.8"], + ["2750","1332","2","49.8","5.4","17.5","-16.9","4.8","-4.7","-10.9","10.0"], + ["2800","1326","2","49.8","5.3","17.6","-17.0","4.8","-4.8","-11.1","10.2"], + ["2850","1321","2","49.7","5.2","17.6","-17.0","4.9","-4.9","-11.3","10.4"], + ["2900","1315","2","49.6","5.1","17.7","-17.1","5.0","-5.0","-11.5","10.6"], + ["2950","1309","2","49.5","5.0","17.8","-17.2","5.1","-5.1","-11.7","10.8"], + ["3000","1304","2","49.5","5.0","17.8","-17.3","5.2","-5.2","-11.9","10.9"], + ["3050","1298","2","49.4","4.9","17.9","-17.3","5.3","-5.2","-12.1","11.1"], + ["3100","1292","2","49.3","4.8","18.0","-17.4","5.3","-5.3","-12.3","11.3"], + ["3150","1286","3","49.2","4.7","18.0","-17.5","5.4","-5.4","-12.5","11.5"], + ["3200","1280","3","49.1","4.6","18.1","-17.5","5.5","-5.5","-12.7","11.7"], + ["3250","1274","3","49.0","4.6","18.2","-17.6","5.6","-5.6","-12.9","11.9"], + ["3300","1268","3","48.9","4.5","18.2","-17.7","5.7","-5.6","-13.1","12.1"], + ["3350","1262","3","48.8","4.4","18.3","-17.7","5.8","-5.7","-13.3","12.2"], + ["3400","1256","3","48.7","4.4","18.4","-17.8","5.9","-5.8","-13.5","12.4"], + ["3450","1250","3","48.6","4.3","18.4","-17.9","5.9","-5.9","-13.8","12.6"], + ["3500","1244","3","48.5","4.2","18.5","-17.9","6.0","-6.0","-14.0","12.8"], + ["3550","1237","3","48.4","4.2","18.6","-18.0","6.1","-6.1","-14.2","13.0"], + ["3600","1231","3","48.3","4.1","18.6","-18.1","6.2","-6.2","-14.4","13.2"], + ["3650","1224","3","48.2","4.0","18.7","-18.1","6.3","-6.3","-14.6","13.4"], + ["3700","1218","3","48.1","4.0","18.7","-18.2","6.4","-6.3","-14.8","13.5"], + ["3750","1211","4","48.0","3.9","18.8","-18.2","6.5","-6.4","-15.0","13.7"], + ["3800","1205","4","47.8","3.9","18.8","-18.3","6.5","-6.5","-15.2","13.9"], + ["3850","1198","4","47.7","3.8","18.9","-18.4","6.6","-6.6","-15.4","14.1"], + ["3900","1191","4","47.6","3.7","18.9","-18.4","6.7","-6.7","-15.6","14.3"], + ["3950","1184","4","47.5","3.7","19.0","-18.5","6.8","-6.8","-15.8","14.5"], + ["4000","1177","4","47.3","3.6","19.1","-18.5","6.9","-6.8","-16.0","14.7"], + ["4050","1170","4","47.2","3.6","19.1","-18.6","7.0","-6.9","-16.2","14.8"], + ["4100","1163","4","47.0","3.5","19.1","-18.6","7.1","-7.0","-16.4","15.0"], + ["4150","1155","5","46.9","3.5","19.2","-18.7","7.1","-7.1","-16.6","15.2"], + ["4200","1148","5","46.7","3.4","19.2","-18.7","7.2","-7.2","-16.8","15.4"], + ["4250","1140","5","46.6","3.4","19.3","-18.8","7.3","-7.3","-17.0","15.6"], + ["4300","1132","5","46.4","3.3","19.3","-18.8","7.4","-7.4","-17.2","15.7"], + ["4350","1124","5","46.2","3.3","19.3","-18.8","7.5","-7.5","-17.4","15.9"], + ["4400","1116","5","46.1","3.2","19.4","-18.9","7.6","-7.5","-17.6","16.1"], + ["4450","1108","6","45.9","3.2","19.4","-18.9","7.7","-7.6","-17.8","16.3"], + ["4500","1100","6","45.7","3.1","19.4","-19.0","7.8","-7.7","-17.9","16.4"], + ["4550","1091","6","45.5","3.1","19.4","-19.0","7.8","-7.8","-18.1","16.6"], + ["4600","1083","6","45.3","3.1","19.5","-19.0","7.9","-7.9","-18.3","16.8"], + ["4650","1074","7","45.1","3.0","19.5","-19.0","8.0","-8.0","-18.5","17.0"], + ["4700","1065","7","44.9","3.0","19.5","-19.1","8.1","-8.1","-18.7","17.1"], + ["4750","1055","7","44.6","2.9","19.5","-19.1","8.2","-8.2","-18.9","17.3"], + ["4800","1046","8","44.4","2.9","19.5","-19.1","8.3","-8.3","-19.1","17.5"], + ["4850","1036","8","44.2","2.8","19.5","-19.1","8.4","-8.3","-19.2","17.6"], + ["4900","1025","8","43.9","2.8","19.5","-19.1","8.5","-8.4","-19.4","17.8"], + ["4950","1015","9","43.6","2.7","19.5","-19.1","8.6","-8.5","-19.6","18.0"], + ["5000","1004","9","43.3","2.7","19.4","-19.1","8.7","-8.6","-19.8","18.1"], + ["5050","992","10","43.0","2.6","19.4","-19.0","8.8","-8.7","-19.9","18.3"], + ["5100","980","11","42.7","2.6","19.4","-19.0","8.9","-8.8","-20.1","18.4"], + ["5150","968","11","42.4","2.5","19.3","-18.9","9.0","-8.9","-20.2","18.6"], + ["5200","955","12","42.0","2.5","19.2","-18.9","9.1","-9.0","-20.4","18.7"], + ["5250","941","13","41.6","2.4","19.2","-18.8","9.1","-9.1","-20.6","18.8"], + ["5300","926","15","41.2","2.4","19.1","-18.8","9.2","-9.2","-20.7","19.0"], + ["5350","910","16","40.7","2.3","19.0","-18.6","9.4","-9.3","-20.8","19.1"], + ["5400","892","18","40.2","2.3","18.8","-18.5","9.5","-9.4","-20.9","19.2"], + ["5450","872","21","39.6","2.2","18.6","-18.3","9.6","-9.5","-21.0","19.3"], + ["5500","849","26","38.8","2.1","18.4","-18.1","9.7","-9.7","-21.1","19.3"], + ["5550","820","33","37.9","2.1","18.0","-17.8","9.8","-9.8","-21.1","19.4"] + ] + }; + + + default {systemChat "Error: MuzzleVelocity not found in LUT"; []}; +}; \ No newline at end of file diff --git a/AGM_Artillery/functions/fn_rangerFinderStart.sqf b/AGM_Artillery/functions/fn_rangerFinderStart.sqf new file mode 100644 index 000000000..32bb29531 --- /dev/null +++ b/AGM_Artillery/functions/fn_rangerFinderStart.sqf @@ -0,0 +1,46 @@ +/* +Name: AGM_Artillery_fnc_rangerFinderStart + +Author: Pabst Mirror + +Description: + Called when mortar range key is pressed. + If key is held long enough, when released a firing solution is calculated and saved to mortar. + +Parameters: + 0: OBJECT - Mortar Vehicle + +Returns: + NONE + +Example: + [theMortar] call AGM_Artillery_fnc_rangerFinderStart + called from AGM_Core_Default_Keys +*/ + +#define MIN_TIME_TABDOWN 0.3 + +_this spawn { + private ["_mortarVeh", "_timeStart"]; + + _mortarVeh = _this select 0; + + _timeStart = time; + + waitUntil { + (!AGM_Artillery_rangefinderKeyDown) || {(vehicle AGM_player) != _mortarVeh} + }; + + if ((vehicle AGM_player) != _mortarVeh) exitWith {}; //player not in mortar + if (!(_mortarVeh getVariable ["AGM_Artillery_rangefinderEnabled", false])) exitWith {}; //should never get here without it set true + if ((isNil "AGM_Artillery_currentWeaponSettings") || {(count AGM_Artillery_currentWeaponSettings) != 6}) exitWith {}; //if weaponSettings isn't valid + if ((time - _timeStart) < MIN_TIME_TABDOWN) exitWith {}; //only update on 'long' presses of TAB + + [_mortarVeh, + true, + (AGM_Artillery_currentWeaponSettings select 1), + (AGM_Artillery_currentWeaponSettings select 2), + (AGM_Artillery_currentWeaponSettings select 3), + (AGM_Artillery_currentWeaponSettings select 4), + (AGM_Artillery_currentWeaponSettings select 5)] spawn AGM_Artillery_fnc_createFiringSolution; +}; diff --git a/AGM_Artillery/functions/fn_simulateCalcRangeTableLine.sqf b/AGM_Artillery/functions/fn_simulateCalcRangeTableLine.sqf new file mode 100644 index 000000000..6884ce234 --- /dev/null +++ b/AGM_Artillery/functions/fn_simulateCalcRangeTableLine.sqf @@ -0,0 +1,80 @@ +/* +Name: AGM_Artillery_fnc_simulateCalcRangeTableLine + +Author: Pabst Mirror + +Description: + Builds a rangeTable line for a certian range, given muzzle velocity and air friction, returns [] if out of range. + +Parameters: + 0: NUMBER - Muzzle Velocity + 1: NUMBER - Air Friction + 2: NUMBER - Range To Hit + +Returns: + ARRAY - Range Table Line Data (see return line) + +Example: + [300, -0.0001, 3000] call AGM_Artillery_fnc_simulateCalcRangeTableLine +*/ + +#define TIME_STEP (1/50) + +private ["_startTime", "_muzzleVelocity", "_rangeToHit", "_airFriction", "_vacElevation", "_radicand", "_maxElev", "_minElev", "_error", "_solutionElevation", "_lastTestResult", "_numberOfAttempts", "_lineElevation", "_lineTimeOfFlight", "_lineHeightElevation", "_lineHeightTime", "_lineCrosswindDeg", "_lineHeadwindMeters", "_lineTailWindMeters", "_result"]; + +_startTime = diag_tickTime; + +_muzzleVelocity = _this select 0; +_rangeToHit = _this select 1; +_airFriction = _this select 2; + +//Run Binary search for correct elevation +_solution = [_rangeToHit, 0, _muzzleVelocity, _airFriction, TIME_STEP] call AGM_Artillery_fnc_simulateFindSolution; +if (_solution isEqualTo []) exitWith {[]}; + +//Real Elevation +_lineElevation = _solution select 0; + +//Time Of Flight: +_lineTimeOfFlight = _solution select 1; + +//Height Adjustment for -100m (another binary search) +_solution = [_rangeToHit, -100, _muzzleVelocity, _airFriction, TIME_STEP] call AGM_Artillery_fnc_simulateFindSolution; +if (_solution isEqualTo []) exitWith {[]};//should never be triggered (lower elevation easier to hit) + +_lineHeightElevation = ((_solution select 0) - _lineElevation); +// _lineHeightTime = (_lastTestResult select 1) - _lineTimeOfFlight; + +//Compute for 10x and divide to minimize rounding errors + +//Crosswind +_lastTestResult = [_lineElevation, _muzzleVelocity, _airFriction, 15, 1, 0, 10, 0, TIME_STEP] call AGM_Artillery_fnc_simulateShot; +_lineCrosswindDeg = (_lastTestResult select 2) / 10; + +//Headwind: +_lastTestResult = [_lineElevation, _muzzleVelocity, _airFriction, 15, 1, -10, 0, 0, TIME_STEP] call AGM_Artillery_fnc_simulateShot; +_lineHeadwindMeters = (_rangeToHit - (_lastTestResult select 0)) / 10; + +//TailWind: +_lastTestResult = [_lineElevation, _muzzleVelocity, _airFriction, 15, 1, 10, 0, 0, TIME_STEP] call AGM_Artillery_fnc_simulateShot; +_lineTailWindMeters = (_rangeToHit - (_lastTestResult select 0)) / 10; + +//Air Temp Dec +_lastTestResult = [_lineElevation, _muzzleVelocity, _airFriction, (15 - 10), 1, 0, 0, 0, TIME_STEP] call AGM_Artillery_fnc_simulateShot; +_lineTempDec = (_rangeToHit - (_lastTestResult select 0)) / 10; + +//Air Temp Inc +_lastTestResult = [_lineElevation, _muzzleVelocity, _airFriction, (15 + 10), 1, 0, 0, 0, TIME_STEP] call AGM_Artillery_fnc_simulateShot; +_lineTempInc = (_rangeToHit - (_lastTestResult select 0)) / 10; + +//Air Density Dec +_lastTestResult = [_lineElevation, _muzzleVelocity, _airFriction, 15, 0.9, 0, 0, 0, TIME_STEP] call AGM_Artillery_fnc_simulateShot; +_lineAirDensDec = (_rangeToHit - (_lastTestResult select 0)) / 10; + +//Air Density Inc +_lastTestResult = [_lineElevation, _muzzleVelocity, _airFriction, 15, 1.1, 0, 0, 0, TIME_STEP] call AGM_Artillery_fnc_simulateShot; +_lineAirDensInc = (_rangeToHit - (_lastTestResult select 0)) / 10; + +// systemChat format ["debug: Range %1 - in %2 sec", _rangeToHit, (diag_tickTime - _startTime)]; + +[_rangeToHit, _lineElevation, _lineHeightElevation, _lineTimeOfFlight, _lineCrosswindDeg, _lineHeadwindMeters, _lineTailWindMeters, _lineTempDec, _lineTempInc, _lineAirDensDec, _lineAirDensInc] diff --git a/AGM_Artillery/functions/fn_simulateFindSolution.sqf b/AGM_Artillery/functions/fn_simulateFindSolution.sqf new file mode 100644 index 000000000..560783694 --- /dev/null +++ b/AGM_Artillery/functions/fn_simulateFindSolution.sqf @@ -0,0 +1,56 @@ +/* +Name: AGM_Artillery_fnc_simulateFindSolution + +Author: Pabst Mirror + +Description: + Converts numbers into nicely formated strings. + +Parameters: + 0: NUMBER - Range to Hit (Meters) + 1: NUMBER - Height To Hit (Meters) + 2: NUMBER - Muzzle Velocity (M/S) + 3: NUMBER - Air Friction + 4: NUMBER - Time Step (seconds) (eg 1/50 will simulate 50 cycles per second) + +Returns: + ARRAY - [NUMBER - Elevation In Degrees, NUMBER - Shot Durration] + +Example: + [_rangeToHit, _heightToHit, _muzzleVelocity, _airFriction, TIME_STEP] call AGM_Artillery_fnc_simulateFindSolution; +*/ + +private ["_rangeToHit", "_heightToHit", "_muzzleVelocity", "_airFriction", "_maxElev", "_minElev", "_error", "_solutionElevation", "_lastTestResult", "_numberOfAttempts"]; + +#define MAX_ATTEMPTS 22 + +_rangeToHit = _this select 0; +_heightToHit = _this select 1; +_muzzleVelocity = _this select 2; +_airFriction = _this select 3; +_timeStep = _this select 4; + +_maxElev = 90; +_minElev = 45; //todo - Low Angle Howitzers??? + +_error = 10000; +_solutionElevation = -1; +_lastTestResult = []; +_numberOfAttempts = 0; + +//(binary search) +while {(_numberOfAttempts < MAX_ATTEMPTS) && ((abs _error) > 0.2)} do { + _numberOfAttempts = _numberOfAttempts + 1; + _solutionElevation = (_maxElev + _minElev) / 2; + _lastTestResult = [_solutionElevation, _muzzleVelocity, _airFriction, 15, 1, 0, 0, _heightToHit, _timeStep] call AGM_Artillery_fnc_simulateShot; + _error = _rangeToHit - (_lastTestResult select 0); + if (_error > 0) then { + _maxElev = _solutionElevation; //test range was short + } else { + _minElev = _solutionElevation; //test range was long + }; +}; +if (_numberOfAttempts >= MAX_ATTEMPTS) exitWith {[]}; + +//return the elevation and time required +[_solutionElevation, (_lastTestResult select 1)] diff --git a/AGM_Artillery/functions/fn_simulateShot.sqf b/AGM_Artillery/functions/fn_simulateShot.sqf new file mode 100644 index 000000000..9bc9cf03f --- /dev/null +++ b/AGM_Artillery/functions/fn_simulateShot.sqf @@ -0,0 +1,77 @@ +/* +Name: AGM_Artillery_fnc_simulateShot + +Author: Pabst Mirror + +Description: + Simulates the path of a fired shell. + +Parameters: + 0: NUMBER - Shot Angle (degrees) + 1: NUMBER - Muzzle Velocity (m/s) + 2: NUMBER - Air Friction + 3: NUMBER - Tempeture (degres celcius) + 4: NUMBER - Relative Air Denisty + 5: NUMBER - Tail Wind (m/s) + 6: NUMBER - Cross Wind (m/s) + 7: NUMBER - Height Of Target (M) + 8: NUMBER - Time Step (fraction of a second) + +Returns: + ARRAY - + NUMBER - Distance Traveld + NUMBER - Shot Time + NUMBER - Offset (degrees) + +Example: + [45, 180, -0.0001, 15, 1, 10, 0, 0, 1/50] call AGM_Artillery_fnc_simulateShot; +*/ + +private ["_angleDeg", "_muzzleVelocity", "_airFriction", "_temp", "_relDensity", "_tailWind", "_crosswind", "_heightOfTarget", "_wind", "_gravity", "_timeStep", "_currentPos", "_currentVelocity", "_currentTime", "_lastPos", "_kCoefficent", "_aparentWind", "_changeInVelocity", "_linConversion", "_middlePos", "_middlePosOld", "_middleTotalTravelTime", "_offsetDeg"]; + +_angleDeg = _this select 0; +_muzzleVelocity = _this select 1; +_airFriction = _this select 2; +_temp = _this select 3; +_relDensity = _this select 4; +_tailWind = _this select 5; +_crosswind = _this select 6; +_heightOfTarget = _this select 7; +_timeStep = _this select 8; + +_wind = [_crosswind, _tailWind, 0]; +_gravity = [0,0,-9.8]; + +_currentPos = [0,0,0]; +_muzzleVelocity = _muzzleVelocity * (1 + ((((_temp + 273.13) / 288.13 - 1) / 2.5 + 1 ) - 1)); +_currentVelocity = [0, (_muzzleVelocity * cos _angleDeg), (_muzzleVelocity * sin _angleDeg)]; + +_currentTime = 0; +_lastPos = _currentPos; + +_kCoefficent = -1 * _relDensity * _airFriction; //save time in the loop and compute once + +while {((_currentVelocity select 2) > 0) || ((_currentPos select 2) >= _heightOfTarget)} do { + _lastPos = _currentPos; + + _aparentWind = _wind vectorDiff _currentVelocity; + _changeInVelocity = _gravity vectorAdd (_aparentWind vectorMultiply ((vectorMagnitude _aparentWind) * _kCoefficent)); + + _currentVelocity = _currentVelocity vectorAdd (_changeInVelocity vectorMultiply _timeStep); + + _currentPos = _currentPos vectorAdd (_currentVelocity vectorMultiply _timeStep); + _currentTime = _currentTime + _timeStep; +}; + +//Uses linearConversion to get a weighted average betwen points before and after dropping below target height +_linConversion = linearConversion [(_lastPos select 2), (_currentPos select 2), _heightOfTarget, 0, 1, true]; +_middlePos = (_lastPos vectorMultiply (1 - _linConversion)) vectorAdd (_currentPos vectorMultiply (_linConversion)); +// _middlePosOld = (_lastPos vectorAdd _currentPos) vectorMultiply 0.5; + +//Same to find travel time +_middleTotalTravelTime = _currentTime - (_timeStep * (1-_linConversion)); + +//Find shot offset (from crosswind), in degrees + _offsetDeg = (_middlePos select 0) aTan2 (_middlePos select 1); + +[(_middlePos select 1), _middleTotalTravelTime, _offsetDeg] diff --git a/AGM_Artillery/gui_mapComputer.hpp b/AGM_Artillery/gui_mapComputer.hpp new file mode 100644 index 000000000..03d49b391 --- /dev/null +++ b/AGM_Artillery/gui_mapComputer.hpp @@ -0,0 +1,96 @@ +class AGM_Artillery_MapComputer_Dialog +{ + idd = -1; + movingEnable = 0; + enableSimulation = 1; + enableDisplay = 1; + onLoad = "((uiNamespace getVariable ['AGM_Artillery_RscWeaponRangeArtilleryCustom', displayNull]) displayCtrl 800858) ctrlSetBackgroundColor [0,0,0,1]; uiNamespace setVariable ['AGM_Artillery_MapComputer_Dialog', _this select 0];"; + onUnLoad = "((uiNamespace getVariable ['AGM_Artillery_RscWeaponRangeArtilleryCustom', displayNull]) displayCtrl 800858) ctrlSetBackgroundColor [0,0,0,0.5];"; + duration = 2147483647; + fadein = 0; + fadeout = 0; + + class controlsBackground { + class BGR_BLACK_TOP: RscText { + idc = -1; + x = 0.11 * safeZoneH + safezoneX; + y = 0 * safeZoneH + safezoneY; + w = 0.183333 * (3/4) * safeZoneH; + h = 0.4083335 * safeZoneH; + colorbackground[] = {0.0,0.0,0.0,1}; + }; + class BGR_BLACK_BOTTOM: RscText { + idc = -1; + x = 0.11 * safeZoneH + safezoneX; + y = 0.5916665 * safeZoneH + safezoneY; + w = 0.183333 * (3/4) * safeZoneH; + h = 0.4083335 * safeZoneH; + colorbackground[] = {0.0,0.0,0.0,1}; + }; + }; + + class controls { + class MiniMap: RscMapControl + { + idc = -1; + type = 101; //100 hides all markers + scaleDefault = 0.25; + colorbackground[] = {0.9,0.9,0.9,1}; + maxSatelliteAlpha = 0.15; + x = 0.2475 * safeZoneH + safezoneX; + y = 0 * safeZoneH + safeZoneY; + w = safeZoneW - (0.2475 * safeZoneH); + h = 1 * safeZoneH; + onMouseButtonClick = "_this call AGM_Artillery_fnc_mapCompEventClickOnMap"; + onDraw = "_this call AGM_Artillery_fnc_mapCompEventDrawMap"; + }; + class ChargeListBox: RscListbox { + idc = 233232; + style = ST_RIGHT; + x = 0.11 * safeZoneH + safezoneX; + y = 4.5 * ((safeZoneH / 1.2) / 25) + (safezoneY + (safezoneH - (safeZoneH / 1.2))/2); + w = 5.475 * (safeZoneH / 40); + h = 5 * ((safeZoneH / 1.2) / 25); + }; + class MapCordsFrame: RscFrame { + idc = -1; + text = "$STR_AGM_Artillery_LoadMapCords"; //--- ToDo: Localize; + x = 0.1125 * safeZoneH + safezoneX; + y = 15.25 * ((safeZoneH / 1.2) / 25) + (safezoneY + (safezoneH - (safeZoneH / 1.2))/2); + w = 5.3 * (safeZoneH / 40); + h = 1.5 * ((safeZoneH / 1.2) / 25); + sizeEx = "0.5 * ((safeZoneH / 1.2) / 25)"; + }; + class MapCordsEdit: RscEdit { + idc = 233237; + x = 0.115 * safeZoneH + safezoneX; + y = 15.75 * ((safeZoneH / 1.2) / 25) + (safezoneY + (safezoneH - (safeZoneH / 1.2))/2); + w = 3.1 * (safeZoneH / 40); + h = 0.9 * ((safeZoneH / 1.2) / 25); + }; + class MapCordsButton: RscButton { + idc = -1; + text = "$STR_AGM_Artillery_LoadShort"; //--- ToDo: Localize; + x = 0.195 * safeZoneH + safezoneX; + y = 15.75 * ((safeZoneH / 1.2) / 25) + (safezoneY + (safezoneH - (safeZoneH / 1.2))/2); + w = 1.9 * (safeZoneH / 40); + h = 0.9 * ((safeZoneH / 1.2) / 25); + action = "[] spawn AGM_Artillery_fnc_mapCompEventEnterCords"; + colorBackground[] = {0.8,0.8,0.8,1}; + colorBackgroundActive[] = {1,1,1,1}; + colorFocused[] = {1,1,1,1}; + }; + class CloseButton: RscButton { + idc = -1; + x = 0.11625 * safeZoneH + safezoneX; + y = 17.0 * ((safeZoneH / 1.2) / 25) + (safezoneY + (safezoneH - (safeZoneH / 1.2))/2); + w = 5 * (safeZoneH / 40); + h = 1 * ((safeZoneH / 1.2) / 25); + text = "$STR_AGM_Core_Cancel"; + action = "closeDialog 0;"; + colorBackground[] = {0.8,0.8,0.8,1}; + colorBackgroundActive[] = {1,1,1,1}; + colorFocused[] = {1,1,1,1}; + }; + }; +}; diff --git a/AGM_Artillery/gui_mortarHud.hpp b/AGM_Artillery/gui_mortarHud.hpp new file mode 100644 index 000000000..d15f02faa --- /dev/null +++ b/AGM_Artillery/gui_mortarHud.hpp @@ -0,0 +1,210 @@ +#define COMPASS_SCALE (safeZoneH / 2) + +class RscInGameUI +{ + class AGM_Artillery_RscWeaponRangeArtilleryCustom { + idd = 300; + onLoad = "uiNamespace setVariable ['AGM_Artillery_RscWeaponRangeArtilleryCustom', _this select 0]; _this call AGM_Artillery_fnc_onHudLoad;"; + class controls + { + //game will auto fill data into these (hidden from sight) + class CA_IGUI_elements_group: RscControlsGroup { + idc = 170; + class VScrollbar: VScrollbar {width = 0;}; + class HScrollbar: HScrollbar {height = 0;}; + x = "0 * (0.01875 * SafezoneH) + (SafezoneX + ((SafezoneW - SafezoneH) / 2))"; + y = "0 * (0.025 * SafezoneH) + (SafezoneY)"; + w = "53.5 * (0.01875 * SafezoneH)"; + h = "40 * (0.025 * SafezoneH)"; + class controls + { + class CA_Heading: RscText + { + idc = 156; + style = 0; + colorText[] = {0.706,0.0745,0.0196,1}; + sizeEx = "0.028*SafezoneH"; + shadow = 0; + font = "EtelkaMonospacePro"; + text = "015"; + x = -1; + y = -1; + w = 0; + h = 0; + }; + class CA_OpticsPitch: RscText + { + idc = 182; + style = 1; + colorText[] = {0.706,0.0745,0.0196,1}; + sizeEx = "0.028*SafezoneH"; + shadow = 0; + font = "EtelkaMonospacePro"; + text = "34.5"; + x = -1; + y = -1; + w = 0; + h = 0; + }; + class CA_OpticsZoom: RscText + { + idc = 180; + style = 1; + colorText[] = {0.706,0.0745,0.0196,1}; + sizeEx = "0.028*SafezoneH"; + shadow = 0; + font = "EtelkaMonospacePro"; + text = "4.5"; + x = -1; + y = -1; + w = 0; + h = 0; + }; + class CA_Distance: RscText + { + idc = 173; + style = 1; + sizeEx = "0.038*SafezoneH"; + colorText[] = {0.706,0.0745,0.0196,1}; + shadow = 0; + font = "EtelkaMonospacePro"; + text = "2456"; + x = -1; + y = -1; + w = 0; + h = 0; + }; + class CA_Time: RscText + { + idc = 174; + style = 1; + sizeEx = "0.038*SafezoneH"; + colorText[] = {0.706,0.0745,0.0196,1}; + shadow = 0; + font = "EtelkaMonospacePro"; + text = "25"; + x = -1; + y = -1; + w = 0; + h = 0; + }; + class CA_Elev: RscText + { + idc = 175; + style = 1; + sizeEx = "0.038*SafezoneH"; + colorText[] = {0.706,0.0745,0.0196,1}; + shadow = 0; + font = "EtelkaMonospacePro"; + text = "80.5"; + x = -1; + y = -1; + w = 0; + h = 0; + }; + class CA_Elev_Need: RscText + { + idc = 176; + style = 1; + sizeEx = "0.038*SafezoneH"; + colorText[] = {0.706,0.0745,0.0196,1}; + shadow = 0; + font = "EtelkaMonospacePro"; + text = "35.4"; + x = -1; + y = -1; + w = 0; + h = 0; + }; + }; + }; + + //Real Controls + class Vector_Center : RscPicture { + idc = 800860; + colorText[] = {1, 0, 0, 0.5}; + x = 0.488 * safezoneW + safezoneX; + y = 0.4783 * safezoneH + safezoneY; + w = 0.4 / 16 * safezoneW; + h = 0.4 / 9 * safezoneH; + text = "\AGM_Vector\rsc\Vector_Center.paa"; + }; + + //Charge display will sit on the weapon/ammo part of the hud, can move anywhere so get cords from profilenamespace + class ChargeText: RscStructuredText { + idc = 800859; + colorText[] = {"(profilenamespace getvariable ['IGUI_TEXT_RGB_R',0])","(profilenamespace getvariable ['IGUI_TEXT_RGB_G',1])","(profilenamespace getvariable ['IGUI_TEXT_RGB_B',1])","(profilenamespace getvariable ['IGUI_TEXT_RGB_A',0.8])"}; + x = "0 * ( ((safezoneW / safezoneH) min 1.2) / 40) + (profilenamespace getvariable [""IGUI_GRID_WEAPON_X"", ((safezoneX + safezoneW) - (12.4 * ( ((safezoneW / safezoneH) min 1.2) / 40)) - 0.5 * ( ((safezoneW / safezoneH) min 1.2) / 40))])"; + y = "2.5 * ( ( ((safezoneW / safezoneH) min 1.2) / 1.2) / 25) + (profilenamespace getvariable [""IGUI_GRID_WEAPON_Y"", (safezoneY + 0.5 * ( ( ((safezoneW / safezoneH) min 1.2) / 1.2) / 25))])"; + w = "10 * ( ((safezoneW / safezoneH) min 1.2) / 40)"; + h = "1 * ( ( ((safezoneW / safezoneH) min 1.2) / 1.2) / 25)"; + size = "0.8 * ( ( ((safezoneW / safezoneH) min 1.2) / 1.2) / 25)"; + }; + class RscStructuredText_1100: RscStructuredText { + idc = 800858; + x = 0.11 * safeZoneH + safezoneX; + y = 0.4083335 * safeZoneH + safeZoneY; + w = 0.183333 * (3/4) * safeZoneH; + h = 0.183333 * safeZoneH; + size = "0.0266667 * safeZoneH;"; + colorBackground[] = {0,0,0,0.5}; + }; + class Text_Elevation: RscStructuredText { + idc = 800855; + text = ""; + x = 0 * safezoneW + safezoneX; + y = (1 * safezoneH + safezoneY) - ((4/3) * (COMPASS_SCALE)) + 0.5 * (COMPASS_SCALE * .2) * (4/3); + w = (COMPASS_SCALE * .2); + h = 0.5 * (COMPASS_SCALE * .2) * (4/3); + colorBackground[] = {1,1,1,0.01}; + size = ((COMPASS_SCALE * .2) * (4/3)) / 7; + }; + class Text_az: RscStructuredText { + idc = 800856; + text = ""; + x = (0.5 * safezoneW + safezoneX) - (COMPASS_SCALE / 2); + y = (1 * safezoneH + safezoneY) - ((COMPASS_SCALE * .2) * (4/3)); + w = (COMPASS_SCALE * .2); + h = (COMPASS_SCALE * .2) * (4/3); + colorBackground[] = {1,1,1,0.01}; + size = ((COMPASS_SCALE * .2) * (4/3)) / 7; + }; + }; + class objects { + class Azimuth_Star { + idc = 800851; + type = 82; + model = "\AGM_Artillery\data\compass_star.p3d"; + scale = COMPASS_SCALE; + direction[] = {0, 0, 1}; + up[] = {0, 1, 0}; + x = 0.5 * safezoneW + safezoneX; + y = (1 * safezoneH + safezoneY + (0.4 * COMPASS_SCALE)); + z = 1.01; + xBack = .5; + yBack = .5; + zBack = 0; + inBack =0; + enableZoom = 0; + zoomDuration = 4.001; + }; + class Azimuth_Base: Azimuth_Star { + idc = 800852; + model = "\AGM_Artillery\data\compass_base.p3d"; + z = 1; + }; + class Elevation_Star: Azimuth_Star { + idc = 800853; + x = (0 * safezoneW + safezoneX - (0.3 * COMPASS_SCALE)); + y = (1 * safezoneH + safezoneY) - ((4/3) * (COMPASS_SCALE / 2)); + up[] = {0, 0, -1}; + }; + class Elevation_Base: Azimuth_Base { + idc = 800854; + x = (0 * safezoneW + safezoneX - (0.3 * COMPASS_SCALE)); + y = (1 * safezoneH + safezoneY) - ((4/3) * (COMPASS_SCALE / 2)); + up[] = {1, 0, 0}; + }; + }; + }; +}; diff --git a/AGM_Artillery/gui_rangeTable.hpp b/AGM_Artillery/gui_rangeTable.hpp new file mode 100644 index 000000000..fb2acfc66 --- /dev/null +++ b/AGM_Artillery/gui_rangeTable.hpp @@ -0,0 +1,95 @@ +class AGM_Artillery_RangeTable_Dialog +{ + idd = -1; + movingEnable = 1; + onLoad = "uiNamespace setVariable ['AGM_Artillery_RangeTable_Dialog_display', _this select 0];"; + objects[] = {}; + + class ControlsBackground + { + class TableBackground: RscPicture + { + idc = -1; + text = "\AGM_Artillery\UI\RangeTable_background.paa"; + x = 18 *(safeZoneH / 40) + (safezoneX + (safezoneW - safeZoneH)/2); + y = 1 * ((safeZoneH / 1.2) / 25) + (safezoneY + (safezoneH - (safeZoneH / 1.2))/2); + w = 16.2634559672906 * (safeZoneH / 40); + h = 23 * ((safeZoneH / 1.2) / 25); + colorBackground[] = {1,1,1,1}; + }; + class ChargeBackground: RscText + { + idc = -1; + x = 13 *(safeZoneH / 40) + (safezoneX + (safezoneW - safeZoneH)/2); + y = 1 * ((safeZoneH / 1.2) / 25) + (safezoneY + (safezoneH - (safeZoneH / 1.2))/2); + w = 5 * (safeZoneH / 40); + h = 5 * ((safeZoneH / 1.2) / 25); + colorBackground[] = {0,0,0,1}; + }; + }; + class controls { + class TheTable : RscListNBox { + + idc = 20001; + // style = ST_CENTER + ST_MULTI + LB_TEXTURES; + // style = ST_LEFT + ST_MULTI + LB_TEXTURES; + // style = LB_MULTI + ST_LEFT; // Style + x = 18 *(safeZoneH / 40) + (safezoneX + (safezoneW - safeZoneH)/2); + y = 3.76 * ((safeZoneH / 1.2) / 25) + (safezoneY + (safezoneH - (safeZoneH / 1.2))/2); + w = 16.2634559672906 * (safeZoneH / 40); + h = 20.24 * ((safeZoneH / 1.2) / 25); + columns[] = {(10/792),(86/792),(172/792),(238/792),(329/792),(405/792),(462/792),(527/792),(588/792),(649/792),(710/792)}; + rowHeight = 0.015 * safeZoneH; + sizeEx = 0.014 * safeZoneH; + font = "EtelkaMonospacePro"; + drawSideArrows = 1; + idcLeft = 14124; + idcRight = 412343243; + colorText[] = {0, 0, 0, 1}; + shadow = 0; + // colorBorder[] = {1,0,0,1}; + // colorBackground[] = {1, 0, 0, 1}; + colorSelectBackground[] = {0, 0, 0, 0.025}; + colorSelectBackground2[] = {0, 0, 0, 0.025}; + colorScrollbar[] = {0.95,0,0.95,1}; + class ListScrollBar: ScrollBar{ + color[] = {0,0,0,0.6}; + }; + }; + class ChargeListBox: RscListbox + { + idc = 1501; + style = ST_RIGHT; + x = 13 *(safeZoneH / 40) + (safezoneX + (safezoneW - safeZoneH)/2); + y = 1 * ((safeZoneH / 1.2) / 25) + (safezoneY + (safezoneH - (safeZoneH / 1.2))/2); + w = 5 * (safeZoneH / 40); + h = 5 * ((safeZoneH / 1.2) / 25); + onLBSelChanged = "_this call AGM_Artillery_fnc_rangeTablePageChange"; + }; + + class CloseBackground: RscText + { + idc = -1; + x = 33.7634559672906 *(safeZoneH / 40) + (safezoneX + (safezoneW - safeZoneH)/2); + y = 1 * ((safeZoneH / 1.2) / 25) + (safezoneY + (safezoneH - (safeZoneH / 1.2))/2); + w = 0.5 * (safeZoneH / 40); + h = 0.5 * ((safeZoneH / 1.2) / 25); + colorBackground[] = {0,0,0,0.5}; + }; + class CloseActiveText: RscActiveText + { + idc = -1; + style = 48; + color[] = {1,1,1,0.7}; + text = "A3\Ui_f\data\GUI\Rsc\RscDisplayArcadeMap\icon_exit_cross_ca.paa"; + x = 33.7634559672906 *(safeZoneH / 40) + (safezoneX + (safezoneW - safeZoneH)/2); + y = 1 * ((safeZoneH / 1.2) / 25) + (safezoneY + (safezoneH - (safeZoneH / 1.2))/2); + w = 0.5 * (safeZoneH / 40); + h = 0.5 * ((safeZoneH / 1.2) / 25); + colorText[] = {1,1,1,0.7}; + colorActive[] = {1,1,1,1}; + tooltip = "Close"; + onButtonClick = "closeDialog 0"; + }; + }; +}; \ No newline at end of file diff --git a/AGM_Artillery/research_table2.jpg b/AGM_Artillery/research_table2.jpg new file mode 100644 index 000000000..7f0e468c0 Binary files /dev/null and b/AGM_Artillery/research_table2.jpg differ diff --git a/AGM_Artillery/stringtable.xml b/AGM_Artillery/stringtable.xml new file mode 100644 index 000000000..a9f8e5ccc --- /dev/null +++ b/AGM_Artillery/stringtable.xml @@ -0,0 +1,88 @@ + + + + + + Azimuth + Azimut + Azimut + + + Elevation + Elevation + Elevación + + + Load Map Cords + + + Load + + + Range + + + Charge + + + Target + Ziel + Objetivo + + + Height + Höhe + Altura + + + Solution + + + Time + Zeit + Tiempo + Czas + Temps + Čas + Tempo + Idő + Tempo + Tемп + + + Computing + + + AGM Advanced Mortar + + + AGM Advanced Mortar (No Optics) + + + AGM Mortar Baseplate + + + AGM Mortar Tube (No Optics) + + + AGM Mortar Tube + + + AGM Mortar Rangetable + + + Assemble AGM Mortar + + + Artillery computer + Dělostřelecký Počítač + L'ordinateur Balistique + Artillerie-Computers + Computer Dell'Artiglieria + Komputera Artyleryjskiego + Computador de Artilharia + баллистический компьютер + Ordenador de Artillería + + + \ No newline at end of file