Initial commit
This commit is contained in:
404
Torque/SDK/example/demo/server/scripts/game.cs
Normal file
404
Torque/SDK/example/demo/server/scripts/game.cs
Normal file
@@ -0,0 +1,404 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Torque Game Engine
|
||||
// Copyright (C) GarageGames.com, Inc.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// Game duration in secs, no limit if the duration is set to 0
|
||||
$Game::Duration = 20 * 60;
|
||||
|
||||
// When a client score reaches this value, the game is ended.
|
||||
$Game::EndGameScore = 30;
|
||||
|
||||
// Pause while looking over the end game screen (in secs)
|
||||
$Game::EndGamePause = 10;
|
||||
|
||||
$BlockSave = 0;
|
||||
//-----------------------------------------------------------------------------
|
||||
// Functions that implement game-play
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
function onServerCreated()
|
||||
{
|
||||
// Server::GameType is sent to the master server.
|
||||
// This variable should uniquely identify your game and/or mod.
|
||||
$Server::GameType = "TGE Demo";
|
||||
|
||||
// Server::MissionType sent to the master server. Clients can
|
||||
// filter servers based on mission type.
|
||||
$Server::MissionType = "Demo Match";
|
||||
|
||||
// GameStartTime is the sim time the game started. Used to calculated
|
||||
// game elapsed time.
|
||||
$Game::StartTime = 0;
|
||||
|
||||
// Load up basic datablocks, objects etc.
|
||||
exec("./audioProfiles.cs");
|
||||
exec("./camera.cs");
|
||||
exec("./markers.cs");
|
||||
exec("./triggers.cs");
|
||||
exec("./inventory.cs");
|
||||
exec("./shapeBase.cs");
|
||||
exec("./staticShape.cs");
|
||||
exec("./radiusDamage.cs");
|
||||
exec("./chimneyfire.cs");
|
||||
exec("./item.cs");
|
||||
exec("./weapon.cs");
|
||||
exec("./flag.cs");
|
||||
|
||||
// Room demo...
|
||||
exec("./scene.cs");
|
||||
exec("./fxlights.cs");
|
||||
exec("./environment.cs");
|
||||
|
||||
// Fps game...
|
||||
exec("./fps.cs");
|
||||
exec("./player.cs");
|
||||
exec("./aiPlayer.cs");
|
||||
exec("./crossbow.cs");
|
||||
|
||||
// Racing game...
|
||||
exec("./racing.cs");
|
||||
exec("./car.cs");
|
||||
|
||||
// Keep track of when the game started
|
||||
$Game::StartTime = $Sim::Time;
|
||||
}
|
||||
|
||||
function onServerDestroyed()
|
||||
{
|
||||
// This function is called as part of a server shutdown.
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
function onMissionLoaded()
|
||||
{
|
||||
// Called by loadMission() once the mission is finished loading.
|
||||
// Nothing special for now, just start up the game play.
|
||||
|
||||
// Determin what type of game play we have and activate the
|
||||
// associated package.
|
||||
echo("Mission Type: " @ MissionInfo.type);
|
||||
activatePackage(MissionInfo.type @ "Game");
|
||||
|
||||
// Override the default game type
|
||||
$Server::GameType = MissionInfo.type;
|
||||
$Server::MissionType = "Play";
|
||||
$Game::Duration = 0;
|
||||
|
||||
if (MissionInfo.type $= "DemoScene") $BlockSave = 1;
|
||||
else $BlockSave = 0;
|
||||
// Start game play, this doesn't wait players...
|
||||
startGame();
|
||||
}
|
||||
|
||||
function onMissionEnded()
|
||||
{
|
||||
// Called by endMission(), right before the mission is destroyed
|
||||
|
||||
// Normally the game should be ended first before the next
|
||||
// mission is loaded, this is here in case loadMission has been
|
||||
// called directly. The mission will be ended if the server
|
||||
// is destroyed, so we only need to cleanup here.
|
||||
deactivatePackage($Server::GameType @ "Game");
|
||||
cancel($Game::Schedule);
|
||||
$Game::Running = false;
|
||||
$Game::Cycling = false;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
function startGame()
|
||||
{
|
||||
// Start up the game. Normally only called once ater a mission is loaded,
|
||||
// but theoretically a game can be stopped and restarted without reloading
|
||||
// the mission.
|
||||
if ($Game::Running) {
|
||||
error("startGame: End the game first!");
|
||||
return;
|
||||
}
|
||||
|
||||
// Inform the client we're starting up
|
||||
for( %clientIndex = 0; %clientIndex < ClientGroup.getCount(); %clientIndex++ ) {
|
||||
%cl = ClientGroup.getObject( %clientIndex );
|
||||
commandToClient(%cl, 'GameStart');
|
||||
|
||||
// Other client specific setup..
|
||||
%cl.score = 0;
|
||||
}
|
||||
|
||||
// Start the game timer
|
||||
if ($Game::Duration)
|
||||
$Game::Schedule = schedule($Game::Duration * 1000, 0, "onGameDurationEnd" );
|
||||
|
||||
$Game::Running = true;
|
||||
}
|
||||
|
||||
function endGame()
|
||||
{
|
||||
// Game specific cleanup...
|
||||
if (!$Game::Running) {
|
||||
error("endGame: No game running!");
|
||||
return;
|
||||
}
|
||||
|
||||
// Stop any game timers
|
||||
cancel($Game::Schedule);
|
||||
|
||||
// Inform the client the game is over
|
||||
for( %clientIndex = 0; %clientIndex < ClientGroup.getCount(); %clientIndex++ ) {
|
||||
%cl = ClientGroup.getObject( %clientIndex );
|
||||
commandToClient(%cl, 'GameEnd');
|
||||
}
|
||||
|
||||
// Delete all the temporary mission objects
|
||||
resetMission();
|
||||
$Game::Running = false;
|
||||
}
|
||||
|
||||
function onGameDurationEnd()
|
||||
{
|
||||
// This "redirect" is here so that we can abort the game cycle if
|
||||
// the $Game::Duration variable has been cleared, without having
|
||||
// to have a function to cancel the schedule.
|
||||
if ($Game::Duration && !isObject(EditorGui))
|
||||
cycleGame();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
function cycleGame()
|
||||
{
|
||||
// This is setup as a schedule so that this function can be called
|
||||
// directly from object callbacks. Object callbacks have to be
|
||||
// carefull about invoking server functions that could cause
|
||||
// their object to be deleted.
|
||||
if (!$Game::Cycling) {
|
||||
$Game::Cycling = true;
|
||||
$Game::Schedule = schedule(0, 0, "onCycleExec");
|
||||
}
|
||||
}
|
||||
|
||||
function onCycleExec()
|
||||
{
|
||||
// End the current game and start another one, we'll pause for a little
|
||||
// so the end game victory screen can be examined by the clients.
|
||||
endGame();
|
||||
$Game::Schedule = schedule($Game::EndGamePause * 1000, 0, "onCyclePauseEnd");
|
||||
}
|
||||
|
||||
function onCyclePauseEnd()
|
||||
{
|
||||
$Game::Cycling = false;
|
||||
|
||||
// Just cycle through the missions for now.
|
||||
%search = $Server::MissionFileSpec;
|
||||
for (%file = findFirstFile(%search); %file !$= ""; %file = findNextFile(%search)) {
|
||||
if (%file $= $Server::MissionFile) {
|
||||
// Get the next one, back to the first if there
|
||||
// is no next.
|
||||
%file = findNextFile(%search);
|
||||
if (%file $= "")
|
||||
%file = findFirstFile(%search);
|
||||
break;
|
||||
}
|
||||
}
|
||||
loadMission(%file);
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
function Game::onClientEnterGame(%this,%client)
|
||||
{
|
||||
// Player has joined the game, normally called when a
|
||||
// new client has connected to the server.
|
||||
}
|
||||
|
||||
function Game::onLeaveEnterGame(%this,%client)
|
||||
{
|
||||
// Player has left the game, normally called when a client
|
||||
// disconnects from the server.
|
||||
}
|
||||
|
||||
function Game::onDeath(%this,%player,%sourceObject, %sourceClient, %damageType, %damLoc)
|
||||
{
|
||||
// Invoked when a client has died.
|
||||
}
|
||||
|
||||
function Game::onLeaveMissionArea(%this,%player)
|
||||
{
|
||||
// The control objects invoked this method when they
|
||||
// move out of the mission area.
|
||||
}
|
||||
|
||||
function Game::onEnterMissionArea(%this,%player)
|
||||
{
|
||||
// The control objects invoked this method when they
|
||||
// move back into the mission area.
|
||||
}
|
||||
|
||||
function Game::spawnPlayer(%this,%client)
|
||||
{
|
||||
// Create a new player for the client and drop him into the world.
|
||||
}
|
||||
|
||||
function Game::createPlayer(%this, %client, %location)
|
||||
{
|
||||
// Create a new player for the client and start him at the
|
||||
// given location.
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// GameConnection Methods
|
||||
// These methods are extensions to the GameConnection class. Extending
|
||||
// GameConnection make is easier to deal with some of this functionality,
|
||||
// but these could also be implemented as stand-alone functions.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
function GameConnection::onClientEnterGame(%this)
|
||||
{
|
||||
commandToClient(%this, 'SyncClock', $Sim::Time - $Game::StartTime);
|
||||
commandToClient(%this, 'SetGameGUI',"PlayGUI");
|
||||
|
||||
// Create a new camera object.
|
||||
%this.camera = new Camera() {
|
||||
dataBlock = Observer;
|
||||
};
|
||||
MissionCleanup.add( %this.camera );
|
||||
%this.camera.scopeToClient(%this);
|
||||
|
||||
// Spawn the player
|
||||
%this.score = 0;
|
||||
%this.spawnPlayer();
|
||||
}
|
||||
|
||||
function GameConnection::onClientLeaveGame(%this)
|
||||
{
|
||||
if (isObject(%this.camera))
|
||||
%this.camera.delete();
|
||||
if (isObject(%this.player))
|
||||
%this.player.delete();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
function GameConnection::onLeaveMissionArea(%this)
|
||||
{
|
||||
// The control objects invoked this method when they
|
||||
// move out of the mission area.
|
||||
}
|
||||
|
||||
function GameConnection::onEnterMissionArea(%this)
|
||||
{
|
||||
// The control objects invoked this method when they
|
||||
// move back into the mission area.
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
function GameConnection::onDeath(%this, %sourceObject, %sourceClient, %damageType, %damLoc)
|
||||
{
|
||||
// Clear out the name on the corpse
|
||||
%this.player.setShapeName("");
|
||||
|
||||
// Switch the client over to the death cam and unhook the player object.
|
||||
if (isObject(%this.camera) && isObject(%this.player)) {
|
||||
%this.camera.setMode("Corpse",%this.player);
|
||||
%this.setControlObject(%this.camera);
|
||||
}
|
||||
%this.player = 0;
|
||||
|
||||
// Doll out points and display an appropriate message
|
||||
if (%damageType $= "Suicide" || %sourceClient == %this) {
|
||||
%this.incScore(-1);
|
||||
messageAll('MsgClientKilled','%1 takes his own life!',%this.name);
|
||||
}
|
||||
else {
|
||||
%sourceClient.incScore(1);
|
||||
messageAll('MsgClientKilled','%1 gets nailed by %2!',%this.name,%sourceClient.name);
|
||||
if (%sourceClient.score >= $Game::EndGameScore)
|
||||
cycleGame();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
function GameConnection::spawnPlayer(%this)
|
||||
{
|
||||
// Combination create player and drop him somewhere
|
||||
%spawnPoint = pickSpawnPoint();
|
||||
%this.createPlayer(%spawnPoint);
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
function GameConnection::createPlayer(%this, %spawnPoint)
|
||||
{
|
||||
if (%this.player > 0) {
|
||||
// The client should not have a player currently
|
||||
// assigned. Assigning a new one could result in
|
||||
// a player ghost.
|
||||
error( "Attempting to create an angus ghost!" );
|
||||
}
|
||||
|
||||
// Create the player object
|
||||
%player = new Player() {
|
||||
dataBlock = PlayerBody;
|
||||
client = %this;
|
||||
};
|
||||
MissionCleanup.add(%player);
|
||||
|
||||
// Player setup...
|
||||
%player.setTransform(%spawnPoint);
|
||||
%player.setEnergyLevel(60);
|
||||
%player.setShapeName(%this.name);
|
||||
|
||||
// Update the camera to start with the player
|
||||
%this.camera.setTransform(%player.getEyeTransform());
|
||||
|
||||
// Give the client control of the player
|
||||
%this.player = %player;
|
||||
%this.setControlObject(%player);
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Support functions
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
function pickSpawnPoint()
|
||||
{
|
||||
%groupName = "MissionGroup/PlayerDropPoints";
|
||||
%group = nameToID(%groupName);
|
||||
|
||||
if (%group != -1) {
|
||||
%count = %group.getCount();
|
||||
if (%count != 0) {
|
||||
%index = getRandom(%count-1);
|
||||
%spawn = %group.getObject(%index);
|
||||
return %spawn.getTransform();
|
||||
}
|
||||
else
|
||||
error("No spawn points found in " @ %groupName);
|
||||
}
|
||||
else
|
||||
error("Missing spawn points group " @ %groupName);
|
||||
|
||||
// Could be no spawn points, in which case we'll stick the
|
||||
// player at the center of the world.
|
||||
return "0 0 300 1 0 0 0";
|
||||
}
|
||||
Reference in New Issue
Block a user