AlliedModders

AlliedModders (https://forums.alliedmods.net/index.php)
-   Scripting Help (https://forums.alliedmods.net/forumdisplay.php?f=11)
-   -   Sort all arrays with one func (https://forums.alliedmods.net/showthread.php?t=293217)

EFFx 01-25-2017 19:36

Sort all arrays with one func
 
I'm trying to get the most knife kills/HS kills, etc just with one function

Thats what I have

PHP Code:

GetTop()
{
    new 
iPlayers[32], iPlayersnumPlayer;
    
    
get_players(iPlayersiPlayersnum)
    
    for(new 
i;iPlayersnum;i++)
    {
        
Player iPlayers[i]
        
        
SortCustom(PlayeriPlayersnumPlayerData[Player][arItemsBought])
    }
    return 
Player[0]
}

SortCustom(elem1elem2, array[]) 
{
    if(array[
elem1] > array[elem2])
        return -
1
        
    
else if(array[elem1] < array[elem2])
        return 
1
        
    
return 0


I have picked it up from Kia's MPV. I know that GetTop() will return the last player, but how can I return the player that have the biggest array's size ? ( arItemsBought ).

Black Rose 01-28-2017 10:25

Re: Sort all arrays with one func
 
?
Code:
GetTop() {     new Players[32], iPlayersnum;         get_players(Players, iPlayersnum)     SortCustom1D(Players, iPlayersnum, "SortCustom")     return Players[0] } public SortCustom(elem1, elem2) {     if(PlayerData[elem1][arItemsBought] > PlayerData[elem2][arItemsBought])         return -1             else if(PlayerData[elem1][arItemsBought] < PlayerData[elem2][arItemsBought])         return 1             return 0 }

EFFx 01-28-2017 16:17

Re: Sort all arrays with one func
 
No, I mean ALL ARRAYS with just one SortCustom. And I meant not the ShortCustom1D, its not possible, I mean another custom function for it. As I said.

PHP Code:

enum PlayerDatas
{
       
arItemsBought,
       
arShoots,
       
arKills,
}

new 
PlayerData[33][PlayerDatas

PHP Code:


GetTop
(PlayerData[id][arKills])

GetTop(arArray[])
{
    new 
iPlayers[32], iPlayersnumPlayer;
    
    
get_players(iPlayersiPlayersnum)
    
    for(new 
i;iPlayersnum;i++)
    {
        
Player iPlayers[i]
        
        
SortCustom(PlayeriPlayersnumarArray)
    }
    return 
Player[0]
}

SortCustom(elem1elem2arArray[]) 
{
    if(
arArray[elem1] > arArray[elem2])
        return -
1
        
    
else if(arArray[elem1] < arArray[elem2])
        return 
1
        
    
return 0


I want return the player's index that have the most array's size. Example:

PHP Code:

for(new i;get_maxplayers();i++)
      
checkChance(ev_BestKillsGetTop(PlayerData[i][arKills]) 

the GetTop should return the player's index that have the most kills. You understand ? Because on the checkChance(), the second parameter is the player's index, I have it there:

PHP Code:

if(iIndex)
{
     new 
userName[32]
     
get_user_name(iIndexuserNamecharsmax(userName))



Black Rose 01-29-2017 06:21

Re: Sort all arrays with one func
 
No I don't understand.

You are looping a sorting function which is illogical.
checkChance() means nothing to me.
You can't supply a sorting function with an array that is related to one player. The whole point is that it is sorting all players. I think what you want to do is to send JUST "arKills", which is basically "2". and then use that as an offset in your internal code.

What you are doing now:
PlayerData[id][arKills] will return an integer basically that points to another integer which is NOT an array.
You then tell the code it's an array, and since it's the last entry in the enumeration you will get an index out of bounds as soon as "elem1" or "elem2" in combination with the previously set player offset "i" + arArray >= the size of your enumeration array.

What you want is the code that I wrote but I assume with more calculations inside. There's nothing that SortCustom1D can't sort, that's the point of SortCustom. You send a list of whatever you want sorted. You decide in the public function what criteria you want to be met and it does exactly that. It will return to you the array you sent it, sorted with the criteria you decided.

If you want to combine the three you first have to decide which of the three is most important. For example "shoots" which I assume is "shots" may be 10000 but kills and items bought are probably more important.
So either you select an order:
if (
items of player 1 > items of player 2
||
kills of player 1 > kills of player 2
||
shots of player 1 > shots of player 2
)
return -1

Or you create some kind of calculation to balance them out to a kind of score (in this case 1 item is worth 2 kills, 1000 shots is worth 1 kill):
if (
items of player 1 * 2 + kills of player 1 + shots of player 1 / 1000
>
items of player 2 * 2 + kills of player 2 + shots of player 2 / 1000
)
return -1

Then you apply it:
Code:
GetTop() {     new Players[32], iPlayersnum;         get_players(Players, iPlayersnum)     SortCustom1D(Players, iPlayersnum, "SortCustom")     return Players[0] } public SortCustom(elem1, elem2) {         if ( PlayerData[elem1][arItemsBought] * 2 + PlayerData[elem1][arKills] + PlayerData[elem1][arShoots] / 1000 > PlayerData[elem2][arItemsBought] * 2 + PlayerData[elem2][arKills] + PlayerData[elem2][arShoots] / 1000 )         return -1             else if ( PlayerData[elem1][arItemsBought] * 2 + PlayerData[elem1][arKills] + PlayerData[elem1][arShoots] / 1000 < PlayerData[elem2][arItemsBought] * 2 + PlayerData[elem2][arKills] + PlayerData[elem2][arShoots] / 1000 )         return 1             return 0 }

I might have misunderstood though. Maybe this is what you want:
Code:
GetTop(arItemsBought) GetTop(PlayerDatas:arOffset) {     new Players[32], iPlayersnum, data[1];     data[0] = any:arOffset;     get_players(Players, iPlayersnum)     SortCustom1D(Players, iPlayersnum, "SortCustom", data, 1);     return Players[0] } public SortCustom(elem1, elem2, array[], data[], datasize) {     new PlayerDatas:arOffset;     if ( ! datasize )         arOffset = PlayerDatas:data[0];     if ( PlayerData[elem1][arOffset] > PlayerData[elem2][arOffset] )         return -1     else if ( PlayerData[elem1][arOffset] < PlayerData[elem2][arOffset] )         return 1     return 0 }

Creating a custom sorting function is not as easy as looping players once. Google "Bubble Sort" to find some basic code if you want to create your own function. I would stick with SortCustom1D.

EFFx 01-29-2017 11:55

Re: Sort all arrays with one func
 
These codes just was for examples.
Obviously checkChance doesn't means nothing for you, I didn't say what it means, its my stock.

Look what I got with that code:

PHP Code:

/* Plugin generated by AMXX-Studio */

#include <amxmodx>
#include <amxmisc>

#define PLUGIN "New Plug-In"
#define VERSION "1.0"
#define AUTHOR "author"

enum Settings
{
    
arKills,
    
arSays
}

new 
PlayerData[33][Settings]

public 
plugin_init() 
{
    
register_plugin(PLUGINVERSIONAUTHOR)
    
    
register_event("DeathMsg","death","a")
    
    
register_clcmd("say /says","cmdSays")
    
register_clcmd("say /kills","cmdKills")

}

public 
death()
{
    
PlayerData[read_data(1)][arKills]++
}

public 
cmdKills(id)
{
    
console_print(id,"%d",GetTop(arKills))
    return 
PLUGIN_HANDLED
}
public 
cmdSays(id)
{
    
PlayerData[id][arSays]++
    
console_print(id,"%d",GetTop(arSays))
    return 
PLUGIN_HANDLED
}

GetTop(Settings:arOffset)
{
    new 
Players[32], iPlayersnumdata[1]
    
    
data[0] = any:arOffset
    get_players
(PlayersiPlayersnum)
    
SortCustom1D(PlayersiPlayersnum"SortCustom"data1)
    
    return 
Players[0]
}

public 
SortCustom(elem1elem2, array[], data[], datasize
{
    new 
Settings:arOffset
    
    
if(!datasize )
        
arOffset Settings:data[0]
    
    if(
PlayerData[elem1][arOffset] > PlayerData[elem2][arOffset])
        return -
1
    
    
else if(PlayerData[elem1][arOffset] < PlayerData[elem2][arOffset])
        return 
1
    
    
return 0


When I start the map and type /says, it returns 1, when one or more bots connect, it shows always 2.
When I start the map and type /kills, it returns 1, when one or more bots connect, it shows 2, when someone has killed, it shows sometimes 7 or 3. And after I died, it returns 2 again.


Look:

PHP Code:

/* Plugin generated by AMXX-Studio */

#include <amxmodx>
#include <amxmisc>

#define PLUGIN "New Plug-In"
#define VERSION "1.0"
#define AUTHOR "author"

enum Settings
{
    
arKills,
    
arSays
}

new 
PlayerData[33][Settings]

public 
plugin_init() 
{
    
register_plugin(PLUGINVERSIONAUTHOR)
    
    
register_clcmd("say /says","cmdSays")
}

public 
cmdSays(id)
{
    
PlayerData[id][arSays]++
    
    new 
iMostSays get_best_player()
    
console_print(id,"%d",iMostSays)
    return 
PLUGIN_HANDLED
}

get_best_player() 

    new 
players[32], num 
    get_players
(playersnum)
    
SortCustom1D(playersnum"sort_bestplayer"
    
    return 
players[0

public 
sort_bestplayer(id1id2

    if(
PlayerData[id1][arSays] > PlayerData[id2][arSays]) 
        return -
1
        
    
else if(PlayerData[id1][arSays]< PlayerData[id2][arSays]) 
        return 
1
    
    
return 0;


This is returning the player that has the biggest says. What I'm asking if is possible I make just the get_best_player() return all PlayerData enumerates. arKills, arSays. Something similar at what you've gave:

PHP Code:

get_best_player(PlayerData[id][arKills]) 

or

PHP Code:

get_best_player(PlayerData[id][arSays]) 


EFFx 01-30-2017 10:42

Re: Sort all arrays with one func
 
Ops, a mistake is up.
Your format isn't showing the top, sometimes I got: EFFx killed 1 enemies. But i've killed 2-3.

Black Rose 01-30-2017 12:36

Re: Sort all arrays with one func
 
So add a few debug messages to show where the problem is.

For example, if the message is displaying less than expected kills:
Log when it is supposed to register the kill count, preferably at more than one point until the variable is set. Including variable values if necessary.
At the point of the printing of the message, log all the variable values related to the message to find anything unexpected.

This is the best way to debug your code. It is also how you learn to understand the code.

The code is kind of big for me to debug since I don't know anything about it. I also can't compile it because I'm missing "cl_buy".
If you want me to debug, please tell me where to get the required files and how to reproduce the error and I will test with bots.

EFFx 01-30-2017 12:45

Re: Sort all arrays with one func
 
Sorry about the cl_buy, I tought you knew where to download it - https://forums.alliedmods.net/showthread.php?t=149380

About the debug, that's what I was doing, Bugsy already told me to always do it when something return a invalid value:

PHP Code:

/* Plugin generated by AMXX-Studio */

#include <amxmodx>
#include <amxmisc>

#define PLUGIN "New Plug-In"
#define VERSION "1.0"
#define AUTHOR "author"

enum Settings
{
    
arPlayerKills,
}

new 
PlayerData[33][Settings]

public 
plugin_init() 
{
    
register_plugin(PLUGINVERSIONAUTHOR)
    
    
register_event("DeathMsg","death","a")
    
    
set_task(1.0,"showHud",. flags "b")
}

public 
death()
{
    
PlayerData[read_data(1)][arPlayerKills]++
}
public 
showHud()
{
    new 
iMostSays GetTop(arPlayerKills)
    
    new 
UserName[32]
    
get_user_name(iMostSaysUserName31)
    
set_hudmessage(0,255,0, -1.00.001.01.0)
    
show_hudmessage(0,"First Player: %s, Kills: %d",UserNamePlayerData[iMostSays][arPlayerKills])
}

GetTop(Settings:arOffset)
{
    new 
Players[32], iPlayersnumdata[1]

    
data[0] = any:arOffset
    
    get_players
(PlayersiPlayersnum)
    
SortCustom1D(PlayersiPlayersnum"SortCustom"data1)

    return 
Players[0]
}

public 
SortCustom(elem1elem2, array[], data[], datasize
{
    new 
Settings:arOffset

    
if(!datasize)
        
arOffset Settings:data[0]

    if(
PlayerData[elem1][arOffset] > PlayerData[elem2][arOffset])
        return -
1

    
else if(PlayerData[elem1][arOffset] < PlayerData[elem2][arOffset])
        return 
1

    
return 0


I have 7 kills and the bot have 4, it shows the bot's name, not mine.

Black Rose 01-30-2017 13:44

Re: Sort all arrays with one func
 
Your sample code works fine for me, so does the big plugin as far as I can see. Is it just one event that has problems or multiple?

EFFx 01-30-2017 13:53

Re: Sort all arrays with one func
 
Yea, the code works fine inicially for me aswell. But example, when you has 7 kills, your name appears on the hud. But if a bot kill 3-4, it shows his name, the hud do not continue with mine. I don't know whats wrong, if the reason is because i'm using 1.8.3, I do not have any idea. And without your GetTop(), it doesn't happen, every value appear correctly. But when I tried to use your GetTop(), it get bugs. As I said, it appear: EFFx Killed 1 enemies while I have killed 2-3. Appear [P0D]Tommy_Lee_Jones (97) has finished off 0 woundest enemies or [P0D]Tommy_Lee_Jones (97) received attacks 0 before dying.


All times are GMT -4. The time now is 20:58.

Powered by vBulletin®
Copyright ©2000 - 2024, vBulletin Solutions, Inc.