PDA

View Full Version : Confused about Arrays / Random client


Mooni
11-13-2014, 10:24
Well i feel like i dont even know how arrays work and im starting to get abit frusturated about it.
Im trying to chose a random client of the clients that have used the sm_c command in the first 5seconds of the round and im stuck.
I have not got to the "first 5sec" part yet, but if you think i will get problems with it feel free to help out with that aswell.

I probably dont make much sens but i would greatly appreciate some detailed examples.

What i got so far:


#include <sourcemod>

new want_c[MAXPLAYERS +1]; //Probably wrong already.

#define PLUGIN_VERSION "0.1"
#define PLUGIN_NAME "Test"
#define PLUGIN_DESCRIPTION "Trying to learn"

public Plugin:myinfo = {
name = PLUGIN_NAME,
author = "Mooni",
description = PLUGIN_DESCRIPTION,
version = PLUGIN_VERSION,
url = ""
};

public OnPluginStart()
{
RegConsoleCmd("sm_c", Command_c);
CreateTimer(5.0, Timer_5sec, TIMER_REPEAT); //idk why i made it repeat but i have not got to that yet anyway.

HookEvent("player_death", playerDeath);
HookEvent("round_start", roundStart);

CreateConVar("sm_c_version", PLUGIN_VERSION, PLUGIN_DESCRIPTION, FCVAR_REPLICATED|FCVAR_SPONLY|FCVAR_PLUGIN);
}

public Action:Command_c(client, args)
{
if(GetClientTeam(client) == CS_TEAM_CT && IsPlayerAlive(client))
{
want_c[/* idk im stupid */] = client; //here im trying to add the client to "want_c"
PrintToChat(client, "[SM] Added you to the c list.");
}
return Plugin_Continue;
}

public Action:Timer_5sec(Handle:timer)
{
if(want_c[/* idk im stupid */] !< 0)
{
GetRandomInt(1, sizeof(want_c[/* idk im stupid */]));
//Here i want to choose a random client that is in "want_c".
//And do something to that client.
//And then stop the timer and dump the list.
}
CloseHandle(Timer_5sec);
}

public Action:playerDeath(Handle:event, const String:name[], bool:dontBroadcast)
{
//if client is in "want_c", remove from "want_c".
}

public Action:roundStart(Handle:event, const String:name[], bool:dontBroadcast)
{
//Here i want the timer to start, so i guess i should move CreateTimer here?
}

The1Speck
11-13-2014, 17:55
Did this in about 5 minutes, so expect some bugs/errors. It should be more than enough in helping.

new Handle:want_c;
new bool:CanUseCmd; //create variables globally

public OnPluginStart()
{
RegConsoleCmd("sm_c", Command_c);
HookEvent("round_start", roundStart);
}

public Action:roundStart(Handle:event, const String:name[], bool:dontBroadcast)
{
want_c = CreateArray(); //create array and and set the handle to it
CreateTimer(5.0, Timer_5sec); //create 5sec timer. remade each round so no need for REPEAT flag
CanUseCmd = true; //lets use a bool to determine if client is able to use the cmd
}

public Action:Command_c(client, args)
{
if(GetClientTeam(client) == CS_TEAM_CT && IsPlayerAlive(client) && CanUseCmd) //check bool
{
PushArrayCell(want_c, GetClientUserId(client));
//adds unique player uid to list, using uid prevents from clients sharing id's
}
return Plugin_Continue;
}

public Action:Timer_5sec(Handle:timer)
{
CanUseCmd = false;
new arraySize = GetArraySize(want_c);
if(arraySize > 0)
{
new aIndex = GetRandomInt(0, arraySize - 1);
new client = GetClientOfUserId(GetArrayCell(want_c, aIndex));
/*
Do what you want with the random client here
*/
}
}

public Action:playerDeath(Handle:event, const String:name[], bool:dontBroadcast)
{
new aIndex = FindValueInArray(want_c, GetEventInt(event, "userid"));
if(aIndex != -1)
{
RemoveFromArray(want_c, aIndex); //remove from array
}
}

