-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
48 changed files
with
2,785 additions
and
15 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
[![Release](https://img.shields.io/github/release/gruppe-adler/grad-replay.svg)](https://github.com/gruppe-adler/grad-replay/release) | ||
[![License](https://img.shields.io/github/license/gruppe-adler/grad-replay.svg)](https://github.com/gruppe-adler/grad-replay/license) | ||
|
||
# grad-replay | ||
ARMA3 mission replay script (working but wip) | ||
* Records player and AI movement and replays at end of mission. | ||
* Meant for PvP but pimped to support AI as well | ||
* Mission duration should be matched to replay precision (see below) - the longer the mission, the less precision is recommended. Better precision (smaller values) results in longer loading times. | ||
|
||
### Required Mods | ||
CBA, ACE3 | ||
|
||
# How to install | ||
### 1. Download Release | ||
### 2. extract GRAD_replay folder into [mission folder]/node_modules | ||
### 3. Add the following to the description.ext | ||
|
||
``` | ||
#include "node_modules\@gruppe-adler\replay\ui\defines.hpp" | ||
#include "node_modules\@gruppe-adler\replay\ui\dialog.hpp" | ||
``` | ||
|
||
``` | ||
// if CfgFunctions already exists, just put the #include part inside | ||
class CfgFunctions { | ||
#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) | ||
sendingChunkSize = 10; // higher number means replay loading is faster, but might cause instability / lags during loading | ||
}; | ||
``` | ||
### 4. Initialize script in init.sqf | ||
`[] call GRAD_replay_fnc_init;` | ||
|
||
### 5. Put this where you want the replay to start (recommended: end of mission) | ||
Must be executed on server only! | ||
``` | ||
// stops record, sends data and starts replay | ||
call GRAD_replay_fnc_stopRecord; | ||
// ends mission after replay is over | ||
[{ | ||
REPLAY_FINISHED | ||
}, { | ||
["END1"] remoteExec ["endMission",0,false]; // your custom end mission call or whatever you want to do after replay | ||
}, []] call CBA_fnc_waitUntilAndExecute; | ||
``` | ||
|
||
### Important | ||
Currently there is **no helper function to resume normal gameplay after replay has played**, this means all assets will be frozen and TFAR spectator channel will be set for all players, furthermore every wound will be healed and all spectator cams left. | ||
|
||
### Script commands | ||
to pause recording, set `GRAD_REPLAY_RECORDING_PAUSED` to true on server / false to resume |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
class GRAD_replay { | ||
|
||
class player { | ||
file = grad-replay\functions\player; | ||
|
||
class addReplayPart {}; | ||
class animateShot {}; | ||
class assembleReplayData {}; | ||
class createMapOverlay {}; | ||
class drawIcon {}; | ||
class getColorFromID {}; | ||
class getRecordEntry {}; | ||
class initReplay {}; | ||
class onPlaybackPosChanged {}; | ||
class preparePlaybackClient {}; | ||
class receiveData {} | ||
class setPlayPauseDisplay {}; | ||
class setTimeDisplay {}; | ||
class showHintPause {}; | ||
class showHintPlay {}; | ||
class showHintReplayFinished {}; | ||
class showPlaybackControl {}; | ||
class showProgressBar {}; | ||
class startPlaybackClient {}; | ||
class stopPlaybackClient {}; | ||
class syncPlaybackPos {}; | ||
}; | ||
|
||
class server { | ||
file = grad-replay\functions\server; | ||
|
||
class canTrackUnit {}; | ||
class getSideColorID {}; | ||
class init {}; | ||
class onFiredMan {}; | ||
class pauseRecord {}; | ||
class preparePlaybackServer {}; | ||
class setMeSpectator {}; | ||
class startRecord {}; | ||
class stopRecord {}; | ||
class storeValue {}; | ||
}; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
#include "script_component.hpp" | ||
|
||
params ["_chunk", "_startIndex"]; | ||
|
||
// 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); | ||
|
||
[{[] call grad_replay_fnc_assembleReplayData},[],1] call CBA_fnc_waitAndExecute; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
params ["_map", "_index"]; | ||
|
||
private _positionData = GRAD_REPLAY_DATABASE_LOCAL_ASSEMBLED param [grad_replay_playbackPosition,[]]; | ||
if !(_positionData isEqualType []) exitWith {}; | ||
|
||
private _iconData = _positionData param [_index,[]]; | ||
if !(_iconData isEqualType []) exitWith {}; | ||
|
||
_iconData params [ | ||
"", | ||
["_colorID", -1], | ||
["_pos", [0,0,0]], | ||
"", | ||
"", | ||
"", | ||
["_firedTarget",[]] | ||
]; | ||
|
||
// unit did not fire shot this tick | ||
if (_firedTarget isEqualTo []) exitWith {}; | ||
|
||
private _color = [_colorID] call grad_replay_fnc_getColorFromID; | ||
private _shotDir = _pos getDir _firedTarget; | ||
private _shotDistance = _pos distance _firedTarget; | ||
private _drawEH = -1; | ||
private _shotAnimTicks = (floor (_shotDistance / GRAD_REPLAY_SHOTANIMSPEED)) min 30; | ||
private _shotAnimCurrentTick = 1; | ||
|
||
// flying lines Star Wars style animation | ||
[{ | ||
params ["_args","_handle"]; | ||
_args params ["_drawEH","_shotAnimCurrentTick","_shotAnimTicks","_map","_pos","_firedTarget","_color","_shotDir"]; | ||
|
||
_newShotEndPos = if (_shotAnimCurrentTick > _shotAnimTicks) then { | ||
_firedTarget | ||
} else { | ||
_pos getPos [GRAD_REPLAY_SHOTANIMSPEED * _shotAnimCurrentTick,_shotDir] | ||
}; | ||
|
||
_startPosTick = (_shotAnimCurrentTick - 2) max 0; | ||
_newShotStartPos = if (_startPosTick > _shotAnimTicks) then { | ||
_firedTarget | ||
} else { | ||
_pos getPos [GRAD_REPLAY_SHOTANIMSPEED * _startPosTick,_shotDir] | ||
}; | ||
|
||
// remove previous draw EH | ||
_map ctrlRemoveEventHandler ["Draw",_drawEH]; | ||
|
||
// create new draw EH and save ID in _drawEH (_args set [0,...]) | ||
if (_startPosTick > _shotAnimTicks) then { | ||
[_handle] call CBA_fnc_removePerFrameHandler; | ||
} else { | ||
_args set [0, | ||
_map ctrlAddEventHandler ["Draw", | ||
format ["(_this select 0) drawLine [%1,%2,%3]",_newShotStartPos,_newShotEndPos,_color] | ||
] | ||
]; | ||
}; | ||
|
||
_args set [1,_shotAnimCurrentTick + 1]; | ||
|
||
},0.1,[_drawEH,_shotAnimCurrentTick,_shotAnimTicks,_map,_pos,_firedTarget,_color,_shotDir]] call CBA_fnc_addPerFrameHandler; | ||
|
||
|
||
// continuous lines style animation | ||
/* [{ | ||
params ["_args","_handle"]; | ||
_args params ["_drawEH","_shotAnimCurrentTick","_shotAnimTicks","_map","_pos","_firedTarget","_color","_shotDir"]; | ||
_newShotPos = if (_shotAnimCurrentTick > _shotAnimTicks) then { | ||
_color set [3,(_color select 3) - 0.2]; | ||
_firedTarget; | ||
} else { | ||
_pos getPos [GRAD_REPLAY_SHOTANIMSPEED * _shotAnimCurrentTick,_shotDir]; | ||
}; | ||
// remove previous draw EH | ||
_map ctrlRemoveEventHandler ["Draw",_drawEH]; | ||
// create new draw EH and save ID in _drawEH (_args set [0,...]) | ||
if (_color select 3 <= 0) then { | ||
[_handle] call CBA_fnc_removePerFrameHandler; | ||
} else { | ||
_args set [0, | ||
_map ctrlAddEventHandler ["Draw", | ||
format ["(_this select 0) drawLine [%1,%2,%3]",_pos,_newShotPos,_color] | ||
] | ||
]; | ||
}; | ||
_args set [1,_shotAnimCurrentTick + 1]; | ||
},0.1,[_drawEH,_shotAnimCurrentTick,_shotAnimTicks,_map,_pos,_firedTarget,_color,_shotDir]] call CBA_fnc_addPerFrameHandler; */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
#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 | ||
[] // fired target | ||
]; | ||
|
||
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); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
createDialog "playbackControl"; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
params ["_map", "_index"]; | ||
|
||
private _positionData = GRAD_REPLAY_DATABASE_LOCAL_ASSEMBLED param [grad_replay_playbackPosition,[]]; | ||
if !(_positionData isEqualType []) exitWith {}; | ||
|
||
private _iconData = _positionData param [_index,[]]; | ||
if !(_iconData isEqualType []) exitWith {}; | ||
|
||
_iconData params [ | ||
["_icon", ""], | ||
["_colorID", -1], | ||
["_pos", [0,0,0]], | ||
["_dir", 0], | ||
["_name", ""], | ||
["_groupname", ""], | ||
"" | ||
]; | ||
|
||
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' | ||
]; |
Oops, something went wrong.