Raised This Month: $ Target: $400
 0% 

Killstreak plugin - problem


Post New Thread Reply   
 
Thread Tools Display Modes
Author Message
subs
Junior Member
Join Date: Aug 2013
Old 08-12-2013 , 21:21   Killstreak plugin - problem
Reply With Quote #1

Hi,

It's my first post ever here, on Allied Modders, today is also the first time I started writing my own plugin.
This forum is quite helpful for most of the cases but now it seems I can't find the answer in other threads/help requests/approved plugins. That's why I need Your help.

I've started writing Killstreak Plugin which (hopefully) is going to look like this:
If players' killstreak is equal or more than 5 he gets +2 points for each kill, if players' killstreak is equal or more than 10 he gets +3 points for each kill. In the end there's a HUD message with current killstreak count.

Everything is working great except for one thing..
Any kill made by every player on the server raises the killstreak counter thus making everyone having a killstreak. I've been trying to find the mistake for like an hour and it seems I'm either blind or just did something wrong from the very beginning.

Sorry for long post and thanks in advance for some guides/help.
Wall of text - off, here's another one:

PHP Code:
#include <amxmodx>
#include <fun>

#define PLUGIN "MISC Killstreak"
#define VERSION "1.0"
#define AUTHOR "subs"

new g_Killerg_Killsg_MsgScoreInfo

public plugin_init()
{
    
register_plugin(PLUGINVERSIONAUTHOR)
    
register_event("DeathMsg""msgDeath""a""1>0")
    
    
set_task(1.0"showKillstreak"0""0"b")
    
    
g_MsgScoreInfo get_user_msgid("ScoreInfo")
}

