boiii-scripts/mp/_rewindobjects.csc
2023-04-13 17:30:38 +02:00

297 lines
13 KiB
Plaintext

#using scripts\codescripts\struct;
#using scripts\shared\system_shared;
#namespace rewindobjects;
function autoexec __init__sytem__() { system::register("rewindobjects",&__init__,undefined,undefined); }
function __init__()
{
level.rewindWatcherArray = [];
}
function initRewindObjectWatchers( localClientNum )
{
level.rewindWatcherArray[localClientNum] = [];
createNapalmRewindWatcher( localClientNum );
createAirstrikeRewindWatcher( localClientNum );
level thread watchRewindableEvents( localClientNum );
}
function watchRewindableEvents( localClientNum )
{
for (;;)
{
if ( isdefined( level.rewindWatcherArray[localClientNum] ) )
{
rewindWatcherKeys = getArrayKeys( level.rewindWatcherArray[localClientNum] );
for ( i = 0; i < rewindWatcherKeys.size; i++ )
{
rewindWatcher = level.rewindWatcherArray[localClientNum][rewindWatcherKeys[i]];
if ( !isdefined( rewindWatcher ) )
continue;
if ( !isdefined( rewindWatcher.event ) )
continue;
timeKeys = getArrayKeys( rewindWatcher.event );
for ( j = 0; j < timeKeys.size; j++ )
{
timeKey = timeKeys[j];
if ( rewindWatcher.event[timeKey].inProgress == true )
continue;
if ( level.serverTime >= timeKey )
{
rewindWatcher thread startRewindableEvent( localClientNum, timeKey );
}
}
}
}
wait( 0.1 );
}
}
function startRewindableEvent( localClientNum, timeKey )
{
player = getlocalplayer( localClientNum );
level endon( "demo_jump" + localClientNum );
self.event[timeKey].inProgress = true;
allFunctionsStarted = false;
while( allFunctionsStarted == false )
{
allFunctionsStarted = true;
assert(isdefined( self.timedFunctions ) );
timedFunctionKeys = getArrayKeys( self.timedFunctions );
for ( i = 0; i < timedFunctionKeys.size; i++ )
{
timedFunction = self.timedFunctions[timedFunctionKeys[i]];
timedFunctionKey = timedFunctionKeys[i];
if ( self.event[timeKey].timedFunction[timedFunctionKey] == true )
continue;
startTime = timeKey + ( timedFunction.startTimeSec * 1000 );
if ( startTime > level.serverTime )
{
allFunctionsStarted = false;
continue;
}
self.event[timeKey].timedFunction[timedFunctionKey] = true;
level thread [[timedFunction.func]]( localClientNum, startTime, timedFunction.startTimeSec, self.event[timeKey].data );
}
wait( 0.1 );
}
}
function createNapalmRewindWatcher( localClientNum )
{
napalmRewindWatcher = createRewindWatcher( localClientNum, "napalm" );
timeIncreaseBetweenPlanes = 0;
//napalmRewindWatcher addTimedFunction( "napalmPlane", _plane::flyPlane, timeIncreaseBetweenPlanes );
}
function createAirstrikeRewindWatcher( localClientNum )
{
airstrikeRewindWatcher = createRewindWatcher( localClientNum, "airstrike" );
// airstrikeRewindWatcher addTimedFunction( "aistrikePlane", _airstrike::flyAirstrikePlane, 0 );
}
function createRewindWatcher( localClientNum, name )
{
player = getlocalplayer( localClientNum );
if ( !isdefined(level.rewindWatcherArray[localClientNum]) )
{
level.rewindWatcherArray[localClientNum] = [];
}
rewindWatcher = getRewindWatcher( localClientNum, name );
if ( !isdefined( rewindWatcher ) )
{
rewindWatcher = SpawnStruct();
level.rewindWatcherArray[localClientNum][level.rewindWatcherArray[localClientNum].size] = rewindWatcher;
}
rewindWatcher.name = name;
rewindWatcher.event = [];
rewindWatcher thread resetOnDemoJump( localClientNum );
return rewindWatcher;
}
function resetOnDemoJump( localClientNum )
{
for (;;)
{
level waittill( "demo_jump" + localClientNum );
self.inProgress = false;
timedFunctionKeys = getArrayKeys( self.timedFunctions );
for ( i = 0; i < timedFunctionKeys.size; i++ )
{
self.timedFunctions[timedFunctionKeys[i]].inProgress = false;
}
eventKeys = getArrayKeys( self.event );
for ( i = 0; i < eventKeys.size; i++ )
{
self.event[eventKeys[i]].inProgress = false;
timedFunctionKeys = getArrayKeys( self.event[eventKeys[i]].timedFunction );
for ( index = 0; index < timedFunctionKeys.size; index++ )
{
self.event[eventKeys[i]].timedFunction[timedFunctionKeys[index]] = false;
}
}
}
}
function addTimedFunction( name, func, relativeStartTimeInSecs )
{
if ( !isdefined(self.timedFunctions) )
{
self.timedFunctions = [];
}
assert( !isdefined(self.timedFunctions[name] ) );
self.timedFunctions[name] = spawnStruct();
self.timedFunctions[name].inProgress = false;
self.timedFunctions[name].func = func;
self.timedFunctions[name].startTimeSec = relativeStartTimeInSecs;
}
function getRewindWatcher( localClientNum, name )
{
if ( !isdefined( level.rewindWatcherArray[localClientNum] ) )
{
return undefined;
}
for ( watcher = 0; watcher < level.rewindWatcherArray[localClientNum].size; watcher++ )
{
if (level.rewindWatcherArray[localClientNum][watcher].name == name )
{
return level.rewindWatcherArray[localClientNum][watcher];
}
}
return undefined;
}
function addRewindableEventToWatcher( startTime, data )
{
// duplicate message
if ( isdefined( self.event[startTime] ) )
{
return;
}
self.event[startTime] = spawnStruct();
self.event[startTime].data = data;
self.event[startTime].inprogress = false;
if ( isdefined( self.timedFunctions ) )
{
timedFunctionKeys = getArrayKeys( self.timedFunctions );
self.event[startTime].timedFunction = [];
for ( i = 0; i < timedFunctionKeys.size; i++ )
{
timedFunctionKey = timedFunctionKeys[i];
self.event[startTime].timedFunction[timedFunctionKey] = false;
}
}
}
function serverTimedMoveTo( localClientNum, startPoint, endPoint, startTime, duration )
{
level endon( "demo_jump" + localClientNum );
timeElapsed = ( level.serverTime - startTime ) * 0.001;
assert( duration > 0 );
doJump = true;
if ( timeElapsed < 0.02 )
doJump = false;
if ( timeElapsed < duration )
{
moveTime = duration - timeElapsed;
if ( doJump )
{
jumpPoint = getPointOnLine( startPoint, endPoint, ( timeElapsed / duration ) );
self.origin = jumpPoint;
}
self moveTo( endPoint, moveTime, 0, 0 );
return true;
}
else
{
self.origin = endPoint;
return false;
}
}
function serverTimedRotateTo( localClientNum, angles, startTime, duration, timeIn, timeout )
{
level endon( "demo_jump" + localClientNum );
timeElapsed = ( level.serverTime - startTime ) * 0.001;
if ( !isdefined ( timeIn ) )
{
timeIn = 0;
}
if ( !isdefined( timeout ) )
{
timeOut = 0;
}
assert( duration > 0 );
if ( timeElapsed < duration )
{
rotateTime = duration - timeElapsed;
self RotateTo(angles, rotateTime, timeIn, timeOut );
return true;
}
else
{
self.angles = angles;
return false;
}
}
function waitForServerTime( localClientNum, timeFromStart )
{
while( timeFromStart > level.serverTime )
{
{wait(.016);};
}
}
function removeClientEntOnJump( clientEnt, localClientNum )
{
clientEnt endon( "complete" );
player = GetLocalPlayer( localClientNum );
level waittill( "demo_jump" + localClientNum );
clientEnt notify( "delete" );
clientEnt forcedelete();
}
function getPointOnLine( startPoint, endPoint, ratio )
{
nextPoint = ( startPoint[0] + ( ( endPoint[0] - startPoint[0] ) * ratio ) ,
startPoint[1] + ( ( endPoint[1] - startPoint[1] ) * ratio ) ,
startPoint[2] + ( ( endPoint[2] - startPoint[2] ) * ratio ) );
return nextPoint;
}