How do you target all players?
I'm not exactly sure what you mean by "target." Blockland doesn't really have a 'targetting' function. I assume you're asking how to get every player on the server though, which is pretty easy:
for(%i = 0; %i < ClientGroup.getCount(); %i++) {
%client = ClientGroup.getObject(%i);
messageClient(%client, '', "You have been targeted!");
}
What is the best way to make a counter, have it loop, call for number of loops so far, etc.
There's two ways to do this, the accurate way and the inaccurate way. First I'll start with the inaccurate way because it's simpler.
There is a function called schedule that allows you to delay the calling of a function. You can easily make a counter by making a function that increases a variable, then using schedule to call itself again after a second.
function counterIncrease() {
$CounterValue++;
schedule(1000, 0, counterIncrease);
}
The arguments for schedule are time (in millseconds, 1000 ms is a second), ignore the second one (always 0), the function to call, then any arguments to call the function with come after that. The issue with schedules are that they're not 100% accurate. They're apt to be off by a number of milliseconds, and this means that over the course of a day or so your counter can become significantly off from the real amount of time that's passed. The best way to get around this is to calculate the actual time that's passed, and just use schedule to keep calling the function.
function counterIncrease(%lastTime) {
%thisTime = getSimTime();
if(%lastTime == 0)
%lastTime = %thisTime;
if(%thisTime - %lastTime > 1000) {
%secondsPassed = mFloor((%thisTime - %lastTime)/1000);
$CounterValue += %secondsPassed;
%lastTime += 1000 * %secondsPassed;
}
schedule(500, 0, counterIncrease, %lastTime);
}
I decreased the schedule to 500ms in this one so that it's impossible for a number to be skipped due to poor timing. This one works by calling the function every 500ms with the last time that the counter increased, then when it's been at least a second since the last time the counter increased, it updates the last time that the counter increased by exactly the amount of seconds that have passed, then increases the counter by the amount of seconds that have passed. This way it doesn't matter if schedule isn't perfect, and if it lags for more than a second it'll update by more than a second.
What is the best way to save and call for custom preferences for clients?
Ah, the old data storage dilemma. There's been a lot of thought put into this one both inside and outside of Blockland. Unfortunately Blockland is pretty stuffty at this. Your best bet is to create a script object every time a player leaves, copy all the important data into it, then save that script object. So, something like this:
package saveScores {
function GameConnection::onClientLeaveGame(%this) {
%saveObj = new ScriptObject(%this.getBLID() @ "_saveObj");
%saveObj.name = %this.getPlayerName();
%saveObj.BL_ID = %this.getBL_ID();
%saveObj.score = %this.score;
%saveObj.position = %this.getPosition();
//whatever else you want to save
%saveObj.save("config/players/" @ %saveObj.BL_ID @ ".cs");
%saveObj.delete();
parent::onClientLeaveGame(%this);
}
};
activatePackage(saveScores);
Then, to load it, just do the opposite:
package loadScores {
function GameConnection::onClientEnterGame(%this) {
exec("config/players/" @ %this.getBLID() @ ".cs");
%saveObj = (%this.getBLID() @ "_saveObj");
%this.score = %saveObj.score;
%this.setTransform(%saveObj.position);
%saveObj.delete();
parent::onClientEnterGame(%this);
}
};
activatePackage(loadScores);
By the way, those can both be put into one package.
How do classes work?
Classes are actually pretty unimportant in Torque. They're super easy though.
function MyClass::sayHello(%this) {
messageAll('', "Hello World!");
return %this;
}
new ScriptObject() {
class = MyClass;
}.sayHello().delete();
You can also use pseudo-classes by using the name of an object.
function MyObject::sayHello(%this) {
messageAll('', "Hello World!");
return %this;
}
new ScriptObject(MyObject).sayHello().delete();