From 349abeeec277602dcf6015044a09338d8e6eaa76 Mon Sep 17 00:00:00 2001
From: dijksterhuis <11841332+dijksterhuis@users.noreply.github.com>
Date: Fri, 12 Jul 2024 17:12:34 +0100
Subject: [PATCH 01/15] Revert "Merge pull request #294 from
dijksterhuis/revert-ctf-changes"
This reverts commit 82b4a6471c9dfd25c5b043dcecd29ed10b8ebfdb, reversing
changes made to c1d07a60d662faf552aa784632e1b0889a4d3761.
---
mission/config/functions.hpp | 2 +
.../config/subconfigs/tasks/primary/tasks.hpp | 12 ++
.../systems/actions/fn_action_lower_flag.sqf | 52 +++++++--
.../actions/fn_action_reraise_flag.sqf | 50 ++++++---
.../dac_cong/fn_ctf_bluefor_raise_flag.sqf | 33 ++++++
.../dac_cong/fn_ctf_opfor_lower_flag.sqf | 32 ++++++
.../defend/fn_task_defend_counterattack.sqf | 103 +++++++++++-------
.../tasks/primary/fn_task_pri_capture.sqf | 91 +++++++++++++---
8 files changed, 289 insertions(+), 86 deletions(-)
create mode 100644 mission/functions/systems/dac_cong/fn_ctf_bluefor_raise_flag.sqf
create mode 100644 mission/functions/systems/dac_cong/fn_ctf_opfor_lower_flag.sqf
diff --git a/mission/config/functions.hpp b/mission/config/functions.hpp
index 3790c5a8..95a7ce75 100644
--- a/mission/config/functions.hpp
+++ b/mission/config/functions.hpp
@@ -221,6 +221,8 @@ class CfgFunctions
file = "functions\systems\dac_cong";
class capture_player {};
+ class ctf_opfor_lower_flag {};
+ class ctf_bluefor_raise_flag {};
}
//Gameplay director, responsible for main game progression and flow.
diff --git a/mission/config/subconfigs/tasks/primary/tasks.hpp b/mission/config/subconfigs/tasks/primary/tasks.hpp
index 05d0d529..3206ce61 100644
--- a/mission/config/subconfigs/tasks/primary/tasks.hpp
+++ b/mission/config/subconfigs/tasks/primary/tasks.hpp
@@ -41,6 +41,18 @@ class capture_zone : task
taskdesc = "Build a respawn so we can reinforce the Forward Operating Base.";
};
+ class build_landing_pad
+ {
+ taskname = "Build FOB Landing Pad";
+ taskdesc = "Build a landing pad so helos can land near the FOB. Emphasis on near!";
+ };
+
+ class build_rearm_repair_refuel
+ {
+ taskname = "Build FOB Rearm/Repair/Refuel Station";
+ taskdesc = "Build a Vehicle Rearm/Repair/Refuel location at the FOB. Possibly next to the helipad.";
+ };
+
class build_flag
{
taskname = "Build FOB Flag";
diff --git a/mission/functions/systems/actions/fn_action_lower_flag.sqf b/mission/functions/systems/actions/fn_action_lower_flag.sqf
index 62660647..28a18c33 100644
--- a/mission/functions/systems/actions/fn_action_lower_flag.sqf
+++ b/mission/functions/systems/actions/fn_action_lower_flag.sqf
@@ -4,24 +4,42 @@
Public: No
Description:
- Dac Cong players can approach a mission critical (player built) flag in a base
- and then lower it, causing a mission objective to fail.
+ Dac Cong players can approach a mission critical (player built)
+ flag in a base and then lower it, causing a mission objective
+ to fail.
+
+ WARNING: This is attached to **PLAYERS**, running in **player** locality.
Parameter(s): none
Returns:
Example(s):
+ call vn_mf_fnc_action_lower_flag;
*/
-private _actionText = format ["%1", "Lower Enemy Flag"];
+private _actionText = format ["%1", "Lower Flag"];
private _actionIdleIcon = "custom\holdactions\holdAction_interact_ca.paa";
private _actionProgressIcon = "custom\holdactions\holdAction_danger_ca.paa";
private _isOpfor = "side player == east";
private _isInRangeOf = "player distance cursorObject < 5";
-private _isValidObjectType = "typeOf cursorObject in ['vn_flag_usa', 'vn_flag_aus', 'vn_flag_arvn', 'vn_flag_nz']";
-private _isObjectiveFlag = "cursorObject getVariable ['canLower', false]";
+private _validFlagsArr = "['vn_flag_usa', 'vn_flag_aus', 'vn_flag_arvn', 'vn_flag_nz']";
+private _isValidObjectType = format [
+ "typeOf cursorObject in %1",
+ _validFlagsArr
+];
+
+/*
+vn_mf_bn_dc_target_flag is publicVariable'd when the flag is built
+within the fn_task_pri_capture code
+
+we need to do this otherwise dac cong could be lowering the wrong flag.
+need to use a publicVar, else we'd need to remoteExec constantly as part
+of condition to show... but mike force hold actions are attached to the PLAYER
+which means constantly running remoteExec's whenever a player is looking at ANYTHING.
+*/
+private _isObjectiveFlag = "!(isNil 'vn_mf_bn_dc_target_flag') && (cursorObject == vn_mf_bn_dc_target_flag)";
private _conditionToShow = format [
"(%1 && %2 && %3 && %4)",
@@ -34,23 +52,33 @@ private _conditionToShow = format [
private _conditionToProgress = "true";
private _codeOnStart = {
+ params ["_target", "_caller", "_actionId", "_arguments"];
allPlayers apply {["DacCongCapturingFlag", []] remoteExec ["para_c_fnc_show_notification", _x]};
};
private _codeOnTick = {
+
params ["_target", "_caller", "_actionId", "_arguments", "_progress", "_maxProgress"];
- private _startingFlagHeight = cursorObject getVariable ["currentHeight", flagAnimationPhase cursorObject];
- private _newHeight = _startingFlagHeight * (1 - (_progress / _maxProgress));
- cursorObject setFlagAnimationPhase _newHeight;
+
+ // only run this script 4 times to reduce network bandwith usage
+ if ((_progress mod (_maxProgress / 4 )) == 0) then {
+ // runs globally on all machines!
+ [vn_mf_bn_dc_target_flag, 4] remoteExec ["vn_mf_fnc_ctf_opfor_lower_flag", 0];
+ };
};
+/*
private _codeOnComplete = {
- [cursorObject] remoteExec ["deleteVehicle", 2];
- allPlayers apply {["DacCongCapturedFlag", []] remoteExec ["para_c_fnc_show_notification", _x]};
+ params ["_target", "_caller", "_actionId", "_arguments"];
};
+
private _codeOnInterrupted = {
- cursorObject setVariable ["currentHeight", flagAnimationPhase cursorObject];
+ params ["_target", "_caller", "_actionId", "_arguments"];
};
+*/
+
+private _codeOnComplete = {};
+private _codeOnInterrupted = {};
private _extraArgsArr = [];
-private _actionDurationSeconds = 20;
+private _actionDurationSeconds = 10;
private _actionPriority = 100;
private _actionRemoveOnComplete = false;
private _showWhenUncon = false;
diff --git a/mission/functions/systems/actions/fn_action_reraise_flag.sqf b/mission/functions/systems/actions/fn_action_reraise_flag.sqf
index dbf7d69e..7eb7df1c 100644
--- a/mission/functions/systems/actions/fn_action_reraise_flag.sqf
+++ b/mission/functions/systems/actions/fn_action_reraise_flag.sqf
@@ -4,54 +4,74 @@
Public: No
Description:
- Dac Cong have lowered a mission critical flag.
- Bluefor need to raise it to 100% again.
+ Dac Cong players have lowered a mission critical (player built)
+ flag in a base. Bluefor need to raise it to 100% again.
+
+ WARNING: This is attached to **PLAYERS**, running in **player** locality.
Parameter(s): none
Returns:
Example(s):
- call vn_mf_fnc_action_capture_player;
+ call vn_mf_fnc_action_reraise_flag;
*/
-private _actionText = format ["%1", "Re-Raise The Flag"];
+private _actionText = format ["%1", "Raise Flag"];
private _actionIdleIcon = "custom\holdactions\holdAction_interact_ca.paa";
private _actionProgressIcon = "custom\holdactions\holdAction_interact_ca.paa";
private _isNotOpfor = "side player == west";
private _isInRangeOf = "player distance cursorObject < 5";
-private _isValidObjectType = "typeOf cursorObject in ['vn_flag_usa', 'vn_flag_aus', 'vn_flag_arvn', 'vn_flag_nz']";
-private _isObjectiveFlag = "(flagAnimationPhase cursorObject) != 1";
+private _validFlagsArr = "['vn_flag_usa', 'vn_flag_aus', 'vn_flag_arvn', 'vn_flag_nz']";
+private _isValidObjectType = format [
+ "typeOf cursorObject in %1",
+ _validFlagsArr
+];
+private _isObjectiveFlag = "!(isNil 'vn_mf_bn_dc_target_flag') && (cursorObject == vn_mf_bn_dc_target_flag)";
+private _isFlagLowered = "(flagAnimationPhase cursorObject) != 1";
+// bluefor can raise the flag only if it has been lowered
private _conditionToShow = format [
- "(%1 && %2 && %3 && %4)",
+ "(%1 && %2 && %3 && %4 && %5)",
_isNotOpfor,
_isInRangeOf,
_isValidObjectType,
- _isObjectiveFlag
+ _isObjectiveFlag,
+ _isFlagLowered
];
private _conditionToProgress = "true";
private _codeOnStart = {
+ params ["_target", "_caller", "_actionId", "_arguments"];
allPlayers apply {["BlueforRaisingFlag", []] remoteExec ["para_c_fnc_show_notification", _x]};
};
private _codeOnTick = {
+
params ["_target", "_caller", "_actionId", "_arguments", "_progress", "_maxProgress"];
- private _startingFlagHeight = cursorObject getVariable ["currentHeight", flagAnimationPhase cursorObject];
- private _newHeight = _startingFlagHeight + ((1 - _startingFlagHeight) * (_progress / _maxProgress));
- cursorObject setFlagAnimationPhase _newHeight;
+
+ // only run this script 4 times to reduce network bandwith usage
+ if ((_progress mod (_maxProgress / 4 )) == 0) then {
+ // runs globally on all machines!
+ [vn_mf_bn_dc_target_flag, 4] remoteExec ["vn_mf_fnc_ctf_bluefor_raise_flag", 0];
+ };
};
+
+/*
private _codeOnComplete = {
- cursorObject setVariable ["currentHeight", flagAnimationPhase cursorObject];
- allPlayers apply {["BlueforRaisedFlag", []] remoteExec ["para_c_fnc_show_notification", _x]};
+ params ["_target", "_caller", "_actionId", "_arguments"];
};
+
private _codeOnInterrupted = {
- cursorObject setVariable ["currentHeight", flagAnimationPhase cursorObject];
+ params ["_target", "_caller", "_actionId", "_arguments"];
};
+*/
+
+private _codeOnComplete = {};
+private _codeOnInterrupted = {};
private _extraArgsArr = [flagAnimationPhase cursorObject];
-private _actionDurationSeconds = 20;
+private _actionDurationSeconds = 10;
private _actionPriority = 100;
private _actionRemoveOnComplete = false;
private _showWhenUncon = false;
diff --git a/mission/functions/systems/dac_cong/fn_ctf_bluefor_raise_flag.sqf b/mission/functions/systems/dac_cong/fn_ctf_bluefor_raise_flag.sqf
new file mode 100644
index 00000000..d6ebf781
--- /dev/null
+++ b/mission/functions/systems/dac_cong/fn_ctf_bluefor_raise_flag.sqf
@@ -0,0 +1,33 @@
+/*
+ File: fn_ctf_bluefor_raise_flag.sqf
+ Author: "DJ" Dijksterhuis
+ Public: No
+
+ Description:
+ Raise the flag on clients and server simulateneously.
+
+ Flags raised on server are not visibly raised on client and vice versa.
+
+ So this script has to be executed on every machine.
+
+ Parameter(s):
+ - _target -- flag we'll be raising
+ - _maxProgress -- maximum number of steps to raise the flag height with
+
+ Returns: nothing
+
+ Example(s):
+ [_target, 4] call vn_mf_fnc_ctf_bluefor_raise_flag;
+*/
+
+
+params ["_target", "_maxProgress"];
+
+private _startingFlagHeight = flagAnimationPhase _target;
+private _newHeight = _startingFlagHeight + (1 / _maxProgress);
+
+if (_newHeight >= 1) exitWith {
+ _target setFlagAnimationPhase 1;
+};
+
+_target setFlagAnimationPhase _newHeight;
diff --git a/mission/functions/systems/dac_cong/fn_ctf_opfor_lower_flag.sqf b/mission/functions/systems/dac_cong/fn_ctf_opfor_lower_flag.sqf
new file mode 100644
index 00000000..306ccd49
--- /dev/null
+++ b/mission/functions/systems/dac_cong/fn_ctf_opfor_lower_flag.sqf
@@ -0,0 +1,32 @@
+/*
+ File: fn_ctf_opfor_lower_flag.sqf
+ Author: "DJ" Dijksterhuis
+ Public: No
+
+ Description:
+ Lower the flag on clients and server simulateneously.
+
+ Flags lowered on server are not visibly lowered on client and vice versa.
+
+ So this script has to be executed on every machine.
+
+ Parameter(s):
+ - _target -- flag we'll be raising
+ - _maxProgress -- maximum number of steps to lower the flag height with
+
+ Returns: nothing
+
+ Example(s):
+ [_target, 4] call vn_mf_fnc_ctf_opfor_lower_flag;
+*/
+
+params ["_target", "_maxProgress"];
+
+private _startingFlagHeight = flagAnimationPhase _target;
+private _newHeight = _startingFlagHeight - (1 / _maxProgress);
+
+if (isServer && _newHeight <= 0) exitWith {
+ deleteVehicle _target;
+};
+
+_target setFlagAnimationPhase _newHeight;
diff --git a/mission/functions/tasks/defend/fn_task_defend_counterattack.sqf b/mission/functions/tasks/defend/fn_task_defend_counterattack.sqf
index 9c858993..4761cbe5 100644
--- a/mission/functions/tasks/defend/fn_task_defend_counterattack.sqf
+++ b/mission/functions/tasks/defend/fn_task_defend_counterattack.sqf
@@ -66,10 +66,12 @@ _taskDataStore setVariable ["INIT", {
private _areaSize = markerSize _marker;
// search for candidate FOBs within the zone's area.
- private _base_search_area = [_markerPos, _areaSize select 0, _areaSize select 1, 0, false];
+ private _base_search_area = [_markerPos, vn_mf_bn_s_zone_radius + 100, vn_mf_bn_s_zone_radius + 100, 0, false];
private _candidate_bases_to_attack = para_g_bases inAreaArray _base_search_area apply {
[_x getVariable "para_g_current_supplies", _x]
};
+
+ // base with most supplies is likely the main fob
_candidate_bases_to_attack sort false;
// candidate FOBs exist
@@ -93,7 +95,7 @@ _taskDataStore setVariable ["INIT", {
_tds setVariable ["fob_exists", true];
- // nearest objects might be buggy
+ // candidate flags can only exist within the established fob
private _possibleFlags = nearestObjects [
[_attackPos select 0, _attackPos select 1],
@@ -101,13 +103,27 @@ _taskDataStore setVariable ["INIT", {
para_g_max_base_radius
];
- if (count _possibleFlags > 0) then {
- private _flag = _possibleFlags select 0;
- _tds setVariable ["flag", _flag];
+ // need to check if they are a paradigm built object!
+ private _paraBuiltFlags = _possibleFlags select {not isNull (_x getVariable ["para_g_building", objNull])};
+
+ if (count _paraBuiltFlags > 0) then {
+
+ _taskDataStore setVariable ["flag_exists", true];
+
+ private _flagsWithDistance = _paraBuiltFlags apply {
+ [_x distance2D _attackPos, _x]
+ };
+
+ _flagsWithDistance sort true;
+
+ private _flag_to_attack = (_flagsWithDistance # 0 ) # 1;
+
+ _tds setVariable ["flag", _flag_to_attack];
_tds setVariable ["flag_exists", true];
+
diag_log format [
"Counterattack: Suitable flag discovered: %1",
- getPos _flag
+ getPos _flag_to_attack
];
};
@@ -191,46 +207,45 @@ _taskDataStore setVariable ["prepare_zone", {
// set up the next task(s)
// one of "defend_flag + defend_fob" or "defend_fob" or "defend_zone".
- if (
- (_tds getVariable ["flag_exists", false])
- && (_tds getVariable ["fob_exists", false])
- ) exitWith {
+ // we'll always have one of the "defend_fob" or "defend_zone" tasks active
+ // both need a red circle around the area that needs defending as players
+ // must hold that area to complete the task.
- // used in the players action to check if players are looking at the right flag.
- // we set it now so the flag cannot be lowered during the prepare counterattack phase
- // but can be lowered during the upcoming defned thr flag phase
- (_tds getVariable "flag") setVariable ["canLower", true];
+ [_tds] call (_tds getVariable "_fnc_create_circle_area");
- [_tds] call (_tds getVariable "_fnc_create_circle_area");
+ // set up the next batch of tasks.
+ // doing a series of if-else statements is tidier / more compact
+ private _next_tasks = [];
- [
- "SUCCEEDED",
- [
- ["defend_fob", _tds getVariable "attackPos"],
- ["defend_flag", getPos (_tds getVariable "flag")]
- ]
- ] call _fnc_finishSubtask;
+ if (_tds getVariable ["fob_exists", false]) then {
+ _next_tasks pushBack ["defend_fob", _tds getVariable "attackPos"];
+ } else {
+ _next_tasks pushBack ["defend_zone", _tds getVariable "attackPos"];
};
+ // NOTE -- flag must be built within an established fob
+ // but nested ifs aren't very clean
+ if (_tds getVariable ["flag_exists", false]) then {
+ _next_tasks pushBack ["defend_flag", getPos (_tds getVariable "flag")];
- if (_tds getVariable ["fob_exists", false]) exitWith {
+ /*
+ Set the publicVariable that allows opfor/bluefor to respectively
+ lower/raise the flag as part of the hold action.
- [_tds] call (_tds getVariable "_fnc_create_circle_area");
+ NOTE: public variables are bad.
- [
- "SUCCEEDED",
- [["defend_fob", _tds getVariable "attackPos"]]
- ] call _fnc_finishSubtask;
- };
+ but we we need to pass a variable out of the task's scope and locality.
+ so there is no other option.
- [_tds] call (_tds getVariable "_fnc_create_circle_area");
+ this variable broadcast only happens once -- when we are switching from
+ prepare to the actual defend tasks. so it should not severly impact network
+ performance as we do not frequently rebroadcast.
+ */
+ vn_mf_bn_dc_target_flag = _tds getVariable "flag";
+ publicVariable "vn_mf_bn_dc_target_flag";
+ };
- // no other options left
- // chuck some AI in the zone and hope they bump into players
- [
- "SUCCEEDED",
- [["defend_zone", _tds getVariable "attackPos"]]
- ] call _fnc_finishSubtask;
+ ["SUCCEEDED", _next_tasks] call _fnc_finishSubtask;
}];
/*
@@ -355,17 +370,25 @@ parameters: _taskDataStore (_tds)
_taskDataStore setVariable ["defend_flag", {
params ["_tds"];
private _flag = _tds getVariable "flag";
+
+ // check if the main task has completed
+ // the ctf defend task can only complete once the main defend task is also completed
private _status = [_tds] call (_tds getVariable "_fnc_check_ai_failure_condition");
/*
failure -- flag object has been deleteVehicle'd
occurs when either
- - Dac Cong full lowered the flag through the action
+ - Dac Cong full lowered the flag through the action (deleteVehicle'd)
- the flag has been hammered out of existence (Bluefor tried to be clever)
*/
- if (isNull _flag) exitWith {
+ if (isNull _flag || isNil "vn_mf_bn_dc_target_flag") exitWith {
+
+ // broadcast that the flag no longer exists.
+ vn_mf_bn_dc_target_flag = nil;
+ publicVariable "vn_mf_bn_dc_target_flag";
+
["CounterAttackExtended"] remoteExec ["para_c_fnc_show_notification", 0];
["FAILED"] call _fnc_finishSubtask;
["FAILED"] call _fnc_finishTask;
@@ -394,8 +417,4 @@ _taskDataStore setVariable ["FINISH", {
params ["_tds"];
[_tds getVariable "attackObjective"] call para_s_fnc_ai_obj_finish_objective;
deleteMarker (_tds getVariable ["CircleAreaMarkerName", "activeDefendCircle"]);
-
- if !(isNull (_tds getVariable ["flag", objNull])) then {
- (_tds getVariable "flag") setVariable ["canLower", false];
- };
}];
diff --git a/mission/functions/tasks/primary/fn_task_pri_capture.sqf b/mission/functions/tasks/primary/fn_task_pri_capture.sqf
index af246034..0bd05c3c 100644
--- a/mission/functions/tasks/primary/fn_task_pri_capture.sqf
+++ b/mission/functions/tasks/primary/fn_task_pri_capture.sqf
@@ -112,8 +112,8 @@ _taskDataStore setVariable ["build_fob", {
private _possibleBases = para_g_bases inAreaArray [
getMarkerPos (_taskDataStore getVariable "taskMarker"),
- selectMax (getMarkerSize (_taskDataStore getVariable "taskMarker") apply {abs _x}),
- selectMax (getMarkerSize (_taskDataStore getVariable "taskMarker") apply {abs _x}),
+ selectMax ((getMarkerSize "activeZoneCircle") apply {abs _x}),
+ selectMax ((getMarkerSize "activeZoneCircle") apply {abs _x}),
0
];
@@ -130,44 +130,101 @@ _taskDataStore setVariable ["build_fob", {
_taskDataStore setVariable ["fob", _possibleBases select 0];
_taskDataStore setVariable ["fob_position_2d", [_fobPos3DASL select 0, _fobPos3DASL select 1]];
+
private _nextTasks = [
- ["build_respawn", (_taskDataStore getVariable "fob_position_2d") getPos [50, 90]],
- ["build_flag", (_taskDataStore getVariable "fob_position_2d") getPos [50, 270]]
+ ["build_respawn", (_taskDataStore getVariable "fob_position_2d") getPos [50, 0]],
+ ["build_flag", (_taskDataStore getVariable "fob_position_2d") getPos [50, 90]],
+ ["build_landing_pad", (_taskDataStore getVariable "fob_position_2d") getPos [50, 180]],
+ ["build_rearm_resupply", (_taskDataStore getVariable "fob_position_2d") getPos [50, 270]]
];
+
["SUCCEEDED", _nextTasks] call _fnc_finishSubtask;
};
}];
-_taskDataStore setVariable ["build_respawn", {
- params ["_taskDataStore"];
+_taskDataStore setVariable ["_fnc_have_built_buildings", {
+ params ["_tds", "_types"];
private _candidates = nearestObjects [
- _taskDataStore getVariable "fob_position_2d",
- ["Land_vn_guardhouse_01", "Land_vn_b_trench_bunker_01_01", "Land_vn_hootch_01_01"],
+ _tds getVariable "fob_position_2d",
+ _types,
para_g_max_base_radius
];
- if !(_candidates isEqualTo []) then {
- _taskDataStore setVariable ["flag_built", true];
+ /*
+ need to check if they are a paradigm built object!
+ otherwise the objective disappears in places like MSS leghorn
+ once FOB is built
+
+ the para_g_building variable is a simple object assigned to
+ the actual arma object, housing all the paradigm building variables.
+ */
+
+ private _para_built_object_first_idx = _candidates findIf {not isNull (_x getVariable ["para_g_building", objNull])};
+
+ (_para_built_object_first_idx > -1)
+}];
+
+
+_taskDataStore setVariable ["build_respawn", {
+ params ["_tds"];
+
+ private _building_types = [
+ "Land_vn_guardhouse_01",
+ "Land_vn_b_trench_bunker_01_01",
+ "Land_vn_hootch_01_01"
+ ];
+ private _building_exists = [_tds, _building_types] call (_tds getVariable "_fnc_have_built_buildings");
+
+ if (_building_exists) then {
+ ["SUCCEEDED"] call _fnc_finishSubtask;
+ };
+}];
+
+_taskDataStore setVariable ["build_landing_pad", {
+ params ["_tds"];
+
+ private _building_types = ["Land_vn_b_helipad_01"];
+ private _building_exists = [_tds, _building_types] call (_tds getVariable "_fnc_have_built_buildings");
+
+ if (_building_exists) then {
+ ["SUCCEEDED"] call _fnc_finishSubtask;
+ };
+}];
+
+_taskDataStore setVariable ["build_rearm_repair_refuel", {
+ params ["_tds"];
+
+ private _building_types = [
+ "vn_b_ammobox_supply_07",
+ "vn_b_ammobox_supply_08",
+ "vn_b_ammobox_supply_09",
+ "Land_vn_usaf_fueltank_75_01"
+ ];
+ private _building_exists = [_tds, _building_types] call (_tds getVariable "_fnc_have_built_buildings");
+
+ if (_building_exists) then {
["SUCCEEDED"] call _fnc_finishSubtask;
};
}];
_taskDataStore setVariable ["build_flag", {
- params ["_taskDataStore"];
+ params ["_tds"];
- private _candidates = nearestObjects [
- _taskDataStore getVariable "fob_position_2d",
- ["vn_flag_usa", "vn_flag_aus", "vn_flag_arvn", "vn_flag_nz"],
- para_g_max_base_radius
+ private _building_types = [
+ "vn_flag_usa",
+ "vn_flag_aus",
+ "vn_flag_arvn",
+ "vn_flag_nz"
];
+ private _building_exists = [_tds, _building_types] call (_tds getVariable "_fnc_have_built_buildings");
- if !(_candidates isEqualTo []) then {
- _taskDataStore setVariable ["flag_built", true];
+ if (_building_exists) then {
["SUCCEEDED"] call _fnc_finishSubtask;
};
}];
+
_taskDataStore setVariable ["AFTER_STATES_RUN", {
params ["_taskDataStore"];
From 0a0cdebcd18828871fafa9b59f629f32ee976c9e Mon Sep 17 00:00:00 2001
From: dijksterhuis <11841332+dijksterhuis@users.noreply.github.com>
Date: Fri, 12 Jul 2024 21:32:39 +0100
Subject: [PATCH 02/15] DacCong: Fully functional capture the flag system.
---
mission/config/functions.hpp | 4 +-
.../systems/actions/fn_action_lower_flag.sqf | 14 ++--
.../actions/fn_action_reraise_flag.sqf | 16 ++---
... => fn_ctf_broadcast_notify_immediate.sqf} | 12 +---
.../fn_ctf_handle_flag_height_change.sqf | 71 +++++++++++++++++++
.../dac_cong/fn_ctf_opfor_lower_flag.sqf | 32 ---------
.../defend/fn_task_defend_counterattack.sqf | 33 +++++++--
mission/stringtable.xml | 4 +-
8 files changed, 115 insertions(+), 71 deletions(-)
rename mission/functions/systems/dac_cong/{fn_ctf_bluefor_raise_flag.sqf => fn_ctf_broadcast_notify_immediate.sqf} (66%)
create mode 100644 mission/functions/systems/dac_cong/fn_ctf_handle_flag_height_change.sqf
delete mode 100644 mission/functions/systems/dac_cong/fn_ctf_opfor_lower_flag.sqf
diff --git a/mission/config/functions.hpp b/mission/config/functions.hpp
index 95a7ce75..492280f9 100644
--- a/mission/config/functions.hpp
+++ b/mission/config/functions.hpp
@@ -221,8 +221,8 @@ class CfgFunctions
file = "functions\systems\dac_cong";
class capture_player {};
- class ctf_opfor_lower_flag {};
- class ctf_bluefor_raise_flag {};
+ class ctf_handle_flag_height_change {};
+ class ctf_broadcast_notify_immediate {};
}
//Gameplay director, responsible for main game progression and flow.
diff --git a/mission/functions/systems/actions/fn_action_lower_flag.sqf b/mission/functions/systems/actions/fn_action_lower_flag.sqf
index 28a18c33..f089352b 100644
--- a/mission/functions/systems/actions/fn_action_lower_flag.sqf
+++ b/mission/functions/systems/actions/fn_action_lower_flag.sqf
@@ -22,7 +22,7 @@ private _actionText = format ["%1", "Lower Flag"];
private _actionIdleIcon = "custom\holdactions\holdAction_interact_ca.paa";
private _actionProgressIcon = "custom\holdactions\holdAction_danger_ca.paa";
-private _isOpfor = "side player == east";
+private _isOpfor = "side player isEqualTo east";
private _isInRangeOf = "player distance cursorObject < 5";
private _validFlagsArr = "['vn_flag_usa', 'vn_flag_aus', 'vn_flag_arvn', 'vn_flag_nz']";
private _isValidObjectType = format [
@@ -39,7 +39,7 @@ need to use a publicVar, else we'd need to remoteExec constantly as part
of condition to show... but mike force hold actions are attached to the PLAYER
which means constantly running remoteExec's whenever a player is looking at ANYTHING.
*/
-private _isObjectiveFlag = "!(isNil 'vn_mf_bn_dc_target_flag') && (cursorObject == vn_mf_bn_dc_target_flag)";
+private _isObjectiveFlag = "!(isNil 'vn_mf_bn_dc_target_flag') && (cursorObject isEqualTo vn_mf_bn_dc_target_flag)";
private _conditionToShow = format [
"(%1 && %2 && %3 && %4)",
@@ -53,17 +53,11 @@ private _conditionToProgress = "true";
private _codeOnStart = {
params ["_target", "_caller", "_actionId", "_arguments"];
- allPlayers apply {["DacCongCapturingFlag", []] remoteExec ["para_c_fnc_show_notification", _x]};
+ ["DacCongCapturingFlag"] remoteExec ["vn_mf_fnc_ctf_broadcast_notify_immediate", 2];
};
private _codeOnTick = {
-
params ["_target", "_caller", "_actionId", "_arguments", "_progress", "_maxProgress"];
-
- // only run this script 4 times to reduce network bandwith usage
- if ((_progress mod (_maxProgress / 4 )) == 0) then {
- // runs globally on all machines!
- [vn_mf_bn_dc_target_flag, 4] remoteExec ["vn_mf_fnc_ctf_opfor_lower_flag", 0];
- };
+ [vn_mf_bn_dc_target_flag, _progress, _maxProgress, -1] remoteExec ["vn_mf_fnc_ctf_handle_flag_height_change", 2];
};
/*
private _codeOnComplete = {
diff --git a/mission/functions/systems/actions/fn_action_reraise_flag.sqf b/mission/functions/systems/actions/fn_action_reraise_flag.sqf
index 7eb7df1c..eb215185 100644
--- a/mission/functions/systems/actions/fn_action_reraise_flag.sqf
+++ b/mission/functions/systems/actions/fn_action_reraise_flag.sqf
@@ -21,15 +21,15 @@ private _actionText = format ["%1", "Raise Flag"];
private _actionIdleIcon = "custom\holdactions\holdAction_interact_ca.paa";
private _actionProgressIcon = "custom\holdactions\holdAction_interact_ca.paa";
-private _isNotOpfor = "side player == west";
+private _isNotOpfor = "(side player) isEqualTo west";
private _isInRangeOf = "player distance cursorObject < 5";
private _validFlagsArr = "['vn_flag_usa', 'vn_flag_aus', 'vn_flag_arvn', 'vn_flag_nz']";
private _isValidObjectType = format [
"typeOf cursorObject in %1",
_validFlagsArr
];
-private _isObjectiveFlag = "!(isNil 'vn_mf_bn_dc_target_flag') && (cursorObject == vn_mf_bn_dc_target_flag)";
-private _isFlagLowered = "(flagAnimationPhase cursorObject) != 1";
+private _isObjectiveFlag = "!(isNil 'vn_mf_bn_dc_target_flag') && (cursorObject isEqualTo vn_mf_bn_dc_target_flag)";
+private _isFlagLowered = "((flagAnimationPhase cursorObject) isNotEqualTo 1)";
// bluefor can raise the flag only if it has been lowered
private _conditionToShow = format [
@@ -45,17 +45,11 @@ private _conditionToProgress = "true";
private _codeOnStart = {
params ["_target", "_caller", "_actionId", "_arguments"];
- allPlayers apply {["BlueforRaisingFlag", []] remoteExec ["para_c_fnc_show_notification", _x]};
+ ["BlueforRaisingFlag"] remoteExec ["vn_mf_fnc_ctf_broadcast_notify_immediate", 2];
};
private _codeOnTick = {
-
params ["_target", "_caller", "_actionId", "_arguments", "_progress", "_maxProgress"];
-
- // only run this script 4 times to reduce network bandwith usage
- if ((_progress mod (_maxProgress / 4 )) == 0) then {
- // runs globally on all machines!
- [vn_mf_bn_dc_target_flag, 4] remoteExec ["vn_mf_fnc_ctf_bluefor_raise_flag", 0];
- };
+ [vn_mf_bn_dc_target_flag, _progress, _maxProgress, 1] remoteExec ["vn_mf_fnc_ctf_handle_flag_height_change", 2];
};
/*
diff --git a/mission/functions/systems/dac_cong/fn_ctf_bluefor_raise_flag.sqf b/mission/functions/systems/dac_cong/fn_ctf_broadcast_notify_immediate.sqf
similarity index 66%
rename from mission/functions/systems/dac_cong/fn_ctf_bluefor_raise_flag.sqf
rename to mission/functions/systems/dac_cong/fn_ctf_broadcast_notify_immediate.sqf
index d6ebf781..db4cbba0 100644
--- a/mission/functions/systems/dac_cong/fn_ctf_bluefor_raise_flag.sqf
+++ b/mission/functions/systems/dac_cong/fn_ctf_broadcast_notify_immediate.sqf
@@ -20,14 +20,6 @@
[_target, 4] call vn_mf_fnc_ctf_bluefor_raise_flag;
*/
+params ["_notificationClass"];
-params ["_target", "_maxProgress"];
-
-private _startingFlagHeight = flagAnimationPhase _target;
-private _newHeight = _startingFlagHeight + (1 / _maxProgress);
-
-if (_newHeight >= 1) exitWith {
- _target setFlagAnimationPhase 1;
-};
-
-_target setFlagAnimationPhase _newHeight;
+[_notificationClass, []] remoteExec ["para_c_fnc_show_notification", -2];
\ No newline at end of file
diff --git a/mission/functions/systems/dac_cong/fn_ctf_handle_flag_height_change.sqf b/mission/functions/systems/dac_cong/fn_ctf_handle_flag_height_change.sqf
new file mode 100644
index 00000000..eeb2ba3f
--- /dev/null
+++ b/mission/functions/systems/dac_cong/fn_ctf_handle_flag_height_change.sqf
@@ -0,0 +1,71 @@
+/*
+ File: fn_ctf_opfor_lower_flag.sqf
+ Author: "DJ" Dijksterhuis
+ Public: No
+
+ Description:
+ Lower the flag on clients and server simulateneously.
+
+ Flags lowered on server are not visibly lowered on client and vice versa.
+
+ So this script has to be executed on every machine.
+
+ Parameter(s):
+ - _target -- flag we'll be raising
+ - _maxProgress -- maximum number of steps to lower the flag height with
+
+ Returns: nothing
+
+ Example(s):
+ [_target, 4] call vn_mf_fnc_ctf_opfor_lower_flag;
+*/
+
+params ["_target", "_progress", "_maxProgress", "_direction"];
+
+private _tickRate = 3;
+
+// only change things every 3 holdAction ticks to ensure we're not spamming clients
+// with a massive amount of changes (always a total of 24 ticks)
+if ((_progress mod _tickRate ) isEqualTo 0) then {
+
+ private _startingFlagHeight = flagAnimationPhase _target;
+ private _newHeight = _startingFlagHeight;
+
+ // -1 ---> dac cong lowering the flag
+ // +1 ---> bluefor raising the flag
+
+ if (_direction isEqualTo -1) then {
+
+ _newHeight = _startingFlagHeight - (_tickRate / _maxProgress);
+
+ if (_newHeight <= 0) exitWith {
+
+ // global command, no need to remoteExec
+ deleteVehicle _target;
+
+ // broadcast notification
+ ["DacCongCapturedFlag", []] remoteExec ["para_c_fnc_show_notification", -2];
+
+ // clear the JIP queue for flag height.
+ remoteExec ["", "JIP_DACCONG_CTF_FLAG_HEIGHT"];
+ };
+
+ } else {
+
+ _newHeight = _startingFlagHeight + (_tickRate / _maxProgress);
+
+ if (_newHeight >= 1) exitWith {
+
+ // broadcast the the new flag height globally with JIP ID (includes server)
+ [_target, 1] remoteExec ["setFlagAnimationPhase", 0, "JIP_DACCONG_CTF_FLAG_HEIGHT"];
+
+ // broadcast notification out to all players
+ ["BlueforRaisedFlag", []] remoteExec ["para_c_fnc_show_notification", -2];
+
+ };
+ };
+ // set the new height globally via JIP queue so new players also see the flag at the right height
+ // includes changing it on the server
+ [_target, _newHeight] remoteExec ["setFlagAnimationPhase", 0, "JIP_DACCONG_CTF_FLAG_HEIGHT"];
+};
+
diff --git a/mission/functions/systems/dac_cong/fn_ctf_opfor_lower_flag.sqf b/mission/functions/systems/dac_cong/fn_ctf_opfor_lower_flag.sqf
deleted file mode 100644
index 306ccd49..00000000
--- a/mission/functions/systems/dac_cong/fn_ctf_opfor_lower_flag.sqf
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- File: fn_ctf_opfor_lower_flag.sqf
- Author: "DJ" Dijksterhuis
- Public: No
-
- Description:
- Lower the flag on clients and server simulateneously.
-
- Flags lowered on server are not visibly lowered on client and vice versa.
-
- So this script has to be executed on every machine.
-
- Parameter(s):
- - _target -- flag we'll be raising
- - _maxProgress -- maximum number of steps to lower the flag height with
-
- Returns: nothing
-
- Example(s):
- [_target, 4] call vn_mf_fnc_ctf_opfor_lower_flag;
-*/
-
-params ["_target", "_maxProgress"];
-
-private _startingFlagHeight = flagAnimationPhase _target;
-private _newHeight = _startingFlagHeight - (1 / _maxProgress);
-
-if (isServer && _newHeight <= 0) exitWith {
- deleteVehicle _target;
-};
-
-_target setFlagAnimationPhase _newHeight;
diff --git a/mission/functions/tasks/defend/fn_task_defend_counterattack.sqf b/mission/functions/tasks/defend/fn_task_defend_counterattack.sqf
index 4761cbe5..fba61e19 100644
--- a/mission/functions/tasks/defend/fn_task_defend_counterattack.sqf
+++ b/mission/functions/tasks/defend/fn_task_defend_counterattack.sqf
@@ -242,7 +242,12 @@ _taskDataStore setVariable ["prepare_zone", {
*/
vn_mf_bn_dc_target_flag = _tds getVariable "flag";
publicVariable "vn_mf_bn_dc_target_flag";
-
+ } else {
+ // if no flag, extend the counterattack timer by 15 minutes.
+ // this is to encourage people to build flags instead of just
+ // meta-ing out of the CTF system with no penalty.
+ private _dur = (_tds getVariable ["holdDuration", 60 * 30]);
+ _tds setVariable ["holdDuration", _dur + (15 * 60)];
};
["SUCCEEDED", _next_tasks] call _fnc_finishSubtask;
@@ -317,6 +322,21 @@ _taskDataStore setVariable ["_fnc_check_ai_failure_condition", {
}];
+/*
+remove all the network'd variables and JIP queue ID for any flags.
+
+parameters: None
+*/
+_taskDataStore setVariable ["_fnc_remove_flag_network_vars", {
+ // broadcast that the flag no longer exists.
+ vn_mf_bn_dc_target_flag = nil;
+ publicVariable "vn_mf_bn_dc_target_flag";
+
+ // clear the JIP queue for flag height, not necessary anymore
+ remoteExec ["", "JIP_DACCONG_CTF_FLAG_HEIGHT"];
+}];
+
+
/*
no one built a FOB, so AI are just going to move to the centre of the zone
@@ -381,13 +401,12 @@ _taskDataStore setVariable ["defend_flag", {
occurs when either
- Dac Cong full lowered the flag through the action (deleteVehicle'd)
- the flag has been hammered out of existence (Bluefor tried to be clever)
+ - a zeus has deleted the flag (badAdmin)
*/
if (isNull _flag || isNil "vn_mf_bn_dc_target_flag") exitWith {
- // broadcast that the flag no longer exists.
- vn_mf_bn_dc_target_flag = nil;
- publicVariable "vn_mf_bn_dc_target_flag";
+ call (_tds getVariable ["_fnc_remove_flag_network_vars", {}]);
["CounterAttackExtended"] remoteExec ["para_c_fnc_show_notification", 0];
["FAILED"] call _fnc_finishSubtask;
@@ -398,6 +417,9 @@ _taskDataStore setVariable ["defend_flag", {
// (30 minutes passed or AI objective has been wiped out)
if (_status == "SUCCESS") exitWith {
+
+ call (_tds getVariable ["_fnc_remove_flag_network_vars", {}]);
+
_tds setVariable ["flagDefended", true];
["SUCCEEDED"] call _fnc_finishSubtask;
};
@@ -417,4 +439,7 @@ _taskDataStore setVariable ["FINISH", {
params ["_tds"];
[_tds getVariable "attackObjective"] call para_s_fnc_ai_obj_finish_objective;
deleteMarker (_tds getVariable ["CircleAreaMarkerName", "activeDefendCircle"]);
+
+ // do this yet again just in case someone tries to complete tasks via commands
+ call (_tds getVariable ["_fnc_remove_flag_network_vars", {}]);
}];
diff --git a/mission/stringtable.xml b/mission/stringtable.xml
index 3af213fc..fec96594 100644
--- a/mission/stringtable.xml
+++ b/mission/stringtable.xml
@@ -729,8 +729,8 @@
The enemy counter-attack was successful. Zone %1 has been lost.
- Enemy counter-attack is succeeding. Timer extended!
- Enemy counter-attack is succeeding. Timer extended!
+ Enemy counter-attack succeeded. Another wave is incoming!
+ Enemy counter-attack succeeded. Another wave is incoming!
No sandbags in inventory
From e3b98dc80e27fc2fa58684eb66fb8013ee37d418 Mon Sep 17 00:00:00 2001
From: dijksterhuis <11841332+dijksterhuis@users.noreply.github.com>
Date: Sat, 10 Aug 2024 17:57:13 +0100
Subject: [PATCH 03/15] DacCong: CTF: Reduce time for defense phase if a flag
exists.
---
.../functions/tasks/defend/fn_task_defend_counterattack.sqf | 3 +++
1 file changed, 3 insertions(+)
diff --git a/mission/functions/tasks/defend/fn_task_defend_counterattack.sqf b/mission/functions/tasks/defend/fn_task_defend_counterattack.sqf
index d2db51c8..e3252818 100644
--- a/mission/functions/tasks/defend/fn_task_defend_counterattack.sqf
+++ b/mission/functions/tasks/defend/fn_task_defend_counterattack.sqf
@@ -162,6 +162,9 @@ _taskDataStore setVariable ["INIT", {
if (count _paraBuiltFlags > 0) then {
_taskDataStore setVariable ["flag_exists", true];
+ // shorten the counterattack duration
+ // if this is post server restart this value should get overwritten.
+ _taskDataStore setVariable ["holdDuration", 30 * 60];
private _flagsWithDistance = _paraBuiltFlags apply {
[_x distance2D _attackPos, _x]
From f145dbc15863c491baac48b47cb247a5a3566d95 Mon Sep 17 00:00:00 2001
From: dijksterhuis <11841332+dijksterhuis@users.noreply.github.com>
Date: Sat, 10 Aug 2024 18:04:23 +0100
Subject: [PATCH 04/15] DacCong: CTF: Increase default counterattack time
(without a flag built).
---
mission/functions/tasks/defend/fn_task_defend_counterattack.sqf | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/mission/functions/tasks/defend/fn_task_defend_counterattack.sqf b/mission/functions/tasks/defend/fn_task_defend_counterattack.sqf
index 8369064f..5468d521 100644
--- a/mission/functions/tasks/defend/fn_task_defend_counterattack.sqf
+++ b/mission/functions/tasks/defend/fn_task_defend_counterattack.sqf
@@ -25,7 +25,7 @@ params ["_taskDataStore"];
/*
Constants
*/
-_taskDataStore setVariable ["holdDuration", 30 * 60];
+_taskDataStore setVariable ["holdDuration", 45 * 60];
_taskDataStore setVariable ["failureDuration", 5 * 60];
// get the counterattack time remaining for this specific zone
From 1e6883f88d13853a81d51bc3b10dd167282fdb5f Mon Sep 17 00:00:00 2001
From: dijksterhuis <11841332+dijksterhuis@users.noreply.github.com>
Date: Sat, 10 Aug 2024 18:07:43 +0100
Subject: [PATCH 05/15] Tasks: CounterAttack: Make timer reduction due to built
flag more robust.
---
.../tasks/defend/fn_task_defend_counterattack.sqf | 15 ++++++++++++---
1 file changed, 12 insertions(+), 3 deletions(-)
diff --git a/mission/functions/tasks/defend/fn_task_defend_counterattack.sqf b/mission/functions/tasks/defend/fn_task_defend_counterattack.sqf
index 5468d521..b1274300 100644
--- a/mission/functions/tasks/defend/fn_task_defend_counterattack.sqf
+++ b/mission/functions/tasks/defend/fn_task_defend_counterattack.sqf
@@ -26,6 +26,7 @@ params ["_taskDataStore"];
Constants
*/
_taskDataStore setVariable ["holdDuration", 45 * 60];
+_taskDataStore setVariable ["flagTimerReduction", 15 * 60];
_taskDataStore setVariable ["failureDuration", 5 * 60];
// get the counterattack time remaining for this specific zone
@@ -162,9 +163,17 @@ _taskDataStore setVariable ["INIT", {
if (count _paraBuiltFlags > 0) then {
_taskDataStore setVariable ["flag_exists", true];
- // shorten the counterattack duration
- // if this is post server restart this value should get overwritten.
- _taskDataStore setVariable ["holdDuration", 30 * 60];
+
+ /*
+ shorten the counterattack duration by 15 minutes
+ if this is post server restart this value should get overwritten when
+ we run `_taskDataStore getVariable "fnc_update_hold_time")` below
+ */
+
+ private _holdDuration = _taskDataStore getVariable "holdDuration";
+ private _timerReduction = _taskDataStore getVariable "flagTimerReduction";
+
+ _taskDataStore setVariable ["holdDuration", _holdDuration - _timerReduction];
private _flagsWithDistance = _paraBuiltFlags apply {
[_x distance2D _attackPos, _x]
From 6c5a999de3be85d08c2c722d71ebb6216a107b53 Mon Sep 17 00:00:00 2001
From: dijksterhuis <11841332+dijksterhuis@users.noreply.github.com>
Date: Sat, 10 Aug 2024 18:43:36 +0100
Subject: [PATCH 06/15] Fixup: Leftover line from merge conflict.
---
mission/functions/tasks/defend/fn_task_defend_counterattack.sqf | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/mission/functions/tasks/defend/fn_task_defend_counterattack.sqf b/mission/functions/tasks/defend/fn_task_defend_counterattack.sqf
index b1274300..5932a4ab 100644
--- a/mission/functions/tasks/defend/fn_task_defend_counterattack.sqf
+++ b/mission/functions/tasks/defend/fn_task_defend_counterattack.sqf
@@ -546,5 +546,5 @@ _taskDataStore setVariable ["FINISH", {
// or the task was forced through with a command
// save current time remaining to the profile DB
[_tds] call (_taskDataStore getVariable "fnc_reset_db_time_remain");
->>>>>>> dj-development
+
}];
From 735f65e76da4574f374eae4eff4421c11e576033 Mon Sep 17 00:00:00 2001
From: dijksterhuis <11841332+dijksterhuis@users.noreply.github.com>
Date: Sun, 11 Aug 2024 00:06:40 +0100
Subject: [PATCH 07/15] DacCong: CTF: Update documentation headers.
---
.../fn_ctf_broadcast_notify_immediate.sqf | 25 +++---
.../fn_ctf_handle_flag_height_change.sqf | 83 ++++++++++---------
2 files changed, 53 insertions(+), 55 deletions(-)
diff --git a/mission/functions/systems/dac_cong/fn_ctf_broadcast_notify_immediate.sqf b/mission/functions/systems/dac_cong/fn_ctf_broadcast_notify_immediate.sqf
index db4cbba0..a46fdc88 100644
--- a/mission/functions/systems/dac_cong/fn_ctf_broadcast_notify_immediate.sqf
+++ b/mission/functions/systems/dac_cong/fn_ctf_broadcast_notify_immediate.sqf
@@ -1,23 +1,18 @@
/*
- File: fn_ctf_bluefor_raise_flag.sqf
- Author: "DJ" Dijksterhuis
- Public: No
+ File: fn_ctf_broadcast_notify_immediate.sqf
+ Author: "DJ" Dijksterhuis
+ Public: No
- Description:
- Raise the flag on clients and server simulateneously.
+ Description:
+ Display a notification for all players (not server).
- Flags raised on server are not visibly raised on client and vice versa.
+ Parameter(s):
+ - _notificationClass -- class name of the notification to show [STRING]
- So this script has to be executed on every machine.
+ Returns: nothing
- Parameter(s):
- - _target -- flag we'll be raising
- - _maxProgress -- maximum number of steps to raise the flag height with
-
- Returns: nothing
-
- Example(s):
- [_target, 4] call vn_mf_fnc_ctf_bluefor_raise_flag;
+ Example(s):
+ ["FireInTheHole"] call vn_mf_fnc_ctf_broadcast_notify_immediate;
*/
params ["_notificationClass"];
diff --git a/mission/functions/systems/dac_cong/fn_ctf_handle_flag_height_change.sqf b/mission/functions/systems/dac_cong/fn_ctf_handle_flag_height_change.sqf
index eeb2ba3f..c88bf361 100644
--- a/mission/functions/systems/dac_cong/fn_ctf_handle_flag_height_change.sqf
+++ b/mission/functions/systems/dac_cong/fn_ctf_handle_flag_height_change.sqf
@@ -1,23 +1,25 @@
/*
- File: fn_ctf_opfor_lower_flag.sqf
- Author: "DJ" Dijksterhuis
- Public: No
+ File: fn_ctf_handle_flag_height_change.sqf
+ Author: "DJ" Dijksterhuis
+ Public: No
- Description:
- Lower the flag on clients and server simulateneously.
+ Description:
+ Handle lowering/raising the flag server side.
- Flags lowered on server are not visibly lowered on client and vice versa.
+ Parameter(s):
+ _target -- flag we'll be raising / lowering
+ _progress -- how many steps
+ _maxProgress -- total steps
+ _direction -- -1/+1 for lower/raise
- So this script has to be executed on every machine.
+ Returns: nothing
- Parameter(s):
- - _target -- flag we'll be raising
- - _maxProgress -- maximum number of steps to lower the flag height with
+ Example(s):
+ // lower
+ [_target, 4, 24, -1] call vn_mf_fnc_ctf_handle_flag_height_change;
- Returns: nothing
-
- Example(s):
- [_target, 4] call vn_mf_fnc_ctf_opfor_lower_flag;
+ // raise
+ [_target, 4, 24, 1] call vn_mf_fnc_ctf_handle_flag_height_change;
*/
params ["_target", "_progress", "_maxProgress", "_direction"];
@@ -28,44 +30,45 @@ private _tickRate = 3;
// with a massive amount of changes (always a total of 24 ticks)
if ((_progress mod _tickRate ) isEqualTo 0) then {
- private _startingFlagHeight = flagAnimationPhase _target;
- private _newHeight = _startingFlagHeight;
+ private _startingFlagHeight = flagAnimationPhase _target;
+ private _newHeight = _startingFlagHeight;
- // -1 ---> dac cong lowering the flag
- // +1 ---> bluefor raising the flag
+ // -1 ---> dac cong lowering the flag
+ // +1 ---> bluefor raising the flag
- if (_direction isEqualTo -1) then {
+ if (_direction isEqualTo -1) then {
- _newHeight = _startingFlagHeight - (_tickRate / _maxProgress);
+ _newHeight = _startingFlagHeight - (_tickRate / _maxProgress);
- if (_newHeight <= 0) exitWith {
+ if (_newHeight <= 0) exitWith {
- // global command, no need to remoteExec
- deleteVehicle _target;
+ // global command, no need to remoteExec
+ deleteVehicle _target;
- // broadcast notification
- ["DacCongCapturedFlag", []] remoteExec ["para_c_fnc_show_notification", -2];
+ // broadcast notification
+ ["DacCongCapturedFlag", []] remoteExec ["para_c_fnc_show_notification", -2];
- // clear the JIP queue for flag height.
- remoteExec ["", "JIP_DACCONG_CTF_FLAG_HEIGHT"];
- };
+ // clear the JIP queue for flag height.
+ remoteExec ["", "JIP_DACCONG_CTF_FLAG_HEIGHT"];
+ };
- } else {
+ } else {
- _newHeight = _startingFlagHeight + (_tickRate / _maxProgress);
+ _newHeight = _startingFlagHeight + (_tickRate / _maxProgress);
- if (_newHeight >= 1) exitWith {
+ if (_newHeight >= 1) exitWith {
- // broadcast the the new flag height globally with JIP ID (includes server)
- [_target, 1] remoteExec ["setFlagAnimationPhase", 0, "JIP_DACCONG_CTF_FLAG_HEIGHT"];
+ // broadcast the the new flag height globally with JIP ID (includes server)
+ [_target, 1] remoteExec ["setFlagAnimationPhase", 0, "JIP_DACCONG_CTF_FLAG_HEIGHT"];
- // broadcast notification out to all players
- ["BlueforRaisedFlag", []] remoteExec ["para_c_fnc_show_notification", -2];
+ // broadcast notification out to all players
+ ["BlueforRaisedFlag", []] remoteExec ["para_c_fnc_show_notification", -2];
- };
- };
- // set the new height globally via JIP queue so new players also see the flag at the right height
- // includes changing it on the server
- [_target, _newHeight] remoteExec ["setFlagAnimationPhase", 0, "JIP_DACCONG_CTF_FLAG_HEIGHT"];
+ };
+ };
+ // set the new height globally via JIP queue so new players also see the flag at the right height
+ // includes changing it on the server
+ [_target, _newHeight] remoteExec ["setFlagAnimationPhase", 0, "JIP_DACCONG_CTF_FLAG_HEIGHT"];
};
+nil
\ No newline at end of file
From 268848c025c204d7610bba7894258b4b6656a9e8 Mon Sep 17 00:00:00 2001
From: dijksterhuis <11841332+dijksterhuis@users.noreply.github.com>
Date: Sun, 11 Aug 2024 01:28:08 +0100
Subject: [PATCH 08/15] DacCong: CTF: Add more docs for the notification
broadcast script.
---
.../fn_ctf_broadcast_notify_immediate.sqf | 18 ++++++++++++++++--
1 file changed, 16 insertions(+), 2 deletions(-)
diff --git a/mission/functions/systems/dac_cong/fn_ctf_broadcast_notify_immediate.sqf b/mission/functions/systems/dac_cong/fn_ctf_broadcast_notify_immediate.sqf
index a46fdc88..33d0d6d7 100644
--- a/mission/functions/systems/dac_cong/fn_ctf_broadcast_notify_immediate.sqf
+++ b/mission/functions/systems/dac_cong/fn_ctf_broadcast_notify_immediate.sqf
@@ -4,7 +4,18 @@
Public: No
Description:
- Display a notification for all players (not server).
+ Display a notification for all players via a remoteExec callback.
+
+ Used to perform a global notification broadcast out to all players
+ from a specific player locality.
+
+ player -> server -> all players
+
+ Means the specific player client isn't sending out remoteExec instructions to
+ all connected players, hopefully mitigating some desync/latency issues and enabling
+ use to implement a CfgRemoteExec later on.
+
+ TODO: Refactor this out to core/helpers?
Parameter(s):
- _notificationClass -- class name of the notification to show [STRING]
@@ -12,7 +23,10 @@
Returns: nothing
Example(s):
- ["FireInTheHole"] call vn_mf_fnc_ctf_broadcast_notify_immediate;
+ // from player locality
+ // remote execs to this script from server
+ // which then remoteExecs a notification for all players
+ ["FireInTheHole"] remoteExec ["vn_mf_fnc_ctf_broadcast_notify_immediate", 2];
*/
params ["_notificationClass"];
From 32a6bbad5ba9dbf92f8dfeadcf179a82623da485 Mon Sep 17 00:00:00 2001
From: dijksterhuis <11841332+dijksterhuis@users.noreply.github.com>
Date: Sun, 11 Aug 2024 01:48:32 +0100
Subject: [PATCH 09/15] DacCong: CTF: Fixup timer; reduce base search radius;
clean up nested ifs.
---
.../defend/fn_task_defend_counterattack.sqf | 59 ++++++++++---------
1 file changed, 30 insertions(+), 29 deletions(-)
diff --git a/mission/functions/tasks/defend/fn_task_defend_counterattack.sqf b/mission/functions/tasks/defend/fn_task_defend_counterattack.sqf
index 82aea7be..f427dc82 100644
--- a/mission/functions/tasks/defend/fn_task_defend_counterattack.sqf
+++ b/mission/functions/tasks/defend/fn_task_defend_counterattack.sqf
@@ -110,7 +110,7 @@ _taskDataStore setVariable ["INIT", {
private _areaSize = markerSize _marker;
// search for candidate FOBs within the zone's area.
- private _base_search_area = [_markerPos, vn_mf_bn_s_zone_radius + 100, vn_mf_bn_s_zone_radius + 100, 0, false];
+ private _base_search_area = [_markerPos, vn_mf_bn_s_zone_radius, vn_mf_bn_s_zone_radius, 0, false];
private _candidate_bases_to_attack = para_g_bases inAreaArray _base_search_area apply {
[_x getVariable "para_g_current_supplies", _x]
};
@@ -278,40 +278,41 @@ _taskDataStore setVariable ["prepare_zone", {
[_tds] call (_tds getVariable "_fnc_create_circle_area");
// set up the next batch of tasks.
- // doing a series of if-else statements is tidier / more compact
+ // doing a series of switch-case pushback statements is tidier / more compact
private _next_tasks = [];
- if (_tds getVariable ["fob_exists", false]) then {
- _next_tasks pushBack ["defend_fob", _tds getVariable "attackPos"];
- } else {
- _next_tasks pushBack ["defend_zone", _tds getVariable "attackPos"];
- };
- // NOTE -- flag must be built within an established fob
- // but nested ifs aren't very clean
- if (_tds getVariable ["flag_exists", false]) then {
- _next_tasks pushBack ["defend_flag", getPos (_tds getVariable "flag")];
+ private _fob_exists = _tds getVariable ["fob_exists", false];
+ private _flag_exists = _tds getVariable ["flag_exists", false];
- /*
- Set the publicVariable that allows opfor/bluefor to respectively
- lower/raise the flag as part of the hold action.
+ switch (true) do {
+ // NOTE -- flag must be built within an established fob
+ case (_fob_exists && _flag_exists) : {
+ /*
+ Set the publicVariable that allows opfor/bluefor to respectively
+ lower/raise the flag as part of the hold action.
- NOTE: public variables are bad.
+ do this as late as possible to ensure opfor cannot lower the flag
+ before the counterattack timer actually starts.
- but we we need to pass a variable out of the task's scope and locality.
- so there is no other option.
+ NOTE: public variables are bad. but we we need to pass a variable
+ out of the task's scope and locality so there is no other option.
- this variable broadcast only happens once -- when we are switching from
- prepare to the actual defend tasks. so it should not severly impact network
- performance as we do not frequently rebroadcast.
- */
- vn_mf_bn_dc_target_flag = _tds getVariable "flag";
- publicVariable "vn_mf_bn_dc_target_flag";
- } else {
- // if no flag, extend the counterattack timer by 15 minutes.
- // this is to encourage people to build flags instead of just
- // meta-ing out of the CTF system with no penalty.
- private _dur = (_tds getVariable ["holdDuration", 60 * 30]);
- _tds setVariable ["holdDuration", _dur + (15 * 60)];
+ this variable broadcast only happens once -- when we are switching from
+ prepare to the actual defend tasks. so it should not severly impact network
+ performance as we do not frequently rebroadcast.
+ */
+ vn_mf_bn_dc_target_flag = _tds getVariable "flag";
+ publicVariable "vn_mf_bn_dc_target_flag";
+
+ _next_tasks pushBack ["defend_flag", getPos (_tds getVariable "flag")];
+ _next_tasks pushBack ["defend_fob", _tds getVariable "attackPos"];
+ };
+ case (_fob_exists) : {
+ _next_tasks pushBack ["defend_fob", _tds getVariable "attackPos"];
+ };
+ default {
+ _next_tasks pushBack ["defend_zone", _tds getVariable "attackPos"];
+ };
};
["SUCCEEDED", _next_tasks] call _fnc_finishSubtask;
From 1e4c7fed8d7f2d4faa8392d7a1ccc4f4a0eaa005 Mon Sep 17 00:00:00 2001
From: dijksterhuis <11841332+dijksterhuis@users.noreply.github.com>
Date: Sun, 11 Aug 2024 01:49:38 +0100
Subject: [PATCH 10/15] Tasks: CounterAttack: Spaces to Tabs.
---
.../functions/tasks/defend/fn_task_defend_counterattack.sqf | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/mission/functions/tasks/defend/fn_task_defend_counterattack.sqf b/mission/functions/tasks/defend/fn_task_defend_counterattack.sqf
index f427dc82..40a6dce6 100644
--- a/mission/functions/tasks/defend/fn_task_defend_counterattack.sqf
+++ b/mission/functions/tasks/defend/fn_task_defend_counterattack.sqf
@@ -402,8 +402,8 @@ _taskDataStore setVariable ["_fnc_remove_flag_network_vars", {
vn_mf_bn_dc_target_flag = nil;
publicVariable "vn_mf_bn_dc_target_flag";
- // clear the JIP queue for flag height, not necessary anymore
- remoteExec ["", "JIP_DACCONG_CTF_FLAG_HEIGHT"];
+ // clear the JIP queue for flag height, not necessary anymore
+ remoteExec ["", "JIP_DACCONG_CTF_FLAG_HEIGHT"];
}];
From 66b2105d20bb79762472ac682dd3a548b2aee6e4 Mon Sep 17 00:00:00 2001
From: dijksterhuis <11841332+dijksterhuis@users.noreply.github.com>
Date: Sun, 11 Aug 2024 01:52:01 +0100
Subject: [PATCH 11/15] Tasks: CounterAttack: Update info text.
---
mission/config/subconfigs/tasks/defend/tasks.hpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/mission/config/subconfigs/tasks/defend/tasks.hpp b/mission/config/subconfigs/tasks/defend/tasks.hpp
index 0999074f..edb6f123 100644
--- a/mission/config/subconfigs/tasks/defend/tasks.hpp
+++ b/mission/config/subconfigs/tasks/defend/tasks.hpp
@@ -28,13 +28,13 @@ class defend_counterattack : task
class defend_zone
{
taskname = "Hold the Zone";
- taskdesc = "Hold the zone for 30 minutes, or until hostiles are eliminated.";
+ taskdesc = "Defend the Zone from enemy counterattack.";
};
class defend_fob
{
taskname = "Defend the FOB";
- taskdesc = "Defend the FOB from counterattack for 30 minutes, or hostile forces are eliminated.";
+ taskdesc = "Defend the FOB from enemy counterattack.";
};
class defend_flag
From 16de8b3430097fceb995ddd58f582aa0399cbbde Mon Sep 17 00:00:00 2001
From: dijksterhuis <11841332+dijksterhuis@users.noreply.github.com>
Date: Thu, 15 Aug 2024 19:31:08 +0100
Subject: [PATCH 12/15] DacCongCTF: Simplify and cleanup notification titles.
---
mission/config/notifications.hpp | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/mission/config/notifications.hpp b/mission/config/notifications.hpp
index b4c1e784..09ff96c5 100644
--- a/mission/config/notifications.hpp
+++ b/mission/config/notifications.hpp
@@ -379,7 +379,7 @@ class CfgNotifications
class DacCongCapturedFlag
{
- title = "Protect The Flag!";
+ title = "Flag Captured!";
description = "You are failure! Dac Cong have captured the flag!";
priority = 6;
color[] = {1,0,0,1};
@@ -388,7 +388,7 @@ class CfgNotifications
class BlueforRaisingFlag
{
- title = "Raise The Flag!";
+ title = "Raising Flag!";
description = "Bluefor are raising the flag.";
priority = 6;
color[] = {0.2,0.3,1,1};
@@ -397,7 +397,7 @@ class CfgNotifications
class BlueforRaisedFlag
{
- title = "Raise The Flag!";
+ title = "Raised Flag!";
description = "Bluefor have raised the flag!";
priority = 6;
color[] = {0.2,0.3,1,1};
From ac34e1375dd289947afc2d4d5a88fdf1df9e42e0 Mon Sep 17 00:00:00 2001
From: dijksterhuis <11841332+dijksterhuis@users.noreply.github.com>
Date: Thu, 15 Aug 2024 19:31:51 +0100
Subject: [PATCH 13/15] DacCongCTF: CounterAttacK: Tweak some settings (attack
duration and base search radius)
- Time for counterattack is now 40 minutes
- Unless a flag is present, which changes it to 30 minutes
- base search radius but back to the zone size.
---
.../defend/fn_task_defend_counterattack.sqf | 17 ++++++++---------
1 file changed, 8 insertions(+), 9 deletions(-)
diff --git a/mission/functions/tasks/defend/fn_task_defend_counterattack.sqf b/mission/functions/tasks/defend/fn_task_defend_counterattack.sqf
index 40a6dce6..101b9ae3 100644
--- a/mission/functions/tasks/defend/fn_task_defend_counterattack.sqf
+++ b/mission/functions/tasks/defend/fn_task_defend_counterattack.sqf
@@ -25,8 +25,8 @@ params ["_taskDataStore"];
/*
Constants
*/
-_taskDataStore setVariable ["holdDuration", 45 * 60];
-_taskDataStore setVariable ["flagTimerReduction", 15 * 60];
+_taskDataStore setVariable ["holdDuration", 40 * 60];
+_taskDataStore setVariable ["flagTimerReduction", 10 * 60];
_taskDataStore setVariable ["failureDuration", 5 * 60];
// get the counterattack time remaining for this specific zone
@@ -46,7 +46,11 @@ _taskDataStore setVariable ["fnc_update_hold_time", {
// update hold duration. if not previously set the counterattack
// will use the default holdDuration value defined above.
if (_holdTimeRemaining >= 0) then {
- diag_log "DEBUG: Updating current zone's counterattack time remaining from profile DB.";
+ diag_log format [
+ "DEBUG: Updating current zone's counterattack time remaining from profile DB: timeS=%1 timeM=%2",
+ _holdTimeRemaining,
+ _holdTimeRemaining / 60
+ ];
_tds setVariable ["holdDuration", _holdTimeRemaining];
};
}];
@@ -85,11 +89,6 @@ _taskDataStore setVariable ["INIT", {
private _marker = _tds getVariable "taskMarker";
private _markerPos = getMarkerPos _marker;
- /*
- // present in SGD Mike Force, but not used anywhere.
- private _hqs = (localNamespace getVariable ["sites_hq", []]) inAreaArray _marker;
- */
-
private _prepTime = _tds getVariable ["prepTime", 180];
_marker setMarkerColor "ColorYellow";
@@ -110,7 +109,7 @@ _taskDataStore setVariable ["INIT", {
private _areaSize = markerSize _marker;
// search for candidate FOBs within the zone's area.
- private _base_search_area = [_markerPos, vn_mf_bn_s_zone_radius, vn_mf_bn_s_zone_radius, 0, false];
+ private _base_search_area = [_markerPos, _areaSize select 0, _areaSize select 1, 0, false];
private _candidate_bases_to_attack = para_g_bases inAreaArray _base_search_area apply {
[_x getVariable "para_g_current_supplies", _x]
};
From 12484064c235693cb39df26f69448ee7e8a0039e Mon Sep 17 00:00:00 2001
From: dijksterhuis <11841332+dijksterhuis@users.noreply.github.com>
Date: Thu, 15 Aug 2024 19:33:21 +0100
Subject: [PATCH 14/15] DacCongCTF: Fixup global broadcast in local dev and
validate function inputs
---
.../fn_ctf_broadcast_notify_immediate.sqf | 36 ++++++++++++++++---
1 file changed, 32 insertions(+), 4 deletions(-)
diff --git a/mission/functions/systems/dac_cong/fn_ctf_broadcast_notify_immediate.sqf b/mission/functions/systems/dac_cong/fn_ctf_broadcast_notify_immediate.sqf
index 33d0d6d7..8403ccf6 100644
--- a/mission/functions/systems/dac_cong/fn_ctf_broadcast_notify_immediate.sqf
+++ b/mission/functions/systems/dac_cong/fn_ctf_broadcast_notify_immediate.sqf
@@ -16,19 +16,47 @@
use to implement a CfgRemoteExec later on.
TODO: Refactor this out to core/helpers?
+ TODO: Rename? Should be like fn_broadcast_global_notification.sqf
Parameter(s):
- _notificationClass -- class name of the notification to show [STRING]
+ - _args -- arguments for string replacement in notification description text [ARRAY]
Returns: nothing
Example(s):
// from player locality
- // remote execs to this script from server
- // which then remoteExecs a notification for all players
+ // remote execs this script on the server
+ // which then remoteExecs a notification for all clients (and server, see note below)
["FireInTheHole"] remoteExec ["vn_mf_fnc_ctf_broadcast_notify_immediate", 2];
+
+ // from server locality
+ ["FireInTheHole"] call vn_mf_fnc_ctf_broadcast_notify_immediate;
*/
-params ["_notificationClass"];
+params [
+ "_notificationClass",
+ ["_args", []]
+];
+
+if (!isServer) exitWith {
+ ["ERROR", "Function should only run on server!"] call para_g_fnc_log;
+};
+
+if (_notificationClass isEqualTo "") exitWith {
+ ["ERROR", format ["Function passed an empty string for _notificationClass! value=%1", _notificationClass]] call para_g_fnc_log;
+};
+
+if !(_notificationClass isEqualType "testvalue") exitWith {
+ ["ERROR", format ["Function passed non-string for _notificationClass! value=%1", _notificationClass]] call para_g_fnc_log;
+};
+
+if !(_args isEqualType []) exitWith {
+ ["ERROR", format ["Function passed non-array for _args! value=%1", _args]] call para_g_fnc_log;
+};
+
+// This *should* be -2 --> but then notifications don't work on player hosted (local development)
+// cba to optimise this right now. it'll be fine for the moment.
+[_notificationClass, _args] remoteExec ["para_c_fnc_show_notification", 0];
-[_notificationClass, []] remoteExec ["para_c_fnc_show_notification", -2];
\ No newline at end of file
+nil;
\ No newline at end of file
From 79aab5fa93889c0a320e4ffa08cf875a792be0d2 Mon Sep 17 00:00:00 2001
From: dijksterhuis <11841332+dijksterhuis@users.noreply.github.com>
Date: Thu, 15 Aug 2024 19:33:58 +0100
Subject: [PATCH 15/15] DacCongCTF: Standardise all DC-CTF notifications to use
the same helper script.
---
.../systems/dac_cong/fn_ctf_handle_flag_height_change.sqf | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/mission/functions/systems/dac_cong/fn_ctf_handle_flag_height_change.sqf b/mission/functions/systems/dac_cong/fn_ctf_handle_flag_height_change.sqf
index c88bf361..e3292b86 100644
--- a/mission/functions/systems/dac_cong/fn_ctf_handle_flag_height_change.sqf
+++ b/mission/functions/systems/dac_cong/fn_ctf_handle_flag_height_change.sqf
@@ -45,8 +45,8 @@ if ((_progress mod _tickRate ) isEqualTo 0) then {
// global command, no need to remoteExec
deleteVehicle _target;
- // broadcast notification
- ["DacCongCapturedFlag", []] remoteExec ["para_c_fnc_show_notification", -2];
+ // broadcast notification out to all players
+ ["DacCongCapturedFlag"] call vn_mf_fnc_ctf_broadcast_notify_immediate;
// clear the JIP queue for flag height.
remoteExec ["", "JIP_DACCONG_CTF_FLAG_HEIGHT"];
@@ -62,7 +62,7 @@ if ((_progress mod _tickRate ) isEqualTo 0) then {
[_target, 1] remoteExec ["setFlagAnimationPhase", 0, "JIP_DACCONG_CTF_FLAG_HEIGHT"];
// broadcast notification out to all players
- ["BlueforRaisedFlag", []] remoteExec ["para_c_fnc_show_notification", -2];
+ ["BlueforRaisedFlag"] call vn_mf_fnc_ctf_broadcast_notify_immediate;
};
};
@@ -71,4 +71,4 @@ if ((_progress mod _tickRate ) isEqualTo 0) then {
[_target, _newHeight] remoteExec ["setFlagAnimationPhase", 0, "JIP_DACCONG_CTF_FLAG_HEIGHT"];
};
-nil
\ No newline at end of file
+nil;
\ No newline at end of file