Raised This Month: $ Target: $400
 0% 

Descent 3 style scoreboard


Post New Thread Reply   
 
Thread Tools Display Modes
Author Message
CornetTheory
Junior Member
Join Date: Jan 2007
Old 01-21-2007 , 04:02   Descent 3 style scoreboard
Reply With Quote #1

please excuse my terrible English, I'm from America.

If you have ever played Descent3, you may remember the unique way it handled the scoreboard:

1. your player would have a number of frags and deaths and it would show your kill to death ratio plus points per hour etc...

all ordered from top score to bottom score

PLAYERA ----- 100kills 30deaths etc..
playerB ----- 30 78
playerC ------23 90
playerD -------90 20


2. when you left the server for whatever reason, your name would appear along with your score, grayed out to everyone else and the board would look like this:


playerB ----- 30kills 78deaths etc..
playerC ------23 90
PLAYERA --- 100 30
playerd ----- 90 20

players B and C are still in the game like normal, but the previous players that are now disconnected, have the scores ordered by kills below the active players.

3. Now, if you "playerA" were to rejoin the match before the map changed, your score would be reinstated, so that the scoreboard would look like this again... (and notice that playerD got off the can and rejoined also)

PLAYERA ----- 100kills 30deaths etc..
playerD -------90 20
playerB ----- 30 78
playerC ------23 90

So what we have here now, turning to the HLDM engine and pawn code, is I would suppose a text file that gets updated with every kill and then caches the player's score details so that even if someone leaves, they can regain their score. Also while they are gone, the other players have a chance to see the absent players 'scores and can then try to beat it.

one thing that I would change is player recognization based off of IP (or steam ID, I personally would prefer IP) so that names can be variable.

another thing that would be really cool, and a bit more like descent3 would be to assign a scoreboard text color for each person's scoreboard ID (assuming it does not change until the map changes) and storing that as well. so that player A "who joined first" will always be red until the map changes and playerB would be blue...ands so on.


I have tried to code this myself, and I found out that by the time it takes me to figure it out, I will be very old. so if some one can do it for me that is wonderful.

if someone can explain what I need to do to structure this into code myself while making it for me that is awesome too.


thanks guys, I now fall upon your expertise.



EDIT: I got a complaint about this post because I said "please excuse my terrible English, I'm from America."

I am in fact American, and I do not speak perfect English. however I speak it much better than the average American, so I made a crack about Americans. Deal with it, from reading these forums for a while, I noticed there are a bunch of grammar-nazis that critisize people for insignificant things, and I didn't want to deal with that.

Last edited by CornetTheory; 01-23-2007 at 19:41.
CornetTheory is offline
Old 01-21-2007, 17:36
kmal2t
This message has been deleted by kmal2t.
CornetTheory
Junior Member
Join Date: Jan 2007
Old 01-21-2007 , 18:05   Re: Descent 3 style scoreboard
Reply With Quote #2

so yea, searching for Descent3 scoreboard would have helped me. gotcha

and I'm not even sure if I want the deaths to be remembered, because I don't think descent remembered them anyway, I just would like that as a plus.

I also want the old scores to be shown in the scoreboard. That I cannot figure out for the life of me

Last edited by CornetTheory; 01-21-2007 at 18:07.
CornetTheory is offline
stupok
Veteran Member
Join Date: Feb 2006
Old 01-22-2007 , 18:13   Re: Descent 3 style scoreboard
Reply With Quote #3

I don't think it's possible to add information to the scoreboard. You can only modify information, like changing a player's team or score/deaths. So having scores from people that are disconnected isn't possible as far as I know.

You could add fake clients and use their id's to write extra information to the scoreboard, but that is very impractical because they would use up slots on your server.

You can take a look at these two plugins, maybe they will suffice.

Enhanced Frags Per Hour

Stats Set Frags/Deaths *Updated 1.7* (Contains DoD + CS)

