AlliedModders

AlliedModders (https://forums.alliedmods.net/index.php)
-   Scripting Help (https://forums.alliedmods.net/forumdisplay.php?f=11)
-   -   overkill, losing negative points? (https://forums.alliedmods.net/showthread.php?t=177313)

HLM 01-30-2012 21:54

overkill, losing negative points?
 
I have a heavily modified version of the overkill version available on these forums, here is my overkill code, the problem with it is the new feature I added, when the numbers become too large, you beging to lose negative values, meaning you are getting points when you should be losing them.

PHP Code:

public overkill() 
{
    if (!
get_pcvar_num(amx_overkill))
    return 
PLUGIN_CONTINUE
    
new killerid read_data(1)
    new 
victimid read_data(2)
    new 
victimname[32]
    
get_user_name(victimid,victimname,31)
    if( (
killerid == ) || (victimid == 0) || (killerid == victimid ) )
    return 
PLUGIN_CONTINUE
    
    
//users should already connected and killer should be alive... duh.. >< just check for safety
    
if(!is_user_connected(victimid))
    return 
PLUGIN_CONTINUE
    
//Reward if it's a teamkill?
    
if (get_user_team(killerid) == get_user_team(victimid) && !get_pcvar_num(amx_ok_ff))
    return 
PLUGIN_CONTINUE
    g_health
[victimid] = 100    
    
new Float:hp float(get_user_health(victimid) * -1)
    if (!
hp)
    return 
PLUGIN_CONTINUE
    
new Float:rewardhp,Float:temp,Float:reward_cap float(get_pcvar_num(amx_ok_reward_cap)),Float:perc get_pcvar_num(amx_ok_perc) / 100.0,Float:perc_capped get_pcvar_num(amx_ok_perc_capped) / 100.0,Float:tempperc
    
new inloop 1
    
    
while (inloop)
    {    
        if (
hp <= reward_cap) {
            
temp hp perc
            inloop 
0
        
}
        
        else {
            
temp reward_cap perc
            hp 
-= reward_cap
            
            tempperc 
perc
            perc 
perc perc_capped
            
//client_print(killerid,print_chat,"perc %d hp %d",perc,hp)
            
if (perc 0) {
                
tempperc perc_capped perc
                temp 
+= tempperc hp
                inloop
=0
                
//client_print(killerid,print_chat,"in loop perc < 0 **perc=%d",perc)
            
}
        }
        
        
rewardhp += temp
    
}
    
    new 
Float:maxreward float(get_pcvar_num(amx_ok_max))
    if (
maxreward)
    
rewardhp rewardhp maxreward maxreward rewardhp
    
    
new Float:health float(get_user_health(killerid))
    
health += rewardhp
    
    
new Float:life_cap float(get_pcvar_num(amx_ok_life_cap))
    if (
life_cap)
    
health health life_cap life_cap health
    
    
    
if(is_user_alive(killerid))
    {
        if(
g_health[killerid] == life_cap)
        {
            
client_print(killerid,print_chat"[OK] Could not gain any more life, you are capped! (%d)",floatround(life_cap))
        }
        else
        {
            
g_health[killerid] = (floatround(health))
            
set_user_health(killerid,floatround(health))
            
client_print(killeridprint_chat"[OK] +%dhp!",floatround(rewardhp))
        }
    }
    if(
get_pcvar_num(amx_ok_bb_enable))
    {
        
get_user_name(victimid,victimname,31)
        new 
healthtransfer g_bhealth[victimid]/2
        
if(healthtransfer 1)
        
healthtransfer 1
        
new healthloss =((g_bhealth[victimid]*10) / (25))
        if(
get_pcvar_num(amx_ok_bb_cap_override))
        {
            
g_bhealth[victimid] -= healthloss
            g_bhealth
[killerid] += healthtransfer
            client_print
(killerid,print_chat,"[OK] (%d)  +%d blood for killing %s.",g_bhealth[killerid],healthtransfer,victimname)
            
client_print(victimid,print_chat,"[OK] (%d) -%d blood.",g_bhealth[victimid],healthloss)
            
DisplayHud(victimid)
            
DisplayHud(killerid)
        }
        else if(!
get_pcvar_num(amx_ok_bb_cap_override))
        {
            if((
g_bhealth[killerid] + healthtransfer) <= (get_pcvar_num(amx_ok_bb_cap)))
            {
                
g_bhealth[victimid] -= healthloss
                g_bhealth
[killerid] += healthtransfer
                client_print
(killerid,print_chat,"[OK] (%d)  +%d blood for killing %s.",g_bhealth[killerid],healthtransfer,victimname)
                
client_print(victimid,print_chat,"[OK] (%d) -%d blood.",g_bhealth[victimid],healthloss)
                
DisplayHud(victimid)
                
DisplayHud(killerid)
            }
            else
            {
                
g_bhealth[killerid] = (get_pcvar_num(amx_ok_bb_cap))
                
client_print(killerid,print_chat,"[OK] You could not gain any more Blood, because your current bank is full(%d)!",(get_pcvar_num(amx_ok_bb_cap)))
                
g_bhealth[victimid] -= healthloss
                g_bhealth
[killerid] = (get_pcvar_num(amx_ok_bb_cap))
                
client_print(victimid,print_chat,"[OK] (%d) -%d blood.",g_bhealth[victimid],healthloss)
                
DisplayHud(victimid)
                
DisplayHud(killerid)
            }
        }
    }
    return 
PLUGIN_CONTINUE 


and here is the fragment of the code that is in need of attention from above.

PHP Code:

if(get_pcvar_num(amx_ok_bb_enable))
    {
        
get_user_name(victimid,victimname,31)
        new 
healthtransfer g_bhealth[victimid]/2
        
if(healthtransfer 1)
        
healthtransfer 1
        
new healthloss =((g_bhealth[victimid]*10) / (25))
        if(
get_pcvar_num(amx_ok_bb_cap_override))
        {
            
g_bhealth[victimid] -= healthloss
            g_bhealth
[killerid] += healthtransfer
            client_print
(killerid,print_chat,"[OK] (%d)  +%d blood for killing %s.",g_bhealth[killerid],healthtransfer,victimname)
            
client_print(victimid,print_chat,"[OK] (%d) -%d blood.",g_bhealth[victimid],healthloss)
            
DisplayHud(victimid)
            
DisplayHud(killerid)
        }
        else if(!
get_pcvar_num(amx_ok_bb_cap_override))
        {
            if((
g_bhealth[killerid] + healthtransfer) <= (get_pcvar_num(amx_ok_bb_cap)))
            {
                
g_bhealth[victimid] -= healthloss
                g_bhealth
[killerid] += healthtransfer
                client_print
(killerid,print_chat,"[OK] (%d)  +%d blood for killing %s.",g_bhealth[killerid],healthtransfer,victimname)
                
client_print(victimid,print_chat,"[OK] (%d) -%d blood.",g_bhealth[victimid],healthloss)
                
DisplayHud(victimid)
                
DisplayHud(killerid)
            }
            else
            {
                
g_bhealth[killerid] = (get_pcvar_num(amx_ok_bb_cap))
                
client_print(killerid,print_chat,"[OK] You could not gain any more Blood, because your current bank is full(%d)!",(get_pcvar_num(amx_ok_bb_cap)))
                
g_bhealth[victimid] -= healthloss
                g_bhealth
[killerid] = (get_pcvar_num(amx_ok_bb_cap))
                
client_print(victimid,print_chat,"[OK] (%d) -%d blood.",g_bhealth[victimid],healthloss)
                
DisplayHud(victimid)
                
DisplayHud(killerid)
            }
        }
    } 



I don't believe I have left out any majorly needed calls or functions or globals, but if you need more information please let me know so I can add it in hopes that I can get help with this, because I am stuck on this problem :/

fysiks 01-30-2012 22:46

Re: overkill, losing negative points?
 
I don't see any reference to "points." You should do some debuging and check the value of the "points" at several different points in the problem code. Then, when it shows something wrong (meaning not what you expected), you know where to look.

HLM 01-30-2012 23:54

Re: overkill, losing negative points?
 
PHP Code:

new healthloss =((g_bhealth[victimid]*10) / (25)) 

why would this math operation return a value of -1? what does it mean and how do I fix it?

edit: I know why, but I want to know how to fix the numbers from going whatever the integer limit may be (2147483647 ?)

fysiks 01-31-2012 00:11

Re: overkill, losing negative points?
 
Quote:

Originally Posted by HLM (Post 1641588)
PHP Code:

new healthloss =((g_bhealth[victimid]*10) / (25)) 

why would this math operation return a value of -1? what does it mean and how do I fix it?

edit: I know why, but I want to know how to fix the numbers from going whatever the integer limit may be (2147483647 ?)

Explain why (since you know). And . . . what? If you are going over the limit then you need to rethink your algorithms.

Also, do you realize that that type of division is not the "normal" type of division? It's called integer division:

E.g.
25/4 = 6
124/25 = 4
etc.

HLM 01-31-2012 00:41

Re: overkill, losing negative points?
 
I dont know of a better way of taking 25% of an integer properly, that would explain my math, and as for the limit, I plan on just setting a limit to the in32 limit, since many of my users have met and exceed that limit.
I will just have to rework my if and else ifs..

fysiks 01-31-2012 00:58

Re: overkill, losing negative points?
 
Quote:

Originally Posted by HLM (Post 1641630)
I dont know of a better way of taking 25% of an integer properly

25% means 1/4 so you have to divide by four (4). You can still use integer math if you don't want to be very accurate (and likely non-consistent). Otherwise, you should use float division then round the answer.

If I calculated correctly, integer division is the same as float division but instead of rounding you use floor().

HLM 01-31-2012 02:29

Re: overkill, losing negative points?
 
looks like ive over complicated things myself a little bit too, lol

thanks for the help fysiks.

edit: one more question, if I want to make a check to see if it reaches the limit, should I check if its bigger than 2147483647, or should I check if it returns -1 ?

fysiks 01-31-2012 02:51

Re: overkill, losing negative points?
 
Quote:

Originally Posted by HLM (Post 1641683)
edit: one more question, if I want to make a check to see if it reaches the limit, should I check if its bigger than 2147483647, or should I check if it returns -1 ?

It's not possible for a number to be bigger than 2147483647. If the stored number is normally stored as positive and will never be negative then you should be able to check for less than 0.

I'm sure there is a method of simulating an unsigned integer (which never goes negative) but I'm not sure that it is worth it.

My best suggestion, however, is to modify how you calculate these "points" or whatever so that they don't gain them fast enough to reach such a limit. Another alternative would be to use a level system. When they reach a max value of "points" then you level them up and start the points over. So, the real point values would be calculated by (not literally):

real_points = level * max_points_per_level + points

This should make the real_points capable of reaching a max of (total_levels * max_points_per_level).


All times are GMT -4. The time now is 17:55.

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