Files
CHOMPStation2/code/__HELPERS/lists.dm
giacomand@gmail.com 7955d348d8 Lots of bugs fixed for advance diseases.
Fixed advance diseases using the same reference in mobs.
Fixed advance diseases referencing other advance diseases' symptoms, instead of just copying it.

I tested it more thoroughly this time and I can't find any issues but if you do please add them to the bug tracker and or contact me on #coderbus.

Added a new reaction which will remove symptoms from a disease. Needs blood and synaptizine.
Added a new symptom, shivering will make you cold.

Tweaked and balanced some symptoms.

Removed the "flex" emote that hulks will do randomly.
Reduced the change to speak for hulks and brain damaged mobs. ( 7% -> 3% chance)

Please let me know if anything is out of place or wrong.

git-svn-id: http://tgstation13.googlecode.com/svn/trunk@5048 316c924e-a436-60f5-8080-3fe189b3f50e
2012-11-13 00:28:07 +00:00

307 lines
7.8 KiB
Plaintext

/*
* Holds procs to help with list operations
* Contains groups:
* Misc
* Sorting
*/
/*
* Misc
*/
//Returns a list in plain english as a string
/proc/english_list(var/list/input, nothing_text = "nothing", and_text = " and ", comma_text = ", ", final_comma_text = "," )
var/total = input.len
if (!total)
return "[nothing_text]"
else if (total == 1)
return "[input[1]]"
else if (total == 2)
return "[input[1]][and_text][input[2]]"
else
var/output = ""
var/index = 1
while (index < total)
if (index == total - 1)
comma_text = final_comma_text
output += "[input[index]][comma_text]"
index++
return "[output][and_text][input[index]]"
//Returns list element or null. Should prevent "index out of bounds" error.
proc/listgetindex(var/list/list,index)
if(istype(list) && list.len)
if(isnum(index))
if(InRange(index,1,list.len))
return list[index]
else if(index in list)
return list[index]
return
proc/islist(list/list)
if(istype(list))
return 1
return 0
//Return either pick(list) or null if list is not of type /list or is empty
proc/safepick(list/list)
if(!islist(list) || !list.len)
return
return pick(list)
//Checks if the list is empty
proc/isemptylist(list/list)
if(!list.len)
return 1
return 0
//Checks for specific types in a list
/proc/is_type_in_list(var/atom/A, var/list/L)
for(var/type in L)
if(istype(A, type))
return 1
return 0
//Empties the list by setting the length to 0. Hopefully the elements get garbage collected
proc/clearlist(list/list)
if(istype(list))
list.len = 0
return
//Removes any null entries from the list
proc/listclearnulls(list/list)
if(istype(list))
while(null in list)
list -= null
return
/*
* Returns list containing all the entries from first list that are not present in second.
* If skiprep = 1, repeated elements are treated as one.
* If either of arguments is not a list, returns null
*/
/proc/difflist(var/list/first, var/list/second, var/skiprep=0)
if(!islist(first) || !islist(second))
return
var/list/result = new
if(skiprep)
for(var/e in first)
if(!(e in result) && !(e in second))
result += e
else
result = first - second
return result
/*
* Returns list containing entries that are in either list but not both.
* If skipref = 1, repeated elements are treated as one.
* If either of arguments is not a list, returns null
*/
/proc/uniquemergelist(var/list/first, var/list/second, var/skiprep=0)
if(!islist(first) || !islist(second))
return
var/list/result = new
if(skiprep)
result = difflist(first, second, skiprep)+difflist(second, first, skiprep)
else
result = first ^ second
return result
//Pretends to pick an element based on its weight but really just seems to pick a random element.
/proc/pickweight(list/L)
var/total = 0
var/item
for (item in L)
if (!L[item])
L[item] = 1
total += L[item]
total = rand(1, total)
for (item in L)
total -=L [item]
if (total <= 0)
return item
return null
//Pick a random element from the list and remove it from the list.
/proc/pick_n_take(list/listfrom)
if (listfrom.len > 0)
var/picked = pick(listfrom)
listfrom -= picked
return picked
return null
//Returns the top(last) element from the list and removes it from the list (typical stack function)
/proc/pop(list/listfrom)
if (listfrom.len > 0)
var/picked = listfrom[listfrom.len]
listfrom.len--
return picked
return null
/*
* Sorting
*/
//Reverses the order of items in the list (Turning a stack into a queue)
/proc/reverselist(var/list/input)
var/list/output = new/list()
for(var/A in input)
output += A
return output
//Randomize: Return the list in a random order
/proc/shuffle(var/list/shufflelist)
if(!shufflelist)
return
var/list/new_list = list()
var/list/old_list = shufflelist.Copy()
while(old_list.len)
var/item = pick(old_list)
new_list += item
old_list -= item
return new_list
//Return a list with no duplicate entries
/proc/uniquelist(var/list/L)
var/list/K = list()
for(var/item in L)
if(!(item in K))
K += item
return K
//Mergesort: divides up the list into halves to begin the sort
/proc/sortKey(var/list/client/L, var/order = 1)
if(isnull(L) || L.len < 2)
return L
var/middle = L.len / 2 + 1
return mergeKey(sortKey(L.Copy(0,middle)), sortKey(L.Copy(middle)), order)
//Mergsort: does the actual sorting and returns the results back to sortAtom
/proc/mergeKey(var/list/client/L, var/list/client/R, var/order = 1)
var/Li=1
var/Ri=1
var/list/result = new()
while(Li <= L.len && Ri <= R.len)
var/client/rL = L[Li]
var/client/rR = R[Ri]
if(sorttext(rL.ckey, rR.ckey) == order)
result += L[Li++]
else
result += R[Ri++]
if(Li <= L.len)
return (result + L.Copy(Li, 0))
return (result + R.Copy(Ri, 0))
//Mergesort: divides up the list into halves to begin the sort
/proc/sortAtom(var/list/atom/L, var/order = 1)
if(isnull(L) || L.len < 2)
return L
var/middle = L.len / 2 + 1
return mergeAtoms(sortAtom(L.Copy(0,middle)), sortAtom(L.Copy(middle)), order)
//Mergsort: does the actual sorting and returns the results back to sortAtom
/proc/mergeAtoms(var/list/atom/L, var/list/atom/R, var/order = 1)
var/Li=1
var/Ri=1
var/list/result = new()
while(Li <= L.len && Ri <= R.len)
var/atom/rL = L[Li]
var/atom/rR = R[Ri]
if(sorttext(rL.name, rR.name) == order)
result += L[Li++]
else
result += R[Ri++]
if(Li <= L.len)
return (result + L.Copy(Li, 0))
return (result + R.Copy(Ri, 0))
//Mergesort: Specifically for record datums in a list.
/proc/sortRecord(var/list/datum/data/record/L, var/field = "name", var/order = 1)
if(isnull(L))
return list()
if(L.len < 2)
return L
var/middle = L.len / 2 + 1
return mergeRecordLists(sortRecord(L.Copy(0, middle), field, order), sortRecord(L.Copy(middle), field, order), field, order)
//Mergsort: does the actual sorting and returns the results back to sortRecord
/proc/mergeRecordLists(var/list/datum/data/record/L, var/list/datum/data/record/R, var/field = "name", var/order = 1)
var/Li=1
var/Ri=1
var/list/result = new()
if(!isnull(L) && !isnull(R))
while(Li <= L.len && Ri <= R.len)
var/datum/data/record/rL = L[Li]
if(isnull(rL))
L -= rL
continue
var/datum/data/record/rR = R[Ri]
if(isnull(rR))
R -= rR
continue
if(sorttext(rL.fields[field], rR.fields[field]) == order)
result += L[Li++]
else
result += R[Ri++]
if(Li <= L.len)
return (result + L.Copy(Li, 0))
return (result + R.Copy(Ri, 0))
//Mergesort: any value in a list
/proc/sortList(var/list/L)
if(L.len < 2)
return L
var/middle = L.len / 2 + 1 // Copy is first,second-1
return mergeLists(sortList(L.Copy(0,middle)), sortList(L.Copy(middle))) //second parameter null = to end of list
//Mergsorge: uses sortList() but uses the var's name specifically. This should probably be using mergeAtom() instead
/proc/sortNames(var/list/L)
var/list/Q = new()
for(var/atom/x in L)
Q[x.name] = x
return sortList(Q)
/proc/mergeLists(var/list/L, var/list/R)
var/Li=1
var/Ri=1
var/list/result = new()
while(Li <= L.len && Ri <= R.len)
if(sorttext(L[Li], R[Ri]) < 1)
result += R[Ri++]
else
result += L[Li++]
if(Li <= L.len)
return (result + L.Copy(Li, 0))
return (result + R.Copy(Ri, 0))
//Converts a bitfield to a list of numbers (or words if a wordlist is provided)
/proc/bitfield2list(bitfield = 0, list/wordlist)
var/list/r = list()
if(istype(wordlist,/list))
var/max = min(wordlist.len,16)
var/bit = 1
for(var/i=1, i<=max, i++)
if(bitfield & bit)
r += wordlist[i]
bit = bit << 1
else
for(var/bit=1, bit<=65535, bit = bit << 1)
if(bitfield & bit)
r += bit
return r