Problem with team-based onClientEnterGame code
by Vincent Ellis · in Torque 3D Beginner · 12/30/2013 (2:14 pm) · 13 replies
I have written the following code for a team-based modification of the onClientEnterGame function, however, it doesn't seem to work. Somehow, all players keep getting added to the red team, instead of a proper balance.
Have i written something wrong here? Can't seem to get my head around it:
Have i written something wrong here? Can't seem to get my head around it:
// Current team totals
%blueTeam = 0;
%redTeam = 0;
// Inform the client of all the other clients
foreach (%connectedClient in ClientGroup) {
if (%connectedClient == %client) continue;
messageClient(
%client,
'MsgClientJoin',
"",
%connectedClient.playerName,
%connectedClient,
%connectedClient.sendGuid,
%connectedClient.team,
%connectedClient.score,
%connectedClient.kills,
%connectedClient.deaths,
%connectedClient.isAIControlled(),
%connectedClient.isAdmin,
%connectedClient.isSuperAdmin
);
switch$ (%connectedClient.team) {
case 'blue':
%blueTeam++;
break;
case 'red':
%redTeam++;
break;
}
}
if (%blueTeam > %redTeam) {
%client.team = 'red';
} else {
%client.team = 'blue';
}
#2
Why inefficient?
12/30/2013 (4:36 pm)
They don't need to be global, since the total amount of players on each team has to be counted on each call of that function. I'm using that code on a vanilla version of T3D 3.5 "Full" template. That's the only modification. Quote:Actually I'm seeing what you did there and although inefficient I would think it should work.
Why inefficient?
#3
In your case, you could do something like this:
foreach (%connectedClient in ClientGroup)
chooseTeam(%client, %connectedclient);
Where you create a function chooseTeam that does all the things you need done.
12/31/2013 (7:38 am)
The foreach command may not work as you might expect it to. It only allows one statement to be processed on each iteration. Even though you have several statements inside the brackets. only the first statement will be processed during the foreach loop. To work around this, you can create and call a function that does everything you need done on each iteration. In your case, you could do something like this:
foreach (%connectedClient in ClientGroup)
chooseTeam(%client, %connectedclient);
Where you create a function chooseTeam that does all the things you need done.
#4
Also, just replaced the foreach with a for and the problem still occurs.
12/31/2013 (9:22 am)
But there are many scripts inside the tools folder, like gametoolsdatablockEditordatablockEditor.cs, which use multiple-statement foreachs.Also, just replaced the foreach with a for and the problem still occurs.
#5
First, I'd try replacing your 'blue' and 'red' strings with "double quoted" versions. In TorqueScript, a 'single quoted' string is a tagged string meant for transmission over the network. It may be messing stuff up, because they don't work as expected when you're not shooting them across the network. Weird, I know.
01/01/2014 (1:41 am)
Yeah, Joseph, that only applies if there are no curly brackets. It works the same as if/while/for in C. You can leave off the curly brackets and it will do only one statement, or you can surround a block with curlies and the whole block is used as the loop body.First, I'd try replacing your 'blue' and 'red' strings with "double quoted" versions. In TorqueScript, a 'single quoted' string is a tagged string meant for transmission over the network. It may be messing stuff up, because they don't work as expected when you're not shooting them across the network. Weird, I know.
#6
01/01/2014 (6:44 am)
I tried replacing blue/red with integer, but still doesn't work.
#7
Can any object be assigned new properties on the fly? Maybe the .team property is not being sent to all other clients.
01/01/2014 (6:51 am)
Is there anywhere else where the .team property might be getting set? Is the MsgClientJoin handled only to adjust the GUI, or is it handled somewhere else inside the engine, not on scripts?Can any object be assigned new properties on the fly? Maybe the .team property is not being sent to all other clients.
#8
01/02/2014 (6:15 am)
Quote:Can any object be assigned new properties on the fly? Maybe the .team property is not being sent to all other clients.Oh. Yes, sorry, I didn't understand the code well enough to realise this would rely on .team being networked. Dynamic members are not networked. I'd recommend adding the team to the message that is sent to all clients after the new client joins.
#9
By the way, i found the reason why the code wasn't working: apparently, break does not work with switch$. Therefore, the break was affecting the foreach loop, not the switch, causing the bug. Hard one to catch. I wonder why this decision was made, makes TorqueScript prone to bugs.
01/02/2014 (6:19 am)
MsgClientJoin? But that function only calls handleClientJoin, which is responsible for calling PlayerListGui.update. There is absolutely no other usage of it. Where i can network the team member properly?By the way, i found the reason why the code wasn't working: apparently, break does not work with switch$. Therefore, the break was affecting the foreach loop, not the switch, causing the bug. Hard one to catch. I wonder why this decision was made, makes TorqueScript prone to bugs.
#10
I take that back - switch$ was a recent addition. Guess they missed a piece.
And while it only tickles the update on the PlayerListGui you can catch it there are update local lists yourself. Don't really need to though - the ClientList is on the server, as you already know. I was unaware of the failure of switch$ to respect break, but I always use integers to track teams.
01/02/2014 (7:15 am)
You'd have to go back 15 or more years to find the people responsible for that one....I take that back - switch$ was a recent addition. Guess they missed a piece.
And while it only tickles the update on the PlayerListGui you can catch it there are update local lists yourself. Don't really need to though - the ClientList is on the server, as you already know. I was unaware of the failure of switch$ to respect break, but I always use integers to track teams.
#11
01/02/2014 (8:18 am)
Does TorqueScript have some kind of constant system? I wanted to create something like TEAM_RED, TEAM_BLUE, etc. with proper INT values. This way, the code stays legible, and safe from these string manipulation aberrations.
#12
Hmm - ok, to clarify, they're not constants but they are globals.
01/02/2014 (6:05 pm)
Yes:$TEAM_RED = 1; $TEAM_BLUE = 2; // or $TEAMS::RED = 1; $TEAMS::BLUE = 2;These are global script variables (prefix with $ instead of %).
Hmm - ok, to clarify, they're not constants but they are globals.
#13
What benefits do you see in a constant system (presumably something like C's enums) over using strings? You could always use global variables ($REDTEAM = 1; $BLUETEAM = 2;), but they won't be any 'safer' than using strings.
One thing I like to do is use quote-less string keywords. If you write an identifier in TS with no prefix (% or $), it will become a string. Try this in the console:
01/02/2014 (6:06 pm)
Oh, that's nasty. Well caught. Regular switch statements (not only switch$) ignore break statements as well; presumably this was intended to make it easier for beginners to use the language and not forget breaks on the end of their cases.What benefits do you see in a constant system (presumably something like C's enums) over using strings? You could always use global variables ($REDTEAM = 1; $BLUETEAM = 2;), but they won't be any 'safer' than using strings.
One thing I like to do is use quote-less string keywords. If you write an identifier in TS with no prefix (% or $), it will become a string. Try this in the console:
hello $= "hello"It's great for readability.
Torque Owner Nathan Martin
TRON 2001 Network
Actually I'm seeing what you did there and although inefficient I would think it should work.