Last edited by stupok; 01-22-2007 at 18:15.
stupok is offline
Old 01-22-2007, 21:47
kmal2t
This message has been deleted by kmal2t.
stupok
Veteran Member
Join Date: Feb 2006
Old 01-22-2007 , 22:16   Re: Descent 3 style scoreboard
Reply With Quote #4

He never said what mod he wanted the plugin for.

Enhanced Frags Per Hour has nothing to do with set_user_deaths, it just uses csstats.

Also, you can change the scoreboard without "cs_set_user_deaths".
stupok is offline
Old 01-22-2007, 22:41
kmal2t
This message has been deleted by kmal2t.
CornetTheory
Junior Member
Join Date: Jan 2007
Old 01-22-2007 , 23:00   Re: Descent 3 style scoreboard
Reply With Quote #5

when I said "HLDM engine"(in the OP) I meant HLDM as the mod it is for.

I actually modified the one called"remember frags and deaths" so that it only remembers frags "I removed all the code that had to do with "teams" and "deaths"

Thanks for getting back to me about the scoreboard, I suppose there is no way if the API isn't there. and as for the deaths, I really don't need those remembered, because it wasn't like that in D3


now I'm getting these errors in the console, despite the fact that the plug works:


L 01/22/2007 - 22:09:29: Plugin called message_begin with an invalid message id (0).
L 01/22/2007 - 22:09:29: [AMXX] Run time error 10 (plugin "D3_scoreboard.amxx") (native "message_begin") - debug not enabled!
L 01/22/2007 - 22:09:29: [AMXX] To enable debug mode, add "debug" after the plugin name in plugins.ini (without quotes).

I did that in the server before I changed anything so I don't know if it is bad or takes up CPU time. it certainly takes up console space though and I would like to fix it.

another thing that would be nifty, perhaps as a consolation...

can we draw this:Enhanced Frags Per Hour to the hud during game play? and perhaps, can the disconnected players be shown there?

Last edited by CornetTheory; 01-22-2007 at 23:24.
CornetTheory is offline
stupok
Veteran Member
Join Date: Feb 2006
Old 01-23-2007 , 00:07   Re: Descent 3 style scoreboard
Reply With Quote #6

If you want some guidance with your faulty plugin, post the source code. (Preferably in Scripting Help.)

In fact, you could actually have a "fake" scoreboard made in a hud display instead of the regular scoreboard, if that is what you want.
stupok is offline
kmal2t
BANNED
Join Date: Apr 2006
Old 01-23-2007 , 01:49   Re: Descent 3 style scoreboard
Reply With Quote #7

I want it to show on the normal +showscores menu when people hit tab.
kmal2t is offline
CornetTheory
Junior Member
Join Date: Jan 2007
Old 01-23-2007 , 09:08   Re: Descent 3 style scoreboard
Reply With Quote #8

As I said in the last post, before I changed anything it was giving me the error, that's why I didn't post the code because it was presumed you could already find it. I am guessing it only produces errors in the console because I am running it in HLDM.

The plugin works, it saves your kills, it saves my bot's kills, and it seems to only remember them after you first make a kill. example: I enter the server with 0 kills, I have 0 kills until I kill something, now I have 345+1 kills on the +scoreboard. For my purposes it is not perfect, I would like it to remember the kills sooner on client connect, I should not have to wait until I kill something. however if it is an issue about how many times the server must parse the database then I can live with how it works now.

now, ADDING to this plugin, yes I want to place a 5 or 6 line mini scoreboard to the HUD while the game is going on with K/D ratio and KPH or KPM or whatever. because descent3 also had this.

