mirror of
https://github.com/exogen/t2-mapper.git
synced 2026-01-19 20:25:01 +00:00
640 lines
17 KiB
C#
640 lines
17 KiB
C#
// updated ObserverQueue
|
|
|
|
// Create queue container...
|
|
if( !isObject("ObserverQueue") )
|
|
{
|
|
new SimGroup("ObserverQueue");
|
|
//ObserverQueue.setPersistent(1); // whats this do..?
|
|
}
|
|
|
|
function validateQueue()
|
|
{
|
|
if( !$TR2::SpecLock && !$Host::TournamentMode )
|
|
{
|
|
%active = GetActiveCount();
|
|
%count = 12 - %active;
|
|
for( %i = 0; %i < %count && ObserverQueue.getCount() > 0; %i++ )
|
|
{
|
|
%cl = getClientFromQueue();
|
|
if( isObject(%cl) )
|
|
{
|
|
Game.assignClientTeam(%cl, $MatchStarted);
|
|
Game.spawnPlayer(%cl, $MatchStarted);
|
|
reindexQueue();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
function getActiveCount()
|
|
{
|
|
%count = 0;
|
|
for( %i = 0; %i < ClientGroup.getCount(); %i++)
|
|
{
|
|
%cl = ClientGroup.getObject(%i);
|
|
if( %cl.team > 0 )
|
|
%count++;
|
|
}
|
|
return %count;
|
|
}
|
|
|
|
function addToQueue(%client)
|
|
{
|
|
if( %client.team > 0 )
|
|
return 0;
|
|
if( !isObject(%client) )
|
|
return 0;
|
|
%unique = 1;
|
|
%count = ObserverQueue.getCount();
|
|
for( %i = 0; %i < %count; %i++ )
|
|
{
|
|
%node = ObserverQueue.getObject(%i);
|
|
if( %node.id == %client )
|
|
{
|
|
%unique = 0;
|
|
}
|
|
}
|
|
reindexQueue();
|
|
if( %unique == 1 )
|
|
{
|
|
%node = new ScriptObject()
|
|
{
|
|
id = %client.getId();
|
|
name = %client.nameBase;
|
|
};
|
|
ObserverQueue.add(%node);
|
|
ObserverQueue.pushToBack(%node);
|
|
}
|
|
%client.allowedToJoinTeam = 1;
|
|
reindexQueue();
|
|
messageQueue();
|
|
return %unique; // 0 = client already added to queue, 1 = client successfully added
|
|
}
|
|
|
|
function removeFromQueue(%client)
|
|
{
|
|
// if( !isObject(%client) )
|
|
// return 0;
|
|
// we shouldn't have duplicates in the queue, but why take a chance..
|
|
%idx = 0;
|
|
%count = ObserverQueue.getCount();
|
|
|
|
|
|
for( %i = 0; %i < %count; %i++ )
|
|
{
|
|
%node = ObserverQueue.getObject(%i);
|
|
if( %node.id == %client.getId() )
|
|
{
|
|
ObserverQueue.pushToBack(%node);
|
|
%node.delete();
|
|
break;
|
|
}
|
|
}
|
|
reindexQueue();
|
|
messageQueue();
|
|
// schedule(100, 0, "reindexQueue");
|
|
// schedule(101, 0, "messageQueue");
|
|
return %idx; // 0 if client not found to remove
|
|
}
|
|
|
|
function messageQueue()
|
|
{
|
|
%total = reindexQueue();
|
|
%count = ObserverQueue.getCount();
|
|
for( %i = 0; %i < %count; %i++ )
|
|
{
|
|
%cl = ObserverQueue.getObject(%i).id;
|
|
if( !%cl.specOnly )
|
|
{
|
|
if( %cl.queueSlot == 1 )
|
|
messageClient(%cl, 'MsgTR2QueuePos', '\c0You are currently \c1NEXT\c0 of \c1%2\c0 in the Observer Queue.~wfx/misc/bounty_objrem2.wav', %cl.queueSlot, %total);
|
|
else
|
|
messageClient(%cl, 'MsgTR2QueuePos', '\c0You are currently \c1%1\c0 of \c1%2\c0 in the Observer Queue.', %cl.queueSlot, %total);
|
|
}
|
|
}
|
|
}
|
|
|
|
function messageQueueClient(%client)
|
|
{
|
|
if( %client.team != 0 )
|
|
{
|
|
messageClient(%client, 'MsgNotObserver', '\c0You are not currently in observer mode.~wfx/powered/station_denied.wav');
|
|
return;
|
|
}
|
|
if( %client.specOnly )
|
|
{
|
|
messageClient(%client, 'MsgSpecOnly', '\c0You are currently in individual spectator only mode.~wfx/powered/station_denied.wav');
|
|
return;
|
|
}
|
|
|
|
%total = reindexQueue();
|
|
%pos = %client.queueSlot;
|
|
|
|
if( %pos $= "" )
|
|
return;
|
|
|
|
if( %pos == 1 )
|
|
messageClient(%client, 'MsgTR2QueuePos', '\c0You are currently \c1NEXT\c0 of \c1%2\c0 in the Observer Queue.!~wfx/misc/bounty_objrem2.wav', %pos, %total);
|
|
else
|
|
messageClient(%client, 'MsgTR2QueuePos', '\c0You are currently \c1%1\c0 of \c1%2\c0 in the Observer Queue.', %pos, %total);
|
|
}
|
|
|
|
function reindexQueue()
|
|
{
|
|
// reassigns client 'slots' in the queue
|
|
// returns the current number of assigned 'slots'
|
|
// only people who are actively in the queue (not spec locked) are counted.
|
|
|
|
%slot = 0;
|
|
//%count = ObserverQueue.getCount();
|
|
for( %i = 0; %i < ObserverQueue.getCount(); %i++ )
|
|
{
|
|
%node = ObserverQueue.getObject(%i);
|
|
%client = %node.id;
|
|
if( !isObject(%client) )
|
|
{
|
|
error("Client " @ %client @ " does not exist!! Removing from queue.");
|
|
if( isObject(%node) )
|
|
{
|
|
ObserverQueue.pushToBack(%node);
|
|
%node.delete();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if( %node.id.team > 0 )
|
|
{
|
|
ObserverQueue.pushToBack(%node);
|
|
%node.delete();
|
|
}
|
|
else if( !%client.specOnly )
|
|
{
|
|
%slot++;
|
|
%client.queueSlot = %slot;
|
|
}
|
|
else
|
|
{
|
|
%client.queueSlot = "";
|
|
}
|
|
}
|
|
}
|
|
return %slot;
|
|
}
|
|
|
|
function getClientFromQueue()
|
|
{
|
|
reindexQueue();
|
|
%count = ObserverQueue.getCount();
|
|
%client = -1;
|
|
for( %i = 0; %i < %count; %i++ )
|
|
{
|
|
%cl = ObserverQueue.getObject(%i).id;
|
|
if( %cl.queueSlot == 1 )
|
|
{
|
|
%client = %cl;
|
|
break;
|
|
}
|
|
}
|
|
return %client;
|
|
}
|
|
|
|
function TR2Game::forceObserver(%game, %client, %reason)
|
|
{
|
|
//make sure we have a valid client...
|
|
if (%client <= 0 || %client.team == 0)
|
|
return;
|
|
|
|
// TR2
|
|
// First set to outer role (just to be safe)
|
|
%game.assignOuterMostRole(%client);
|
|
|
|
// Then release client's role
|
|
%game.releaseRole(%client);
|
|
|
|
// Get rid of the corpse after the force
|
|
%client.forceRespawn = true;
|
|
%client.inSpawnBuilding = true;
|
|
|
|
// first kill this player
|
|
if(%client.player)
|
|
%client.player.scriptKill(0);
|
|
|
|
// TR2: Fix observer timeouts; for some reason %client.player is already 0
|
|
// in that case, so scriptKill() won't get called
|
|
if (%client.playerToDelete !$= "")
|
|
{
|
|
%client.enableZones = false;
|
|
%client.playerToDelete.delete();
|
|
}
|
|
|
|
if( %client.respawnTimer )
|
|
cancel(%client.respawnTimer);
|
|
|
|
%client.respawnTimer = "";
|
|
|
|
// remove them from the team rank array
|
|
%game.removeFromTeamRankArray(%client);
|
|
|
|
// place them in observer mode
|
|
%client.lastObserverSpawn = -1;
|
|
%client.observerStartTime = getSimTime();
|
|
%adminForce = 0;
|
|
|
|
switch$ ( %reason )
|
|
{
|
|
case "playerChoose":
|
|
messageClient(%client, 'MsgClientJoinTeam', '\c2You have become an observer.', %client.name, %game.getTeamName(0), %client, 0 );
|
|
echo(%client.nameBase@" (cl "@%client@") entered observer mode");
|
|
%client.lastTeam = %client.team;
|
|
%client.specOnly = true; // this guy wants to sit out...
|
|
|
|
case "AdminForce":
|
|
messageClient(%client, 'MsgClientJoinTeam', '\c2You have been forced into observer mode by the admin.', %client.name, %game.getTeamName(0), %client, 0 );
|
|
echo(%client.nameBase@" (cl "@%client@") was forced into observer mode by admin");
|
|
%client.lastTeam = %client.team;
|
|
%adminForce = 1;
|
|
|
|
if($Host::TournamentMode)
|
|
{
|
|
if(!$matchStarted)
|
|
{
|
|
if(%client.camera.Mode $= "pickingTeam")
|
|
{
|
|
commandToClient( %client, 'processPickTeam');
|
|
clearBottomPrint( %client );
|
|
}
|
|
else
|
|
{
|
|
clearCenterPrint(%client);
|
|
%client.notReady = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
case "spawnTimeout":
|
|
messageClient(%client, 'MsgClientJoinTeam', '\c2You have been placed in observer mode due to delay in respawning.', %client.name, %game.getTeamName(0), %client, 0 );
|
|
echo(%client.nameBase@" (cl "@%client@") was placed in observer mode due to spawn delay");
|
|
// save the team the player was on - only if this was a delay in respawning
|
|
%client.lastTeam = %client.team;
|
|
%client.specOnly = true; // why force an afk player back into the game?
|
|
|
|
case "specLockEnabled":
|
|
messageClient(%client, 'MsgClientJoinTeam', '\c2Spectator lock is enabled. You were automatically forced to observer.', %client.name, %game.getTeamName(0), %client, 0 );
|
|
%client.lastTeam = %client.team;
|
|
|
|
case "teamsMaxed":
|
|
messageClient(%client, 'MsgClientJoinTeam', '\c2Teams are at capacity. You were automatically forced to observer.', %client.name, %game.getTeamName(0), %client, 0 );
|
|
%client.lastTeam = %client.team;
|
|
|
|
case "gameForce":
|
|
messageClient(%client, 'MsgClientJoinTeam', '\c2You have become an observer.', %client.name, %game.getTeamName(0), %client, 0 );
|
|
%client.lastTeam = %client.team;
|
|
}
|
|
|
|
// switch client to team 0 (observer)
|
|
%client.team = 0;
|
|
%client.player.team = 0;
|
|
setTargetSensorGroup( %client.target, %client.team );
|
|
%client.setSensorGroup( %client.team );
|
|
|
|
// set their control to the obs. cam
|
|
%client.setControlObject( %client.camera );
|
|
commandToClient(%client, 'setHudMode', 'Observer');
|
|
|
|
// display the hud
|
|
//displayObserverHud(%client, 0);
|
|
updateObserverFlyHud(%client);
|
|
|
|
|
|
// message everyone about this event
|
|
if( !%adminForce )
|
|
messageAllExcept(%client, -1, 'MsgClientJoinTeam', '\c2%1 has become an observer.', %client.name, %game.getTeamName(0), %client, 0 );
|
|
else
|
|
messageAllExcept(%client, -1, 'MsgClientJoinTeam', '\c2The admin has forced %1 to become an observer.', %client.name, %game.getTeamName(0), %client, 0 );
|
|
|
|
updateCanListenState( %client );
|
|
|
|
// call the onEvent for this game type
|
|
%game.onClientEnterObserverMode(%client); //Bounty uses this to remove this client from others' hit lists
|
|
|
|
if( !%client.tr2SpecMode )
|
|
{
|
|
%client.camera.getDataBlock().setMode( %client.camera, "observerFly" );
|
|
}
|
|
else
|
|
{
|
|
if( $TheFlag.carrier.client !$= "" )
|
|
%game.observeObject(%client, $TheFlag.carrier.client, 1);
|
|
else
|
|
%game.observeObject(%client, $TheFlag, 2);
|
|
}
|
|
|
|
// Queuing...
|
|
if( %reason !$= "specLockEnabled" && %reason !$= "teamsMaxed" && !$Host::TournamentMode )
|
|
{
|
|
%vacant = ((6 * 2) - getActiveCount());
|
|
%nextCl = getClientFromQueue();
|
|
|
|
if( isObject(%nextCl) && %vacant > 0 && %nextCl.queueSlot <= %vacant )
|
|
{
|
|
%game.assignClientTeam(%nextCl, $MatchStarted );
|
|
%game.spawnPlayer(%nextCl, $MatchStarted);
|
|
}
|
|
}
|
|
addToQueue(%client);
|
|
%client.allowedToJoinTeam = 1;
|
|
}
|
|
|
|
function TR2Game::clientJoinTeam( %game, %client, %team, %fromObs )
|
|
{
|
|
//%game.assignClientTeam(%client, $MatchStarted);
|
|
if( (12 - getActiveCount()) > 0 || $Host::TournamentMode )
|
|
{
|
|
%client.allowedToJoinTeam = 1;
|
|
|
|
//first, remove the client from the team rank array
|
|
//the player will be added to the new team array as soon as he respawns...
|
|
%game.removeFromTeamRankArray(%client);
|
|
|
|
%pl = %client.player;
|
|
if(isObject(%pl))
|
|
{
|
|
if(%pl.isMounted())
|
|
%pl.getDataBlock().doDismount(%pl);
|
|
%pl.scriptKill(0);
|
|
}
|
|
|
|
// reset the client's targets and tasks only
|
|
clientResetTargets(%client, true);
|
|
|
|
// give this client a new handle to disassociate ownership of deployed objects
|
|
if( %team $= "" && (%team > 0 && %team <= %game.numTeams))
|
|
{
|
|
if( %client.team == 1 )
|
|
%client.team = 2;
|
|
else
|
|
%client.team = 1;
|
|
}
|
|
else
|
|
%client.team = %team;
|
|
|
|
// Set the client's skin:
|
|
if (!%client.isAIControlled())
|
|
setTargetSkin( %client.target, %game.getTeamSkin(%client.team) );
|
|
setTargetSensorGroup( %client.target, %client.team );
|
|
%client.setSensorGroup( %client.team );
|
|
|
|
// Spawn the player:
|
|
%game.spawnPlayer(%client, $MatchStarted);
|
|
|
|
if(%fromObs $= "" || !%fromObs)
|
|
{
|
|
messageAllExcept( %client, -1, 'MsgClientJoinTeam', '\c1%1 switched to team %2.', %client.name, %game.getTeamName(%client.team), %client, %client.team );
|
|
messageClient( %client, 'MsgClientJoinTeam', '\c1You switched to team %2.', $client.name, %game.getTeamName(%client.team), %client, %client.team );
|
|
}
|
|
else
|
|
{
|
|
messageAllExcept( %client, -1, 'MsgClientJoinTeam', '\c1%1 joined team %2.', %client.name, %game.getTeamName(%client.team), %client, %team );
|
|
messageClient( %client, 'MsgClientJoinTeam', '\c1You joined team %2.', $client.name, %game.getTeamName(%client.team), %client, %client.team );
|
|
}
|
|
|
|
updateCanListenState( %client );
|
|
|
|
// MES - switch objective hud lines when client switches teams
|
|
messageClient(%client, 'MsgCheckTeamLines', "", %client.team);
|
|
logEcho(%client.nameBase@" (cl "@%client@") switched to team "@%client.team);
|
|
|
|
|
|
removeFromQueue(%client);
|
|
}
|
|
else
|
|
{
|
|
//error("Forced to observer: " @%client.nameBase @ " via JoinTeam");
|
|
%game.forceObserver(%client, "gameForce");
|
|
}
|
|
}
|
|
// if( %client.allowedToJoinTeam == 1 )
|
|
// {
|
|
// DefaultGame::clientJoinTeam( %game, %client, %team, %respawn );
|
|
// removeFromQueue(%client);
|
|
// }
|
|
// else
|
|
// {
|
|
// %game.forceObserver(%client, "gameForce");
|
|
// }
|
|
|
|
|
|
function TR2Game::assignClientTeam(%game, %client, %respawn )
|
|
{
|
|
if( %client.team > 0 )
|
|
return;
|
|
%size[0] = 0;
|
|
%size[1] = 0;
|
|
%size[2] = 0;
|
|
%leastTeam = 0;
|
|
for( %i = 0; %i < ClientGroup.getCount(); %i++ )
|
|
{
|
|
%cl = ClientGroup.getObject(%i);
|
|
if( %cl != %client )
|
|
%size[%cl.team]++;
|
|
}
|
|
%playing = %size[1] + %size[2];
|
|
|
|
if( %playing < (6 << 1) ) // HEH HEH
|
|
{
|
|
%game.removeFromTeamRankArray(%client);
|
|
%leastTeam = (%size[1] <= %size[2]) ? 1 : 2;
|
|
removeFromQueue(%client);
|
|
|
|
%client.lastTeam = %client.team;
|
|
%client.team = %leastTeam;
|
|
|
|
|
|
// Assign the team skin:
|
|
if ( %client.isAIControlled() )
|
|
{
|
|
if ( %leastTeam & 1 )
|
|
{
|
|
%client.skin = addTaggedString( "basebot" );
|
|
setTargetSkin( %client.target, 'basebot' );
|
|
}
|
|
else
|
|
{
|
|
%client.skin = addTaggedString( "basebbot" );
|
|
setTargetSkin( %client.target, 'basebbot' );
|
|
}
|
|
}
|
|
else
|
|
setTargetSkin( %client.target, %game.getTeamSkin(%client.team) );
|
|
|
|
messageAllExcept( %client, -1, 'MsgClientJoinTeam', '\c1%1 joined %2.', %client.name, %game.getTeamName(%client.team), %client, %client.team );
|
|
messageClient( %client, 'MsgClientJoinTeam', '\c1You joined the %2 team.', %client.name, %game.getTeamName(%client.team), %client, %client.team );
|
|
|
|
updateCanListenState( %client );
|
|
|
|
clearBottomPrint(%client); // clear out the observer hud...
|
|
|
|
echo(%client.nameBase@" (cl "@%client@") joined team "@%client.team);
|
|
//error("Assigned: " @%client.nameBase @ " to team: " @ %team @ " via AssignTeam");
|
|
}
|
|
else
|
|
{
|
|
//error("Forced to observer: " @%client.nameBase @ " via AssignTeam");
|
|
%game.forceObserver(%client, "teamsMaxed");
|
|
}
|
|
// hes been checked for team join ability..
|
|
%client.allowedToJoinTeam = 1;
|
|
}
|
|
|
|
function TR2Game::ObserverOnTrigger(%game, %data, %obj, %trigger, %state)
|
|
{
|
|
//trigger types: 0:fire 1:altTrigger 2:jump 3:jet 4:throw
|
|
if (!$missionRunning)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
%client = %obj.getControllingClient();
|
|
|
|
if (!isObject(%client))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
// Knockdowns
|
|
// Moved up since players in the game should have a little priority over observers
|
|
// save a little execution time and effort :
|
|
if (%obj.mode $= "playerDeath")
|
|
{
|
|
if(!%client.waitRespawn && getSimTime() > %client.suicideRespawnTime)
|
|
{
|
|
commandToClient(%client, 'setHudMode', 'Standard');
|
|
if (%client.playerToDelete !$= "")
|
|
{
|
|
%client.enableZones = false;
|
|
%client.playerToDelete.delete();
|
|
}
|
|
|
|
// Use current flymode rotation
|
|
%transform = %client.camera.getTransform();
|
|
%oldTrans = %client.plyrTransformAtDeath;
|
|
%oldPos = getWord(%oldTrans, 0) SPC getWord(%oldTrans, 1) SPC getWord(%oldTrans, 2);
|
|
%newRot = getWord(%transform, 3) SPC getWord(%transform, 4) SPC getWord(%transform, 5) SPC getWord(%transform, 6);
|
|
%client.plyrTransformAtDeath = %oldPos SPC %newRot;
|
|
|
|
Game.spawnPlayer( %client, true );
|
|
%client.camera.setFlyMode();
|
|
%client.setControlObject(%client.player);
|
|
}
|
|
return false;
|
|
}
|
|
|
|
// Observer zoom
|
|
if( %obj.mode $= "followFlag" || %obj.mode $= "observerFollow" )
|
|
{
|
|
if( %trigger == 3 )
|
|
{
|
|
%client.obsZoomLevel++;
|
|
if (%client.obsZoomLevel >= $TR2::numObsZoomLevels)
|
|
%client.obsZoomLevel = 0;
|
|
|
|
// Move the camera
|
|
%game.observeObject(%client, %client.observeTarget, %client.observeType);
|
|
|
|
//%pos = %client.camera.getPosition();
|
|
//%rot = %client.camera
|
|
return false;
|
|
}
|
|
else
|
|
return false;
|
|
}
|
|
|
|
if( %obj.mode $= "observerFly" )
|
|
{
|
|
// unfortunately, it seems that sometimes the "observer speed up" thing doesn't always happen...
|
|
if (%trigger == 0)
|
|
{
|
|
clearBottomPrint(%client);
|
|
return false;
|
|
}
|
|
//press JET
|
|
else if (%trigger == 3)
|
|
{
|
|
%markerObj = Game.pickObserverSpawn(%client, true);
|
|
%transform = %markerObj.getTransform();
|
|
%obj.setTransform(%transform);
|
|
%obj.setFlyMode();
|
|
clearBottomPrint(%client);
|
|
return false;
|
|
}
|
|
//press JUMP
|
|
else if (%trigger == 2)
|
|
{
|
|
clearBottomPrint(%client);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
if( %obj.mode $= "pre-game" )
|
|
{
|
|
return true; // use default action
|
|
}
|
|
|
|
if( %obj.mode $= "justJoined" )
|
|
{
|
|
if( !$TR2::SpecLock && !$Host::TournamentMode )
|
|
{
|
|
if( %client.team <= 0 )
|
|
{
|
|
if( getActiveCount() < ($TR2::DefaultTeamSize * 2) )
|
|
{
|
|
%game.assignClientTeam(%client, 0);
|
|
%game.spawnPlayer(%client, 0);
|
|
}
|
|
else
|
|
{
|
|
%game.forceObserver(%client, "teamsMaxed");
|
|
}
|
|
}
|
|
else if( %client.team >= 1 )
|
|
{
|
|
%game.spawnPlayer(%client, 0);
|
|
}
|
|
|
|
if( isObject(%client.player) ) // player was successfully created...
|
|
{
|
|
if(!$MatchStarted && !$CountdownStarted)
|
|
%client.camera.getDataBlock().setMode( %client.camera, "pre-game", %client.player );
|
|
else if(!$MatchStarted && $CountdownStarted)
|
|
%client.camera.getDataBlock().setMode( %client.camera, "pre-game", %client.player );
|
|
else
|
|
{
|
|
%client.camera.setFlyMode();
|
|
commandToClient(%client, 'setHudMode', 'Standard');
|
|
%client.setControlObject( %client.player );
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// kind of weak, but tourney mode *is* a form of spec lock :/
|
|
%game.forceObserver(%client, "specLockEnabled");
|
|
}
|
|
return false;
|
|
}
|
|
|
|
// Queue
|
|
if( %trigger == 0 )
|
|
{
|
|
if( %obj.mode !$= "playerDeath" )
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
|
|
|