Skip to content

Commit

Permalink
Merge pull request #20 from gruppe-adler/saving-rework
Browse files Browse the repository at this point in the history
Saving Rework
  • Loading branch information
nomisum authored Oct 19, 2018
2 parents d9eedec + fe25452 commit 5e1b56d
Show file tree
Hide file tree
Showing 26 changed files with 1,003 additions and 854 deletions.
19 changes: 10 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,17 +23,18 @@ CBA, ACE3
```
// if CfgFunctions already exists, just put the #include part inside
class CfgFunctions {
#include "node_modules\@gruppe-adler\replay\cfgFunctions.hpp"
};
#include "node_modules\@gruppe-adler\replay\cfgFunctions.hpp"
};
```

```
class GRAD_Replay {
precision = 5; // precision of replay, 5 means every 5 seconds one snapshot (number)
trackedSides[] = {"west", "east", "civilian"}; // defines the sides that will be tracked (possible are "west", "east", "independant", "civilian") (array)
stepsPerTick = 1; // defines steps played back at once (number)
trackedVehicles = 0; // defines if empty and AI steered vehicles will be tracked (0/1)
trackedAI = 0; // defines if AI will be tracked (0/1)
precision = 5; // precision of replay, 5 means every 5 seconds one snapshot (number)
trackedSides[] = {"west", "east", "civilian"}; // defines the sides that will be tracked (possible are "west", "east", "independant", "civilian") (array)
stepsPerTick = 1; // defines steps played back at once (number)
trackedVehicles = 0; // defines if empty and AI steered vehicles will be tracked (0/1)
trackedAI = 0; // defines if AI will be tracked (0/1)
sendingChunkSize = 10; // higher number means replay loading is faster, but might cause instability / lags during loading
};
```
### 4. Initialize script in init.sqf
Expand All @@ -47,9 +48,9 @@ call GRAD_replay_fnc_stopRecord;
// ends mission after replay is over
[{
REPLAY_FINISHED
REPLAY_FINISHED
}, {
["END1"] remoteExec ["endMission",0,false]; // your custom end mission call or whatever you want to do after replay
["END1"] remoteExec ["endMission",0,false]; // your custom end mission call or whatever you want to do after replay
}, []] call CBA_fnc_waitUntilAndExecute;
```

Expand Down
11 changes: 7 additions & 4 deletions cfgFunctions.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,10 @@ class GRAD_replay {
file = MODULES_DIRECTORY\@gruppe-adler\replay\functions\player;

class addReplayPart {};
class assembleReplayData {};
class createMapOverlay {};
class drawIcon {};
class getColorFromID {};
class getRecordEntry {};
class initReplay {};
class onPlaybackPosChanged {};
Expand All @@ -27,16 +29,17 @@ class GRAD_replay {
class syncPlaybackPos {};
};

class server {
file = MODULES_DIRECTORY\@gruppe-adler\replay\functions\server;
class server {
file = MODULES_DIRECTORY\@gruppe-adler\replay\functions\server;

class getSideColor {};
class canTrackUnit {};
class getSideColorID {};
class init {};
class pauseRecord {};
class preparePlaybackServer {};
class setMeSpectator {};
class startRecord {};
class stopRecord {};
class storeValue {};
};
};
};
24 changes: 20 additions & 4 deletions functions/player/fn_addReplayPart.sqf
Original file line number Diff line number Diff line change
@@ -1,6 +1,22 @@
params ["_array", "_index"];
#include "script_component.hpp"

// hintsilent format ["appending array %1", count GRAD_REPLAY_DATABASE_LOCAL];
// diag_log format ["appending array %1", count GRAD_REPLAY_DATABASE_LOCAL];
params ["_chunk", "_startIndex"];

GRAD_REPLAY_DATABASE_LOCAL set [_index, (parseSimpleArray _array)];
// add all received parts to database
{
GRAD_REPLAY_DATABASE_LOCAL set [_startIndex + _forEachIndex, _x];
} forEach _chunk;

// start assembling, if everything has been received
private _targetCount = missionNamespace getVariable ["GRAD_REPLAY_DATABASE_TARGET_COUNT_LOCAL",9999999];
if ({!isNil "_x"} count GRAD_REPLAY_DATABASE_LOCAL >= _targetCount) then {

// apparently function can run multiple times in parallel --> exit here if other instance was first
if (player getVariable ["grad_replay_playerReceiptComplete",false]) exitWith {};
player setVariable ["grad_replay_playerReceiptComplete",true,true];

INFO_1("Client replay receipt completed at serverTime %1",serverTime);
diag_log [{!isNil "_x"} count GRAD_REPLAY_DATABASE_LOCAL,count GRAD_REPLAY_DATABASE_LOCAL,_targetCount,_startIndex,count _chunk];

[{[] call grad_replay_fnc_assembleReplayData},[],1] call CBA_fnc_waitAndExecute;
};
76 changes: 76 additions & 0 deletions functions/player/fn_assembleReplayData.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
#include "script_component.hpp"

params [["_part",0],["_startIndex",0],["_startTime",diag_tickTime],["_currentUnitsDataStates",[]]];

if (_part == 0) then {
INFO("Assembling replay data.");
} else {
INFO_2("Continuing assembly at index %1 (recursion %2).",_startIndex,_part);
};

if (isNil "GRAD_REPLAY_DATABASE_LOCAL_ASSEMBLED") then {
GRAD_REPLAY_DATABASE_LOCAL_ASSEMBLED = [];
};

private _typeDefaults = [
"", // icon
-1, // color ID
[0,0], // pos2D
-1, // dir
"", // name
"" // group name
];

private _interrupt = false;
private _startTimePart = diag_tickTime;
private _continueAt = 0;

for [{_i=_startIndex},{_i< count GRAD_REPLAY_DATABASE_LOCAL},{_i=_i+1}] do {

_compressedIntervalData = GRAD_REPLAY_DATABASE_LOCAL select _i;
_intervalData = [];

{
// catch nil entries, not sure what's causing them
if (!isNil "_x") then {

// timestamp
if (_x isEqualType 0) exitWith {
_intervalData pushBack _x;
};

// data array
if (_x isEqualType []) then {
_unitData = [];
_compressedUnitData = _x;

if (_forEachIndex >= count _currentUnitsDataStates) then {
_currentUnitsDataStates pushBack [];
};
_currentUnitDataState = _currentUnitsDataStates select _forEachIndex;

{
if (isNil "_x") then {
_unitData pushBack (_currentUnitDataState param [_forEachIndex,_typeDefaults select _forEachIndex]);
} else {
_currentUnitDataState set [_forEachIndex,_x];
_unitData pushBack _x;
};
} forEach _compressedUnitData;

_intervalData pushBack _unitData;
};
};
} forEach _compressedIntervalData;

GRAD_REPLAY_DATABASE_LOCAL_ASSEMBLED pushBack _intervalData;

if ((diag_tickTime - _startTimePart) > 0.2) exitWith {_interrupt = true; _continueAt = _i + 1};
};

if (_interrupt) then {
[{_this call grad_replay_fnc_assembleReplayData},[_part + 1,_continueAt,_startTime,_currentUnitsDataStates]] call CBA_fnc_execNextFrame;
} else {
player setVariable ["grad_replay_playerAssemblyComplete",true,true];
INFO_1("Assembling completed in %1s",diag_tickTime - _startTime);
};
32 changes: 16 additions & 16 deletions functions/player/fn_drawIcon.sqf
Original file line number Diff line number Diff line change
@@ -1,36 +1,36 @@
params ["_map", "_index"];

private _positionData = GRAD_REPLAY_DATABASE_LOCAL param [grad_replay_playbackPosition,[]];
private _positionData = GRAD_REPLAY_DATABASE_LOCAL_ASSEMBLED param [grad_replay_playbackPosition,[]];
if !(_positionData isEqualType []) exitWith {};

private _iconData = _positionData param [_index,[]];
if !(_iconData isEqualType []) exitWith {};

_scale = ctrlMapScale _map;
_showName = _scale < 0.03;

_iconData params [
["_icon", ""],
["_color", [0,0,0,0]],
["_colorID", -1],
["_pos", [0,0,0]],
["_dir", 0],
["_name", ""],
["_groupname", ""]
];


_name = if (_showName) then { _name + " " + _groupname } else { "" };
private _showName = (ctrlMapScale _map) < 0.03;
private _name = if (_showName) then { _name + " " + _groupname } else { "" };
private _color = [_colorID] call grad_replay_fnc_getColorFromID;

_map drawIcon [
_icon,
_color,
_pos,
24,
24,
_dir,
_name,
1,
0.03,
'TahomaB',
'right'
_icon,
_color,
_pos,
24,
24,
_dir,
_name,
1,
0.03,
'TahomaB',
'right'
];
31 changes: 31 additions & 0 deletions functions/player/fn_getColorFromID.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/* Color lookup table to reduce variable size when saving.
*
*/


#define DEFAULT_COLOR [0.7,0.6,0,1]

params [["_colorID",-1]];

private _colors = [

// side color IDs
[0,0.3,0.6,1], // 0: WEST
[0.5,0,0,1], // 1: EAST
[0,0.5,0,1], // 2: INDEPENDENT
[0.4,0,0.5,1], // 3: CIVILIAN
[0.7,0.6,0,1], // 4: SIDEEMPTY

// unconscious IDs are currently hardcoded to be exactly +5 in fn_startRecord!
[0,0.3,0.6,0.5], // 5: WEST unconscious
[0.5,0,0,0.5], // 6: EAST unconscious
[0,0.5,0,0.5], // 7: INDEPENDENT unconscious
[0.4,0,0.5,0.5], // 8: CIVILIAN unconscious
[0.7,0.6,0,0.5], // 9: SIDEEMPTY unconscious

// other
[0.2,0.2,0.2,0.5], // 10: dead unit
[1,0,0,1] // 11: funkwagen-red when sending, speciality for mission "breaking contact"
];

_colors param [_colorID,DEFAULT_COLOR]
24 changes: 12 additions & 12 deletions functions/player/fn_onPlaybackPosChanged.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@ params ["_control"];

if (isMultiplayer && !(serverCommandAvailable "#kick")) exitWith {};

grad_replay_playbackPosition =
ceil (
linearConversion [
0,
10,
sliderPosition ctrlIDC (_control select 0),
0,
count GRAD_REPLAY_DATABASE_LOCAL,
true]
);
(_control select 0) ctrlSetTooltip format ["%1 / %2", grad_replay_playbackPosition, count GRAD_REPLAY_DATABASE_LOCAL];
// systemchat format ['sliderPosition: %1 %', grad_replay_playbackPosition];
grad_replay_playbackPosition =
ceil (
linearConversion [
0,
10,
sliderPosition ctrlIDC (_control select 0),
0,
count GRAD_REPLAY_DATABASE_LOCAL_ASSEMBLED,
true]
);
(_control select 0) ctrlSetTooltip format ["%1 / %2", grad_replay_playbackPosition, count GRAD_REPLAY_DATABASE_LOCAL_ASSEMBLED];
// systemchat format ['sliderPosition: %1 %', grad_replay_playbackPosition];
6 changes: 2 additions & 4 deletions functions/player/fn_preparePlaybackClient.sqf
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
#include "\z\ace\addons\main\script_component.hpp"

{_x setMarkerAlphaLocal 0;} forEach allMapMarkers; // hide all markers for replay --> to be tested

if (dialog) then {closeDialog 0;};

[ "TIMER", "onEachFrame" ] call BIS_fnc_removeStackedEventHandler;
ctrlDelete (uiNamespace getVariable "GRAD_replay_rsc_loadingBar");
ctrlDelete (uiNamespace getVariable "GRAD_replay_txt_loading");
ctrlDelete (uiNamespace getVariable "GRAD_replay_txt_loadingInfo");

[] spawn GRAD_replay_fnc_startPlaybackClient;
[] spawn GRAD_replay_fnc_startPlaybackClient;
12 changes: 6 additions & 6 deletions functions/player/fn_receiveData.sqf
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
params ["_count", "_index", "_playerCount"];
params ["_replayLength", "_index", "_playerCount"];

// quit EG spec
if (["IsInitialized"] call BIS_fnc_EGSpectator) then {
["Terminate"] call BIS_fnc_EGSpectator;
["Terminate"] call BIS_fnc_EGSpectator;
};


// quit ACE spec
if (!isNil "ace_spectator_isSet") then {
[false] call ace_spectator_fnc_setSpectator;
[false] call ace_spectator_fnc_setSpectator;
};

GRAD_REPLAY_DATABASE_TARGET_COUNT_LOCAL = _count;
[_count, _index, _playerCount] spawn GRAD_replay_fnc_showProgressBar;
GRAD_REPLAY_DATABASE_TARGET_COUNT_LOCAL = _replayLength;
[_replayLength, _index, _playerCount] spawn GRAD_replay_fnc_showProgressBar;


// quit grad cam
Expand All @@ -23,4 +23,4 @@ GRAD_CINEMACAM = objNull;
GCamKill = true;

// let players be able to talk already
[player, true] call TFAR_fnc_forceSpectator;
[player, true] call TFAR_fnc_forceSpectator;
8 changes: 4 additions & 4 deletions functions/player/fn_removeDrawEventhandler.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ params ["_array"];

// delete icons frame before
if (count _array > 0) then {
{
((findDisplay 12) displayCtrl 51) ctrlRemoveEventHandler ["Draw", _x];
} forEach _array;
};
{
((findDisplay 12) displayCtrl 51) ctrlRemoveEventHandler ["Draw", _x];
} forEach _array;
};
6 changes: 3 additions & 3 deletions functions/player/fn_setPlayPauseDisplay.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ params ["_isPlay"];
disableSerialization;

if (_isPlay) then {
((findDisplay 80000) displayCtrl 80005) ctrlSetText "node_modules\@gruppe-adler\replay\ui\play.paa";
((findDisplay 80000) displayCtrl 80005) ctrlSetText "node_modules\@gruppe-adler\replay\ui\play.paa";
} else {
((findDisplay 80000) displayCtrl 80005) ctrlSetText "node_modules\@gruppe-adler\replay\ui\pause.paa";
};
((findDisplay 80000) displayCtrl 80005) ctrlSetText "node_modules\@gruppe-adler\replay\ui\pause.paa";
};
4 changes: 2 additions & 2 deletions functions/player/fn_setTimeDisplay.sqf
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
params ["_position"];

disableSerialization;
_time = GRAD_REPLAY_DATABASE_LOCAL select _position select (count (GRAD_REPLAY_DATABASE_LOCAL select _position) - 1);
private _time = GRAD_REPLAY_DATABASE_LOCAL_ASSEMBLED select _position select (count (GRAD_REPLAY_DATABASE_LOCAL_ASSEMBLED select _position) - 1);

// if (_time find ".paa" > -1) exitWith { diag_log format ["grad-replay: catch unvalid time display: %1", _position]; };

((findDisplay 80000) displayCtrl 80004) ctrlSetText _time;
((findDisplay 80000) displayCtrl 80004) ctrlSetText ([_time,"HH:MM:SS"] call BIS_fnc_timeToString);
Loading

0 comments on commit 5e1b56d

Please sign in to comment.