as you can see from the code I ripped off johnny's plugin, removed all the death and team variables, and tried to use non-CS #includes, and changed the code accordingly. it compiles with 0 warnings and 0 errors
Code:
new PLUGINNAME[] = "Remember the frags-mod"
new VERSION[] = "0.6"
new AUTHOR[] = "CornetTheory"
/*
AMX MOD X: http://www.amxmodx.org/forums/viewtopic.php?p=15733
AMX MOD: http://amxmod.net/forums/viewtopic.php?t=19024
Copyleft by Johnny got his gun <-- CornetTheory is just a dirty copycat hack.!

REMEMBER THE FRAGS
==================
Frags and deaths count will be remembered by server when you log off/map changes/server shuts down. Next time you log on your frags and deaths count will be like they were when you left.
With a cvar you can have the stats reset after a specific amount of seconds and when a new map loads - this way you can prevent "reconnectors" since their frags + deaths will remain unchanged for the specified time, or until a new map loads.

INSTALL
=======
Yes. :-)

USAGE
=====
Cvar: rememberthefrags_resetseconds (default 0)
Specify for how many seconds after a player leaves the server his stats will be remembered.
Set to 0 and it will never forget the stats. If anything but 0, this will also reset stats when a new map loads.
You can set it to -1, and stats will be remembered forever until a new map loads, ie no resetting after a specific time.

RELEASES
========
2007-01-21    version 0.6:    I  (CTheory) converted this to HLDM (not CS), and removed the "deaths" functionality

2004-05-17    version 0.5:    Changed rememberthefrags_resetonnewmap into rememberthefrags_resetseconds.
2004-05-17    version 0.4:    Added rememberthefrags_resetonnewmap.
2004-05-01    version 0.3:    Fixed for amxx.
                            Fixed setting deaths.
2003-11-25    version 0.2b:    Well long time no sea, and not a lot of working plugin lately because of new stuff with Steam and all.
                            Setting deaths back doesn't seem to work anymore, added to to do list.
2003-07-24    version 0.2:    Now remembers deaths also.
2003-07-23    version 0.1:    First release

TO DO
=====
- ?
*/

#include <amxmodx>
#include <amxmisc>
#include <fun>

// Globals below
new gmsgScoreInfo
new bool:reread = false
new playersFrags[33]
// Globals above


public client_disconnect(id) {
    storeFrags(id)
    
    new seconds = get_cvar_num("rememberthefrags_resetseconds")
    if (seconds > 0) {
        new key[40] = "frags"
        setKeyString(id, key)
        set_task(float(seconds), "resetuserstats", 0, key, strlen(key))

    }
}

public resetuserstats(key[]) {
    //server_print("Will reset this key: ^"%s^"", key)
    if (!vaultdata_exists(key))
        return

    if (!remove_vaultdata(key))
        server_print("[%] Error - Key for %s exists, but couldn't be removed!", PLUGINNAME, key)
}

public client_putinserver(id) {
    // Restore frags n deaths from file.
    new idd[1]
    idd[0] = id
    set_task(1.0,"delayedrestore",0,idd,1)

    return PLUGIN_CONTINUE
}

public delayedrestore(idd[]) {
    restoreVaultData(idd[0])
}

/*
public restoreme(id,level,cid) {
    if (!cmd_access(id,level,cid,1)) {
        return PLUGIN_HANDLED
    }

    restoreVaultData(id)

    return PLUGIN_HANDLED
}
*/

public saveme(id,level,cid) {
    /*
    if (!cmd_access(id,level,cid,1)) {
        return PLUGIN_HANDLED
    }
    */

    storeFrags(id)
    
    return PLUGIN_HANDLED
}

restoreVaultData(id) {
    new keyString[40] = "frags", frags
    setKeyString(id,keyString)

    if (vaultdata_exists(keyString)) {
        frags = get_vaultdata(keyString)
        set_user_frags(id,frags)
    }

    
    if (!frags)
        frags = get_user_frags(id)
    
    // With the below message, we can update the scores shown without having to wait
    // for next round or when id dies/shoots someone or something like that.
    sendScoreInfo(id,frags)
}

