diff --git a/A3A/addons/core/CfgFunctions.hpp b/A3A/addons/core/CfgFunctions.hpp index ea8586914a..a197962c0f 100644 --- a/A3A/addons/core/CfgFunctions.hpp +++ b/A3A/addons/core/CfgFunctions.hpp @@ -654,6 +654,9 @@ class CfgFunctions class SUP_SAM {}; class SUP_SAMAvailable {}; class SUP_SAMRoutine {}; + class SUP_tank {}; + class SUP_tankAvailable {}; + class SUP_tankRoutine {}; class SUP_UAV {}; class SUP_UAVRoutine {}; class SUP_QRFVehAirdrop {}; diff --git a/A3A/addons/core/Templates/Templates/STALKER/STALKER_AI_ClearSky.sqf b/A3A/addons/core/Templates/Templates/STALKER/STALKER_AI_ClearSky.sqf index 791b13504d..abd2790ff8 100644 --- a/A3A/addons/core/Templates/Templates/STALKER/STALKER_AI_ClearSky.sqf +++ b/A3A/addons/core/Templates/Templates/STALKER/STALKER_AI_ClearSky.sqf @@ -15,6 +15,7 @@ // Vehicles // ////////////////////////// +["attributeMoreTrucks", true] call _fnc_saveToTemplate; // due to emissions in "the zone" and such, you don't want helis and planes flying around all the time ["attributeLowAir", true] call _fnc_saveToTemplate; // due to emissions in "the zone" and such, you don't want helis and planes flying around all the time ["ammobox", "B_supplyCrate_F"] call _fnc_saveToTemplate; diff --git a/A3A/addons/core/Templates/Templates/STALKER/STALKER_AI_ClearSky_RHS.sqf b/A3A/addons/core/Templates/Templates/STALKER/STALKER_AI_ClearSky_RHS.sqf index bbe02fb437..bc5fb1abbc 100644 --- a/A3A/addons/core/Templates/Templates/STALKER/STALKER_AI_ClearSky_RHS.sqf +++ b/A3A/addons/core/Templates/Templates/STALKER/STALKER_AI_ClearSky_RHS.sqf @@ -15,6 +15,7 @@ // Vehicles // ////////////////////////// +["attributeMoreTrucks", true] call _fnc_saveToTemplate; // due to emissions in "the zone" and such, you don't want helis and planes flying around all the time ["attributeLowAir", true] call _fnc_saveToTemplate; // due to emissions in "the zone" and such, you don't want helis and planes flying around all the time ["ammobox", "B_supplyCrate_F"] call _fnc_saveToTemplate; diff --git a/A3A/addons/core/Templates/Templates/STALKER/STALKER_AI_Freedom.sqf b/A3A/addons/core/Templates/Templates/STALKER/STALKER_AI_Freedom.sqf index 92aef722f8..cea1779c2a 100644 --- a/A3A/addons/core/Templates/Templates/STALKER/STALKER_AI_Freedom.sqf +++ b/A3A/addons/core/Templates/Templates/STALKER/STALKER_AI_Freedom.sqf @@ -15,6 +15,7 @@ // Vehicles // ////////////////////////// +["attributeMoreTrucks", true] call _fnc_saveToTemplate; // due to emissions in "the zone" and such, you don't want helis and planes flying around all the time ["attributeLowAir", true] call _fnc_saveToTemplate; // due to emissions in "the zone" and such, you don't want helis and planes flying around all the time ["ammobox", "B_supplyCrate_F"] call _fnc_saveToTemplate; diff --git a/A3A/addons/core/Templates/Templates/STALKER/STALKER_AI_Freedom_RHS.sqf b/A3A/addons/core/Templates/Templates/STALKER/STALKER_AI_Freedom_RHS.sqf index e7556a2364..9ef655ebb4 100644 --- a/A3A/addons/core/Templates/Templates/STALKER/STALKER_AI_Freedom_RHS.sqf +++ b/A3A/addons/core/Templates/Templates/STALKER/STALKER_AI_Freedom_RHS.sqf @@ -15,6 +15,7 @@ // Vehicles // ////////////////////////// +["attributeMoreTrucks", true] call _fnc_saveToTemplate; // due to emissions in "the zone" and such, you don't want helis and planes flying around all the time ["attributeLowAir", true] call _fnc_saveToTemplate; // due to emissions in "the zone" and such, you don't want helis and planes flying around all the time ["ammobox", "B_supplyCrate_F"] call _fnc_saveToTemplate; diff --git a/A3A/addons/core/Templates/Templates/STALKER/STALKER_AI_Military.sqf b/A3A/addons/core/Templates/Templates/STALKER/STALKER_AI_Military.sqf index f20bda5dd7..590f557a85 100644 --- a/A3A/addons/core/Templates/Templates/STALKER/STALKER_AI_Military.sqf +++ b/A3A/addons/core/Templates/Templates/STALKER/STALKER_AI_Military.sqf @@ -15,6 +15,7 @@ // Vehicles // ////////////////////////// +["attributeMoreTrucks", true] call _fnc_saveToTemplate; // due to emissions in "the zone" and such, you don't want helis and planes flying around all the time ["attributeLowAir", true] call _fnc_saveToTemplate; // due to emissions in "the zone" and such, you don't want helis and planes flying around all the time ["ammobox", "B_supplyCrate_F"] call _fnc_saveToTemplate; diff --git a/A3A/addons/core/Templates/Templates/STALKER/STALKER_AI_Military_RHS.sqf b/A3A/addons/core/Templates/Templates/STALKER/STALKER_AI_Military_RHS.sqf index 0c21623bf4..4211d5ffe0 100644 --- a/A3A/addons/core/Templates/Templates/STALKER/STALKER_AI_Military_RHS.sqf +++ b/A3A/addons/core/Templates/Templates/STALKER/STALKER_AI_Military_RHS.sqf @@ -15,6 +15,7 @@ // Vehicles // ////////////////////////// +["attributeMoreTrucks", true] call _fnc_saveToTemplate; // due to emissions in "the zone" and such, you don't want helis and planes flying around all the time ["attributeLowAir", true] call _fnc_saveToTemplate; // due to emissions in "the zone" and such, you don't want helis and planes flying around all the time ["ammobox", "B_supplyCrate_F"] call _fnc_saveToTemplate; diff --git a/A3A/addons/core/Templates/Templates/STALKER/STALKER_AI_Monolith.sqf b/A3A/addons/core/Templates/Templates/STALKER/STALKER_AI_Monolith.sqf index a36f78bca1..3cd8476217 100644 --- a/A3A/addons/core/Templates/Templates/STALKER/STALKER_AI_Monolith.sqf +++ b/A3A/addons/core/Templates/Templates/STALKER/STALKER_AI_Monolith.sqf @@ -15,6 +15,7 @@ // Vehicles // ////////////////////////// +["attributeMoreTrucks", true] call _fnc_saveToTemplate; // due to emissions in "the zone" and such, you don't want helis and planes flying around all the time ["attributeLowAir", true] call _fnc_saveToTemplate; // due to emissions in "the zone" and such, you don't want helis and planes flying around all the time ["ammobox", "B_supplyCrate_F"] call _fnc_saveToTemplate; diff --git a/A3A/addons/core/Templates/Templates/STALKER/STALKER_AI_Monolith_RHS.sqf b/A3A/addons/core/Templates/Templates/STALKER/STALKER_AI_Monolith_RHS.sqf index 3d79407151..1f73764888 100644 --- a/A3A/addons/core/Templates/Templates/STALKER/STALKER_AI_Monolith_RHS.sqf +++ b/A3A/addons/core/Templates/Templates/STALKER/STALKER_AI_Monolith_RHS.sqf @@ -15,6 +15,7 @@ // Vehicles // ////////////////////////// +["attributeMoreTrucks", true] call _fnc_saveToTemplate; // due to emissions in "the zone" and such, you don't want helis and planes flying around all the time ["attributeLowAir", true] call _fnc_saveToTemplate; // due to emissions in "the zone" and such, you don't want helis and planes flying around all the time ["ammobox", "B_supplyCrate_F"] call _fnc_saveToTemplate; diff --git a/A3A/addons/core/functions/Base/fn_destroyCity.sqf b/A3A/addons/core/functions/Base/fn_destroyCity.sqf index 6efe63eb35..f6de9102e1 100644 --- a/A3A/addons/core/functions/Base/fn_destroyCity.sqf +++ b/A3A/addons/core/functions/Base/fn_destroyCity.sqf @@ -2,15 +2,17 @@ params ["_markerX"]; private _positionX = getMarkerPos _markerX; private _size = [_markerX] call A3A_fnc_sizeMarker; -private _buildings = _positionX nearobjects ["house",_size]; + +private _buildings = _positionX nearObjects ["house",_size]; { - if (random 100 < 70) then { - for "_i" from 1 to 7 do { - _x setHit [format ["dam%1",_i],1]; - _x setHit [format ["dam %1",_i],1]; - }; - }; + private _hitpoints = getAllHitPointsDamage _x; + if (_hitpoints isEqualTo []) then { continue }; + if (random 100 < 30) then { continue }; + private _building = _x; + { + _building setHit [_x, 1]; + } forEach (_hitpoints # 1 select { _x find "dam" == 0 }); } forEach _buildings; [_markerX,false] spawn A3A_fnc_blackout; \ No newline at end of file diff --git a/A3A/addons/core/functions/Base/fn_getVehiclesGroundSupport.sqf b/A3A/addons/core/functions/Base/fn_getVehiclesGroundSupport.sqf index dce1148d1e..e37e3b7a31 100644 --- a/A3A/addons/core/functions/Base/fn_getVehiclesGroundSupport.sqf +++ b/A3A/addons/core/functions/Base/fn_getVehiclesGroundSupport.sqf @@ -9,7 +9,7 @@ Arguments: Return value: [vehType, weight, vehType2, weight2, ...] */ -params ["_side", "_level"]; +params ["_side", "_level", ["_tanksOnly", false]]; _level = (_level max 1 min 10) - 1; private _faction = [A3A_faction_occ, A3A_faction_inv] select (_side == Invaders); @@ -31,6 +31,10 @@ private _ltankWeight = [ 0, 10, 15, 25, 30, 35, 30, 25, 20, 15] select _lev private _vehAA = (_faction get "vehiclesAA") select { A3A_vehicleResourceCosts get _x >= 100 }; if (_vehAA isEqualTo []) then { _tankWeight = _tankWeight + _aaWeight }; +[_faction get "vehiclesLightTanks", _ltankWeight] call _fnc_addArrayToWeights; +[_faction get "vehiclesTanks", _tankWeight] call _fnc_addArrayToWeights; +if (_tanksOnly) exitWith { _vehWeights }; + // only occupants use militia vehicles? if (_side == Occupants) then { [_faction get "vehiclesMilitiaLightArmed", _milCarWeight] call _fnc_addArrayToWeights; @@ -40,8 +44,6 @@ if (_side == Occupants) then { }; }; [_faction get "vehiclesLightArmed", _carWeight] call _fnc_addArrayToWeights; -[_faction get "vehiclesTanks", _tankWeight] call _fnc_addArrayToWeights; -[_faction get "vehiclesLightTanks", _ltankWeight] call _fnc_addArrayToWeights; [_vehAA, _aaWeight] call _fnc_addArrayToWeights; _vehWeights; diff --git a/A3A/addons/core/functions/Base/fn_getVehiclesGroundTransport.sqf b/A3A/addons/core/functions/Base/fn_getVehiclesGroundTransport.sqf index 502346a73f..938d9d57e8 100644 --- a/A3A/addons/core/functions/Base/fn_getVehiclesGroundTransport.sqf +++ b/A3A/addons/core/functions/Base/fn_getVehiclesGroundTransport.sqf @@ -36,9 +36,20 @@ private _ltankWeight = [ 0, 0, 15, 25, 30, 35, 30, 25, 20, 15] select _level // Assumption is that at least one of APC or battle bus exists if (_faction get "vehiclesTanks" isEqualTo []) then { _tankWeight = _tankWeight + _ltankWeight }; if (_faction get "vehiclesLightTanks" isEqualTo []) then { _ltankWeight = _ltankWeight + _ifvWeight }; -if (_faction get "vehiclesIFVs" isEqualTo []) then { _apcWeight = _apcWeight + _ifvWeight }; -if (_faction get "vehiclesAPCs" isEqualTo []) then { _lapcWeight = _lapcWeight + _apcWeight }; + +if (_faction getOrDefault ["attributeMoreTrucks", false]) then { + _truckWeight = [60, 60, 60, 60, 60, 60, 55, 50, 45, 40] select _level; + _lapcWeight = [10, 15, 20, 20, 20, 20, 20, 20, 20, 20] select _level; + _apcWeight = [ 0, 4, 8, 12, 16, 20, 20, 20, 20, 20] select _level; + _ifvWeight = [ 0, 0, 2, 4, 6, 8, 12, 16, 20, 25] select _level; +}; + if (_faction get "vehiclesLightAPCs" isEqualTo []) then { _apcWeight = _apcWeight + _lapcWeight/2; _truckWeight = _truckWeight + _lapcWeight/2; }; +if (_faction get "vehiclesIFVs" isEqualTo []) then { _apcWeight = _apcWeight + _ifvWeight }; +if (_faction get "vehiclesAPCs" isEqualTo []) then { + if (_faction get "vehiclesLightAPCs" isEqualTo []) exitWith { _ifvWeight = _ifvWeight + _apcWeight }; + _lapcWeight = _lapcWeight + _apcWeight; +}; // only occupants use militia vehicle types? if (_side == Occupants) then { diff --git a/A3A/addons/core/functions/CREATE/fn_createAttackForceLand.sqf b/A3A/addons/core/functions/CREATE/fn_createAttackForceLand.sqf index 9edb19938a..09d7fc50a5 100644 --- a/A3A/addons/core/functions/CREATE/fn_createAttackForceLand.sqf +++ b/A3A/addons/core/functions/CREATE/fn_createAttackForceLand.sqf @@ -14,6 +14,7 @@ Arguments: Number of attack/support vehicles to create Optional, tier modifier to apply to vehicle selection (Default: 0) Optional, troop type to use (Default: "Normal") + Optional, true to only use tanks (Default: false) Return array: Resources spent @@ -24,26 +25,44 @@ Return array: #include "..\..\script_component.hpp" FIX_LINE_NUMBERS() -params ["_side", "_base", "_target", "_resPool", "_vehCount", "_vehAttackCount", ["_tierMod", 0]]; +params ["_side", "_base", "_target", "_resPool", "_vehCount", "_vehAttackCount", ["_tierMod", 0], ["_troopType", "Normal"], ["_tanksOnly", false]]; private _targpos = if (_target isEqualType []) then { _target } else { markerPos _target }; private _transportRatio = 1 - _vehAttackCount / _vehCount; +if (_tierMod isEqualTo 0) then {_tierMod = 1}; + private _resourcesSpent = 0; private _vehicles = []; private _crewGroups = []; private _cargoGroups = []; -private _transportPool = [_side, tierWar+_tierMod] call A3A_fnc_getVehiclesGroundTransport; -private _supportPool = [_side, tierWar+_tierMod] call A3A_fnc_getVehiclesGroundSupport; +private _transportPool = []; +private _supportPool = []; + +// Bandaid fix for whatever was causing everything to break, this seems to work consistently. If _tierMod was 0, even the normal pools would break... +if (_tanksOnly) then { + _transportPool = [_side, 6] call A3A_fnc_getVehiclesGroundTransport; + _supportPool = [_side, 6, true] call A3A_fnc_getVehiclesGroundSupport; +} else { + _transportPool = [_side, tierWar+_tierMod] call A3A_fnc_getVehiclesGroundTransport; + _supportPool = [_side, tierWar+_tierMod, true] call A3A_fnc_getVehiclesGroundSupport; +}; private _numTransports = 0; private _isTransport = _vehAttackCount < _vehCount; // normal case, first vehicle should be a transport private _landPosBlacklist = []; for "_i" from 1 to _vehCount do { - private _vehType = selectRandomWeighted ([_supportPool, _transportPool] select _isTransport); + private _vehType = ObjNull; + + // Attempt to grab veh types + _vehType = selectRandomWeighted ([_supportPool, _transportPool] select _isTransport); + if (isNil "_vehType") then { + Error_1("Failed to grab land vehicle, attempting to grab a transport vehicle.", _base); + _vehType = selectRandomWeighted _transportPool; + }; - private _vehData = [_vehType, "Normal", _resPool, _landPosBlacklist, _side, _base, _targPos] call A3A_fnc_createAttackVehicle; + private _vehData = [_vehType, _troopType, _resPool, _landPosBlacklist, _side, _base, _targPos] call A3A_fnc_createAttackVehicle; if !(_vehData isEqualType []) exitWith { Error_1("Failed to spawn land vehicle at marker %1", _base); }; // couldn't create for some reason, assume we're out of spawn places? diff --git a/A3A/addons/core/functions/Supports/fn_SUP_ASFRoutine.sqf b/A3A/addons/core/functions/Supports/fn_SUP_ASFRoutine.sqf index fdad511912..b79f63ccc2 100644 --- a/A3A/addons/core/functions/Supports/fn_SUP_ASFRoutine.sqf +++ b/A3A/addons/core/functions/Supports/fn_SUP_ASFRoutine.sqf @@ -35,6 +35,7 @@ _plane setVariable ["SupportData", _suppData]; // for use in EHs private _group = [_side, _plane] call A3A_fnc_createVehicleCrew; { [_x, nil, false, _resPool] call A3A_fnc_NATOinit } forEach units _group; _group deleteGroupWhenEmpty true; +[-10 * count units _group, _side, _resPool] call A3A_fnc_addEnemyResources; _plane addEventHandler ["Killed", { params ["_plane"]; diff --git a/A3A/addons/core/functions/Supports/fn_SUP_CASRoutine.sqf b/A3A/addons/core/functions/Supports/fn_SUP_CASRoutine.sqf index e5dc6d3c80..d0505b5200 100644 --- a/A3A/addons/core/functions/Supports/fn_SUP_CASRoutine.sqf +++ b/A3A/addons/core/functions/Supports/fn_SUP_CASRoutine.sqf @@ -35,6 +35,7 @@ private _group = [_side, _plane] call A3A_fnc_createVehicleCrew; { [_x, nil, false, _resPool] call A3A_fnc_NATOinit } forEach units _group; _group deleteGroupWhenEmpty true; _group setBehaviourStrong "CARELESS"; +[-10 * count units _group, _side, _resPool] call A3A_fnc_addEnemyResources; _plane setVehicleRadar 1; diff --git a/A3A/addons/core/functions/Supports/fn_SUP_UAVRoutine.sqf b/A3A/addons/core/functions/Supports/fn_SUP_UAVRoutine.sqf index d7ba572888..3c11a695ef 100644 --- a/A3A/addons/core/functions/Supports/fn_SUP_UAVRoutine.sqf +++ b/A3A/addons/core/functions/Supports/fn_SUP_UAVRoutine.sqf @@ -27,6 +27,7 @@ private _uav = createVehicle [_planeType, _spawnPos, [], 0, "FLY"]; [_side, _uav] call A3A_fnc_createVehicleCrew; _groupVeh = group driver _uav; { [_x, nil, false, _resPool] call A3A_fnc_NATOinit } forEach (crew _uav); // arguable +[-10 * count units _groupVeh, _side, _resPool] call A3A_fnc_addEnemyResources; [_uav, _side, _resPool] call A3A_fnc_AIVEHinit; private _gunner = gunner _uav; diff --git a/A3A/addons/core/functions/Supports/fn_SUP_airstrikeRoutine.sqf b/A3A/addons/core/functions/Supports/fn_SUP_airstrikeRoutine.sqf index 6f3c1fc349..8bc5cfc4ec 100644 --- a/A3A/addons/core/functions/Supports/fn_SUP_airstrikeRoutine.sqf +++ b/A3A/addons/core/functions/Supports/fn_SUP_airstrikeRoutine.sqf @@ -38,6 +38,7 @@ _group deleteGroupWhenEmpty true; _x disableAI "TARGET"; _x disableAI "AUTOTARGET"; } forEach units _group; +[-10 * count units _group, _side, _resPool] call A3A_fnc_addEnemyResources; // Should we really have these? _plane addEventHandler ["Killed", { diff --git a/A3A/addons/core/functions/Supports/fn_SUP_artillery.sqf b/A3A/addons/core/functions/Supports/fn_SUP_artillery.sqf index 33894899cc..106e56df8e 100644 --- a/A3A/addons/core/functions/Supports/fn_SUP_artillery.sqf +++ b/A3A/addons/core/functions/Supports/fn_SUP_artillery.sqf @@ -65,4 +65,4 @@ A3A_activeSupports pushBack _suppData; [_reveal, _side, "ARTILLERY", _targPos, _delay] spawn A3A_fnc_showInterceptedSetupCall; // Vehicle cost + extra support cost for balance -(A3A_vehicleResourceCosts get _vehType) + 200; +(A3A_vehicleResourceCosts get _vehType) + (10 * count units _group) + 200; diff --git a/A3A/addons/core/functions/Supports/fn_SUP_artilleryAvailable.sqf b/A3A/addons/core/functions/Supports/fn_SUP_artilleryAvailable.sqf index d968fc48df..f258da4698 100644 --- a/A3A/addons/core/functions/Supports/fn_SUP_artilleryAvailable.sqf +++ b/A3A/addons/core/functions/Supports/fn_SUP_artilleryAvailable.sqf @@ -19,4 +19,4 @@ if (_target isKindOf "Air") exitWith { 0 }; // can't hit air // Weighted against mortars if(tierWar < 5) exitWith { 0 }; -(tierWar - 4) / 8; // ~12.5% at tier 5, 75% at tier 10 +(tierWar - 4) / 12; // ~8.3% at tier 5, 50% at tier 10 diff --git a/A3A/addons/core/functions/Supports/fn_SUP_mortar.sqf b/A3A/addons/core/functions/Supports/fn_SUP_mortar.sqf index feb5456456..5749cffee2 100644 --- a/A3A/addons/core/functions/Supports/fn_SUP_mortar.sqf +++ b/A3A/addons/core/functions/Supports/fn_SUP_mortar.sqf @@ -83,4 +83,4 @@ A3A_activeSupports pushBack _suppData; [_reveal, _side, "MORTAR", _targPos, _delay] spawn A3A_fnc_showInterceptedSetupCall; // Mortar cost (might be free?) + extra support cost for balance -(A3A_vehicleResourceCosts getOrDefault [_vehType, 0]) + 100; +(A3A_vehicleResourceCosts getOrDefault [_vehType, 0]) + (10 * count units _group) + 100; \ No newline at end of file diff --git a/A3A/addons/core/functions/Supports/fn_SUP_mortarAvailable.sqf b/A3A/addons/core/functions/Supports/fn_SUP_mortarAvailable.sqf index 2833e7b1cf..7c55febcf0 100644 --- a/A3A/addons/core/functions/Supports/fn_SUP_mortarAvailable.sqf +++ b/A3A/addons/core/functions/Supports/fn_SUP_mortarAvailable.sqf @@ -20,4 +20,4 @@ if (_target isKindOf "Air") exitWith { 0 }; // can't hit air // balance this one against artillery if (tierWar < 2) exitWith { 0 }; if (tierWar < 5 or !("ARTILLERY" in _availTypes)) exitWith { 1 }; -1 - (tierWar - 4) / 8; // // 87.5% at tier 5, 25% at tier 10 +1 - (tierWar - 4) / 12; // // 91.7% at tier 5, 50% at tier 1 \ No newline at end of file diff --git a/A3A/addons/core/functions/Supports/fn_SUP_tank.sqf b/A3A/addons/core/functions/Supports/fn_SUP_tank.sqf new file mode 100644 index 0000000000..688ddb4a82 --- /dev/null +++ b/A3A/addons/core/functions/Supports/fn_SUP_tank.sqf @@ -0,0 +1,51 @@ +/* Sets up a land QRF support + +Environment: Server, scheduled, internal + +Arguments: + The (unique) name of the support, mostly for logging + The side from which the support should be sent (occupants or invaders) + Resource pool used for this support. Should be "attack" or "defence" + Maximum resources to spend on this support. Must be greater than zero + Initial target, or "false" for none. + Estimated position of target, or center of target zone + Reveal value 0-1, higher values mean more information provided about support + Setup delay time in seconds, if negative will calculate based on war tier + +Returns: + Resource cost of support call, or -1 for failure +*/ + +#include "..\..\script_component.hpp" +FIX_LINE_NUMBERS() + +params ["_suppName", "_side", "_resPool", "_maxSpend", "_target", "_targPos", "_reveal", "_delay"]; + +private _base = [_side, _targPos] call A3A_fnc_availableBasesLand; +if (isNil "_base") exitWith { Info("Tanks cancelled because no land bases available"); -1 }; + +// Prevent ground QRFs spawning on top of each other. Should be gone after a minute. +[_base, 1] call A3A_fnc_addTimeForIdle; + +private _vehCount = 2 min ceil (_maxSpend / 200); +private _estResources = _vehCount * 200; + +// Land QRF delay is purely dependent on travel as they're slow enough already +if (_delay < 0) then { _delay = 0 }; // land QRFs slow enough already + +private _targArray = []; +if (_target isEqualType objNull and {!isNull _target}) then { + // Should probably put a partial "troops" entry in here too? + A3A_supportStrikes pushBack [_side, "TARGET", _target, time + 1800, 1800, 150*_vehCount]; + _targArray = [_target, _targPos]; +}; + +// name, side, suppType, center, radius, [target, targpos] +private _suppData = [_supportName, _side, "TANK", _targPos, 1000, _targArray]; +A3A_activeSupports pushBack _suppData; +[_suppData, _resPool, _base, _vehCount, _delay, _estResources] spawn A3A_fnc_SUP_tankRoutine; + +private _approxTime = _delay + (markerPos _base distance2D _targPos) / (30 / 3.6); // (badly) estimated travel time +[_reveal, _side, "TANK", _targPos, _approxTime] spawn A3A_fnc_showInterceptedSetupCall; + +_estResources; // *estimated* resource cost of vehicles \ No newline at end of file diff --git a/A3A/addons/core/functions/Supports/fn_SUP_tankAvailable.sqf b/A3A/addons/core/functions/Supports/fn_SUP_tankAvailable.sqf new file mode 100644 index 0000000000..3f758faaeb --- /dev/null +++ b/A3A/addons/core/functions/Supports/fn_SUP_tankAvailable.sqf @@ -0,0 +1,22 @@ +/* Get tank support selection weight against target +Arguments: + Target object + Side to send support from + Max resource spend (not currently used) + Array of strings of available types for this faction +Return value: + Weight value, 0 for unavailable or useless +*/ + +#include "..\..\script_component.hpp" +FIX_LINE_NUMBERS() + +params ["_target", "_side", "_maxSpend", "_availTypes"]; + +if (_target isKindOf "Air") exitWith { 0 }; // can't hit air + +if (_target isKindOf "Man") exitWith { 0.001 }; // Don't spawn to attack meatsacks, but re-use active supports + +// Against vehicles and statics, use more frequently against more dangerous stuff +private _threat = A3A_groundVehicleThreat getOrDefault [typeOf _target, 0]; +0.001 + _threat / 80; \ No newline at end of file diff --git a/A3A/addons/core/functions/Supports/fn_SUP_tankRoutine.sqf b/A3A/addons/core/functions/Supports/fn_SUP_tankRoutine.sqf new file mode 100644 index 0000000000..32f39d0648 --- /dev/null +++ b/A3A/addons/core/functions/Supports/fn_SUP_tankRoutine.sqf @@ -0,0 +1,126 @@ +/* Create and maintain close air support bomber +Environment: Server, must be spawned +Arguments: + Active support data, see initSupports + Resource pool of support, "attack" or "defence" + Marker name of source land base + Number of tanks to send + Delay time in seconds + Estimated resources already spent on support +// Amount of information to reveal to rebels, 0-1 +*/ +#include "..\..\script_component.hpp" +FIX_LINE_NUMBERS() + +Debug_1("tankRoutine called with %1", _this); + +params ["_suppData", "_resPool", "_base", "_vehCount", "_sleepTime", "_estResources"]; +_suppData params ["_supportName", "_side", "_suppType", "_suppCenter", "_suppRadius", "_suppTarget"]; + +sleep _sleepTime; + +// Only spawn tanks +private _data = [_side, _base, _suppCenter, _resPool, _vehCount, _vehCount, 2, "Normal", true] call A3A_fnc_createAttackForceLand; +_data params ["_resources", "_vehicles", "_crewGroups", "_cargoGroups"]; +Info_1("Spawn performed: Vehicles %1", _vehicles apply { typeOf _x }); + +// Update the resource usage for the final value +[_estResources - _resources, _side, _resPool] remoteExec ["A3A_fnc_addEnemyResources", 2]; + + +#define STATE_TRAVEL 1 +#define STATE_ACQUIRE 2 +#define STATE_ATTACK 3 + +private _timeOut = time + 1800; +private _remTargets = 2; +private _state = STATE_TRAVEL; +private _targetObj = objNull; + +while {true} do +{ + private _remVehicles = _vehicles select { canFire _x and canMove _x and side _x == _side }; + if (_remVehicles isEqualTo []) exitWith { + Info_1("%1 has been defeated, starting retreat", _supportName); + }; + if (time > _timeOut) exitWith { + Info_1("%1 has timed out, starting retreat", _supportName); + }; + if (_remTargets <= 0) exitWith { + Info_1("%1 has run out of targets, aborting routine", _supportName); + }; + + switch (_state) do + { + case STATE_TRAVEL: { + if (_remVehicles inAreaArray [_suppCenter, _suppRadius, _suppRadius] isEqualTo []) exitWith { sleep 5 }; + + Debug_1("%1 reached patrol zone, acquiring target", _supportName); + _state = STATE_ACQUIRE; + continue; + }; + + case STATE_ACQUIRE: { + if (_suppTarget isEqualTo []) exitWith { sleep 5 }; + + _targetObj = _suppTarget select 0; + if !(_targetObj call A3A_fnc_canFight) exitWith { + _suppTarget resize 0; + Debug_1("%1 skips target, as it is already dead", _supportName); + }; + Debug_2("Next target for %2 is %1", _suppTarget, _supportName); + + private _lastKnownPos = _suppTarget select 1; + private _knownDist = _lastKnownPos distance2d getPosATL _targetObj; + private _knowledge = random 0.3 + _knownDist / _suppRadius; + + { + // reveal based on proximity to last known pos + _x reveal [_targetObj, 4*_knowledge]; + + { deleteWaypoint _x } forEachReversed (waypoints _x); + private _attackWP = _x addWaypoint [_targetObj, 0]; + _attackWP setWaypointType "DESTROY"; + _attackWP waypointAttachVehicle _targetObj; + private _sadWP = _x addWaypoint [_lastKnownPos, 0]; + _sadWP setWaypointType "SAD"; + + _x setCurrentWaypoint ([_sadWP, _attackWP] select (_knowledge > random 0.5)); + _x setBehaviourStrong "COMBAT"; + _x setCombatMode "RED"; + + } forEach _crewGroups; + + _timeout = _timeout + 300; + _state = STATE_ATTACK; + continue; + }; + + case STATE_ATTACK: { + if (alive _targetObj and {_targetObj distance2D _suppCenter < _suppRadius}) exitWith { sleep 5 }; + + _remTargets = _remTargets - 1; + _suppTarget resize 0; // clear target array so support routines can add the next + + if !(alive _targetObj) then { + Debug_1("Target destroyed, %1 returns to cycle mode", _supportName); + } else { + Debug_1("Target evaded, %1 returns to cycle mode", _supportName); + }; + + { + _x setBehaviourStrong "AWARE"; + _x setCombatMode "YELLOW"; + } forEach _crewGroups; + + _timeout = _timeout - 300; + _state = STATE_ACQUIRE; + continue; + }; + }; +}; + +_suppData set [4, 0]; // Set activesupport radius to 0, enables cleanup + +{ [_x] spawn A3A_fnc_VEHDespawner } forEach _vehicles; +{ [_x] spawn A3A_fnc_enemyReturnToBase } forEach (_crewGroups + _cargoGroups); \ No newline at end of file diff --git a/A3A/addons/core/functions/Supports/fn_initSupports.sqf b/A3A/addons/core/functions/Supports/fn_initSupports.sqf index 77c34ce72d..fa0597346f 100644 --- a/A3A/addons/core/functions/Supports/fn_initSupports.sqf +++ b/A3A/addons/core/functions/Supports/fn_initSupports.sqf @@ -38,7 +38,8 @@ private _initData = [ ["MORTAR", "AREA", 0.5, 0.9, 100, 50, "", "staticMortars"], ["HOWITZER", "AREA", 0.5, 0.9, 125, 65, "", "staticHowitzers"], ["ASF", "TARGET", 1.0, 0.4, 0, 100, "", "vehiclesPlanesAA"], // balanced against SAMs (if available), 66/33 weighting - ["CAS", "TARGET", 1.0, 0.4, 0, 100, "", "vehiclesPlanesCAS"], + ["CAS", "TARGET", 0.5, 0.3, 0, 100, "", "vehiclesPlanesCAS"], + ["TANK", "TARGET", 0.5, 0.7, 0, 100, "", ""], // balanced against CAS, lowAir based ["CASDIVE", "TARGET", 0.8, 0.3, 0, 100, "", "vehiclesPlanesCAS"], ["QRFLAND", "TROOPS", 1.0, 1.4, 0, 0, "", ""], ["QRFAIR", "TROOPS", 0.5, 0.1, 0, 0, "", ""], diff --git a/A3A/addons/core/functions/Supports/fn_showInterceptedSetupCall.sqf b/A3A/addons/core/functions/Supports/fn_showInterceptedSetupCall.sqf index 08101e08e1..1f79fd7029 100644 --- a/A3A/addons/core/functions/Supports/fn_showInterceptedSetupCall.sqf +++ b/A3A/addons/core/functions/Supports/fn_showInterceptedSetupCall.sqf @@ -56,6 +56,10 @@ else { _text = format [localize "STR_notifiers_SUP_setup_QRFVehAirdrop", _sideName]; }; + case ("TANK"): + { + _text = format [localize "STR_A3A_fn_support_showIntStpCll_TANK", _sideName]; + }; case ("AIRSTRIKE"): { _text = format [localize "STR_notifiers_SUP_setup_airstrike", _sideName]; @@ -121,7 +125,7 @@ private _timeStr = if(_setupTime < 60) then { "<1" } else { str round (_setup if(_reveal >= 0.8) then { - if(toupper _supportType in ["QRFLAND", "QRFAIR", "COUNTERATTACK", "MAJORATTACK", "QRFVEHAIRDROP"]) then + if(toupper _supportType in ["QRFLAND", "QRFAIR", "COUNTERATTACK", "MAJORATTACK", "QRFVEHAIRDROP", "TANK"]) then { _text = format [localize "STR_notifiers_SUP_QRF_setup_arrival", _text, _timeStr]; } diff --git a/A3A/addons/core/functions/init/fn_initServer.sqf b/A3A/addons/core/functions/init/fn_initServer.sqf index bf8da0785a..9866eb5557 100644 --- a/A3A/addons/core/functions/init/fn_initServer.sqf +++ b/A3A/addons/core/functions/init/fn_initServer.sqf @@ -17,6 +17,7 @@ if (call A3A_fnc_modBlacklist) exitWith {}; // hide all the HQ objects { + _x enableRopeAttach false; _x allowDamage false; _x hideObjectGlobal true; } forEach [boxX, flagX, vehicleBox, mapX, petros]; diff --git a/A3A/addons/ultimate/Stringtable.xml b/A3A/addons/ultimate/Stringtable.xml index cc87a74d50..171bcff66a 100644 --- a/A3A/addons/ultimate/Stringtable.xml +++ b/A3A/addons/ultimate/Stringtable.xml @@ -121,4 +121,9 @@ Dismemberment + + + %1 just sent a tank platoon. + +