public OnClientDisconnect(client)
//prevents errors if client disconnects after doing want_c
{
new aIndex = FindValueInArray(want_c, GetClientUserId(client));
if(aIndex != -1)
{
RemoveFromArray(want_c, aIndex);
}
}

Bacardi
11-14-2014, 18:20
Well i feel like i dont even know how arrays work and im starting to get abit frusturated about it.
Im trying to chose a random client of the clients that have used the sm_c command in the first 5seconds of the round and im stuck.
I have not got to the "first 5sec" part yet, but if you think i will get problems with it feel free to help out with that aswell.

I probably dont make much sens but i would greatly appreciate some detailed examples.
...


4 Arrays (https://wiki.alliedmods.net/Introduction_to_SourcePawn#Arrays)

4.1 Declaration (https://wiki.alliedmods.net/Introduction_to_SourcePawn#Declaration_2)
4.2 Usage (https://wiki.alliedmods.net/Introduction_to_SourcePawn#Usage)




my old topic
[Q] About array (https://forums.alliedmods.net/showthread.php?t=183626)


Ok, players/clients are entities in game. And entities have a index number.
- First index, 0, is server/console/world or error.
- Valid client index are 1 to server current -maxplayers, different server have set different size of max players to play.
Indexs which are greater than server -maxplayer are for rest entities in game.
- SRCDS can reach maximum 65 slot in some game mods
L4D have 8 slots max, TF2 have 32 slots max and cs:s 65 slots max, etc. etc. (MAXPLAYERS (https://sm.alliedmods.net/api/index.php?fastload=file&id=25&) hard coded to 65).

When we create global array, we use now player index as a array index. We need to know how big it should be so it would work in different games and server.
So result is this
new want_c[MAXPLAYERS]
However, array start work from index 0, and end to index 64 for now.
When we use player index as array index, in 65 slots server that very final player will cause error in this plugin "Array index out of bounds"
This is why we add one extra index in array.
new want_c[MAXPLAYERS +1] // array from 0 to 65

Lets change this array to use boolean value, true|false. example player use a command, we store "true" in array
new bool:want_c[MAXPLAYERS +1]; // boolean


public OnPluginStart()
{
RegConsoleCmd("sm_c", Command_c);
}

public Action:Command_c(client, args)
{
// Client use command, save it in array as true
want_c[client] = true;

return Plugin_Handled;
}


....
here simple example
#include <cstrike>

new bool:want_c[MAXPLAYERS +1]; // Store clients command use


public OnPluginStart()
{
RegConsoleCmd("sm_c", Command_c);

HookEvent("round_start", roundStart);
}

public Action:Command_c(client, args)
{
// Client use command, save it in array as true
want_c[client] = true;

return Plugin_Handled;
}

public roundStart(Handle:event, const String:name[], bool:dontBroadcast)
{
// loop, Reset clients array settings to false
for(new i = 1; i <= MaxClients; i++)
{
want_c[i] = false;
}

// start timer
CreateTimer(5.0, Timer_5sec, TIMER_FLAG_NO_MAPCHANGE);
}

public Action:Timer_5sec(Handle:timer)
{
// new array to collect clients
new targets[MaxClients +1];
new counter;

// loop
for(new client = 1; client <= MaxClients; client++)
{
// Used command, in game, in team ct and alive
if(want_c[client] && IsClientInGame(client) && GetClientTeam(client) == CS_TEAM_CT && IsPlayerAlive(client))
{
targets[counter] = client;
counter++;
}
}

// there are clients in list
if(counter != 0)
{
// I re-use variable "counter" to save random value
counter = GetRandomInt(0, counter -1);

PrintToChatAll("[SM] Player %N is it !!", targets[counter]);
}

return Plugin_Continue;
}

Mooni
11-23-2014, 09:05
Sorry for my late response and thanks alot for the examples!

friagram
11-23-2014, 09:19
http://www.cplusplus.com/doc/tutorial/arrays/