sendScoreInfo(id,frags) {
    message_begin(MSG_ALL,gmsgScoreInfo)
    write_byte(id)
    write_short(frags)
    write_short(0)
    message_end()
}

setKeyString(id,keyString[40]) {
    if (is_user_bot(id)) {
        new name[32]
        get_user_name(id,name,31)
        new spaces = charOccurances(name," ")
        for (new i = 0;i < spaces;i++) {
            replace(name,31," ","_")
        }

        copy(keyString[5],34,name)
    }
    else {
        new authidString[32]
        get_user_authid(id, authidString, 31)
        copy(keyString[5], 34, authidString)
    }
}

storeFrags(id) {
    new keyString[40] = "frags"
    setKeyString(id,keyString)
    //client_print(0,print_chat,"fragKeyString after copy is '%s'.",fragKeyString)

    new fragsString[10]
    num_to_str(get_user_frags(id),fragsString,9)

    set_vaultdata(keyString,fragsString)
    //client_print(0,print_chat,"Stored %s to %s.",fragsString,keyString)
}

stock charOccurances(string[],matchchar[]) {
    if (strlen(matchchar) != 1)
        return -1

    new occurances
    new len = strlen(string)
    for (new i = 0;i < len;i++) {
        if (string[i] == matchchar[0]) {
            occurances++
        }
    }

    return occurances
}

/*storeDeaths(id) {
    new keyString[40] = "death"
    setKeyString(id,keyString)
    //client_print(0,print_chat,"keyString after copy is '%s'.",keyString)

    new deathString[10]
    num_to_str(get_user_deaths(id),deathString,9)

    set_vaultdata(keyString,deathString)
    //client_print(0,print_chat,"Stored %s to %s.",deathString,keyString)
}*/


public restarting_event() {
    reread = true

    // Will need to do a quick remembering of current frags here...
    // Restore these values at next newround_event. Only restore
    // if these are larger than the values in the vault. If not,
    // use those larger values.
    new players[32], playersFound
    get_players(players,playersFound)

    for (new i = 0;i < playersFound;i++) 
    
    {
        playersFrags[players[i]] = get_user_frags(players[i])
    }

}

public commencing_event() {
    reread = true

    // Will need to do a quick remembering of current frags here...
    // Restore these values at next newround_event. Only restore
    // if these are larger than the values in the vault. If not,
    // use those larger values.
    new players[32], playersFound
    get_players(players,playersFound)

    for (new i = 0;i < playersFound;i++) {
        playersFrags[players[i]] = get_user_frags(players[i])
    }

}

public instantReread() {
    if (reread) {
        reread = false
        reread_function()
    }
}

stock getVaultFrags(id) {
    new keyString[40] = "frags"
    setKeyString(id,keyString)
    if (vaultdata_exists(keyString)) {
        return get_vaultdata(keyString)
    }
    else {
        return playersFrags[id]
    }

    return 0
}

public reread_function() {
    new players[32], playersFound, keyString[40], vaultFrags, name[32]

    get_players(players,playersFound)

    for (new i = 0;i < playersFound;i++) {
        get_user_name(players[i],name,31)
        keyString = "frags"
        setKeyString(players[i],keyString)

        if (!vaultdata_exists(keyString)) {
            //client_print(0,print_chat,"%s has no previous frags stored, restoring %d from variable.",name,playersFrags[players[i]])
            set_user_frags(players[i],playersFrags[players[i]])

            sendScoreInfo(players[i],playersFrags[players[i]])
        }
        else {
            // Compare values, set the biggest one.
            vaultFrags = get_vaultdata(keyString)
            if (vaultFrags >= playersFrags[players[i]]) {
                set_user_frags(players[i],vaultFrags)

                sendScoreInfo(players[i],vaultFrags)
                //client_print(0,print_chat,"%s has larger value in variable, %d to %d.",name,vaultFrags,playersFrags[players[i]])
            }
            else {
                set_user_frags(players[i],playersFrags[players[i]])

                sendScoreInfo(players[i],playersFrags[players[i]])
                //client_print(0,print_chat,"%s has larger value in vault, %d to %d.",name,playersFrags[players[i]],vaultFrags)
            }
        }
    }
}

