Skip to content

Commit

Permalink
last changes for game on 16th
Browse files Browse the repository at this point in the history
  • Loading branch information
nomisum committed Dec 15, 2018
1 parent c3fc269 commit 9966c82
Show file tree
Hide file tree
Showing 48 changed files with 2,785 additions and 15 deletions.
13 changes: 7 additions & 6 deletions description.ext
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@

#include "node_modules\grad-fortifications\grad_fortifications.hpp"
#include "node_modules\grad-customGear\saveDialog\dialog.hpp"
#include "node_modules\@gruppe-adler\replay\ui\defines.hpp"
#include "node_modules\@gruppe-adler\replay\ui\dialog.hpp"
#include "grad-replay\ui\defines.hpp"
#include "grad-replay\ui\dialog.hpp"

class CfgFunctions {
#include "grad_carryBoat\cfgFunctions.hpp"
Expand All @@ -22,7 +22,7 @@ class CfgFunctions {
#include "grad_tracking\cfgFunctions.hpp"
#include "grad_emptycars\cfgFunctions.hpp"
#include "BC_objectives\cfgFunctions.hpp"
#include "node_modules\@gruppe-adler\replay\cfgFunctions.hpp"
#include "grad-replay\cfgFunctions.hpp"
#include "node_modules\grad-customGear\cfgFunctions.hpp"
};

Expand Down Expand Up @@ -122,7 +122,7 @@ class Params
title = "Length of sending time";
values[] = {30, 300, 600, 900, 1320, 1800, 2700, 3600, 4500, 5400, 6300};
texts[] = {"30s (DEBUG)", "5'","10' (recommended for 3 radio positions)", "15'", "22' (recommended for 2 radio positions)", "30'", "45' (recommended for 1 radio position)", "1h'", "1h15'","1h30'","1h45'"};
default = 1320;
default = 1800;
};

class GRAD_INTERVALS_NEEDED
Expand All @@ -146,7 +146,7 @@ class Params
title = "InGame Replay Accuracy";
values[] = {1,2,3,4,5};
texts[] = {"every 1s","every 2s","every 3s","every 4s","every 5s"};
default = 3;
default = 5;
};

class AR3PLAY_ENABLE_REPLAY
Expand Down Expand Up @@ -210,7 +210,7 @@ class Params
title = "Preparation time";
values[] = {0,60,120,180,240,300,480,600,900};
texts[] = {"off","1min","2min","3min","4min","5min","8min","10min","15min"};
default = 300;
default = 480;
};
};

Expand Down Expand Up @@ -360,6 +360,7 @@ class Loadouts {

resetLoadout = 1;
handleRadios = 1;
perPlayerDelay = 2;

class AllUnits {
binoculars = "Binocular";
Expand Down
674 changes: 674 additions & 0 deletions grad-replay/LICENSE

Large diffs are not rendered by default.

61 changes: 61 additions & 0 deletions grad-replay/README.md
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
43 changes: 43 additions & 0 deletions grad-replay/cfgFunctions.hpp
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 {};
};
};
21 changes: 21 additions & 0 deletions grad-replay/functions/player/fn_addReplayPart.sqf
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;
};
94 changes: 94 additions & 0 deletions grad-replay/functions/player/fn_animateShot.sqf
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; */
77 changes: 77 additions & 0 deletions grad-replay/functions/player/fn_assembleReplayData.sqf
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);
};
1 change: 1 addition & 0 deletions grad-replay/functions/player/fn_createMapOverlay.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
createDialog "playbackControl";
35 changes: 35 additions & 0 deletions grad-replay/functions/player/fn_drawIcon.sqf
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'
];
Loading

0 comments on commit 9966c82

Please sign in to comment.