mirror of
https://github.com/goonstation/goonstation-2020.git
synced 2026-07-13 08:02:19 +01:00
678 lines
19 KiB
Plaintext
678 lines
19 KiB
Plaintext
|
|
/*
|
|
replacetext(haystack, needle, replace)
|
|
|
|
Replaces all occurrences of needle in haystack (case-insensitive)
|
|
with replace value.
|
|
|
|
replaceText(haystack, needle, replace)
|
|
|
|
Replaces all occurrences of needle in haystack (case-sensitive)
|
|
with replace value.
|
|
*/
|
|
|
|
var/list/vowels_lower = list("a","e","i","o","u")
|
|
var/list/vowels_upper = list("A","E","I","O","U")
|
|
var/list/consonants_lower = list("b","c","d","f","g","h","j","k","l","m","n","p","q","r","s","t","v","w","x","y","z")
|
|
var/list/consonants_upper = list("B","C","D","F","G","H","J","K","L","M","N","P","Q","R","S","T","V","W","X","Y","Z")
|
|
var/list/symbols = list("!","?",".",",","'","\"","@","#","$","%","^","&","*","+","-","=","_","(",")","<",">","\[","\]",":",";")
|
|
var/list/numbers = list("0","1","2","3","4","5","6","7","8","9")
|
|
|
|
var/list/stinkDescs = list("nasty","unpleasant","foul","horrible","rotten","unholy",
|
|
"repulsive","noxious","putrid","gross","unsavory","fetid","pungent","vulgar")
|
|
var/list/stinkTypes = list("smell","stink","odor","reek","stench","miasma")
|
|
var/list/stinkExclamations = list("Ugh","Good lord","Good grief","Christ","Fuck","Eww")
|
|
var/list/stinkThings = list("garbage can","trash heap","cesspool","toilet","pile of poo",
|
|
"butt","skunk","outhouse","corpse","fart","devil")
|
|
var/list/stinkVerbs = list("took a shit","died","farted","threw up","wiped its ass")
|
|
var/list/stinkThingies = list("ass","taint","armpit","excretions","leftovers","Readster")
|
|
|
|
/proc/stinkString()
|
|
// i am five - ISN
|
|
switch (rand(1,4))
|
|
if (1)
|
|
return "[pick(stinkExclamations)], there's a \a [pick(stinkDescs)] [pick(stinkTypes)] in here..."
|
|
if (2)
|
|
return "[pick(stinkExclamations)], there's a \a [pick(stinkDescs)] [pick(stinkTypes)] in here..."
|
|
if (3)
|
|
return "[pick(stinkExclamations)], it smells like \a [pick(stinkThings)] [pick(stinkVerbs)] in here!"
|
|
else
|
|
return "[pick(stinkExclamations)], it smells like \a [pick(stinkThings)]'s [pick(stinkThingies)] in here!"
|
|
|
|
//For fuck's sake.
|
|
/*
|
|
/proc/bubblesort(list/L)
|
|
var i, j
|
|
for(i=L.len, i>0, i--)
|
|
for(j=1, j<i, j++)
|
|
if(L[j] > L[j+1])
|
|
L.Swap(j, j+1)
|
|
return L
|
|
*/
|
|
/proc/get_local_apc(O)
|
|
var/turf/T = get_turf(O)
|
|
if (!T)
|
|
return null
|
|
var/area/A = T.loc
|
|
|
|
if (A.type == /area)
|
|
// dont search space for an apc
|
|
return null
|
|
|
|
for (var/obj/machinery/power/apc/APC in A.contents)
|
|
if (!(APC.status & BROKEN))
|
|
return APC
|
|
|
|
// Lots and lots of APCs use area strings to make the blowout random event possible.
|
|
for (var/obj/machinery/power/apc/APC2 in machines)
|
|
var/area/A2 = null
|
|
if (!isnull(APC2.areastring))
|
|
A2 = get_area_name(APC2.areastring)
|
|
if (!isnull(A2) && istype(A2) && A == A2 && !(APC2.status & BROKEN))
|
|
return APC2
|
|
|
|
return null
|
|
|
|
/proc/get_area_name(N) //get area by it's name
|
|
|
|
for(var/area/A in world)
|
|
LAGCHECK(LAG_LOW)
|
|
if(A.name == N)
|
|
return A
|
|
return 0
|
|
|
|
/proc/get_area_by_type(var/type_path)
|
|
if (!ispath(type_path))
|
|
return null
|
|
|
|
for (var/area/A in world)
|
|
LAGCHECK(LAG_LOW)
|
|
if (A.type == type_path)
|
|
return A
|
|
|
|
return null
|
|
|
|
/proc/in_range(atom/source, atom/user)
|
|
if(bounds_dist(source, user) == 0 || get_dist(source, user) <= 1) // fucking byond
|
|
return 1
|
|
else if (source in bible_contents && locate(/obj/item/storage/bible) in range(1, user)) // whoever added the global bibles, fuck you
|
|
return 1
|
|
else
|
|
if (iscarbon(user))
|
|
var/mob/living/carbon/C = user
|
|
if (C.bioHolder.HasEffect("telekinesis") && get_dist(source, user) <= 7) //You can only reach stuff within your screen.
|
|
var/X = source:x
|
|
var/Y = source:y
|
|
var/Z = source:z
|
|
if (isrestrictedz(Z) || isrestrictedz(user:z))
|
|
boutput(user, "<span style=\"color:red\">Your telekinetic powers don't seem to work here.</span>")
|
|
return 0
|
|
SPAWN_DBG(0)
|
|
//I really shouldnt put this here but i dont have a better idea
|
|
var/obj/overlay/O = new /obj/overlay ( locate(X,Y,Z) )
|
|
O.name = "sparkles"
|
|
O.anchored = 1
|
|
O.set_density(0)
|
|
O.layer = FLY_LAYER
|
|
O.dir = pick(cardinal)
|
|
O.icon = 'icons/effects/effects.dmi'
|
|
O.icon_state = "nothing"
|
|
flick("empdisable",O)
|
|
SPAWN_DBG(5 DECI SECONDS)
|
|
qdel(O)
|
|
|
|
return 1
|
|
if (istype(source, /obj/machinery) && isAI(user))
|
|
return 1
|
|
|
|
return 0 //not in range and not telekinetic
|
|
|
|
|
|
var/obj/item/dummy/click_dummy = new
|
|
/proc/test_click(turf/from, turf/target)
|
|
for (var/atom/A in from)
|
|
if (A.flags & ON_BORDER)
|
|
if (!A.CheckExit(click_dummy, target))
|
|
return 0
|
|
for (var/atom/A in target)
|
|
if (A.flags & ON_BORDER)
|
|
if (!A.CanPass(click_dummy, from, 1, 0))
|
|
return 0
|
|
return 1
|
|
|
|
/proc/can_reach(mob/user, atom/target)
|
|
if (target in bible_contents)
|
|
target = locate(/obj/item/storage/bible) in range(1, user) // fuck bibles
|
|
if (!target)
|
|
return 0
|
|
var/turf/UT = get_turf(user)
|
|
var/turf/TT = get_turf(target)
|
|
if (TT)
|
|
var/obj/cover/C = locate() in TT
|
|
if (C && target != C)
|
|
return 0
|
|
if (UT && TT != UT)
|
|
var/obj/cover/C = locate() in UT
|
|
if (C && target != C)
|
|
return 0
|
|
if (isturf(user.loc))
|
|
if (!in_range(target, user))
|
|
return 0
|
|
var/T1 = get_turf(user)
|
|
var/T2 = get_turf(target)
|
|
if (T1 == T2)
|
|
return 1
|
|
else
|
|
if (!click_dummy)
|
|
click_dummy = new
|
|
|
|
var/dir = get_dir(T1, T2)
|
|
if (dir & (dir-1))
|
|
var/dir1, dir2
|
|
switch (dir)
|
|
if (NORTHEAST)
|
|
dir1 = NORTH
|
|
dir2 = EAST
|
|
if (NORTHWEST)
|
|
dir1 = NORTH
|
|
dir2 = WEST
|
|
if (SOUTHEAST)
|
|
dir1 = SOUTH
|
|
dir2 = EAST
|
|
if (SOUTHWEST)
|
|
dir1 = SOUTH
|
|
dir2 = WEST
|
|
var/D1 = get_step(T1, dir1)
|
|
var/D2 = get_step(T1, dir2)
|
|
|
|
if (test_click(T1, D1))
|
|
if ((target.flags & ON_BORDER) || test_click(D1, T2))
|
|
return 1
|
|
if (test_click(T1, D2))
|
|
if ((target.flags & ON_BORDER) || test_click(D2, T2))
|
|
return 1
|
|
else
|
|
return (target.flags & ON_BORDER) || test_click(T1, T2)
|
|
else if (isobj(target) || ismob(target))
|
|
var/atom/L = target.loc
|
|
while (L && !isturf(L))
|
|
if (L == user)
|
|
return 1
|
|
L = L.loc
|
|
return 0
|
|
|
|
/proc/AutoUpdateAI(obj/subject)
|
|
if (!subject)
|
|
return
|
|
for(var/mob/living/silicon/ai/M in mobs)
|
|
var/mob/AI = M
|
|
if (M.deployed_to_eyecam)
|
|
AI = M.eyecam
|
|
|
|
if (AI && AI.client && AI.machine == subject)
|
|
subject.attack_ai(AI)
|
|
|
|
/proc/get_viewing_AIs(center = null, distance = world.view)
|
|
. = list()
|
|
|
|
for (var/mob/living/silicon/ai/theAI in AIs)
|
|
if (theAI.deployed_to_eyecam)
|
|
var/mob/dead/aieye/AIeye = theAI.eyecam
|
|
if (AIeye in view(center, distance))
|
|
. += AIeye
|
|
. += theAI
|
|
//if (istype(theAI.current) && (theAI.current in view(center, distance)) )
|
|
// . += theAI
|
|
|
|
//Kinda sorta like viewers but includes observers. In theory.
|
|
/proc/observersviewers(var/Dist=world.view, var/Center=usr)
|
|
var/list/viewMobs = viewers(Dist, Center)
|
|
|
|
for(var/mob/dead/target_observer/M in observers)
|
|
if(!M.client) continue
|
|
if(M.target in view(Dist, Center) || M.target == Center)
|
|
viewMobs += M
|
|
|
|
return viewMobs
|
|
|
|
/proc/AIviewers(Depth=world.view,Center=usr)
|
|
if (istype(Depth, /atom))
|
|
var/newDepth = isnum(Center) ? Center : world.view
|
|
Center = Depth
|
|
Depth = newDepth
|
|
|
|
return viewers(Depth, Center) + get_viewing_AIs(Center, Depth)
|
|
|
|
//A unique network ID for devices that could use one
|
|
/proc/format_net_id(var/refstring)
|
|
if(!refstring)
|
|
return
|
|
. = copytext(refstring,4,(length(refstring)))
|
|
. = add_zero(., 8)
|
|
|
|
|
|
//A little wrapper around format_net_id to account for non-null tag values
|
|
/proc/generate_net_id(var/atom/the_atom)
|
|
if(!the_atom) return
|
|
var/tag_holder = the_atom.tag
|
|
the_atom.tag = null //So we generate from internal ref id
|
|
. = format_net_id("\ref[the_atom]")
|
|
the_atom.tag = tag_holder
|
|
|
|
/proc/can_act(var/mob/M, var/include_cuffs = 1)
|
|
if(!M) return 0 //Please pass the M, I need a sprinkle of it on my potatoes.
|
|
if(include_cuffs && M.handcuffed) return 0
|
|
if(M.getStatusDuration("stunned")) return 0
|
|
if(M.getStatusDuration("weakened")) return 0
|
|
if(M.getStatusDuration("paralysis")) return 0
|
|
if(M.stat) return 0
|
|
return 1
|
|
|
|
#define CLUWNE_NOISE_DELAY 50
|
|
|
|
/proc/process_accents(var/mob/living/carbon/human/H, var/message)
|
|
if (!H || !istext(message))
|
|
return
|
|
|
|
if (H.bioHolder && !H.speech_void)
|
|
var/datum/bioEffect/speech/S = null
|
|
for(var/X in H.bioHolder.effects)
|
|
S = H.bioHolder.GetEffect(X)
|
|
if (istype(S,/datum/bioEffect/speech/))
|
|
message = S.OnSpeak(message)
|
|
|
|
if (H.grabbed_by && H.grabbed_by.len)
|
|
for (var/obj/item/grab/rag_muffle/RM in H.grabbed_by)
|
|
if (RM.state > 0)
|
|
message = mufflespeech(message)
|
|
break
|
|
|
|
if (iscluwne(H))
|
|
message = honk(message)
|
|
if (world.time >= (H.last_cluwne_noise + CLUWNE_NOISE_DELAY))
|
|
playsound(get_turf(H), pick("sound/voice/cluwnelaugh1.ogg","sound/voice/cluwnelaugh2.ogg","sound/voice/cluwnelaugh3.ogg"), 70, 0, 0, H.get_age_pitch())
|
|
H.last_cluwne_noise = world.time
|
|
if (ishorse(H))
|
|
message = neigh(message)
|
|
if (world.time >= (H.last_cluwne_noise + CLUWNE_NOISE_DELAY))
|
|
playsound(get_turf(H), pick("sound/voice/cluwnelaugh1.ogg","sound/voice/cluwnelaugh2.ogg","sound/voice/cluwnelaugh3.ogg"), 70, 0, 0, H.get_age_pitch())
|
|
H.last_cluwne_noise = world.time
|
|
|
|
if ((H.reagents && H.reagents.get_reagent_amount("ethanol") > 30 && !isdead(H)) || H.traitHolder.hasTrait("alcoholic"))
|
|
if((H.reagents.get_reagent_amount("ethanol") > 125 && prob(20)))
|
|
message = say_superdrunk(message)
|
|
else
|
|
message = say_drunk(message)
|
|
|
|
var/datum/ailment_data/disease/berserker = H.find_ailment_by_type(/datum/ailment/disease/berserker/)
|
|
if (istype(berserker,/datum/ailment_data/disease/) && berserker.stage > 1)
|
|
if (prob(10))
|
|
message = say_furious(message)
|
|
message = replacetext(message, ".", "!")
|
|
message = replacetext(message, ",", "!")
|
|
message = replacetext(message, "?", "!")
|
|
message = uppertext(message)
|
|
var/addexc = rand(2,6)
|
|
while (addexc > 0)
|
|
message += "!"
|
|
--addexc
|
|
|
|
if(H.bioHolder && H.bioHolder.genetic_stability < 50)
|
|
if (prob(40))
|
|
message = say_gurgle(message)
|
|
|
|
if(H.mutantrace && !isdead(H))
|
|
message = H.mutantrace.say_filter(message)
|
|
|
|
if(HasturPresent == 1)
|
|
message = replacetext(message, "Hastur", "????")
|
|
message = replacetext(message, "H.a.s.t.u.r", "????")
|
|
message = replacetext(message, "H.astur", "????")
|
|
message = replacetext(message, "H.a.stur", "????")
|
|
message = replacetext(message, "H.a.s.tur", "????")
|
|
message = replacetext(message, "H.a.s.t.ur", "????")
|
|
message = replacetext(message, "H-a-s-t-u-r", "????")
|
|
message = replacetext(message, "H-astur", "????")
|
|
message = replacetext(message, "H-a-stur", "????")
|
|
message = replacetext(message, "H-a-s-tur", "????")
|
|
message = replacetext(message, "H-a-s-t-ur", "????")
|
|
message = replacetext(message, "H a s t u r", "????")
|
|
message = replacetext(message, "H astur", "????")
|
|
message = replacetext(message, "H a s tur", "????")
|
|
message = replacetext(message, "H a s t ur", "????")
|
|
|
|
#ifdef CANADADAY
|
|
if (prob(30)) message = replacetext(message, "?", " Eh?")
|
|
#endif
|
|
|
|
return message
|
|
|
|
|
|
/proc/can_see(var/atom/source, var/atom/target, var/length=5) // I couldnt be arsed to do actual raycasting :I This is horribly inaccurate.
|
|
var/turf/current = get_turf(source)
|
|
var/turf/target_turf = get_turf(target)
|
|
var/steps = 0
|
|
|
|
while(current != target_turf)
|
|
if(steps > length) return 0
|
|
if(!current) return 0
|
|
if(current.opacity) return 0
|
|
for(var/atom/A in current)
|
|
if(A.opacity) return 0
|
|
current = get_step_towards(current, target_turf)
|
|
steps++
|
|
|
|
return 1
|
|
|
|
|
|
/mob/proc/get_equipped_items()
|
|
. = list()
|
|
if(src.back) . += src.back
|
|
if(src.ears) . += src.ears
|
|
if(src.wear_mask) . += src.wear_mask
|
|
|
|
if(src.l_hand && src.l_hand.c_flags & EQUIPPED_WHILE_HELD) . += src.l_hand
|
|
if(src.r_hand && src.r_hand.c_flags & EQUIPPED_WHILE_HELD) . += src.r_hand
|
|
|
|
|
|
/proc/get_step_towards2(var/atom/ref , var/atom/trg)
|
|
var/base_dir = get_dir(ref, get_step_towards(ref,trg))
|
|
var/turf/temp = get_step_towards(ref,trg)
|
|
|
|
if(is_blocked_turf(temp))
|
|
var/dir_alt1 = turn(base_dir, 90)
|
|
var/dir_alt2 = turn(base_dir, -90)
|
|
var/turf/turf_last1 = temp
|
|
var/turf/turf_last2 = temp
|
|
var/free_tile = null
|
|
var/breakpoint = 0
|
|
|
|
while(!free_tile && breakpoint < 10)
|
|
if(!is_blocked_turf(turf_last1))
|
|
free_tile = turf_last1
|
|
break
|
|
if(!is_blocked_turf(turf_last2))
|
|
free_tile = turf_last2
|
|
break
|
|
turf_last1 = get_step(turf_last1,dir_alt1)
|
|
turf_last2 = get_step(turf_last2,dir_alt2)
|
|
breakpoint++
|
|
|
|
if(!free_tile) return get_step(ref, base_dir)
|
|
else return get_step_towards(ref,free_tile)
|
|
|
|
else return get_step(ref, base_dir)
|
|
|
|
/proc/get_areas(var/areatype)
|
|
//Takes: Area type as text string or as typepath OR an instance of the area.
|
|
//Returns: A list of all areas of that type in the world.
|
|
//Notes: Simple!
|
|
if(!areatype) return null
|
|
if(istext(areatype)) areatype = text2path(areatype)
|
|
if(isarea(areatype))
|
|
var/area/areatemp = areatype
|
|
areatype = areatemp.type
|
|
|
|
. = new/list()
|
|
|
|
for(var/area/R in world)
|
|
LAGCHECK(LAG_LOW)
|
|
if(istype(R, areatype))
|
|
. += R
|
|
|
|
/proc/get_areas_with_turfs(var/areatype)
|
|
//Takes: Area type as text string or as typepath OR an instance of the area.
|
|
//Returns: A list of all areas of that type in the world.
|
|
//Notes: Simple!
|
|
if(!areatype) return null
|
|
if(istext(areatype)) areatype = text2path(areatype)
|
|
if(isarea(areatype))
|
|
var/area/areatemp = areatype
|
|
areatype = areatemp.type
|
|
|
|
. = new/list()
|
|
|
|
for(var/area/R in world)
|
|
LAGCHECK(LAG_LOW)
|
|
if(istype(R, areatype))
|
|
for (var/turf/T in R)
|
|
. += R
|
|
break
|
|
|
|
/proc/get_area_turfs(var/areatype, var/floors_only)
|
|
//Takes: Area type as text string or as typepath OR an instance of the area.
|
|
//Returns: A list of all turfs in areas of that type of that type in the world.
|
|
//Notes: Simple!
|
|
|
|
if(!areatype)
|
|
return null
|
|
if(istext(areatype)) areatype = text2path(areatype)
|
|
if(isarea(areatype))
|
|
var/area/areatemp = areatype
|
|
areatype = areatemp.type
|
|
|
|
. = new/list()
|
|
var/list/areas = get_areas(areatype)
|
|
for(var/area/R in areas)
|
|
for(var/turf/T in R)
|
|
if(floors_only && (!isfloor(T) || is_blocked_turf(T)))
|
|
continue
|
|
. += T
|
|
|
|
/proc/get_area_all_atoms(var/areatype)
|
|
//Takes: Area type as text string or as typepath OR an instance of the area.
|
|
//Returns: A list of all atoms (objs, turfs, mobs) in areas of that type of that type in the world.
|
|
//Notes: Simple!
|
|
|
|
if(!areatype) return null
|
|
if(istext(areatype)) areatype = text2path(areatype)
|
|
if(isarea(areatype))
|
|
var/area/areatemp = areatype
|
|
areatype = areatemp.type
|
|
|
|
. = new/list()
|
|
var/list/areas = get_areas(areatype)
|
|
for(var/area/R in areas)
|
|
for(var/atom/A in R)
|
|
. += A
|
|
|
|
/datum/coords //Simple datum for storing coordinates.
|
|
var/x_pos = null
|
|
var/y_pos = null
|
|
var/z_pos = null
|
|
|
|
|
|
/datum/color //Simple datum for RGBA colours
|
|
// used as an alternative to rgb() proc
|
|
// for ease of access to components
|
|
var/r = null // all stored as 0-255
|
|
var/g = null
|
|
var/b = null
|
|
var/a = null
|
|
|
|
New(_r,_g,_b,_a=255)
|
|
r = _r
|
|
g = _g
|
|
b = _b
|
|
a = _a
|
|
|
|
proc/from_hex(var/hexstr)
|
|
r = GetRedPart(hexstr)
|
|
g = GetGreenPart(hexstr)
|
|
b = GetBluePart(hexstr)
|
|
a = 255
|
|
return
|
|
|
|
// return in #RRGGBB hex form
|
|
proc/to_rgb()
|
|
return rgb(r,g,b)
|
|
|
|
// return in #RRGGBBAA hex form
|
|
proc/to_rgba()
|
|
return rgb(r,g,b,a)
|
|
|
|
|
|
/area/proc/move_contents_to(var/area/A, var/turftoleave=null, var/ignore_fluid = 0)
|
|
set waitfor = 0
|
|
|
|
//Takes: Area. Optional: turf type to leave behind.
|
|
//Returns: Nothing.
|
|
//Notes: Attempts to move the contents of one area to another area.
|
|
// Movement based on lower left corner. Tiles that do not fit
|
|
// into the new area will not be moved.
|
|
|
|
var/testmove = 0
|
|
|
|
|
|
// if(prob(5)) testmove = 1
|
|
|
|
if(!A || !src) return 0
|
|
|
|
var/list/turfs_src = get_area_turfs(src.type)
|
|
var/list/turfs_trg = get_area_turfs(A.type)
|
|
|
|
var/src_min_x = 0
|
|
var/src_min_y = 0
|
|
for (var/turf/T in turfs_src)
|
|
if(T.x < src_min_x || !src_min_x) src_min_x = T.x
|
|
if(T.y < src_min_y || !src_min_y) src_min_y = T.y
|
|
|
|
DEBUG_MESSAGE("src_min_x = [src_min_x], src_min_y = [src_min_y]")
|
|
var/trg_min_x = 0
|
|
var/trg_min_y = 0
|
|
for (var/turf/T in turfs_trg)
|
|
if(T.x < trg_min_x || !trg_min_x) trg_min_x = T.x
|
|
if(T.y < trg_min_y || !trg_min_y) trg_min_y = T.y
|
|
|
|
DEBUG_MESSAGE("trg_min_x = [src_min_x], trg_min_y = [src_min_y]")
|
|
|
|
var/list/refined_src = new/list()
|
|
for(var/turf/T in turfs_src)
|
|
refined_src += T
|
|
refined_src[T] = new/datum/coords
|
|
var/datum/coords/C = refined_src[T]
|
|
C.x_pos = (T.x - src_min_x)
|
|
C.y_pos = (T.y - src_min_y)
|
|
|
|
var/list/refined_trg = new/list()
|
|
for(var/turf/T in turfs_trg)
|
|
refined_trg += T
|
|
refined_trg[T] = new/datum/coords
|
|
var/datum/coords/C = refined_trg[T]
|
|
C.x_pos = (T.x - trg_min_x)
|
|
C.y_pos = (T.y - trg_min_y)
|
|
|
|
var/list/fromupdate = new/list()
|
|
var/list/toupdate = new/list()
|
|
|
|
moving:
|
|
for (var/turf/T in refined_src)
|
|
var/datum/coords/C_src = refined_src[T]
|
|
for (var/turf/B in refined_trg)
|
|
var/datum/coords/C_trg = refined_trg[B]
|
|
if(C_src.x_pos == C_trg.x_pos && C_src.y_pos == C_trg.y_pos)
|
|
|
|
var/old_app = T.appearance
|
|
var/olddir = T.dir
|
|
//var/old_icon_state1 = T.icon_state
|
|
|
|
var/turf/X
|
|
if(testmove) X = new T.type(get_step(B,pick(cardinal))) //remove this
|
|
else X = new T.type (B)
|
|
X.appearance = old_app
|
|
X.dir = olddir
|
|
//X.icon_state = old_icon_state1
|
|
|
|
for(var/obj/O in T)
|
|
if (!istype(O, /obj) || istype(O, /obj/forcefield) || istype(O, /obj/overlay/tile_effect)) continue
|
|
if (!ignore_fluid && istype(O, /obj/fluid)) continue
|
|
O.set_loc(X)
|
|
for(var/mob/M in T)
|
|
DEBUG_MESSAGE("Moving mob [M] from [T] to [X].")
|
|
if(!ismob(M)) continue
|
|
M.set_loc(X)
|
|
|
|
toupdate += X
|
|
|
|
if(turftoleave)
|
|
var/turf/ttl = new turftoleave(T)
|
|
|
|
fromupdate += ttl
|
|
|
|
else
|
|
T.ReplaceWithSpace()
|
|
|
|
refined_src -= T
|
|
refined_trg -= B
|
|
continue moving
|
|
|
|
var/list/doors = new/list()
|
|
|
|
if(toupdate.len)
|
|
for(var/turf/simulated/T1 in toupdate)
|
|
for(var/obj/machinery/door/D2 in T1)
|
|
doors += D2
|
|
if(T1.parent)
|
|
air_master.queue_update_group(T1.parent)
|
|
else
|
|
air_master.queue_update_tile(T1)
|
|
|
|
if(fromupdate.len)
|
|
for(var/turf/simulated/T2 in fromupdate)
|
|
for(var/obj/machinery/door/D2 in T2)
|
|
doors += D2
|
|
if(T2.parent)
|
|
air_master.queue_update_group(T2.parent)
|
|
else
|
|
air_master.queue_update_tile(T2)
|
|
|
|
for(var/obj/O in doors)
|
|
O:update_nearby_tiles(1)
|
|
|
|
|
|
|
|
// return description of how full a container is
|
|
proc/get_fullness(var/percent)
|
|
|
|
if(percent == 0)
|
|
return "empty"
|
|
if(percent < 2)
|
|
return "nearly empty"
|
|
if(percent < 24)
|
|
return "less than a quarter full"
|
|
if(percent < 26)
|
|
return "a quarter full"
|
|
if(percent < 37)
|
|
return "more than a quarter full"
|
|
if(percent < 49)
|
|
return "less than half full"
|
|
if(percent < 51)
|
|
return "half full"
|
|
if(percent < 62)
|
|
return "more than half full"
|
|
if(percent < 74)
|
|
return "less than three-quarters full"
|
|
if(percent < 76)
|
|
return "three-quarters full"
|
|
if(percent < 97)
|
|
return "more than three-quarters full"
|
|
if(percent < 99.5)
|
|
return "nearly full"
|
|
return "full"
|
|
|
|
// return description of transparency/opaqueness
|
|
|
|
proc/get_opaqueness(var/trans) // 0=transparent, 255=fully opaque
|
|
if(trans < 25)
|
|
return "clear"
|
|
if(trans < 60)
|
|
return "transparent"
|
|
if(trans< 150)
|
|
return "mostly transparent"
|
|
if(trans <200)
|
|
return "dense"
|
|
return "opaque"
|
|
|
|
proc/LoadSavefile(name)
|
|
. = new/savefile(name)
|