Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

@@ -142,7 +142,6 @@
return 1

/obj/effect/hotspot/Destroy()
..()
SetLuminosity(0)
SSair.hotspots -= src
DestroyTurf()
@@ -151,6 +150,7 @@
if(T.active_hotspot == src)
T.active_hotspot = null
loc = null
..()
return QDEL_HINT_PUTINPOOL

/obj/effect/hotspot/proc/DestroyTurf()
@@ -53,6 +53,8 @@
#define CARBON_LIFEFORM_FIRE_RESISTANCE 200+T0C //Resistance to fire damage
#define CARBON_LIFEFORM_FIRE_DAMAGE 4 //Fire damage
//Plasma fire properties
#define OXYGEN_BURN_RATE_BASE 1.4
#define PLASMA_BURN_RATE_DELTA 8
#define PLASMA_MINIMUM_BURN_TEMPERATURE 100+T0C
#define PLASMA_UPPER_TEMPERATURE 1370+T0C
#define PLASMA_MINIMUM_OXYGEN_NEEDED 2
@@ -287,4 +287,7 @@ var/list/bloody_footprints_cache = list()
#define DYNAMIC_LIGHTING_DISABLED 0 //dynamic lighting disabled (area stays at full brightness)
#define DYNAMIC_LIGHTING_ENABLED 1 //dynamic lighting enabled
#define DYNAMIC_LIGHTING_IFSTARLIGHT 2 //dynamic lighting enabled only if starlight is.
#define IS_DYNAMIC_LIGHTING(A) ( A.lighting_use_dynamic == DYNAMIC_LIGHTING_IFSTARLIGHT ? config.starlight : A.lighting_use_dynamic )
#define IS_DYNAMIC_LIGHTING(A) ( A.lighting_use_dynamic == DYNAMIC_LIGHTING_IFSTARLIGHT ? config.starlight : A.lighting_use_dynamic )

//subtypesof(), typesof() without the parent path
#define subtypesof(typepath) ( typesof(typepath) - typepath )
@@ -28,16 +28,14 @@


//Species
for(var/spath in typesof(/datum/species))
if(spath == /datum/species)
continue
for(var/spath in subtypesof(/datum/species))
var/datum/species/S = new spath()
if(S.roundstart)
roundstart_species[S.name] = S.type
roundstart_species[S.id] = S.type
species_list[S.id] = S.type

//Surgeries
for(var/path in (typesof(/datum/surgery) - /datum/surgery))
for(var/path in (subtypesof(/datum/surgery)))
surgeries_list += new path()

init_subtypes(/datum/table_recipe, table_recipes)
@@ -58,8 +56,7 @@
//if no list/L is provided, one is created.
/proc/init_subtypes(prototype, list/L)
if(!istype(L)) L = list()
for(var/path in typesof(prototype))
if(path == prototype) continue
for(var/path in subtypesof(prototype))
L += new path()
return L

@@ -68,8 +65,6 @@
/proc/init_paths(prototype, list/L)
if(!istype(L))
L = list()
for(var/path in typesof(prototype))
if(path == prototype)
continue
for(var/path in subtypesof(prototype))
L+= path
return L
@@ -1342,4 +1342,4 @@ B --><-- A
L += T.contents
c_dist++

return L
return L
@@ -210,6 +210,8 @@ var/datum/global_hud/global_hud = new()
hoggod_hud()
else if(isguardian(mymob))
guardian_hud()
else if(isovermind(mymob))
blob_hud()

//Version denotes which style should be displayed. blank or 0 means "next version"
/datum/hud/proc/show_hud(version = 0)
@@ -14,25 +14,6 @@
mymob.client.screen += list(mymob.blind)
mymob.client.screen += mymob.client.void

/datum/hud/proc/blob_hud(ui_style = 'icons/mob/screen_midnight.dmi')

blobpwrdisplay = new /obj/screen()
blobpwrdisplay.name = "blob power"
blobpwrdisplay.icon_state = "block"
blobpwrdisplay.screen_loc = ui_health
blobpwrdisplay.layer = 20

blobhealthdisplay = new /obj/screen()
blobhealthdisplay.name = "blob health"
blobhealthdisplay.icon_state = "block"
blobhealthdisplay.screen_loc = ui_internal
blobhealthdisplay.layer = 20

mymob.client.screen = list()
mymob.client.screen += list(blobpwrdisplay, blobhealthdisplay)
mymob.client.screen += mymob.client.void


/datum/hud/proc/hoggod_hud(ui_style = 'icons/mob/screen_midnight.dmi')
deity_health_display = new /obj/screen()
deity_health_display.name = "Nexus Health"
@@ -1,17 +1,35 @@
// Blob Overmind Controls


/mob/camera/blob/CtrlClickOn(atom/A) // Expand blob
/mob/camera/blob/ClickOn(var/atom/A, var/params) //Expand blob
var/list/modifiers = params2list(params)
if(modifiers["middle"])
MiddleClickOn(A)
return
if(modifiers["shift"])
ShiftClickOn(A)
return
if(modifiers["alt"])
AltClickOn(A)
return
if(modifiers["ctrl"])
CtrlClickOn(A)
return
var/turf/T = get_turf(A)
if(T)
expand_blob(T)

/mob/camera/blob/MiddleClickOn(atom/A) // Rally spores
/mob/camera/blob/MiddleClickOn(atom/A) //Rally spores
var/turf/T = get_turf(A)
if(T)
rally_spores(T)

/mob/camera/blob/AltClickOn(atom/A) // Create a shield
/mob/camera/blob/CtrlClickOn(atom/A) //Create a shield
var/turf/T = get_turf(A)
if(T)
create_shield(T)
create_shield(T)

/mob/camera/blob/AltClickOn(atom/A) //Remove a blob
var/turf/T = get_turf(A)
if(T)
remove_blob(T)
@@ -186,7 +186,7 @@


/datum/configuration/New()
var/list/L = typesof(/datum/game_mode) - /datum/game_mode
var/list/L = subtypesof(/datum/game_mode)
for(var/T in L)
// I wish I didn't have to instance the game modes in order to look up
// their information, but it is the only way (at least that I know of).
@@ -663,7 +663,7 @@
/datum/configuration/proc/pick_mode(mode_name)
// I wish I didn't have to instance the game modes in order to look up
// their information, but it is the only way (at least that I know of).
for(var/T in (typesof(/datum/game_mode) - /datum/game_mode))
for(var/T in subtypesof(/datum/game_mode))
var/datum/game_mode/M = new T()
if(M.config_tag && M.config_tag == mode_name)
return M
@@ -672,7 +672,7 @@

/datum/configuration/proc/get_runnable_modes()
var/list/datum/game_mode/runnable_modes = new
for(var/T in (typesof(/datum/game_mode) - /datum/game_mode))
for(var/T in subtypesof(/datum/game_mode))
var/datum/game_mode/M = new T()
//world << "DEBUG: [T], tag=[M.config_tag], prob=[probabilities[M.config_tag]]"
if(!(M.config_tag in modes))
@@ -688,7 +688,7 @@

/datum/configuration/proc/get_runnable_midround_modes(crew)
var/list/datum/game_mode/runnable_modes = new
for(var/T in (typesof(/datum/game_mode) - /datum/game_mode - ticker.mode.type))
for(var/T in (subtypesof(/datum/game_mode) - ticker.mode.type))
var/datum/game_mode/M = new T()
if(!(M.config_tag in modes))
qdel(M)
@@ -36,12 +36,14 @@ calculate the longest number of ticks the MC can wait between each cycle without
*/
/datum/controller/game_controller/proc/calculateGCD()
var/GCD
//shortest fire rate is the lower of two ticks or 1ds
var/minimumInterval = min(world.tick_lag*2,1)
for(var/datum/subsystem/SS in subsystems)
if(SS.wait)
GCD = Gcd(round(SS.wait*10), GCD)
GCD = round(GCD)
if(GCD < world.tick_lag*10)
GCD = world.tick_lag*10
if(GCD < minimumInterval*10)
GCD = minimumInterval*10
processing_interval = GCD/10

/datum/controller/game_controller/proc/setup(zlevel)
@@ -67,6 +69,7 @@ calculate the longest number of ticks the MC can wait between each cycle without
sleep(-1)

crewmonitor.generateMiniMaps()
populate_asset_cache()

world << "<span class='boldannounce'>Initializations complete</span>"

@@ -93,12 +96,12 @@ calculate the longest number of ticks the MC can wait between each cycle without
while(1) //far more efficient than recursively calling ourself
if(processing_interval > 0)
++iteration

var/startingtick = world.time
start_time = world.timeofday
var/SubSystemRan = 0
for(var/datum/subsystem/SS in subsystems)
if(SS.can_fire > 0)
if(SS.next_fire <= world.time)
if(SS.next_fire <= world.time && SS.last_fire+(SS.wait*0.5) <= world.time)
SubSystemRan = 1
timer = world.timeofday
last_thing_processed = SS.type
@@ -108,19 +111,29 @@ calculate the longest number of ticks the MC can wait between each cycle without
if (SS.dynamic_wait)
var/oldwait = SS.wait
var/GlobalCostDelta = (SSCostPerSecond-(SS.cost/(SS.wait/10)))-1
var/NewWait = MC_AVERAGE(oldwait,(SS.cost-SS.dwait_buffer+GlobalCostDelta)*SS.dwait_delta)
var/NewWait = (SS.cost-SS.dwait_buffer+GlobalCostDelta)*SS.dwait_delta
NewWait = NewWait*(world.cpu/100+1)
NewWait = MC_AVERAGE(oldwait,NewWait)
SS.wait = Clamp(NewWait,SS.dwait_lower,SS.dwait_upper)
if (oldwait != SS.wait)
calculateGCD()
SS.next_fire += SS.wait
++SS.times_fired

//we caused byond to miss a tick, stop processing for a bit
if (startingtick < world.time || start_time+1 < world.timeofday)
break
sleep(-1)

cost = MC_AVERAGE(cost, world.timeofday - start_time)
if (SubSystemRan)
calculateSScost()
sleep(processing_interval)
var/extrasleep = 0
if (startingtick < world.time || start_time+1 < world.timeofday)
//we caused byond to miss a tick, sleep a bit extra
extrasleep += world.tick_lag*2
if (world.cpu > 80)
extrasleep += extrasleep+processing_interval
sleep(processing_interval+extrasleep)
else
sleep(50)

@@ -178,7 +178,7 @@ var/datum/subsystem/events/SSevent
var/MM = text2num(time2text(world.timeofday, "MM")) // get the current month
var/DD = text2num(time2text(world.timeofday, "DD")) // get the current day

for(var/H in typesof(/datum/holiday) - /datum/holiday)
for(var/H in subtypesof(/datum/holiday))
var/datum/holiday/holiday = new H()
if(holiday.shouldCelebrate(DD, MM, YY))
holiday.celebrate()
@@ -24,7 +24,7 @@ var/datum/subsystem/job/SSjob

/datum/subsystem/job/proc/SetupOccupations(faction = "Station")
occupations = list()
var/list/all_jobs = typesof(/datum/job)
var/list/all_jobs = subtypesof(/datum/job)
if(!all_jobs.len)
world << "<span class='boldannounce'>Error setting up jobs, no job datums found</span>"
return 0
@@ -342,10 +342,10 @@ var/datum/subsystem/job/SSjob
if(!joined_late)
var/obj/S = null
for(var/obj/effect/landmark/start/sloc in start_landmarks_list)
if(sloc.name != rank)
if(sloc.name != rank)
S = sloc //so we can revert to spawning them on top of eachother if something goes wrong
continue
if(locate(/mob/living) in sloc.loc)
if(locate(/mob/living) in sloc.loc)
continue
S = sloc
break
@@ -30,7 +30,7 @@ var/datum/subsystem/nano/SSnano
//Ignore directories
if(copytext(filename, length(filename)) != "/")
if(fexists(path + filename))
asset_files.Add(fcopy_rsc(path + filename))
asset_files[filename] = fcopy_rsc(path + filename)


/datum/subsystem/nano/stat_entry()
@@ -52,9 +52,7 @@ var/datum/subsystem/shuttle/SSshuttle

ordernum = rand(1,9000)

for(var/typepath in typesof(/datum/supply_packs))
if(typepath == /datum/supply_packs)
continue
for(var/typepath in subtypesof(/datum/supply_packs))
var/datum/supply_packs/P = new typepath()
if(P.name == "HEADER") continue // To filter out group headers
supply_packs["[P.type]"] = P
@@ -145,7 +145,6 @@
/obj/docking_port/mobile/pod
name = "escape pod"
id = "pod"

dwidth = 1
width = 3
height = 4
@@ -182,9 +181,67 @@
admin_controlled = 0
icon_state = "dorm_emag"

/obj/docking_port/stationary/random
name = "escape pod"
id = "pod"
dwidth = 1
width = 3
height = 4

/obj/docking_port/stationary/random/initialize()
..()
var/target_area = /area/mine/unexplored
var/turfs = get_area_turfs(target_area)
var/T=pick(turfs)
src.loc = T

//Pod suits/pickaxes


/obj/item/clothing/head/helmet/space/orange
name = "emergency space helmet"
icon_state = "syndicate-helm-orange"
item_state = "syndicate-helm-orange"

/obj/item/clothing/suit/space/orange
name = "emergency space suit"
icon_state = "syndicate-orange"
item_state = "syndicate-orange"
slowdown = 3

/obj/item/weapon/pickaxe/emergency
name = "emergency disembarkation tool"
desc = "For extracting yourself from rough landings."

