mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-07-14 16:14:38 +00:00
Core now spawns a ControlObject directly, with callbacks allowing overriding of values to control what spawns (and what occurs afterwards) to tie several tracking variables to a given client connection.
By default this list of variables would be:
%this.spawnClass = "Camera";
%this.spawnDBType = "CameraData";
%this.spawnDataBlock = "Observer";
%this.playerSpawnGroups = "PlayerSpawnPoints PlayerDropPoints";
%this.spawnPoint = "";
%this.spawnLocation = "0 0 0";
Also adds several callbacks so that these values can be overridden by modules and gamemodes, kicked off from the %client.spawnControlObject(); command :
callOnModules("setSpawnObjectType", "Game", %this);
callGamemodeFunction("setSpawnObjectType", %this);
callOnModules("setSpawnPoint", "Game", %this);
callGamemodeFunction("setSpawnPoint", %this);
callOnModules("onPostSpawn", "Game", %this);
callGamemodeFunction("onPostSpawn", %this);
This is to ensure that a game mode can supersede modules, but even modules can dictate spawn behaviors for minimalist implementations and drop-in interop support
This commit is contained in:
parent
a88aa7a007
commit
c5ae9af0ae
3 changed files with 110 additions and 108 deletions
|
|
@ -27,7 +27,7 @@
|
||||||
// anything else will be sent back as an error to the client.
|
// anything else will be sent back as an error to the client.
|
||||||
// All the connect args are passed also to onConnectRequest
|
// All the connect args are passed also to onConnectRequest
|
||||||
//
|
//
|
||||||
function GameConnection::onConnectRequest( %client, %netAddress, %name )
|
function GameConnection::onConnectRequest( %this, %netAddress, %name )
|
||||||
{
|
{
|
||||||
echo("Connect request from: " @ %netAddress);
|
echo("Connect request from: " @ %netAddress);
|
||||||
if($Server::PlayerCount >= $pref::Server::MaxPlayers)
|
if($Server::PlayerCount >= $pref::Server::MaxPlayers)
|
||||||
|
|
@ -47,11 +47,11 @@ function GameConnection::onConnect( %this, %clientData )
|
||||||
sendLoadInfoToClient(%this);
|
sendLoadInfoToClient(%this);
|
||||||
|
|
||||||
// Simulated client lag for testing...
|
// Simulated client lag for testing...
|
||||||
// %client.setSimulatedNetParams(0.1, 30);
|
// %this.setSimulatedNetParams(0.1, 30);
|
||||||
|
|
||||||
// Get the client's unique id:
|
// Get the client's unique id:
|
||||||
// %authInfo = %client.getAuthInfo();
|
// %authInfo = %this.getAuthInfo();
|
||||||
// %client.guid = getField(%authInfo, 3);
|
// %this.guid = getField(%authInfo, 3);
|
||||||
%this.guid = 0;
|
%this.guid = 0;
|
||||||
addToServerGuidList(%this.guid);
|
addToServerGuidList(%this.guid);
|
||||||
|
|
||||||
|
|
@ -86,14 +86,110 @@ function GameConnection::onConnect( %this, %clientData )
|
||||||
$Server::PlayerCount++;
|
$Server::PlayerCount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function GameConnection::spawnControlObject( %this )
|
||||||
|
{
|
||||||
|
//baseline controlObject spawn type with extention points
|
||||||
|
%this.spawnClass = "Camera";
|
||||||
|
%this.spawnDBType = "CameraData";
|
||||||
|
%this.spawnDataBlock = "Observer";
|
||||||
|
callOnModules("setSpawnObjectType", "Game", %this);
|
||||||
|
callGamemodeFunction("setSpawnObjectType", %this);
|
||||||
|
}
|
||||||
|
|
||||||
|
function GameConnection::onSetSpawnObjectTypeComplete( %this )
|
||||||
|
{
|
||||||
|
if (isObject(%this.player))
|
||||||
|
{
|
||||||
|
// The client should not already have a player. Assigning
|
||||||
|
// a new one could result in an uncontrolled player object.
|
||||||
|
error("Attempting to create a player for a client that already has one!");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Spawn with the engine's Sim::spawnObject() function
|
||||||
|
%this.player = spawnObject(%this.spawnClass, %this.spawnDataBlock);
|
||||||
|
|
||||||
|
if (!%this.player.isMemberOfClass(%this.spawnClass))
|
||||||
|
warn("Trying to spawn a class that does not derive from "@ %this.spawnClass);
|
||||||
|
|
||||||
|
// Add the player object to MissionCleanup so that it
|
||||||
|
// won't get saved into the level files and will get
|
||||||
|
// cleaned up properly
|
||||||
|
MissionCleanup.add(%this.player);
|
||||||
|
|
||||||
|
// Store the client object on the player object for
|
||||||
|
// future reference
|
||||||
|
%this.player.client = %this;
|
||||||
|
|
||||||
|
%this.setSpawnPoint();
|
||||||
|
|
||||||
|
// Give the client control of the camera if in the editor
|
||||||
|
if( $startWorldEditor )
|
||||||
|
{
|
||||||
|
%control = %this.camera;
|
||||||
|
%control.mode = "Fly";
|
||||||
|
EditorGui.syncCameraGui();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
%control = %this.player;
|
||||||
|
|
||||||
|
// Allow the player/camera to receive move data from the GameConnection. Without this
|
||||||
|
// the user is unable to control the player/camera.
|
||||||
|
if (!isDefined("%noControl"))
|
||||||
|
%this.setControlObject(%control);
|
||||||
|
}
|
||||||
|
|
||||||
|
function GameConnection::setSpawnPoint( %this )
|
||||||
|
{
|
||||||
|
//baseline spawn point config rules with extention points
|
||||||
|
%this.playerSpawnGroups = "PlayerSpawnPoints PlayerDropPoints";
|
||||||
|
%this.spawnPoint = "";
|
||||||
|
%this.spawnLocation = "0 0 0";
|
||||||
|
callOnModules("setSpawnPoint", "Game", %this);
|
||||||
|
callGamemodeFunction("setSpawnPoint", %this);
|
||||||
|
}
|
||||||
|
|
||||||
|
function GameConnection::onSetSpawnPointComplete( %this )
|
||||||
|
{
|
||||||
|
if (isObject(%this.player))
|
||||||
|
%this.player.setTransform(%this.spawnLocation);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// If we weren't able to create the player object then warn the user
|
||||||
|
// When the player clicks OK in one of these message boxes, we will fall through
|
||||||
|
// to the "if (!isObject(%player))" check below.
|
||||||
|
if (isDefined("%this.spawnDataBlock"))
|
||||||
|
{
|
||||||
|
MessageBoxOK("Spawn Failed",
|
||||||
|
"Unable to create a player with class " @ %this.spawnClass @
|
||||||
|
" and datablock " @ %this.spawnDataBlock @ ".\n\nStarting as an Observer instead.",
|
||||||
|
"");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MessageBoxOK("Spawn Failed",
|
||||||
|
"Unable to create a player with class " @ %this.spawnClass @
|
||||||
|
".\n\nStarting as an Observer instead.",
|
||||||
|
"");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
%this.onPostSpawn();
|
||||||
|
}
|
||||||
|
|
||||||
|
function GameConnection::onPostSpawn( %this )
|
||||||
|
{
|
||||||
|
//post controlObject create extention points
|
||||||
|
callOnModules("onPostSpawn", "Game", %this);
|
||||||
|
callGamemodeFunction("onPostSpawn", %this);
|
||||||
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// A player's name could be obtained from the auth server, but for
|
// A player's name could be obtained from the auth server, but for
|
||||||
// now we use the one passed from the client.
|
// now we use the one passed from the client.
|
||||||
// %realName = getField( %authInfo, 0 );
|
// %realName = getField( %authInfo, 0 );
|
||||||
//
|
//
|
||||||
function GameConnection::setPlayerName(%client,%name)
|
function GameConnection::setPlayerName(%this,%name)
|
||||||
{
|
{
|
||||||
%client.sendGuid = 0;
|
%this.sendGuid = 0;
|
||||||
|
|
||||||
// Minimum length requirements
|
// Minimum length requirements
|
||||||
%name = trim( strToPlayerName( %name ) );
|
%name = trim( strToPlayerName( %name ) );
|
||||||
|
|
@ -112,8 +208,8 @@ function GameConnection::setPlayerName(%client,%name)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tag the name with the "smurf" color:
|
// Tag the name with the "smurf" color:
|
||||||
%client.nameBase = %name;
|
%this.nameBase = %name;
|
||||||
%client.playerName = addTaggedString("\cp\c8" @ %name @ "\co");
|
%this.playerName = addTaggedString("\cp\c8" @ %name @ "\co");
|
||||||
}
|
}
|
||||||
|
|
||||||
function isNameUnique(%name)
|
function isNameUnique(%name)
|
||||||
|
|
@ -132,7 +228,7 @@ function isNameUnique(%name)
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// This function is called when a client drops for any reason
|
// This function is called when a client drops for any reason
|
||||||
//
|
//
|
||||||
function GameConnection::onDrop(%client, %reason)
|
function GameConnection::onDrop(%this, %reason)
|
||||||
{
|
{
|
||||||
%entityIds = parseMissionGroupForIds("Entity", "");
|
%entityIds = parseMissionGroupForIds("Entity", "");
|
||||||
%entityCount = getWordCount(%entityIds);
|
%entityCount = getWordCount(%entityIds);
|
||||||
|
|
@ -148,15 +244,15 @@ function GameConnection::onDrop(%client, %reason)
|
||||||
%entityIds = %entityIds SPC %child.getID();
|
%entityIds = %entityIds SPC %child.getID();
|
||||||
}
|
}
|
||||||
|
|
||||||
%entity.notify("onClientDisconnect", %client);
|
%entity.notify("onClientDisconnect", %this);
|
||||||
}
|
}
|
||||||
|
|
||||||
if($missionRunning)
|
if($missionRunning)
|
||||||
{
|
{
|
||||||
%hasGameMode = callGamemodeFunction("onClientLeaveGame", %client);
|
%hasGameMode = callGamemodeFunction("onClientLeaveGame", %this);
|
||||||
}
|
}
|
||||||
|
|
||||||
removeFromServerGuidList( %client.guid );
|
removeFromServerGuidList( %this.guid );
|
||||||
|
|
||||||
$Server::PlayerCount--;
|
$Server::PlayerCount--;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -178,6 +178,8 @@ function serverCmdMissionStartPhase3Ack(%client, %seq)
|
||||||
%client.currentPhase = 3;
|
%client.currentPhase = 3;
|
||||||
|
|
||||||
%hasGameMode = callGamemodeFunction("onClientEnterGame", %client);
|
%hasGameMode = callGamemodeFunction("onClientEnterGame", %client);
|
||||||
|
|
||||||
|
%client.spawnControlObject();
|
||||||
|
|
||||||
//if that also failed, just spawn a camera
|
//if that also failed, just spawn a camera
|
||||||
if(%hasGameMode == 0)
|
if(%hasGameMode == 0)
|
||||||
|
|
|
||||||
|
|
@ -51,16 +51,6 @@ function ExampleGameMode::onMissionReset(%this)
|
||||||
|
|
||||||
function ExampleGameMode::initGameVars(%this)
|
function ExampleGameMode::initGameVars(%this)
|
||||||
{
|
{
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
// What kind of "camera" is spawned is either controlled directly by the
|
|
||||||
// SpawnSphere or it defaults back to the values set here. This also controls
|
|
||||||
// which SimGroups to attempt to select the spawn sphere's from by walking down
|
|
||||||
// the list of SpawnGroups till it finds a valid spawn object.
|
|
||||||
// These override the values set in core/scripts/server/spawn.cs
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
%this.defaultCameraClass = "Camera";
|
|
||||||
%this.defaultCameraDataBlock = "Observer";
|
|
||||||
%this.defaultCameraSpawnGroups = "CameraSpawnPoints PlayerSpawnPoints PlayerDropPoints";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function ExampleGameMode::onGameDurationEnd(%this)
|
function ExampleGameMode::onGameDurationEnd(%this)
|
||||||
|
|
@ -82,15 +72,6 @@ function ExampleGameMode::onClientEnterGame(%this, %client)
|
||||||
//Set the player name based on the client's connection data
|
//Set the player name based on the client's connection data
|
||||||
%client.setPlayerName(%client.connectData);
|
%client.setPlayerName(%client.connectData);
|
||||||
|
|
||||||
// Find a spawn point for the camera
|
|
||||||
// This function currently relies on some helper functions defined in
|
|
||||||
// core/scripts/server/spawn.cs. For custom spawn behaviors one can either
|
|
||||||
// override the properties on the SpawnSphere's or directly override the
|
|
||||||
// functions themselves.
|
|
||||||
%cameraSpawnPoint = %this.pickCameraSpawnPoint(%this.DefaultCameraSpawnGroups);
|
|
||||||
// Spawn a camera for this client using the found %spawnPoint
|
|
||||||
%this.spawnCamera(%client, %cameraSpawnPoint);
|
|
||||||
|
|
||||||
// Inform the client of all the other clients
|
// Inform the client of all the other clients
|
||||||
%count = ClientGroup.getCount();
|
%count = ClientGroup.getCount();
|
||||||
for (%cl = 0; %cl < %count; %cl++)
|
for (%cl = 0; %cl < %count; %cl++)
|
||||||
|
|
@ -175,81 +156,4 @@ function ExampleGameMode::onSubsceneUnloaded(%this)
|
||||||
{
|
{
|
||||||
echo("===================================");
|
echo("===================================");
|
||||||
echo("ExampleGameMode - Subscene is unloaded");
|
echo("ExampleGameMode - Subscene is unloaded");
|
||||||
}
|
|
||||||
|
|
||||||
function ExampleGameMode::spawnCamera(%this, %client, %spawnPoint)
|
|
||||||
{
|
|
||||||
// Set the control object to the default camera
|
|
||||||
if (!isObject(%client.camera))
|
|
||||||
{
|
|
||||||
if (%this.defaultCameraClass !$= "")
|
|
||||||
%client.camera = spawnObject(%this.defaultCameraClass, %this.defaultCameraDataBlock);
|
|
||||||
}
|
|
||||||
|
|
||||||
// If we have a camera then set up some properties
|
|
||||||
if (isObject(%client.camera))
|
|
||||||
{
|
|
||||||
MissionCleanup.add( %client.camera );
|
|
||||||
%client.camera.scopeToClient(%client);
|
|
||||||
|
|
||||||
%client.setControlObject(%client.camera);
|
|
||||||
|
|
||||||
if(!isObject(%spawnPoint))
|
|
||||||
%spawnPoint = %this.pickCameraSpawnPoint(%this.defaultCameraSpawnGroups);
|
|
||||||
|
|
||||||
if (isObject(%spawnPoint))
|
|
||||||
{
|
|
||||||
// Attempt to treat %spawnPoint as an object
|
|
||||||
if (getWordCount(%spawnPoint) == 1 && isObject(%spawnPoint))
|
|
||||||
{
|
|
||||||
%client.camera.setTransform(%spawnPoint.getTransform());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Treat %spawnPoint as an AxisAngle transform
|
|
||||||
%client.camera.setTransform(%spawnPoint);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
// pickCameraSpawnPoint() is responsible for finding a valid spawn point for a
|
|
||||||
// camera.
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
function ExampleGameMode::pickCameraSpawnPoint(%this, %spawnGroups)
|
|
||||||
{
|
|
||||||
// Walk through the groups until we find a valid object
|
|
||||||
for (%i = 0; %i < getWordCount(%spawnGroups); %i++)
|
|
||||||
{
|
|
||||||
%group = getWord(%spawnGroups, %i);
|
|
||||||
|
|
||||||
%count = getWordCount(%group);
|
|
||||||
|
|
||||||
if (isObject(%group))
|
|
||||||
%spawnPoint = %group.getRandom();
|
|
||||||
|
|
||||||
if (isObject(%spawnPoint))
|
|
||||||
return %spawnPoint;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Didn't find a spawn point by looking for the groups
|
|
||||||
// so let's return the "default" SpawnSphere
|
|
||||||
// First create it if it doesn't already exist
|
|
||||||
if (!isObject(DefaultCameraSpawnSphere))
|
|
||||||
{
|
|
||||||
%spawn = new SpawnSphere(DefaultCameraSpawnSphere)
|
|
||||||
{
|
|
||||||
dataBlock = "SpawnSphereMarker";
|
|
||||||
spawnClass = $Game::DefaultCameraClass;
|
|
||||||
spawnDatablock = $Game::DefaultCameraDataBlock;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Add it to the MissionCleanup group so that it
|
|
||||||
// doesn't get saved to the Mission (and gets cleaned
|
|
||||||
// up of course)
|
|
||||||
MissionCleanup.add(%spawn);
|
|
||||||
}
|
|
||||||
|
|
||||||
return DefaultCameraSpawnSphere;
|
|
||||||
}
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue