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