/obj/item/weapon/storage/pod
name = "emergency space suits"
desc = "A wall mounted safe containing space suits. Will only open in emergencies."
anchored = 1
density = 0
icon = 'icons/obj/storage.dmi'
icon_state = "safe"

/obj/item/weapon/storage/pod/New()
..()
new /obj/item/clothing/head/helmet/space/orange(src)
new /obj/item/clothing/head/helmet/space/orange(src)
new /obj/item/clothing/suit/space/orange(src)
new /obj/item/clothing/suit/space/orange(src)
new /obj/item/clothing/mask/gas(src)
new /obj/item/clothing/mask/gas(src)
new /obj/item/weapon/tank/internals/air(src)
new /obj/item/weapon/tank/internals/air(src)
new /obj/item/weapon/pickaxe/emergency(src)
new /obj/item/weapon/pickaxe/emergency(src)

/obj/item/weapon/storage/pod/attackby(obj/item/weapon/W, mob/user, params)
return

/obj/item/weapon/storage/pod/MouseDrop(over_object, src_location, over_location)
if(security_level == SEC_LEVEL_RED || security_level == SEC_LEVEL_DELTA)
return ..()
else
usr << "The storage unit will only unlock during a Red or Delta security alert."

/obj/item/weapon/storage/pod/attack_hand(mob/user)
return
@@ -100,7 +100,7 @@
WARNING("Invalid custom AI laws, check silicon_laws.txt")
return
if(2)
var/datum/ai_laws/lawtype = pick(typesof(/datum/ai_laws/default) - /datum/ai_laws/default)
var/datum/ai_laws/lawtype = pick(subtypesof(/datum/ai_laws/default))
var/datum/ai_laws/templaws = new lawtype()
inherent = templaws.inherent

@@ -411,7 +411,7 @@ body

else if(href_list["datumrefresh"])
var/datum/DAT = locate(href_list["datumrefresh"])
if(!istype(DAT, /datum))
if(!DAT) //can't be an istype() because /client etc aren't datums
return
src.debug_variables(DAT)

@@ -27,7 +27,7 @@
#define BIOHAZARD "BIOHAZARD THREAT!"


var/list/diseases = typesof(/datum/disease) - /datum/disease
var/list/diseases = subtypesof(/datum/disease)


/datum/disease
@@ -1,6 +1,6 @@
// Symptoms are the effects that engineered advanced diseases do.

var/list/list_symptoms = typesof(/datum/symptom) - /datum/symptom
var/list/list_symptoms = subtypesof(/datum/symptom)
var/list/dictionary_symptoms = list()

var/global/const/SYMPTOM_ACTIVATION_PROB = 3
@@ -163,11 +163,11 @@ What are the archived variables for?
else
temperature_scale = (temperature-PLASMA_MINIMUM_BURN_TEMPERATURE)/(PLASMA_UPPER_TEMPERATURE-PLASMA_MINIMUM_BURN_TEMPERATURE)
if(temperature_scale > 0)
oxygen_burn_rate = 1.4 - temperature_scale
oxygen_burn_rate = OXYGEN_BURN_RATE_BASE - temperature_scale
if(oxygen > toxins*PLASMA_OXYGEN_FULLBURN)
plasma_burn_rate = (toxins*temperature_scale)/4
plasma_burn_rate = (toxins*temperature_scale)/PLASMA_BURN_RATE_DELTA
else
plasma_burn_rate = (temperature_scale*(oxygen/PLASMA_OXYGEN_FULLBURN))/4
plasma_burn_rate = (temperature_scale*(oxygen/PLASMA_OXYGEN_FULLBURN))/PLASMA_BURN_RATE_DELTA
if(plasma_burn_rate > MINIMUM_HEAT_CAPACITY)
toxins -= plasma_burn_rate
oxygen -= plasma_burn_rate*oxygen_burn_rate
@@ -19,16 +19,16 @@
var/l_hand = null
var/list/backpack_contents = list() // In the list(path=count,otherpath=count) format

/datum/outfit/proc/pre_equip(mob/living/carbon/human/H)
/datum/outfit/proc/pre_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
//to be overriden for customization depending on client prefs,species etc
return

/datum/outfit/proc/post_equip(mob/living/carbon/human/H)
/datum/outfit/proc/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
//to be overriden for toggling internals, id binding, access etc
return

/datum/outfit/proc/equip(mob/living/carbon/human/H)
pre_equip(H)
/datum/outfit/proc/equip(mob/living/carbon/human/H, visualsOnly = FALSE)
pre_equip(H, visualsOnly)

//Start with uniform,suit,backpack for additional slots
if(uniform)
@@ -70,6 +70,6 @@
for(var/i=0,i<number,i++)
H.equip_to_slot_or_del(new path(H),slot_in_backpack)

post_equip(H)
post_equip(H, visualsOnly)

return 1
@@ -2,13 +2,15 @@

/obj/effect/proc_holder/spell/aoe_turf/conjure/construct/lesser
charge_max = 1800
action_icon_state = "artificer"
action_background_icon_state = "bg_demon"

/obj/effect/proc_holder/spell/aoe_turf/conjure/construct/lesser/cult
cult_req = 1
charge_max = 2500

/obj/effect/proc_holder/spell/aoe_turf/conjure/floor
name = "Floor Construction"
name = "Summon Cult Floor"
desc = "This spell constructs a cult floor"

school = "conjuration"
@@ -17,11 +19,12 @@
invocation = "none"
invocation_type = "none"
range = 0
summon_type = list(/turf/simulated/floor/plasteel/cult)
centcom_cancast = 0 //Stop crashing the server by spawning turfs on transit tiles
summon_type = list(/turf/simulated/floor/engine/cult)
action_icon_state = "floorconstruct"
action_background_icon_state = "bg_cult"

/obj/effect/proc_holder/spell/aoe_turf/conjure/wall
name = "Lesser Construction"
name = "Summon Cult Wall"
desc = "This spell constructs a cult wall"

school = "conjuration"
@@ -30,8 +33,10 @@
invocation = "none"
invocation_type = "none"
range = 0
action_icon_state = "lesserconstruct"
action_background_icon_state = "bg_cult"

summon_type = list(/turf/simulated/wall/cult)
centcom_cancast = 0 //Stop crashing the server by spawning turfs on transit tiles

/obj/effect/proc_holder/spell/aoe_turf/conjure/wall/reinforced
name = "Greater Construction"
@@ -43,7 +48,6 @@
invocation = "none"
invocation_type = "none"
range = 0
centcom_cancast = 0 //Stop crashing the server by spawning turfs on transit tiles

summon_type = list(/turf/simulated/wall/r_wall)

@@ -57,7 +61,8 @@
invocation = "none"
invocation_type = "none"
range = 0

action_icon_state = "summonsoulstone"
action_background_icon_state = "bg_demon"

summon_type = list(/obj/item/device/soulstone)

@@ -76,8 +81,10 @@
invocation = "none"
invocation_type = "none"
range = 0
summon_type = list(/obj/effect/forcefield)
summon_type = list(/obj/effect/forcefield/cult)
summon_lifespan = 200
action_icon_state = "cultforcewall"
action_background_icon_state = "bg_demon"


/obj/effect/proc_holder/spell/targeted/ethereal_jaunt/shift
@@ -93,6 +100,8 @@
include_user = 1
jaunt_duration = 50 //in deciseconds
centcom_cancast = 0 //Stop people from getting to centcom
action_icon_state = "phaseshift"
action_background_icon_state = "bg_demon"

/obj/effect/proc_holder/spell/targeted/ethereal_jaunt/shift/jaunt_disappear(atom/movable/overlay/animation, mob/living/target)
animation.icon_state = "phase_shift"
@@ -118,6 +127,8 @@
invocation_type = "none"
proj_lifespan = 10
max_targets = 6
action_icon_state = "magicm"
action_background_icon_state = "bg_demon"


/obj/effect/proc_holder/spell/targeted/smoke/disable
@@ -135,3 +146,5 @@

smoke_spread = 3
smoke_amt = 4
action_icon_state = "parasmoke"
action_background_icon_state = "bg_cult"
@@ -1,6 +1,6 @@
/obj/effect/proc_holder/spell/targeted/lightning
name = "Lightning Bolt"
desc = "Throws a lightning bolt at the nearby enemy. Classic."
desc = "Charges up and throws a lightning bolt at nearby enemies. Classic."
charge_type = "recharge"
charge_max = 300
clothes_req = 1
@@ -10,20 +10,15 @@
cooldown_min = 30
selection_type = "view"
random_target = 1
var/start_time = 0
var/ready = 0
var/image/halo = null
var/sound/Snd // so far only way i can think of to stop a sound, thank MSO for the idea.

action_icon_state = "lightning"

/obj/effect/proc_holder/spell/targeted/lightning/Click()
if(!ready && start_time==0)
if(cast_check())
StartChargeup()
else
if(ready && cast_check(skipcharge=1))
choose_targets()
if(!ready && cast_check())
StartChargeup()
return 1

/obj/effect/proc_holder/spell/targeted/lightning/proc/StartChargeup(mob/user = usr)
@@ -33,14 +28,14 @@
halo = image("icon"='icons/effects/effects.dmi',"icon_state" ="electricity","layer" = EFFECTS_LAYER)
user.overlays.Add(halo)
playsound(get_turf(usr), Snd, 50, 0)
start_time = world.time
if(do_mob(user,user,100,uninterruptible=1))
if(ready)
Discharge()
if(ready && cast_check(skipcharge=1))
choose_targets()
else
Reset(user)

/obj/effect/proc_holder/spell/targeted/lightning/proc/Reset(mob/user = usr)
ready = 0
start_time = 0
if(halo)
user.overlays.Remove(halo)

@@ -49,14 +44,6 @@
Reset(user)
..()

/obj/effect/proc_holder/spell/targeted/lightning/proc/Discharge(mob/user = usr)
var/mob/living/M = user
//M.electrocute_act(25,"Lightning Bolt")
M << "<span class='danger'>You lose control over the spell.</span>"
Reset(user)
start_recharge()


/obj/effect/proc_holder/spell/targeted/lightning/cast(list/targets, mob/user = usr)
ready = 0
var/mob/living/carbon/target = targets[1]
@@ -70,8 +57,7 @@
playsound(get_turf(usr), 'sound/magic/lightningbolt.ogg', 50, 1)
user.Beam(target,icon_state="lightning",icon='icons/effects/effects.dmi',time=5)

var/energy = min(world.time - start_time,100)
Bolt(user,target,max(15,energy/2),5,user) //5 bounces for energy/2 burn
Bolt(user,target,30,5,user)
Reset(user)

/obj/effect/proc_holder/spell/targeted/lightning/proc/Bolt(mob/origin,mob/target,bolt_energy,bounces,mob/user = usr)
@@ -92,4 +78,4 @@
return
var/mob/living/next = pick(possible_targets)
if(next)
Bolt(current,next,bolt_energy,bounces-1,user)
Bolt(current,next,max((bolt_energy-5),5),bounces-1,user)
@@ -3,12 +3,12 @@
desc = "This spell fires several, slow moving, magic projectiles at nearby targets."

school = "evocation"
charge_max = 150
charge_max = 200
clothes_req = 1
invocation = "FORTI GY AMA"
invocation_type = "shout"
range = 7
cooldown_min = 90 //15 deciseconds reduction per rank
cooldown_min = 60 //35 deciseconds reduction per rank

max_targets = 0

@@ -159,12 +159,12 @@
/obj/effect/proc_holder/spell/aoe_turf/conjure/timestop
name = "Stop Time"
desc = "This spell stops time for everyone except for you, allowing you to move freely while your enemies and even projectiles are frozen."
charge_max = 400
charge_max = 500
clothes_req = 1
invocation = "TOKI WO TOMARE"
invocation_type = "shout"
range = 0
cooldown_min = 90
cooldown_min = 100
summon_amt = 1
action_icon_state = "time"

