A hand with something that's probably simple...
by Justin Pitta · in Torque Game Engine · 10/02/2009 (10:27 pm) · 10 replies
I'm trying to modify FPS Demo to add a bunch of passive bots running around a path to make a sort of shooting gallery...
AIManager is the enginge I belive I need to mess with to spawn more than 1 bot... On it's death in the demo, it respawns on the same path... I have successfuly gotten it to respawn randomly on a diffrent path I made with:
What I cant figure out, is when I do this:
I get:
Any ideas? I assume tis is probably a simple oversight, but I'm the new guy, that's why I'm here... (Yes, I'm using Torsion) I'ts wierd because it says the issuie is between the ##, but the ## surround nothing... Not sure how to follow a breadcrumb trail when there isn't a crumb to start with.
AIManager is the enginge I belive I need to mess with to spawn more than 1 bot... On it's death in the demo, it respawns on the same path... I have successfuly gotten it to respawn randomly on a diffrent path I made with:
function AIManager::think(%this)
{
// We could hook into the player's onDestroyed state instead of
// having to "think", but thinking allows us to consider other
// things...
if (!isObject(%this.player))
%this.player = %this.spawn();
%this.schedule(500,think);
}
function AIManager::spawn(%this)
{
%newPath = getRandom(9); //Used to randomly pick the path
%player = AIPlayer::spawnOnPath("","MissionGroup/Paths/Path"@%newPath);
if (isObject(%player))
{
%player.followPath("MissionGroup/Paths/Path"@%newPath,-1);
%player.mountImage(CrossbowImage,0);
%player.setInventory(CrossbowAmmo,1000);
return %player;
}
else
return 0;
}What I cant figure out, is when I do this:
$AIManager::botCount = 3;
function AIManager::think(%this)
{
// We could hook into the player's onDestroyed state instead of
// having to "think", but thinking allows us to consider other
// things...
for( %x = 0, %x < $AIManager::botCount, %x++)
{
if (!isObject(%this.player[%x]))
%this.player[%x] = %this.spawn();
%this.schedule(500,think);
}
}I get:
//-------------------------- 10/2/2009 -- 18:26:37 -----
Compiling starter.fps/server/scripts/aiPlayer.cs...
starter.fps/server/scripts/aiPlayer.cs Line: 233 - parse error
>>> Advanced script error report. Line 233.
>>> Some error context, with ## on sides of error halt:
//-----------------------------------------------------------------------------
function AIManager::think(%this)
{
// We could hook into the player's onDestroyed state instead of
// having to "think", but thinking allows us to consider other
// things...
for( %x = 0, %x < $AIManager::botCount, %x++)
## ## {
if (!isObject(%this.player[%x]))
%this.player[%x] = %this.spawn();
%this.schedule(500,think);
}
}
function AIManager::spawn(%this)
{
%newPath = getRandom(9);
%player = AIPlayer::spawnOnPath("","MissionGroup/Paths/Path"@%newPath);
>>> Error report complete.Any ideas? I assume tis is probably a simple oversight, but I'm the new guy, that's why I'm here... (Yes, I'm using Torsion) I'ts wierd because it says the issuie is between the ##, but the ## surround nothing... Not sure how to follow a breadcrumb trail when there isn't a crumb to start with.
About the author
#2
Yes, the ##s never seem to be quite accurate. Usually they are placed after the error in question. In this case:
10/03/2009 (12:02 am)
EDIT: Ah, ninjad. :PYes, the ##s never seem to be quite accurate. Usually they are placed after the error in question. In this case:
for( %x = 0, %x < $AIManager::botCount, %x++)After each statement, you need a ; rather than a ,. So:
for( %x = 0; %x < $AIManager::botCount; %x++)Also, I'd take the schedule out of the for loop. Each schedule call starts a new timer to call that method. So say you were spawning two bots. Think is called, the loop runs through twice, and two schedules are created. Then 500ms later, each of those schedules executes the same function. And in the right conditions, each of those could schedule two more calls of the same function. (Actually, I don't think they could - but you get the idea.) Now, the way it's set up, you probably wouldn't run into much of a propagation problem. But it'd be much cleaner and less risky to just move the schedule outside the for loop.
#3
"expected ; where , is" or something...
Terrible... Emberassing...
Works great now, thanks! I'll probably be here later this evening with more questions... I'll keep it all in one thread... Don't want to pollute the forums...
10/03/2009 (7:49 pm)
Wow.... Missing the , to ; is flat out embarassing... Talk about tunnel vision... You'd think IDE's would be more verbose..."expected ; where , is" or something...
Terrible... Emberassing...
Works great now, thanks! I'll probably be here later this evening with more questions... I'll keep it all in one thread... Don't want to pollute the forums...
#4
I can't for the life of me keep track of the score. I can't find anywhere in the code how to handle respawns. I figured If I can find where thier 'death' happened, I can simply increment a $playerscore variable, and print that to the screens message box...
10/03/2009 (11:00 pm)
Ok - So I have my mission setup properly, got tons of guys running around a little village with thier own paths, all dynamically spawned along one of several paths...I can't for the life of me keep track of the score. I can't find anywhere in the code how to handle respawns. I figured If I can find where thier 'death' happened, I can simply increment a $playerscore variable, and print that to the screens message box...
#5
EDIT: digging deeper... incScore is defined in common/server.clientConnection.cs. It calls a function to message everyone with the updated score.
EDIT: addMessageCallback seems like your man. Function. Thing.
It adds a reference to call a certain script function when a message of a certain type is received. So you'd need to create a client function to increase a score counter GUI (have a look at GettingStarted.pdf), and add a message callback that calls that function when a score message is received.
10/04/2009 (1:20 am)
Score should be in the starter.fps scripts by default. See this in player.cs:function Armor::damage(%this, %obj, %sourceObject, %position, %damage, %damageType)
{
if (%obj.getState() $= "Dead")
return;
%obj.applyDamage(%damage);
%location = "Body";
// Deal with client callbacks here because we don't have this
// information in the onDamage or onDisable methods
%client = %obj.client;
%sourceClient = %sourceObject ? %sourceObject.client : 0;
if (%obj.getState() $= "Dead")
%client.onDeath(%sourceObject, %sourceClient, %damageType, %location);
}Which calls this in game.cs: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();
}
}You'd need to add a GUI to show the score for a client, which you'd probably implement as a commandToClient in incScore.EDIT: digging deeper... incScore is defined in common/server.clientConnection.cs. It calls a function to message everyone with the updated score.
EDIT: addMessageCallback seems like your man. Function. Thing.
It adds a reference to call a certain script function when a message of a certain type is received. So you'd need to create a client function to increase a score counter GUI (have a look at GettingStarted.pdf), and add a message callback that calls that function when a score message is received.
#6
10/04/2009 (6:41 pm)
Ok... In game.cs there is a $Game::EndGameScore variable... I have set that to 5, and killed WAY more than 5 bots... game does not end... Leads me to belive that the scoring was mean for multiplayer? with multiple clients? and it gives no message in the message window when I kill something, so I don't belive it's actually tracking the bot kills...
#7
10/04/2009 (9:28 pm)
I'd put echoes through the scripts that *should* be causing the score to increase, and see where the chain stops.
#8
10/04/2009 (10:20 pm)
If you're just using the standard starter.fps ai code, it's caue the aiplayer doesn't have a connection, he's just a shape running around, gotta expand his code and add an ondeath or on disabled function. Can't figure it out myself or I would be able to help more, compare player.cs to aiplayer.cs.
#9
10/04/2009 (11:49 pm)
I'm using torsion, and but break points in the onDeath function in game.cs, and it doesnt stop once...
#10
Funny - seems there should be console spam from this:
Anyway, you'd probably need to add a check to onDamage to see if this is an AI character, and if so then increase the score of the sourceClient.
10/05/2009 (2:12 am)
Erg. That was silly of me. I was reading the script wrong. Rich, you're right that AIPlayers don't get onDeath called because there's no client connection involved.Funny - seems there should be console spam from this:
%client.onDeath(%sourceObject, %sourceClient, %damageType, %location);Since the client of an AIPlayer wouldn't be anything useful.
Anyway, you'd probably need to add a check to onDamage to see if this is an AI character, and if so then increase the score of the sourceClient.
Torque Owner Guy Allard
Default Studio Name
( ; not , in the for statement)