mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2025-12-11 10:43:20 +00:00
Conflict Resolution
This one made a lynx cry.
This commit is contained in:
@@ -40,33 +40,6 @@
|
||||
|
||||
#define ACCESSORY_SLOT_TORSO (ACCESSORY_SLOT_UTILITY|ACCESSORY_SLOT_WEAPON)
|
||||
|
||||
<<<<<<< HEAD
|
||||
// Flags bitmasks. - Used in /atom/var/flags
|
||||
#define NOBLUDGEON 0x1 // When an item has this it produces no "X has been hit by Y with Z" message with the default handler.
|
||||
#define CONDUCT 0x2 // Conducts electricity. (metal etc.)
|
||||
#define ON_BORDER 0x4 // Item has priority to check when entering or leaving.
|
||||
#define NOBLOODY 0x8 // Used for items if they don't want to get a blood overlay.
|
||||
#define OPENCONTAINER 0x10 // Is an open container for chemistry purposes.
|
||||
#define PHORONGUARD 0x20 // Does not get contaminated by phoron.
|
||||
#define NOREACT 0x40 // Reagents don't react inside this container.
|
||||
#define PROXMOVE 0x80 // Does this object require proximity checking in Enter()?
|
||||
#define OVERLAY_QUEUED 0x100 // Atom queued to SSoverlay for COMPILE_OVERLAYS
|
||||
|
||||
//Flags for items (equipment) - Used in /obj/item/var/item_flags
|
||||
#define THICKMATERIAL 0x1 // Prevents syringes, parapens and hyposprays if equipped to slot_suit or slot_head.
|
||||
#define AIRTIGHT 0x2 // Functions with internals.
|
||||
#define NOSLIP 0x4 // Prevents from slipping on wet floors, in space, etc.
|
||||
#define BLOCK_GAS_SMOKE_EFFECT 0x8 // Blocks the effect that chemical clouds would have on a mob -- glasses, mask and helmets ONLY! (NOTE: flag shared with ONESIZEFITSALL)
|
||||
#define FLEXIBLEMATERIAL 0x10 // At the moment, masks with this flag will not prevent eating even if they are covering your face.
|
||||
|
||||
// Flags for pass_flags. - Used in /atom/var/pass_flags
|
||||
#define PASSTABLE 0x1
|
||||
#define PASSGLASS 0x2
|
||||
#define PASSGRILLE 0x4
|
||||
#define PASSBLOB 0x8
|
||||
|
||||
=======
|
||||
>>>>>>> 9ff8103... Merge pull request #5636 from kevinz000/pixel_projectiles
|
||||
// Bitmasks for the /obj/item/var/flags_inv variable. These determine when a piece of clothing hides another, i.e. a helmet hiding glasses.
|
||||
// WARNING: The following flags apply only to the external suit!
|
||||
#define HIDEGLOVES 0x1
|
||||
|
||||
@@ -1,760 +1,3 @@
|
||||
<<<<<<< HEAD:code/_helpers/lists.dm
|
||||
/*
|
||||
* 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 = "" )
|
||||
switch(input.len)
|
||||
if(0) return nothing_text
|
||||
if(1) return "[input[1]]"
|
||||
if(2) return "[input[1]][and_text][input[2]]"
|
||||
else return "[jointext(input, comma_text, 1, -1)][final_comma_text][and_text][input[input.len]]"
|
||||
|
||||
//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)
|
||||
return(istype(list))
|
||||
|
||||
//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
|
||||
|
||||
//Checks for specific paths in a list
|
||||
/proc/is_path_in_list(var/atom/A, var/list/L)
|
||||
for(var/path in L)
|
||||
if(ispath(A, path))
|
||||
return 1
|
||||
return 0
|
||||
|
||||
//////////////////////////////////////////////////////
|
||||
// "typecache" utilities - Making and searching them
|
||||
//////////////////////////////////////////////////////
|
||||
|
||||
//Checks for specific types in specifically structured (Assoc "type" = TRUE) lists ('typecaches')
|
||||
/proc/is_type_in_typecache(atom/A, list/L)
|
||||
if(!LAZYLEN(L) || !A)
|
||||
return FALSE
|
||||
return L[A.type]
|
||||
|
||||
//returns a new list with only atoms that are in typecache L
|
||||
/proc/typecache_filter_list(list/atoms, list/typecache)
|
||||
. = list()
|
||||
for(var/thing in atoms)
|
||||
var/atom/A = thing
|
||||
if(typecache[A.type])
|
||||
. += A
|
||||
|
||||
/proc/typecache_filter_list_reverse(list/atoms, list/typecache)
|
||||
. = list()
|
||||
for(var/thing in atoms)
|
||||
var/atom/A = thing
|
||||
if(!typecache[A.type])
|
||||
. += A
|
||||
|
||||
/proc/typecache_filter_multi_list_exclusion(list/atoms, list/typecache_include, list/typecache_exclude)
|
||||
. = list()
|
||||
for(var/thing in atoms)
|
||||
var/atom/A = thing
|
||||
if(typecache_include[A.type] && !typecache_exclude[A.type])
|
||||
. += A
|
||||
|
||||
//Like typesof() or subtypesof(), but returns a typecache instead of a list
|
||||
/proc/typecacheof(path, ignore_root_path, only_root_path = FALSE)
|
||||
if(ispath(path))
|
||||
var/list/types = list()
|
||||
if(only_root_path)
|
||||
types = list(path)
|
||||
else
|
||||
types = ignore_root_path ? subtypesof(path) : typesof(path)
|
||||
var/list/L = list()
|
||||
for(var/T in types)
|
||||
L[T] = TRUE
|
||||
return L
|
||||
else if(islist(path))
|
||||
var/list/pathlist = path
|
||||
var/list/L = list()
|
||||
if(ignore_root_path)
|
||||
for(var/P in pathlist)
|
||||
for(var/T in subtypesof(P))
|
||||
L[T] = TRUE
|
||||
else
|
||||
for(var/P in pathlist)
|
||||
if(only_root_path)
|
||||
L[P] = TRUE
|
||||
else
|
||||
for(var/T in typesof(P))
|
||||
L[T] = TRUE
|
||||
return L
|
||||
|
||||
//////////////////////////////////////////////////////
|
||||
|
||||
//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
|
||||
|
||||
//Returns the next element in parameter list after first appearance of parameter element. If it is the last element of the list or not present in list, returns first element.
|
||||
/proc/next_in_list(element, list/L)
|
||||
for(var/i=1, i<L.len, i++)
|
||||
if(L[i] == element)
|
||||
return L[i+1]
|
||||
return L[1]
|
||||
|
||||
/*
|
||||
* Sorting
|
||||
*/
|
||||
|
||||
//Reverses the order of items in the list
|
||||
/proc/reverselist(list/L)
|
||||
var/list/output = list()
|
||||
if(L)
|
||||
for(var/i = L.len; i >= 1; i--)
|
||||
output += L[i]
|
||||
return output
|
||||
|
||||
//Randomize: Return the list in a random order
|
||||
/proc/shuffle(var/list/L)
|
||||
if(!L)
|
||||
return
|
||||
|
||||
L = L.Copy()
|
||||
|
||||
for(var/i=1; i<L.len; i++)
|
||||
L.Swap(i, rand(i,L.len))
|
||||
return L
|
||||
|
||||
//same, but returns nothing and acts on list in place
|
||||
/proc/shuffle_inplace(list/L)
|
||||
if(!L)
|
||||
return
|
||||
|
||||
for(var/i=1, i<L.len, ++i)
|
||||
L.Swap(i,rand(i,L.len))
|
||||
|
||||
//Return a list with no duplicate entries
|
||||
/proc/uniquelist(var/list/L)
|
||||
. = list()
|
||||
for(var/i in L)
|
||||
. |= i
|
||||
|
||||
//same, but returns nothing and acts on list in place (also handles associated values properly)
|
||||
/proc/uniqueList_inplace(list/L)
|
||||
var/temp = L.Copy()
|
||||
L.len = 0
|
||||
for(var/key in temp)
|
||||
if (isnum(key))
|
||||
L |= key
|
||||
else
|
||||
L[key] = temp[key]
|
||||
|
||||
|
||||
//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))
|
||||
|
||||
|
||||
// List of lists, sorts by element[key] - for things like crew monitoring computer sorting records by name.
|
||||
/proc/sortByKey(var/list/L, var/key)
|
||||
if(L.len < 2)
|
||||
return L
|
||||
var/middle = L.len / 2 + 1
|
||||
return mergeKeyedLists(sortByKey(L.Copy(0, middle), key), sortByKey(L.Copy(middle), key), key)
|
||||
|
||||
/proc/mergeKeyedLists(var/list/L, var/list/R, var/key)
|
||||
var/Li=1
|
||||
var/Ri=1
|
||||
var/list/result = new()
|
||||
while(Li <= L.len && Ri <= R.len)
|
||||
if(sorttext(L[Li][key], R[Ri][key]) < 1)
|
||||
// Works around list += list2 merging lists; it's not pretty but it works
|
||||
result += "temp item"
|
||||
result[result.len] = R[Ri++]
|
||||
else
|
||||
result += "temp item"
|
||||
result[result.len] = L[Li++]
|
||||
|
||||
if(Li <= L.len)
|
||||
return (result + L.Copy(Li, 0))
|
||||
return (result + R.Copy(Ri, 0))
|
||||
|
||||
|
||||
//Mergesort: any value in a list, preserves key=value structure
|
||||
/proc/sortAssoc(var/list/L)
|
||||
if(L.len < 2)
|
||||
return L
|
||||
var/middle = L.len / 2 + 1 // Copy is first,second-1
|
||||
return mergeAssoc(sortAssoc(L.Copy(0,middle)), sortAssoc(L.Copy(middle))) //second parameter null = to end of list
|
||||
|
||||
/proc/mergeAssoc(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&R[Ri++]
|
||||
else
|
||||
result += L&L[Li++]
|
||||
|
||||
if(Li <= L.len)
|
||||
return (result + L.Copy(Li, 0))
|
||||
return (result + R.Copy(Ri, 0))
|
||||
|
||||
// Macros to test for bits in a bitfield. Note, that this is for use with indexes, not bit-masks!
|
||||
#define BITTEST(bitfield,index) ((bitfield) & (1 << (index)))
|
||||
#define BITSET(bitfield,index) (bitfield) |= (1 << (index))
|
||||
#define BITRESET(bitfield,index) (bitfield) &= ~(1 << (index))
|
||||
#define BITFLIP(bitfield,index) (bitfield) ^= (1 << (index))
|
||||
|
||||
//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
|
||||
|
||||
// Returns the key based on the index
|
||||
/proc/get_key_by_index(var/list/L, var/index)
|
||||
var/i = 1
|
||||
for(var/key in L)
|
||||
if(index == i)
|
||||
return key
|
||||
i++
|
||||
return null
|
||||
|
||||
// Returns the key based on the index
|
||||
/proc/get_key_by_value(var/list/L, var/value)
|
||||
for(var/key in L)
|
||||
if(L[key] == value)
|
||||
return key
|
||||
|
||||
/proc/count_by_type(var/list/L, type)
|
||||
var/i = 0
|
||||
for(var/T in L)
|
||||
if(istype(T, type))
|
||||
i++
|
||||
return i
|
||||
|
||||
//Don't use this on lists larger than half a dozen or so
|
||||
/proc/insertion_sort_numeric_list_ascending(var/list/L)
|
||||
//world.log << "ascending len input: [L.len]"
|
||||
var/list/out = list(pop(L))
|
||||
for(var/entry in L)
|
||||
if(isnum(entry))
|
||||
var/success = 0
|
||||
for(var/i=1, i<=out.len, i++)
|
||||
if(entry <= out[i])
|
||||
success = 1
|
||||
out.Insert(i, entry)
|
||||
break
|
||||
if(!success)
|
||||
out.Add(entry)
|
||||
|
||||
//world.log << " output: [out.len]"
|
||||
return out
|
||||
|
||||
/proc/insertion_sort_numeric_list_descending(var/list/L)
|
||||
//world.log << "descending len input: [L.len]"
|
||||
var/list/out = insertion_sort_numeric_list_ascending(L)
|
||||
//world.log << " output: [out.len]"
|
||||
return reverselist(out)
|
||||
|
||||
/proc/dd_sortedObjectList(var/list/L, var/cache=list())
|
||||
if(L.len < 2)
|
||||
return L
|
||||
var/middle = L.len / 2 + 1 // Copy is first,second-1
|
||||
return dd_mergeObjectList(dd_sortedObjectList(L.Copy(0,middle), cache), dd_sortedObjectList(L.Copy(middle), cache), cache) //second parameter null = to end of list
|
||||
|
||||
/proc/dd_mergeObjectList(var/list/L, var/list/R, var/list/cache)
|
||||
var/Li=1
|
||||
var/Ri=1
|
||||
var/list/result = new()
|
||||
while(Li <= L.len && Ri <= R.len)
|
||||
var/LLi = L[Li]
|
||||
var/RRi = R[Ri]
|
||||
var/LLiV = cache[LLi]
|
||||
var/RRiV = cache[RRi]
|
||||
if(!LLiV)
|
||||
LLiV = LLi:dd_SortValue()
|
||||
cache[LLi] = LLiV
|
||||
if(!RRiV)
|
||||
RRiV = RRi:dd_SortValue()
|
||||
cache[RRi] = RRiV
|
||||
if(LLiV < RRiV)
|
||||
result += L[Li++]
|
||||
else
|
||||
result += R[Ri++]
|
||||
|
||||
if(Li <= L.len)
|
||||
return (result + L.Copy(Li, 0))
|
||||
return (result + R.Copy(Ri, 0))
|
||||
|
||||
// Insert an object into a sorted list, preserving sortedness
|
||||
/proc/dd_insertObjectList(var/list/L, var/O)
|
||||
var/min = 1
|
||||
var/max = L.len
|
||||
var/Oval = O:dd_SortValue()
|
||||
|
||||
while(1)
|
||||
var/mid = min+round((max-min)/2)
|
||||
|
||||
if(mid == max)
|
||||
L.Insert(mid, O)
|
||||
return
|
||||
|
||||
var/Lmid = L[mid]
|
||||
var/midval = Lmid:dd_SortValue()
|
||||
if(Oval == midval)
|
||||
L.Insert(mid, O)
|
||||
return
|
||||
else if(Oval < midval)
|
||||
max = mid
|
||||
else
|
||||
min = mid+1
|
||||
|
||||
/*
|
||||
proc/dd_sortedObjectList(list/incoming)
|
||||
/*
|
||||
Use binary search to order by dd_SortValue().
|
||||
This works by going to the half-point of the list, seeing if the node in
|
||||
question is higher or lower cost, then going halfway up or down the list
|
||||
and checking again. This is a very fast way to sort an item into a list.
|
||||
*/
|
||||
var/list/sorted_list = new()
|
||||
var/low_index
|
||||
var/high_index
|
||||
var/insert_index
|
||||
var/midway_calc
|
||||
var/current_index
|
||||
var/current_item
|
||||
var/current_item_value
|
||||
var/current_sort_object_value
|
||||
var/list/list_bottom
|
||||
|
||||
var/current_sort_object
|
||||
for (current_sort_object in incoming)
|
||||
low_index = 1
|
||||
high_index = sorted_list.len
|
||||
while (low_index <= high_index)
|
||||
// Figure out the midpoint, rounding up for fractions. (BYOND rounds down, so add 1 if necessary.)
|
||||
midway_calc = (low_index + high_index) / 2
|
||||
current_index = round(midway_calc)
|
||||
if (midway_calc > current_index)
|
||||
current_index++
|
||||
current_item = sorted_list[current_index]
|
||||
|
||||
current_item_value = current_item:dd_SortValue()
|
||||
current_sort_object_value = current_sort_object:dd_SortValue()
|
||||
if (current_sort_object_value < current_item_value)
|
||||
high_index = current_index - 1
|
||||
else if (current_sort_object_value > current_item_value)
|
||||
low_index = current_index + 1
|
||||
else
|
||||
// current_sort_object == current_item
|
||||
low_index = current_index
|
||||
break
|
||||
|
||||
// Insert before low_index.
|
||||
insert_index = low_index
|
||||
|
||||
// Special case adding to end of list.
|
||||
if (insert_index > sorted_list.len)
|
||||
sorted_list += current_sort_object
|
||||
continue
|
||||
|
||||
// Because BYOND lists don't support insert, have to do it by:
|
||||
// 1) taking out bottom of list, 2) adding item, 3) putting back bottom of list.
|
||||
list_bottom = sorted_list.Copy(insert_index)
|
||||
sorted_list.Cut(insert_index)
|
||||
sorted_list += current_sort_object
|
||||
sorted_list += list_bottom
|
||||
return sorted_list
|
||||
*/
|
||||
|
||||
proc/dd_sortedtextlist(list/incoming, case_sensitive = 0)
|
||||
// Returns a new list with the text values sorted.
|
||||
// Use binary search to order by sortValue.
|
||||
// This works by going to the half-point of the list, seeing if the node in question is higher or lower cost,
|
||||
// then going halfway up or down the list and checking again.
|
||||
// This is a very fast way to sort an item into a list.
|
||||
var/list/sorted_text = new()
|
||||
var/low_index
|
||||
var/high_index
|
||||
var/insert_index
|
||||
var/midway_calc
|
||||
var/current_index
|
||||
var/current_item
|
||||
var/list/list_bottom
|
||||
var/sort_result
|
||||
|
||||
var/current_sort_text
|
||||
for (current_sort_text in incoming)
|
||||
low_index = 1
|
||||
high_index = sorted_text.len
|
||||
while (low_index <= high_index)
|
||||
// Figure out the midpoint, rounding up for fractions. (BYOND rounds down, so add 1 if necessary.)
|
||||
midway_calc = (low_index + high_index) / 2
|
||||
current_index = round(midway_calc)
|
||||
if (midway_calc > current_index)
|
||||
current_index++
|
||||
current_item = sorted_text[current_index]
|
||||
|
||||
if (case_sensitive)
|
||||
sort_result = sorttextEx(current_sort_text, current_item)
|
||||
else
|
||||
sort_result = sorttext(current_sort_text, current_item)
|
||||
|
||||
switch(sort_result)
|
||||
if (1)
|
||||
high_index = current_index - 1 // current_sort_text < current_item
|
||||
if (-1)
|
||||
low_index = current_index + 1 // current_sort_text > current_item
|
||||
if (0)
|
||||
low_index = current_index // current_sort_text == current_item
|
||||
break
|
||||
|
||||
// Insert before low_index.
|
||||
insert_index = low_index
|
||||
|
||||
// Special case adding to end of list.
|
||||
if (insert_index > sorted_text.len)
|
||||
sorted_text += current_sort_text
|
||||
continue
|
||||
|
||||
// Because BYOND lists don't support insert, have to do it by:
|
||||
// 1) taking out bottom of list, 2) adding item, 3) putting back bottom of list.
|
||||
list_bottom = sorted_text.Copy(insert_index)
|
||||
sorted_text.Cut(insert_index)
|
||||
sorted_text += current_sort_text
|
||||
sorted_text += list_bottom
|
||||
return sorted_text
|
||||
|
||||
|
||||
proc/dd_sortedTextList(list/incoming)
|
||||
var/case_sensitive = 1
|
||||
return dd_sortedtextlist(incoming, case_sensitive)
|
||||
|
||||
|
||||
/datum/proc/dd_SortValue()
|
||||
return "[src]"
|
||||
|
||||
/obj/machinery/dd_SortValue()
|
||||
return "[sanitize_old(name)]"
|
||||
|
||||
/obj/machinery/camera/dd_SortValue()
|
||||
return "[c_tag]"
|
||||
|
||||
/datum/alarm/dd_SortValue()
|
||||
return "[sanitize_old(last_name)]"
|
||||
|
||||
/proc/subtypesof(prototype)
|
||||
return (typesof(prototype) - prototype)
|
||||
|
||||
//creates every subtype of prototype (excluding prototype) and adds it to list L.
|
||||
//if no list/L is provided, one is created.
|
||||
/proc/init_subtypes(prototype, list/L)
|
||||
if(!istype(L)) L = list()
|
||||
for(var/path in subtypesof(prototype))
|
||||
L += new path()
|
||||
return L
|
||||
|
||||
//creates every subtype of prototype (excluding prototype) and adds it to list L as a type/instance pair.
|
||||
//if no list/L is provided, one is created.
|
||||
/proc/init_subtypes_assoc(prototype, list/L)
|
||||
if(!istype(L)) L = list()
|
||||
for(var/path in subtypesof(prototype))
|
||||
L[path] = new path()
|
||||
return L
|
||||
|
||||
//Move a single element from position fromIndex within a list, to position toIndex
|
||||
//All elements in the range [1,toIndex) before the move will be before the pivot afterwards
|
||||
//All elements in the range [toIndex, L.len+1) before the move will be after the pivot afterwards
|
||||
//In other words, it's as if the range [fromIndex,toIndex) have been rotated using a <<< operation common to other languages.
|
||||
//fromIndex and toIndex must be in the range [1,L.len+1]
|
||||
//This will preserve associations ~Carnie
|
||||
/proc/moveElement(list/L, fromIndex, toIndex)
|
||||
if(fromIndex == toIndex || fromIndex+1 == toIndex) //no need to move
|
||||
return
|
||||
if(fromIndex > toIndex)
|
||||
++fromIndex //since a null will be inserted before fromIndex, the index needs to be nudged right by one
|
||||
|
||||
L.Insert(toIndex, null)
|
||||
L.Swap(fromIndex, toIndex)
|
||||
L.Cut(fromIndex, fromIndex+1)
|
||||
|
||||
//Move elements [fromIndex,fromIndex+len) to [toIndex-len, toIndex)
|
||||
//Same as moveElement but for ranges of elements
|
||||
//This will preserve associations ~Carnie
|
||||
/proc/moveRange(list/L, fromIndex, toIndex, len=1)
|
||||
var/distance = abs(toIndex - fromIndex)
|
||||
if(len >= distance) //there are more elements to be moved than the distance to be moved. Therefore the same result can be achieved (with fewer operations) by moving elements between where we are and where we are going. The result being, our range we are moving is shifted left or right by dist elements
|
||||
if(fromIndex <= toIndex)
|
||||
return //no need to move
|
||||
fromIndex += len //we want to shift left instead of right
|
||||
|
||||
for(var/i=0, i<distance, ++i)
|
||||
L.Insert(fromIndex, null)
|
||||
L.Swap(fromIndex, toIndex)
|
||||
L.Cut(toIndex, toIndex+1)
|
||||
else
|
||||
if(fromIndex > toIndex)
|
||||
fromIndex += len
|
||||
|
||||
for(var/i=0, i<len, ++i)
|
||||
L.Insert(toIndex, null)
|
||||
L.Swap(fromIndex, toIndex)
|
||||
L.Cut(fromIndex, fromIndex+1)
|
||||
|
||||
//replaces reverseList ~Carnie
|
||||
/proc/reverseRange(list/L, start=1, end=0)
|
||||
if(L.len)
|
||||
start = start % L.len
|
||||
end = end % (L.len+1)
|
||||
if(start <= 0)
|
||||
start += L.len
|
||||
if(end <= 0)
|
||||
end += L.len + 1
|
||||
|
||||
--end
|
||||
while(start < end)
|
||||
L.Swap(start++,end--)
|
||||
|
||||
return L
|
||||
|
||||
//Copies a list, and all lists inside it recusively
|
||||
//Does not copy any other reference type
|
||||
/proc/deepCopyList(list/l)
|
||||
if(!islist(l))
|
||||
return l
|
||||
. = l.Copy()
|
||||
for(var/i = 1 to l.len)
|
||||
if(islist(.[i]))
|
||||
.[i] = .(.[i])
|
||||
=======
|
||||
/*
|
||||
* Holds procs to help with list operations
|
||||
* Contains groups:
|
||||
@@ -1513,4 +756,3 @@ proc/dd_sortedTextList(list/incoming)
|
||||
. = list()
|
||||
for(var/i in L)
|
||||
. |= i
|
||||
>>>>>>> 9ff8103... Merge pull request #5636 from kevinz000/pixel_projectiles:code/_helpers/_lists.dm
|
||||
|
||||
@@ -45,6 +45,3 @@
|
||||
. = B[STAT_ENTRY_TIME] - A[STAT_ENTRY_TIME]
|
||||
if (!.)
|
||||
. = B[STAT_ENTRY_COUNT] - A[STAT_ENTRY_COUNT]
|
||||
|
||||
/proc/cmp_timer(datum/timedevent/a, datum/timedevent/b)
|
||||
return a.timeToRun - b.timeToRun
|
||||
|
||||
@@ -1267,9 +1267,11 @@ var/mob/dview/dview_mob = new
|
||||
if(!center)
|
||||
return
|
||||
|
||||
if(!dview_mob) //VOREStation Add - Emergency Backup
|
||||
//VOREStation Add - Emergency Backup
|
||||
if(!dview_mob)
|
||||
dview_mob = new()
|
||||
WARNING("dview mob was lost, and had to be recreated!")
|
||||
//VOREStation Add End
|
||||
|
||||
dview_mob.loc = center
|
||||
|
||||
@@ -1455,25 +1457,6 @@ var/mob/dview/dview_mob = new
|
||||
if(337.5)
|
||||
return "North-Northwest"
|
||||
|
||||
//This is used to force compiletime errors if you incorrectly supply variable names. Crafty!
|
||||
#define NAMEOF(datum, X) (#X || ##datum.##X)
|
||||
|
||||
//Creates a callback with the specific purpose of setting a variable
|
||||
#define VARSET_CALLBACK(datum, var, var_value) CALLBACK(GLOBAL_PROC, /proc/___callbackvarset, weakref(##datum), NAMEOF(##datum, ##var), ##var_value)
|
||||
|
||||
//Helper for the above
|
||||
/proc/___callbackvarset(list_or_datum, var_name, var_value)
|
||||
if(isweakref(list_or_datum))
|
||||
var/weakref/wr = list_or_datum
|
||||
list_or_datum = wr.resolve()
|
||||
if(!list_or_datum)
|
||||
return
|
||||
if(length(list_or_datum))
|
||||
list_or_datum[var_name] = var_value
|
||||
return
|
||||
var/datum/D = list_or_datum
|
||||
D.vars[var_name] = var_value
|
||||
|
||||
/proc/pass()
|
||||
return
|
||||
|
||||
@@ -1566,4 +1549,4 @@ var/mob/dview/dview_mob = new
|
||||
/proc/IsValidSrc(datum/D)
|
||||
if(istype(D))
|
||||
return !QDELETED(D)
|
||||
return FALSE
|
||||
return FALSE
|
||||
@@ -169,6 +169,11 @@
|
||||
set_dir(direct)
|
||||
if(. && has_buckled_mobs() && !handle_buckled_mob_movement(loc,direct)) //movement failed due to buckled mob(s)
|
||||
return FALSE
|
||||
//VOREStation Add
|
||||
else if(. && riding_datum)
|
||||
riding_datum.handle_vehicle_layer()
|
||||
riding_datum.handle_vehicle_offsets()
|
||||
//VOREStation Add End
|
||||
|
||||
//Called after a successful Move(). By this point, we've already moved
|
||||
/atom/movable/proc/Moved(atom/OldLoc, Dir, Forced = FALSE)
|
||||
@@ -475,12 +480,8 @@
|
||||
|
||||
/atom/movable/proc/adjust_rotation(new_rotation)
|
||||
icon_rotation = new_rotation
|
||||
<<<<<<< HEAD
|
||||
update_transform()
|
||||
=======
|
||||
update_transform()
|
||||
|
||||
// Called when touching a lava tile.
|
||||
/atom/movable/proc/lava_act()
|
||||
fire_act(null, 10000, 1000)
|
||||
>>>>>>> 9ff8103... Merge pull request #5636 from kevinz000/pixel_projectiles
|
||||
|
||||
@@ -17,12 +17,6 @@
|
||||
/datum/computer/file/embedded_program/proc/receive_signal(datum/signal/signal, receive_method, receive_param)
|
||||
return
|
||||
|
||||
<<<<<<< HEAD
|
||||
/datum/computer/file/embedded_program/proc/process()
|
||||
return
|
||||
|
||||
=======
|
||||
>>>>>>> 9ff8103... Merge pull request #5636 from kevinz000/pixel_projectiles
|
||||
/datum/computer/file/embedded_program/proc/post_signal(datum/signal/signal, comm_line)
|
||||
if(master)
|
||||
master.post_signal(signal, comm_line)
|
||||
|
||||
@@ -195,16 +195,3 @@
|
||||
else
|
||||
L.set_dir(dir)
|
||||
return TRUE
|
||||
<<<<<<< HEAD
|
||||
|
||||
/atom/movable/Move(atom/newloc, direct = 0)
|
||||
. = ..()
|
||||
if(. && has_buckled_mobs() && !handle_buckled_mob_movement(newloc, direct)) //movement failed due to buckled mob(s)
|
||||
. = 0
|
||||
//VOREStation Add
|
||||
else if(. && riding_datum)
|
||||
riding_datum.handle_vehicle_layer()
|
||||
riding_datum.handle_vehicle_offsets()
|
||||
//VOREStation Add End
|
||||
=======
|
||||
>>>>>>> 9ff8103... Merge pull request #5636 from kevinz000/pixel_projectiles
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
var/randomdir = TRUE
|
||||
var/timerid
|
||||
|
||||
/obj/effect/temp_visual/initialize()
|
||||
/obj/effect/temp_visual/Initialize()
|
||||
. = ..()
|
||||
if(randomdir)
|
||||
dir = pick(list(NORTH, SOUTH, EAST, WEST))
|
||||
@@ -36,4 +36,3 @@
|
||||
dir = set_dir
|
||||
. = ..()
|
||||
|
||||
|
||||
|
||||
@@ -131,17 +131,10 @@
|
||||
|
||||
/obj/structure/window/CanPass(atom/movable/mover, turf/target, height=0, air_group=0)
|
||||
if(istype(mover) && mover.checkpass(PASSGLASS))
|
||||
<<<<<<< HEAD
|
||||
return 1
|
||||
if(is_fulltile())
|
||||
return 0 //full tile window, you can't move into it!
|
||||
if(get_dir(loc, target) & dir)
|
||||
=======
|
||||
return TRUE
|
||||
if(is_fulltile())
|
||||
return FALSE //full tile window, you can't move into it!
|
||||
if((get_dir(loc, target) & dir) || (get_dir(mover, target) == turn(dir, 180)))
|
||||
>>>>>>> 9ff8103... Merge pull request #5636 from kevinz000/pixel_projectiles
|
||||
return !density
|
||||
else
|
||||
return TRUE
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
|
||||
#define RECOMMENDED_VERSION 501
|
||||
/world/New()
|
||||
world.log << "Map Loading Complete"
|
||||
//logs
|
||||
//VOREStation Edit Start
|
||||
log_path += time2text(world.realtime, "YYYY/MM-Month/DD-Day/round-hh-mm-ss")
|
||||
diary = file("[log_path].log")
|
||||
href_logfile = file("[log_path]-hrefs.htm")
|
||||
error_log = file("[log_path]-error.log")
|
||||
debug_log = file("[log_path]-debug.log")
|
||||
debug_log << "[log_end]\n[log_end]\nStarting up. [time_stamp()][log_end]\n---------------------[log_end]"
|
||||
diary = start_log("[log_path].log")
|
||||
href_logfile = start_log("[log_path]-hrefs.htm")
|
||||
error_log = start_log("[log_path]-error.log")
|
||||
debug_log = start_log("[log_path]-debug.log")
|
||||
//VOREStation Edit End
|
||||
|
||||
changelog_hash = md5('html/changelog.html') //used for telling if the changelog has changed recently
|
||||
|
||||
if(byond_version < RECOMMENDED_VERSION)
|
||||
@@ -20,8 +21,9 @@
|
||||
// dumb and hardcoded but I don't care~
|
||||
config.server_name += " #[(world.port % 1000) / 100]"
|
||||
|
||||
if(config && config.log_runtime)
|
||||
log = file("data/logs/runtime/[time2text(world.realtime,"YYYY-MM-DD-(hh-mm-ss)")]-runtime.log")
|
||||
// TODO - Figure out what this is. Can you assign to world.log?
|
||||
// if(config && config.log_runtime)
|
||||
// log = file("data/logs/runtime/[time2text(world.realtime,"YYYY-MM-DD-(hh-mm-ss)")]-runtime.log")
|
||||
|
||||
GLOB.timezoneOffset = text2num(time2text(0,"hh")) * 36000
|
||||
|
||||
@@ -54,6 +56,9 @@
|
||||
// Create robolimbs for chargen.
|
||||
populate_robolimb_list()
|
||||
|
||||
//Must be done now, otherwise ZAS zones and lighting overlays need to be recreated.
|
||||
createRandomZlevel()
|
||||
|
||||
processScheduler = new
|
||||
master_controller = new /datum/controller/game_controller()
|
||||
|
||||
@@ -79,7 +84,7 @@ var/world_topic_spam_protect_ip = "0.0.0.0"
|
||||
var/world_topic_spam_protect_time = world.timeofday
|
||||
|
||||
/world/Topic(T, addr, master, key)
|
||||
debug_log << "TOPIC: \"[T]\", from:[addr], master:[master], key:[key][log_end]"
|
||||
log_topic("\"[T]\", from:[addr], master:[master], key:[key]")
|
||||
|
||||
if (T == "ping")
|
||||
var/x = 1
|
||||
@@ -256,7 +261,7 @@ var/world_topic_spam_protect_time = world.timeofday
|
||||
info["hasbeenrev"] = M.mind ? M.mind.has_been_rev : "No mind"
|
||||
info["stat"] = M.stat
|
||||
info["type"] = M.type
|
||||
if(isliving(M))
|
||||
if(istype(M, /mob/living))
|
||||
var/mob/living/L = M
|
||||
info["damage"] = list2params(list(
|
||||
oxy = L.getOxyLoss(),
|
||||
@@ -377,6 +382,7 @@ var/world_topic_spam_protect_time = world.timeofday
|
||||
/*spawn(0)
|
||||
world << sound(pick('sound/AI/newroundsexy.ogg','sound/misc/apcdestroyed.ogg','sound/misc/bangindonk.ogg')) // random end sounds!! - LastyBatsy
|
||||
*/
|
||||
|
||||
if (reason || fast_track) //special reboot, do none of the normal stuff
|
||||
if (usr)
|
||||
log_admin("[key_name(usr)] Has requested an immediate world restart via client side debugging tools")
|
||||
@@ -625,7 +631,7 @@ proc/establish_old_db_connection()
|
||||
|
||||
// Things to do when a new z-level was just made.
|
||||
/world/proc/max_z_changed()
|
||||
if(!islist(GLOB.players_by_zlevel))
|
||||
if(!istype(GLOB.players_by_zlevel, /list))
|
||||
GLOB.players_by_zlevel = new /list(world.maxz, 0)
|
||||
while(GLOB.players_by_zlevel.len < world.maxz)
|
||||
GLOB.players_by_zlevel.len++
|
||||
|
||||
@@ -96,34 +96,9 @@ default behaviour is:
|
||||
to_chat(src, "<span class='warning'>[tmob] is restrained, you cannot push past</span>")
|
||||
now_pushing = 0
|
||||
return
|
||||
<<<<<<< HEAD
|
||||
|
||||
if((tmob.mob_always_swap || (tmob.a_intent == I_HELP || tmob.restrained()) && (a_intent == I_HELP || src.restrained())) && tmob.canmove && canmove && !tmob.buckled && !buckled && !dense && can_move_mob(tmob, 1, 0)) // mutual brohugs all around!
|
||||
var/turf/oldloc = loc
|
||||
forceMove(tmob.loc)
|
||||
|
||||
//VOREstation Edit - Begin
|
||||
if (istype(tmob, /mob/living/simple_mob)) //check bumpnom chance, if it's a simplemob that's bumped
|
||||
tmob.Bumped(src)
|
||||
else if(istype(src, /mob/living/simple_mob)) //otherwise, if it's a simplemob doing the bumping. Simplemob on simplemob doesn't seem to trigger but that's fine.
|
||||
Bumped(tmob)
|
||||
if (tmob.loc == src) //check if they got ate, and if so skip the forcemove
|
||||
now_pushing = 0
|
||||
return
|
||||
|
||||
// In case of micros, we don't swap positions; instead occupying the same square!
|
||||
if (handle_micro_bump_helping(tmob))
|
||||
now_pushing = 0
|
||||
return
|
||||
// TODO - Check if we need to do something about the slime.UpdateFeed() we are skipping below.
|
||||
// VOREStation Edit - End
|
||||
|
||||
tmob.forceMove(oldloc)
|
||||
=======
|
||||
if( tmob.pulling == M && ( M.restrained() && !( tmob.restrained() ) && tmob.stat == 0) )
|
||||
if ( !(world.time % 5) )
|
||||
to_chat(src, "<span class='warning'>[tmob] is restraining [M], you cannot push past</span>")
|
||||
>>>>>>> 9ff8103... Merge pull request #5636 from kevinz000/pixel_projectiles
|
||||
now_pushing = 0
|
||||
return
|
||||
|
||||
@@ -151,6 +126,21 @@ default behaviour is:
|
||||
if((tmob.mob_always_swap || (tmob.a_intent == I_HELP || tmob.restrained()) && (a_intent == I_HELP || src.restrained())) && tmob.canmove && canmove && !tmob.buckled && !buckled && !dense && can_move_mob(tmob, 1, 0)) // mutual brohugs all around!
|
||||
var/turf/oldloc = loc
|
||||
forceMove(tmob.loc)
|
||||
//VOREstation Edit - Begin
|
||||
if (istype(tmob, /mob/living/simple_mob)) //check bumpnom chance, if it's a simplemob that's bumped
|
||||
tmob.Bumped(src)
|
||||
else if(istype(src, /mob/living/simple_mob)) //otherwise, if it's a simplemob doing the bumping. Simplemob on simplemob doesn't seem to trigger but that's fine.
|
||||
Bumped(tmob)
|
||||
if (tmob.loc == src) //check if they got ate, and if so skip the forcemove
|
||||
now_pushing = 0
|
||||
return
|
||||
|
||||
// In case of micros, we don't swap positions; instead occupying the same square!
|
||||
if (handle_micro_bump_helping(tmob))
|
||||
now_pushing = 0
|
||||
return
|
||||
// TODO - Check if we need to do something about the slime.UpdateFeed() we are skipping below.
|
||||
// VOREStation Edit - End
|
||||
tmob.forceMove(oldloc)
|
||||
now_pushing = 0
|
||||
return
|
||||
@@ -161,6 +151,18 @@ default behaviour is:
|
||||
if(a_intent == I_HELP || src.restrained())
|
||||
now_pushing = 0
|
||||
return
|
||||
// VOREStation Edit - Begin
|
||||
// Plow that nerd.
|
||||
if(ishuman(tmob))
|
||||
var/mob/living/carbon/human/H = tmob
|
||||
if(H.species.lightweight == 1 && prob(50))
|
||||
H.visible_message("<span class='warning'>[src] bumps into [H], knocking them off balance!</span>")
|
||||
H.Weaken(5)
|
||||
now_pushing = 0
|
||||
return
|
||||
// Handle grabbing, stomping, and such of micros!
|
||||
if(handle_micro_bump_other(tmob)) return
|
||||
// VOREStation Edit - End
|
||||
if(istype(tmob, /mob/living/carbon/human) && (FAT in tmob.mutations))
|
||||
if(prob(40) && !(FAT in src.mutations))
|
||||
to_chat(src, "<span class='danger'>You fail to push [tmob]'s fat ass out of the way.</span>")
|
||||
@@ -170,39 +172,9 @@ default behaviour is:
|
||||
if(prob(99))
|
||||
now_pushing = 0
|
||||
return
|
||||
<<<<<<< HEAD
|
||||
|
||||
// VOREStation Edit - Begin
|
||||
// Plow that nerd.
|
||||
if(ishuman(tmob))
|
||||
var/mob/living/carbon/human/H = tmob
|
||||
if(H.species.lightweight == 1 && prob(50))
|
||||
H.visible_message("<span class='warning'>[src] bumps into [H], knocking them off balance!</span>")
|
||||
H.Weaken(5)
|
||||
now_pushing = 0
|
||||
return
|
||||
// Handle grabbing, stomping, and such of micros!
|
||||
if(handle_micro_bump_other(tmob)) return
|
||||
// VOREStation Edit - End
|
||||
|
||||
if(istype(tmob, /mob/living/carbon/human) && (FAT in tmob.mutations))
|
||||
if(prob(40) && !(FAT in src.mutations))
|
||||
to_chat(src, "<span class='danger'>You fail to push [tmob]'s fat ass out of the way.</span>")
|
||||
now_pushing = 0
|
||||
return
|
||||
if(tmob.r_hand && istype(tmob.r_hand, /obj/item/weapon/shield/riot))
|
||||
if(prob(99))
|
||||
now_pushing = 0
|
||||
return
|
||||
if(tmob.l_hand && istype(tmob.l_hand, /obj/item/weapon/shield/riot))
|
||||
if(prob(99))
|
||||
now_pushing = 0
|
||||
return
|
||||
if(!(tmob.status_flags & CANPUSH))
|
||||
=======
|
||||
if(tmob.l_hand && istype(tmob.l_hand, /obj/item/weapon/shield/riot))
|
||||
if(prob(99))
|
||||
>>>>>>> 9ff8103... Merge pull request #5636 from kevinz000/pixel_projectiles
|
||||
now_pushing = 0
|
||||
return
|
||||
if(!(tmob.status_flags & CANPUSH))
|
||||
@@ -211,39 +183,26 @@ default behaviour is:
|
||||
|
||||
tmob.LAssailant = src
|
||||
|
||||
<<<<<<< HEAD
|
||||
now_pushing = 0
|
||||
spawn(0)
|
||||
..()
|
||||
if (!istype(AM, /atom/movable) || AM.anchored)
|
||||
//VOREStation Edit - object-specific proc for running into things
|
||||
if(((confused || is_blind()) && stat == CONSCIOUS && prob(50) && m_intent=="run") || flying)
|
||||
AM.stumble_into(src)
|
||||
//VOREStation Edit End
|
||||
/* VOREStation Removal - See above
|
||||
Weaken(2)
|
||||
playsound(loc, "punch", 25, 1, -1)
|
||||
visible_message("<span class='warning'>[src] [pick("ran", "slammed")] into \the [AM]!</span>")
|
||||
src.apply_damage(5, BRUTE)
|
||||
src << ("<span class='warning'>You just [pick("ran", "slammed")] into \the [AM]!</span>")
|
||||
to_chat(src, "<span class='warning'>You just [pick("ran", "slammed")] into \the [AM]!</span>")
|
||||
*/ // VOREStation Removal End
|
||||
=======
|
||||
now_pushing = 0
|
||||
. = ..()
|
||||
if (!istype(AM, /atom/movable) || AM.anchored)
|
||||
//VOREStation Edit - object-specific proc for running into things
|
||||
if(((confused || is_blind()) && stat == CONSCIOUS && prob(50) && m_intent=="run") || flying)
|
||||
AM.stumble_into(src)
|
||||
//VOREStation Edit End
|
||||
/* VOREStation Removal - See above
|
||||
if(confused && prob(50) && m_intent=="run")
|
||||
Weaken(2)
|
||||
playsound(loc, "punch", 25, 1, -1)
|
||||
visible_message("<span class='warning'>[src] [pick("ran", "slammed")] into \the [AM]!</span>")
|
||||
src.apply_damage(5, BRUTE)
|
||||
to_chat(src, "<span class='warning'>You just [pick("ran", "slammed")] into \the [AM]!</span>")
|
||||
*/ // VOREStation Removal End
|
||||
return
|
||||
if (!now_pushing)
|
||||
if(isobj(AM))
|
||||
var/obj/I = AM
|
||||
if(!can_pull_size || can_pull_size < I.w_class)
|
||||
>>>>>>> 9ff8103... Merge pull request #5636 from kevinz000/pixel_projectiles
|
||||
return
|
||||
now_pushing = 1
|
||||
|
||||
|
||||
@@ -1194,8 +1194,6 @@ mob/proc/yank_out_object()
|
||||
closeToolTip(usr) //No reason not to, really
|
||||
|
||||
..()
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
|
||||
// Manages a global list of mobs with clients attached, indexed by z-level.
|
||||
/mob/proc/update_client_z(new_z) // +1 to register, null to unregister.
|
||||
@@ -1212,4 +1210,3 @@ mob/proc/yank_out_object()
|
||||
/mob/onTransitZ(old_z, new_z)
|
||||
..()
|
||||
update_client_z(new_z)
|
||||
>>>>>>> 9ff8103... Merge pull request #5636 from kevinz000/pixel_projectiles
|
||||
|
||||
@@ -109,65 +109,6 @@
|
||||
*/
|
||||
return
|
||||
|
||||
<<<<<<< HEAD
|
||||
//This proc should never be overridden elsewhere at /atom/movable to keep directions sane.
|
||||
/atom/movable/Move(newloc, direct)
|
||||
if (direct & (direct - 1))
|
||||
if (direct & 1)
|
||||
if (direct & 4)
|
||||
if (step(src, NORTH))
|
||||
step(src, EAST)
|
||||
else
|
||||
if (step(src, EAST))
|
||||
step(src, NORTH)
|
||||
else
|
||||
if (direct & 8)
|
||||
if (step(src, NORTH))
|
||||
step(src, WEST)
|
||||
else
|
||||
if (step(src, WEST))
|
||||
step(src, NORTH)
|
||||
else
|
||||
if (direct & 2)
|
||||
if (direct & 4)
|
||||
if (step(src, SOUTH))
|
||||
step(src, EAST)
|
||||
else
|
||||
if (step(src, EAST))
|
||||
step(src, SOUTH)
|
||||
else
|
||||
if (direct & 8)
|
||||
if (step(src, SOUTH))
|
||||
step(src, WEST)
|
||||
else
|
||||
if (step(src, WEST))
|
||||
step(src, SOUTH)
|
||||
else
|
||||
var/atom/A = src.loc
|
||||
|
||||
var/olddir = dir //we can't override this without sacrificing the rest of movable/New()
|
||||
. = ..()
|
||||
if(direct != olddir)
|
||||
dir = olddir
|
||||
set_dir(direct)
|
||||
|
||||
src.move_speed = world.time - src.l_move_time
|
||||
src.l_move_time = world.time
|
||||
src.m_flag = 1
|
||||
if(A && A.z != src.z) // If we changed z-levels, tell the AM that.
|
||||
on_z_change(A.z, src.z)
|
||||
if ((A != src.loc && A && A.z == src.z))
|
||||
src.last_move = get_dir(A, src.loc)
|
||||
if(.)
|
||||
Moved(A, direct)
|
||||
return
|
||||
|
||||
// Called on a successful Move().
|
||||
/atom/movable/proc/Moved(atom/oldloc)
|
||||
return
|
||||
|
||||
=======
|
||||
>>>>>>> 9ff8103... Merge pull request #5636 from kevinz000/pixel_projectiles
|
||||
/client/proc/Move_object(direct)
|
||||
if(mob && mob.control_object)
|
||||
if(mob.control_object.density)
|
||||
|
||||
@@ -100,7 +100,7 @@
|
||||
damage = 32
|
||||
damage_type = BRUTE
|
||||
check_armour = "bomb"
|
||||
kill_count = 3 // Our "range" var is named "kill_count". Yes it is.
|
||||
range = 3 // Our "range" var is named "kill_count". Yes it is.
|
||||
|
||||
var/pressure_decrease = 0.25
|
||||
var/turf_aoe = FALSE
|
||||
@@ -219,7 +219,7 @@
|
||||
cost = 24 //so you can fit four plus a tracer cosmetic
|
||||
|
||||
/obj/item/borg/upgrade/modkit/range/modify_projectile(obj/item/projectile/kinetic/K)
|
||||
K.kill_count += modifier
|
||||
K.range += modifier
|
||||
|
||||
|
||||
//Damage
|
||||
|
||||
@@ -230,18 +230,6 @@
|
||||
if(prob(50))
|
||||
homing_offset_y = -homing_offset_y
|
||||
|
||||
<<<<<<< HEAD
|
||||
//TODO: make it so this is called more reliably, instead of sometimes by bullet_act() and sometimes not
|
||||
/obj/item/projectile/proc/on_hit(var/atom/target, var/blocked = 0, var/def_zone = null)
|
||||
if(blocked >= 100) return 0//Full block
|
||||
if(!isliving(target)) return 0
|
||||
// if(isanimal(target)) return 0
|
||||
var/mob/living/L = target
|
||||
L.apply_effects(stun, weaken, paralyze, irradiate, stutter, eyeblur, drowsy, agony, blocked, incendiary, flammability) // add in AGONY!
|
||||
if(modifier_type_to_apply)
|
||||
L.add_modifier(modifier_type_to_apply, modifier_duration)
|
||||
return 1
|
||||
=======
|
||||
/obj/item/projectile/process()
|
||||
last_process = world.time
|
||||
if(!loc || !fired || !trajectory)
|
||||
@@ -327,7 +315,6 @@
|
||||
/obj/item/projectile/proc/after_z_change(atom/olcloc, atom/newloc)
|
||||
|
||||
/obj/item/projectile/proc/before_z_change(atom/oldloc, atom/newloc)
|
||||
>>>>>>> 9ff8103... Merge pull request #5636 from kevinz000/pixel_projectiles
|
||||
|
||||
/obj/item/projectile/proc/before_move()
|
||||
return
|
||||
@@ -591,85 +578,9 @@
|
||||
|
||||
//hit messages
|
||||
if(silenced)
|
||||
<<<<<<< HEAD
|
||||
return
|
||||
|
||||
if(ispath(muzzle_type))
|
||||
var/obj/effect/projectile/M = new muzzle_type(get_turf(src))
|
||||
|
||||
if(istype(M))
|
||||
M.set_transform(T)
|
||||
M.pixel_x = location.pixel_x
|
||||
M.pixel_y = location.pixel_y
|
||||
M.update_light()
|
||||
M.activate()
|
||||
|
||||
/obj/item/projectile/proc/tracer_effect(var/matrix/M)
|
||||
if(ispath(tracer_type))
|
||||
var/obj/effect/projectile/P = new tracer_type(location.loc)
|
||||
|
||||
if(istype(P))
|
||||
P.set_transform(M)
|
||||
P.pixel_x = location.pixel_x
|
||||
P.pixel_y = location.pixel_y
|
||||
P.update_light()
|
||||
if(!hitscan)
|
||||
P.activate(step_delay) //if not a hitscan projectile, remove after a single delay
|
||||
else
|
||||
P.activate()
|
||||
|
||||
/obj/item/projectile/proc/impact_effect(var/matrix/M)
|
||||
if(ispath(tracer_type) && location)
|
||||
var/obj/effect/projectile/P = new impact_type(location.loc)
|
||||
|
||||
if(istype(P))
|
||||
P.set_transform(M)
|
||||
P.pixel_x = location.pixel_x
|
||||
P.pixel_y = location.pixel_y
|
||||
P.update_light()
|
||||
P.activate()
|
||||
|
||||
//"Tracing" projectile
|
||||
/obj/item/projectile/test //Used to see if you can hit them.
|
||||
invisibility = 101 //Nope! Can't see me!
|
||||
yo = null
|
||||
xo = null
|
||||
var/result = 0 //To pass the message back to the gun.
|
||||
var/atom/movable/result_ref = null // The thing that got hit that made the check return true.
|
||||
|
||||
/obj/item/projectile/test/Bump(atom/A as mob|obj|turf|area)
|
||||
if(A == firer)
|
||||
loc = A.loc
|
||||
return //cannot shoot yourself
|
||||
if(istype(A, /obj/item/projectile))
|
||||
return
|
||||
if(istype(A, /obj/structure/foamedmetal)) //Turrets can detect through foamed metal, but will have to blast through it. Similar to windows, if someone runs behind it, a person should probably just not shoot.
|
||||
return
|
||||
if(istype(A, /obj/structure/girder)) //They see you there.
|
||||
return
|
||||
if(istype(A, /obj/structure/door_assembly)) //And through there.
|
||||
return
|
||||
if(istype(A, /obj/structure)) //Unanchored things you can shove around will still keep the turret or other firing at your position. Aim intent still functions.
|
||||
var/obj/structure/S = A
|
||||
if(!S.anchored)
|
||||
return
|
||||
if(istype(A, /mob/living) || istype(A, /obj/mecha) || istype(A, /obj/vehicle))
|
||||
result_ref = A
|
||||
result = 2 //We hit someone, return 1!
|
||||
return
|
||||
result = 1
|
||||
return
|
||||
|
||||
/obj/item/projectile/test/launch(atom/target)
|
||||
var/turf/curloc = get_turf(src)
|
||||
var/turf/targloc = get_turf(target)
|
||||
if(!curloc || !targloc)
|
||||
return 0
|
||||
=======
|
||||
to_chat(target_mob, "<span class='danger'>You've been hit in the [parse_zone(def_zone)] by \the [src]!</span>")
|
||||
else
|
||||
visible_message("<span class='danger'>\The [target_mob] is hit by \the [src] in the [parse_zone(def_zone)]!</span>")//X has fired Y is now given by the guns so you cant tell who shot you if you could not see the shooter
|
||||
>>>>>>> 9ff8103... Merge pull request #5636 from kevinz000/pixel_projectiles
|
||||
|
||||
//admin logs
|
||||
if(!no_attack_log)
|
||||
@@ -680,17 +591,7 @@
|
||||
if (result == PROJECTILE_CONTINUE)
|
||||
return FALSE
|
||||
|
||||
<<<<<<< HEAD
|
||||
/obj/item/projectile/test/process(var/turf/targloc)
|
||||
while(src) //Loop on through!
|
||||
if(result)
|
||||
return result_ref
|
||||
// return (result - 1)
|
||||
if((!( targloc ) || loc == targloc))
|
||||
targloc = locate(min(max(x + xo, 1), world.maxx), min(max(y + yo, 1), world.maxy), z) //Finding the target turf at map edge
|
||||
=======
|
||||
return TRUE
|
||||
>>>>>>> 9ff8103... Merge pull request #5636 from kevinz000/pixel_projectiles
|
||||
|
||||
|
||||
/obj/item/projectile/proc/launch_projectile(atom/target, target_zone, mob/user, params, angle_override, forced_spread = 0)
|
||||
@@ -701,25 +602,8 @@
|
||||
if(get_turf(target) == get_turf(src))
|
||||
direct_target = target
|
||||
|
||||
<<<<<<< HEAD
|
||||
var/mob/living/M = locate() in get_turf(src)
|
||||
if(istype(M)) //If there is someting living...
|
||||
result_ref = M
|
||||
return result_ref //Return 1
|
||||
else
|
||||
M = locate() in get_step(src,targloc)
|
||||
if(istype(M))
|
||||
result_ref = M
|
||||
return result_ref
|
||||
|
||||
//Helper proc to check if you can hit them or not.
|
||||
/proc/check_trajectory(atom/target as mob|obj, atom/firer as mob|obj, var/pass_flags=PASSTABLE|PASSGLASS|PASSGRILLE, flags=null)
|
||||
if(!istype(target) || !istype(firer))
|
||||
return 0
|
||||
=======
|
||||
preparePixelProjectile(target, user? user : get_turf(src), params, forced_spread)
|
||||
return fire(angle_override, direct_target)
|
||||
>>>>>>> 9ff8103... Merge pull request #5636 from kevinz000/pixel_projectiles
|
||||
|
||||
//called to launch a projectile from a gun
|
||||
/obj/item/projectile/proc/launch_from_gun(atom/target, target_zone, mob/user, params, angle_override, forced_spread, obj/item/weapon/gun/launcher)
|
||||
|
||||
@@ -7,9 +7,9 @@
|
||||
damage_type = HALLOSS
|
||||
light_color = "#00CECE"
|
||||
|
||||
muzzle_type = /obj/effect/projectile/laser_omni/muzzle
|
||||
tracer_type = /obj/effect/projectile/laser_omni/tracer
|
||||
impact_type = /obj/effect/projectile/laser_omni/impact
|
||||
muzzle_type = /obj/effect/projectile/muzzle/laser_omni
|
||||
tracer_type = /obj/effect/projectile/tracer/laser_omni
|
||||
impact_type = /obj/effect/projectile/impact/laser_omni
|
||||
|
||||
/obj/item/projectile/beam/stun
|
||||
agony = 35
|
||||
@@ -22,9 +22,9 @@
|
||||
damage_type = HALLOSS
|
||||
light_color = "#00CC33"
|
||||
|
||||
muzzle_type = /obj/effect/projectile/xray/muzzle
|
||||
tracer_type = /obj/effect/projectile/xray/tracer
|
||||
impact_type = /obj/effect/projectile/xray/impact
|
||||
muzzle_type = /obj/effect/projectile/muzzle/xray
|
||||
tracer_type = /obj/effect/projectile/tracer/xray
|
||||
impact_type = /obj/effect/projectile/impact/xray
|
||||
|
||||
/obj/item/projectile/beam/energy_net/on_hit(var/atom/netted)
|
||||
do_net(netted)
|
||||
@@ -38,6 +38,6 @@
|
||||
icon_state = "bluelaser"
|
||||
light_color = "#0066FF"
|
||||
|
||||
muzzle_type = /obj/effect/projectile/laser_blue/muzzle
|
||||
tracer_type = /obj/effect/projectile/laser_blue/tracer
|
||||
impact_type = /obj/effect/projectile/laser_blue/impact
|
||||
muzzle_type = /obj/effect/projectile/muzzle/laser_blue
|
||||
tracer_type = /obj/effect/projectile/tracer/laser_blue
|
||||
impact_type = /obj/effect/projectile/impact/laser_blue
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
name = "chemical shell"
|
||||
icon_state = "bullet"
|
||||
damage = 10
|
||||
kill_count = 15 //if the shell hasn't hit anything after travelling this far it just explodes.
|
||||
range = 15 //if the shell hasn't hit anything after travelling this far it just explodes.
|
||||
flash_strength = 15
|
||||
brightness = 15
|
||||
|
||||
|
||||
@@ -116,9 +116,6 @@
|
||||
return ..(target, blocked, def_zone)
|
||||
|
||||
/obj/item/projectile/bullet/magnetic/fuelrod/supermatter/check_penetrate()
|
||||
<<<<<<< HEAD
|
||||
return 1
|
||||
=======
|
||||
return 1
|
||||
|
||||
/obj/item/projectile/bullet/magnetic/bore
|
||||
@@ -145,4 +142,3 @@
|
||||
return 1
|
||||
else
|
||||
..()
|
||||
>>>>>>> 9ff8103... Merge pull request #5636 from kevinz000/pixel_projectiles
|
||||
|
||||
@@ -540,26 +540,26 @@
|
||||
name = "laser beam"
|
||||
icon_state = "xray"
|
||||
light_color = "#00FF00"
|
||||
muzzle_type = /obj/effect/projectile/xray/muzzle
|
||||
tracer_type = /obj/effect/projectile/xray/tracer
|
||||
impact_type = /obj/effect/projectile/xray/impact
|
||||
muzzle_type = /obj/effect/projectile/muzzle/xray
|
||||
tracer_type = /obj/effect/projectile/tracer/xray
|
||||
impact_type = /obj/effect/projectile/impact/xray
|
||||
|
||||
/obj/item/projectile/beam/imperial
|
||||
name = "laser beam"
|
||||
fire_sound = 'sound/weapons/mandalorian.ogg'
|
||||
icon_state = "darkb"
|
||||
light_color = "#8837A3"
|
||||
muzzle_type = /obj/effect/projectile/darkmatter/muzzle
|
||||
tracer_type = /obj/effect/projectile/darkmatter/tracer
|
||||
impact_type = /obj/effect/projectile/darkmatter/impact
|
||||
muzzle_type = /obj/effect/projectile/muzzle/darkmatter
|
||||
tracer_type = /obj/effect/projectile/tracer/darkmatter
|
||||
impact_type = /obj/effect/projectile/impact/darkmatter
|
||||
|
||||
/obj/item/projectile/beam/stun/kin21
|
||||
name = "kinh21 stun beam"
|
||||
icon_state = "omnilaser"
|
||||
light_color = "#0000FF"
|
||||
muzzle_type = /obj/effect/projectile/laser_omni/muzzle
|
||||
tracer_type = /obj/effect/projectile/laser_omni/tracer
|
||||
impact_type = /obj/effect/projectile/laser_omni/impact
|
||||
muzzle_type = /obj/effect/projectile/muzzle/laser_omni
|
||||
tracer_type = /obj/effect/projectile/tracer/laser_omni
|
||||
impact_type = /obj/effect/projectile/impact/laser_omni
|
||||
|
||||
//--------------- StG-60 ----------------
|
||||
/obj/item/ammo_magazine/m792
|
||||
|
||||
@@ -45,6 +45,6 @@
|
||||
/obj/item/projectile/beam/dominator
|
||||
name = "dominator lethal beam"
|
||||
icon_state = "xray"
|
||||
muzzle_type = /obj/effect/projectile/xray/muzzle
|
||||
tracer_type = /obj/effect/projectile/xray/tracer
|
||||
impact_type = /obj/effect/projectile/xray/impact
|
||||
muzzle_type = /obj/effect/projectile/muzzle/xray
|
||||
tracer_type = /obj/effect/projectile/tracer/xray
|
||||
impact_type = /obj/effect/projectile/impact/xray
|
||||
@@ -309,9 +309,9 @@
|
||||
damage_type = HALLOSS
|
||||
light_color = "#00CC33"
|
||||
|
||||
muzzle_type = /obj/effect/projectile/laser_omni/muzzle
|
||||
tracer_type = /obj/effect/projectile/laser_omni/tracer
|
||||
impact_type = /obj/effect/projectile/laser_omni/impact
|
||||
muzzle_type = /obj/effect/projectile/muzzle/laser_omni
|
||||
tracer_type = /obj/effect/projectile/tracer/laser_omni
|
||||
impact_type = /obj/effect/projectile/impact/laser_omni
|
||||
|
||||
/obj/item/projectile/beam/final_option/on_hit(var/atom/impacted)
|
||||
if(isliving(impacted))
|
||||
|
||||
@@ -104,9 +104,9 @@
|
||||
icon_state = "omnilaser" //A little more cyan
|
||||
light_color = "#00C6FF"
|
||||
agony = 50 //Normal is 40 when this was set
|
||||
muzzle_type = /obj/effect/projectile/laser_omni/muzzle
|
||||
tracer_type = /obj/effect/projectile/laser_omni/tracer
|
||||
impact_type = /obj/effect/projectile/laser_omni/impact
|
||||
muzzle_type = /obj/effect/projectile/muzzle/laser_omni
|
||||
tracer_type = /obj/effect/projectile/tracer/laser_omni
|
||||
impact_type = /obj/effect/projectile/impact/laser_omni
|
||||
|
||||
//R&D Design
|
||||
/datum/design/item/weapon/protector
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
check_armour = "melee"
|
||||
embed_chance = 0
|
||||
vacuum_traversal = 0
|
||||
kill_count = 6 //Scary name, but just deletes the projectile after this range
|
||||
range = 6 //Scary name, but just deletes the projectile after this range
|
||||
|
||||
/obj/item/projectile/pummel/on_hit(var/atom/movable/target, var/blocked = 0)
|
||||
if(isliving(target))
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
check_armour = "melee"
|
||||
embed_chance = 0
|
||||
vacuum_traversal = 0
|
||||
kill_count = 5 //Scary name, but just deletes the projectile after this range
|
||||
range = 5 //Scary name, but just deletes the projectile after this range
|
||||
|
||||
/obj/item/projectile/sickshot/on_hit(var/atom/movable/target, var/blocked = 0)
|
||||
if(isliving(target))
|
||||
|
||||
@@ -65,9 +65,9 @@
|
||||
check_armour = "laser"
|
||||
var/set_size = 1 //Let's default to 100%
|
||||
|
||||
muzzle_type = /obj/effect/projectile/xray/muzzle
|
||||
tracer_type = /obj/effect/projectile/xray/tracer
|
||||
impact_type = /obj/effect/projectile/xray/impact
|
||||
muzzle_type = /obj/effect/projectile/muzzle/xray
|
||||
tracer_type = /obj/effect/projectile/tracer/xray
|
||||
impact_type = /obj/effect/projectile/impact/xray
|
||||
|
||||
on_hit(var/atom/target)
|
||||
var/mob/living/M = target
|
||||
|
||||
681
code/world.dm
681
code/world.dm
@@ -1,688 +1,7 @@
|
||||
<<<<<<< HEAD
|
||||
|
||||
/*
|
||||
The initialization of the game happens roughly like this:
|
||||
|
||||
1. All global variables are initialized (including the global_init instance).
|
||||
2. The map is initialized, and map objects are created.
|
||||
3. world/New() runs, creating the process scheduler (and the old master controller) and spawning their setup.
|
||||
4. processScheduler/setup() runs, creating all the processes. game_controller/setup() runs, calling initialize() on all movable atoms in the world.
|
||||
5. The gameticker is created.
|
||||
|
||||
*/
|
||||
var/global/datum/global_init/init = new ()
|
||||
|
||||
/*
|
||||
Pre-map initialization stuff should go here.
|
||||
*/
|
||||
/datum/global_init/New()
|
||||
|
||||
makeDatumRefLists()
|
||||
load_configuration()
|
||||
|
||||
initialize_integrated_circuits_list()
|
||||
|
||||
qdel(src) //we're done
|
||||
|
||||
/datum/global_init/Destroy()
|
||||
global.init = null
|
||||
return 2 // QDEL_HINT_IWILLGC
|
||||
|
||||
=======
|
||||
//Global init and the rest of world's code have been moved to code/global_init.dm and code/game/world.dm respectively.
|
||||
>>>>>>> 9ff8103... Merge pull request #5636 from kevinz000/pixel_projectiles
|
||||
/world
|
||||
mob = /mob/new_player
|
||||
turf = /turf/space
|
||||
area = /area/space
|
||||
view = "15x15"
|
||||
cache_lifespan = 7
|
||||
<<<<<<< HEAD
|
||||
|
||||
|
||||
|
||||
#define RECOMMENDED_VERSION 501
|
||||
/world/New()
|
||||
world.log << "Map Loading Complete"
|
||||
//logs
|
||||
log_path += time2text(world.realtime, "YYYY/MM-Month/DD-Day/round-hh-mm-ss")
|
||||
diary = start_log("[log_path].log")
|
||||
href_logfile = start_log("[log_path]-hrefs.htm")
|
||||
error_log = start_log("[log_path]-error.log")
|
||||
debug_log = start_log("[log_path]-debug.log")
|
||||
|
||||
changelog_hash = md5('html/changelog.html') //used for telling if the changelog has changed recently
|
||||
|
||||
if(byond_version < RECOMMENDED_VERSION)
|
||||
world.log << "Your server's byond version does not meet the recommended requirements for this server. Please update BYOND"
|
||||
|
||||
config.post_load()
|
||||
|
||||
if(config && config.server_name != null && config.server_suffix && world.port > 0)
|
||||
// dumb and hardcoded but I don't care~
|
||||
config.server_name += " #[(world.port % 1000) / 100]"
|
||||
|
||||
// TODO - Figure out what this is. Can you assign to world.log?
|
||||
// if(config && config.log_runtime)
|
||||
// log = file("data/logs/runtime/[time2text(world.realtime,"YYYY-MM-DD-(hh-mm-ss)")]-runtime.log")
|
||||
|
||||
GLOB.timezoneOffset = text2num(time2text(0,"hh")) * 36000
|
||||
|
||||
callHook("startup")
|
||||
//Emergency Fix
|
||||
load_mods()
|
||||
//end-emergency fix
|
||||
|
||||
src.update_status()
|
||||
|
||||
. = ..()
|
||||
|
||||
#if UNIT_TEST
|
||||
log_unit_test("Unit Tests Enabled. This will destroy the world when testing is complete.")
|
||||
log_unit_test("If you did not intend to enable this please check code/__defines/unit_testing.dm")
|
||||
#endif
|
||||
|
||||
// Set up roundstart seed list.
|
||||
plant_controller = new()
|
||||
|
||||
// This is kinda important. Set up details of what the hell things are made of.
|
||||
populate_material_list()
|
||||
|
||||
// Create frame types.
|
||||
populate_frame_types()
|
||||
|
||||
// Create floor types.
|
||||
populate_flooring_types()
|
||||
|
||||
// Create robolimbs for chargen.
|
||||
populate_robolimb_list()
|
||||
|
||||
//Must be done now, otherwise ZAS zones and lighting overlays need to be recreated.
|
||||
createRandomZlevel()
|
||||
|
||||
processScheduler = new
|
||||
master_controller = new /datum/controller/game_controller()
|
||||
|
||||
processScheduler.deferSetupFor(/datum/controller/process/ticker)
|
||||
processScheduler.setup()
|
||||
Master.Initialize(10, FALSE)
|
||||
|
||||
spawn(1)
|
||||
master_controller.setup()
|
||||
#if UNIT_TEST
|
||||
initialize_unit_tests()
|
||||
#endif
|
||||
|
||||
spawn(3000) //so we aren't adding to the round-start lag
|
||||
if(config.ToRban)
|
||||
ToRban_autoupdate()
|
||||
|
||||
#undef RECOMMENDED_VERSION
|
||||
|
||||
return
|
||||
|
||||
var/world_topic_spam_protect_ip = "0.0.0.0"
|
||||
var/world_topic_spam_protect_time = world.timeofday
|
||||
|
||||
/world/Topic(T, addr, master, key)
|
||||
log_topic("\"[T]\", from:[addr], master:[master], key:[key]")
|
||||
|
||||
if (T == "ping")
|
||||
var/x = 1
|
||||
for (var/client/C)
|
||||
x++
|
||||
return x
|
||||
|
||||
else if(T == "players")
|
||||
var/n = 0
|
||||
for(var/mob/M in player_list)
|
||||
if(M.client)
|
||||
n++
|
||||
return n
|
||||
|
||||
else if (copytext(T,1,7) == "status")
|
||||
var/input[] = params2list(T)
|
||||
var/list/s = list()
|
||||
s["version"] = game_version
|
||||
s["mode"] = master_mode
|
||||
s["respawn"] = config.abandon_allowed
|
||||
s["enter"] = config.enter_allowed
|
||||
s["vote"] = config.allow_vote_mode
|
||||
s["ai"] = config.allow_ai
|
||||
s["host"] = host ? host : null
|
||||
|
||||
// This is dumb, but spacestation13.com's banners break if player count isn't the 8th field of the reply, so... this has to go here.
|
||||
s["players"] = 0
|
||||
s["stationtime"] = stationtime2text()
|
||||
s["roundduration"] = roundduration2text()
|
||||
|
||||
if(input["status"] == "2")
|
||||
var/list/players = list()
|
||||
var/list/admins = list()
|
||||
|
||||
for(var/client/C in GLOB.clients)
|
||||
if(C.holder)
|
||||
if(C.holder.fakekey)
|
||||
continue
|
||||
admins[C.key] = C.holder.rank
|
||||
players += C.key
|
||||
|
||||
s["players"] = players.len
|
||||
s["playerlist"] = list2params(players)
|
||||
var/list/adm = get_admin_counts()
|
||||
var/list/presentmins = adm["present"]
|
||||
var/list/afkmins = adm["afk"]
|
||||
s["admins"] = presentmins.len + afkmins.len //equivalent to the info gotten from adminwho
|
||||
s["adminlist"] = list2params(admins)
|
||||
else
|
||||
var/n = 0
|
||||
var/admins = 0
|
||||
|
||||
for(var/client/C in GLOB.clients)
|
||||
if(C.holder)
|
||||
if(C.holder.fakekey)
|
||||
continue //so stealthmins aren't revealed by the hub
|
||||
admins++
|
||||
s["player[n]"] = C.key
|
||||
n++
|
||||
|
||||
s["players"] = n
|
||||
s["admins"] = admins
|
||||
|
||||
return list2params(s)
|
||||
|
||||
else if(T == "manifest")
|
||||
var/list/positions = list()
|
||||
var/list/set_names = list(
|
||||
"heads" = command_positions,
|
||||
"sec" = security_positions,
|
||||
"eng" = engineering_positions,
|
||||
"med" = medical_positions,
|
||||
"sci" = science_positions,
|
||||
"car" = cargo_positions,
|
||||
"civ" = civilian_positions,
|
||||
"bot" = nonhuman_positions
|
||||
)
|
||||
|
||||
for(var/datum/data/record/t in data_core.general)
|
||||
var/name = t.fields["name"]
|
||||
var/rank = t.fields["rank"]
|
||||
var/real_rank = make_list_rank(t.fields["real_rank"])
|
||||
|
||||
var/department = 0
|
||||
for(var/k in set_names)
|
||||
if(real_rank in set_names[k])
|
||||
if(!positions[k])
|
||||
positions[k] = list()
|
||||
positions[k][name] = rank
|
||||
department = 1
|
||||
if(!department)
|
||||
if(!positions["misc"])
|
||||
positions["misc"] = list()
|
||||
positions["misc"][name] = rank
|
||||
|
||||
// Synthetics don't have actual records, so we will pull them from here.
|
||||
for(var/mob/living/silicon/ai/ai in mob_list)
|
||||
if(!positions["bot"])
|
||||
positions["bot"] = list()
|
||||
positions["bot"][ai.name] = "Artificial Intelligence"
|
||||
for(var/mob/living/silicon/robot/robot in mob_list)
|
||||
// No combat/syndicate cyborgs, no drones.
|
||||
if(robot.module && robot.module.hide_on_manifest)
|
||||
continue
|
||||
if(!positions["bot"])
|
||||
positions["bot"] = list()
|
||||
positions["bot"][robot.name] = "[robot.modtype] [robot.braintype]"
|
||||
|
||||
for(var/k in positions)
|
||||
positions[k] = list2params(positions[k]) // converts positions["heads"] = list("Bob"="Captain", "Bill"="CMO") into positions["heads"] = "Bob=Captain&Bill=CMO"
|
||||
|
||||
return list2params(positions)
|
||||
|
||||
else if(T == "revision")
|
||||
if(revdata.revision)
|
||||
return list2params(list(branch = revdata.branch, date = revdata.date, revision = revdata.revision))
|
||||
else
|
||||
return "unknown"
|
||||
|
||||
else if(copytext(T,1,5) == "info")
|
||||
var/input[] = params2list(T)
|
||||
if(input["key"] != config.comms_password)
|
||||
if(world_topic_spam_protect_ip == addr && abs(world_topic_spam_protect_time - world.time) < 50)
|
||||
|
||||
spawn(50)
|
||||
world_topic_spam_protect_time = world.time
|
||||
return "Bad Key (Throttled)"
|
||||
|
||||
world_topic_spam_protect_time = world.time
|
||||
world_topic_spam_protect_ip = addr
|
||||
|
||||
return "Bad Key"
|
||||
|
||||
var/list/search = params2list(input["info"])
|
||||
var/list/ckeysearch = list()
|
||||
for(var/text in search)
|
||||
ckeysearch += ckey(text)
|
||||
|
||||
var/list/match = list()
|
||||
|
||||
for(var/mob/M in mob_list)
|
||||
var/strings = list(M.name, M.ckey)
|
||||
if(M.mind)
|
||||
strings += M.mind.assigned_role
|
||||
strings += M.mind.special_role
|
||||
for(var/text in strings)
|
||||
if(ckey(text) in ckeysearch)
|
||||
match[M] += 10 // an exact match is far better than a partial one
|
||||
else
|
||||
for(var/searchstr in search)
|
||||
if(findtext(text, searchstr))
|
||||
match[M] += 1
|
||||
|
||||
var/maxstrength = 0
|
||||
for(var/mob/M in match)
|
||||
maxstrength = max(match[M], maxstrength)
|
||||
for(var/mob/M in match)
|
||||
if(match[M] < maxstrength)
|
||||
match -= M
|
||||
|
||||
if(!match.len)
|
||||
return "No matches"
|
||||
else if(match.len == 1)
|
||||
var/mob/M = match[1]
|
||||
var/info = list()
|
||||
info["key"] = M.key
|
||||
info["name"] = M.name == M.real_name ? M.name : "[M.name] ([M.real_name])"
|
||||
info["role"] = M.mind ? (M.mind.assigned_role ? M.mind.assigned_role : "No role") : "No mind"
|
||||
var/turf/MT = get_turf(M)
|
||||
info["loc"] = M.loc ? "[M.loc]" : "null"
|
||||
info["turf"] = MT ? "[MT] @ [MT.x], [MT.y], [MT.z]" : "null"
|
||||
info["area"] = MT ? "[MT.loc]" : "null"
|
||||
info["antag"] = M.mind ? (M.mind.special_role ? M.mind.special_role : "Not antag") : "No mind"
|
||||
info["hasbeenrev"] = M.mind ? M.mind.has_been_rev : "No mind"
|
||||
info["stat"] = M.stat
|
||||
info["type"] = M.type
|
||||
if(istype(M, /mob/living))
|
||||
var/mob/living/L = M
|
||||
info["damage"] = list2params(list(
|
||||
oxy = L.getOxyLoss(),
|
||||
tox = L.getToxLoss(),
|
||||
fire = L.getFireLoss(),
|
||||
brute = L.getBruteLoss(),
|
||||
clone = L.getCloneLoss(),
|
||||
brain = L.getBrainLoss()
|
||||
))
|
||||
else
|
||||
info["damage"] = "non-living"
|
||||
info["gender"] = M.gender
|
||||
return list2params(info)
|
||||
else
|
||||
var/list/ret = list()
|
||||
for(var/mob/M in match)
|
||||
ret[M.key] = M.name
|
||||
return list2params(ret)
|
||||
|
||||
else if(copytext(T,1,9) == "adminmsg")
|
||||
/*
|
||||
We got an adminmsg from IRC bot lets split the input then validate the input.
|
||||
expected output:
|
||||
1. adminmsg = ckey of person the message is to
|
||||
2. msg = contents of message, parems2list requires
|
||||
3. validatationkey = the key the bot has, it should match the gameservers commspassword in it's configuration.
|
||||
4. sender = the ircnick that send the message.
|
||||
*/
|
||||
|
||||
|
||||
var/input[] = params2list(T)
|
||||
if(input["key"] != config.comms_password)
|
||||
if(world_topic_spam_protect_ip == addr && abs(world_topic_spam_protect_time - world.time) < 50)
|
||||
|
||||
spawn(50)
|
||||
world_topic_spam_protect_time = world.time
|
||||
return "Bad Key (Throttled)"
|
||||
|
||||
world_topic_spam_protect_time = world.time
|
||||
world_topic_spam_protect_ip = addr
|
||||
|
||||
return "Bad Key"
|
||||
|
||||
var/client/C
|
||||
var/req_ckey = ckey(input["adminmsg"])
|
||||
|
||||
for(var/client/K in GLOB.clients)
|
||||
if(K.ckey == req_ckey)
|
||||
C = K
|
||||
break
|
||||
if(!C)
|
||||
return "No client with that name on server"
|
||||
|
||||
var/rank = input["rank"]
|
||||
if(!rank)
|
||||
rank = "Admin"
|
||||
|
||||
var/message = "<font color='red'>IRC-[rank] PM from <b><a href='?irc_msg=[input["sender"]]'>IRC-[input["sender"]]</a></b>: [input["msg"]]</font>"
|
||||
var/amessage = "<font color='blue'>IRC-[rank] PM from <a href='?irc_msg=[input["sender"]]'>IRC-[input["sender"]]</a> to <b>[key_name(C)]</b> : [input["msg"]]</font>"
|
||||
|
||||
C.received_irc_pm = world.time
|
||||
C.irc_admin = input["sender"]
|
||||
|
||||
C << 'sound/effects/adminhelp.ogg'
|
||||
C << message
|
||||
|
||||
|
||||
for(var/client/A in admins)
|
||||
if(A != C)
|
||||
A << amessage
|
||||
|
||||
return "Message Successful"
|
||||
|
||||
else if(copytext(T,1,6) == "notes")
|
||||
/*
|
||||
We got a request for notes from the IRC Bot
|
||||
expected output:
|
||||
1. notes = ckey of person the notes lookup is for
|
||||
2. validationkey = the key the bot has, it should match the gameservers commspassword in it's configuration.
|
||||
*/
|
||||
var/input[] = params2list(T)
|
||||
if(input["key"] != config.comms_password)
|
||||
if(world_topic_spam_protect_ip == addr && abs(world_topic_spam_protect_time - world.time) < 50)
|
||||
|
||||
spawn(50)
|
||||
world_topic_spam_protect_time = world.time
|
||||
return "Bad Key (Throttled)"
|
||||
|
||||
world_topic_spam_protect_time = world.time
|
||||
world_topic_spam_protect_ip = addr
|
||||
return "Bad Key"
|
||||
|
||||
return show_player_info_irc(ckey(input["notes"]))
|
||||
|
||||
else if(copytext(T,1,4) == "age")
|
||||
var/input[] = params2list(T)
|
||||
if(input["key"] != config.comms_password)
|
||||
if(world_topic_spam_protect_ip == addr && abs(world_topic_spam_protect_time - world.time) < 50)
|
||||
spawn(50)
|
||||
world_topic_spam_protect_time = world.time
|
||||
return "Bad Key (Throttled)"
|
||||
|
||||
world_topic_spam_protect_time = world.time
|
||||
world_topic_spam_protect_ip = addr
|
||||
return "Bad Key"
|
||||
|
||||
var/age = get_player_age(input["age"])
|
||||
if(isnum(age))
|
||||
if(age >= 0)
|
||||
return "[age]"
|
||||
else
|
||||
return "Ckey not found"
|
||||
else
|
||||
return "Database connection failed or not set up"
|
||||
|
||||
|
||||
/world/Reboot(reason = 0, fast_track = FALSE)
|
||||
/*spawn(0)
|
||||
world << sound(pick('sound/AI/newroundsexy.ogg','sound/misc/apcdestroyed.ogg','sound/misc/bangindonk.ogg')) // random end sounds!! - LastyBatsy
|
||||
*/
|
||||
|
||||
if (reason || fast_track) //special reboot, do none of the normal stuff
|
||||
if (usr)
|
||||
log_admin("[key_name(usr)] Has requested an immediate world restart via client side debugging tools")
|
||||
message_admins("[key_name_admin(usr)] Has requested an immediate world restart via client side debugging tools")
|
||||
world << "<span class='boldannounce'>[key_name_admin(usr)] has requested an immediate world restart via client side debugging tools</span>"
|
||||
|
||||
else
|
||||
world << "<span class='boldannounce'>Rebooting world immediately due to host request</span>"
|
||||
else
|
||||
processScheduler.stop()
|
||||
Master.Shutdown() //run SS shutdowns
|
||||
for(var/client/C in GLOB.clients)
|
||||
if(config.server) //if you set a server location in config.txt, it sends you there instead of trying to reconnect to the same world address. -- NeoFite
|
||||
C << link("byond://[config.server]")
|
||||
|
||||
log_world("World rebooted at [time_stamp()]")
|
||||
..()
|
||||
|
||||
/hook/startup/proc/loadMode()
|
||||
world.load_mode()
|
||||
return 1
|
||||
|
||||
/world/proc/load_mode()
|
||||
if(!fexists("data/mode.txt"))
|
||||
return
|
||||
|
||||
|
||||
var/list/Lines = file2list("data/mode.txt")
|
||||
if(Lines.len)
|
||||
if(Lines[1])
|
||||
master_mode = Lines[1]
|
||||
log_misc("Saved mode is '[master_mode]'")
|
||||
|
||||
/world/proc/save_mode(var/the_mode)
|
||||
var/F = file("data/mode.txt")
|
||||
fdel(F)
|
||||
F << the_mode
|
||||
|
||||
|
||||
/hook/startup/proc/loadMOTD()
|
||||
world.load_motd()
|
||||
return 1
|
||||
|
||||
/world/proc/load_motd()
|
||||
join_motd = file2text("config/motd.txt")
|
||||
|
||||
|
||||
/proc/load_configuration()
|
||||
config = new /datum/configuration()
|
||||
config.load("config/config.txt")
|
||||
config.load("config/game_options.txt","game_options")
|
||||
config.loadsql("config/dbconfig.txt")
|
||||
config.loadforumsql("config/forumdbconfig.txt")
|
||||
|
||||
/hook/startup/proc/loadMods()
|
||||
world.load_mods()
|
||||
world.load_mentors() // no need to write another hook.
|
||||
return 1
|
||||
|
||||
/world/proc/load_mods()
|
||||
if(config.admin_legacy_system)
|
||||
var/text = file2text("config/moderators.txt")
|
||||
if (!text)
|
||||
error("Failed to load config/mods.txt")
|
||||
else
|
||||
var/list/lines = splittext(text, "\n")
|
||||
for(var/line in lines)
|
||||
if (!line)
|
||||
continue
|
||||
|
||||
if (copytext(line, 1, 2) == ";")
|
||||
continue
|
||||
|
||||
var/title = "Moderator"
|
||||
var/rights = admin_ranks[title]
|
||||
|
||||
var/ckey = copytext(line, 1, length(line)+1)
|
||||
var/datum/admins/D = new /datum/admins(title, rights, ckey)
|
||||
D.associate(GLOB.directory[ckey])
|
||||
|
||||
/world/proc/load_mentors()
|
||||
if(config.admin_legacy_system)
|
||||
var/text = file2text("config/mentors.txt")
|
||||
if (!text)
|
||||
error("Failed to load config/mentors.txt")
|
||||
else
|
||||
var/list/lines = splittext(text, "\n")
|
||||
for(var/line in lines)
|
||||
if (!line)
|
||||
continue
|
||||
if (copytext(line, 1, 2) == ";")
|
||||
continue
|
||||
|
||||
var/title = "Mentor"
|
||||
var/rights = admin_ranks[title]
|
||||
|
||||
var/ckey = copytext(line, 1, length(line)+1)
|
||||
var/datum/admins/D = new /datum/admins(title, rights, ckey)
|
||||
D.associate(GLOB.directory[ckey])
|
||||
|
||||
/world/proc/update_status()
|
||||
var/s = ""
|
||||
|
||||
if (config && config.server_name)
|
||||
s += "<b>[config.server_name]</b> — "
|
||||
|
||||
s += "<b>[station_name()]</b>";
|
||||
s += " ("
|
||||
s += "<a href=\"http://\">" //Change this to wherever you want the hub to link to.
|
||||
// s += "[game_version]"
|
||||
s += "Default" //Replace this with something else. Or ever better, delete it and uncomment the game version.
|
||||
s += "</a>"
|
||||
s += ")"
|
||||
|
||||
var/list/features = list()
|
||||
|
||||
if(ticker)
|
||||
if(master_mode)
|
||||
features += master_mode
|
||||
else
|
||||
features += "<b>STARTING</b>"
|
||||
|
||||
if (!config.enter_allowed)
|
||||
features += "closed"
|
||||
|
||||
features += config.abandon_allowed ? "respawn" : "no respawn"
|
||||
|
||||
if (config && config.allow_vote_mode)
|
||||
features += "vote"
|
||||
|
||||
if (config && config.allow_ai)
|
||||
features += "AI allowed"
|
||||
|
||||
var/n = 0
|
||||
for (var/mob/M in player_list)
|
||||
if (M.client)
|
||||
n++
|
||||
|
||||
if (n > 1)
|
||||
features += "~[n] players"
|
||||
else if (n > 0)
|
||||
features += "~[n] player"
|
||||
|
||||
|
||||
if (config && config.hostedby)
|
||||
features += "hosted by <b>[config.hostedby]</b>"
|
||||
|
||||
if (features)
|
||||
s += ": [jointext(features, ", ")]"
|
||||
|
||||
/* does this help? I do not know */
|
||||
if (src.status != s)
|
||||
src.status = s
|
||||
|
||||
#define FAILED_DB_CONNECTION_CUTOFF 5
|
||||
var/failed_db_connections = 0
|
||||
var/failed_old_db_connections = 0
|
||||
|
||||
/hook/startup/proc/connectDB()
|
||||
if(!config.sql_enabled)
|
||||
world.log << "SQL connection disabled in config."
|
||||
else if(!setup_database_connection())
|
||||
world.log << "Your server failed to establish a connection with the feedback database."
|
||||
else
|
||||
world.log << "Feedback database connection established."
|
||||
return 1
|
||||
|
||||
proc/setup_database_connection()
|
||||
|
||||
if(failed_db_connections > FAILED_DB_CONNECTION_CUTOFF) //If it failed to establish a connection more than 5 times in a row, don't bother attempting to conenct anymore.
|
||||
return 0
|
||||
|
||||
if(!dbcon)
|
||||
dbcon = new()
|
||||
|
||||
var/user = sqlfdbklogin
|
||||
var/pass = sqlfdbkpass
|
||||
var/db = sqlfdbkdb
|
||||
var/address = sqladdress
|
||||
var/port = sqlport
|
||||
|
||||
dbcon.Connect("dbi:mysql:[db]:[address]:[port]","[user]","[pass]")
|
||||
. = dbcon.IsConnected()
|
||||
if ( . )
|
||||
failed_db_connections = 0 //If this connection succeeded, reset the failed connections counter.
|
||||
else
|
||||
failed_db_connections++ //If it failed, increase the failed connections counter.
|
||||
world.log << dbcon.ErrorMsg()
|
||||
|
||||
return .
|
||||
|
||||
//This proc ensures that the connection to the feedback database (global variable dbcon) is established
|
||||
proc/establish_db_connection()
|
||||
if(failed_db_connections > FAILED_DB_CONNECTION_CUTOFF)
|
||||
return 0
|
||||
|
||||
if(!dbcon || !dbcon.IsConnected())
|
||||
return setup_database_connection()
|
||||
else
|
||||
return 1
|
||||
|
||||
|
||||
/hook/startup/proc/connectOldDB()
|
||||
if(!config.sql_enabled)
|
||||
world.log << "SQL connection disabled in config."
|
||||
else if(!setup_old_database_connection())
|
||||
world.log << "Your server failed to establish a connection with the SQL database."
|
||||
else
|
||||
world.log << "SQL database connection established."
|
||||
return 1
|
||||
|
||||
//These two procs are for the old database, while it's being phased out. See the tgstation.sql file in the SQL folder for more information.
|
||||
proc/setup_old_database_connection()
|
||||
|
||||
if(failed_old_db_connections > FAILED_DB_CONNECTION_CUTOFF) //If it failed to establish a connection more than 5 times in a row, don't bother attempting to conenct anymore.
|
||||
return 0
|
||||
|
||||
if(!dbcon_old)
|
||||
dbcon_old = new()
|
||||
|
||||
var/user = sqllogin
|
||||
var/pass = sqlpass
|
||||
var/db = sqldb
|
||||
var/address = sqladdress
|
||||
var/port = sqlport
|
||||
|
||||
dbcon_old.Connect("dbi:mysql:[db]:[address]:[port]","[user]","[pass]")
|
||||
. = dbcon_old.IsConnected()
|
||||
if ( . )
|
||||
failed_old_db_connections = 0 //If this connection succeeded, reset the failed connections counter.
|
||||
else
|
||||
failed_old_db_connections++ //If it failed, increase the failed connections counter.
|
||||
world.log << dbcon.ErrorMsg()
|
||||
|
||||
return .
|
||||
|
||||
//This proc ensures that the connection to the feedback database (global variable dbcon) is established
|
||||
proc/establish_old_db_connection()
|
||||
if(failed_old_db_connections > FAILED_DB_CONNECTION_CUTOFF)
|
||||
return 0
|
||||
|
||||
if(!dbcon_old || !dbcon_old.IsConnected())
|
||||
return setup_old_database_connection()
|
||||
else
|
||||
return 1
|
||||
|
||||
// Things to do when a new z-level was just made.
|
||||
/world/proc/max_z_changed()
|
||||
if(!istype(GLOB.players_by_zlevel, /list))
|
||||
GLOB.players_by_zlevel = new /list(world.maxz, 0)
|
||||
while(GLOB.players_by_zlevel.len < world.maxz)
|
||||
GLOB.players_by_zlevel.len++
|
||||
GLOB.players_by_zlevel[GLOB.players_by_zlevel.len] = list()
|
||||
|
||||
// Call this to make a new blank z-level, don't modify maxz directly.
|
||||
/world/proc/increment_max_z()
|
||||
maxz++
|
||||
max_z_changed()
|
||||
|
||||
#undef FAILED_DB_CONNECTION_CUTOFF
|
||||
=======
|
||||
>>>>>>> 9ff8103... Merge pull request #5636 from kevinz000/pixel_projectiles
|
||||
|
||||
@@ -16,11 +16,8 @@
|
||||
#include "code\_map_tests.dm"
|
||||
#include "code\_unit_tests.dm"
|
||||
#include "code\global.dm"
|
||||
<<<<<<< HEAD:vorestation.dme
|
||||
#include "code\global_vr.dm"
|
||||
=======
|
||||
#include "code\global_init.dm"
|
||||
>>>>>>> 9ff8103... Merge pull request #5636 from kevinz000/pixel_projectiles:polaris.dme
|
||||
#include "code\global_vr.dm"
|
||||
#include "code\hub.dm"
|
||||
#include "code\names.dm"
|
||||
#include "code\stylesheet.dm"
|
||||
@@ -101,11 +98,7 @@
|
||||
#include "code\_helpers\global_lists.dm"
|
||||
#include "code\_helpers\global_lists_vr.dm"
|
||||
#include "code\_helpers\icons.dm"
|
||||
<<<<<<< HEAD:vorestation.dme
|
||||
#include "code\_helpers\icons_vr.dm"
|
||||
#include "code\_helpers\lists.dm"
|
||||
=======
|
||||
>>>>>>> 9ff8103... Merge pull request #5636 from kevinz000/pixel_projectiles:polaris.dme
|
||||
#include "code\_helpers\logging.dm"
|
||||
#include "code\_helpers\logging_vr.dm"
|
||||
#include "code\_helpers\matrices.dm"
|
||||
@@ -120,12 +113,8 @@
|
||||
#include "code\_helpers\type2type.dm"
|
||||
#include "code\_helpers\type2type_vr.dm"
|
||||
#include "code\_helpers\unsorted.dm"
|
||||
<<<<<<< HEAD:vorestation.dme
|
||||
#include "code\_helpers\unsorted_vr.dm"
|
||||
#include "code\_helpers\vector.dm"
|
||||
=======
|
||||
#include "code\_helpers\view.dm"
|
||||
>>>>>>> 9ff8103... Merge pull request #5636 from kevinz000/pixel_projectiles:polaris.dme
|
||||
#include "code\_helpers\sorts\__main.dm"
|
||||
#include "code\_helpers\sorts\comparators.dm"
|
||||
#include "code\_helpers\sorts\TimSort.dm"
|
||||
|
||||
Reference in New Issue
Block a user