The scoreboard contains two mapped lists that keep track of the scores. The script listens to all primitives called [WaS-K] Explosive Puppy
in order to filter out other messages. Additionally, to prevent cheating, the owner of the puppy object is checked at run-time.
The script is placed inside an invisible primitive at the top of the torch that contains the rezzing coordinates for the puppies in the description.
/////////////////////////////////////////////////////////////////////////// // Copyright (C) Wizardry and Steamworks 2012 - 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 killers = []; list scores = []; /////////////////////////////////////////////////////////////////////////// // 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 Killas ◎", <1,.6,.8>, 1); integer comChannel = ((integer)("0x"+llGetSubString((string)llGetOwner(),-8,-1)) & 0x3FFFFFFF) ^ 0xBFFFFFFF; llListen(comChannel, "[WaS-K] Explosive Puppy", "", ""); //llRegionSay(comChannel, "puppeh_death=" + (string)killer); } 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) != "puppeh_death") return; string killer = llKey2Name(llList2Key(data, 1)); string fName = llList2String(llParseString2List(killer, [" "], []), 0); if(llList2String(llParseString2List(killer, [" "], []), 1) == "Resident") { killer = fName; } integer idx = llListFindList(killers, (list)killer); if(idx == -1) { killers += killer; scores += 1; jump display; } integer score = llList2Integer(scores, idx); scores = llListReplaceList(scores, (list)(score+1), idx, idx); @display; llSetTimerEvent(1); } timer() { list sort = wasDualQuicksort(scores, killers); 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 Killas ◎ \n" + display, <1,.6,.8>, 1); llSetTimerEvent(0); } touch_start(integer total_number) { vector iPos = ZERO_VECTOR; list dVec = llParseString2List(llGetObjectDesc(), ["<", ",", ">"], []); iPos.x = llList2Float(dVec, 0); iPos.y = llList2Float(dVec, 1); iPos.z = llList2Float(dVec, 2); llRezObject("[WaS-K] Explosive Puppy", iPos, ZERO_VECTOR, ZERO_ROTATION, 0); } on_rez(integer num) { llResetScript(); } }