Playerset testing
#1

UPDATE: Help no longer needed. This is an old topic which holds documentation for a now developed and tested YSI feature.

Hello.

I am looking for people to help test a new experimental library I have developed, based around an entirely new concept I call "player sets". I have in the past abstracted things like admin levels and factions in to "player groups", but this code goes one further and allows you to use any combination of players in the same way. To see what I mean, take a look at this example:

pawn Code:
#include <YSI\y_playerset>

#define SetHealth PSF:_SetHealth
stock _SetHealth(@PlayerVar:playerid, Float:health)
{
    SetPlayerHealth(playerid, health);
}

CMD:health(playerid, params[])
{
    SetHealth(playerid, 40.0);
}
Now that doesn't look like much, in fact it looks quite pointless - there's nothing gained that you couldn't do directly. The real power of this library comes from how you can call the function. The code above calls the function with a single player, let's instead call it with an array:

pawn Code:
#include <YSI\y_playerset>

#define SetHealth PSF:_SetHealth
stock _SetHealth(@PlayerVar:playerid, Float:health)
{
    SetPlayerHealth(playerid, health);
}

CMD:health(playerid, params[])
{
    new
        players[MAX_PLAYERS] = {5, 7, 11, 34, INVALID_PLAYER_ID};
    SetHealth(players, 50.0);
}
That will now call "SetHealth" for FOUR players (5, 7, 11 and 34). So we have actually written a function which can take a variable OR an array (that doesn't sound like much, but hopefully the more experienced coders will appreciate this). Note that here the array passed is a list of players. If there are less that "MAX_PLAYERS" in the array, the last item MUST be "INVALID_PLAYER_ID" so the code knows to stop searching.

That's not all you can call it with:

y_groups groups:

pawn Code:
new Group:x = Group_Create("x");
SetHealth(x, 60.0);
// Will not set anyone's health because the "x" group is empty, but would
// normally set all the members to 60.
boolean arrays:

pawn Code:
new bool:truefalse[MAX_PLAYERS] = {true, false, false, false, true, ...};
SetHealth(truefalse, 70.0);
// Will set players 0 and 4 to 70 as they are the only ones set to true.
Custom enum arrays:

pawn Code:
enum e_PLAYER_INFO
{
    Float:e_PLAYER_INFO_HEALTH,
    bool:e_PLAYER_INFO_ADMIN,
    e_PLAYER_INFO_OTHER
}

new
    gPlayerInfo[MAX_PLAYERS][e_PLAYER_INFO];
pawn Code:
SetHealth(gPlayerInfo<e_PLAYER_INFO_ADMIN>, 100.0);
// Will set the health of everyone who is connected and set as admin in
// "gPlayerInfo" to 100.
This can vastly simplify the amount of code you need to write, you can write a generic message function and wrap it:

pawn Code:
#define SendMessage PSF:_SendMessage
stock _SendMessage(@PlayerVar:playerid, colour, msg[])
{
    SendClientMessage(playerid, colour, msg);
}

stock SendAdminMessage(colour, msg[])
{
    SendMessage(gPlayerInfo<e_PLAYER_INFO_ADMIN>, colour, msg);
}
Notes:

The "#define" lines I've included above the functions are important.

DO NOT use "return" in your function when using "@PlayerVar", it will break the code quite impressively!

There are three ways to use the collection of players passed to the function: "@PlayerVar", "@PlayerArray" and "@PlayerSet":

pawn Code:
#define SetHealth1 PSF:_SetHealth1
stock _SetHealth1(@PlayerVar:playerid, Float:health)
{
    SetPlayerHealth(playerid, health);
}

#define SetHealth2 PSF:_SetHealth2
stock _SetHealth2(@PlayerArray:players<MAX_PLAYERS>, Float:health)
{
    foreach (new playerid : PA(players))
    {
        SetPlayerHealth(playerid, health);
    }
}

#define SetHealth3 PSF:_SetHealth3
stock _SetHealth3(@PlayerSet:players, Float:health)
{
    foreach (new playerid : PS(players))
    {
        SetPlayerHealth(playerid, health);
    }
}
The difference is not very clear here, but the first is a single variable, the second is an array, the third is an iterator. When using "@PlayerVar" the code will loop over all passed players internally and call the function once per player. The second version puts all the selected players in to a bit array (technically in to an array from "y_playerarray", which is slightly different, but still compressed data); this means that you have all the players at once in a single array. The third version returns a reference to an iterator; with this you can loop over players but not view them all at once, you can also pass this very efficiently to other "PSF" functions.
Reply
#2

Well i can help with the test, but i can't really comment the function cause i don't see an need to set the health of an specific ID..
Reply
#3

I think you've slightly missed the point. The health function was just an example, I gave a message function example lower down. The point is that you can set the health of a single person, a group of people or an array of people with the same code...
Reply
#4

wow, this is the hardest code ive ever seen in my life o.O
Reply
#5

An even more odd use. This is a replacement for my old Text_Send function from YSI 0.1. In that version there were multiple functions for sending to different people with and without formatting, in this version I think I've improved it vastly. Note that now you have a default text set in a file directly linked to that file, but you can use others. Also note that the identifiers are no longer strings:

pawn Code:
#define Text_Send(%0,%1) PSF(_Text_Send,%0,YSI_gDefaultText,#%1)
#define _Text_Send(%0,YSI_gDefaultText,#%1->%2) _Text_Send(%0,#%1,#%2)
That code will detect when a player is using the "GROUP->TEXT" format and actually get rid of the call to the file default variable. If they are not using that format then nothing will happen at all. This makes the format of _Text_Send:

pawn Code:
_Text_Send(PlayerSet<playerid>, const group[], const text[], {Float,_}:...)
But because it's wrapped up in a nice macro, you don't ever need to know half the parameters even exist.

Possible uses:

Code:
Text_Send(playerid, TEXT_NO_RACE);
Text_Send(admingroup, RACE_TEXT -> TEXT_NO_RACE);
Text_Send(someArrayOfPlayers, TEXT_STARTING_RACE, 5);
Reply
#6

so this topic meant about using text? ( soz i know im an advanced scripter but this is too hard for me:P. i like to learn more from Y_Less )
Reply
#7

man that a quite good and time saving idea...
I'd be glad to help you
Reply
#8

Quote:
Originally Posted by AK47317
View Post
so this topic meant about using text? ( soz i know im an advanced scripter but this is too hard for me:P. i like to learn more from Y_Less )
No, that again is just an example of using it. It allows you to use arrays or varaibles interchangably, though it seems none of you get the point.
Reply
#9

Very nice idea, but is it faster then just looping though players and checking the team?
Reply
#10

It's a simplified loop, you no longer would have to supply conditionals. I understand the purpose but honestly speaking it seems to be just as easy to use a loop
Reply


Forum Jump:


Users browsing this thread: 2 Guest(s)