/*
public setdatafromstats(id,level,cid) {
    if (!cmd_access(id,level,cid,1)) {
        return PLUGIN_HANDLED
    }
    new stats[8], bodyHits[8]
    get_user_wstats(id,0,stats,bodyHits)
    set_user_frags(id,stats[0])
    set_user_deaths_cs(id,stats[1])
    console_print(id,"0:%d, 1:%d, 2:%d, 3:%d, 4:%d, 5:%d, 6:%d, 7:%d",stats[0],stats[1],stats[2],stats[3],stats[4],stats[5],stats[6],stats[7])
    sendScoreInfo(id,stats[0],stats[1],get_user_team(id))

    return PLUGIN_HANDLED
}
*/

resetstats() {
    new vaultpath[128]
    get_localinfo("amxx_vault", vaultpath, sizeof vaultpath - 1)
    if (!file_exists(vaultpath))
        return

    new line, textline[128], linelength
    new const LEN = sizeof textline - 1
    new key[64]
    new const KEYLEN = sizeof key - 1
    new bool:removed, keysremoved = 0
    do {
        removed = false
        line = 0
        while ((line = read_file(vaultpath, line, textline, LEN, linelength))) {
            if (linelength > 5 && equal(textline, "frags", 5) || equal(textline, "death", 5))
                //server_print("Line: %d, text: %s", line, textline)
                if (parse(textline, key, KEYLEN)) {
                    //server_print("Key: %s", key)
                    if (!remove_vaultdata(key))
                        server_print("[%s] Couldn't remove stats key: %s", key)
                    else {
                        removed = true
                        keysremoved++
                    }
                }
                else {
                    //server_print("Couldn't parse: %s", textline)
                }
        }
    }
    while (removed)

    server_print("[%s] Removed %d stats keys from vault.", PLUGINNAME, keysremoved)
}

public plugin_init() {
    register_plugin(PLUGINNAME, VERSION, AUTHOR)
    //register_clcmd("0restorevault","restoreme",ADMIN_CFG,": restores your frags from vault.")
    //register_clcmd("0restorestats","setdatafromstats",ADMIN_CFG,": restores your frags from stats.")
    //register_clcmd("amx_storefrags","saveme",0,"- stores your frags and deaths.")
    register_event("TextMsg","commencing_event","a","2=#Game_Commencing")
    register_event("TextMsg","restarting_event","a","2=#Game_will_restart_in")
    //register_event("ResetHUD","newround_event","b")
    register_event("SendAudio","instantReread","b","2=%!MRAD_GO","2=%!MRAD_MOVEOUT","2=%!MRAD_LETSGO","2=%!MRAD_LOCKNLOAD")
    gmsgScoreInfo = get_user_msgid("ScoreInfo")

    register_cvar("rememberthefrags_resetseconds", "0")

    if (get_cvar_num("rememberthefrags_resetseconds"))
        resetstats()
}
Thanks Johnny got his gun for the original code to mess with.

and thank you for responding stupok hopefully we can work this out.

Last edited by CornetTheory; 01-23-2007 at 09:12.
CornetTheory is offline
kmal2t
BANNED
Join Date: Apr 2006
Old 01-25-2007 , 19:13   Re: Descent 3 style scoreboard
Reply With Quote #9

so is there a way to put this on the +showscores menu??? Or at least "trick it" into looking like its on it??
kmal2t is offline
kmal2t
BANNED
Join Date: Apr 2006
Old 01-27-2007 , 14:39   Re: Descent 3 style scoreboard
Reply With Quote #10

Stupok you never replied about how you would change the scoreboard w/o using cs_set_user_deaths
kmal2t 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 15:12.


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