zombies_score.lsl
///////////////////////////////////////////////////////////////////////////
//  Copyright (C) Wizardry and Steamworks 2011 - License: GNU GPLv3      //
//  Please see: http://www.gnu.org/licenses/gpl.html for legal details,  //
//  rights of fair usage, the disclaimer and warranty conditions.        //
///////////////////////////////////////////////////////////////////////////
 
list scores = [];
list names = [];
 
///////////////////////////////////////////////////////////////////////////
//    Copyright (C) 2013 Wizardry and Steamworks - License: GNU GPLv3    //
///////////////////////////////////////////////////////////////////////////
list wasDualQuicksort(list a, list b) {
    if(llGetListLength(a) <= 1) return a+b;
 
    integer pivot_a = llList2Integer(a, 0);
    a = llDeleteSubList(a, 0, 0);
    string pivot_b = llList2String(b, 0);
    b = llDeleteSubList(b, 0, 0);
 
    list less = [];
    list less_b = [];
    list more = [];
    list more_b = [];
 
    do {
        if(llList2Integer(a, 0) > pivot_a) {
            less += llList2List(a, 0, 0);
            less_b += llList2List(b, 0, 0);
            jump continue;
        }
        more += llList2List(a, 0, 0);
        more_b += llList2List(b, 0, 0);
@continue;
        a = llDeleteSubList(a, 0, 0);
        b = llDeleteSubList(b, 0, 0);
    } while(llGetListLength(a));
    return wasDualQuicksort(less, less_b) + [ pivot_a ] + [ pivot_b ] + wasDualQuicksort(more, more_b);
}
 
default
{
    state_entry()
    {
        llSetText("◎ Top ◎ \nKill more zombies!", <1,1,0>, 1);
        integer comChannel = ((integer)("0x"+llGetSubString((string)llGetOwner(),-8,-1)) & 0x3FFFFFFF) ^ 0xBFFFFFFF;
        llListen(comChannel, "[K] Zombie", "", "");
    }
    listen(integer channel, string name, key id, string message) {
        key obj = llList2Key(llGetObjectDetails(id, [OBJECT_OWNER]), 0);
        if(obj != llGetOwner()) return;
        list data = llParseString2List(message, [":"], [""]);
        if(llList2String(data, 0) != "kzb") return;
        name = llList2String(data, 1);
        if(name == "") return;
        if(!~llListFindList(names, (list)name)) {
            names = llListInsertList(names, (list)name, 0);
            scores = llListInsertList(scores, (list)1, 0);
            jump compute;
        }
        integer idx = llListFindList(names, (list)name);
        integer score = llList2Integer(scores, idx)+1;
        scores=llListReplaceList(scores, (list)score, idx, idx);
@compute;
        list sort = wasDualQuicksort(scores, names);
        string display = "";
        integer count = 0;
        do {
            display += llList2String(sort, 1);
            display += " -> ";
            display += llList2String(sort, 0);
            display += "\n";
            sort = llDeleteSubList(sort, 0, 0);
            sort = llDeleteSubList(sort, 0, 0);
            if(++count==5) jump show;
        } while(llGetListLength(sort));
@show;
        llSetText("◎ Top ◎ \n" + display, <1,1,0>, 1);
    }
    on_rez(integer num) {
        llResetScript();
    }
}