public 
msgDeath(id)
{
    
g_Killer read_data(1)
    
    if (
g_Killer && is_user_alive(g_Killer))
    {
        
g_Kills++    // Start killstreak counter
        
        
if (g_Kills >= && g_Kills 10// Give +2 points for each kill if players' killstreak is equal or more than 5
        
{
            
set_user_frags(g_Killerget_user_frags(g_Killer) + 1)
        }
            
        else if (
g_Kills >= 10// Give +3 points for each kill if players' killstreak is equal or more than 10
        
{
            
set_user_frags(g_Killerget_user_frags(g_Killer) + 2)
        }
        
message_begin(MSG_ALLg_MsgScoreInfo// Add points to scoreboard
        
write_byte(g_Killer)
        
write_short(get_user_frags(g_Killer))
        
write_short(get_user_deaths(g_Killer))
        
write_short(0)
        
write_short(get_user_team(g_Killer))
        
message_end()
    }
    else
    {
        
g_Kills // Clear killstreak counter when player dies
    
}
}

public 
showKillstreak(id)
{
    
set_hudmessage(0952450.00.000.01.10.10.515
    
show_hudmessage(id"Killstreak: %i"g_Kills


Last edited by subs; 08-12-2013 at 21:29. Reason: Correction
subs is offline
wickedd
Veteran Member
Join Date: Nov 2009
Old 08-12-2013 , 21:36   Re: Killstreak plugin - problem
Reply With Quote #2

PHP Code:
new g_Kills33 ]


public 
msgDeath( )
{
    ++
g_Killsid ]

    if( 
g_Killsid ] >= )
    {
        
//your code
    
}

__________________
Just buy the fucking game!!!!
I hate No-Steamers and lazy ass people.

Last edited by wickedd; 08-12-2013 at 21:39.
wickedd is offline
Black Rose
Veteran Member
Join Date: Feb 2011
Location: Stockholm, Sweden
Old 08-12-2013 , 21:41   Re: Killstreak plugin - problem
Reply With Quote #3

Some of your variables didn't really need to be global, therefor I moved them inside of the function.

Code:
if (g_Killer && is_user_alive(g_Killer)) { // ... else {     g_Kills = 0 // Clear killstreak counter }
This check is pretty good for a beginner since most beginners just assume that everyone is connected and alive. But in this case I felt that it's more relevant if people are connected than actually alive. Being alive doesn't affect the function that you are trying to achieve. Also, if someone would commit suicide g_Killer would be 0 and therefor you would reset the counter.



Code:
        if (g_Kills[killer] >= 5 && g_Kills[killer] < 10) // Give +2 points for each kill if players' killstreak is equal or more than 5         {             set_user_frags(killer, get_user_frags(killer) + 1)         }                 else if (g_Kills[killer] >= 10) // Give +3 points for each kill if players' killstreak is equal or more than 10         {             set_user_frags(killer, get_user_frags(killer) + 2)         }
If you want you could replace this with
Code:
set_user_frags(killer, get_user_frags(killer) + g_Kills[killer] >= 10 ? 2 : g_Kills[killer] >= 5 ? 1 : 0)
This will make the code slightly harder to read but much more compact.

You could also do this but then it wouldn't stop at +2, it could continue forever.
Code:
set_user_frags(killer, get_user_frags(killer) + g_Kills[killer] / 5)

You could of course solve that by doing this which is compact and readable.
Code:
set_user_frags(killer, get_user_frags(killer) + clamp(g_Kills[killer] / 5, 0, 2))
The clamp(value, min, max) makes sure that value stays between min and max

In the end coding is so much personal preference, so you decide which option suits you best.



Here's an example that should work:
Code:
#include <amxmodx> #include <fun> #define PLUGIN "MISC Killstreak" #define VERSION "1.0" #define AUTHOR "subs" new g_MsgScoreInfo new g_Kills[33] public plugin_init() {     register_plugin(PLUGIN, VERSION, AUTHOR)     register_event("DeathMsg", "msgDeath", "a", "1>0")         set_task(1.0, "showKillstreak", 0, "", 0, "b")         g_MsgScoreInfo = get_user_msgid("ScoreInfo") } public msgDeath(id) {     new killer = read_data(1)     new victim = read_data(2)         if ( is_user_connected(victim) )         g_Kills[victim] = 0         if ( is_user_connected(killer) )     {         g_Kills[killer]++    // Start killstreak counter                 set_user_frags(killer, get_user_frags(killer) + clamp(g_Kills[killer] / 5, 0, 2))                 message_begin(MSG_ALL, g_MsgScoreInfo) // Add points to scoreboard         write_byte(killer)         write_short(get_user_frags(killer))         write_short(get_user_deaths(killer))         write_short(0)         write_short(get_user_team(killer))         message_end()     } } public showKillstreak(id) {     set_hudmessage(0, 95, 245, 0.0, 0.0, 0, 0.0, 1.1, 0.1, 0.5, 15)       show_hudmessage(id, "Killstreak: %i", g_Kills)   }
__________________

Last edited by Black Rose; 08-12-2013 at 21:45.
Black Rose is offline
subs
Junior Member
Join Date: Aug 2013
Old 08-12-2013 , 22:01   Re: Killstreak plugin - problem
Reply With Quote #4

Thank you for such fast response !

I guess it was mostly about this?
PHP Code:
g_Kills[killer]++ 
What about ?
PHP Code:
new g_Kills[33
I mean, what if someone, somehow gets more than that?

And thanks for kind words, trying to do my best


++
Found another problem, this time with HUD Message.
Since it didn't count killstreak at all I've changed it from:
PHP Code:
public showKillstreak(id

    
set_hudmessage(0952450.00.000.01.10.10.515)  
    
show_hudmessage(id"Killstreak: %i"g_Kills)  

to:
PHP Code:
public showKillstreak(id

    
set_hudmessage(0952450.00.000.01.10.10.515)  
    
show_hudmessage(id"Killstreak: %i"g_Kills[killer])  

Now it counts but whenever anyone builds its killstreak it shows up on my HUD Message.
(I kill = shows my kills, someone kills = show its kills)

Last edited by subs; 08-12-2013 at 22:28. Reason: Another problem
subs is offline
Black Rose
Veteran Member
Join Date: Feb 2011
Location: Stockholm, Sweden
Old 08-12-2013 , 22:41   Re: Killstreak plugin - problem
Reply With Quote #5

The g_Kills[33] creates 33 an array of variables that are separated.
We use these to store the 32 players in index 1-32, index 0 is never used for readability. We don't use id-1 just to save some memory.

This is of course instead of using separate variables for everyone, because that would just be stupid. For example:
Code:
new g_Kills1 new g_Kills2 new g_Kills3 // ... new g_Kills31 new g_Kills32 // And when it's called: if ( id == 1 )     g_Kills1++ if ( id == 2 )     g_Kills2++ if ( id == 3 )     g_Kills3++ // ... if ( id == 31 )     g_Kills31++ if ( id == 32 )     g_Kills32++

So when g_Kills[id] is called, and lets say id is 4 then the 4th index of the variable will be read. The limit of the variable is way more than what you will achieve before a mapchange or the server crashes by random.
__________________

Last edited by Black Rose; 08-12-2013 at 22:43.
Black Rose is offline
subs
Junior Member
Join Date: Aug 2013
Old 08-12-2013 , 22:43   Re: Killstreak plugin - problem
Reply With Quote #6

Thanks for explanation
Any ideas on this HUD message thing?
subs is offline
Old 08-12-2013, 22:58
wickedd
This message has been deleted by wickedd. Reason: nvm look below
Black Rose
Veteran Member
Join Date: Feb 2011
Location: Stockholm, Sweden
Old 08-12-2013 , 23:16   Re: Killstreak plugin - problem
Reply With Quote #8

Sorry I didn't read that.
Well since killer is an argument that is sent through the message "DeathMsg" you cannot use it like before.
The best way would be to loop through players and check which are connected/alive (whichever you want) and then display it to everyone. You only have to loop the actual show_hudmessage(), not set_hudmessage.

Here are some examples, they all work:
Code:
#include <amxmodx> public plugin_init() {     register_plugin("Test Plugin ", "", "");     } public showKillstreak(id) {     new iPlayers     new Players[32]         get_players(Players, iPlayers, "ach")     /*     * This will retreive player ID's of the players that are matching the condition of "flags"     * In this case "ac" means we return people who are:     * "a" Not dead (One could say alive, dead people doesn't have a killstreak)     * "c" Not a bot (They can't see messages)     * "h" Not HLTV (They aren't playing, they don't have a killstreak)     *     * iPlayers is a return that will be set to the number of players inside of "Players" array.     *     * Explenation of parameter 3, flags:     * "a" - don't collect dead players.     * "b" - don't collect alive players.     * "c" - skip bots.     * "d" - skip real players.     * "e" - match with team.     * "f" - match with part of name.     * "g" - ignore case sensitivity.     * "h" - skip HLTV.     */         // This line can stay outside of the loop, the arguments will get saved for all players     set_hudmessage(0, 95, 245, 0.0, 0.0, 0, 0.0, 1.1, 0.1, 0.5, 15)         /* This creates a loop. The loop will start with 0 since that's what we set i to.     * It will then repeat what's inside of the loop until i reaches iPlayers.     * It will add 1 to i after every loop.     * If we set it to ++i it will be added before the loop is started but that destroys the point of this.     *     * Inside this Players[] array all the relevant indexes of players are stored.     * It then get's the first relevant index with Players[i] (Players[0] in the first loop)     * That index will then be used inside g_Kills.     *     * Let's say that the first loop has an i value of 0, which it always is.     * Players[i] (Players[0]) can for example hold a player ID of 4 because that is the first ID that matches our flags ("ach").     * So basically it calls the variable g_Kills[4]     */         for ( new i = 0 ; i <= iPlayers ; i++ )         show_hudmessage(id, "Killstreak: %i", g_Kills[Players[i]])   }
Here is another way where we don't use get_players() and instead make our own filter.
The outcome is the same, it's just another way of doing it.
Code:
#include <amxmodx> #include <fakemeta> // One of these methods require global_get() which is a function of the fakemeta library. // So we have to include that before we can use the functions, otherwise the script won't compile. new g_MaxClients public plugin_init() {     register_plugin("Test Plugin ", "", "");         g_MaxClients = global_get(glb_maxClients);     /* This is set to max players, this makes sure we don't do any work where it's not needed.     * It basically replaces iPlayers in the previous example.     */ } public showKillstreak(id) {     // This line can stay outside of the loop, the arguments will get saved for all players     set_hudmessage(0, 95, 245, 0.0, 0.0, 0, 0.0, 1.1, 0.1, 0.5, 15)         /* Here the maxclients are set to 32.     * This is generally seen as bad coding habits since some servers have, for example, 24 players.     * We could avoid this extra work of looping through 8 ID's that will never exist in next example     */     for ( new i = 0 ; i <= 32 ; i++ ) {         if ( is_user_connected(i) && is_user_alive(i) && ! is_user_bot(i) && ! is_user_hltv(i) )             show_hudmessage(id, "Killstreak: %i", g_Kills[i])     }         /* In this example we take use of global_get(glb_MaxClients) and store that value in a variable.     * This means that if the maxclients are set to, for example, 24 the variable g_MaxClients would be set to that.     * This would stop us from looping through those ID's that will never exist.     */     for ( new i = 0 ; i < g_MaxClients ; i++ ) {         if ( is_user_connected(i) && is_user_alive(i) && ! is_user_bot(i) && ! is_user_hltv(i) )             show_hudmessage(id, "Killstreak: %i", g_Kills[i])     } }


I suggest you longen the time of the HudMessage and shorten the set_task() interval. You could add a second HudMessage to update every time the kills get updated instead. If the channel is the same on both messages the new one will overwrite the old one:
Code:
#include <amxmodx> #include <fun> #define PLUGIN "MISC Killstreak" #define VERSION "1.0" #define AUTHOR "subs" new g_MsgScoreInfo new g_Kills[33] new g_MaxClients public plugin_init() {     register_plugin(PLUGIN, VERSION, AUTHOR)     register_event("DeathMsg", "msgDeath", "a", "1>0")         set_task(10.0, "showKillstreak", 0, "", 0, "b")         g_MsgScoreInfo = get_user_msgid("ScoreInfo")     g_MaxClients = global_get(glb_maxClients); } public msgDeath(id) {     new killer = read_data(1)     new victim = read_data(2)         if ( is_user_connected(victim) )     g_Kills[victim] = 0         if ( is_user_connected(killer) )     {         g_Kills[killer]++    // Start killstreak counter                 set_user_frags(killer, get_user_frags(killer) + clamp(g_Kills[killer] / 5, 0, 2))                 message_begin(MSG_ALL, g_MsgScoreInfo) // Add points to scoreboard         write_byte(killer)         write_short(get_user_frags(killer))         write_short(get_user_deaths(killer))         write_short(0)         write_short(get_user_team(killer))         message_end()     }         // Whenever there's a change it will update immediately instead of waiting for the next loop.     // There are only 4 channels of hudmessages and -1 which is auto (1-4). I changed to channel 2.     // If it conflicts with another message, try another channel by changing the last parameter.     // Remember to change it in showKillstreak() aswell.     set_hudmessage(0, 95, 245, 0.0, 0.0, 0, 0.0, 10.1, 0.1, 0.5, 2)     show_hudmessage(id, "Killstreak: %i", g_Kills[killer]) } public showKillstreak(id) {     set_hudmessage(0, 95, 245, 0.0, 0.0, 0, 0.0, 10.1, 0.1, 0.5, 2)     for ( new i = 0 ; i <= g_MaxClients ; i++ ) {         if ( is_user_connected(i) && is_user_alive(i) && ! is_user_bot(i) && ! is_user_hltv(i) )         show_hudmessage(id, "Killstreak: %i", g_Kills[i])     } }
__________________

Last edited by Black Rose; 08-13-2013 at 10:02.
Black Rose is offline
devilicioux
Veteran Member
Join Date: Jun 2013
Location: Delhi,India
Old 08-13-2013 , 04:08   Re: Killstreak plugin - problem
Reply With Quote #9

Wow !! Just read Up the Black Rose's Explanation Learnt alot
Tysm Black Rose for awesome explanation.And Plugin is Nice as well.

Edit : Have 1 question in mind .. what is the actual difference between
MSG_BROADCAST and MSG_ALL

Searched a little it says the difference is the streams of sending message . Didnt understand.
Can any1 give a quick info regarding streams and when to use _BROADCAST and When _ALL ?
__________________
You keep bringing ANTICHRISTUS down .. He will rise again and kick asses !

#RespectList ANTICHRISTUS fysiks Bugsy

Most Common Errors You Can Encounter Every Now and Then

Last edited by devilicioux; 08-13-2013 at 04:13. Reason: Quick Ques
devilicioux is offline
Black Rose
Veteran Member
Join Date: Feb 2011
Location: Stockholm, Sweden
Old 08-13-2013 , 07:42   Re: Killstreak plugin - problem
Reply With Quote #10

Quote:
Originally Posted by devilicioux View Post
Wow !! Just read Up the Black Rose's Explanation Learnt alot
Tysm Black Rose for awesome explanation.And Plugin is Nice as well.

Edit : Have 1 question in mind .. what is the actual difference between
MSG_BROADCAST and MSG_ALL

Searched a little it says the difference is the streams of sending message . Didnt understand.
Can any1 give a quick info regarding streams and when to use _BROADCAST and When _ALL ?
This is defined in message_const.in
Code:
#define	MSG_BROADCAST               0        // Unreliable to all
#define	MSG_ONE                     1        // Reliable to one (msg_entity)
#define	MSG_ALL                     2        // Reliable to all
#define	MSG_INIT                    3        // Write to the init string
#define MSG_PVS                     4        // Ents in PVS of org
#define MSG_PAS                     5        // Ents in PAS of org
#define MSG_PVS_R                   6        // Reliable to PVS
#define MSG_PAS_R                   7        // Reliable to PAS
#define MSG_ONE_UNRELIABLE          8        // Send to one client, but don't put in reliable stream, put in unreliable datagram (could be dropped)
#define	MSG_SPEC                    9        // Sends to all spectator proxies
The most used are of course BROADCAST, ALL, ONE and ONE_UNRELIABLE.
I'm sure you could find a more detailed explanation by one of the top coders if you search the forum.
A rule of thumb is to use BROADCAST and ONE_UNRELIABLE unless it's absolutely critical that the message reaches the client.
__________________
Black Rose is offline
Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -4. The time now is 16:00.


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