diff --git a/TO-DO.txt b/TO-DO.txt index ab003ed..d92329d 100644 --- a/TO-DO.txt +++ b/TO-DO.txt @@ -1,5 +1,6 @@ TO DO: - - Fix kills/vehicle destruction sometimes awarding double the points that it should (including headshot damage) + - Fix occasional double-kill registration for an individual unit + - Maybe why kills/vehicle destruction sometimes awards double the points that it should (including headshot damage)? - Fix loadouts sometimes not getting applied to AI units (same issue as gAI when locality changes?) - Fix spotting animation not working (same issue as healing action) - Implement resupply ability to support: @@ -17,10 +18,6 @@ TO DO: + Sector letters on maps - Spawn menu - End screen - - Fix spawn menu inconsistencies - + Sides with no tickets don't get greyed out - - Fix AI groups sometimes getting duplicated (with incorrect callsigns) - + Sometimes spawn menus cannot be opened at all + chat spam (see screenshot) - Move macros/variables pertaining to a side's definition into single file (merge with loadouts file?) - (Investigate Joe's isssue with being able to spawn when no sectors are owned) - Add a custom scoreboard UI @@ -36,6 +33,11 @@ TO DO: - Search for "DEBUG" and "TODO" keywords DONE: + - Fix unconsciousState AI subsystem referencing serverside variables (causing AI to not respawn) + - Fix spawn menu inconsistencies + + Sides with no tickets don't get greyed out + + Fix AI groups sometimes getting duplicated (with incorrect callsigns) + + Sometimes spawn menus cannot be opened at all + chat spam (see screenshot) - Revisit ACE pointing keybinding transfer (still just picking the first one, not all) - Fix bleeding out in multiplayer resetting the respawn time - Investigate weapon kill icons not showing when players get killed by AI on a dedicated server diff --git a/mission/settings.inc b/mission/settings.inc index 9e5858d..20aa984 100644 --- a/mission/settings.inc +++ b/mission/settings.inc @@ -18,7 +18,7 @@ #define MACRO_AI_INCLUDEPLAYERS false // Whether or not players are counted towards the AI limit #define MACRO_AI_ALLOWVEHICLES true // Whether or not the AI is allowed to use any vehicles at all. Only affects vehicles that would otherwise be allowed for AI use #define MACRO_AI_PEACEFULMODE false // Whether or not the AI is allowed to engage other units. - #define MACRO_AI_MAXUNITSPERGROUP 4 // How many AI units are allowed to form up in a group + #define MACRO_AI_MAXUNITSPERGROUP 6 // How many AI units are allowed to form up in a group #define MACRO_AI_SPAWNWEIGHT_EAST 1 // The weight towards spawning AI on the "east" (OPFOR) side #define MACRO_AI_SPAWNWEIGHT_RESISTANCE 0 // The weight towards spawning AI on the "resistance" (INDFOR) side diff --git a/res/common/macros.inc b/res/common/macros.inc index 8f67ef2..8ad4b39 100644 --- a/res/common/macros.inc +++ b/res/common/macros.inc @@ -463,7 +463,7 @@ #define MACRO_UNIT_HEALTH_THRESHOLDLOW 0.5 // The threshold of health below which a unit is considered to be at low health // Framework - #define MACRO_MISSION_FRAMEWORK_VERSION "0.14.657" // The version of this framework + #define MACRO_MISSION_FRAMEWORK_VERSION "0.14.662" // The version of this framework #define MACRO_MISSION_FRAMEWORK_GAMEMODE "Conquest" // Multiplayer settings (referenced by the Steam server browser) diff --git a/scripts/ai/fn_ai_resetRespawnTime.sqf b/scripts/ai/fn_ai_resetRespawnTime.sqf index 86961e0..aa03e98 100644 --- a/scripts/ai/fn_ai_resetRespawnTime.sqf +++ b/scripts/ai/fn_ai_resetRespawnTime.sqf @@ -1,11 +1,11 @@ /* -------------------------------------------------------------------------------------------------------------------- Author: Cre8or Description: - [S][GA] - Resets the AI unit's death time state to the server's current time (which is where AI respawning is being - handled). + [LA][LE] + Resets the AI unit's death time state to the machine's current time, which is different per-machine. This + ensures correct respawn times across locality transitions. - Either called on a local AI unit's death, or remotely on unit unconsciousness. + Either called on unit unconsciousness, or death (if not already unconscious). Arguments: 0: The concerned unit Returns: @@ -18,14 +18,29 @@ params [ ["_unit", objNull, [objNull]] ]; -if (!isServer or {isNull _unit}) exitWith {}; +if (isNull _unit or {isPlayer _unit}) exitWith {}; -private _unitIndex = _unit getVariable [QGVAR(unitIndex), -1]; +// Set up some variables +private _time = time; -if (_unitIndex >= 0 and {_unitIndex < GVAR(param_ai_maxCount)}) then { - GVAR(ai_sys_handleRespawn_respawnTimes) set [_unitIndex, time + GVAR(param_gm_unit_respawnDelay)]; + + + + +// Interface with unitControl to allow unconscious units to give up and bleed out +if ([_unit, true] call FUNC(unit_isAlive)) then { + _unit setVariable [QGVAR(ai_unitControl_unconsciousState_respawnTime), _time + GVAR(param_gm_unit_respawnDelay), false]; +}; + +// Special case: the server is in charge of respawning units, and uses additional variables. +if (isServer) then { + private _unitIndex = _unit getVariable [QGVAR(unitIndex), -1]; + + if (_unitIndex >= 0 and {_unitIndex < GVAR(param_ai_maxCount)}) then { + GVAR(ai_sys_handleRespawn_respawnTimes) set [_unitIndex, _time + GVAR(param_gm_unit_respawnDelay)]; + }; }; diff --git a/scripts/ai/unitControl/subSys_unconsciousState.sqf b/scripts/ai/unitControl/subSys_unconsciousState.sqf index ec97f98..a6712c2 100644 --- a/scripts/ai/unitControl/subSys_unconsciousState.sqf +++ b/scripts/ai/unitControl/subSys_unconsciousState.sqf @@ -1,14 +1,21 @@ // Set up some variables -private _respawnTime = GVAR(ai_sys_handleRespawn_respawnTimes) param [_unitIndex, -1]; +private _respawnTime = _unit getVariable [QGVAR(ai_unitControl_unconsciousState_respawnTime), -1]; -// The unit should be able to respawn, but is still unconscious -if (_time > _respawnTime) then { +// Enforce bleed-out +private _bleedoutTime = _unit getVariable [QGVAR(bleedoutTime), -1]; +if (_time > _bleedoutTime) then { + _unit setDamage 1; + + breakTo QGVAR(ai_sys_unitControl_loop_local); - // If there are no medics nearby, give up +}; + +// Allow the unit to give up prematurely if it can respawn, hasn't bled out yet, and has no medics nearby +if (_time > _respawnTime) then { private _c_maxMedicalDistSqr = MACRO_AI_MEDICAL_MAXACTIONDISTANCE ^ 2; private _medics = GVAR(ai_sys_unitControl_cache) getOrDefault [format ["unitsMedic_%1", _side], []]; @@ -17,12 +24,4 @@ if (_time > _respawnTime) then { breakTo QGVAR(ai_sys_unitControl_loop_local); }; - - // Enforce bleed-out - private _bleedoutTime = _unit getVariable [QGVAR(bleedoutTime), -1]; - if (_time > _bleedoutTime) then { - _unit setDamage 1; - - breakTo QGVAR(ai_sys_unitControl_loop_local); - }; }; diff --git a/scripts/gameMode/fn_gm_processUnitDamage.sqf b/scripts/gameMode/fn_gm_processUnitDamage.sqf index 9b8f2a7..dd7b29a 100644 --- a/scripts/gameMode/fn_gm_processUnitDamage.sqf +++ b/scripts/gameMode/fn_gm_processUnitDamage.sqf @@ -98,8 +98,8 @@ if (_health > 0) then { _unit setVariable [QGVAR(addHitDetection_assistDamages), _assistDamages, false]; }; - // Clamp the health to 0 - _unit setVariable [QGVAR(health), _health max 0, true]; + // Health can't be <= 0 + _unit setVariable [QGVAR(health), _health, true]; // Unit is unconscious / dead } else { diff --git a/scripts/units/fn_unit_onKilled.sqf b/scripts/units/fn_unit_onKilled.sqf index e6a08fe..1ac55f3 100644 --- a/scripts/units/fn_unit_onKilled.sqf +++ b/scripts/units/fn_unit_onKilled.sqf @@ -69,7 +69,7 @@ if ( // Serverside AI respawn time handling -if (isServer and {!_isUnconscious}) then { +if (isServer and {!_isUnconscious} and {!isPlayer _unit}) then { [_unit] call FUNC(ai_resetRespawnTime); }; diff --git a/scripts/units/fn_unit_setUnconscious.sqf b/scripts/units/fn_unit_setUnconscious.sqf index 04bb801..362c1f0 100644 --- a/scripts/units/fn_unit_setUnconscious.sqf +++ b/scripts/units/fn_unit_setUnconscious.sqf @@ -49,7 +49,9 @@ if (_newState) then { [_unit] call FUNC(anim_unconscious); // Update the respawn time on AI units - [_unit] remoteExecCall [QFUNC(ai_resetRespawnTime), 2, false]; + if (!isPlayer _unit) then { + [_unit] remoteExecCall [QFUNC(ai_resetRespawnTime), 0, false]; + }; // Revived } else {