| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725 |
- //-----------------------------------------------------------------------------
- // Copyright (c) 2012 GarageGames, LLC
- //
- // Permission is hereby granted, free of charge, to any person obtaining a copy
- // of this software and associated documentation files (the "Software"), to
- // deal in the Software without restriction, including without limitation the
- // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- // sell copies of the Software, and to permit persons to whom the Software is
- // furnished to do so, subject to the following conditions:
- //
- // The above copyright notice and this permission notice shall be included in
- // all copies or substantial portions of the Software.
- //
- // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- // IN THE SOFTWARE.
- //-----------------------------------------------------------------------------
- // ----------------------------------------------------------------------------
- // DeathmatchGame
- // ----------------------------------------------------------------------------
- // Depends on methods found in gameCore.cs. Those added here are specific to
- // this game type and/or over-ride the "default" game functionaliy.
- //
- // The desired Game Type must be added to each mission's LevelInfo object.
- // - gameType = "Deathmatch";
- // If this information is missing then the GameCore will default to Deathmatch.
- // ----------------------------------------------------------------------------
- function DeathMatchGame::initGameVars(%game)
- {
- //echo (%game @"\c4 -> "@ %game.class @" -> DeathMatchGame::initGameVars");
- //-----------------------------------------------------------------------------
- // What kind of "player" 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
- //-----------------------------------------------------------------------------
-
- // Leave $Game::defaultPlayerClass and $Game::defaultPlayerDataBlock as empty strings ("")
- // to spawn a the $Game::defaultCameraClass as the control object.
- $Game::defaultPlayerClass = "Player";
- $Game::defaultPlayerDataBlock = "DefaultPlayerData";
- $Game::defaultPlayerSpawnGroups = "PlayerSpawnPoints PlayerDropPoints";
- //-----------------------------------------------------------------------------
- // 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
- //-----------------------------------------------------------------------------
- $Game::defaultCameraClass = "Camera";
- $Game::defaultCameraDataBlock = "Observer";
- $Game::defaultCameraSpawnGroups = "CameraSpawnPoints PlayerSpawnPoints PlayerDropPoints";
- // Set the gameplay parameters
- %game.duration = 30 * 60;
- %game.endgameScore = 20;
- %game.endgamePause = 10;
- %game.allowCycling = false; // Is mission cycling allowed?
- }
- function DeathMatchGame::onGameDurationEnd(%game)
- {
- // 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 && !(EditorIsActive() && GuiEditorIsActive()))
- Game.onGameDurationEnd();
- }
- function DeathMatchGame::onClientEnterGame(%this, %client)
- {
- // This function currently relies on some helper functions defined in
- // core/scripts/spawn.cs. For custom spawn behaviors one can either
- // override the properties on the SpawnSphere's or directly override the
- // functions themselves.
- //echo (%game @"\c4 -> "@ %game.class @" -> GameCore::onClientEntergame");
- // Sync the client's clocks to the server's
- commandToClient(%client, 'SyncClock', $Sim::Time - $Game::StartTime);
-
- //Set the player name based on the client's connection data
- %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 = pickCameraSpawnPoint($Game::DefaultCameraSpawnGroups);
- // Spawn a camera for this client using the found %spawnPoint
- %client.spawnCamera(%cameraSpawnPoint);
- // Setup game parameters, the onConnect method currently starts
- // everyone with a 0 score.
- %client.score = 0;
- %client.kills = 0;
- %client.deaths = 0;
- // weaponHUD
- %client.RefreshWeaponHud(0, "", "");
- // Prepare the player object.
- %this.preparePlayer(%client);
- // Inform the client of all the other clients
- %count = ClientGroup.getCount();
- for (%cl = 0; %cl < %count; %cl++)
- {
- %other = ClientGroup.getObject(%cl);
- if ((%other != %client))
- {
- // These should be "silent" versions of these messages...
- messageClient(%client, 'MsgClientJoin', "",
- %other.playerName,
- %other,
- %other.sendGuid,
- %other.team,
- %other.score,
- %other.kills,
- %other.deaths,
- %other.isAIControlled(),
- %other.isAdmin,
- %other.isSuperAdmin);
- }
- }
- // Inform the client we've joined up
- messageClient(%client,
- 'MsgClientJoin', '\c2Welcome to the Torque demo app %1.',
- %client.playerName,
- %client,
- %client.sendGuid,
- %client.team,
- %client.score,
- %client.kills,
- %client.deaths,
- %client.isAiControlled(),
- %client.isAdmin,
- %client.isSuperAdmin);
- // Inform all the other clients of the new guy
- messageAllExcept(%client, -1, 'MsgClientJoin', '\c1%1 joined the game.',
- %client.playerName,
- %client,
- %client.sendGuid,
- %client.team,
- %client.score,
- %client.kills,
- %client.deaths,
- %client.isAiControlled(),
- %client.isAdmin,
- %client.isSuperAdmin);
- }
- function DeathMatchGame::onClientLeaveGame(%this, %client)
- {
- // Cleanup the camera
- if (isObject(%this.camera))
- %this.camera.delete();
- }
- //-----------------------------------------------------------------------------
- // The server has started up so do some game start up
- //-----------------------------------------------------------------------------
- function DeathMatchGame::onMissionStart(%this)
- {
- //set up the game and game variables
- %this.initGameVars();
- $Game::Duration = %this.duration;
- $Game::EndGameScore = %this.endgameScore;
- $Game::EndGamePause = %this.endgamePause;
-
- //echo (%game @"\c4 -> "@ %game.class @" -> GameCore::onStartGame");
- 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;
- %cl.kills = 0;
- %cl.deaths = 0;
- }
- // Start the game timer
- if ($Game::Duration)
- $Game::Schedule = %this.schedule($Game::Duration * 1000, "onGameDurationEnd");
-
- $Game::Running = true;
-
- $Game = %this;
- }
- function DeathMatchGame::onMissionEnded(%this)
- {
- if (!$Game::Running)
- {
- error("endGame: No game running!");
- return;
- }
- // Stop any game timers
- cancel($Game::Schedule);
- for (%clientIndex = 0; %clientIndex < ClientGroup.getCount(); %clientIndex++)
- {
- %cl = ClientGroup.getObject(%clientIndex);
- commandToClient(%cl, 'GameEnd', $Game::EndGamePause);
- }
- $Game::Running = false;
- $Game::Cycling = false;
- $Game = "";
- }
- function DeathMatchGame::onMissionReset(%this)
- {
- // Called by resetMission(), after all the temporary mission objects
- // have been deleted.
- %this.initGameVars();
- $Game::Duration = %this.duration;
- $Game::EndGameScore = %this.endgameScore;
- $Game::EndGamePause = %this.endgamePause;
- }
- //-----------------------------------------------------------------------------
- // Functions that implement game-play
- // These are here for backwards compatibilty only, games and/or mods should
- // really be overloading the server and mission functions listed ubove.
- //-----------------------------------------------------------------------------
- // Added this stage to creating a player so game types can override it easily.
- // This is a good place to initiate team selection.
- function DeathMatchGame::preparePlayer(%this, %client)
- {
- //echo (%game @"\c4 -> "@ %game.class @" -> GameCore::preparePlayer");
- // Find a spawn point for the player
- // This function currently relies on some helper functions defined in
- // core/scripts/spawn.cs. For custom spawn behaviors one can either
- // override the properties on the SpawnSphere's or directly override the
- // functions themselves.
- %playerSpawnPoint = pickPlayerSpawnPoint($Game::DefaultPlayerSpawnGroups);
- // Spawn a camera for this client using the found %spawnPoint
- //%client.spawnPlayer(%playerSpawnPoint);
- %this.spawnPlayer(%client, %playerSpawnPoint);
- // Starting equipment
- %this.loadOut(%client.player);
- }
- function DeathMatchGame::loadOut(%game, %player)
- {
- //echo (%game @"\c4 -> "@ %game.class @" -> GameCore::loadOut");
- %player.clearWeaponCycle();
-
- %player.setInventory(Ryder, 1);
- %player.setInventory(RyderClip, %player.maxInventory(RyderClip));
- %player.setInventory(RyderAmmo, %player.maxInventory(RyderAmmo)); // Start the gun loaded
- %player.addToWeaponCycle(Ryder);
- %player.setInventory(Lurker, 1);
- %player.setInventory(LurkerClip, %player.maxInventory(LurkerClip));
- %player.setInventory(LurkerAmmo, %player.maxInventory(LurkerAmmo)); // Start the gun loaded
- %player.addToWeaponCycle(Lurker);
- %player.setInventory(LurkerGrenadeLauncher, 1);
- %player.setInventory(LurkerGrenadeAmmo, %player.maxInventory(LurkerGrenadeAmmo));
- %player.addToWeaponCycle(LurkerGrenadeLauncher);
- %player.setInventory(ProxMine, %player.maxInventory(ProxMine));
- %player.addToWeaponCycle(ProxMine);
- %player.setInventory(DeployableTurret, %player.maxInventory(DeployableTurret));
- %player.addToWeaponCycle(DeployableTurret);
-
- if (%player.getDatablock().mainWeapon.image !$= "")
- {
- %player.mountImage(%player.getDatablock().mainWeapon.image, 0);
- }
- else
- {
- %player.mountImage(Ryder, 0);
- }
- }
- // Customized kill message for falling deaths
- function sendMsgClientKilled_Impact( %msgType, %client, %sourceClient, %damLoc )
- {
- messageAll( %msgType, '%1 fell to his death!', %client.playerName );
- }
- // Customized kill message for suicides
- function sendMsgClientKilled_Suicide( %msgType, %client, %sourceClient, %damLoc )
- {
- messageAll( %msgType, '%1 takes his own life!', %client.playerName );
- }
- // Default death message
- function sendMsgClientKilled_Default( %msgType, %client, %sourceClient, %damLoc )
- {
- if ( %sourceClient == %client )
- sendMsgClientKilled_Suicide(%client, %sourceClient, %damLoc);
- else if ( %sourceClient.team !$= "" && %sourceClient.team $= %client.team )
- messageAll( %msgType, '%1 killed by %2 - friendly fire!', %client.playerName, %sourceClient.playerName );
- else
- messageAll( %msgType, '%1 gets nailed by %2!', %client.playerName, %sourceClient.playerName );
- }
- function DeathMatchGame::onDeath(%game, %client, %sourceObject, %sourceClient, %damageType, %damLoc)
- {
- //echo (%game @"\c4 -> "@ %game.class @" -> GameCore::onDeath");
-
- // clear the weaponHUD
- %client.RefreshWeaponHud(0, "", "");
- // Clear out the name on the corpse
- %client.player.setShapeName("");
- // Switch the client over to the death cam and unhook the player object.
- if (isObject(%client.camera) && isObject(%client.player))
- {
- %client.camera.setMode("Corpse", %client.player);
- %client.setControlObject(%client.camera);
- }
- %client.player = 0;
- // Display damage appropriate kill message
- %sendMsgFunction = "sendMsgClientKilled_" @ %damageType;
- if ( !isFunction( %sendMsgFunction ) )
- %sendMsgFunction = "sendMsgClientKilled_Default";
- call( %sendMsgFunction, 'MsgClientKilled', %client, %sourceClient, %damLoc );
- // Dole out points and check for win
- if (( %damageType $= "Suicide" || %sourceClient == %client ) && isObject(%sourceClient))
- {
- %game.incDeaths( %client, 1, true );
- %game.incScore( %client, -1, false );
- }
- else
- {
- %game.incDeaths( %client, 1, false );
- %game.incScore( %sourceClient, 1, true );
- %game.incKills( %sourceClient, 1, false );
- // If the game may be ended by a client getting a particular score, check that now.
- if ( $Game::EndGameScore > 0 && %sourceClient.kills >= $Game::EndGameScore )
- %game.cycleGame();
- }
- }
- // ----------------------------------------------------------------------------
- // Scoring
- // ----------------------------------------------------------------------------
- function DeathMatchGame::incKills(%game, %client, %kill, %dontMessageAll)
- {
- %client.kills += %kill;
-
- if( !%dontMessageAll )
- messageAll('MsgClientScoreChanged', "", %client.score, %client.kills, %client.deaths, %client);
- }
- function DeathMatchGame::incDeaths(%game, %client, %death, %dontMessageAll)
- {
- %client.deaths += %death;
- if( !%dontMessageAll )
- messageAll('MsgClientScoreChanged', "", %client.score, %client.kills, %client.deaths, %client);
- }
- function DeathMatchGame::incScore(%game, %client, %score, %dontMessageAll)
- {
- %client.score += %score;
- if( !%dontMessageAll )
- messageAll('MsgClientScoreChanged', "", %client.score, %client.kills, %client.deaths, %client);
- }
- function DeathMatchGame::getScore(%client) { return %client.score; }
- function DeathMatchGame::getKills(%client) { return %client.kills; }
- function DeathMatchGame::getDeaths(%client) { return %client.deaths; }
- function DeathMatchGame::getTeamScore(%client)
- {
- %score = %client.score;
- if ( %client.team !$= "" )
- {
- // Compute team score
- for (%i = 0; %i < ClientGroup.getCount(); %i++)
- {
- %other = ClientGroup.getObject(%i);
- if ((%other != %client) && (%other.team $= %client.team))
- %score += %other.score;
- }
- }
- return %score;
- }
- // ----------------------------------------------------------------------------
- // Spawning
- // ----------------------------------------------------------------------------
- function DeathMatchGame::spawnPlayer(%game, %client, %spawnPoint, %noControl)
- {
- //echo (%game @"\c4 -> "@ %game.class @" -> GameCore::spawnPlayer");
- if (isObject(%client.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!");
- }
- // Attempt to treat %spawnPoint as an object
- if (getWordCount(%spawnPoint) == 1 && isObject(%spawnPoint))
- {
- // Defaults
- %spawnClass = $Game::DefaultPlayerClass;
- %spawnDataBlock = $Game::DefaultPlayerDataBlock;
- // Overrides by the %spawnPoint
- if (isDefined("%spawnPoint.spawnClass"))
- {
- %spawnClass = %spawnPoint.spawnClass;
- %spawnDataBlock = %spawnPoint.spawnDatablock;
- }
- else if (isDefined("%spawnPoint.spawnDatablock"))
- {
- // This may seem redundant given the above but it allows
- // the SpawnSphere to override the datablock without
- // overriding the default player class
- %spawnDataBlock = %spawnPoint.spawnDatablock;
- }
- %spawnProperties = %spawnPoint.spawnProperties;
- %spawnScript = %spawnPoint.spawnScript;
- // Spawn with the engine's Sim::spawnObject() function
- %player = spawnObject(%spawnClass, %spawnDatablock, "",
- %spawnProperties, %spawnScript);
- // If we have an object do some initial setup
- if (isObject(%player))
- {
- // Pick a location within the spawn sphere.
- %spawnLocation = %game.pickPointInSpawnSphere(%player, %spawnPoint);
- %player.setTransform(%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("%spawnDatablock"))
- {
- MessageBoxOK("Spawn Player Failed",
- "Unable to create a player with class " @ %spawnClass @
- " and datablock " @ %spawnDatablock @ ".\n\nStarting as an Observer instead.",
- "");
- }
- else
- {
- MessageBoxOK("Spawn Player Failed",
- "Unable to create a player with class " @ %spawnClass @
- ".\n\nStarting as an Observer instead.",
- "");
- }
- }
- }
- else
- {
-
- // Create a default player
- %player = spawnObject($Game::DefaultPlayerClass, $Game::DefaultPlayerDataBlock);
-
- if (!%player.isMemberOfClass("Player"))
- warn("Trying to spawn a class that does not derive from Player.");
- // Treat %spawnPoint as a transform
- %player.setTransform(%spawnPoint);
- }
- // If we didn't actually create a player object then bail
- if (!isObject(%player))
- {
- // Make sure we at least have a camera
- %client.spawnCamera(%spawnPoint);
- return;
- }
- // Update the default camera to start with the player
- if (isObject(%client.camera) && !isDefined("%noControl"))
- {
- if (%player.getClassname() $= "Player")
- %client.camera.setTransform(%player.getEyeTransform());
- else
- %client.camera.setTransform(%player.getTransform());
- }
- // 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(%player);
- // Store the client object on the player object for
- // future reference
- %player.client = %client;
-
- // If the player's client has some owned turrets, make sure we let them
- // know that we're a friend too.
- if (%client.ownedTurrets)
- {
- for (%i=0; %i<%client.ownedTurrets.getCount(); %i++)
- {
- %turret = %client.ownedTurrets.getObject(%i);
- %turret.addToIgnoreList(%player);
- }
- }
- // Player setup...
- if (%player.isMethod("setShapeName"))
- %player.setShapeName(%client.playerName);
- if (%player.isMethod("setEnergyLevel"))
- %player.setEnergyLevel(%player.getDataBlock().maxEnergy);
- if (!isDefined("%client.skin"))
- {
- // Determine which character skins are not already in use
- %availableSkins = %player.getDatablock().availableSkins; // TAB delimited list of skin names
- %count = ClientGroup.getCount();
- for (%cl = 0; %cl < %count; %cl++)
- {
- %other = ClientGroup.getObject(%cl);
- if (%other != %client)
- {
- %availableSkins = strreplace(%availableSkins, %other.skin, "");
- %availableSkins = strreplace(%availableSkins, "\t\t", ""); // remove empty fields
- }
- }
- // Choose a random, unique skin for this client
- %count = getFieldCount(%availableSkins);
- %client.skin = addTaggedString( getField(%availableSkins, getRandom(%count)) );
- }
- %player.setSkinName(%client.skin);
- // Give the client control of the player
- %client.player = %player;
- // Give the client control of the camera if in the editor
- if( $startWorldEditor )
- {
- %control = %client.camera;
- %control.mode = "Fly";
- EditorGui.syncCameraGui();
- }
- else
- %control = %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"))
- %client.setControlObject(%control);
- }
- function DeathMatchGame::pickPointInSpawnSphere(%this, %objectToSpawn, %spawnSphere)
- {
- %SpawnLocationFound = false;
- %attemptsToSpawn = 0;
- while(!%SpawnLocationFound && (%attemptsToSpawn < 5))
- {
- %sphereLocation = %spawnSphere.getTransform();
-
- // Attempt to spawn the player within the bounds of the spawnsphere.
- %angleY = mDegToRad(getRandom(0, 100) * m2Pi());
- %angleXZ = mDegToRad(getRandom(0, 100) * m2Pi());
- %sphereLocation = setWord( %sphereLocation, 0, getWord(%sphereLocation, 0) + (mCos(%angleY) * mSin(%angleXZ) * getRandom(-%spawnSphere.radius, %spawnSphere.radius)));
- %sphereLocation = setWord( %sphereLocation, 1, getWord(%sphereLocation, 1) + (mCos(%angleXZ) * getRandom(-%spawnSphere.radius, %spawnSphere.radius)));
-
- %SpawnLocationFound = true;
- // Now have to check that another object doesn't already exist at this spot.
- // Use the bounding box of the object to check if where we are about to spawn in is
- // clear.
- %boundingBoxSize = %objectToSpawn.getDatablock().boundingBox;
- %searchRadius = getWord(%boundingBoxSize, 0);
- %boxSizeY = getWord(%boundingBoxSize, 1);
-
- // Use the larger dimention as the radius to search
- if (%boxSizeY > %searchRadius)
- %searchRadius = %boxSizeY;
-
- // Search a radius about the area we're about to spawn for players.
- initContainerRadiusSearch( %sphereLocation, %searchRadius, $TypeMasks::PlayerObjectType );
- while ( (%objectNearExit = containerSearchNext()) != 0 )
- {
- // If any player is found within this radius, mark that we need to look
- // for another spot.
- %SpawnLocationFound = false;
- break;
- }
-
- // If the attempt at finding a clear spawn location failed
- // try no more than 5 times.
- %attemptsToSpawn++;
- }
-
- // If we couldn't find a spawn location after 5 tries, spawn the object
- // At the center of the sphere and give a warning.
- if (!%SpawnLocationFound)
- {
- %sphereLocation = %spawnSphere.getTransform();
- warn("WARNING: Could not spawn player after" SPC %attemptsToSpawn
- SPC "tries in spawnsphere" SPC %spawnSphere SPC "without overlapping another player. Attempting spawn in center of sphere.");
- }
-
- return %sphereLocation;
- }
- // ----------------------------------------------------------------------------
- // Observer
- // ----------------------------------------------------------------------------
- function DeathMatchGame::spawnObserver(%game, %client)
- {
- //echo (%game @"\c4 -> "@ %game.class @" -> GameCore::spawnObserver");
- // Position the camera on one of our observer spawn points
- %client.camera.setTransform(%game.pickObserverSpawnPoint());
- // Set control to the camera
- %client.setControlObject(%client.camera);
- }
- function DeathMatchGame::pickObserverSpawnPoint(%game)
- {
- //echo (%game @"\c4 -> "@ %game.class @" -> GameCore::pickObserverSpawnPoint");
- %groupName = "MissionGroup/ObserverSpawnPoints";
- %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";
- }
- // ----------------------------------------------------------------------------
- // Server
- // ----------------------------------------------------------------------------
- // Called by GameCore::cycleGame() when we need to destroy the server
- // because we're done playing. We don't want to call destroyServer()
- // directly so we can first check that we're about to destroy the
- // correct server session.
- function DeathMatchGame::DestroyServer(%serverSession)
- {
- if (%serverSession == $Server::Session)
- {
- if (isObject(LocalClientConnection))
- {
- // We're a local connection so issue a disconnect. The server will
- // be automatically destroyed for us.
- disconnect();
- }
- else
- {
- // We're a stand alone server
- destroyServer();
- }
- }
- }
- // ----------------------------------------------------------------------------
- // weapon HUD
- // ----------------------------------------------------------------------------
- function GameConnection::setAmmoAmountHud(%client, %amount, %amountInClips )
- {
- commandToClient(%client, 'SetAmmoAmountHud', %amount, %amountInClips);
- }
- function GameConnection::RefreshWeaponHud(%client, %amount, %preview, %ret, %zoomRet, %amountInClips)
- {
- commandToClient(%client, 'RefreshWeaponHud', %amount, %preview, %ret, %zoomRet, %amountInClips);
- }
|