@@ -1102,6 +1102,8 @@ var/list/all_supply_groups = list(supply_emergency,supply_security,supply_engine
/obj/item/hand_labeler_refill,
/obj/item/hand_labeler_refill,
/obj/item/weapon/paper_bin,
/obj/item/weapon/pen/fourcolor,
/obj/item/weapon/pen/fourcolor,
/obj/item/weapon/pen,
/obj/item/weapon/pen/blue,
/obj/item/weapon/pen/red,
@@ -8,7 +8,7 @@ var/list/uplink_items = list()
// A keyed list, acting as categories, which are lists to the datum.

var/list/last = list()
for(var/item in typesof(/datum/uplink_item))
for(var/item in subtypesof(/datum/uplink_item))

var/datum/uplink_item/I = new item()
if(!I.item)
@@ -28,7 +28,7 @@ var/const/WIRE_EXPLODE = 1

/datum/wires/explosive/c4/explode()
var/obj/item/weapon/c4/P = holder
P.explode(get_turf(P))
P.explode()



@@ -88,8 +88,8 @@ var/global/max_secret_rooms = 6
theme = "cavein"
walltypes = list(/turf/simulated/mineral/random/high_chance=1)
floortypes = list(/turf/simulated/floor/plating/asteroid/airless, /turf/simulated/floor/plating/beach/sand)
treasureitems = list(/obj/mecha/working/ripley/mining=1, /obj/item/weapon/pickaxe/drill/diamonddrill=2,/obj/item/weapon/gun/energy/kinetic_accelerator=1,
/obj/item/weapon/resonator=1, /obj/item/weapon/pickaxe/drill/jackhammer=5)
treasureitems = list(/obj/mecha/working/ripley/mining=1, /obj/item/weapon/pickaxe/drill/diamonddrill=2,/obj/item/weapon/gun/energy/kinetic_accelerator/hyper=1,
/obj/item/weapon/resonator/upgraded=1, /obj/item/weapon/pickaxe/drill/jackhammer=5)
fluffitems = list(/obj/effect/decal/cleanable/blood=3,/obj/effect/decal/remains/human=1,/obj/item/clothing/under/overalls=1,
/obj/item/weapon/reagent_containers/food/snacks/grown/chili=1,/obj/item/weapon/tank/internals/oxygen/red=2)

@@ -123,7 +123,7 @@ var/global/max_secret_rooms = 6
theme = "plantlab"
treasureitems = list(/obj/item/weapon/gun/energy/floragun=1,/obj/item/seeds/novaflowerseed=2,/obj/item/seeds/bluespacetomatoseed=2,/obj/item/seeds/bluetomatoseed=2,
/obj/item/seeds/coffee_robusta_seed=2, /obj/item/seeds/cashseed=2)
fluffitems = list(/obj/structure/flora/kirbyplants=1,/obj/structure/table/reinforced=2,/obj/machinery/hydroponics=1,
fluffitems = list(/obj/structure/flora/kirbyplants=1,/obj/structure/table/reinforced=2,/obj/machinery/hydroponics/constructable=1,
/obj/effect/glowshroom/single=2,/obj/item/weapon/reagent_containers/syringe/charcoal=2,
/obj/item/weapon/reagent_containers/glass/bottle/diethylamine=3,/obj/item/weapon/reagent_containers/glass/bottle/ammonia=3)

@@ -165,6 +165,10 @@ var/global/max_secret_rooms = 6
valid = 0
continue

if(locate(/area/mine/abandoned) in surroundings)
valid = 0
continue

if(locate(/turf/space) in surroundings)
valid = 0
continue
@@ -14,7 +14,7 @@
return rgb(rand(0,255),rand(0,255),rand(0,255))

/obj/machinery/abductor/gland_dispenser/New()
gland_types = typesof(/obj/item/organ/internal/gland) - /obj/item/organ/internal/gland
gland_types = subtypesof(/obj/item/organ/internal/gland)
gland_types = shuffle(gland_types)
gland_colors = new/list(gland_types.len)
amounts = new/list(gland_types.len)
@@ -155,7 +155,7 @@
H << "<span class='warning'>You feel intensely watched.</span>"
sleep(5)
H << "<span class='warning'><b>Your mind snaps!</b></span>"
var/objtype = pick(typesof(/datum/objective/abductee/) - /datum/objective/abductee/)
var/objtype = pick(subtypesof(/datum/objective/abductee/))
var/datum/objective/abductee/O = new objtype()
ticker.mode.abductees += H.mind
H.mind.objectives += O
@@ -6,6 +6,7 @@
health = 400
maxhealth = 400
explosion_block = 6
point_return = -1
var/overmind_get_delay = 0 // we don't want to constantly try to find an overmind, do it every 30 seconds
var/resource_delay = 0
var/point_rate = 2
@@ -5,6 +5,7 @@
desc = "A thick spire of tendrils."
health = 200
maxhealth = 200
point_return = 25
var/list/spores = list()
var/max_spores = 3
var/spore_delay = 0
@@ -5,6 +5,7 @@
desc = "A large, pulsating yellow mass."
health = 200
maxhealth = 200
point_return = 25

/obj/effect/blob/node/New(loc, var/h = 100)
blob_nodes += src
@@ -5,6 +5,7 @@
desc = "A thin spire of slightly swaying tendrils."
health = 60
maxhealth = 60
point_return = 15
var/resource_delay = 0

/obj/effect/blob/resource/update_icon()
@@ -6,6 +6,7 @@
health = 150
maxhealth = 150
explosion_block = 3
point_return = 2


/obj/effect/blob/shield/update_icon()
@@ -20,6 +21,9 @@
/obj/effect/blob/shield/CanAtmosPass(turf/T)
return 0

/obj/effect/blob/shield/BlockSuperconductivity()
return 1

/obj/effect/blob/shield/CanPass(atom/movable/mover, turf/target, height=0)
if(istype(mover) && mover.checkpass(PASSBLOB)) return 1
return 0
@@ -5,17 +5,19 @@
desc = "A huge, smooth mass supported by tendrils."
health = 60
maxhealth = 60
point_return = -1
var/point_bonus = 50 //How much the overmind's point cap increases from storage blobs

/obj/effect/blob/storage/update_icon()
if(health <= 0)
overmind.max_blob_points -= 50
overmind.max_blob_points -= point_bonus
qdel(src)

/obj/effect/blob/storage/PulseAnimation(activate = 0)
if(activate)
..()
return

/obj/effect/blob/storage/proc/update_max_blob_points(new_point_increase)
/obj/effect/blob/storage/creation_action()
if(overmind)
overmind.max_blob_points += new_point_increase
overmind.max_blob_points += point_bonus
@@ -25,7 +25,7 @@
real_name = new_name
last_attack = world.time
var/list/possible_reagents = list()
for(var/type in (typesof(/datum/reagent/blob) - /datum/reagent/blob))
for(var/type in (subtypesof(/datum/reagent/blob)))
possible_reagents.Add(new type)
blob_reagent_datum = pick(possible_reagents)
if(blob_core)
@@ -53,14 +53,7 @@
..()
sync_mind()
src << "<span class='notice'>You are the overmind!</span>"
src << "Your randomly chosen reagent is: <b>[blob_reagent_datum.name]</b>!"
src << "You are the overmind and can control the blob! You can expand, which will attack people, and place new blob pieces such as..."
src << "<b>Normal Blob</b> will expand your reach and allow you to upgrade into special blobs that perform certain functions."
src << "<b>Shield Blob</b> is a strong and expensive blob which can take more damage. It is fireproof and can block air, use this to protect yourself from station fires."
src << "<b>Resource Blob</b> is a blob which will collect more resources for you, try to build these earlier to get a strong income. It will benefit from being near your core or multiple nodes, by having an increased resource rate; put it alone and it won't create resources at all."
src << "<b>Node Blob</b> is a blob which will grow, like the core. Unlike the core it won't give you a small income but it can power resource and factory blobs to increase their rate."
src << "<b>Factory Blob</b> is a blob which will spawn blob spores which will attack nearby food. Putting this nearby nodes and your core will increase the spawn rate; put it alone and it will not spawn any spores."
src << "<b>Shortcuts:</b> CTRL Click = Expand Blob / Middle Mouse Click = Rally Spores / Alt Click = Create Shield"
blob_help()
update_health()

/mob/camera/blob/proc/update_health()
@@ -126,3 +119,157 @@
/mob/camera/blob/proc/can_attack()
return (world.time > (last_attack + CLICK_CD_RANGE))


/obj/screen/blob
icon = 'icons/mob/blob.dmi'

/obj/screen/blob/BlobHelp
icon_state = "ui_help"
name = "Blob Help"
desc = "Help on playing blob!"

/obj/screen/blob/BlobHelp/Click()
if(isovermind(usr))
var/mob/camera/blob/B = usr
B.blob_help()

/obj/screen/blob/JumpToNode
icon_state = "ui_tonode"
name = "Jump to Node"
desc = "Moves your camera to a selected blob node."

/obj/screen/blob/JumpToNode/Click()
if(isovermind(usr))
var/mob/camera/blob/B = usr
B.jump_to_node()

/obj/screen/blob/JumpToCore
icon_state = "ui_tocore"
name = "Jump to Core"
desc = "Moves your camera to your blob core."

/obj/screen/blob/JumpToCore/Click()
if(isovermind(usr))
var/mob/camera/blob/B = usr
B.transport_core()

/obj/screen/blob/StorageBlob
icon_state = "ui_factory"
name = "Produce Storage Blob (20)"
desc = "Produces a storage blob for 20 points."

/obj/screen/blob/StorageBlob/Click()
if(isovermind(usr))
var/mob/camera/blob/B = usr
B.create_storage()

/obj/screen/blob/ResourceBlob
icon_state = "ui_resource"
name = "Produce Resource Blob (40)"
desc = "Produces a resource blob for 40 points."

/obj/screen/blob/ResourceBlob/Click()
if(isovermind(usr))
var/mob/camera/blob/B = usr
B.create_resource()

/obj/screen/blob/NodeBlob
icon_state = "ui_node"
name = "Produce Node Blob (60)"
desc = "Produces a node blob for 60 points."

/obj/screen/blob/NodeBlob/Click()
if(isovermind(usr))
var/mob/camera/blob/B = usr
B.create_node()

/obj/screen/blob/FactoryBlob
icon_state = "ui_factory"
name = "Produce Factory Blob (60)"
desc = "Produces a resource blob for 60 points."

/obj/screen/blob/FactoryBlob/Click()
if(isovermind(usr))
var/mob/camera/blob/B = usr
B.create_factory()

/obj/screen/blob/ReadaptChemical
icon_state = "ui_chemswap"
name = "Readapt Chemical (40)"
desc = "Randomly rerolls your chemical for 40 points."

/obj/screen/blob/ReadaptChemical/Click()
if(isovermind(usr))
var/mob/camera/blob/B = usr
B.chemical_reroll()

/obj/screen/blob/RelocateCore
icon_state = "ui_swap"
name = "Relocate Core (80)"
desc = "Swaps a node and your core for 80 points."

/obj/screen/blob/RelocateCore/Click()
if(isovermind(usr))
var/mob/camera/blob/B = usr
B.relocate_core()

/datum/hud/proc/blob_hud(ui_style = 'icons/mob/screen_midnight.dmi')
adding = list()

var/obj/screen/using

blobpwrdisplay = new /obj/screen()
blobpwrdisplay.name = "blob power"
blobpwrdisplay.icon_state = "block"
blobpwrdisplay.screen_loc = ui_health
blobpwrdisplay.mouse_opacity = 0
blobpwrdisplay.layer = 20
adding += blobpwrdisplay

blobhealthdisplay = new /obj/screen()
blobhealthdisplay.name = "blob health"
blobhealthdisplay.icon_state = "block"
blobhealthdisplay.screen_loc = ui_internal
blobhealthdisplay.mouse_opacity = 0
blobhealthdisplay.layer = 20
adding += blobhealthdisplay

using = new /obj/screen/blob/BlobHelp()
using.screen_loc = "NORTH:-6,WEST:6"
adding += using

using = new /obj/screen/blob/JumpToNode()
using.screen_loc = ui_inventory
adding += using

using = new /obj/screen/blob/JumpToCore()
using.screen_loc = ui_zonesel
adding += using

using = new /obj/screen/blob/StorageBlob()
using.screen_loc = ui_belt
adding += using

using = new /obj/screen/blob/ResourceBlob()
using.screen_loc = ui_back
adding += using

using = new /obj/screen/blob/NodeBlob()
using.screen_loc = ui_lhand
adding += using

using = new /obj/screen/blob/FactoryBlob()
using.screen_loc = ui_rhand
adding += using

using = new /obj/screen/blob/ReadaptChemical()
using.screen_loc = ui_storage1
adding += using

using = new /obj/screen/blob/RelocateCore()
using.screen_loc = ui_storage2
adding += using

mymob.client.screen = list()
mymob.client.screen += mymob.client.void
mymob.client.screen += adding
@@ -45,9 +45,7 @@
if(!can_buy(price))
return
B.color = blob_reagent_datum.color
var/obj/effect/blob/N = B.change_to(blobType)
N.overmind = src
N.adjustcolors(blob_reagent_datum.color)
var/obj/effect/blob/N = B.change_to(blobType, src)
return N

/mob/camera/blob/verb/create_shield_power()
@@ -79,10 +77,9 @@

/mob/camera/blob/verb/create_storage()
set category = "Blob"
set name = "Create Storage Blob (40)"
set name = "Create Storage Blob (20)"
set desc = "Create a storage tower which will store extra resources for you. This increases your max resource cap by 50."
var/obj/effect/blob/storage/R = createSpecial(40, /obj/effect/blob/storage, 3)
R.update_max_blob_points(50)
createSpecial(20, /obj/effect/blob/storage, 3)

/mob/camera/blob/verb/create_blobbernaut()
set category = "Blob"
@@ -91,10 +88,10 @@
var/turf/T = get_turf(src)
var/obj/effect/blob/B = locate(/obj/effect/blob) in T
if(!B)
src << "You must be on a blob!"
src << "<span class='warning'>You must be on a blob!</span>"
return
if(!istype(B, /obj/effect/blob/factory))
src << "Unable to use this blob, find a factory blob."
src << "<span class='warning'>Unable to use this blob, find a factory blob.</span>"
return
if(!can_buy(20))
return
@@ -112,7 +109,7 @@
var/turf/T = get_turf(src)
var/obj/effect/blob/node/B = locate(/obj/effect/blob/node) in T
if(!B)
src << "You must be on a blob node!"
src << "<span class='warning'>You must be on a blob node!</span>"
return
if(!can_buy(80))
return
@@ -123,15 +120,24 @@
/mob/camera/blob/verb/revert()
set category = "Blob"
set name = "Remove Blob"
set desc = "Removes a blob."
set desc = "Removes a blob, giving you back some resources."
var/turf/T = get_turf(src)
var/obj/effect/blob/B = locate(/obj/effect/blob) in T
remove_blob(T)

/mob/camera/blob/proc/remove_blob(turf/T)
var/obj/effect/blob/B = locate() in T
if(!B)
src << "You must be on a blob!"
src << "<span class='warning'>There is no blob there!</span>"
return
if(B.point_return < 0)
src << "<span class='warning'>Unable to remove this blob.</span>"
return
if(istype(B, /obj/effect/blob/core))
src << "Unable to remove this blob."
if(max_blob_points < B.point_return + blob_points)
src << "<span class='warning'>You have too many resources to remove this blob!</span>"
return
if(B.point_return)
add_points(B.point_return)
src << "<span class='notice'>Gained [B.point_return] resources from removing the [B].</span>"
qdel(B)

/mob/camera/blob/verb/expand_blob_power()
@@ -146,11 +152,11 @@
return
var/obj/effect/blob/B = locate() in T
if(B)
src << "There is a blob here!"
src << "<span class='warning'>There is a blob there!</span>"
return
var/obj/effect/blob/OB = locate() in circlerange(T, 1)
if(!OB)
src << "There is no blob adjacent to you."
src << "<span class='warning'>There is no blob adjacent to the target tile!</span>"
return
if(!can_buy(5))
return
@@ -166,14 +172,12 @@

/mob/camera/blob/verb/rally_spores_power()
set category = "Blob"
set name = "Rally Spores (5)"
set name = "Rally Spores"
set desc = "Rally the spores to move to your location."
var/turf/T = get_turf(src)
rally_spores(T)

/mob/camera/blob/proc/rally_spores(turf/T)
if(!can_buy(5))
return
src << "You rally your spores."
var/list/surrounding_turfs = block(locate(T.x - 1, T.y - 1, T.z), locate(T.x + 1, T.y + 1, T.z))
if(!surrounding_turfs.len)
@@ -188,11 +192,11 @@
set name = "Split consciousness (100) (One use)"
set desc = "Expend resources to attempt to produce another sentient overmind"
if(!blob_nodes || !blob_nodes.len)
src << "<span class='warning'>A node is required to birth your offspring...</span>"
src << "<span class='warning'>A node is required to produce another overmind.</span>"
return
var/obj/effect/blob/node/N = locate(/obj/effect/blob) in blob_nodes
if(!N)
src << "<span class='warning'>A node is required to birth your offspring...</span>"
src << "<span class='warning'>A node is required to produce another overmind.</span>"
return
if(!can_buy(100))
return
@@ -213,19 +217,38 @@
else
usr << "You broadcast with your minions, <B>[speak_text]</B>"
for(var/mob/living/simple_animal/hostile/blob_minion in blob_mobs)
blob_minion.say(speak_text)
if(blob_minion.stat == CONSCIOUS)
blob_minion.say(speak_text)

/mob/camera/blob/verb/chemical_reroll()
set category = "Blob"
set name = "Reactive Chemical Adaptation (50)"
set name = "Reactive Chemical Adaptation (40)"
set desc = "Replaces your chemical with a different one"
if(!can_buy(50))
if(!can_buy(40))
return
var/list/excluded = list(/datum/reagent/blob, blob_reagent_datum.type)
var/datum/reagent/blob/B = pick((typesof(/datum/reagent/blob) - excluded))
var/datum/reagent/blob/B = pick((subtypesof(/datum/reagent/blob) - blob_reagent_datum.type))
blob_reagent_datum = new B
for(var/obj/effect/blob/BL in blobs)
BL.adjustcolors(blob_reagent_datum.color)
for(var/mob/living/simple_animal/hostile/blob/BLO)
BLO.adjustcolors(blob_reagent_datum.color)
src << "Your reagent is now: <b>[blob_reagent_datum.name]</b>!"
src << "Your reagent is now: <b><font color=\"[blob_reagent_datum.color]\">[blob_reagent_datum.name]</b></font>!"
src << "The <b><font color=\"[blob_reagent_datum.color]\">[blob_reagent_datum.name]</b></font> reagent [blob_reagent_datum.description]"

/mob/camera/blob/verb/blob_help()
set category = "Blob"
set name = "*Blob Help*"
set desc = "Help on how to blob."
src << "Your blob reagent is: <b><font color=\"[blob_reagent_datum.color]\">[blob_reagent_datum.name]</b></font>!"
src << "The <b><font color=\"[blob_reagent_datum.color]\">[blob_reagent_datum.name]</b></font> reagent [blob_reagent_datum.description]"
src << "<b>As the overmind, you can control the blob!</b>"
src << "<b>You can expand, which will attack people, damage objects, or place a Normal Blob if the tile is clear.</b>"
src << "<i>Normal Blobs</i> will expand your reach and can be upgraded into special blobs that perform certain functions."
src << "<b>You can upgrade normal blobs into the following types of blob:</b>"
src << "<i>Shield Blobs</i> are strong and expensive blobs which take more damage. In additon, they are fireproof and can block air, use these to protect yourself from station fires."
src << "<i>Storage Blobs</i> are blobs which allow you to store 50 more resources. These blobs do not need to be near nodes to function."
src << "<i>Resource Blobs</i> are blobs which produce more resources for you, build as many of these as possible to consume the station. This type of blob must be placed near node blobs or your core to work."
src << "<i>Factory Blobs</i> are blobs that spawn blob spores which will attack nearby enemies. This type of blob must be placed near node blobs or your core to work."
src << "<i>Node Blobs</i> are blobs which grow, like the core. Like the core it can activate resource and factory blobs."
src << "<b>In addition to the buttons on your HUD, there are a few click shortcuts to speed up expansion and defense.</b>"
src << "<b>Shortcuts:</b> Click = Expand Blob <b>|</b> Middle Mouse Click = Rally Spores <b>|</b> Ctrl Click = Create Shield Blob <b>|</b> Alt Click = Remove Blob"
@@ -8,6 +8,7 @@
opacity = 0
anchored = 1
explosion_block = 1
var/point_return = 0 //How many points the blob gets back when it removes a blob of that type. If less than 0, blob cannot be removed.
var/health = 30
var/maxhealth = 30
var/health_regen = 2
@@ -26,6 +27,8 @@
A.blob_act()
return

/obj/effect/blob/proc/creation_action() //When it's created by the overmind, do this.
return

/obj/effect/blob/Destroy()
blobs -= src
@@ -192,15 +195,15 @@
health -= damage
update_icon()

/obj/effect/blob/proc/change_to(type)
/obj/effect/blob/proc/change_to(type, controller)
if(!ispath(type))
throw EXCEPTION("change_to(): invalid type for blob")
return
var/obj/effect/blob/B = new type(src.loc)
if(!istype(type, /obj/effect/blob/core) || !istype(type, /obj/effect/blob/node))
B.color = color
else
B.adjustcolors(color)
if(controller)
B.overmind = controller
B.creation_action()
B.adjustcolors(color)
qdel(src)
return B

@@ -80,7 +80,7 @@ var/list/slot2type = list("head" = /obj/item/clothing/head/changeling, "wear_mas

//Decide if it's ok for the lings to have a team objective
//And then set it up to be handed out in forge_changeling_objectives
var/list/team_objectives = typesof(/datum/objective/changeling_team_objective) - /datum/objective/changeling_team_objective
var/list/team_objectives = subtypesof(/datum/objective/changeling_team_objective)
var/list/possible_team_objectives = list()
for(var/T in team_objectives)
var/datum/objective/changeling_team_objective/CTO = T
@@ -159,6 +159,7 @@
user.mind.transfer_to(target)
if(ghost && ghost.mind)
ghost.mind.transfer_to(user)
else
user.key = ghost.key

user.Paralyse(2)
@@ -247,7 +247,7 @@ It also contains rune words, which are soon to be removed.
var/rune_to_scribe
var/entered_rune_name
var/list/possible_runes = list()
for(var/T in typesof(/obj/effect/rune) - /obj/effect/rune/malformed - /obj/effect/rune)
for(var/T in subtypesof(/obj/effect/rune) - /obj/effect/rune/malformed)
var/obj/effect/rune/R = T
if(initial(R.cultist_name))
possible_runes.Add(initial(R.cultist_name)) //This is to allow the menu to let cultists select runes by name rather than by object path. I don't know a better way to do this
@@ -1,5 +1,5 @@
var/list/sacrificed = list()
var/list/non_revealed_runes = (typesof(/obj/effect/rune) - /obj/effect/rune/malformed - /obj/effect/rune )
var/list/non_revealed_runes = (subtypesof(/obj/effect/rune) - /obj/effect/rune/malformed)

/*
@@ -15,6 +15,7 @@
/obj/machinery/dominator/New()
..()
SetLuminosity(2)
poi_list |= src

/obj/machinery/dominator/examine(mob/user)
..()
@@ -109,6 +110,7 @@
/obj/machinery/dominator/Destroy()
if(operating != -1)
set_broken()
poi_list.Remove(src)
return ..()

/obj/machinery/dominator/emp_act(severity)
@@ -21,6 +21,7 @@
var/list/structures = list()
var/list/conduits = list()
var/prophets_sacrificed_in_name = 0
var/image/ghostimage = null //For observer with darkness off visiblity


/mob/camera/god/New()
@@ -32,6 +33,10 @@
if(ticker && ticker.mode && ticker.mode.name == "hand of god")
addtimer(src,"forceplacenexus",1200)

ghostimage = image(src.icon,src,src.icon_state)
ghost_darkness_images |= ghostimage
updateallghostimages()


//Rebuilds the list based on the gamemode's lists
//As they are the most accurate each tick
@@ -50,7 +55,8 @@
for(var/datum/mind/F in followers)
if(F.current)
F.current << "<span class='danger'>Your god is DEAD!</span>"

ghost_darkness_images -= ghostimage
updateallghostimages()
return ..()


@@ -3,7 +3,7 @@
if(global_handofgod_traptypes.len && global_handofgod_structuretypes.len)
return

var/list/types = typesof(/obj/structure/divine) - /obj/structure/divine - /obj/structure/divine/trap
var/list/types = subtypesof(/obj/structure/divine) - /obj/structure/divine/trap
for(var/T in types)
var/obj/structure/divine/D = T
if(initial(D.constructable))
@@ -217,7 +217,7 @@

/obj/structure/divine/nexus
name = "nexus"
desc = "It anchors a deity to this world. It radiates an unusual aura. Cultists protect this at all costs. It looks well protected from explosion shock."
desc = "It anchors a deity to this world. It radiates an unusual aura. Cultists protect this at all costs. It looks well protected from explosive shock."
icon_state = "nexus"
health = 500
maxhealth = 500
@@ -399,7 +399,7 @@
user.reagents.add_reagent("hell_water",20)
else
user << "<span class='notice'>The water feels warm and soothing as you touch it. The fountain immediately dries up shortly afterwards.</span>"
user.reagents.add_reagent("doctorsdelight",20)
user.reagents.add_reagent("godblood",20)
update_icons()
spawn(time_between_uses)
if(src)
@@ -230,7 +230,7 @@ var/hsboxspawn = 1

if(!clothinfo)
clothinfo = "<b>Clothing</b> <a href='?\ref[src];hsb=hsbreag'>(Reagent Containers)</a> <a href='?\ref[src];hsb=hsbobj'>(Other Items)</a><hr><br>"
var/list/all_items = typesof(/obj/item/clothing) - /obj/item/clothing
var/list/all_items = subtypesof(/obj/item/clothing)
for(var/typekey in spawn_forbidden)
all_items -= typesof(typekey)
for(var/O in reverseRange(all_items))
@@ -244,7 +244,7 @@ var/hsboxspawn = 1

if(!reaginfo)
reaginfo = "<b>Reagent Containers</b> <a href='?\ref[src];hsb=hsbcloth'>(Clothing)</a> <a href='?\ref[src];hsb=hsbobj'>(Other Items)</a><hr><br>"
var/list/all_items = typesof(/obj/item/weapon/reagent_containers) - /obj/item/weapon/reagent_containers
var/list/all_items = subtypesof(/obj/item/weapon/reagent_containers)
for(var/typekey in spawn_forbidden)
all_items -= typesof(typekey)
for(var/O in reverseRange(all_items))
@@ -258,7 +258,7 @@ var/hsboxspawn = 1

if(!objinfo)
objinfo = "<b>Other Items</b> <a href='?\ref[src];hsb=hsbcloth'>(Clothing)</a> <a href='?\ref[src];hsb=hsbreag'>(Reagent Containers)</a><hr><br>"
var/list/all_items = typesof(/obj/item/) - typesof(/obj/item/clothing) - typesof(/obj/item/weapon/reagent_containers) - /obj/item
var/list/all_items = subtypesof(/obj/item/) - typesof(/obj/item/clothing) - typesof(/obj/item/weapon/reagent_containers)
for(var/typekey in spawn_forbidden)
all_items -= typesof(typekey)

@@ -3,7 +3,7 @@
for(var/i=1, i<=DNA_STRUC_ENZYMES_BLOCKS, i++)
avnums[i] = i

for(var/A in typesof(/datum/mutation/human) - /datum/mutation/human)
for(var/A in subtypesof(/datum/mutation/human))
var/datum/mutation/human/B = new A()
if(B.dna_block == NON_SCANNABLE)
continue
@@ -290,7 +290,7 @@ var/global/list/multiverse = list()
M.faction = list("[usr.real_name]")
if(prob(50))
var/list/all_species = list()
for(var/speciestype in typesof(/datum/species) - /datum/species)
for(var/speciestype in subtypesof(/datum/species))
var/datum/species/S = new speciestype()
if(!S.dangerous_existence)
all_species += speciestype
@@ -268,7 +268,7 @@

/datum/spellbook_entry/item/staffdoor
name = "Staff of Door Creation"
desc = "A particular staff that can mold solid metal into ornate wooden doors. Useful for getting around in the absence of other transportation. Does not work on glass."
desc = "A particular staff that can mold solid metal into ornate doors. Useful for getting around in the absence of other transportation. Does not work on glass."
item_path = /obj/item/weapon/gun/magic/staff/door
log_name = "SD"
cost = 1
@@ -350,35 +350,17 @@
limit = 3
category = "Assistance"

/datum/spellbook_entry/item/super_matter
name = "Supermatter Sword"
desc = "Buying this is an incredibly bad idea. The radiation will kill you within minutes. Please consider other options."
item_path = /obj/item/weapon/melee/supermatter_sword
log_name = "SX"
category = "Weapons"
cost = 6

/datum/spellbook_entry/item/veil_render
name = "Veil Render"
desc = "A sword that can cut through reality itself, leading to mass destruction. Remember to run after you use it!"
item_path = /obj/item/weapon/veilrender
log_name = "VR"
category = "Weapons"
limit = 2

/datum/spellbook_entry/item/mjolnir
name = "Mjolnir"
desc = "A mighty hammer on loan from Thor, God of Thunder. It crackles with barely contained power."
item_path = /obj/item/weapon/twohanded/mjollnir
log_name = "MJ"
category = "Weapons"

/datum/spellbook_entry/item/singularity_hammer
name = "Singularity Hammer"
desc = "A hammer that creates an intensely powerful field of gravity where it strikes, pulling everthing nearby to the point of impact."
item_path = /obj/item/weapon/twohanded/singularityhammer
log_name = "SI"
category = "Weapons"

/datum/spellbook_entry/summon
name = "Summon Stuff"
@@ -512,7 +494,7 @@
user << "It appears to have no author."

/obj/item/weapon/spellbook/proc/Initialize()
var/entry_types = typesof(/datum/spellbook_entry) - /datum/spellbook_entry - /datum/spellbook_entry/item - /datum/spellbook_entry/summon
var/entry_types = subtypesof(/datum/spellbook_entry) - /datum/spellbook_entry/item - /datum/spellbook_entry/summon
for(var/T in entry_types)
var/datum/spellbook_entry/E = new T
if(E.IsAvailible())
@@ -784,28 +766,8 @@
user <<"<span class='notice'>You stare at the book some more, but there doesn't seem to be anything else to learn...</span>"
return

if(user.mind.special_verbs.len)
for(var/V in user.mind.special_verbs)
user.verbs -= V

if(stored_swap.mind.special_verbs.len)
for(var/V in stored_swap.mind.special_verbs)
stored_swap.verbs -= V

var/mob/dead/observer/ghost = stored_swap.ghostize(0)

user.mind.transfer_to(stored_swap)

if(stored_swap.mind.special_verbs.len)
for(var/V in user.mind.special_verbs)
user.verbs += V

ghost.mind.transfer_to(user)
user.key = ghost.key

if(user.mind.special_verbs.len)
for(var/V in user.mind.special_verbs)
user.verbs += V
var/obj/effect/proc_holder/spell/targeted/mind_transfer/swapper = new
swapper.cast(user, stored_swap, 1)

stored_swap <<"<span class='warning'>You're suddenly somewhere else... and someone else?!</span>"
user <<"<span class='warning'>Suddenly you're staring at [src] again... where are you, who are you?!</span>"
@@ -40,12 +40,15 @@ Captain
backpack = /obj/item/weapon/storage/backpack/captain
satchel = /obj/item/weapon/storage/backpack/satchel_cap

/datum/outfit/job/captain/post_equip(mob/living/carbon/human/H)
/datum/outfit/job/captain/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
..()

var/obj/item/clothing/under/U = H.w_uniform
U.attachTie(new /obj/item/clothing/tie/medal/gold/captain())

if(visualsOnly)
return

var/obj/item/weapon/implant/loyalty/L = new/obj/item/weapon/implant/loyalty(H)
L.imp_in = H
L.implanted = 1
@@ -97,7 +100,10 @@ Head of Personnel
backpack_contents = list(/obj/item/weapon/storage/box/ids=1,\
/obj/item/weapon/melee/classic_baton/telescopic=1)

/datum/outfit/job/hop/post_equip(mob/living/carbon/human/H)
/datum/outfit/job/hop/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
..()

if(visualsOnly)
return

announce_head(H, list("Supply", "Service"))
@@ -31,12 +31,20 @@ Clown
backpack = /obj/item/weapon/storage/backpack/clown
satchel = /obj/item/weapon/storage/backpack/clown

/datum/outfit/job/clown/pre_equip(mob/living/carbon/human/H)
/datum/outfit/job/clown/pre_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
..()

if(visualsOnly)
return

H.fully_replace_character_name(H.real_name, pick(clown_names))

/datum/outfit/job/clown/post_equip(mob/living/carbon/human/H)
/datum/outfit/job/clown/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
..()

if(visualsOnly)
return

new /obj/item/weapon/reagent_containers/food/snacks/grown/banana(H.back, 50)

H.dna.add_mutation(CLOWNMUT)
@@ -76,8 +84,12 @@ Mime
backpack = /obj/item/weapon/storage/backpack/mime
satchel = /obj/item/weapon/storage/backpack/mime

/datum/outfit/job/mime/post_equip(mob/living/carbon/human/H)
/datum/outfit/job/mime/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
..()

if(visualsOnly)
return

if(H.mind)
H.mind.AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/conjure/mime_wall(null))
H.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/mime/speak(null))
@@ -144,8 +156,12 @@ Lawyer
l_hand = /obj/item/weapon/storage/briefcase
l_pocket = /obj/item/device/laser_pointer

/datum/outfit/job/lawyer/pre_equip(mob/living/carbon/human/H)
/datum/outfit/job/lawyer/pre_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
..()

if(visualsOnly)
return

var/datum/job/lawyer/J = SSjob.GetJob(H.job)
J.lawyers++
if(J.lawyers>1)
@@ -26,9 +26,12 @@ Chaplain
backpack_contents = list(/obj/item/device/camera/spooky = 1)


/datum/outfit/job/chaplain/post_equip(mob/living/carbon/human/H)
/datum/outfit/job/chaplain/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
..()

if(visualsOnly)
return

var/obj/item/weapon/storage/book/bible/B = new /obj/item/weapon/storage/book/bible/booze(H)
var/new_religion = "Christianity"
if(H.client && H.client.prefs.custom_names["religion"])
@@ -43,8 +43,12 @@ Chief Engineer
box = /obj/item/weapon/storage/box/engineer
pda_slot = slot_l_store

/datum/outfit/job/ce/post_equip(mob/living/carbon/human/H)
/datum/outfit/job/ce/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
..()

if(visualsOnly)
return

announce_head(H, list("Engineering"))

/*
@@ -45,17 +45,17 @@
/datum/job/proc/equip_items(mob/living/carbon/human/H)

//But don't override this
/datum/job/proc/equip(mob/living/carbon/human/H)
/datum/job/proc/equip(mob/living/carbon/human/H, visualsOnly = FALSE)
if(!H)
return 0

//Equip the rest of the gear
H.dna.species.before_equip_job(src, H)
H.dna.species.before_equip_job(src, H, visualsOnly)

if(outfit)
H.equipOutfit(outfit)
H.equipOutfit(outfit, visualsOnly)

H.dna.species.after_equip_job(src, H)
H.dna.species.after_equip_job(src, H, visualsOnly)

/datum/job/proc/apply_fingerprints(mob/living/carbon/human/H)
if(!istype(H))
@@ -146,27 +146,32 @@

var/pda_slot = slot_belt

/datum/outfit/job/pre_equip(mob/living/carbon/human/H)
/datum/outfit/job/pre_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
if(H.backbag == 1) //Backpack
back = backpack
else //Satchel
back = satchel

backpack_contents[box] = 1

/datum/outfit/job/post_equip(mob/living/carbon/human/H)
/datum/outfit/job/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
if(visualsOnly)
return

var/obj/item/weapon/card/id/C = H.wear_id
var/datum/job/J = SSjob.GetJob(H.job) // Not sure the best idea
C.access = J.get_access()
C.registered_name = H.real_name
C.assignment = H.job
C.update_label()
H.sec_hud_set_ID()
if(istype(C))
var/datum/job/J = SSjob.GetJob(H.job) // Not sure the best idea
C.access = J.get_access()
C.registered_name = H.real_name
C.assignment = H.job
C.update_label()
H.sec_hud_set_ID()

var/obj/item/device/pda/PDA = H.get_item_by_slot(pda_slot)
PDA.owner = H.real_name
PDA.ownjob = H.job
PDA.update_label()
if(istype(PDA))
PDA.owner = H.real_name
PDA.ownjob = H.job
PDA.update_label()

/datum/outfit/job/proc/announce_head(var/mob/living/carbon/human/H, var/channels) //tells the given channel that the given mob is the new department head. See communications.dm for valid channels.
spawn(4) //to allow some initialization
@@ -39,8 +39,12 @@ Chief Medical Officer
backpack = /obj/item/weapon/storage/backpack/medic
satchel = /obj/item/weapon/storage/backpack/satchel_med

/datum/outfit/job/cmo/post_equip(mob/living/carbon/human/H)
/datum/outfit/job/cmo/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
..()

if(visualsOnly)
return

announce_head(H, list("Medical")) //tell underlings (medical radio) they have a head

/*
@@ -40,8 +40,12 @@ Research Director
l_pocket = /obj/item/device/laser_pointer
backpack_contents = list(/obj/item/weapon/melee/classic_baton/telescopic=1)

/datum/outfit/job/rd/post_equip(mob/living/carbon/human/H)
/datum/outfit/job/rd/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
..()

if(visualsOnly)
return

announce_head(H, list("Science")) //tell underlings (science radio) they have a head

/*
@@ -50,8 +50,12 @@ Head of Security
backpack = /obj/item/weapon/storage/backpack/security
satchel = /obj/item/weapon/storage/backpack/satchel_sec

/datum/outfit/job/hos/post_equip(mob/living/carbon/human/H)
/datum/outfit/job/hos/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
..()

if(visualsOnly)
return

var/obj/item/weapon/implant/loyalty/L = new/obj/item/weapon/implant/loyalty(H)
L.imp_in = H
L.implanted = 1
@@ -101,8 +105,12 @@ Warden
backpack = /obj/item/weapon/storage/backpack/security
satchel = /obj/item/weapon/storage/backpack/satchel_sec

/datum/outfit/job/warden/post_equip(mob/living/carbon/human/H)
/datum/outfit/job/warden/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
..()

if(visualsOnly)
return

var/obj/item/weapon/implant/loyalty/L = new/obj/item/weapon/implant/loyalty(H)
L.imp_in = H
L.implanted = 1
@@ -145,11 +153,14 @@ Detective
/obj/item/weapon/melee/classic_baton/telescopic=1)
mask = /obj/item/clothing/mask/cigarette

/datum/outfit/job/detective/post_equip(mob/living/carbon/human/H)
/datum/outfit/job/detective/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
..()
var/obj/item/clothing/mask/cigarette/cig = H.wear_mask
cig.light("")

if(visualsOnly)
return

var/obj/item/weapon/implant/loyalty/L = new/obj/item/weapon/implant/loyalty(H)
L.imp_in = H
L.implanted = 1
@@ -207,11 +218,13 @@ var/list/sec_departments = list("engineering", "supply", "medical", "science")
var/destination = null
var/spawn_point = null

/datum/outfit/job/security/pre_equip(mob/living/carbon/human/H)
/datum/outfit/job/security/pre_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
..()

if(sec_departments.len)
department = pick(sec_departments)
sec_departments -= department
if(!visualsOnly)
sec_departments -= department
switch(department)
if("supply")
ears = /obj/item/device/radio/headset/headset_sec/alt/department/supply
@@ -238,18 +251,21 @@ var/list/sec_departments = list("engineering", "supply", "medical", "science")
spawn_point = locate(/obj/effect/landmark/start/depsec/science) in department_security_spawns
tie = /obj/item/clothing/tie/armband/science

/datum/outfit/job/security/post_equip(mob/living/carbon/human/H)
/datum/outfit/job/security/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
..()

var/obj/item/clothing/under/U = H.w_uniform
if(tie)
U.attachTie(new tie)

if(visualsOnly)
return

var/obj/item/weapon/implant/loyalty/L = new/obj/item/weapon/implant/loyalty(H)
L.imp_in = H
L.implanted = 1
H.sec_hud_set_implants()

var/obj/item/clothing/under/U = H.w_uniform
if(tie)
U.attachTie(new tie)

var/obj/item/weapon/card/id/W = H.wear_id
W.access |= dep_access

@@ -1,4 +1,4 @@
#define CAMERA_UPGRADE_XRAY 1
#define CAMERA_UPGRADE_XRAY 1
#define CAMERA_UPGRADE_EMP_PROOF 2
#define CAMERA_UPGRADE_MOTION 4

@@ -107,10 +107,6 @@
..()
return

/obj/machinery/camera/blob_act()
qdel(src)
return

/obj/machinery/camera/proc/setViewRange(num = 7)
src.view_range = num
cameranet.updateVisibility(src, 0)
@@ -43,7 +43,7 @@
// If it's a generic arcade machine, pick a random arcade
// circuit board for it and make the new machine
if(!circuit)
var/choice = pick(typesof(/obj/item/weapon/circuitboard/arcade) - /obj/item/weapon/circuitboard/arcade)
var/choice = pick(subtypesof(/obj/item/weapon/circuitboard/arcade))
var/obj/item/weapon/circuitboard/CB = new choice()
new CB.build_path(loc, CB)
qdel(src)
@@ -391,7 +391,7 @@ var/time_last_changed_position = 0
t1 = newJob

else if(t1 == "Unassigned")
modify.access = list()
modify.access -= get_all_accesses()

else
var/datum/job/jobdatum
@@ -64,13 +64,6 @@
set_broken()
..()


/obj/machinery/computer/blob_act()
if (prob(75))
verbs.Cut()
set_broken()
density = 0

/obj/machinery/computer/update_icon()
overlays.Cut()
if(stat & NOPOWER)
@@ -77,6 +77,10 @@ var/global/datum/crewmonitor/crewmonitor = new
src.jobs = jobs
src.interfaces = list()
src.data = list()
register_asset("crewmonitor.js",'crew.js')
register_asset("crewmonitor.css",'crew.css')
for (var/z = 1 to world.maxz)
register_asset("minimap_[z].png", file("[getMinimapFile(z)].png"))

/datum/crewmonitor/Destroy()
if (src.interfaces)
@@ -87,6 +91,8 @@ var/global/datum/crewmonitor/crewmonitor = new
return ..()

/datum/crewmonitor/proc/show(mob/mob, z)
if (mob.client)
sendResources(mob.client)
if (!z) z = mob.z

if (z > 0 && src.interfaces)
@@ -260,10 +266,11 @@ var/global/datum/crewmonitor/crewmonitor = new
sendResources(C)
initialized = TRUE

/datum/crewmonitor/proc/sendResources(client/C)
C << browse_rsc('crew.js', "crewmonitor.js")
C << browse_rsc('crew.css', "crewmonitor.css")
for (var/z = 1 to world.maxz) C << browse_rsc(file("[getMinimapFile(z)].png"), "minimap_[z].png")
/datum/crewmonitor/proc/sendResources(var/client/client)
send_asset(client, "crewmonitor.js")
send_asset(client, "crewmonitor.css")
for (var/z = 1 to world.maxz)
send_asset(client, "minimap_[z].png")

/datum/crewmonitor/proc/getMinimapFile(z)
return "data/minimaps/map_[z]"
@@ -315,7 +315,7 @@ to destroy them and players will be able to make replacements.
board_type = "machine"
origin_tech = "programming=3;engineering=5;bluespace=5;materials=4"
req_components = list(
/obj/item/bluespace_crystal = 3,
/obj/item/weapon/ore/bluespace_crystal = 3,
/obj/item/weapon/stock_parts/matter_bin = 1)

/obj/item/weapon/circuitboard/teleporter_station
@@ -324,7 +324,7 @@ to destroy them and players will be able to make replacements.
board_type = "machine"
origin_tech = "programming=4;engineering=4;bluespace=4"
req_components = list(
/obj/item/bluespace_crystal = 2,
/obj/item/weapon/ore/bluespace_crystal = 2,
/obj/item/weapon/stock_parts/capacitor = 2,
/obj/item/weapon/stock_parts/console_screen = 1)

@@ -334,7 +334,7 @@ to destroy them and players will be able to make replacements.
board_type = "machine"
origin_tech = "programming=4;engineering=3;materials=3;bluespace=4"
req_components = list(
/obj/item/bluespace_crystal = 2,
/obj/item/weapon/ore/bluespace_crystal = 2,
/obj/item/weapon/stock_parts/capacitor = 1,
/obj/item/stack/cable_coil = 1,
/obj/item/weapon/stock_parts/console_screen = 1)
@@ -110,7 +110,7 @@
|| locate(/obj/machinery/computer/cloning, get_step(src, WEST)))

occupant.notify_ghost_cloning("Your corpse has been placed into a cloning scanner. Re-enter your corpse if you want to be cloned!", source = src)

var/obj/machinery/computer/scan_consolenew/console
for(dir in list(NORTH,EAST,SOUTH,WEST))
console = locate(/obj/machinery/computer/scan_consolenew, get_step(src, dir))
@@ -167,8 +167,4 @@
if(..(user,1,0)) //don't set the machine, since there's no dialog
return

toggle_open(user)

/obj/machinery/dna_scannernew/blob_act()
if(prob(75))
qdel(src)
toggle_open(user)
@@ -2,7 +2,6 @@

/obj/item/weapon/electronics/airlock
name = "airlock electronics"

req_access = list(access_maint_tunnels)

var/list/conf_access = null
@@ -72,13 +71,9 @@
return

if (href_list["login"])
var/obj/item/I = usr.get_active_hand()
if (istype(I, /obj/item/device/pda))
var/obj/item/device/pda/pda = I
I = pda.id
if (I && src.check_access(I))
if(allowed(usr))
src.locked = 0
src.last_configurator = I:registered_name
src.last_configurator = usr.name

if (locked)
return
@@ -230,10 +230,6 @@ For the other part of the code, check silicon say.dm. Particularly robot talk.*/
qdel(src)
return

/obj/machinery/hologram/blob_act()
qdel(src)
return

/obj/machinery/hologram/holopad/Destroy()
for (var/mob/living/silicon/ai/master in masters)
clear_holo(master)
@@ -147,7 +147,7 @@ Class Procs:
if(use_power && stat == 0)
use_power(7500/severity)

new/obj/effect/overlay/temp/emp(src.loc)
PoolOrNew(/obj/effect/overlay/temp/emp, src.loc)
..()

/obj/machinery/proc/open_machine()
@@ -188,7 +188,9 @@ Class Procs:
update_icon()

/obj/machinery/blob_act()
if(prob(50))
if(!density)
qdel(src)
if(prob(75))
qdel(src)

/obj/machinery/proc/auto_use_power()
@@ -220,53 +222,6 @@ Class Procs:

////////////////////////////////////////////////////////////////////////////////////////////

/mob/proc/canUseTopic() //TODO: once finished, place these procs on the respective mob files
return

/mob/dead/observer/canUseTopic()
if(check_rights(R_ADMIN, 0))
return

/mob/living/canUseTopic(atom/movable/M, be_close = 0, no_dextery = 0)
if(incapacitated())
return
if(no_dextery)
if(be_close && in_range(M, src))
return 1
else
src << "<span class='warning'>You don't have the dexterity to do this!</span>"
return

/mob/living/carbon/human/canUseTopic(atom/movable/M, be_close = 0)
if(incapacitated() || lying )
return
if(!Adjacent(M))
if((be_close == 0) && (dna.check_mutation(TK)))
if(tkMaxRangeCheck(src, M))
return 1
return
if(!isturf(M.loc) && M.loc != src)
return
return 1

/mob/living/silicon/ai/canUseTopic(atom/movable/M, be_close = 0)
if(stat)
return
if(be_close && !in_range(M, src))
return
//stop AIs from leaving windows open and using then after they lose vision
//apc_override is needed here because AIs use their own APC when powerless
//get_turf_pixel() is because APCs in maint aren't actually in view of the inner camera
if(cameranet && !cameranet.checkTurfVis(get_turf_pixel(M)) && !apc_override)
return
return 1

/mob/living/silicon/robot/canUseTopic(atom/movable/M, be_close = 0)
if(stat || lockcharge || stunned || weakened)
return
if(be_close && !in_range(M, src))
return
return 1

/obj/machinery/attack_ai(mob/user)
if(isrobot(user))
@@ -237,7 +237,7 @@
money = 0

for(var/i = 0, i < 5, i++)
var/cointype = pick(typesof(/obj/item/weapon/coin) - /obj/item/weapon/coin)
var/cointype = pick(subtypesof(/obj/item/weapon/coin))
var/obj/item/weapon/coin/C = new cointype(loc)
random_step(C, 2, 50)

@@ -256,9 +256,9 @@
link_power_station()
component_parts = list()
component_parts += new /obj/item/weapon/circuitboard/teleporter_hub(null)
component_parts += new /obj/item/bluespace_crystal/artificial(null)
component_parts += new /obj/item/bluespace_crystal/artificial(null)
component_parts += new /obj/item/bluespace_crystal/artificial(null)
component_parts += new /obj/item/weapon/ore/bluespace_crystal/artificial(null)
component_parts += new /obj/item/weapon/ore/bluespace_crystal/artificial(null)
component_parts += new /obj/item/weapon/ore/bluespace_crystal/artificial(null)
component_parts += new /obj/item/weapon/stock_parts/matter_bin(null)
RefreshParts()

@@ -352,8 +352,8 @@
..()
component_parts = list()
component_parts += new /obj/item/weapon/circuitboard/teleporter_station(null)
component_parts += new /obj/item/bluespace_crystal/artificial(null)
component_parts += new /obj/item/bluespace_crystal/artificial(null)
component_parts += new /obj/item/weapon/ore/bluespace_crystal/artificial(null)
component_parts += new /obj/item/weapon/ore/bluespace_crystal/artificial(null)
component_parts += new /obj/item/weapon/stock_parts/capacitor(null)
component_parts += new /obj/item/weapon/stock_parts/capacitor(null)
component_parts += new /obj/item/weapon/stock_parts/console_screen(null)
@@ -113,10 +113,8 @@
malfunction()

/obj/machinery/vending/blob_act()
if(prob(75))
malfunction()
else
qdel(src)
malfunction()
..()


/obj/machinery/vending/proc/build_inventory(list/productlist, hidden=0, req_coin=0, start_empty = null)
@@ -120,8 +120,10 @@
return
var/list/occupant = list()
occupant |= mecha.occupant
mecha.occupant.sight |= SEE_TURFS
scanning = 1
mineral_scan_pulse(occupant,get_turf(loc))
spawn(equip_cooldown)
scanning = 0
mecha.occupant.sight -= SEE_TURFS

@@ -1221,7 +1221,7 @@
"backkey"=/obj/item/weapon/crowbar,
"desc"="The bluespace crystal is installed."),
//10
list("key"=/obj/item/bluespace_crystal,
list("key"=/obj/item/weapon/ore/bluespace_crystal,
"backkey"=/obj/item/weapon/screwdriver,
"desc"="Super capacitor is secured."),
//12
@@ -1417,7 +1417,7 @@
holder.icon_state = "phazon16"
else
user.visible_message("[user] removes the bluespace crystal from the [holder].", "<span class='notice'>You remove the bluespace crystal from the [holder].</span>")
new /obj/item/bluespace_crystal(get_turf(holder))
new /obj/item/weapon/ore/bluespace_crystal(get_turf(holder))
holder.icon_state = "phazon14"
if(8)
if(diff==FORWARD)
@@ -16,7 +16,7 @@

/atom/movable/MouseDrop_T(mob/living/M, mob/living/user)
. = ..()
if(can_buckle && istype(M))
if(can_buckle && istype(M) && !buckled_mob)
if(user_buckle_mob(M, user))
return 1

@@ -11,7 +11,10 @@
/obj/effect/forcefield/CanAtmosPass(turf/T)
return !density


/obj/effect/forcefield/cult
desc = "An unholy shield that blocks all attacks."
name = "glowing wall"
icon_state = "cultshield"

///////////Mimewalls///////////

@@ -20,37 +20,56 @@
spawn(10) qdel(src)

/obj/effect/overlay/temp
icon = 'icons/effects/effects.dmi'
icon_state = "nothing"
anchored = 1
layer = 4.1
mouse_opacity = 0
var/duration = 10
var/randomdir = 1

/obj/effect/overlay/temp/Destroy()
..()
return QDEL_HINT_PUTINPOOL

/obj/effect/overlay/temp/New()
if(randomdir)
dir = pick(cardinal)
flick("[icon_state]", src) //Because we might be pulling it from a pool, flick whatever icon it uses so it starts at the start of the icon's animation.
spawn(duration)
qdel(src)


/obj/effect/overlay/temp/cult
name = "unholy glow"
icon_state = "wallglow"
layer = 2.01
randomdir = 0
duration = 10

/obj/effect/overlay/temp/cult/floor
icon_state = "floorglow"
duration = 5


/obj/effect/overlay/temp/revenant
name = "spooky lights"
icon = 'icons/effects/effects.dmi'
icon_state = "purplesparkles"

/obj/effect/overlay/temp/revenant/cracks
name = "glowing cracks"
icon_state = "purplecrack"
duration = 6


/obj/effect/overlay/temp/emp
name = "emp sparks"
icon = 'icons/effects/effects.dmi'
icon_state = "empdisable"

/obj/effect/overlay/temp/emp/pulse
name = "emp pulse"
icon_state = "emp pulse"
duration = 20
duration = 8
randomdir = 0


@@ -9,7 +9,7 @@
log_game("EMP with size ([heavy_range], [light_range]) in area [epicenter.loc.name] ")

if(heavy_range > 1)
new/obj/effect/overlay/temp/emp/pulse(epicenter)
PoolOrNew(/obj/effect/overlay/temp/emp/pulse, epicenter)

if(heavy_range > light_range)
light_range = heavy_range
@@ -233,14 +233,6 @@ var/global/list/obj/item/device/pda/PDAs = list()
/obj/item/device/pda/proc/update_label()
name = "PDA-[owner] ([ownjob])" //Name generalisation

/obj/item/device/pda/proc/can_use(mob/user)
if(user && ismob(user))
if(user.incapacitated())
return 0
if(loc == user)
return 1
return 0

/obj/item/device/pda/GetAccess()
if(id)
return id.GetAccess()
@@ -252,12 +244,13 @@ var/global/list/obj/item/device/pda/PDAs = list()

/obj/item/device/pda/MouseDrop(obj/over_object, src_location, over_location)
var/mob/M = usr
if((!istype(over_object, /obj/screen)) && can_use(M))
if((!istype(over_object, /obj/screen)) && usr.canUseTopic(src))
return attack_self(M)
return

//NOTE: graphic resources are loaded on client login
/obj/item/device/pda/attack_self(mob/user)
var/datum/asset/assets = get_asset_datum(/datum/asset/simple/pda)
assets.send(user)

user.set_machine(src)

@@ -450,9 +443,8 @@ var/global/list/obj/item/device/pda/PDAs = list()
..()
var/mob/living/U = usr
//Looking for master was kind of pointless since PDAs don't appear to have one.
//if ((src in U.contents) || ( istype(loc, /turf) && in_range(src, U) ) )

if(can_use(U)) //Why reinvent the wheel? There's a proc that does exactly that.
if(usr.canUseTopic(src))
add_fingerprint(U)
U.set_machine(src)

@@ -710,7 +702,7 @@ var/global/list/obj/item/device/pda/PDAs = list()
return
if (!in_range(src, U) && loc != U)
return
if(!can_use(U))
if(!U.canUseTopic(src))
return
if(emped)
t = Gibberish(t, 100)
@@ -794,13 +786,11 @@ var/global/list/obj/item/device/pda/PDAs = list()
if(issilicon(usr))
return

if(can_use(usr))
if(usr.canUseTopic(src))
if(id)
remove_id()
else
usr << "<span class='warning'>This PDA does not have an ID in it!</span>"
else
usr << "<span class='warning'>You cannot do that while restrained!</span>"

/obj/item/device/pda/verb/verb_remove_id()
set category = "Object"
@@ -810,14 +800,11 @@ var/global/list/obj/item/device/pda/PDAs = list()
if(issilicon(usr))
return

if ( can_use(usr) )
if (usr.canUseTopic(src))
if(id)
remove_id()
else
usr << "<span class='warning'>This PDA does not have an ID in it!</span>"
else
usr << "<span class='warning'>You cannot do that while restrained!</span>"


/obj/item/device/pda/verb/verb_remove_pen()
set category = "Object"
@@ -827,7 +814,7 @@ var/global/list/obj/item/device/pda/PDAs = list()
if(issilicon(usr))
return

if ( can_use(usr) )
if (usr.canUseTopic(src))
var/obj/item/weapon/pen/O = locate() in src
if(O)
if (istype(loc, /mob))
@@ -839,8 +826,6 @@ var/global/list/obj/item/device/pda/PDAs = list()
O.loc = get_turf(src)
else
usr << "<span class='warning'>This PDA does not have a pen in it!</span>"
else
usr << "<span class='warning'>You cannot do that while restrained!</span>"

/obj/item/device/pda/proc/id_check(mob/user, choice as num)//To check for IDs; 1 for in-pda use, 2 for out of pda use.
if(choice == 1)
@@ -889,11 +874,10 @@ var/global/list/obj/item/device/pda/PDAs = list()
else
//Basic safety check. If either both objects are held by user or PDA is on ground and card is in hand.
if(((src in user.contents) && (C in user.contents)) || (istype(loc, /turf) && in_range(src, user) && (C in user.contents)) )
if( can_use(user) )//If they can still act.
if(!id_check(user, 2))
return
user << "<span class='notice'>You put the ID into \the [src]'s slot.</span>"
updateSelfDialog()//Update self dialog on success.
if(!id_check(user, 2))
return
user << "<span class='notice'>You put the ID into \the [src]'s slot.</span>"
updateSelfDialog()//Update self dialog on success.
return //Return in case of failed check or when successful.
updateSelfDialog()//For the non-input related code.
else if(istype(C, /obj/item/device/paicard) && !src.pai)
11 code/game/objects/items/toys.dm 100644 → 100755
@@ -321,8 +321,9 @@
attack_verb = list("attacked", "coloured")
var/paint_color = "#FF0000" //RGB
var/drawtype = "rune"
var/list/graffiti = list("amyjon","face","matt","revolution","engie","guy","end","dwarf","uboa","body","cyka","arrow","poseur tag")
var/list/graffiti = list("amyjon","face","matt","revolution","engie","guy","end","dwarf","uboa","body","cyka","arrow","star","poseur tag")
var/list/letters = list("a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z")
var/list/numerals = list("0","1","2","3","4","5","6","7","8","9")
var/list/oriented = list("arrow","body") // These turn to face the same way as the drawer
var/uses = 30 //0 for unlimited uses
var/instant = 0
@@ -355,7 +356,7 @@

/obj/item/toy/crayon/proc/update_window(mob/living/user)
dat += "<center><h2>Currently selected: [drawtype]</h2><br>"
dat += "<a href='?src=\ref[src];type=random_letter'>Random letter</a><a href='?src=\ref[src];type=letter'>Pick letter</a>"
dat += "<a href='?src=\ref[src];type=random_letter'>Random letter</a><a href='?src=\ref[src];type=letter'>Pick letter/number</a>"
dat += "<hr>"
dat += "<h3>Runes:</h3><br>"
dat += "<a href='?src=\ref[src];type=random_rune'>Random rune</a>"
@@ -386,7 +387,7 @@
if("random_letter")
temp = pick(letters)
if("letter")
temp = input("Choose the letter.", "Scribbles") in letters
temp = input("Choose what to write.", "Scribbles") in (letters|numerals)
if("random_rune")
temp = "rune[rand(1,6)]"
if("random_graffiti")
@@ -413,6 +414,8 @@
temp = "letter"
else if(graffiti.Find(drawtype))
temp = "graffiti"
else if(numerals.Find(drawtype))
temp = "number"

////////////////////////// GANG FUNCTIONS
var/area/territory
@@ -468,7 +471,7 @@
else
new /obj/effect/decal/cleanable/crayon(target,paint_color,drawtype,temp,graf_rot)

user << "<span class='notice'>You finish [instant ? "spraying" : "drawing"] [temp].</span>"
user << "<span class='notice'>You finish [instant ? "spraying" : "drawing"] \the [temp].</span>"
if(instant<0)
playsound(user.loc, 'sound/effects/spray.ogg', 5, 1, 5)
if(uses < 0)
@@ -67,20 +67,20 @@
timer = newtime
user << "Timer set for [timer] seconds."

/obj/item/weapon/c4/afterattack(atom/movable/target, mob/user, flag)
/obj/item/weapon/c4/afterattack(atom/movable/AM, mob/user, flag)
if (!flag)
return
if (ismob(target) || istype(target, /obj/item/weapon/storage/))
if (ismob(AM) || istype(AM, /obj/item/weapon/storage/))
return
if(loc == target)
if(loc == AM)
return

user << "<span class='notice'>You start planting the bomb...</span>"

if(do_after(user, 50, target = target) && in_range(user, target))
if(do_after(user, 50, target = AM))
if(!user.unEquip(src))
return
src.target = target
src.target = AM
loc = null

message_admins("[key_name_admin(user)](<A HREF='?_src_=holder;adminmoreinfo=\ref[user]'>?</A>) (<A HREF='?_src_=holder;adminplayerobservefollow=\ref[user]'>FLW</A>) planted [src.name] on [target.name] at ([target.x],[target.y],[target.z] - <A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[target.x];Y=[target.y];Z=[target.z]'>JMP</a>) with [timer] second fuse",0,1)
@@ -89,16 +89,21 @@
target.overlays += image_overlay
user << "<span class='notice'>You plant the bomb. Timer counting down from [timer].</span>"
spawn(timer*10)
if(target && !target.gc_destroyed)
explode(get_turf(target))
else
qdel(src)
explode()

/obj/item/weapon/c4/proc/explode(turf/location)
location.ex_act(2, target)
explosion(location,0,0,3)
/obj/item/weapon/c4/proc/explode()
if(qdeleted(src))
return
var/turf/location
if(target)
target.overlays -= image_overlay
if(!qdeleted(target))
location = get_turf(target)
target.overlays -= image_overlay
else
location = get_turf(src)
if(location)
location.ex_act(2, target)
explosion(location,0,0,3)
qdel(src)

/obj/item/weapon/c4/attack(mob/M, mob/user, def_zone)
@@ -60,8 +60,8 @@
/obj/item/clothing/suit/poncho/green,
/obj/item/clothing/suit/poncho/red)

gift_type_list += typesof(/obj/item/clothing/head/collectable) - /obj/item/clothing/head/collectable
gift_type_list += typesof(/obj/item/toy) - (((typesof(/obj/item/toy/cards) - /obj/item/toy/cards/deck) + /obj/item/toy/ammo) + /obj/item/toy) //All toys, except for abstract types and syndicate cards.
gift_type_list += subtypesof(/obj/item/clothing/head/collectable)
gift_type_list += subtypesof(/obj/item/toy) - (((typesof(/obj/item/toy/cards) - /obj/item/toy/cards/deck) + /obj/item/toy/ammo)) //All toys, except for abstract types and syndicate cards.

var/gift_type = pick(gift_type_list)

@@ -211,3 +211,6 @@
shard.Consume()
T.ChangeTurf(/turf/space)
T.CalculateAdjacentTurfs()

/obj/item/weapon/melee/supermatter_sword/add_blood()
return
@@ -12,6 +12,8 @@
cameranet.updateVisibility(src)

/obj/structure/blob_act()
if(!density)
qdel(src)
if(prob(50))
qdel(src)

@@ -20,7 +20,7 @@


//filling the barsigns list
for(var/bartype in typesof(/datum/barsign) - /datum/barsign)
for(var/bartype in subtypesof(/datum/barsign))
var/datum/barsign/signinfo = new bartype
if(!signinfo.hidden)
barsigns += signinfo
@@ -53,10 +53,9 @@
return

/obj/structure/bed/blob_act()
if(prob(75))
if(buildstacktype)
new buildstacktype(loc, buildstackamount)
qdel(src)
if(buildstacktype)
new buildstacktype(loc, buildstackamount)
qdel(src)

/obj/structure/bed/attackby(obj/item/weapon/W, mob/user, params)
if(istype(W, /obj/item/weapon/wrench))
@@ -69,9 +69,9 @@
update_icon()

/obj/structure/fireaxecabinet/blob_act()
if(prob(75) && fireaxe)
if(fireaxe)
fireaxe.loc = src.loc
qdel(src)
qdel(src)

/obj/structure/fireaxecabinet/attack_hand(mob/user)
if(open || glass_hp <= 0)
@@ -24,7 +24,6 @@
stored = new/obj/item/stack/rods(src)

/obj/structure/lattice/blob_act()
qdel(src)
return

/obj/structure/lattice/ex_act(severity, target)
@@ -131,7 +131,7 @@

/obj/structure/mirror/magic/New()
if(!choosable_races.len)
for(var/speciestype in typesof(/datum/species) - /datum/species)
for(var/speciestype in subtypesof(/datum/species))
var/datum/species/S = new speciestype()
if(!(S.id in races_blacklist))
choosable_races += S.id
@@ -142,7 +142,7 @@
..()

/obj/structure/mirror/magic/badmin/New()
for(var/speciestype in typesof(/datum/species) - /datum/species)
for(var/speciestype in subtypesof(/datum/species))
var/datum/species/S = new speciestype()
choosable_races += S.id
..()
@@ -83,7 +83,7 @@
if(tableclimber && tableclimber != user)
tableclimber.Weaken(2)
tableclimber.visible_message("<span class='warning'>[tableclimber.name] has been knocked off the table", "You're knocked off the table!", "You see [tableclimber.name] get knocked off the table</span>")

..()

/obj/structure/table/attack_tk() // no telehulk sorry
return
@@ -100,6 +100,7 @@
return !density

/obj/structure/table/MouseDrop_T(atom/movable/O, mob/user)
..()
if(ismob(O) && user == O && ishuman(user))
if(user.canmove)
climb_table(user)
@@ -46,7 +46,7 @@
var/mob/living/carbon/M = A
switch(wet)
if(TURF_WET_WATER)
if(!M.slip(4, 2, null, NO_SLIP_WHEN_WALKING))
if(!M.slip(3, 1, null, NO_SLIP_WHEN_WALKING))
M.inertia_dir = 0
return
if(TURF_WET_LUBE)
@@ -78,7 +78,7 @@
new /obj/effect/decal/cleanable/dirt(src)
return

if(istype(A, /area/crew_quarters/toilet) || istype(A, /area/crew_quarters/locker/locker_toilet) || istype(A, /area/crew_quarters/bar))
if(istype(A, /area/crew_quarters/toilet) || istype(A, /area/crew_quarters/locker/locker_toilet))
if(prob(40))
if(prob(90))
new /obj/effect/decal/cleanable/vomit/old(src)
@@ -130,4 +130,4 @@
new /obj/effect/decal/cleanable/greenglow(src) //this cleans itself up but it might startle you when you see it.
return

return
return
@@ -169,7 +169,7 @@ var/list/icons_to_ignore_at_floor_init = list("damaged1","damaged2","damaged3","

/turf/simulated/floor/narsie_act()
if(prob(20))
ChangeTurf(/turf/simulated/floor/plasteel/cult)
ChangeTurf(/turf/simulated/floor/engine/cult)

/turf/simulated/floor/can_have_cabling()
return !burnt & !broken & !lava
@@ -124,6 +124,10 @@
name = "engraved floor"
icon_state = "cult"

/turf/simulated/floor/engine/cult/New()
PoolOrNew(/obj/effect/overlay/temp/cult/floor, src)
..()

/turf/simulated/floor/engine/cult/narsie_act()
return

@@ -159,18 +163,65 @@
nitrogen = 0
temperature = TCMB

/turf/simulated/floor/plating/abductor
name = "alien floor"
icon_state = "alienpod1"

/turf/simulated/floor/plating/abductor/New()
..()
icon_state = "alienpod[rand(1,9)]"





///LAVA


/turf/simulated/floor/plating/lava
name = "lava"
icon_state = "lava"
baseturf = /turf/simulated/floor/plating/lava //lava all the way down
slowdown = 2
var/processing = 0
luminosity = 1

/turf/simulated/floor/plating/lava/airless
oxygen = 0
nitrogen = 0
temperature = TCMB

/turf/simulated/floor/plating/abductor
name = "alien floor"
icon_state = "alienpod1"
/turf/simulated/floor/plating/lava/Entered(atom/movable/AM)
burn_stuff()
if(!processing)
processing = 1
SSobj.processing |= src

/turf/simulated/floor/plating/abductor/New()
..()
icon_state = "alienpod[rand(1,9)]"
/turf/simulated/floor/plating/lava/process()
if(!contents)
processing = 0
SSobj.processing.Remove(src)
return
burn_stuff()

/turf/simulated/floor/plating/lava/proc/burn_stuff()
for(var/atom/movable/AM in contents)
if(!istype(AM))
return
if(istype(AM, /obj))
var/obj/O = AM
if(istype(O, /obj/effect/decal/cleanable/ash)) //So we don't get stuck burning the same ash pile forever
qdel(O)
return
if(O.burn_state == -1)
O.burn_state = 0 //Even fireproof things burn up in lava
O.fire_act()
else if (istype(AM, /mob/living))
var/mob/living/L = AM
L.adjustFireLoss(20)
L.adjust_fire_stacks(20)
L.IgniteMob()


/turf/simulated/floor/plating/lava/attackby(obj/item/C, mob/user, params) //Lava isn't a good foundation to build on
return
@@ -7,6 +7,10 @@
builtin_sheet = null
canSmoothWith = null

/turf/simulated/wall/cult/New()
PoolOrNew(/obj/effect/overlay/temp/cult, src)
..()

/turf/simulated/wall/cult/break_wall()
new /obj/effect/decal/cleanable/blood(src)
return (new /obj/structure/cultgirder(src))
@@ -580,7 +580,7 @@ var/list/admin_verbs_hideable = list(
var/list/Lines = file2list("config/admins.txt")
for(var/line in Lines)
var/list/splitline = text2list(line, " = ")
if(lowertext(splitline[1]) == ckey)
if(ckey(splitline[1]) == ckey)
if(splitline.len >= 2)
rank = ckeyEx(splitline[2])
break
@@ -185,7 +185,7 @@
if("turf-reference")
master.buildmode.valueholder = input(usr,"Enter variable value:" ,"Value") as turf in world
if(AREA_BUILDMODE)
var/list/gen_paths = typesof(/datum/mapGenerator) - /datum/mapGenerator
var/list/gen_paths = subtypesof(/datum/mapGenerator)

var/type = input(usr,"Select Generator Type","Type") as null|anything in gen_paths
if(!type) return
@@ -419,7 +419,7 @@ var/list/TYPES_SHORTCUTS = list(
var/global/list/g_fancy_list_of_types = null
/proc/get_fancy_list_of_types()
if (isnull(g_fancy_list_of_types)) //init
var/list/temp = sortList(typesof(/atom) - typesof(/area) - /atom - /atom/movable)
var/list/temp = sortList(subtypesof(/atom) - typesof(/area) - /atom/movable)
g_fancy_list_of_types = new(temp.len)
for(var/type in temp)
var/typename = "[type]"
@@ -627,7 +627,7 @@ var/global/list/g_fancy_list_of_types = null


var/list/outfits = list("Naked","Custom","As Job...")
var/list/paths = typesof(/datum/outfit) - /datum/outfit - typesof(/datum/outfit/job)
var/list/paths = subtypesof(/datum/outfit) - typesof(/datum/outfit/job)
for(var/path in paths)
var/datum/outfit/O = path //not much to initalize here but whatever
outfits[initial(O.name)] = path
@@ -6,7 +6,7 @@
var/list/organs = list()
switch(operation)
if("add organ")
for(var/path in typesof(/obj/item/organ/internal) - /obj/item/organ/internal)
for(var/path in subtypesof(/obj/item/organ/internal))
var/dat = replacetext("[path]", "/obj/item/organ/internal/", ":")
organs[dat] = path

@@ -16,7 +16,7 @@
organ.Insert(C)

if("add implant")
for(var/path in typesof(/obj/item/weapon/implant) - /obj/item/weapon/implant)
for(var/path in subtypesof(/obj/item/weapon/implant))
var/dat = replacetext("[path]", "/obj/item/weapon/implant/", ":")
organs[dat] = path

@@ -6,7 +6,7 @@

/obj/effect/landmark/corpse
name = "Unknown"
var/mobname = "Unknown" //Unused now but it'd fuck up maps to remove it now
var/mobname = "default" //Use for the ghost spawner variant, so they don't come out named "sleeper"
var/mobgender = MALE //Set to male by default due to the patriarchy. Other options include FEMALE and NEUTER
var/mob_species = null //Set to make them a mutant race such as lizard or skeleton
var/corpseuniform = null //Set this to an object path to have the slot filled with said object on the corpse.
@@ -45,7 +45,10 @@

/obj/effect/landmark/corpse/proc/createCorpse(death, ckey) //Creates a mob and checks for gear in each slot before attempting to equip it.
var/mob/living/carbon/human/M = new /mob/living/carbon/human (src.loc)
M.real_name = src.name
if(mobname != "default")
M.real_name = mobname
else
M.real_name = src.name
M.gender = src.mobgender
if(mob_species)
M.set_species(mob_species)
@@ -295,6 +298,7 @@
/obj/effect/landmark/corpse/commander/alive
death = FALSE
roundstart = FALSE
mobname = "Nanotrasen Commander"
name = "sleeper"
icon = 'icons/obj/Cryogenic2.dmi'
icon_state = "sleeper"
@@ -0,0 +1,206 @@
#define ASSET_CACHE_SEND_TIMEOUT 25 // Amount of time MAX to send an asset, if this get exceeded we cancel the sleeping.

//List of ALL assets for the above, format is list(filename = asset).
/var/global/list/asset_cache = list()

/client
var/list/cache = list() // List of all assets sent to this client by the asset cache.
var/list/completed_asset_jobs = list() // List of all completed jobs, awaiting acknowledgement.
var/list/sending = list()
var/last_asset_job = 0 // Last job done.

//This proc sends the asset to the client, but only if it needs it.
/proc/send_asset(var/client/client, var/asset_name, var/verify = TRUE)
if(!istype(client))
if(ismob(client))
var/mob/M = client
if(M.client)
client = M.client

else
return 0

else
return 0

if(client.cache.Find(asset_name) || client.sending.Find(asset_name))
return 0

client << browse_rsc(asset_cache[asset_name], asset_name)
if(!verify || !winexists(client, "asset_cache_browser")) // Can't access the asset cache browser, rip.
client.cache += asset_name
return 1

client.sending |= asset_name
var/job = ++client.last_asset_job

client << browse({"
<script>
window.location.href="?asset_cache_confirm_arrival=[job]"
</script>
"}, "window=asset_cache_browser")

var/t = 0
var/timeout_time = ASSET_CACHE_SEND_TIMEOUT * client.sending.len
while(client && !client.completed_asset_jobs.Find(job) && t < timeout_time) // Reception is handled in Topic()
sleep(1) // Lock up the caller until this is received.
t++

if(client)
client.sending -= asset_name
client.cache |= asset_name
client.completed_asset_jobs -= job

return 1

/proc/send_asset_list(var/client/client, var/list/asset_list, var/verify = TRUE)
if(!istype(client))
if(ismob(client))
var/mob/M = client
if(M.client)
client = M.client

else
return 0

else
return 0

var/list/unreceived = asset_list - (client.cache + client.sending)
if(!unreceived || !unreceived.len)
return 0

for(var/asset in unreceived)
if (asset in asset_cache)
client << browse_rsc(asset_cache[asset], asset)

if(!verify || !winexists(client, "asset_cache_browser")) // Can't access the asset cache browser, rip.
client.cache += unreceived
return 1

client.sending |= unreceived
var/job = ++client.last_asset_job

client << browse({"
<script>
window.location.href="?asset_cache_confirm_arrival=[job]"
</script>
"}, "window=asset_cache_browser")

var/t = 0
var/timeout_time = ASSET_CACHE_SEND_TIMEOUT * client.sending.len
while(client && !client.completed_asset_jobs.Find(job) && t < timeout_time) // Reception is handled in Topic()
sleep(1) // Lock up the caller until this is received.
t++

if(client)
client.sending -= unreceived
client.cache |= unreceived
client.completed_asset_jobs -= job

return 1

//This proc will download the files without clogging up the browse() queue, used for passively sending files on connection start.
proc/getFilesSlow(var/client/client, var/list/files, var/register_asset = TRUE)
for(var/file in files)
if (register_asset)
register_asset(file,files[file])
send_asset(client,file)

//This proc "registers" an asset, it adds it to the cache for further use, you cannot touch it from this point on or you'll fuck things up.
//if it's an icon or something be careful, you'll have to copy it before further use.
/proc/register_asset(var/asset_name, var/asset)
asset_cache[asset_name] = asset

//From here on out it's populating the asset cache.
/proc/populate_asset_cache()
for(var/type in typesof(/datum/asset) - list(/datum/asset, /datum/asset/simple))
var/datum/asset/A = new type()
A.register()

//These datums are used to populate the asset cache, the proc "register()" does this.

//all of our asset datums, used for referring to these later
/var/global/list/asset_datums = list()

//get a assetdatum or make a new one
/proc/get_asset_datum(var/type)
if (!(type in asset_datums))
return new type()
return asset_datums[type]

/datum/asset/New()
asset_datums[type] = src

/datum/asset/proc/register()
return

/datum/asset/proc/send(client)
return

//If you don't need anything complicated.
/datum/asset/simple
var/assets = list()
var/verify = FALSE

/datum/asset/simple/register()
for(var/asset_name in assets)
register_asset(asset_name, assets[asset_name])
/datum/asset/simple/send(client)
send_asset_list(client,assets,verify)


//DEFINITIONS FOR ASSET DATUMS START HERE.


/datum/asset/simple/pda
assets = list(
"pda_atmos.png" = 'icons/pda_icons/pda_atmos.png',
"pda_back.png" = 'icons/pda_icons/pda_back.png',
"pda_bell.png" = 'icons/pda_icons/pda_bell.png',
"pda_blank.png" = 'icons/pda_icons/pda_blank.png',
"pda_boom.png" = 'icons/pda_icons/pda_boom.png',
"pda_bucket.png" = 'icons/pda_icons/pda_bucket.png',
"pda_medbot.png" = 'icons/pda_icons/pda_medbot.png',
"pda_floorbot.png" = 'icons/pda_icons/pda_floorbot.png',
"pda_cleanbot.png" = 'icons/pda_icons/pda_cleanbot.png',
"pda_crate.png" = 'icons/pda_icons/pda_crate.png',
"pda_cuffs.png" = 'icons/pda_icons/pda_cuffs.png',
"pda_eject.png" = 'icons/pda_icons/pda_eject.png',
"pda_exit.png" = 'icons/pda_icons/pda_exit.png',
"pda_flashlight.png" = 'icons/pda_icons/pda_flashlight.png',
"pda_honk.png" = 'icons/pda_icons/pda_honk.png',
"pda_mail.png" = 'icons/pda_icons/pda_mail.png',
"pda_medical.png" = 'icons/pda_icons/pda_medical.png',
"pda_menu.png" = 'icons/pda_icons/pda_menu.png',
"pda_mule.png" = 'icons/pda_icons/pda_mule.png',
"pda_notes.png" = 'icons/pda_icons/pda_notes.png',
"pda_power.png" = 'icons/pda_icons/pda_power.png',
"pda_rdoor.png" = 'icons/pda_icons/pda_rdoor.png',
"pda_reagent.png" = 'icons/pda_icons/pda_reagent.png',
"pda_refresh.png" = 'icons/pda_icons/pda_refresh.png',
"pda_scanner.png" = 'icons/pda_icons/pda_scanner.png',
"pda_signaler.png" = 'icons/pda_icons/pda_signaler.png',
"pda_status.png" = 'icons/pda_icons/pda_status.png'
)

/datum/asset/simple/paper
assets = list(
"large_stamp-clown.png" = 'icons/stamp_icons/large_stamp-clown.png',
"large_stamp-deny.png" = 'icons/stamp_icons/large_stamp-deny.png',
"large_stamp-ok.png" = 'icons/stamp_icons/large_stamp-ok.png',
"large_stamp-hop.png" = 'icons/stamp_icons/large_stamp-hop.png',
"large_stamp-cmo.png" = 'icons/stamp_icons/large_stamp-cmo.png',
"large_stamp-ce.png" = 'icons/stamp_icons/large_stamp-ce.png',
"large_stamp-hos.png" = 'icons/stamp_icons/large_stamp-hos.png',
"large_stamp-rd.png" = 'icons/stamp_icons/large_stamp-rd.png',
"large_stamp-cap.png" = 'icons/stamp_icons/large_stamp-cap.png',
"large_stamp-qm.png" = 'icons/stamp_icons/large_stamp-qm.png',
"large_stamp-law.png" = 'icons/stamp_icons/large_stamp-law.png'
)

//Registers HTML Interface assets.
/datum/asset/HTML_interface/register()
for(var/path in typesof(/datum/html_interface))
var/datum/html_interface/hi = new path()
hi.registerResources()