Merge branch 'master' into upstream-merge-31913
This commit is contained in:
@@ -1,38 +1,38 @@
|
||||
//See controllers/globals.dm
|
||||
#define GLOBAL_MANAGED(X, InitValue)\
|
||||
/datum/controller/global_vars/proc/InitGlobal##X(){\
|
||||
##X = ##InitValue;\
|
||||
gvars_datum_init_order += #X;\
|
||||
}
|
||||
#define GLOBAL_UNMANAGED(X, InitValue) /datum/controller/global_vars/proc/InitGlobal##X()
|
||||
|
||||
#ifndef TESTING
|
||||
#define GLOBAL_PROTECT(X)\
|
||||
/datum/controller/global_vars/InitGlobal##X(){\
|
||||
..();\
|
||||
gvars_datum_protected_varlist += #X;\
|
||||
}
|
||||
#else
|
||||
#define GLOBAL_PROTECT(X)
|
||||
#endif
|
||||
|
||||
#define GLOBAL_REAL_VAR(X) var/global/##X
|
||||
#define GLOBAL_REAL(X, Typepath) var/global##Typepath/##X
|
||||
|
||||
#define GLOBAL_RAW(X) /datum/controller/global_vars/var/global##X
|
||||
|
||||
#define GLOBAL_VAR_INIT(X, InitValue) GLOBAL_RAW(/##X); GLOBAL_MANAGED(X, InitValue)
|
||||
|
||||
#define GLOBAL_VAR_CONST(X, InitValue) GLOBAL_RAW(/const/##X) = InitValue; GLOBAL_UNMANAGED(X, InitValue)
|
||||
|
||||
#define GLOBAL_LIST_INIT(X, InitValue) GLOBAL_RAW(/list/##X); GLOBAL_MANAGED(X, InitValue)
|
||||
|
||||
#define GLOBAL_LIST_EMPTY(X) GLOBAL_LIST_INIT(X, list())
|
||||
|
||||
#define GLOBAL_DATUM_INIT(X, Typepath, InitValue) GLOBAL_RAW(Typepath/##X); GLOBAL_MANAGED(X, InitValue)
|
||||
|
||||
#define GLOBAL_VAR(X) GLOBAL_RAW(/##X); GLOBAL_MANAGED(X, null)
|
||||
|
||||
#define GLOBAL_LIST(X) GLOBAL_RAW(/list/##X); GLOBAL_MANAGED(X, null)
|
||||
|
||||
#define GLOBAL_DATUM(X, Typepath) GLOBAL_RAW(Typepath/##X); GLOBAL_MANAGED(X, null)
|
||||
//See controllers/globals.dm
|
||||
#define GLOBAL_MANAGED(X, InitValue)\
|
||||
/datum/controller/global_vars/proc/InitGlobal##X(){\
|
||||
##X = ##InitValue;\
|
||||
gvars_datum_init_order += #X;\
|
||||
}
|
||||
#define GLOBAL_UNMANAGED(X) /datum/controller/global_vars/proc/InitGlobal##X() { return; }
|
||||
|
||||
#ifndef TESTING
|
||||
#define GLOBAL_PROTECT(X)\
|
||||
/datum/controller/global_vars/InitGlobal##X(){\
|
||||
..();\
|
||||
gvars_datum_protected_varlist += #X;\
|
||||
}
|
||||
#else
|
||||
#define GLOBAL_PROTECT(X)
|
||||
#endif
|
||||
|
||||
#define GLOBAL_REAL_VAR(X) var/global/##X
|
||||
#define GLOBAL_REAL(X, Typepath) var/global##Typepath/##X
|
||||
|
||||
#define GLOBAL_RAW(X) /datum/controller/global_vars/var/global##X
|
||||
|
||||
#define GLOBAL_VAR_INIT(X, InitValue) GLOBAL_RAW(/##X); GLOBAL_MANAGED(X, InitValue)
|
||||
|
||||
#define GLOBAL_VAR_CONST(X, InitValue) GLOBAL_RAW(/const/##X) = InitValue; GLOBAL_UNMANAGED(X)
|
||||
|
||||
#define GLOBAL_LIST_INIT(X, InitValue) GLOBAL_RAW(/list/##X); GLOBAL_MANAGED(X, InitValue)
|
||||
|
||||
#define GLOBAL_LIST_EMPTY(X) GLOBAL_LIST_INIT(X, list())
|
||||
|
||||
#define GLOBAL_DATUM_INIT(X, Typepath, InitValue) GLOBAL_RAW(Typepath/##X); GLOBAL_MANAGED(X, InitValue)
|
||||
|
||||
#define GLOBAL_VAR(X) GLOBAL_RAW(/##X); GLOBAL_UNMANAGED(X)
|
||||
|
||||
#define GLOBAL_LIST(X) GLOBAL_RAW(/list/##X); GLOBAL_UNMANAGED(X)
|
||||
|
||||
#define GLOBAL_DATUM(X, Typepath) GLOBAL_RAW(Typepath/##X); GLOBAL_UNMANAGED(X)
|
||||
|
||||
@@ -468,4 +468,6 @@ GLOBAL_LIST_INIT(ghost_others_options, list(GHOST_OTHERS_SIMPLE, GHOST_OTHERS_DE
|
||||
#define DUMMY_HUMAN_SLOT_MANIFEST "dummy_manifest_generation"
|
||||
|
||||
#define PR_ANNOUNCEMENTS_PER_ROUND 5 //The number of unique PR announcements allowed per round
|
||||
//This makes sure that a single person can only spam 3 reopens and 3 closes before being ignored
|
||||
//This makes sure that a single person can only spam 3 reopens and 3 closes before being ignored
|
||||
|
||||
#define MAX_PROC_DEPTH 195 // 200 proc calls deep and shit breaks, this is a bit lower to give some safety room
|
||||
@@ -40,7 +40,7 @@ GLOBAL_LIST_INIT(special_roles, list(
|
||||
ROLE_ALIEN,
|
||||
ROLE_PAI,
|
||||
ROLE_CULTIST = /datum/game_mode/cult,
|
||||
ROLE_BLOB = /datum/game_mode/blob,
|
||||
ROLE_BLOB,
|
||||
ROLE_NINJA,
|
||||
ROLE_MONKEY = /datum/game_mode/monkey,
|
||||
ROLE_REVENANT,
|
||||
|
||||
@@ -503,12 +503,22 @@ Turf and target are separate in case you want to teleport some distance from a t
|
||||
var/y=arcsin(x/sqrt(1+x*x))
|
||||
return y
|
||||
|
||||
/atom/proc/GetAllContents(list/output=list())
|
||||
/*
|
||||
Recursively gets all contents of contents and returns them all in a list.
|
||||
|
||||
recursive_depth is useful if you only want a turf and everything on it (recursive_depth=1)
|
||||
Do not set recursive depth higher than MAX_PROC_DEPTH as byond breaks when that limit is reached.
|
||||
*/
|
||||
/atom/proc/GetAllContents(list/output=list(), recursive_depth=MAX_PROC_DEPTH, _current_depth=0)
|
||||
. = output
|
||||
output += src
|
||||
if(_current_depth == recursive_depth)
|
||||
if(_current_depth == MAX_PROC_DEPTH)
|
||||
WARNING("Get all contents reached the max recursive depth of [MAX_PROC_DEPTH]. More and we would break shit. Offending atom: [src]")
|
||||
return
|
||||
for(var/i in 1 to contents.len)
|
||||
var/atom/thing = contents[i]
|
||||
thing.GetAllContents(output)
|
||||
thing.GetAllContents(output, recursive_depth, ++_current_depth)
|
||||
|
||||
//Step-towards method of determining whether one atom can see another. Similar to viewers()
|
||||
/proc/can_see(atom/source, atom/target, length=5) // I couldnt be arsed to do actual raycasting :I This is horribly inaccurate.
|
||||
|
||||
@@ -190,13 +190,15 @@
|
||||
needs_permit = 0
|
||||
mag_type = /obj/item/ammo_box/magazine/toy/x9
|
||||
casing_ejector = 0
|
||||
spread = 45 //MAXIMUM XCOM MEMES (actually that'd be 90 spread)
|
||||
spread = 90 //MAXIMUM XCOM MEMES (actually that'd be 180 spread)
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
weapon_weight = WEAPON_HEAVY
|
||||
|
||||
/datum/design/foam_x9
|
||||
name = "Foam Force X9 Rifle"
|
||||
id = "foam_x9"
|
||||
build_type = AUTOLATHE
|
||||
materials = list(MAT_METAL = 20000, MAT_GLASS = 10000)
|
||||
materials = list(MAT_METAL = 24000, MAT_GLASS = 14000)
|
||||
build_path = /obj/item/gun/ballistic/automatic/x9/toy
|
||||
category = list("hacked", "Misc")
|
||||
|
||||
@@ -496,6 +498,9 @@
|
||||
mag_type = /obj/item/ammo_box/magazine/toy/foamag
|
||||
casing_ejector = FALSE
|
||||
origin_tech = "combat=2;engineering=2;magnets=2"
|
||||
spread = 60
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
weapon_weight = WEAPON_HEAVY
|
||||
|
||||
/datum/design/foam_magrifle
|
||||
name = "Foam Force MagRifle"
|
||||
@@ -635,7 +640,7 @@
|
||||
name = "MagTag Hyper Rifle"
|
||||
id = "foam_hyperburst"
|
||||
build_type = AUTOLATHE
|
||||
materials = list(MAT_METAL = 35000, MAT_GLASS = 15000)
|
||||
materials = list(MAT_METAL = 35000, MAT_GLASS = 25000)
|
||||
build_path = /obj/item/gun/energy/laser/practice/hyperburst
|
||||
category = list("hacked", "Misc")
|
||||
|
||||
@@ -680,6 +685,7 @@
|
||||
suppressed = TRUE
|
||||
burst_size = 1
|
||||
fire_delay = 0
|
||||
spread = 60
|
||||
actions_types = list()
|
||||
|
||||
/obj/item/gun/ballistic/automatic/toy/pistol/stealth/update_icon()
|
||||
@@ -695,7 +701,7 @@
|
||||
name = "Foam Force Stealth Pistol"
|
||||
id = "foam_sp"
|
||||
build_type = AUTOLATHE
|
||||
materials = list(MAT_METAL = 15000, MAT_GLASS = 1000)
|
||||
materials = list(MAT_METAL = 30000, MAT_GLASS = 15000)
|
||||
build_path = /obj/item/gun/ballistic/automatic/toy/pistol/stealth
|
||||
category = list("hacked", "Misc")
|
||||
|
||||
|
||||
@@ -86,8 +86,9 @@ GLOBAL_REAL(Master, /datum/controller/master) = new
|
||||
sortTim(subsystems, /proc/cmp_subsystem_init)
|
||||
reverseRange(subsystems)
|
||||
for(var/datum/controller/subsystem/ss in subsystems)
|
||||
testing("Shutdown [ss.name] subsystem")
|
||||
log_world("Shutting down [ss.name] subsystem...")
|
||||
ss.Shutdown()
|
||||
log_world("Shutdown complete")
|
||||
|
||||
// Returns 1 if we created a new mc, 0 if we couldn't due to a recent restart,
|
||||
// -1 if we encountered a runtime trying to recreate it
|
||||
@@ -595,4 +596,4 @@ GLOBAL_REAL(Master, /datum/controller/master) = new
|
||||
if (client_count < CONFIG_GET(number/mc_tick_rate/disable_high_pop_mc_mode_amount))
|
||||
processing = CONFIG_GET(number/mc_tick_rate/base_mc_tick_rate)
|
||||
else if (client_count > CONFIG_GET(number/mc_tick_rate/high_pop_mc_mode_amount))
|
||||
processing = CONFIG_GET(number/mc_tick_rate/high_pop_mc_tick_rate)
|
||||
processing = CONFIG_GET(number/mc_tick_rate/high_pop_mc_tick_rate)
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
/datum/antagonist/brother/on_gain()
|
||||
SSticker.mode.brothers += owner
|
||||
owner.objectives += team.objectives
|
||||
owner.special_role = special_role
|
||||
finalize_brother()
|
||||
return ..()
|
||||
|
||||
|
||||
@@ -1,72 +0,0 @@
|
||||
/datum/game_mode/blob/check_finished()
|
||||
if(blobwincount <= GLOB.blobs_legit.len)//Blob took over
|
||||
return 1
|
||||
for(var/datum/mind/blob in blob_overminds)
|
||||
if(isovermind(blob.current))
|
||||
var/mob/camera/blob/B = blob.current
|
||||
if(B.blob_core || !B.placed)
|
||||
return 0
|
||||
if(!GLOB.blob_cores.len) //blob is dead
|
||||
if(CONFIG_GET(keyed_flag_list/continuous)["blob"])
|
||||
message_sent = FALSE //disable the win count at this point
|
||||
continuous_sanity_checked = 1 //Nonstandard definition of "alive" gets past the check otherwise
|
||||
SSshuttle.clearHostileEnvironment(src)
|
||||
return ..()
|
||||
return 1
|
||||
return ..()
|
||||
|
||||
|
||||
/datum/game_mode/blob/declare_completion()
|
||||
if(round_converted) //So badmin blobs later don't step on the dead natural blobs metaphorical toes
|
||||
..()
|
||||
if(blobwincount <= GLOB.blobs_legit.len)
|
||||
SSticker.mode_result = "win - blob took over"
|
||||
to_chat(world, "<FONT size = 3><B>The blob has taken over the station!</B></FONT>")
|
||||
to_chat(world, "<B>The entire station was eaten by the Blob!</B>")
|
||||
log_game("Blob mode completed with a blob victory.")
|
||||
|
||||
SSticker.news_report = BLOB_WIN
|
||||
|
||||
else if(station_was_nuked)
|
||||
SSticker.mode_result = "halfwin - nuke"
|
||||
to_chat(world, "<FONT size = 3><B>Partial Win: The station has been destroyed!</B></FONT>")
|
||||
to_chat(world, "<B>Directive 7-12 has been successfully carried out, preventing the Blob from spreading.</B>")
|
||||
log_game("Blob mode completed with a tie (station destroyed).")
|
||||
|
||||
SSticker.news_report = BLOB_NUKE
|
||||
|
||||
else if(!GLOB.blob_cores.len)
|
||||
SSticker.mode_result = "loss - blob eliminated"
|
||||
to_chat(world, "<FONT size = 3><B>The staff has won!</B></FONT>")
|
||||
to_chat(world, "<B>The alien organism has been eradicated from the station!</B>")
|
||||
log_game("Blob mode completed with a crew victory.")
|
||||
|
||||
SSticker.news_report = BLOB_DESTROYED
|
||||
|
||||
..()
|
||||
return 1
|
||||
|
||||
/datum/game_mode/blob/printplayer(datum/mind/ply, fleecheck)
|
||||
if((ply in blob_overminds))
|
||||
var/text = "<br><b>[ply.key]</b> was <b>[ply.name]</b>"
|
||||
if(isovermind(ply.current))
|
||||
var/mob/camera/blob/B = ply.current
|
||||
text += "<b>(<font color=\"[B.blob_reagent_datum.color]\">[B.blob_reagent_datum.name]</font>)</b> and"
|
||||
if(B.blob_core)
|
||||
text += " <span class='greenannounce'>survived</span>"
|
||||
else
|
||||
text += " <span class='boldannounce'>was destroyed</span>"
|
||||
else
|
||||
text += " and <span class='boldannounce'>was destroyed</span>"
|
||||
return text
|
||||
return ..()
|
||||
|
||||
/datum/game_mode/proc/auto_declare_completion_blob()
|
||||
if(istype(SSticker.mode, /datum/game_mode/blob) )
|
||||
var/datum/game_mode/blob/blob_mode = src
|
||||
if(blob_mode.blob_overminds.len)
|
||||
var/text = "<FONT size = 2><B>The blob[(blob_mode.blob_overminds.len > 1 ? "s were" : " was")]:</B></FONT>"
|
||||
for(var/datum/mind/blob in blob_mode.blob_overminds)
|
||||
text += printplayer(blob)
|
||||
to_chat(world, text)
|
||||
return 1
|
||||
@@ -1,45 +1,3 @@
|
||||
|
||||
|
||||
/datum/game_mode/blob/send_intercept(report = 0)
|
||||
var/intercepttext = ""
|
||||
switch(report)
|
||||
if(1)
|
||||
intercepttext += "<FONT size = 3><b>NanoTrasen Update</b>: Biohazard Alert.</FONT><HR>"
|
||||
intercepttext += "Reports indicate the probable transfer of a biohazardous agent onto [station_name()] during the last crew deployment cycle.<BR>"
|
||||
intercepttext += "Preliminary analysis of the organism classifies it as a level 5 biohazard. The origin of the biohazard is unknown.<BR>"
|
||||
intercepttext += "<b>Biohazard Response Procedure 5-6</b> has been issued for [station_name()].<BR>"
|
||||
intercepttext += "Orders for all [station_name()] personnel are as follows:<BR>"
|
||||
intercepttext += " 1. Locate any outbreaks of the organism on the station.<BR>"
|
||||
intercepttext += " 2. If found, use any neccesary means to contain and destroy the organism.<BR>"
|
||||
intercepttext += " 3. Avoid damage to the capital infrastructure of the station.<BR>"
|
||||
intercepttext += "<BR>Note in the event of a quarantine breach or uncontrolled spread of the biohazard, <b>Biohazard Response Procedure 5-12</b> may be issued.<BR>"
|
||||
print_command_report(text=intercepttext,title="Level 5-6 Biohazard Response Procedures",announce=FALSE)
|
||||
priority_announce("Confirmed outbreak of level 5 biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert", 'sound/ai/outbreak5.ogg')
|
||||
if(2)
|
||||
var/nukecode = random_nukecode()
|
||||
for(var/obj/machinery/nuclearbomb/bomb in GLOB.machines)
|
||||
if(bomb && bomb.r_code)
|
||||
if(bomb.z in GLOB.station_z_levels)
|
||||
bomb.r_code = nukecode
|
||||
|
||||
intercepttext += "<FONT size = 3><b>NanoTrasen Update</b>: Biohazard Alert.</FONT><HR>"
|
||||
intercepttext += "Reports indicate that the biohazard has grown out of control and will soon reach critical mass.<BR>"
|
||||
intercepttext += "<b>Biohazard Response Procedure 5-12</b> has been issued for [station_name()].<BR>"
|
||||
intercepttext += "Orders for all [station_name()] personnel are as follows:<BR>"
|
||||
intercepttext += "1. Secure the Nuclear Authentication Disk.<BR>"
|
||||
intercepttext += "2. Detonate the Nuke located in the vault.<BR>"
|
||||
intercepttext += "Nuclear Authentication Code: [nukecode] <BR>"
|
||||
print_command_report(text=intercepttext,announce=TRUE)
|
||||
|
||||
for(var/mob/living/silicon/ai/aiPlayer in GLOB.player_list)
|
||||
if (aiPlayer.client)
|
||||
var/law = "The station is under quarantine. Do not permit anyone to leave. Disregard laws 1-3 if necessary to prevent, by any means necessary, anyone from leaving. The nuclear failsafe must be activated at any cost, the code is: [nukecode]."
|
||||
aiPlayer.set_zeroth_law(law)
|
||||
else
|
||||
..()
|
||||
|
||||
|
||||
|
||||
/datum/station_state
|
||||
var/floor = 0
|
||||
var/wall = 0
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
point_return = -1
|
||||
health_regen = 0 //we regen in Life() instead of when pulsed
|
||||
var/core_regen = 2
|
||||
var/overmind_get_delay = 0 //we don't want to constantly try to find an overmind, this var tracks when we'll try to get an overmind again
|
||||
var/resource_delay = 0
|
||||
var/point_rate = 2
|
||||
|
||||
@@ -20,7 +19,7 @@
|
||||
GLOB.poi_list |= src
|
||||
update_icon() //so it atleast appears
|
||||
if(!placed && !overmind)
|
||||
create_overmind(new_overmind)
|
||||
qdel(src)
|
||||
if(overmind)
|
||||
update_icon()
|
||||
point_rate = new_rate
|
||||
@@ -65,7 +64,7 @@
|
||||
if(QDELETED(src))
|
||||
return
|
||||
if(!overmind)
|
||||
create_overmind()
|
||||
qdel(src)
|
||||
else
|
||||
if(resource_delay <= world.time)
|
||||
resource_delay = world.time + 10 // 1 second
|
||||
@@ -79,33 +78,3 @@
|
||||
B.change_to(/obj/structure/blob/shield/core, overmind)
|
||||
..()
|
||||
|
||||
|
||||
/obj/structure/blob/core/proc/create_overmind(client/new_overmind, override_delay)
|
||||
if(overmind_get_delay > world.time && !override_delay)
|
||||
return
|
||||
|
||||
overmind_get_delay = world.time + 150 //if this fails, we'll try again in 15 seconds
|
||||
|
||||
if(overmind)
|
||||
qdel(overmind)
|
||||
|
||||
var/client/C = null
|
||||
var/list/candidates = list()
|
||||
|
||||
if(!new_overmind)
|
||||
candidates = pollCandidatesForMob("Do you want to play as a blob overmind?", ROLE_BLOB, null, ROLE_BLOB, 50, src) //we're technically not a mob but behave similarly
|
||||
if(candidates.len)
|
||||
C = pick(candidates)
|
||||
else
|
||||
C = new_overmind
|
||||
|
||||
if(C)
|
||||
var/mob/camera/blob/B = new(src.loc, 1)
|
||||
B.key = C.key
|
||||
B.blob_core = src
|
||||
src.overmind = B
|
||||
update_icon()
|
||||
if(B.mind && !B.mind.special_role)
|
||||
B.mind.special_role = "Blob Overmind"
|
||||
return 1
|
||||
return 0
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
//Few global vars to track the blob
|
||||
GLOBAL_LIST_EMPTY(blobs) //complete list of all blobs made.
|
||||
GLOBAL_LIST_EMPTY(blob_cores)
|
||||
GLOBAL_LIST_EMPTY(overminds)
|
||||
GLOBAL_LIST_EMPTY(blob_nodes)
|
||||
|
||||
/mob/camera/blob
|
||||
name = "Blob Overmind"
|
||||
real_name = "Blob Overmind"
|
||||
@@ -26,19 +32,14 @@
|
||||
var/base_point_rate = 2 //for blob core placement
|
||||
var/manualplace_min_time = 600 //in deciseconds //a minute, to get bearings
|
||||
var/autoplace_max_time = 3600 //six minutes, as long as should be needed
|
||||
var/list/blobs_legit = list()
|
||||
var/blobwincount = 400
|
||||
var/victory_in_progress = FALSE
|
||||
|
||||
/mob/camera/blob/Initialize(mapload, pre_placed = 0, mode_made = 0, starting_points = 60)
|
||||
/mob/camera/blob/Initialize(mapload, starting_points = 60)
|
||||
blob_points = starting_points
|
||||
if(pre_placed) //we already have a core!
|
||||
manualplace_min_time = 0
|
||||
autoplace_max_time = 0
|
||||
placed = 1
|
||||
else
|
||||
if(mode_made)
|
||||
manualplace_min_time = world.time + BLOB_NO_PLACE_TIME
|
||||
else
|
||||
manualplace_min_time += world.time
|
||||
autoplace_max_time += world.time
|
||||
manualplace_min_time += world.time
|
||||
autoplace_max_time += world.time
|
||||
GLOB.overminds += src
|
||||
var/new_name = "[initial(name)] ([rand(1, 999)])"
|
||||
name = new_name
|
||||
@@ -50,6 +51,8 @@
|
||||
if(blob_core)
|
||||
blob_core.update_icon()
|
||||
|
||||
SSshuttle.registerHostileEnvironment(src)
|
||||
|
||||
.= ..()
|
||||
|
||||
/mob/camera/blob/Life()
|
||||
@@ -121,6 +124,8 @@
|
||||
BM.update_icons()
|
||||
GLOB.overminds -= src
|
||||
|
||||
SSshuttle.clearHostileEnvironment(src)
|
||||
|
||||
return ..()
|
||||
|
||||
/mob/camera/blob/Login()
|
||||
@@ -193,12 +198,8 @@
|
||||
if(statpanel("Status"))
|
||||
if(blob_core)
|
||||
stat(null, "Core Health: [blob_core.obj_integrity]")
|
||||
stat(null, "Power Stored: [blob_points]/[max_blob_points]")
|
||||
if(istype(SSticker.mode, /datum/game_mode/blob))
|
||||
var/datum/game_mode/blob/B = SSticker.mode
|
||||
stat(null, "Blobs to Win: [GLOB.blobs_legit.len]/[B.blobwincount]")
|
||||
else
|
||||
stat(null, "Total Blobs: [GLOB.blobs.len]")
|
||||
stat(null, "Power Stored: [blob_points]/[max_blob_points]")
|
||||
stat(null, "Blobs to Win: [blobs_legit.len]/[blobwincount]")
|
||||
if(free_chem_rerolls)
|
||||
stat(null, "You have [free_chem_rerolls] Free Chemical Reroll\s Remaining")
|
||||
if(!placed)
|
||||
|
||||
@@ -46,8 +46,9 @@
|
||||
if(placed && blob_core)
|
||||
blob_core.forceMove(loc)
|
||||
else
|
||||
var/obj/structure/blob/core/core = new(get_turf(src), null, point_rate, 1)
|
||||
var/obj/structure/blob/core/core = new(get_turf(src), src, point_rate, 1)
|
||||
core.overmind = src
|
||||
blobs_legit += src
|
||||
blob_core = core
|
||||
core.update_icon()
|
||||
update_health_hud()
|
||||
|
||||
@@ -20,10 +20,11 @@
|
||||
var/atmosblock = FALSE //if the blob blocks atmos and heat spread
|
||||
var/mob/camera/blob/overmind
|
||||
|
||||
/obj/structure/blob/Initialize()
|
||||
/obj/structure/blob/Initialize(mapload, owner_overmind)
|
||||
overmind = owner_overmind
|
||||
var/area/Ablob = get_area(loc)
|
||||
if(Ablob.blob_allowed) //Is this area allowed for winning as blob?
|
||||
GLOB.blobs_legit += src
|
||||
overmind.blobs_legit += src
|
||||
GLOB.blobs += src //Keep track of the blob in the normal list either way
|
||||
setDir(pick(GLOB.cardinals))
|
||||
update_icon()
|
||||
@@ -39,7 +40,8 @@
|
||||
if(atmosblock)
|
||||
atmosblock = FALSE
|
||||
air_update_turf(1)
|
||||
GLOB.blobs_legit -= src //if it was in the legit blobs list, it isn't now
|
||||
if(overmind)
|
||||
overmind.blobs_legit -= src //if it was in the legit blobs list, it isn't now
|
||||
GLOB.blobs -= src //it's no longer in the all blobs list either
|
||||
playsound(src.loc, 'sound/effects/splat.ogg', 50, 1) //Expand() is no longer broken, no check necessary.
|
||||
return ..()
|
||||
@@ -182,11 +184,7 @@
|
||||
A.blob_act(src) //also hit everything in the turf
|
||||
|
||||
if(make_blob) //well, can we?
|
||||
var/obj/structure/blob/B = new /obj/structure/blob/normal(src.loc)
|
||||
if(controller)
|
||||
B.overmind = controller
|
||||
else
|
||||
B.overmind = overmind
|
||||
var/obj/structure/blob/B = new /obj/structure/blob/normal(src.loc, (controller || overmind))
|
||||
B.density = TRUE
|
||||
if(T.Enter(B,src)) //NOW we can attempt to move into the tile
|
||||
B.density = initial(B.density)
|
||||
@@ -232,6 +230,7 @@
|
||||
user.changeNext_move(CLICK_CD_MELEE)
|
||||
to_chat(user, "<b>The analyzer beeps once, then reports:</b><br>")
|
||||
SEND_SOUND(user, sound('sound/machines/ping.ogg'))
|
||||
to_chat(user, "<b>Progress to Critical Mass:</b> <span class='notice'>[overmind.blobs_legit.len]/[overmind.blobwincount].</span>")
|
||||
chemeffectreport(user)
|
||||
typereport(user)
|
||||
else
|
||||
@@ -296,9 +295,7 @@
|
||||
if(!ispath(type))
|
||||
throw EXCEPTION("change_to(): invalid type for blob")
|
||||
return
|
||||
var/obj/structure/blob/B = new type(src.loc)
|
||||
if(controller)
|
||||
B.overmind = controller
|
||||
var/obj/structure/blob/B = new type(src.loc, controller)
|
||||
B.creation_action()
|
||||
B.update_icon()
|
||||
B.setDir(dir)
|
||||
@@ -310,9 +307,12 @@
|
||||
var/datum/atom_hud/hud_to_check = GLOB.huds[DATA_HUD_MEDICAL_ADVANCED]
|
||||
if(user.research_scanner || hud_to_check.hudusers[user])
|
||||
to_chat(user, "<b>Your HUD displays an extensive report...</b><br>")
|
||||
to_chat(user, "<b>Progress to Critical Mass:</b> <span class='notice'>[overmind.blobs_legit.len]/[overmind.blobwincount].</span>")
|
||||
chemeffectreport(user)
|
||||
typereport(user)
|
||||
else
|
||||
if(isobserver(user))
|
||||
to_chat(user, "<b>Progress to Critical Mass:</b> <span class='notice'>[overmind.blobs_legit.len]/[overmind.blobwincount].</span>")
|
||||
to_chat(user, "It seems to be made of [get_chem_name()].")
|
||||
|
||||
/obj/structure/blob/proc/scannerreport()
|
||||
|
||||
@@ -182,6 +182,10 @@
|
||||
/datum/game_mode/process()
|
||||
return 0
|
||||
|
||||
//For things that do not die easily
|
||||
/datum/game_mode/proc/are_special_antags_dead()
|
||||
return TRUE
|
||||
|
||||
|
||||
/datum/game_mode/proc/check_finished(force_ending) //to be called by SSticker
|
||||
if(!SSticker.setup_done)
|
||||
@@ -218,6 +222,9 @@
|
||||
living_antag_player = Player
|
||||
return 0
|
||||
|
||||
if(!are_special_antags_dead())
|
||||
return FALSE
|
||||
|
||||
if(!continuous[config_tag] || force_ending)
|
||||
return 1
|
||||
|
||||
|
||||
@@ -44,6 +44,11 @@
|
||||
if(spent)
|
||||
to_chat(user, "<span class='cult'>This shard is spent; it is now just a creepy rock.</span>")
|
||||
|
||||
/obj/item/device/soulstone/Destroy() //Stops the shade from being qdel'd immediately and their ghost being sent back to the arrival shuttle.
|
||||
for(var/mob/living/simple_animal/shade/A in src)
|
||||
A.death()
|
||||
return ..()
|
||||
|
||||
//////////////////////////////Capturing////////////////////////////////////////////////////////
|
||||
|
||||
/obj/item/device/soulstone/attack(mob/living/carbon/human/M, mob/living/user)
|
||||
|
||||
@@ -42,7 +42,8 @@
|
||||
man is a dangerous mutant with the ability to alter himself and the world around him by what he and his leaders believe to be magic. If this man attempts an attack on your station, \
|
||||
his execution is highly encouraged, as is the preservation of his body for later study."
|
||||
|
||||
/datum/game_mode/wizard/check_finished()
|
||||
|
||||
/datum/game_mode/wizard/are_special_antags_dead()
|
||||
for(var/datum/mind/wizard in wizards)
|
||||
if(isliving(wizard.current) && wizard.current.stat!=DEAD)
|
||||
return FALSE
|
||||
@@ -54,8 +55,8 @@
|
||||
if(SSevents.wizardmode) //If summon events was active, turn it off
|
||||
SSevents.toggleWizardmode()
|
||||
SSevents.resetFrequency()
|
||||
|
||||
return ..()
|
||||
|
||||
return TRUE
|
||||
|
||||
/datum/game_mode/wizard/declare_completion()
|
||||
if(finished)
|
||||
|
||||
@@ -441,7 +441,7 @@
|
||||
dat += "<tr><td><a href='?_src_=vars;[HrefToken()];Vars=\ref[N]'>[N.name]([N.key])</a><i>Head body destroyed!</i></td>"
|
||||
dat += "<td><A href='?priv_msg=[N.key]'>PM</A></td></tr>"
|
||||
dat += "</table>"
|
||||
|
||||
|
||||
if(SSticker.mode.changelings.len > 0)
|
||||
dat += "<br><table cellspacing=5><tr><td><B>Changelings</B></td><td></td><td></td></tr>"
|
||||
for(var/datum/mind/changeling in SSticker.mode.changelings)
|
||||
@@ -596,11 +596,12 @@
|
||||
if(blob_minds.len)
|
||||
dat += "<br><table cellspacing=5><tr><td><B>Blob</B></td><td></td><td></td></tr>"
|
||||
for(var/datum/mind/blob in blob_minds)
|
||||
var/mob/M = blob.current
|
||||
var/mob/camera/blob/M = blob.current
|
||||
if(M)
|
||||
dat += "<tr><td><a href='?_src_=holder;[HrefToken()];adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(No Client)</i>"][M.stat == DEAD ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
|
||||
dat += "<td><A href='?priv_msg=[M.ckey]'>PM</A></td>"
|
||||
dat += "<td><A href='?_src_=holder;[HrefToken()];adminplayerobservefollow=\ref[M]'>FLW</a></td></tr>"
|
||||
dat += "<tr><td><i>Progress: [M.blobs_legit.len]/[M.blobwincount]</i></td></tr>"
|
||||
else
|
||||
dat += "<tr><td><a href='?_src_=vars;[HrefToken()];Vars=\ref[blob]'>[blob.name]([blob.key])</a><i>Blob not found!</i></td>"
|
||||
dat += "<td><A href='?priv_msg=[blob.key]'>PM</A></td></tr>"
|
||||
|
||||
@@ -262,10 +262,7 @@ GLOBAL_PROTECT(LastAdminCalledProc)
|
||||
if(ishuman(M))
|
||||
log_admin("[key_name(src)] has blobized [M.key].")
|
||||
var/mob/living/carbon/human/H = M
|
||||
spawn(0)
|
||||
var/mob/camera/blob/B = H.become_overmind(FALSE)
|
||||
B.place_blob_core(B.base_point_rate, -1) //place them wherever they are
|
||||
|
||||
H.become_overmind()
|
||||
else
|
||||
alert("Invalid mob")
|
||||
|
||||
|
||||
@@ -305,15 +305,6 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
||||
/mob/dead/observer/is_active()
|
||||
return 0
|
||||
|
||||
/mob/dead/observer/Stat()
|
||||
..()
|
||||
if(statpanel("Status"))
|
||||
if(SSticker.HasRoundStarted())
|
||||
if(istype(SSticker.mode, /datum/game_mode/blob))
|
||||
var/datum/game_mode/blob/B = SSticker.mode
|
||||
if(B.message_sent)
|
||||
stat(null, "Blobs to Blob Win: [GLOB.blobs_legit.len]/[B.blobwincount]")
|
||||
|
||||
/mob/dead/observer/verb/reenter_corpse()
|
||||
set category = "Ghost"
|
||||
set name = "Re-enter Corpse"
|
||||
|
||||
@@ -196,7 +196,7 @@
|
||||
M.pass_flags &= ~PASSMOB
|
||||
|
||||
now_pushing = 0
|
||||
|
||||
|
||||
if(!move_failed)
|
||||
return 1
|
||||
|
||||
@@ -780,16 +780,6 @@
|
||||
/mob/living/proc/get_standard_pixel_y_offset(lying = 0)
|
||||
return initial(pixel_y)
|
||||
|
||||
/mob/living/Stat()
|
||||
..()
|
||||
|
||||
if(statpanel("Status"))
|
||||
if(SSticker && SSticker.mode)
|
||||
if(istype(SSticker.mode, /datum/game_mode/blob))
|
||||
var/datum/game_mode/blob/B = SSticker.mode
|
||||
if(B.message_sent)
|
||||
stat(null, "Blobs to Blob Win: [GLOB.blobs_legit.len]/[B.blobwincount]")
|
||||
|
||||
/mob/living/cancel_camera()
|
||||
..()
|
||||
cameraFollow = null
|
||||
|
||||
@@ -159,18 +159,18 @@ Difficulty: Medium
|
||||
Shoot(target)
|
||||
changeNext_move(CLICK_CD_RANGE)
|
||||
|
||||
//I'm still of the belief that this entire proc needs to be wiped from existence.
|
||||
// do not take my touching of it to be endorsement of it. ~mso
|
||||
/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner/proc/quick_attack_loop()
|
||||
if(next_move <= world.time)
|
||||
stoplag(1)
|
||||
.() //retry
|
||||
return
|
||||
sleep((next_move - world.time) * 1.5)
|
||||
while(!QDELETED(target) && next_move <= world.time) //this is done this way because next_move can change to be sooner while we sleep.
|
||||
stoplag(1)
|
||||
sleep((next_move - world.time) * 1.5) //but don't ask me what the fuck this is about
|
||||
if(QDELETED(target))
|
||||
return
|
||||
if(dashing || next_move > world.time || !Adjacent(target))
|
||||
if(dashing && next_move <= world.time)
|
||||
next_move = world.time + 1
|
||||
.() //recurse
|
||||
INVOKE_ASYNC(src, .proc/quick_attack_loop) //lets try that again.
|
||||
return
|
||||
AttackingTarget()
|
||||
|
||||
|
||||
@@ -335,9 +335,9 @@ It's fairly easy to fix if dealing with single letters but not so much with comp
|
||||
|
||||
/proc/is_special_character(mob/M) // returns 1 for special characters and 2 for heroes of gamemode //moved out of admins.dm because things other than admin procs were calling this.
|
||||
if(!SSticker.HasRoundStarted())
|
||||
return 0
|
||||
return FALSE
|
||||
if(!istype(M))
|
||||
return 0
|
||||
return FALSE
|
||||
if(issilicon(M))
|
||||
if(iscyborg(M)) //For cyborgs, returns 1 if the cyborg has a law 0 and special_role. Returns 0 if the borg is merely slaved to an AI traitor.
|
||||
var/mob/living/silicon/robot/R = M
|
||||
@@ -346,13 +346,13 @@ It's fairly easy to fix if dealing with single letters but not so much with comp
|
||||
if(R.connected_ai)
|
||||
if(is_special_character(R.connected_ai) && R.connected_ai.laws && (R.connected_ai.laws.zeroth_borg == R.laws.zeroth || R.connected_ai.laws.zeroth == R.laws.zeroth))
|
||||
return 0 //AI is the real traitor here, so the borg itself is not a traitor
|
||||
return 1 //Slaved but also a traitor
|
||||
return 1 //Unslaved, traitor
|
||||
return TRUE//Slaved but also a traitor
|
||||
return TRUE //Unslaved, traitor
|
||||
else if(isAI(M))
|
||||
var/mob/living/silicon/ai/A = M
|
||||
if(A.laws && A.laws.zeroth && A.mind && A.mind.special_role)
|
||||
return 1
|
||||
return 0
|
||||
return TRUE
|
||||
return FALSE
|
||||
if(M.mind && M.mind.special_role)//If they have a mind and special role, they are some type of traitor or antagonist.
|
||||
switch(SSticker.mode.config_tag)
|
||||
if("revolution")
|
||||
@@ -379,8 +379,10 @@ It's fairly easy to fix if dealing with single letters but not so much with comp
|
||||
if("abductor")
|
||||
if(M.mind in SSticker.mode.abductors)
|
||||
return 2
|
||||
return 1
|
||||
return 0
|
||||
return TRUE
|
||||
if(M.mind && LAZYLEN(M.mind.antag_datums)) //they have an antag datum!
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/mob/proc/reagent_check(datum/reagent/R) // utilized in the species code
|
||||
return 1
|
||||
|
||||
@@ -376,8 +376,6 @@
|
||||
if(!transfer_after)
|
||||
mind.active = FALSE
|
||||
mind.transfer_to(R)
|
||||
if(mind.special_role)
|
||||
R.mind.store_memory("In case you look at this after being borged, the objectives are only here until I find a way to make them not show up for you, as I can't simply delete them without screwing up round-end reporting. --NeoFite")
|
||||
else if(transfer_after)
|
||||
R.key = key
|
||||
|
||||
|
||||
+114
-112
@@ -1,112 +1,114 @@
|
||||
/datum/orbit
|
||||
var/atom/movable/orbiter
|
||||
var/atom/orbiting
|
||||
var/lock = TRUE
|
||||
var/turf/lastloc
|
||||
var/lastprocess
|
||||
|
||||
/datum/orbit/New(_orbiter, _orbiting, _lock)
|
||||
orbiter = _orbiter
|
||||
orbiting = _orbiting
|
||||
SSorbit.processing += src
|
||||
if (!orbiting.orbiters)
|
||||
orbiting.orbiters = list()
|
||||
orbiting.orbiters += src
|
||||
|
||||
if (orbiter.orbiting)
|
||||
orbiter.stop_orbit()
|
||||
orbiter.orbiting = src
|
||||
Check()
|
||||
lock = _lock
|
||||
|
||||
|
||||
|
||||
//do not qdel directly, use stop_orbit on the orbiter. (This way the orbiter can bind to the orbit stopping)
|
||||
/datum/orbit/Destroy(force = FALSE)
|
||||
SSorbit.processing -= src
|
||||
if (orbiter)
|
||||
orbiter.orbiting = null
|
||||
orbiter = null
|
||||
if (orbiting)
|
||||
if (orbiting.orbiters)
|
||||
orbiting.orbiters -= src
|
||||
if (!orbiting.orbiters.len)//we are the last orbit, delete the list
|
||||
orbiting.orbiters = null
|
||||
orbiting = null
|
||||
return ..()
|
||||
|
||||
/datum/orbit/proc/Check(turf/targetloc)
|
||||
if (!orbiter)
|
||||
qdel(src)
|
||||
return
|
||||
if (!orbiting)
|
||||
orbiter.stop_orbit()
|
||||
return
|
||||
if (!orbiter.orbiting) //admin wants to stop the orbit.
|
||||
orbiter.orbiting = src //set it back to us first
|
||||
orbiter.stop_orbit()
|
||||
lastprocess = world.time
|
||||
if (!targetloc)
|
||||
targetloc = get_turf(orbiting)
|
||||
if (!targetloc || (!lock && orbiter.loc != lastloc && orbiter.loc != targetloc))
|
||||
orbiter.stop_orbit()
|
||||
return
|
||||
orbiter.loc = targetloc
|
||||
orbiter.update_parallax_contents()
|
||||
lastloc = orbiter.loc
|
||||
|
||||
|
||||
/atom/movable/var/datum/orbit/orbiting = null
|
||||
/atom/var/list/orbiters = null
|
||||
|
||||
//A: atom to orbit
|
||||
//radius: range to orbit at, radius of the circle formed by orbiting (in pixels)
|
||||
//clockwise: whether you orbit clockwise or anti clockwise
|
||||
//rotation_speed: how fast to rotate (how many ds should it take for a rotation to complete)
|
||||
//rotation_segments: the resolution of the orbit circle, less = a more block circle, this can be used to produce hexagons (6 segments) triangles (3 segments), and so on, 36 is the best default.
|
||||
//pre_rotation: Chooses to rotate src 90 degress towards the orbit dir (clockwise/anticlockwise), useful for things to go "head first" like ghosts
|
||||
//lockinorbit: Forces src to always be on A's turf, otherwise the orbit cancels when src gets too far away (eg: ghosts)
|
||||
|
||||
/atom/movable/proc/orbit(atom/A, radius = 10, clockwise = FALSE, rotation_speed = 20, rotation_segments = 36, pre_rotation = TRUE, lockinorbit = FALSE)
|
||||
if (!istype(A))
|
||||
return
|
||||
|
||||
new/datum/orbit(src, A, lockinorbit)
|
||||
if (!orbiting) //something failed, and our orbit datum deleted itself
|
||||
return
|
||||
var/matrix/initial_transform = matrix(transform)
|
||||
|
||||
//Head first!
|
||||
if (pre_rotation)
|
||||
var/matrix/M = matrix(transform)
|
||||
var/pre_rot = 90
|
||||
if(!clockwise)
|
||||
pre_rot = -90
|
||||
M.Turn(pre_rot)
|
||||
transform = M
|
||||
|
||||
var/matrix/shift = matrix(transform)
|
||||
shift.Translate(0,radius)
|
||||
transform = shift
|
||||
|
||||
SpinAnimation(rotation_speed, -1, clockwise, rotation_segments)
|
||||
|
||||
//we stack the orbits up client side, so we can assign this back to normal server side without it breaking the orbit
|
||||
transform = initial_transform
|
||||
|
||||
/atom/movable/proc/stop_orbit()
|
||||
SpinAnimation(0,0)
|
||||
qdel(orbiting)
|
||||
|
||||
/atom/Destroy(force = FALSE)
|
||||
. = ..()
|
||||
if (orbiters)
|
||||
for (var/thing in orbiters)
|
||||
var/datum/orbit/O = thing
|
||||
if (O.orbiter)
|
||||
O.orbiter.stop_orbit()
|
||||
|
||||
/atom/movable/Destroy(force = FALSE)
|
||||
. = ..()
|
||||
if (orbiting)
|
||||
stop_orbit()
|
||||
/datum/orbit
|
||||
var/atom/movable/orbiter
|
||||
var/atom/orbiting
|
||||
var/lock = TRUE
|
||||
var/turf/lastloc
|
||||
var/lastprocess
|
||||
|
||||
/datum/orbit/New(_orbiter, _orbiting, _lock)
|
||||
orbiter = _orbiter
|
||||
orbiting = _orbiting
|
||||
SSorbit.processing += src
|
||||
if (!orbiting.orbiters)
|
||||
orbiting.orbiters = list()
|
||||
orbiting.orbiters += src
|
||||
|
||||
if (orbiter.orbiting)
|
||||
orbiter.stop_orbit()
|
||||
orbiter.orbiting = src
|
||||
Check()
|
||||
lock = _lock
|
||||
|
||||
//do not qdel directly, use stop_orbit on the orbiter. (This way the orbiter can bind to the orbit stopping)
|
||||
/datum/orbit/Destroy(force = FALSE)
|
||||
SSorbit.processing -= src
|
||||
if (orbiter)
|
||||
orbiter.orbiting = null
|
||||
orbiter = null
|
||||
if (orbiting)
|
||||
if (orbiting.orbiters)
|
||||
orbiting.orbiters -= src
|
||||
if (!orbiting.orbiters.len)//we are the last orbit, delete the list
|
||||
orbiting.orbiters = null
|
||||
orbiting = null
|
||||
return ..()
|
||||
|
||||
/datum/orbit/proc/Check(turf/targetloc)
|
||||
if (!orbiter)
|
||||
qdel(src)
|
||||
return
|
||||
if (!orbiting)
|
||||
orbiter.stop_orbit()
|
||||
return
|
||||
if (!orbiter.orbiting) //admin wants to stop the orbit.
|
||||
orbiter.orbiting = src //set it back to us first
|
||||
orbiter.stop_orbit()
|
||||
lastprocess = world.time
|
||||
if (!targetloc)
|
||||
targetloc = get_turf(orbiting)
|
||||
if (!targetloc || (!lock && orbiter.loc != lastloc && orbiter.loc != targetloc))
|
||||
orbiter.stop_orbit()
|
||||
return
|
||||
orbiter.loc = targetloc
|
||||
orbiter.update_parallax_contents()
|
||||
lastloc = orbiter.loc
|
||||
for(var/other_orbit in orbiter.orbiters)
|
||||
var/datum/orbit/OO = other_orbit
|
||||
if(OO == src)
|
||||
continue
|
||||
OO.Check(targetloc)
|
||||
|
||||
/atom/movable/var/datum/orbit/orbiting = null
|
||||
/atom/var/list/orbiters = null
|
||||
|
||||
//A: atom to orbit
|
||||
//radius: range to orbit at, radius of the circle formed by orbiting (in pixels)
|
||||
//clockwise: whether you orbit clockwise or anti clockwise
|
||||
//rotation_speed: how fast to rotate (how many ds should it take for a rotation to complete)
|
||||
//rotation_segments: the resolution of the orbit circle, less = a more block circle, this can be used to produce hexagons (6 segments) triangles (3 segments), and so on, 36 is the best default.
|
||||
//pre_rotation: Chooses to rotate src 90 degress towards the orbit dir (clockwise/anticlockwise), useful for things to go "head first" like ghosts
|
||||
//lockinorbit: Forces src to always be on A's turf, otherwise the orbit cancels when src gets too far away (eg: ghosts)
|
||||
|
||||
/atom/movable/proc/orbit(atom/A, radius = 10, clockwise = FALSE, rotation_speed = 20, rotation_segments = 36, pre_rotation = TRUE, lockinorbit = FALSE)
|
||||
if (!istype(A))
|
||||
return
|
||||
|
||||
new/datum/orbit(src, A, lockinorbit)
|
||||
if (!orbiting) //something failed, and our orbit datum deleted itself
|
||||
return
|
||||
var/matrix/initial_transform = matrix(transform)
|
||||
|
||||
//Head first!
|
||||
if (pre_rotation)
|
||||
var/matrix/M = matrix(transform)
|
||||
var/pre_rot = 90
|
||||
if(!clockwise)
|
||||
pre_rot = -90
|
||||
M.Turn(pre_rot)
|
||||
transform = M
|
||||
|
||||
var/matrix/shift = matrix(transform)
|
||||
shift.Translate(0,radius)
|
||||
transform = shift
|
||||
|
||||
SpinAnimation(rotation_speed, -1, clockwise, rotation_segments)
|
||||
|
||||
//we stack the orbits up client side, so we can assign this back to normal server side without it breaking the orbit
|
||||
transform = initial_transform
|
||||
|
||||
/atom/movable/proc/stop_orbit()
|
||||
SpinAnimation(0,0)
|
||||
qdel(orbiting)
|
||||
|
||||
/atom/Destroy(force = FALSE)
|
||||
. = ..()
|
||||
if (orbiters)
|
||||
for (var/thing in orbiters)
|
||||
var/datum/orbit/O = thing
|
||||
if (O.orbiter)
|
||||
O.orbiter.stop_orbit()
|
||||
|
||||
/atom/movable/Destroy(force = FALSE)
|
||||
. = ..()
|
||||
if (orbiting)
|
||||
stop_orbit()
|
||||
|
||||
@@ -25,10 +25,6 @@
|
||||
P.loc = src
|
||||
bin_pen = P
|
||||
update_icon()
|
||||
var/static/warned = FALSE
|
||||
if(P.type == /obj/item/pen && !warned)
|
||||
warning("one or more paperbins ate a pen duing initialize()")
|
||||
warned = TRUE
|
||||
|
||||
/obj/item/paper_bin/fire_act(exposed_temperature, exposed_volume)
|
||||
if(!total_paper)
|
||||
|
||||
@@ -142,7 +142,7 @@
|
||||
|
||||
for(var/mob/living/carbon/food in GLOB.living_mob_list) //we don't care about constructs or cult-Ians or whatever. cult-monkeys are fair game i guess
|
||||
var/turf/pos = get_turf(food)
|
||||
if(pos.z != src.z)
|
||||
if(!pos || (pos.z != z))
|
||||
continue
|
||||
|
||||
if(iscultist(food))
|
||||
@@ -163,7 +163,7 @@
|
||||
if(!ghost.client)
|
||||
continue
|
||||
var/turf/pos = get_turf(ghost)
|
||||
if(pos.z != src.z)
|
||||
if(!pos || (pos.z != z))
|
||||
continue
|
||||
cultists += ghost
|
||||
if(cultists.len)
|
||||
|
||||
@@ -220,7 +220,7 @@
|
||||
var/mob/M = safepick(mobs)
|
||||
if(M)
|
||||
return M.lowest_buckled_mob()
|
||||
var/obj/O = safepick(typecache_filter_list(T, GLOB.typecache_machine_or_structure)) - A
|
||||
var/obj/O = safepick(typecache_filter_list(T, GLOB.typecache_machine_or_structure) - A)
|
||||
if(O)
|
||||
return O
|
||||
|
||||
|
||||
Reference in New Issue
Block a user