Mission Type Objects and Team Implementation
by Richard Preziosi · in Torque Game Engine · 10/19/2009 (7:57 am) · 8 replies
So I incorporated a packages system to allow players to pick mission types (CTF, DM, TDM, etc). I've got that portion working, the proper echoes are put out on each type of selection. However I'm having a bit of a time getting the teams implementation put in. Both resources are linked below for reference.
Teams Implementation: www.garagegames.com/community/resource/view/2312/
Mission Type Objects: www.garagegames.com/community/resources/view/3816
When I try to run the TDMGame this is the error I'm getting in my console:
Here's my TDMGame.cs
If I need to post anything else lemme know, gonna keep hacking away at it, but been an hour now and I've been unsuccessful.
Thanks
Teams Implementation: www.garagegames.com/community/resource/view/2312/
Mission Type Objects: www.garagegames.com/community/resources/view/3816
When I try to run the TDMGame this is the error I'm getting in my console:
NetObject::scopeToClient: Couldn't find connection game scriptsAndAssets/server/scripts/TDMGame.cs (197): Unknown command setControlObject. Object game(2297) game -> TDMGame -> DefaultGame -> ScriptObject -> SimObject
Here's my TDMGame.cs
//=============================================================================
//
// TDMGame.cs
//
//
// Written by Daniel Neilsen on 28/1/03 as part of the
// TGE Game Object Type Tutorial
// wizardsworld@bigpond.com
//
//=============================================================================
$MissionTypeName[TDM] = "Team Death Match";
package TDMGame
{
function GameConnection::onLeaveMissionArea(%this)
{
// The control objects invoked this method when they
// move out of the mission area.
echo("This is a stupid Gametype package example");
}
};
$Team1 = new ScriptObject()
{
teamId = 1;
name = Red;
score = 0;
numPlayers = 0;
};
$Team2 = new ScriptObject()
{
teamId = 2;
name = Blue;
score = 0;
numPlayers = 0;
};
function TDMGame::onMissionLoaded()
{
// Called by loadMission() once the mission is finished loading.
// Nothing special for now, just start up the game play.
startGame();
}
function TDMGame::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.
cancel($Game::Schedule);
$Game::Running = false;
$Game::Cycling = false;
}
//-----------------------------------------------------------------------------
function TDMGame::startGame()
{
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;
// Start the AIManager
new ScriptObject(AIManager) {};
MissionCleanup.add(AIManager);
AIManager.think();
}
function TDMGame::endGame()
{
if (!$Game::Running) {
error("endGame: No game running!");
return;
}
// Stop the AIManager
AIManager.delete();
// 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 TDMGame::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 TDMGame::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 TDMGame::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 TDMGame::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);
}
//-----------------------------------------------------------------------------
// 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 TDMGame::onClientEnterGame(%this)
{
commandToClient(%this, 'SyncClock', $Sim::Time - $Game::StartTime);
// Create a new camera object.
%this.camera = new Camera() {
dataBlock = Observer;
};
MissionCleanup.add( %this.camera );
%this.camera.scopeToClient(%this);
// Setup game parameters, the onConnect method currently starts
// everyone with a 0 score.
%this.score = 0;
%this.team = 0; //default team is 0 (observer)
//Spawn a camera by default on a observer point
%this.camera.setTransform(TDMGame::pickObserverPoint(%this));
%this.camera.setVelocity("0 0 0");
%this.setControlObject(%this.camera);
}
function TDMGame::onClientLeaveGame(%this)
{
if (isObject(%this.camera))
%this.camera.delete();
if (isObject(%this.player))
%this.player.delete();
}
//-----------------------------------------------------------------------------
function TDMGame::onLeaveMissionArea(%this)
{
// The control objects invoked this method when they
// move out of the mission area.
}
function TDMGame::onEnterMissionArea(%this)
{
// The control objects invoked this method when they
// move back into the mission area.
}
//-----------------------------------------------------------------------------
function TDMGame::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 TDMGame::spawnPlayer(%this)
{
// Combination create player and drop him somewhere
%spawnPoint = pickSpawnPoint();
%this.createPlayer(%spawnPoint);
}
//-----------------------------------------------------------------------------
function TDMGame::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.setShapeName(%this.name);
// Starting equipment
%player.setInventory(Glock,1);
%player.mountImage(GlockImage,0);
%player.setInventory(GlockAmmo,999);
// Shielded?
%player.shielded = 0;
// 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 TDMGame::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";
}
function TDMGame::pickObserverPoint(%client)
{
%groupName = "MissionGroup/ObserverDropPoints";
%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 observer spawn points found in " @ %groupName);
}
else
error("Missing observer 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";
}
function TDMGame::joinTeam(%this, %teamid)
{
//We only have 2 teams so if team is greater than 2 or less than 0 its invalid.
if (%teamid > 2 || %teamid < 0)
return false;
//If we already are on that team return.
if (%teamid == %this.team.teamId)
return false;
%this.leaveTeam();
if (%teamid == 1)
%this.team = $Team1;
if (%teamid == 2)
%this.team = $Team2;
MessageAll('MsgClientJoinTeam', 'c2%1 joined the %2 side',
%this.name,
%this.team.name,
%this.team.teamId,
%this,
%this.sendGuid,
%this.score,
%this.isAiControlled(),
%this.isAdmin,
%this.isSuperAdmin);
%this.spawnPlayer();
}
function TDMGame::leaveTeam(%client, %teamnumber)
{
%this.score = 0;
messageAll('MsgClientLeaveTeam', 'c2%1 left the %2 team.',
%client.name,
%client.team.name,
%client);
if (%client.player)
%client.player.delete();
}If I need to post anything else lemme know, gonna keep hacking away at it, but been an hour now and I've been unsuccessful.
Thanks
#2
10/20/2009 (9:58 am)
Have to break this up into halves as the word limit is kicking my ass on it.//=============================================================================
//
// TDMGame.cs
//
//
// Written by Daniel Neilsen on 28/1/03 as part of the
// TGE Game Object Type Tutorial
// wizardsworld@bigpond.com
//
//=============================================================================
$MissionTypeName[TDM] = "Team Death Match";
$Team1 = new ScriptObject()
{
teamId = 1;
name = Red;
score = 0;
numPlayers = 0;
};
$Team2 = new ScriptObject()
{
teamId = 2;
name = Blue;
score = 0;
numPlayers = 0;
};
function TDMGame::activatePackages(%game)
{
activatePackage(TDMGame);
if(isPackage(%game.class) && %game.class !$= TDMGame)
activatePackage(%game.class);
}
function TDMGame::deactivatePackages(%game)
{
if(isPackage(%game.class) && %game.class !$= TDMGame)
deactivatePackage(%game.class);
deactivatePackage(TDMGame);
}
package TDMGame
{
function GameConnection::onLeaveMissionArea(%this)
{
// The control objects invoked this method when they
// move out of the mission area.
echo("This is a stupid Gametype package example");
}
};
activatePackage(TDMGame);
//-----------------------------------------------------------------------------
// System Control Functions
function TDMGame::onMissionLoaded(%game)
{
//set up game and game variables
%game.initGameVars();
%game.startGame();
}
function TDMGame::onMissionEnded(%game)
{
// 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.
cancel($Game::Schedule);
$Game::Running = false;
$Game::Cycling = false;
}
function TDMGame::onMissionReset(%game)
{
%game.startGame();
}
function TDMGame::startGame(%game)
{
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 TDMGame::endGame(%game)
{
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;
}
//-----------------------------------------------------------------------------
// Game Setup
function TDMGame::initGameVars(%game)
{
//None in default
}
function TDMGame::getNumTeams(%game)
{
if(%game.numTeams $= "")
return 1;
else
return %game.numTeams;
}
#3
10/20/2009 (10:00 am)
part 2//-----------------------------------------------------------------------------
// Client Management
function GameConnection::onClientEnterGame(%game, %client)
{
commandToClient(%client, 'SyncClock', $Sim::Time - $Game::StartTime);
// Create a new camera object.
%client.camera = new Camera() {
dataBlock = Observer;
};
MissionCleanup.add( %client.camera );
%client.camera.scopeToClient(%client);
// Setup game parameters, the onConnect method currently starts
// everyone with a 0 score.
%client.score = 0;
%client.team = 0; //default team is 0 (observer)
//Spawn a camera by default on a observer point
%client.camera.setTransform(pickObserverPoint(%client));
%client.camera.setVelocity("0 0 0");
%game.setControlObject(%client.camera);
}
function TDMGame::onClientLeaveGame(%client)
{
if (isObject(%client.camera))
%client.camera.delete();
if (isObject(%client.player))
%client.player.delete();
}
function TDMGame::spawnPlayer(%game, %client)
{
%spawnPoint = %game.pickSpawnPoint();
%game.createPlayer(%client, %spawnPoint);
}
function TDMGame::pickSpawnPoint(%game)
{
%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";
}
function TDMGame::pickObserverPoint(%client)
{
%groupName = "MissionGroup/ObserverDropPoints";
%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 observer spawn points found in " @ %groupName);
}
else
error("Missing observer 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";
}
function TDMGame::createPlayer(%game, %client, %spawnPoint)
{
echo( "TDM Game Bitches");
if (%client.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 = %client;
};
MissionCleanup.add(%player);
// Player setup...
%player.setTransform(%spawnPoint);
%player.setShapeName(%client.name);
// Starting equipment
%player.setInventory(Crossbow,1);
%player.setInventory(CrossbowAmmo,10);
//%player.mountImage(CrossbowImage,0);
%player.setInventory(Glock,1);
%player.setInventory(GlockAmmo,10);
%player.setInventory(Ak47,1);
%player.setInventory(Ak47Ammo,10);
// Update the camera to start with the player
%client.camera.setTransform(%player.getEyeTransform());
// Give the client control of the player
%client.player = %player;
%client.setControlObject(%player);
}
function TDMGame::joinTeam(%client, %teamid)
{
//We only have 2 teams so if team is greater than 2 or less than 0 its invalid.
if (%teamid > 2 || %teamid < 0)
return false;
//If we already are on that team return.
if (%teamid == %client.team.teamId)
return false;
%client.TDMGame::leaveTeam();
if (%teamid == 1)
%client.team = $Team1;
if (%teamid == 2)
%client.team = $Team2;
MessageAll('MsgClientJoinTeam', 'c2%1 joined the %2 side',
%client.name,
%client.team.name,
%client.team.teamId,
%client,
%client.sendGuid,
%client.score,
%client.isAiControlled(),
%client.isAdmin,
%client.isSuperAdmin);
%game.TDMGame::spawnPlayer();
}
function TDMGame::leaveTeam(%client, %teamnumber)
{
%this.score = 0;
messageAll('MsgClientLeaveTeam', 'c2%1 left the %2 team.',
%client.name,
%client.team.name,
%client);
if (%client.player)
%client.player.delete();
}
#4
Eventhough it says package it's not actually activating a package. each *game.cs is set up with only the specific functions tied to that type of gameplay.
Is execing scripts like that actually a good idea, seems way easier than packaging and makes me wonder why I was doing it to begin with. Does it not leave the functions in memory and accessible in any mode? I'd test it out and see if things are overlapping when I change maps, but don't have any maps set up.
10/20/2009 (12:12 pm)
Got the idea to download realm wars as I thought it would be a bit better laid out than some of the resources for packaging. To my surprise they aren't using packaging in realm wars. instead using this function inside of init.cs.function initGamePackage(%missiontype)
{
// use $Server::MissionType as a global mission type descriptor.
$Server::MissionType = %missiontype;
echo("************* Mission Type detected as: " @ $Server::MissionType @ "n");
echo("******* initGamePackage in example.rw.server.init.cs calledn");
// PC: choose the type of "game.cs" script to spawn based on mission info from the mission script.
if (%missiontype $= "DeathMatch")
{
echo("Deathmatch gamen");
exec("./scripts/dmgame.cs");
}
if (%missiontype $= "TeamDeathMatch")
{
echo("TeamDeathMatch gamen");
exec("./scripts/tdmgame.cs");
}
if (%missiontype $= "CTF")
{
echo("Capture the flag game type!n");
exec("./scripts/ctfgame.cs");
}
}Eventhough it says package it's not actually activating a package. each *game.cs is set up with only the specific functions tied to that type of gameplay.
Is execing scripts like that actually a good idea, seems way easier than packaging and makes me wonder why I was doing it to begin with. Does it not leave the functions in memory and accessible in any mode? I'd test it out and see if things are overlapping when I change maps, but don't have any maps set up.
#5
Thanks
10/21/2009 (11:09 am)
Has anyone implemented different mission types that would be willing to explain how they did it, cause been a few days now to no avail, and I'm basically stuck indefinitely until I can get this going.Thanks
#6
Have you overridden the common (core) functions:
loadMissionStage2() endMission() resetMission() as part of your "default game" type so that the package functionality can get kicked off and/or work properly?
I haven't looked through the code you've listed but your error is probably occurring due to calling the wrong parameter/arg.
10/21/2009 (12:03 pm)
I've done this in Torque 3D. Have you overridden the common (core) functions:
I haven't looked through the code you've listed but your error is probably occurring due to calling the wrong parameter/arg.
#7
In what you did for T3D, were you using packages or some other way? If packages and you understand them well enough, might I send you my files and you give them a looksee?
Thanks
10/21/2009 (12:20 pm)
yeah they're overwritten, or atleast if I understand the loading order of everything they should be.In what you did for T3D, were you using packages or some other way? If packages and you understand them well enough, might I send you my files and you give them a looksee?
Thanks
#8
10/24/2009 (6:51 am)
Sorry to bump, just still struggling with this, and still at a standstill, if anyone can help would be great.
Torque Owner Richard Preziosi
WinterLeaf Entertainment
If I add a TDMGame:: to the functions they do not function at all, however if i leave off the TDMGame:: it atleast exec's the functions, I'm guessing this ie because I don't have a TDMGame:: somewhere else in one of the other files concerning the teams functions.
What is happening, is that it is not spawning as an observer, I can join teams, but as soon as i do it turns the screen pink, the chat screen is still visible and does display that i have joined the appropriate team.
I'm guessing all of this problem is due to it being incorporated into a package and I'm just missing a few TDMGame::s somewhere.
Will post updated code in next post.
Thanks