Merge branch 'master' into ALRAUNE_STUFF

This commit is contained in:
Cameron653
2018-07-23 20:08:30 -04:00
committed by GitHub
314 changed files with 40595 additions and 337577 deletions
+4
View File
@@ -219,3 +219,7 @@
#define SUIT_SENSOR_BINARY 1
#define SUIT_SENSOR_VITAL 2
#define SUIT_SENSOR_TRACKING 3
// Hair Defines
#define HAIR_VERY_SHORT 0x1
#define HAIR_TIEABLE 0x4
+3
View File
@@ -177,6 +177,9 @@
#define O_LIVER "liver"
#define O_KIDNEYS "kidneys"
#define O_APPENDIX "appendix"
#define O_VOICE "voicebox"
// Non-Standard organs
#define O_PLASMA "plasma vessel"
#define O_HIVE "hive node"
#define O_NUTRIENT "nutrient vessel"
+1
View File
@@ -50,6 +50,7 @@
#define LANGUAGE_MINBUS "Minbus"
#define LANGUAGE_EVENT1 "Occursus"
#define LANGUAGE_AKHANI "Akhani"
#define LANGUAGE_ALAI "Alai"
// Language flags.
#define WHITELISTED 1 // Language is available if the speaker is whitelisted.
+2 -1
View File
@@ -31,7 +31,7 @@ var/global/list/runlevel_flags = list(RUNLEVEL_LOBBY, RUNLEVEL_SETUP, RUNLEVEL_G
#define INIT_ORDER_DEFAULT 0
#define INIT_ORDER_LIGHTING 0
#define INIT_ORDER_AIR -1
#define INIT_ORDER_HOLOMAPS -5
#define INIT_ORDER_PLANETS -4
#define INIT_ORDER_OVERLAY -6
#define INIT_ORDER_XENOARCH -20
@@ -44,6 +44,7 @@ var/global/list/runlevel_flags = list(RUNLEVEL_LOBBY, RUNLEVEL_SETUP, RUNLEVEL_G
#define FIRE_PRIORITY_AIRFLOW 30
#define FIRE_PRIORITY_AIR 35
#define FIRE_PRIORITY_DEFAULT 50
#define FIRE_PRIORITY_PLANETS 75
#define FIRE_PRIORITY_MACHINES 100
#define FIRE_PRIORITY_OVERLAYS 500
+1
View File
@@ -0,0 +1 @@
#define INIT_ORDER_HOLOMAPS -5 //VOREStation Add
+13 -1
View File
@@ -12,4 +12,16 @@
var/area/A = locate(areapath) // Check if it actually exists
if(istype(A) && A.z in using_map.player_levels)
grand_list_of_areas += A
return grand_list_of_areas
return grand_list_of_areas
/** Checks if any living humans are in a given area! */
/proc/is_area_occupied(var/area/myarea)
// Testing suggests looping over human_mob_list is quicker than looping over area contents
for(var/mob/living/carbon/human/H in human_mob_list)
if(H.stat >= DEAD) //Conditions for exclusion here, like if disconnected people start blocking it.
continue
var/area/A = get_area(H)
if(A == myarea) //The loc of a turf is the area it is in.
return 1
return 0
+4
View File
@@ -60,6 +60,7 @@ var/list/gamemode_cache = list()
var/humans_need_surnames = 0
var/allow_random_events = 0 // enables random events mid-round when set to 1
var/allow_ai = 1 // allow ai job
var/allow_ai_drones = 0 // allow ai controlled drones
var/hostedby = null
var/respawn = 1
var/guest_jobban = 1
@@ -400,6 +401,9 @@ var/list/gamemode_cache = list()
if ("allow_ai")
config.allow_ai = 1
if ("allow_ai_drones")
config.allow_ai_drones = 1
// if ("authentication")
// config.enable_authentication = 1
+183
View File
@@ -0,0 +1,183 @@
SUBSYSTEM_DEF(planets)
name = "Planets"
init_order = INIT_ORDER_PLANETS
priority = FIRE_PRIORITY_PLANETS
wait = 2 SECONDS
flags = SS_BACKGROUND
runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME
var/list/new_outdoor_turfs = list()
var/list/new_outdoor_walls = list()
var/list/planets = list()
var/list/z_to_planet = list()
var/list/currentrun = list()
var/list/needs_sun_update = list()
var/list/needs_temp_update = list()
/datum/controller/subsystem/planets/Initialize(timeofday)
admin_notice("<span class='danger'>Initializing planetary weather.</span>", R_DEBUG)
createPlanets()
allocateTurfs(TRUE)
..()
/datum/controller/subsystem/planets/proc/createPlanets()
var/list/planet_datums = subtypesof(/datum/planet)
for(var/P in planet_datums)
var/datum/planet/NP = new P()
planets.Add(NP)
for(var/Z in NP.expected_z_levels)
if(Z > z_to_planet.len)
z_to_planet.len = Z
if(z_to_planet[Z])
admin_notice("<span class='danger'>Z[Z] is shared by more than one planet!</span>", R_DEBUG)
continue
z_to_planet[Z] = NP
/datum/controller/subsystem/planets/proc/addTurf(var/turf/T,var/is_edge)
if(is_edge)
new_outdoor_walls |= T
else
new_outdoor_turfs |= T
/datum/controller/subsystem/planets/proc/removeTurf(var/turf/T,var/is_edge)
if(is_edge)
new_outdoor_walls -= T
else
new_outdoor_turfs -= T
if(z_to_planet.len >= T.z)
var/datum/planet/P = z_to_planet[T.z]
if(!P)
return
if(is_edge)
P.planet_floors -= T
else
P.planet_walls -= T
/datum/controller/subsystem/planets/proc/allocateTurfs(var/initial = FALSE)
var/list/currentlist = new_outdoor_turfs
while(currentlist.len)
var/turf/simulated/OT = currentlist[currentlist.len]
currentlist.len--
if(istype(OT) && z_to_planet.len >= OT.z && z_to_planet[OT.z])
var/datum/planet/P = z_to_planet[OT.z]
P.planet_floors |= OT
OT.vis_contents |= P.weather_holder.visuals
if(!initial && MC_TICK_CHECK)
return
currentlist = new_outdoor_walls
while(currentlist.len)
var/turf/unsimulated/wall/planetary/PW = currentlist[currentlist.len]
currentlist.len--
if(istype(PW) && z_to_planet.len >= PW.z && z_to_planet[PW.z])
var/datum/planet/P = z_to_planet[PW.z]
P.planet_walls |= PW
if(!initial && MC_TICK_CHECK)
return
/datum/controller/subsystem/planets/proc/unallocateTurf(var/turf/simulated/T)
if(istype(T) && z_to_planet[T.z])
var/datum/planet/P = z_to_planet[T.z]
P.planet_floors -= T
T.vis_contents -= P.weather_holder.visuals
/datum/controller/subsystem/planets/fire(resumed = 0)
if(new_outdoor_turfs.len || new_outdoor_walls.len)
allocateTurfs()
if(!resumed)
src.currentrun = planets.Copy()
var/list/needs_sun_update = src.needs_sun_update
while(needs_sun_update.len)
var/datum/planet/P = needs_sun_update[needs_sun_update.len]
needs_sun_update.len--
updateSunlight(P)
if(MC_TICK_CHECK)
return
var/list/needs_temp_update = src.needs_temp_update
while(needs_temp_update.len)
var/datum/planet/P = needs_temp_update[needs_temp_update.len]
needs_temp_update.len--
updateTemp(P)
if(MC_TICK_CHECK)
return
var/list/currentrun = src.currentrun
while(currentrun.len)
var/datum/planet/P = currentrun[currentrun.len]
currentrun.len--
P.process(last_fire)
//Sun light needs changing
if(P.needs_work & PLANET_PROCESS_SUN)
P.needs_work &= ~PLANET_PROCESS_SUN
needs_sun_update |= P
//Temperature needs updating
if(P.needs_work & PLANET_PROCESS_TEMP)
P.needs_work &= ~PLANET_PROCESS_TEMP
needs_temp_update |= P
if(MC_TICK_CHECK)
return
/datum/controller/subsystem/planets/proc/updateSunlight(var/datum/planet/P)
// Remove old value from corners
var/list/sunlit_corners = P.sunlit_corners
var/old_lum_r = -P.sun["lum_r"]
var/old_lum_g = -P.sun["lum_g"]
var/old_lum_b = -P.sun["lum_b"]
if(old_lum_r || old_lum_g || old_lum_b)
for(var/C in sunlit_corners)
var/datum/lighting_corner/LC = C
LC.update_lumcount(old_lum_r, old_lum_g, old_lum_b)
CHECK_TICK
sunlit_corners.Cut()
// Calculate new values to apply
var/new_brightness = P.sun["brightness"]
var/new_color = P.sun["color"]
var/lum_r = new_brightness * GetRedPart (new_color) / 255
var/lum_g = new_brightness * GetGreenPart(new_color) / 255
var/lum_b = new_brightness * GetBluePart (new_color) / 255
var/static/update_gen = -1 // Used to prevent double-processing corners. Otherwise would happen when looping over adjacent turfs.
for(var/I in P.planet_floors)
var/turf/simulated/T = I
if(!T.lighting_corners_initialised)
T.generate_missing_corners()
for(var/C in T.get_corners())
var/datum/lighting_corner/LC = C
if(LC.update_gen != update_gen && LC.active)
sunlit_corners += LC
LC.update_gen = update_gen
LC.update_lumcount(lum_r, lum_g, lum_b)
CHECK_TICK
update_gen--
P.sun["lum_r"] = lum_r
P.sun["lum_g"] = lum_g
P.sun["lum_b"] = lum_b
/datum/controller/subsystem/planets/proc/updateTemp(var/datum/planet/P)
//Set new temperatures
for(var/W in P.planet_walls)
var/turf/unsimulated/wall/planetary/wall = W
wall.set_temperature(P.weather_holder.temperature)
CHECK_TICK
/datum/controller/subsystem/planets/proc/weatherDisco()
var/count = 100000
while(count > 0)
count--
for(var/planet in planets)
var/datum/planet/P = planet
if(P.weather_holder)
P.weather_holder.change_weather(pick(P.weather_holder.allowed_weather_types))
sleep(3)
+9 -3
View File
@@ -45,12 +45,18 @@ SUBSYSTEM_DEF(transcore)
current_run.len--
//Remove if not in a human anymore.
if(!imp || !ishuman(imp.loc))
if(!imp || !isorgan(imp.loc))
implants -= imp
continue
//We're in a human, at least.
var/mob/living/carbon/human/H = imp.loc
//We're in an organ, at least.
var/obj/item/organ/external/EO = imp.loc
var/mob/living/carbon/human/H = EO.owner
if(!H)
implants -= imp
continue
//In a human
BITSET(H.hud_updateflag, BACKUP_HUD)
if(H == imp.imp_in && H.mind && H.stat < DEAD)
-3
View File
@@ -133,9 +133,6 @@
if("Vote")
debug_variables(vote)
feedback_add_details("admin_verb", "DVote")
if("Planets")
debug_variables(planet_controller)
feedback_add_details("admin_verb", "DPlanets")
message_admins("Admin [key_name_admin(usr)] is debugging the [controller] controller.")
return
+2 -4
View File
@@ -84,10 +84,8 @@
for(var/mob/living/silicon/robot/robot in mob_list)
// No combat/syndicate cyborgs, no drones.
if(robot.module && robot.module.hide_on_manifest)
continue
bot[robot.name] = "[robot.modtype] [robot.braintype]"
if(!robot.scrambledcodes && !(robot.module && robot.module.hide_on_manifest))
bot[robot.name] = "[robot.modtype] [robot.braintype]"
if(heads.len > 0)
+4 -4
View File
@@ -22,16 +22,16 @@
cost = 40
containertype = /obj/structure/closet/crate/secure/gear
containername = "Security equipment crate"
access = access_security
access = access_security*/
/datum/supply_packs/munitions/egunpistol
name = "Weapons - Energy sidearms"
contains = list(/obj/item/weapon/gun/energy/gun = 2)
cost = 40
cost = 50
containertype = /obj/structure/closet/crate/secure/weapon
containername = "Energy sidearms crate"
access = access_security
*/
access = access_armory //VOREStation Edit - Guns are for the armory.
/datum/supply_packs/munitions/flareguns
name = "Weapons - Flare guns"
contains = list(
+1 -1
View File
@@ -144,7 +144,7 @@ var/global/list/PDA_Manifest = list()
for(var/mob/living/silicon/robot/robot in mob_list)
// No combat/syndicate cyborgs, no drones.
if(robot.module && robot.module.hide_on_manifest)
if(!robot.scrambledcodes && !(robot.module && robot.module.hide_on_manifest))
continue
bot[++bot.len] = list("name" = robot.real_name, "rank" = "[robot.modtype] [robot.braintype]", "active" = "Active")
+3 -1
View File
@@ -79,7 +79,9 @@
Think through your actions and make the roleplay immersive! <b>Please remember all \
rules aside from those without explicit exceptions apply to antagonists.</b>"
var/can_use_aooc = TRUE // If true, will be given the AOOC verb, along with the ability to use it.
// var/can_use_aooc = TRUE // If true, will be given the AOOC verb, along with the ability to use it.
var/can_hear_aooc = TRUE // If FALSE, the antag can neither speak nor hear AOOC. If TRUE, they can at least hear it.
var/can_speak_aooc = TRUE // If TRUE, the antag can freely spean in AOOC.
/datum/antagonist/New()
..()
+1 -1
View File
@@ -36,7 +36,7 @@
and it otherwise has no bearing on your round.</span>"
player.current.verbs |= /mob/living/proc/write_ambition
if(can_use_aooc)
if(can_speak_aooc)
player.current.client.verbs += /client/proc/aooc
// Handle only adding a mind and not bothering with gear etc.
+2 -1
View File
@@ -25,7 +25,8 @@ var/datum/antagonist/ert/ert
initial_spawn_req = 5
initial_spawn_target = 7
can_use_aooc = FALSE // They're the good guys.
can_hear_aooc = FALSE // They're the good guys.
can_speak_aooc = FALSE // Just in case the above var bugs, or gets touched.
/datum/antagonist/ert/create_default(var/mob/source)
var/mob/living/carbon/human/M = ..()
+1 -1
View File
@@ -24,7 +24,7 @@ var/datum/antagonist/trader/traders
initial_spawn_req = 5
initial_spawn_target = 7
can_use_aooc = FALSE // They're not real antags.
can_speak_aooc = FALSE // They're not real antags.
/datum/antagonist/trader/create_default(var/mob/source)
var/mob/living/carbon/human/M = ..()
+1 -3
View File
@@ -17,7 +17,7 @@ var/datum/antagonist/renegade/renegades
Think through your actions and make the roleplay immersive! <b>Please remember all \
rules aside from those without explicit exceptions apply to antagonists.</b>"
flags = ANTAG_SUSPICIOUS | ANTAG_IMPLANT_IMMUNE | ANTAG_RANDSPAWN | ANTAG_VOTABLE
can_use_aooc = FALSE
can_speak_aooc = FALSE // They aren't 'true' antags, but they still need to hear blanket antag instructions
hard_cap = 8
hard_cap_round = 12
@@ -61,8 +61,6 @@ var/datum/antagonist/renegade/renegades
list(/obj/item/weapon/gun/projectile/luger,/obj/item/weapon/gun/projectile/luger/brown)
)
can_use_aooc = FALSE // They aren't 'true' antags.
/datum/antagonist/renegade/New()
..()
renegades = src
+1 -1
View File
@@ -15,4 +15,4 @@ var/datum/antagonist/thug/thugs
Think through your actions and make the roleplay immersive! <b>Please remember all \
rules aside from those with explicit exceptions apply to antagonists.</b>"
flags = ANTAG_SUSPICIOUS | ANTAG_IMPLANT_IMMUNE | ANTAG_RANDSPAWN | ANTAG_VOTABLE
can_use_aooc = FALSE
can_speak_aooc = FALSE
+1 -1
View File
@@ -5,7 +5,7 @@ var/datum/antagonist/traitor/traitors
id = MODE_TRAITOR
protected_jobs = list("Security Officer", "Warden", "Detective", "Internal Affairs Agent", "Head of Security", "Colony Director")
flags = ANTAG_SUSPICIOUS | ANTAG_RANDSPAWN | ANTAG_VOTABLE
can_use_aooc = FALSE
can_speak_aooc = FALSE // If they want to plot and plan as this sort of traitor, they'll need to do it ICly.
/datum/antagonist/traitor/auto
id = MODE_AUTOTRAITOR
@@ -5,12 +5,14 @@
var/list/languages
var/identifying_gender
var/list/flavour_texts
var/list/genMods
/datum/absorbed_dna/New(var/newName, var/newDNA, var/newSpecies, var/newLanguages, var/newIdentifying_Gender, var/list/newFlavour)
/datum/absorbed_dna/New(var/newName, var/newDNA, var/newSpecies, var/newLanguages, var/newIdentifying_Gender, var/list/newFlavour, var/list/newGenMods)
..()
name = newName
dna = newDNA
speciesName = newSpecies
languages = newLanguages
identifying_gender = newIdentifying_Gender
flavour_texts = newFlavour ? newFlavour.Copy() : null
flavour_texts = newFlavour ? newFlavour.Copy() : null
genMods = newGenMods ? newGenMods.Copy() : null
@@ -78,7 +78,7 @@
src << "<span class='notice'>We can now re-adapt, reverting our evolution so that we may start anew, if needed.</span>"
var/datum/absorbed_dna/newDNA = new(T.real_name, T.dna, T.species.name, T.languages, T.identifying_gender, T.flavor_texts)
var/datum/absorbed_dna/newDNA = new(T.real_name, T.dna, T.species.name, T.languages, T.identifying_gender, T.flavor_texts, T.modifiers)
absorbDNA(newDNA)
if(T.mind && T.mind.changeling)
@@ -48,6 +48,13 @@
src.UpdateAppearance()
domutcheck(src, null)
changeling_update_languages(changeling.absorbed_languages)
if(chosen_dna.genMods)
var/mob/living/carbon/human/self = src
for(var/datum/modifier/mod in self.modifiers)
self.modifiers.Remove(mod.type)
for(var/datum/modifier/mod in chosen_dna.genMods)
self.modifiers.Add(mod.type)
src.verbs -= /mob/proc/changeling_transform
spawn(10)
+1 -1
View File
@@ -83,7 +83,7 @@ The "dust" will damage the hull of the station causin minor hull breaches.
endx = world.maxx-TRANSITIONEDGE
//VOREStation Edit - No space dust outside of space
var/list/z_levels = using_map.station_levels.Copy()
for(var/datum/planet/P in planet_controller.planets)
for(var/datum/planet/P in SSplanets.planets)
z_levels.Remove(P.expected_z_levels)
var/z_level = pick(z_levels)
//VOREStation Edit End
@@ -31,7 +31,7 @@
return TRUE
/obj/item/weapon/spell/proc/within_range(var/atom/target, var/max_range = 7) // Beyond 7 is off the screen.
if(range(get_dist(owner, target) <= max_range))
if(target in view(max_range, owner))
return TRUE
return FALSE
@@ -21,11 +21,13 @@
if(!AM.loc) //Don't teleport HUD telements to us.
return
if(AM.anchored)
user << "<span class='warning'>\The [hit_atom] is firmly secured and anchored, you can't move it!</span>"
to_chat(user, "<span class='warning'>\The [hit_atom] is firmly secured and anchored, you can't move it!</span>")
return
if(!within_range(hit_atom) && !check_for_scepter())
user << "<span class='warning'>\The [hit_atom] is too far away.</span>"
to_chat(user, "<span class='warning'>\The [hit_atom] is too far away.</span>")
return
//Teleporting an item.
if(istype(hit_atom, /obj/item))
var/obj/item/I = hit_atom
@@ -47,7 +49,7 @@
//Now let's try to teleport a living mob.
else if(istype(hit_atom, /mob/living))
var/mob/living/L = hit_atom
L << "<span class='danger'>You are teleported towards \the [user].</span>"
to_chat(L, "<span class='danger'>You are teleported towards \the [user].</span>")
var/datum/effect/effect/system/spark_spread/s1 = new /datum/effect/effect/system/spark_spread
var/datum/effect/effect/system/spark_spread/s2 = new /datum/effect/effect/system/spark_spread
s1.set_up(2, 1, user)
@@ -60,7 +62,7 @@
spawn(1 SECOND)
if(!user.Adjacent(L))
user << "<span class='warning'>\The [L] is out of your reach.</span>"
to_chat(user, "<span class='warning'>\The [L] is out of your reach.</span>")
qdel(src)
return
+2
View File
@@ -149,5 +149,7 @@
feedback_set_details("religion_book","[new_book_style]")
return 1
/* If you uncomment this, every time the mob preview updates it makes a new PDA. It seems to work just fine and display without it, so why this exists, haven't a clue. -Hawk
/datum/job/chaplain/equip_preview(var/mob/living/carbon/human/H, var/alt_title)
return equip(H, alt_title, FALSE)
*/
+2 -1
View File
@@ -391,7 +391,8 @@ var/global/datum/controller/occupations/job_master
H.amend_exploitable(G.path)
if(G.slot == "implant")
H.implant_loadout(G)
var/obj/item/weapon/implant/I = G.spawn_item(H)
I.implant_loadout(H)
continue
if(G.slot && !(G.slot in custom_equip_slots))
+122 -73
View File
@@ -13,27 +13,29 @@
idle_power_usage = 40
active_power_usage = 300
var/stored_matter = 0
var/max_stored_matter = 0
var/obj/item/weapon/reagent_containers/container = null // This is the beaker that holds all of the biomass
var/print_delay = 100
var/base_print_delay = 100 // For Adminbus reasons
var/printing
var/loaded_dna //Blood sample for DNA hashing.
// These should be subtypes of /obj/item/organ
// Costs roughly 20u Phoron (1 sheet) per internal organ, limbs are 60u for limb and extremity
var/list/products = list(
"Heart" = list(/obj/item/organ/internal/heart, 25),
"Lungs" = list(/obj/item/organ/internal/lungs, 25),
"Heart" = list(/obj/item/organ/internal/heart, 20),
"Lungs" = list(/obj/item/organ/internal/lungs, 20),
"Kidneys" = list(/obj/item/organ/internal/kidneys,20),
"Eyes" = list(/obj/item/organ/internal/eyes, 20),
"Liver" = list(/obj/item/organ/internal/liver, 25),
"Arm, Left" = list(/obj/item/organ/external/arm, 65),
"Arm, Right" = list(/obj/item/organ/external/arm/right, 65),
"Leg, Left" = list(/obj/item/organ/external/leg, 65),
"Leg, Right" = list(/obj/item/organ/external/leg/right, 65),
"Foot, Left" = list(/obj/item/organ/external/foot, 40),
"Foot, Right" = list(/obj/item/organ/external/foot/right, 40),
"Hand, Left" = list(/obj/item/organ/external/hand, 40),
"Hand, Right" = list(/obj/item/organ/external/hand/right, 40)
"Liver" = list(/obj/item/organ/internal/liver, 20),
"Arm, Left" = list(/obj/item/organ/external/arm, 40),
"Arm, Right" = list(/obj/item/organ/external/arm/right, 40),
"Leg, Left" = list(/obj/item/organ/external/leg, 40),
"Leg, Right" = list(/obj/item/organ/external/leg/right, 40),
"Foot, Left" = list(/obj/item/organ/external/foot, 20),
"Foot, Right" = list(/obj/item/organ/external/foot/right, 20),
"Hand, Left" = list(/obj/item/organ/external/hand, 20),
"Hand, Right" = list(/obj/item/organ/external/hand/right, 20)
)
/obj/machinery/organ_printer/attackby(var/obj/item/O, var/mob/user)
@@ -57,25 +59,27 @@
/obj/machinery/organ_printer/New()
..()
component_parts = list()
component_parts += new /obj/item/weapon/stock_parts/matter_bin(src)
component_parts += new /obj/item/weapon/stock_parts/matter_bin(src)
component_parts += new /obj/item/weapon/stock_parts/manipulator(src)
component_parts += new /obj/item/weapon/stock_parts/manipulator(src)
RefreshParts()
/obj/machinery/organ_printer/examine(var/mob/user)
. = ..()
to_chat(user, "<span class='notice'>It is loaded with [stored_matter]/[max_stored_matter] matter units.</span>")
var/biomass = get_biomass_volume()
if(biomass)
to_chat(user, "<span class='notice'>It is loaded with [biomass] units of biomass.</span>")
else
to_chat(user, "<span class='notice'>It is not loaded with any biomass.</span>")
/obj/machinery/organ_printer/RefreshParts()
print_delay = initial(print_delay)
max_stored_matter = 0
for(var/obj/item/weapon/stock_parts/matter_bin/bin in component_parts)
max_stored_matter += bin.rating * 100
// Print Delay updating
print_delay = base_print_delay
for(var/obj/item/weapon/stock_parts/manipulator/manip in component_parts)
print_delay -= (manip.rating-1)*10
print_delay = max(0,print_delay)
. = ..()
/obj/machinery/organ_printer/attack_hand(mob/user)
@@ -91,6 +95,14 @@
to_chat(user, "<span class='notice'>\The [src] is busy!</span>")
return
if(container)
var/response = alert(user, "What do you want to do?", "Bioprinter Menu", "Print Limbs", "Cancel")
if(response == "Print Limbs")
printing_menu(user)
else
to_chat(user, "<span class='warning'>\The [src] can't operate without a reagent reservoir!</span>")
/obj/machinery/organ_printer/proc/printing_menu(mob/user)
var/choice = input("What would you like to print?") as null|anything in products
if(!choice || printing || (stat & (BROKEN|NOPOWER)))
@@ -99,7 +111,7 @@
if(!can_print(choice))
return
stored_matter -= products[choice][2]
container.reagents.remove_reagent("biomass", products[choice][2])
use_power = 2
printing = 1
@@ -118,9 +130,42 @@
print_organ(choice)
return
/obj/machinery/organ_printer/verb/eject_beaker()
set name = "Eject Beaker"
set category = "Object"
set src in oview(1)
if(usr.stat != 0)
return
add_fingerprint(usr)
remove_beaker()
return
// Does exactly what it says it does
// Returns 1 if it succeeds, 0 if it fails. Added in case someone wants to add messages to the user.
/obj/machinery/organ_printer/proc/remove_beaker()
if(container)
container.forceMove(get_turf(src))
container = null
return 1
return 0
// Checks for reagents, then reports how much biomass it has in it
/obj/machinery/organ_printer/proc/get_biomass_volume()
var/biomass_count = 0
if(container && container.reagents)
for(var/datum/reagent/R in container.reagents.reagent_list)
if(R.id == "biomass")
biomass_count += R.volume
return biomass_count
/obj/machinery/organ_printer/proc/can_print(var/choice)
if(stored_matter < products[choice][2])
visible_message("<span class='notice'>\The [src] displays a warning: 'Not enough matter. [stored_matter] stored and [products[choice][2]] needed.'</span>")
var/biomass = get_biomass_volume()
if(biomass < products[choice][2])
visible_message("<span class='notice'>\The [src] displays a warning: 'Not enough biomass. [biomass] stored and [products[choice][2]] needed.'</span>")
return 0
if(!loaded_dna || !loaded_dna["donor"])
@@ -162,6 +207,59 @@
/obj/item/weapon/stock_parts/matter_bin = 2,
/obj/item/weapon/stock_parts/manipulator = 2)
// FLESH ORGAN PRINTER
/obj/machinery/organ_printer/flesh
name = "bioprinter"
desc = "It's a machine that prints replacement organs."
icon_state = "bioprinter"
circuit = /obj/item/weapon/circuitboard/bioprinter
/obj/machinery/organ_printer/flesh/full/New()
. = ..()
container = new /obj/item/weapon/reagent_containers/glass/bottle/biomass(src)
/obj/machinery/organ_printer/flesh/dismantle()
var/turf/T = get_turf(src)
if(T)
if(container)
container.forceMove(T)
container = null
return ..()
/obj/machinery/organ_printer/flesh/print_organ(var/choice)
var/obj/item/organ/O = ..()
playsound(src.loc, 'sound/machines/ding.ogg', 50, 1)
visible_message("<span class='info'>\The [src] dings, then spits out \a [O].</span>")
return O
/obj/machinery/organ_printer/flesh/attackby(obj/item/weapon/W, mob/user)
// DNA sample from syringe.
if(istype(W,/obj/item/weapon/reagent_containers/syringe)) //TODO: Make this actually empty the syringe
var/obj/item/weapon/reagent_containers/syringe/S = W
var/datum/reagent/blood/injected = locate() in S.reagents.reagent_list //Grab some blood
if(injected && injected.data)
loaded_dna = injected.data
S.reagents.remove_reagent("blood", injected.volume)
to_chat(user, "<span class='info'>You scan the blood sample into the bioprinter.</span>")
return
else if(istype(W,/obj/item/weapon/reagent_containers/glass))
var/obj/item/weapon/reagent_containers/glass/G = W
if(container)
to_chat(user, "<span class='warning'>\The [src] already has a container loaded!</span>")
return
else if(do_after(user, 1 SECOND))
user.visible_message("[user] has loaded \the [G] into \the [src].", "You load \the [G] into \the [src].")
container = G
user.drop_item()
G.forceMove(src)
return
return ..()
// END FLESH ORGAN PRINTER
/* Roboprinter is made obsolete by the system already in place and mapped into Robotics
/obj/item/weapon/circuitboard/roboprinter
name = "roboprinter circuit"
build_path = /obj/machinery/organ_printer/robot
@@ -224,53 +322,4 @@
return
return ..()
// END ROBOT ORGAN PRINTER
// FLESH ORGAN PRINTER
/obj/machinery/organ_printer/flesh
name = "bioprinter"
desc = "It's a machine that prints replacement organs."
icon_state = "bioprinter"
circuit = /obj/item/weapon/circuitboard/bioprinter
var/amount_per_slab = 50
/obj/machinery/organ_printer/flesh/full/New()
. = ..()
stored_matter = max_stored_matter
/obj/machinery/organ_printer/flesh/dismantle()
var/turf/T = get_turf(src)
if(T)
while(stored_matter >= amount_per_slab)
stored_matter -= amount_per_slab
new /obj/item/weapon/reagent_containers/food/snacks/meat(T)
return ..()
/obj/machinery/organ_printer/flesh/print_organ(var/choice)
var/obj/item/organ/O = ..()
playsound(src.loc, 'sound/machines/ding.ogg', 50, 1)
visible_message("<span class='info'>\The [src] dings, then spits out \a [O].</span>")
return O
/obj/machinery/organ_printer/flesh/attackby(obj/item/weapon/W, mob/user)
// Load with matter for printing.
if(istype(W, /obj/item/weapon/reagent_containers/food/snacks/meat))
if((max_stored_matter - stored_matter) < amount_per_slab)
to_chat(user, "<span class='warning'>\The [src] is too full.</span>")
return
stored_matter += amount_per_slab
user.drop_item()
to_chat(user, "<span class='info'>\The [src] processes \the [W]. Levels of stored biomass now: [stored_matter]</span>")
qdel(W)
return
// DNA sample from syringe.
else if(istype(W,/obj/item/weapon/reagent_containers/syringe)) //TODO: Make this actually empty the syringe
var/obj/item/weapon/reagent_containers/syringe/S = W
var/datum/reagent/blood/injected = locate() in S.reagents.reagent_list //Grab some blood
if(injected && injected.data)
loaded_dna = injected.data
to_chat(user, "<span class='info'>You scan the blood sample into the bioprinter.</span>")
return
return ..()
// END FLESH ORGAN PRINTER
*/
+93 -39
View File
@@ -23,7 +23,7 @@
break
return selected
#define CLONE_BIOMASS 150
#define CLONE_BIOMASS 30 //VOREstation Edit
/obj/machinery/clonepod
name = "cloning pod"
@@ -33,17 +33,18 @@
circuit = /obj/item/weapon/circuitboard/clonepod
icon = 'icons/obj/cloning.dmi'
icon_state = "pod_0"
req_access = list(access_genetics) //For premature unlocking.
req_access = list(access_genetics) // For premature unlocking.
var/mob/living/occupant
var/heal_level = 20 //The clone is released once its health reaches this level.
var/heal_level = 20 // The clone is released once its health reaches this level.
var/heal_rate = 1
var/notoxin = 0
var/locked = 0
var/obj/machinery/computer/cloning/connected = null //So we remember the connected clone machine.
var/mess = 0 //Need to clean out it if it's full of exploded clone.
var/attempting = 0 //One clone attempt at a time thanks
var/eject_wait = 0 //Don't eject them as soon as they are created fuckkk
var/biomass = CLONE_BIOMASS * 3
var/mess = 0 // Need to clean out it if it's full of exploded clone.
var/attempting = 0 // One clone attempt at a time thanks
var/eject_wait = 0 // Don't eject them as soon as they are created fuckkk
var/list/containers = list() // Beakers for our liquid biomass
var/container_limit = 3 // How many beakers can the machine hold?
/obj/machinery/clonepod/New()
..()
@@ -68,11 +69,9 @@
return
if((!isnull(occupant)) && (occupant.stat != 2))
var/completion = (100 * ((occupant.health + 50) / (heal_level + 100))) // Clones start at -150 health
user << "Current clone cycle is [round(completion)]% complete."
to_chat(user, "Current clone cycle is [round(completion)]% complete.")
return
//Clonepod
//Start growing a human clone in the pod!
/obj/machinery/clonepod/proc/growclone(var/datum/dna2/record/R)
if(mess || attempting)
@@ -98,6 +97,9 @@
if(istype(modifier_type, /datum/modifier/no_clone))
return 0
// Remove biomass when the cloning is started, rather than when the guy pops out
remove_biomass(CLONE_BIOMASS)
attempting = 1 //One at a time!!
locked = 1
@@ -164,6 +166,7 @@
for(var/datum/language/L in R.languages)
H.add_language(L.name)
H.flavor_texts = R.flavor.Copy()
H.suiciding = 0
attempting = 0
@@ -171,16 +174,6 @@
//Grow clones to maturity then kick them out. FREELOADERS
/obj/machinery/clonepod/process()
var/visible_message = 0
for(var/obj/item/weapon/reagent_containers/food/snacks/meat/meat in range(1, src))
qdel(meat)
biomass += 50
visible_message = 1 // Prevent chatspam when multiple meat are near
if(visible_message)
visible_message("<span class = 'notice'>[src] sucks in and processes the nearby biomass.</span>")
if(stat & NOPOWER) //Autoeject if power is lost
if(occupant)
locked = 0
@@ -240,25 +233,28 @@
return
if(istype(W, /obj/item/weapon/card/id)||istype(W, /obj/item/device/pda))
if(!check_access(W))
user << "<span class='warning'>Access Denied.</span>"
to_chat(user, "<span class='warning'>Access Denied.</span>")
return
if((!locked) || (isnull(occupant)))
return
if((occupant.health < -20) && (occupant.stat != 2))
user << "<span class='warning'>Access Refused.</span>"
to_chat(user, "<span class='warning'>Access Refused.</span>")
return
else
locked = 0
user << "System unlocked."
else if(istype(W, /obj/item/weapon/reagent_containers/food/snacks/meat))
user << "<span class='notice'>\The [src] processes \the [W].</span>"
biomass += 50
user.drop_item()
qdel(W)
to_chat(user, "System unlocked.")
else if(istype(W,/obj/item/weapon/reagent_containers/glass))
if(LAZYLEN(containers) >= container_limit)
to_chat(user, "<span class='warning'>\The [src] has too many containers loaded!</span>")
else if(do_after(user, 1 SECOND))
user.visible_message("[user] has loaded \the [W] into \the [src].", "You load \the [W] into \the [src].")
containers += W
user.drop_item()
W.forceMove(src)
return
else if(istype(W, /obj/item/weapon/wrench))
if(locked && (anchored || occupant))
user << "<span class='warning'>Can not do that while [src] is in use.</span>"
to_chat(user, "<span class='warning'>Can not do that while [src] is in use.</span>")
else
if(anchored)
anchored = 0
@@ -274,7 +270,7 @@
else if(istype(W, /obj/item/device/multitool))
var/obj/item/device/multitool/M = W
M.connecting = src
user << "<span class='notice'>You load connection data from [src] to [M].</span>"
to_chat(user, "<span class='notice'>You load connection data from [src] to [M].</span>")
M.update_icon()
return
else
@@ -283,7 +279,7 @@
/obj/machinery/clonepod/emag_act(var/remaining_charges, var/mob/user)
if(isnull(occupant))
return
user << "You force an emergency ejection."
to_chat(user, "You force an emergency ejection.")
locked = 0
go_out()
return 1
@@ -308,10 +304,6 @@
heal_level = rating * 10 - 20
heal_rate = round(rating / 4)
if(rating >= 8)
notoxin = 1
else
notoxin = 0
/obj/machinery/clonepod/verb/eject()
set name = "Eject Cloner"
@@ -348,10 +340,66 @@
domutcheck(occupant) //Waiting until they're out before possible transforming.
occupant = null
biomass -= CLONE_BIOMASS
update_icon()
return
// Returns the total amount of biomass reagent in all of the pod's stored containers
/obj/machinery/clonepod/proc/get_biomass()
var/biomass_count = 0
if(LAZYLEN(containers))
for(var/obj/item/weapon/reagent_containers/glass/G in containers)
for(var/datum/reagent/R in G.reagents.reagent_list)
if(R.id == "biomass")
biomass_count += R.volume
return biomass_count
// Removes [amount] biomass, spread across all containers. Doesn't have any check that you actually HAVE enough biomass, though.
/obj/machinery/clonepod/proc/remove_biomass(var/amount = CLONE_BIOMASS) //Just in case it doesn't get passed a new amount, assume one clone
var/to_remove = 0 // Tracks how much biomass has been found so far
if(LAZYLEN(containers))
for(var/obj/item/weapon/reagent_containers/glass/G in containers)
if(to_remove < amount) //If we have what we need, we can stop. Checked every time we switch beakers
for(var/datum/reagent/R in G.reagents.reagent_list)
if(R.id == "biomass") // Finds Biomass
var/need_remove = max(0, amount - to_remove) //Figures out how much biomass is in this container
if(R.volume >= need_remove) //If we have more than enough in this beaker, only take what we need
R.remove_self(need_remove)
to_remove = amount
else //Otherwise, take everything and move on
to_remove += R.volume
R.remove_self(R.volume)
else
continue
else
return 1
return 0
// Empties all of the beakers from the cloning pod, used to refill it
/obj/machinery/clonepod/verb/empty_beakers()
set name = "Eject Beakers"
set category = "Object"
set src in oview(1)
if(usr.stat != 0)
return
add_fingerprint(usr)
drop_beakers()
return
// Actually does all of the beaker dropping
// Returns 1 if it succeeds, 0 if it fails. Added in case someone wants to add messages to the user.
/obj/machinery/clonepod/proc/drop_beakers()
if(LAZYLEN(containers))
var/turf/T = get_turf(src)
if(T)
for(var/obj/item/weapon/reagent_containers/glass/G in containers)
G.forceMove(T)
containers -= G
return 1
return 0
/obj/machinery/clonepod/proc/malfunction()
if(occupant)
connected_message("Critical Error!")
@@ -406,6 +454,12 @@
else if(mess)
icon_state = "pod_g"
/obj/machinery/clonepod/full/New()
..()
for(var/i = 1 to container_limit)
containers += new /obj/item/weapon/reagent_containers/glass/bottle/biomass(src)
//Health Tracker Implant
/obj/item/weapon/implant/health
@@ -475,11 +529,11 @@
/obj/item/weapon/disk/data/attack_self(mob/user as mob)
read_only = !read_only
user << "You flip the write-protect tab to [read_only ? "protected" : "unprotected"]."
to_chat(user, "You flip the write-protect tab to [read_only ? "protected" : "unprotected"].")
/obj/item/weapon/disk/data/examine(mob/user)
..(user)
user << text("The write-protect tab is set to [read_only ? "protected" : "unprotected"].")
to_chat(user, text("The write-protect tab is set to [read_only ? "protected" : "unprotected"]."))
return
/*
+4 -2
View File
@@ -200,14 +200,16 @@ GLOBAL_LIST_BOILERPLATE(all_deactivated_AI_cores, /obj/structure/AIcore/deactiva
if(!istype(transfer) || locate(/mob/living/silicon/ai) in src)
return
if(transfer.controlling_drone)
transfer.controlling_drone.release_ai_control("Unit control lost. Core transfer completed.")
transfer.aiRestorePowerRoutine = 0
transfer.control_disabled = 0
transfer.aiRadio.disabledAi = 0
transfer.loc = get_turf(src)
transfer.create_eyeobj()
transfer.cancel_camera()
user << "<span class='notice'>Transfer successful:</span> [transfer.name] placed within stationary core."
transfer << "You have been transferred into a stationary core. Remote device connection restored."
to_chat(user, "<span class='notice'>Transfer successful:</span> [transfer.name] placed within stationary core.")
to_chat(transfer, "You have been transferred into a stationary core. Remote device connection restored.")
if(card)
card.clear()
+5 -6
View File
@@ -67,7 +67,7 @@
user.drop_item()
W.loc = src
diskette = W
user << "You insert [W]."
to_chat(user, "You insert [W].")
updateUsrDialog()
return
else if(istype(W, /obj/item/device/multitool))
@@ -77,7 +77,7 @@
pods += P
P.connected = src
P.name = "[initial(P.name)] #[pods.len]"
user << "<span class='notice'>You connect [P] to [src].</span>"
to_chat(user, "<span class='notice'>You connect [P] to [src].</span>")
else if (menu == 4 && (istype(W, /obj/item/weapon/card/id) || istype(W, /obj/item/device/pda)))
if(check_access(W))
@@ -116,7 +116,7 @@
var/pods_list_ui[0]
for(var/obj/machinery/clonepod/pod in pods)
pods_list_ui[++pods_list_ui.len] = list("pod" = pod, "biomass" = pod.biomass)
pods_list_ui[++pods_list_ui.len] = list("pod" = pod, "biomass" = pod.get_biomass())
if(pods)
data["pods"] = pods_list_ui
@@ -244,7 +244,7 @@
//Look for that player! They better be dead!
if(istype(C))
//Can't clone without someone to clone. Or a pod. Or if the pod is busy. Or full of gibs.
if(!pods.len)
if(!LAZYLEN(pods))
temp = "Error: No clone pods detected."
else
var/obj/machinery/clonepod/pod = pods[1]
@@ -252,13 +252,12 @@
pod = input(usr,"Select a cloning pod to use", "Pod selection") as anything in pods
if(pod.occupant)
temp = "Error: Clonepod is currently occupied."
else if(pod.biomass < CLONE_BIOMASS)
else if(pod.get_biomass() < CLONE_BIOMASS)
temp = "Error: Not enough biomass."
else if(pod.mess)
temp = "Error: Clonepod malfunction."
else if(!config.revival_cloning)
temp = "Error: Unable to initiate cloning cycle."
else if(pod.growclone(C))
temp = "Initiating cloning cycle..."
records.Remove(C)
+3
View File
@@ -28,6 +28,9 @@
var/obj/machinery/computer3/laptop/stored_computer = null
/obj/item/device/laptop/get_cell()
return stored_computer.battery
/obj/item/device/laptop/verb/open_computer()
set name = "Open Laptop"
set category = "Object"
+2
View File
@@ -362,6 +362,8 @@
qdel(R.mmi)
for(var/obj/item/I in R.module) // the tools the borg has; metal, glass, guns etc
for(var/mob/M in I) //VOREStation edit
despawn_occupant(M)
for(var/obj/item/O in I) // the things inside the tools, if anything; mainly for janiborg trash bags
O.forceMove(R)
qdel(I)
+9
View File
@@ -47,6 +47,7 @@
var/check_synth = 0 //if active, will shoot at anything not an AI or cyborg
var/check_all = 0 //If active, will fire on anything, including synthetics.
var/ailock = 0 // AI cannot use this
var/faction = null //if set, will not fire at people in the same faction for any reason.
var/attacked = 0 //if set to 1, the turret gets pissed off and shoots at people nearby (unless they have sec access!)
@@ -80,6 +81,11 @@
lethal = 1
installation = /obj/item/weapon/gun/energy/laser
/obj/machinery/porta_turret/stationary/syndie // Generic turrets for POIs that need to not shoot their buddies.
enabled = TRUE
check_all = TRUE
faction = "syndicate" // Make sure this equals the faction that the mobs in the POI have or they will fight each other.
/obj/machinery/porta_turret/ai_defense
name = "defense turret"
desc = "This variant appears to be much more durable."
@@ -552,6 +558,9 @@ var/list/turret_icons
if(!L)
return TURRET_NOT_TARGET
if(faction && L.faction == faction)
return TURRET_NOT_TARGET
if(!emagged && issilicon(L) && check_all == 0) // Don't target silica, unless told to neutralize everything.
return TURRET_NOT_TARGET
+9 -127
View File
@@ -41,35 +41,12 @@ obj/machinery/recharger
return
if(istype(G, /obj/item/weapon/gun/energy))
var/obj/item/weapon/gun/energy/E = G
if(!E.power_supply)
to_chat(user, "<span class='notice'>Your gun has no power cell.</span>")
return
if(E.self_recharge)
to_chat(user, "<span class='notice'>Your gun has no recharge port.</span>")
return
if(istype(G, /obj/item/weapon/gun/energy/staff))
if(!G.get_cell())
to_chat(user, "This device does not have a battery installed.")
return
if(istype(G, /obj/item/device/flashlight))
var/obj/item/device/flashlight/F = G
if(!F.power_use)
return
if(!F.cell)
return
if(istype(G, /obj/item/device/laptop))
var/obj/item/device/laptop/L = G
if(!L.stored_computer.battery)
user << "There's no battery in it!"
return
if(istype(G, /obj/item/device/electronic_assembly))
var/obj/item/device/electronic_assembly/assembly = G
if(!assembly.battery)
to_chat(user, "<span class='warning'>The assembly doesn't have a power cell.</span>")
return
if(istype(G, /obj/item/weapon/weldingtool/electric))
var/obj/item/weapon/weldingtool/electric/welder = G
if(!welder.power_supply)
to_chat(user, "<span class='notice'>Your welder has no power cell.</span>")
return
user.drop_item()
G.loc = src
@@ -109,71 +86,8 @@ obj/machinery/recharger
update_use_power(1)
icon_state = icon_state_idle
else
if(istype(charging, /obj/item/weapon/gun/energy))
var/obj/item/weapon/gun/energy/E = charging
if(!E.power_supply.fully_charged())
icon_state = icon_state_charging
E.power_supply.give(active_power_usage*CELLRATE)
update_use_power(2)
else
icon_state = icon_state_charged
update_use_power(1)
return
if(istype(charging, /obj/item/weapon/gun/magnetic))
var/obj/item/weapon/gun/magnetic/M = charging
if(!M.cell.fully_charged())
icon_state = icon_state_charging
M.cell.give(active_power_usage*CELLRATE)
update_use_power(2)
else
icon_state = icon_state_charged
update_use_power(1)
return
if(istype(charging, /obj/item/weapon/melee/baton))
var/obj/item/weapon/melee/baton/B = charging
if(B.bcell)
if(!B.bcell.fully_charged())
icon_state = icon_state_charging
B.bcell.give(active_power_usage*CELLRATE)
update_use_power(2)
else
icon_state = icon_state_charged
update_use_power(1)
else
icon_state = icon_state_idle
update_use_power(1)
return
if(istype(charging, /obj/item/device/laptop))
var/obj/item/device/laptop/L = charging
if(!L.stored_computer.battery.fully_charged())
icon_state = icon_state_charging
L.stored_computer.battery.give(active_power_usage*CELLRATE)
update_use_power(2)
else
icon_state = icon_state_charged
update_use_power(1)
return
if(istype(charging, /obj/item/device/flashlight))
var/obj/item/device/flashlight/F = charging
if(F.cell)
if(!F.cell.fully_charged())
icon_state = icon_state_charging
F.cell.give(active_power_usage*CELLRATE)
update_use_power(2)
else
icon_state = icon_state_charged
update_use_power(1)
else
icon_state = icon_state_idle
update_use_power(1)
return
if(istype(charging, /obj/item/weapon/cell))
var/obj/item/weapon/cell/C = charging
var/obj/item/weapon/cell/C = charging.get_cell()
if(istype(C))
if(!C.fully_charged())
icon_state = icon_state_charging
C.give(active_power_usage*CELLRATE)
@@ -181,25 +95,9 @@ obj/machinery/recharger
else
icon_state = icon_state_charged
update_use_power(1)
return
if(istype(charging, /obj/item/device/electronic_assembly))
var/obj/item/device/electronic_assembly/assembly = charging
if(assembly.battery)
if(!assembly.battery.fully_charged())
icon_state = icon_state_charging
assembly.battery.give(active_power_usage*CELLRATE)
update_use_power(2)
else
icon_state = icon_state_charged
update_use_power(1)
else
icon_state = icon_state_idle
update_use_power(1)
return
//VOREStation Add - NSFW Batteries
if(istype(charging, /obj/item/ammo_casing/nsfw_batt))
else if(istype(charging, /obj/item/ammo_casing/nsfw_batt))
var/obj/item/ammo_casing/nsfw_batt/batt = charging
if(batt.shots_left >= initial(batt.shots_left))
icon_state = icon_state_charged
@@ -211,31 +109,16 @@ obj/machinery/recharger
return
//VOREStation Add End
if(istype(charging, /obj/item/weapon/weldingtool/electric))
var/obj/item/weapon/weldingtool/electric/C = charging
if(!C.power_supply.fully_charged())
icon_state = icon_state_charging
C.power_supply.give(active_power_usage*CELLRATE)
update_use_power(2)
else
icon_state = icon_state_charged
update_use_power(1)
return
/obj/machinery/recharger/emp_act(severity)
if(stat & (NOPOWER|BROKEN) || !anchored)
..(severity)
return
if(istype(charging, /obj/item/weapon/gun/energy))
var/obj/item/weapon/gun/energy/E = charging
if(E.power_supply)
E.power_supply.emp_act(severity)
if(charging)
var/obj/item/weapon/cell/C = charging.get_cell()
if(istype(C))
C.emp_act(severity)
else if(istype(charging, /obj/item/weapon/melee/baton))
var/obj/item/weapon/melee/baton/B = charging
if(B.bcell)
B.bcell.charge = 0
..(severity)
/obj/machinery/recharger/update_icon() //we have an update_icon() in addition to the stuff in process to make it feel a tiny bit snappier.
@@ -244,7 +127,6 @@ obj/machinery/recharger
else
icon_state = icon_state_idle
/obj/machinery/recharger/wallcharger
name = "wall recharger"
icon = 'icons/obj/stationobjs.dmi'
+1
View File
@@ -31,6 +31,7 @@ GLOBAL_LIST_BOILERPLATE(all_portals, /obj/effect/portal)
return
/obj/effect/portal/New()
..() // Necessary for the list boilerplate to work
spawn(300)
qdel(src)
return
+19 -11
View File
@@ -64,20 +64,24 @@
add_attack_logs(user,carded_ai,"Purged from AI Card")
flush = 1
carded_ai.suiciding = 1
carded_ai << "Your power has been disabled!"
to_chat(carded_ai, "Your power has been disabled!")
while (carded_ai && carded_ai.stat != 2)
if(carded_ai.controlling_drone && prob(carded_ai.oxyloss)) //You feel it creeping? Eventually will reach 100, resulting in the second half of the AI's remaining life being lonely.
carded_ai.controlling_drone.release_ai_control("Unit lost. Integrity too low to maintain connection.")
carded_ai.adjustOxyLoss(2)
carded_ai.updatehealth()
sleep(10)
flush = 0
if (href_list["radio"])
carded_ai.aiRadio.disabledAi = text2num(href_list["radio"])
carded_ai << "<span class='warning'>Your Subspace Transceiver has been [carded_ai.aiRadio.disabledAi ? "disabled" : "enabled"]!</span>"
user << "<span class='notice'>You [carded_ai.aiRadio.disabledAi ? "disable" : "enable"] the AI's Subspace Transceiver.</span>"
to_chat(carded_ai, "<span class='warning'>Your Subspace Transceiver has been [carded_ai.aiRadio.disabledAi ? "disabled" : "enabled"]!</span>")
to_chat(user, "<span class='notice'>You [carded_ai.aiRadio.disabledAi ? "disable" : "enable"] the AI's Subspace Transceiver.</span>")
if (href_list["wireless"])
carded_ai.control_disabled = text2num(href_list["wireless"])
carded_ai << "<span class='warning'>Your wireless interface has been [carded_ai.control_disabled ? "disabled" : "enabled"]!</span>"
user << "<span class='notice'>You [carded_ai.control_disabled ? "disable" : "enable"] the AI's wireless interface.</span>"
to_chat(carded_ai, "<span class='warning'>Your wireless interface has been [carded_ai.control_disabled ? "disabled" : "enabled"]!</span>")
to_chat(user, "<span class='notice'>You [carded_ai.control_disabled ? "disable" : "enable"] the AI's wireless interface.</span>")
if(carded_ai.control_disabled && carded_ai.controlling_drone)
carded_ai.controlling_drone.release_ai_control("Unit control terminated at intellicore port.")
update_icon()
return 1
@@ -94,12 +98,12 @@
icon_state = "aicard"
/obj/item/device/aicard/proc/grab_ai(var/mob/living/silicon/ai/ai, var/mob/living/user)
if(!ai.client)
user << "<span class='danger'>ERROR:</span> AI [ai.name] is offline. Unable to transfer."
if(!ai.client && !ai.controlling_drone)
to_chat(user, "<span class='danger'>ERROR:</span> AI [ai.name] is offline. Unable to transfer.")
return 0
if(carded_ai)
user << "<span class='danger'>Transfer failed:</span> Existing AI found on remote device. Remove existing AI to install a new one."
to_chat(user, "<span class='danger'>Transfer failed:</span> Existing AI found on remote device. Remove existing AI to install a new one.")
return 0
if(!user.IsAdvancedToolUser() && isanimal(user))
@@ -108,7 +112,9 @@
return 0
user.visible_message("\The [user] starts transferring \the [ai] into \the [src]...", "You start transferring \the [ai] into \the [src]...")
ai << "<span class='danger'>\The [user] is transferring you into \the [src]!</span>"
to_chat(ai, "<span class='danger'>\The [user] is transferring you into \the [src]!</span>")
if(ai.controlling_drone)
to_chat(ai.controlling_drone, "<span class='danger'>\The [user] is transferring you into \the [src]!</span>")
if(do_after(user, 100))
if(istype(ai.loc, /turf/))
@@ -124,11 +130,13 @@
ai.control_disabled = 1
ai.aiRestorePowerRoutine = 0
carded_ai = ai
if(ai.controlling_drone)
ai.controlling_drone.release_ai_control("Unit control lost.")
if(ai.client)
ai << "You have been transferred into a mobile core. Remote access lost."
to_chat(ai, "You have been transferred into a mobile core. Remote access lost.")
if(user.client)
user << "<span class='notice'><b>Transfer successful:</b></span> [ai.name] extracted from current device and placed within mobile core."
to_chat(ai, "<span class='notice'><b>Transfer successful:</b></span> [ai.name] extracted from current device and placed within mobile core.")
ai.canmove = 1
update_icon()
+252 -253
View File
@@ -1,253 +1,252 @@
// Proc: ui_interact()
// Parameters: 4 (standard NanoUI arguments)
// Description: Uses a bunch of for loops to turn lists into lists of lists, so they can be displayed in nanoUI, then displays various buttons to the user.
/obj/item/device/communicator/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/key_state = null)
// this is the data which will be sent to the ui
var/data[0] //General nanoUI information
var/communicators[0] //List of communicators
var/invites[0] //Communicators and ghosts we've invited to our communicator.
var/requests[0] //Communicators and ghosts wanting to go in our communicator.
var/voices[0] //Current /mob/living/voice s inside the device.
var/connected_communicators[0] //Current communicators connected to the device.
var/im_contacts_ui[0] //List of communicators that have been messaged.
var/im_list_ui[0] //List of messages.
var/weather[0]
var/injection = null
var/modules_ui[0] //Home screen info.
//First we add other 'local' communicators.
for(var/obj/item/device/communicator/comm in known_devices)
if(comm.network_visibility && comm.exonet)
communicators[++communicators.len] = list("name" = sanitize(comm.name), "address" = comm.exonet.address)
//Now for ghosts who we pretend have communicators.
for(var/mob/observer/dead/O in known_devices)
if(O.client && O.client.prefs.communicator_visibility == 1 && O.exonet)
communicators[++communicators.len] = list("name" = sanitize("[O.client.prefs.real_name]'s communicator"), "address" = O.exonet.address, "ref" = "\ref[O]")
//Lists all the other communicators that we invited.
for(var/obj/item/device/communicator/comm in voice_invites)
if(comm.exonet)
invites[++invites.len] = list("name" = sanitize(comm.name), "address" = comm.exonet.address, "ref" = "\ref[comm]")
//Ghosts we invited.
for(var/mob/observer/dead/O in voice_invites)
if(O.exonet && O.client)
invites[++invites.len] = list("name" = sanitize("[O.client.prefs.real_name]'s communicator"), "address" = O.exonet.address, "ref" = "\ref[O]")
//Communicators that want to talk to us.
for(var/obj/item/device/communicator/comm in voice_requests)
if(comm.exonet)
requests[++requests.len] = list("name" = sanitize(comm.name), "address" = comm.exonet.address, "ref" = "\ref[comm]")
//Ghosts that want to talk to us.
for(var/mob/observer/dead/O in voice_requests)
if(O.exonet && O.client)
requests[++requests.len] = list("name" = sanitize("[O.client.prefs.real_name]'s communicator"), "address" = O.exonet.address, "ref" = "\ref[O]")
//Now for all the voice mobs inside the communicator.
for(var/mob/living/voice/voice in contents)
voices[++voices.len] = list("name" = sanitize("[voice.name]'s communicator"), "true_name" = sanitize(voice.name))
//Finally, all the communicators linked to this one.
for(var/obj/item/device/communicator/comm in communicating)
connected_communicators[++connected_communicators.len] = list("name" = sanitize(comm.name), "true_name" = sanitize(comm.name), "ref" = "\ref[comm]")
//Devices that have been messaged or recieved messages from.
for(var/obj/item/device/communicator/comm in im_contacts)
if(comm.exonet)
im_contacts_ui[++im_contacts_ui.len] = list("name" = sanitize(comm.name), "address" = comm.exonet.address, "ref" = "\ref[comm]")
for(var/mob/observer/dead/ghost in im_contacts)
if(ghost.exonet)
im_contacts_ui[++im_contacts_ui.len] = list("name" = sanitize(ghost.name), "address" = ghost.exonet.address, "ref" = "\ref[ghost]")
//Actual messages.
for(var/I in im_list)
im_list_ui[++im_list_ui.len] = list("address" = I["address"], "to_address" = I["to_address"], "im" = I["im"])
//Weather reports.
if(planet_controller)
for(var/datum/planet/planet in planet_controller.planets)
if(planet.weather_holder && planet.weather_holder.current_weather)
var/list/W = list(
"Planet" = planet.name,
"Time" = planet.current_time.show_time("hh:mm"),
"Weather" = planet.weather_holder.current_weather.name,
"Temperature" = planet.weather_holder.temperature - T0C,
"High" = planet.weather_holder.current_weather.temp_high - T0C,
"Low" = planet.weather_holder.current_weather.temp_low - T0C)
weather[++weather.len] = W
injection = "<div>Test</div>"
//Modules for homescreen.
for(var/list/R in modules)
modules_ui[++modules_ui.len] = R
data["owner"] = owner ? owner : "Unset"
data["occupation"] = occupation ? occupation : "Swipe ID to set."
data["connectionStatus"] = get_connection_to_tcomms()
data["visible"] = network_visibility
data["address"] = exonet.address ? exonet.address : "Unallocated"
data["targetAddress"] = target_address
data["targetAddressName"] = target_address_name
data["currentTab"] = selected_tab
data["knownDevices"] = communicators
data["invitesSent"] = invites
data["requestsReceived"] = requests
data["voice_mobs"] = voices
data["communicating"] = connected_communicators
data["video_comm"] = video_source ? "\ref[video_source.loc]" : null
data["imContacts"] = im_contacts_ui
data["imList"] = im_list_ui
data["time"] = stationtime2text()
data["ring"] = ringer
data["homeScreen"] = modules_ui
data["note"] = note // current notes
data["weather"] = weather
data["aircontents"] = src.analyze_air()
data["flashlight"] = fon
data["injection"] = injection
// update the ui if it exists, returns null if no ui is passed/found
ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open)
if(!ui)
// the ui does not exist, so we'll create a new() one
// for a list of parameters and their descriptions see the code docs in \code\modules\nano\nanoui.dm
ui = new(user, src, ui_key, "communicator.tmpl", "Communicator", 475, 700, state = key_state)
// add templates for screens in common with communicator.
ui.add_template("atmosphericScan", "atmospheric_scan.tmpl")
// when the ui is first opened this is the data it will use
ui.set_initial_data(data)
// open the new ui window
ui.open()
// auto update every five Master Controller tick
ui.set_auto_update(5)
// Proc: Topic()
// Parameters: 2 (standard Topic arguments)
// Description: Responds to NanoUI button presses.
/obj/item/device/communicator/Topic(href, href_list)
if(..())
return 1
if(href_list["rename"])
var/new_name = sanitizeSafe(input(usr,"Please enter your name.","Communicator",usr.name) )
if(new_name)
register_device(new_name)
if(href_list["toggle_visibility"])
switch(network_visibility)
if(1) //Visible, becoming invisbile
network_visibility = 0
if(camera)
camera.remove_network(NETWORK_COMMUNICATORS)
if(0) //Invisible, becoming visible
network_visibility = 1
if(camera)
camera.add_network(NETWORK_COMMUNICATORS)
if(href_list["toggle_ringer"])
ringer = !ringer
if(href_list["add_hex"])
var/hex = href_list["add_hex"]
add_to_EPv2(hex)
if(href_list["write_target_address"])
var/new_address = sanitizeSafe(input(usr,"Please enter the desired target EPv2 address. Note that you must write the colons \
yourself.","Communicator",src.target_address) )
if(new_address)
target_address = new_address
if(href_list["clear_target_address"])
target_address = ""
if(href_list["dial"])
if(!get_connection_to_tcomms())
usr << "<span class='danger'>Error: Cannot connect to Exonet node.</span>"
return
var/their_address = href_list["dial"]
exonet.send_message(their_address, "voice")
if(href_list["decline"])
var/ref_to_remove = href_list["decline"]
var/atom/decline = locate(ref_to_remove)
if(decline)
del_request(decline)
if(href_list["message"])
if(!get_connection_to_tcomms())
usr << "<span class='danger'>Error: Cannot connect to Exonet node.</span>"
return
var/their_address = href_list["message"]
var/text = sanitizeSafe(input(usr,"Enter your message.","Text Message"))
if(text)
exonet.send_message(their_address, "text", text)
im_list += list(list("address" = exonet.address, "to_address" = their_address, "im" = text))
log_pda("(COMM: [src]) sent \"[text]\" to [exonet.get_atom_from_address(their_address)]", usr)
for(var/mob/M in player_list)
if(M.stat == DEAD && M.is_preference_enabled(/datum/client_preference/ghost_ears))
if(istype(M, /mob/new_player) || M.forbid_seeing_deadchat)
continue
if(exonet.get_atom_from_address(their_address) == M)
continue
M.show_message("Comm IM - [src] -> [exonet.get_atom_from_address(their_address)]: [text]")
if(href_list["disconnect"])
var/name_to_disconnect = href_list["disconnect"]
for(var/mob/living/voice/V in contents)
if(name_to_disconnect == V.name)
close_connection(usr, V, "[usr] hung up")
for(var/obj/item/device/communicator/comm in communicating)
if(name_to_disconnect == comm.name)
close_connection(usr, comm, "[usr] hung up")
if(href_list["startvideo"])
var/ref_to_video = href_list["startvideo"]
var/obj/item/device/communicator/comm = locate(ref_to_video)
if(comm)
connect_video(usr, comm)
if(href_list["endvideo"])
if(video_source)
end_video()
if(href_list["watchvideo"])
if(video_source)
watch_video(usr,video_source.loc)
if(href_list["copy"])
target_address = href_list["copy"]
if(href_list["copy_name"])
target_address_name = href_list["copy_name"]
if(href_list["hang_up"])
for(var/mob/living/voice/V in contents)
close_connection(usr, V, "[usr] hung up")
for(var/obj/item/device/communicator/comm in communicating)
close_connection(usr, comm, "[usr] hung up")
if(href_list["switch_tab"])
selected_tab = href_list["switch_tab"]
if(href_list["edit"])
var/n = input(usr, "Please enter message", name, notehtml)
n = sanitizeSafe(n, extra = 0)
if(n)
note = html_decode(n)
notehtml = note
note = replacetext(note, "\n", "<br>")
else
note = ""
notehtml = note
if(href_list["Light"])
fon = !fon
set_light(fon * flum)
nanomanager.update_uis(src)
add_fingerprint(usr)
// Proc: ui_interact()
// Parameters: 4 (standard NanoUI arguments)
// Description: Uses a bunch of for loops to turn lists into lists of lists, so they can be displayed in nanoUI, then displays various buttons to the user.
/obj/item/device/communicator/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/key_state = null)
// this is the data which will be sent to the ui
var/data[0] //General nanoUI information
var/communicators[0] //List of communicators
var/invites[0] //Communicators and ghosts we've invited to our communicator.
var/requests[0] //Communicators and ghosts wanting to go in our communicator.
var/voices[0] //Current /mob/living/voice s inside the device.
var/connected_communicators[0] //Current communicators connected to the device.
var/im_contacts_ui[0] //List of communicators that have been messaged.
var/im_list_ui[0] //List of messages.
var/weather[0]
var/injection = null
var/modules_ui[0] //Home screen info.
//First we add other 'local' communicators.
for(var/obj/item/device/communicator/comm in known_devices)
if(comm.network_visibility && comm.exonet)
communicators[++communicators.len] = list("name" = sanitize(comm.name), "address" = comm.exonet.address)
//Now for ghosts who we pretend have communicators.
for(var/mob/observer/dead/O in known_devices)
if(O.client && O.client.prefs.communicator_visibility == 1 && O.exonet)
communicators[++communicators.len] = list("name" = sanitize("[O.client.prefs.real_name]'s communicator"), "address" = O.exonet.address, "ref" = "\ref[O]")
//Lists all the other communicators that we invited.
for(var/obj/item/device/communicator/comm in voice_invites)
if(comm.exonet)
invites[++invites.len] = list("name" = sanitize(comm.name), "address" = comm.exonet.address, "ref" = "\ref[comm]")
//Ghosts we invited.
for(var/mob/observer/dead/O in voice_invites)
if(O.exonet && O.client)
invites[++invites.len] = list("name" = sanitize("[O.client.prefs.real_name]'s communicator"), "address" = O.exonet.address, "ref" = "\ref[O]")
//Communicators that want to talk to us.
for(var/obj/item/device/communicator/comm in voice_requests)
if(comm.exonet)
requests[++requests.len] = list("name" = sanitize(comm.name), "address" = comm.exonet.address, "ref" = "\ref[comm]")
//Ghosts that want to talk to us.
for(var/mob/observer/dead/O in voice_requests)
if(O.exonet && O.client)
requests[++requests.len] = list("name" = sanitize("[O.client.prefs.real_name]'s communicator"), "address" = O.exonet.address, "ref" = "\ref[O]")
//Now for all the voice mobs inside the communicator.
for(var/mob/living/voice/voice in contents)
voices[++voices.len] = list("name" = sanitize("[voice.name]'s communicator"), "true_name" = sanitize(voice.name))
//Finally, all the communicators linked to this one.
for(var/obj/item/device/communicator/comm in communicating)
connected_communicators[++connected_communicators.len] = list("name" = sanitize(comm.name), "true_name" = sanitize(comm.name), "ref" = "\ref[comm]")
//Devices that have been messaged or recieved messages from.
for(var/obj/item/device/communicator/comm in im_contacts)
if(comm.exonet)
im_contacts_ui[++im_contacts_ui.len] = list("name" = sanitize(comm.name), "address" = comm.exonet.address, "ref" = "\ref[comm]")
for(var/mob/observer/dead/ghost in im_contacts)
if(ghost.exonet)
im_contacts_ui[++im_contacts_ui.len] = list("name" = sanitize(ghost.name), "address" = ghost.exonet.address, "ref" = "\ref[ghost]")
//Actual messages.
for(var/I in im_list)
im_list_ui[++im_list_ui.len] = list("address" = I["address"], "to_address" = I["to_address"], "im" = I["im"])
//Weather reports.
for(var/datum/planet/planet in SSplanets.planets)
if(planet.weather_holder && planet.weather_holder.current_weather)
var/list/W = list(
"Planet" = planet.name,
"Time" = planet.current_time.show_time("hh:mm"),
"Weather" = planet.weather_holder.current_weather.name,
"Temperature" = planet.weather_holder.temperature - T0C,
"High" = planet.weather_holder.current_weather.temp_high - T0C,
"Low" = planet.weather_holder.current_weather.temp_low - T0C)
weather[++weather.len] = W
injection = "<div>Test</div>"
//Modules for homescreen.
for(var/list/R in modules)
modules_ui[++modules_ui.len] = R
data["owner"] = owner ? owner : "Unset"
data["occupation"] = occupation ? occupation : "Swipe ID to set."
data["connectionStatus"] = get_connection_to_tcomms()
data["visible"] = network_visibility
data["address"] = exonet.address ? exonet.address : "Unallocated"
data["targetAddress"] = target_address
data["targetAddressName"] = target_address_name
data["currentTab"] = selected_tab
data["knownDevices"] = communicators
data["invitesSent"] = invites
data["requestsReceived"] = requests
data["voice_mobs"] = voices
data["communicating"] = connected_communicators
data["video_comm"] = video_source ? "\ref[video_source.loc]" : null
data["imContacts"] = im_contacts_ui
data["imList"] = im_list_ui
data["time"] = stationtime2text()
data["ring"] = ringer
data["homeScreen"] = modules_ui
data["note"] = note // current notes
data["weather"] = weather
data["aircontents"] = src.analyze_air()
data["flashlight"] = fon
data["injection"] = injection
// update the ui if it exists, returns null if no ui is passed/found
ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open)
if(!ui)
// the ui does not exist, so we'll create a new() one
// for a list of parameters and their descriptions see the code docs in \code\modules\nano\nanoui.dm
ui = new(user, src, ui_key, "communicator.tmpl", "Communicator", 475, 700, state = key_state)
// add templates for screens in common with communicator.
ui.add_template("atmosphericScan", "atmospheric_scan.tmpl")
// when the ui is first opened this is the data it will use
ui.set_initial_data(data)
// open the new ui window
ui.open()
// auto update every five Master Controller tick
ui.set_auto_update(5)
// Proc: Topic()
// Parameters: 2 (standard Topic arguments)
// Description: Responds to NanoUI button presses.
/obj/item/device/communicator/Topic(href, href_list)
if(..())
return 1
if(href_list["rename"])
var/new_name = sanitizeSafe(input(usr,"Please enter your name.","Communicator",usr.name) )
if(new_name)
register_device(new_name)
if(href_list["toggle_visibility"])
switch(network_visibility)
if(1) //Visible, becoming invisbile
network_visibility = 0
if(camera)
camera.remove_network(NETWORK_COMMUNICATORS)
if(0) //Invisible, becoming visible
network_visibility = 1
if(camera)
camera.add_network(NETWORK_COMMUNICATORS)
if(href_list["toggle_ringer"])
ringer = !ringer
if(href_list["add_hex"])
var/hex = href_list["add_hex"]
add_to_EPv2(hex)
if(href_list["write_target_address"])
var/new_address = sanitizeSafe(input(usr,"Please enter the desired target EPv2 address. Note that you must write the colons \
yourself.","Communicator",src.target_address) )
if(new_address)
target_address = new_address
if(href_list["clear_target_address"])
target_address = ""
if(href_list["dial"])
if(!get_connection_to_tcomms())
usr << "<span class='danger'>Error: Cannot connect to Exonet node.</span>"
return
var/their_address = href_list["dial"]
exonet.send_message(their_address, "voice")
if(href_list["decline"])
var/ref_to_remove = href_list["decline"]
var/atom/decline = locate(ref_to_remove)
if(decline)
del_request(decline)
if(href_list["message"])
if(!get_connection_to_tcomms())
usr << "<span class='danger'>Error: Cannot connect to Exonet node.</span>"
return
var/their_address = href_list["message"]
var/text = sanitizeSafe(input(usr,"Enter your message.","Text Message"))
if(text)
exonet.send_message(their_address, "text", text)
im_list += list(list("address" = exonet.address, "to_address" = their_address, "im" = text))
log_pda("(COMM: [src]) sent \"[text]\" to [exonet.get_atom_from_address(their_address)]", usr)
for(var/mob/M in player_list)
if(M.stat == DEAD && M.is_preference_enabled(/datum/client_preference/ghost_ears))
if(istype(M, /mob/new_player) || M.forbid_seeing_deadchat)
continue
if(exonet.get_atom_from_address(their_address) == M)
continue
M.show_message("Comm IM - [src] -> [exonet.get_atom_from_address(their_address)]: [text]")
if(href_list["disconnect"])
var/name_to_disconnect = href_list["disconnect"]
for(var/mob/living/voice/V in contents)
if(name_to_disconnect == V.name)
close_connection(usr, V, "[usr] hung up")
for(var/obj/item/device/communicator/comm in communicating)
if(name_to_disconnect == comm.name)
close_connection(usr, comm, "[usr] hung up")
if(href_list["startvideo"])
var/ref_to_video = href_list["startvideo"]
var/obj/item/device/communicator/comm = locate(ref_to_video)
if(comm)
connect_video(usr, comm)
if(href_list["endvideo"])
if(video_source)
end_video()
if(href_list["watchvideo"])
if(video_source)
watch_video(usr,video_source.loc)
if(href_list["copy"])
target_address = href_list["copy"]
if(href_list["copy_name"])
target_address_name = href_list["copy_name"]
if(href_list["hang_up"])
for(var/mob/living/voice/V in contents)
close_connection(usr, V, "[usr] hung up")
for(var/obj/item/device/communicator/comm in communicating)
close_connection(usr, comm, "[usr] hung up")
if(href_list["switch_tab"])
selected_tab = href_list["switch_tab"]
if(href_list["edit"])
var/n = input(usr, "Please enter message", name, notehtml)
n = sanitizeSafe(n, extra = 0)
if(n)
note = html_decode(n)
notehtml = note
note = replacetext(note, "\n", "<br>")
else
note = ""
notehtml = note
if(href_list["Light"])
fon = !fon
set_light(fon * flum)
nanomanager.update_uis(src)
add_fingerprint(usr)
@@ -41,6 +41,9 @@
processing_objects -= src
return ..()
/obj/item/device/flashlight/get_cell()
return cell
/obj/item/device/flashlight/verb/toggle()
set name = "Toggle Flashlight Brightness"
set category = "Object"
@@ -38,6 +38,9 @@ var/global/list/active_radio_jammers = list()
qdel_null(power_source)
return ..()
/obj/item/device/radio_jammer/get_cell()
return power_source
/obj/item/device/radio_jammer/proc/turn_off(mob/user)
if(user)
to_chat(user,"<span class='warning'>\The [src] deactivates.</span>")
+2 -1
View File
@@ -52,8 +52,9 @@
/obj/structure/largecrate/animal/crashedshuttle
name = "SCP"
/obj/structure/largecrate/animal/crashedshuttle/initialize()
starts_with = pick(/mob/living/simple_animal/hostile/statue, /obj/item/cursed_marble)
starts_with = pick(/mob/living/simple_animal/hostile/statue, /obj/item/cursed_marble, /obj/item/weapon/deadringer)
name = pick("Spicy Crust Pizzeria", "Soap and Care Products", "Sally's Computer Parts", "Steve's Chocolate Pastries", "Smith & Christian's Plastics","Standard Containers & Packaging Co.", "Sanitary Chemical Purgation (LTD)")
name += " delivery crate"
return ..()
+5 -5
View File
@@ -170,7 +170,7 @@
singular_name = "advanced trauma kit"
desc = "An advanced trauma kit for severe injuries."
icon_state = "traumakit"
heal_brute = 3
heal_brute = 7 //VOREStation Edit
origin_tech = list(TECH_BIO = 1)
apply_sounds = list('sound/effects/rip1.ogg','sound/effects/rip2.ogg','sound/effects/tape.ogg')
@@ -198,8 +198,8 @@
continue
if (W.bandaged && W.disinfected)
continue
if(used == amount)
break
//if(used == amount) //VOREStation Edit
// break //VOREStation Edit
if(!do_mob(user, M, W.damage/5))
to_chat(user, "<span class='notice'>You must stand still to bandage wounds.</span>")
break
@@ -219,7 +219,7 @@
W.disinfect()
W.heal_damage(heal_brute)
playsound(src, pick(apply_sounds), 25)
used++
used = 1 //VOREStation Edit
affecting.update_damages()
if(used == amount)
if(affecting.is_bandaged())
@@ -233,7 +233,7 @@
singular_name = "advanced burn kit"
desc = "An advanced treatment kit for severe burns."
icon_state = "burnkit"
heal_burn = 3
heal_burn = 7 //VOREStation Edit
origin_tech = list(TECH_BIO = 1)
apply_sounds = list('sound/effects/ointment.ogg')
@@ -198,3 +198,9 @@
throw_range = 20
flags = 0
no_variants = FALSE
/obj/item/stack/tile/roofing
name = "roofing"
singular_name = "roofing"
desc = "A section of roofing material. You can use it to repair the ceiling, or expand it."
icon_state = "techtile_grid"
+6 -3
View File
@@ -167,21 +167,24 @@
if(!istype(M))
return 0
if (user.a_intent == I_HELP)
return ..()
if(target_name != M.name)
target_name = M.name
src.wdata = list()
src.chemtraces = list()
src.timeofdeath = null
user << "<span class='notice'>A new patient has been registered. Purging data for previous patient.</span>"
to_chat(user, "<span class='notice'>A new patient has been registered. Purging data for previous patient.</span>")
src.timeofdeath = M.timeofdeath
var/obj/item/organ/external/S = M.get_organ(user.zone_sel.selecting)
if(!S)
usr << "<span class='warning'>You can't scan this body part.</span>"
to_chat(user, "<span class='warning'>You can't scan this body part.</span>")
return
if(!S.open)
usr << "<span class='warning'>You have to cut [S] open first!</span>"
to_chat(user, "<span class='warning'>You have to cut [S] open first!</span>")
return
M.visible_message("<span class='notice'>\The [user] scans the wounds on [M]'s [S.name] with [src]</span>")
@@ -21,12 +21,26 @@
/obj/item/weapon/implant/proc/activate()
return
// What does the implant do upon injection?
// return 0 if the implant fails (ex. Revhead and loyalty implant.)
// return 1 if the implant succeeds (ex. Nonrevhead and loyalty implant.)
/obj/item/weapon/implant/proc/implanted(var/mob/source)
// Moves the implant where it needs to go, and tells it if there's more to be done in post_implant
/obj/item/weapon/implant/proc/handle_implant(var/mob/source, var/target_zone = BP_TORSO)
. = TRUE
imp_in = source
implanted = TRUE
if(ishuman(source))
var/mob/living/carbon/human/H = source
var/obj/item/organ/external/affected = H.get_organ(target_zone)
if(affected)
affected.implants += src
part = affected
if(part)
forceMove(part)
else
forceMove(source)
listening_objects |= src
return 1
// Takes place after handle_implant, if that returns TRUE
/obj/item/weapon/implant/proc/post_implant(var/mob/source)
/obj/item/weapon/implant/proc/get_data()
return "No information available"
@@ -49,6 +63,12 @@
icon_state = "implant_melted"
malfunction = MALFUNCTION_PERMANENT
/obj/item/weapon/implant/proc/implant_loadout(var/mob/living/carbon/human/H)
if(H)
var/obj/item/organ/external/affected = H.organs_by_name[BP_HEAD]
if(handle_implant(H, affected))
post_implant(H)
/obj/item/weapon/implant/Destroy()
if(part)
part.implants.Remove(src)
@@ -69,6 +89,11 @@
else
..()
//////////////////////////////
// Tracking Implant
//////////////////////////////
GLOBAL_LIST_BOILERPLATE(all_tracking_implants, /obj/item/weapon/implant/tracking)
/obj/item/weapon/implant/tracking
@@ -84,9 +109,8 @@ GLOBAL_LIST_BOILERPLATE(all_tracking_implants, /obj/item/weapon/implant/tracking
id = rand(1, 1000)
..()
/obj/item/weapon/implant/tracking/implanted(var/mob/source)
/obj/item/weapon/implant/tracking/post_implant(var/mob/source)
processing_objects.Add(src)
return 1
/obj/item/weapon/implant/tracking/Destroy()
processing_objects.Remove(src)
@@ -142,7 +166,9 @@ Implant Specifics:<BR>"}
spawn(delay)
malfunction--
//////////////////////////////
// Death Explosive Implant
//////////////////////////////
/obj/item/weapon/implant/dexplosive
name = "explosive"
desc = "And boom goes the weasel."
@@ -177,7 +203,9 @@ Implant Specifics:<BR>"}
/obj/item/weapon/implant/dexplosive/islegal()
return 0
//BS12 Explosive
//////////////////////////////
// Explosive Implant
//////////////////////////////
/obj/item/weapon/implant/explosive
name = "explosive implant"
desc = "A military grade micro bio-explosive. Highly dangerous."
@@ -249,15 +277,13 @@ Implant Specifics:<BR>"}
if(t)
t.hotspot_expose(3500,125)
/obj/item/weapon/implant/explosive/implanted(mob/source as mob)
/obj/item/weapon/implant/explosive/post_implant(mob/source as mob)
elevel = alert("What sort of explosion would you prefer?", "Implant Intent", "Localized Limb", "Destroy Body", "Full Explosion")
phrase = input("Choose activation phrase:") as text
var/list/replacechars = list("'" = "","\"" = "",">" = "","<" = "","(" = "",")" = "")
phrase = replace_characters(phrase, replacechars)
usr.mind.store_memory("Explosive implant in [source] can be activated by saying something containing the phrase ''[src.phrase]'', <B>say [src.phrase]</B> to attempt to activate.", 0, 0)
usr << "The implanted explosive implant in [source] can be activated by saying something containing the phrase ''[src.phrase]'', <B>say [src.phrase]</B> to attempt to activate."
listening_objects |= src
return 1
/obj/item/weapon/implant/explosive/emp_act(severity)
if (malfunction)
@@ -311,6 +337,9 @@ Implant Specifics:<BR>"}
explosion(get_turf(imp_in), -1, -1, 1, 3)
qdel(src)
//////////////////////////////
// Chemical Implant
//////////////////////////////
GLOBAL_LIST_BOILERPLATE(all_chem_implants, /obj/item/weapon/implant/chem)
/obj/item/weapon/implant/chem
@@ -336,20 +365,17 @@ Can only be loaded while still in its original case.<BR>
the implant may become unstable and either pre-maturely inject the subject or simply break."}
return dat
/obj/item/weapon/implant/chem/New()
..()
var/datum/reagents/R = new/datum/reagents(50)
reagents = R
R.my_atom = src
/obj/item/weapon/implant/chem/trigger(emote, source as mob)
if(emote == "deathgasp")
src.activate(src.reagents.total_volume)
return
/obj/item/weapon/implant/chem/activate(var/cause)
if((!cause) || (!src.imp_in)) return 0
var/mob/living/carbon/R = src.imp_in
@@ -384,6 +410,9 @@ the implant may become unstable and either pre-maturely inject the subject or si
spawn(20)
malfunction--
//////////////////////////////
// Loyalty Implant
//////////////////////////////
/obj/item/weapon/implant/loyalty
name = "loyalty implant"
desc = "Makes you loyal or such."
@@ -401,20 +430,24 @@ the implant may become unstable and either pre-maturely inject the subject or si
<b>Integrity:</b> Implant will last so long as the nanobots are inside the bloodstream."}
return dat
/obj/item/weapon/implant/loyalty/implanted(mob/M)
if(!istype(M, /mob/living/carbon/human)) return 0
/obj/item/weapon/implant/loyalty/handle_implant(mob/M, target_zone = BP_TORSO)
. = ..(M, target_zone)
if(!istype(M, /mob/living/carbon/human))
. = FALSE
var/mob/living/carbon/human/H = M
var/datum/antagonist/antag_data = get_antag_data(H.mind.special_role)
if(antag_data && (antag_data.flags & ANTAG_IMPLANT_IMMUNE))
H.visible_message("[H] seems to resist the implant!", "You feel the corporate tendrils of [using_map.company_name] try to invade your mind!")
return 0
else
clear_antag_roles(H.mind, 1)
H << "<span class='notice'>You feel a surge of loyalty towards [using_map.company_name].</span>"
return 1
. = FALSE
/obj/item/weapon/implant/loyalty/post_implant(mob/M)
var/mob/living/carbon/human/H = M
clear_antag_roles(H.mind, 1)
to_chat(H, "<span class='notice'>You feel a surge of loyalty towards [using_map.company_name].</span>")
//////////////////////////////
// Adrenaline Implant
//////////////////////////////
/obj/item/weapon/implant/adrenalin
name = "adrenalin"
desc = "Removes all stuns and knockdowns."
@@ -445,14 +478,13 @@ the implant may become unstable and either pre-maturely inject the subject or si
return
/obj/item/weapon/implant/adrenalin/implanted(mob/source)
/obj/item/weapon/implant/adrenalin/post_implant(mob/source)
source.mind.store_memory("A implant can be activated by using the pale emote, <B>say *pale</B> to attempt to activate.", 0, 0)
source << "The implanted freedom implant can be activated by using the pale emote, <B>say *pale</B> to attempt to activate."
listening_objects |= src
return 1
//////////////////////////////
// Death Alarm Implant
//////////////////////////////
/obj/item/weapon/implant/death_alarm
name = "death alarm implant"
desc = "An alarm which monitors host vital signs and transmits a radio message upon death."
@@ -529,11 +561,13 @@ the implant may become unstable and either pre-maturely inject the subject or si
spawn(20)
malfunction--
/obj/item/weapon/implant/death_alarm/implanted(mob/source as mob)
/obj/item/weapon/implant/death_alarm/post_implant(mob/source as mob)
mobname = source.real_name
processing_objects.Add(src)
return 1
//////////////////////////////
// Compressed Matter Implant
//////////////////////////////
/obj/item/weapon/implant/compressed
name = "compressed matter implant"
desc = "Based on compressed matter technology, can store a single item."
@@ -571,13 +605,12 @@ the implant may become unstable and either pre-maturely inject the subject or si
scanned.loc = t
qdel(src)
/obj/item/weapon/implant/compressed/implanted(mob/source as mob)
/obj/item/weapon/implant/compressed/post_implant(mob/source)
src.activation_emote = input("Choose activation emote:") in list("blink", "blink_r", "eyebrow", "chuckle", "twitch", "frown", "nod", "blush", "giggle", "grin", "groan", "shrug", "smile", "pale", "sniff", "whimper", "wink")
if (source.mind)
source.mind.store_memory("Compressed matter implant can be activated by using the [src.activation_emote] emote, <B>say *[src.activation_emote]</B> to attempt to activate.", 0, 0)
source << "The implanted compressed matter implant can be activated by using the [src.activation_emote] emote, <B>say *[src.activation_emote]</B> to attempt to activate."
listening_objects |= src
return 1
/obj/item/weapon/implant/compressed/islegal()
return 0
@@ -3,43 +3,39 @@
desc = "Allows the user to understand and speak almost all known languages.."
var/uses = 1
get_data()
var/dat = {"
<b>Implant Specifications:</b><BR>
<b>Name:</b> Language Implant<BR>
<b>Life:</b> One day.<BR>
<b>Important Notes:</b> Personnel with this implant can speak almost all known languages.<BR>
<HR>
<b>Implant Details:</b> Subjects injected with implant can understand and speak almost all known languages.<BR>
<b>Function:</b> Contains specialized nanobots to stimulate the brain so the user can speak and understand previously unknown languages.<BR>
<b>Special Features:</b> Will allow the user to understand almost all languages.<BR>
<b>Integrity:</b> Implant can only be used once before the nanobots are depleted."}
return dat
/obj/item/weapon/implant/vrlanguage/get_data()
var/dat = {"
<b>Implant Specifications:</b><BR>
<b>Name:</b> Language Implant<BR>
<b>Life:</b> One day.<BR>
<b>Important Notes:</b> Personnel with this implant can speak almost all known languages.<BR>
<HR>
<b>Implant Details:</b> Subjects injected with implant can understand and speak almost all known languages.<BR>
<b>Function:</b> Contains specialized nanobots to stimulate the brain so the user can speak and understand previously unknown languages.<BR>
<b>Special Features:</b> Will allow the user to understand almost all languages.<BR>
<b>Integrity:</b> Implant can only be used once before the nanobots are depleted."}
return dat
/obj/item/weapon/implant/vrlanguage/trigger(emote, mob/source as mob)
if (src.uses < 1)
return 0
if (emote == "smile")
src.uses--
to_chat(source,"<span class='notice'>You suddenly feel as if you can understand other languages!</span>")
source.add_language(LANGUAGE_CHIMPANZEE)
source.add_language(LANGUAGE_NEAERA)
source.add_language(LANGUAGE_STOK)
source.add_language(LANGUAGE_FARWA)
source.add_language(LANGUAGE_UNATHI)
source.add_language(LANGUAGE_SIIK)
source.add_language(LANGUAGE_SKRELLIAN)
source.add_language(LANGUAGE_SCHECHI)
source.add_language(LANGUAGE_BIRDSONG)
source.add_language(LANGUAGE_SAGARU)
source.add_language(LANGUAGE_CANILUNZT)
source.add_language(LANGUAGE_SOL_COMMON) //In case they're giving a xenomorph an implant or something.
trigger(emote, mob/source as mob)
if (src.uses < 1) return 0
if (emote == "smile")
src.uses--
source << "<span class='notice'>You suddenly feel as if you can understand other languages!</span>"
source.add_language(LANGUAGE_CHIMPANZEE)
source.add_language(LANGUAGE_NEAERA)
source.add_language(LANGUAGE_STOK)
source.add_language(LANGUAGE_FARWA)
source.add_language(LANGUAGE_UNATHI)
source.add_language(LANGUAGE_SIIK)
source.add_language(LANGUAGE_SKRELLIAN)
source.add_language(LANGUAGE_SCHECHI)
source.add_language(LANGUAGE_BIRDSONG)
source.add_language(LANGUAGE_SAGARU)
source.add_language(LANGUAGE_CANILUNZT)
source.add_language(LANGUAGE_SOL_COMMON) //In case they're giving a xenomorph an implant or something.
return
implanted(mob/source)
source.mind.store_memory("A implant can be activated by using the smile emote, <B>say *smile</B> to attempt to activate.", 0, 0)
source << "The implanted language implant can be activated by using the smile emote, <B>say *smile</B> to attempt to activate."
return 1
/obj/item/weapon/implant/vrlanguage/post_implant(mob/source)
source.mind.store_memory("A implant can be activated by using the smile emote, <B>say *smile</B> to attempt to activate.", 0, 0)
to_chat(source,"The implanted language implant can be activated by using the smile emote, <B>say *smile</B> to attempt to activate.")
return 1
@@ -135,10 +135,9 @@
for (var/mob/O in viewers(M, null))
O.show_message("<span class='warning'>\The [M] has been implanted by \the [src].</span>", 1)
if(imp.implanted(M))
imp.loc = M
imp.imp_in = M
imp.implanted = 1
if(imp.handle_implant(M, BP_TORSO))
imp.post_implant(M)
implant_list -= imp
break
return
@@ -56,16 +56,11 @@
add_attack_logs(user,M,"Implanted with [imp.name] using [name]")
if(src.imp.implanted(M))
src.imp.loc = M
src.imp.imp_in = M
src.imp.implanted = 1
if (ishuman(M))
var/mob/living/carbon/human/H = M
var/obj/item/organ/external/affected = H.get_organ(user.zone_sel.selecting)
affected.implants += src.imp
imp.part = affected
if(imp.handle_implant(M))
imp.post_implant(M)
if(ishuman(M))
var/mob/living/carbon/human/H = M
BITSET(H.hud_updateflag, IMPLOYAL_HUD)
BITSET(H.hud_updateflag, BACKUP_HUD) //VOREStation Add - Backup HUD updates
@@ -16,7 +16,9 @@
/obj/item/weapon/implant/freedom/trigger(emote, mob/living/carbon/source as mob)
if (src.uses < 1) return 0
if (src.uses < 1)
return 0
if (emote == src.activation_emote)
src.uses--
source << "You feel a faint click."
@@ -46,13 +48,9 @@
W.layer = initial(W.layer)
return
/obj/item/weapon/implant/freedom/implanted(mob/living/carbon/source)
/obj/item/weapon/implant/freedom/post_implant(mob/source)
source.mind.store_memory("Freedom implant can be activated by using the [src.activation_emote] emote, <B>say *[src.activation_emote]</B> to attempt to activate.", 0, 0)
source << "The implanted freedom implant can be activated by using the [src.activation_emote] emote, <B>say *[src.activation_emote]</B> to attempt to activate."
listening_objects |= src
return 1
/obj/item/weapon/implant/freedom/get_data()
var/dat = {"
@@ -4,7 +4,26 @@
/obj/item/weapon/implant/language
name = "GalCom language implant"
desc = "An implant allowing someone to speak and hear the range of frequencies used in Galactic Common, as well as produce any phonemes that they usually cannot. Only helps with hearing and producing sounds, not understanding them."
desc = "An implant allowing someone to speak the range of frequencies used in Galactic Common, as well as produce any phonemes that they usually cannot. Only helps with producing sounds, not understanding them."
var/list/languages = list(LANGUAGE_GALCOM) // List of languages that this assists with
/obj/item/weapon/implant/language/post_implant(mob/M) // Amends the mob's voice organ, then deletes itself
if(ishuman(M))
var/mob/living/carbon/human/H = M
var/obj/item/organ/internal/voicebox/V = locate() in H.internal_organs
if(V)
var/list/need_amend = list() // If they've already got all the languages they need, then they don't need this implant to do anything
for(var/L in languages)
if(L in V.will_assist_languages)
continue
else
need_amend |= L
if(LAZYLEN(need_amend))
if(V.robotic < ORGAN_ASSISTED)
V.mechassist()
for(var/L in need_amend)
V.add_assistable_langs(L)
qdel_null(src)
/obj/item/weapon/implant/language/get_data()
var/dat = {"
@@ -14,16 +33,19 @@
<b>Important Notes:</b> Affects hearing and speech.<BR>
<HR>
<b>Implant Details:</b><BR>
<b>Function:</b> Allows a being otherwise incapable to both hear the frequencies Galactic Common is generally spoken at, as well as to produce the phonemes of the language.<BR>
<b>Function:</b> Allows a being otherwise incapable of speaking Galactic Common to produce the phonemes of the language.<BR>
<b>Special Features:</b> None.<BR>
<b>Integrity:</b> Implant will function for expected life, barring physical damage."}
return dat
// EAL Implant
/obj/item/weapon/implant/language/eal
name = "EAL language implant"
desc = "An implant allowing an organic to both hear and speak Encoded Audio Language accurately. Only helps with hearing and producing sounds, not understanding them."
desc = "An implant allowing an organic to speak Encoded Audio Language passably. Only helps with producing sounds, not understanding them."
languages = list(LANGUAGE_EAL)
/obj/item/weapon/implant/language/get_data()
/obj/item/weapon/implant/language/eal/get_data()
var/dat = {"
<b>Implant Specifications:</b><BR>
<b>Name:</b> Vey-Med L-2 Encoded Audio Language Implant<BR>
@@ -31,7 +53,25 @@
<b>Important Notes:</b> Affects hearing and speech.<BR>
<HR>
<b>Implant Details:</b><BR>
<b>Function:</b> Allows an organic to accurately process and speak Encoded Audio Language.<BR>
<b>Function:</b> Allows an organic to accurately speak Encoded Audio Language.<BR>
<b>Special Features:</b> None.<BR>
<b>Integrity:</b> Implant will function for expected life, barring physical damage."}
return dat
/obj/item/weapon/implant/language/skrellian
name = "Skrellian language implant"
desc = "An implant allowing someone to speak the range of frequencies used in Skrellian, as well as produce any phonemes that they usually cannot. Only helps with hearing and producing sounds, not understanding them."
languages = list(LANGUAGE_SKRELLIAN)
/obj/item/weapon/implant/language/skrellian/get_data()
var/dat = {"
<b>Implant Specifications:</b><BR>
<b>Name:</b> Vey-Med L-1 Galactic Common Implant<BR>
<b>Life:</b> 5 years<BR>
<b>Important Notes:</b> Affects hearing and speech.<BR>
<HR>
<b>Implant Details:</b><BR>
<b>Function:</b> Allows a being otherwise incapable of speaking Skrellian to produce the phonemes of the language.<BR>
<b>Special Features:</b> None.<BR>
<b>Integrity:</b> Implant will function for expected life, barring physical damage."}
return dat
@@ -30,7 +30,7 @@
update()
return
/obj/item/weapon/implant/reagent_generator/implanted(mob/living/carbon/source)
/obj/item/weapon/implant/reagent_generator/post_implant(mob/living/carbon/source)
processing_objects += src
to_chat(source, "<span class='notice'>You implant [source] with \the [src].</span>")
assigned_proc = new assigned_proc(source, verb_name, verb_desc)
@@ -11,15 +11,13 @@
..()
return
/obj/item/weapon/implant/uplink/implanted(mob/source)
/obj/item/weapon/implant/uplink/post_implant(mob/source)
listening_objects |= src
activation_emote = input("Choose activation emote:") in list("blink", "blink_r", "eyebrow", "chuckle", "twitch", "frown", "nod", "blush", "giggle", "grin", "groan", "shrug", "smile", "pale", "sniff", "whimper", "wink")
source.mind.store_memory("Uplink implant can be activated by using the [src.activation_emote] emote, <B>say *[src.activation_emote]</B> to attempt to activate.", 0, 0)
source << "The implanted uplink implant can be activated by using the [src.activation_emote] emote, <B>say *[src.activation_emote]</B> to attempt to activate."
listening_objects |= src
return 1
/obj/item/weapon/implant/uplink/trigger(emote, mob/source as mob)
if(hidden_uplink && usr == source) // Let's not have another people activate our uplink
hidden_uplink.check_trigger(source, emote, activation_emote)
return
return
+1
View File
@@ -16,6 +16,7 @@ GLOBAL_LIST_BOILERPLATE(all_mops, /obj/item/weapon/mop)
/obj/item/weapon/mop/New()
create_reagents(30)
..()
/obj/item/weapon/mop/afterattack(atom/A, mob/user, proximity)
if(!proximity) return
@@ -4,6 +4,9 @@
icon = 'icons/policetape.dmi'
icon_state = "tape"
w_class = ITEMSIZE_SMALL
toolspeed = 3 //You can use it in surgery. It's stupid, but you can.
var/turf/start
var/turf/end
var/tape_type = /obj/item/tape
@@ -67,6 +67,7 @@
/obj/item/weapon/extinguisher/mini,
/obj/item/weapon/tape_roll,
/obj/item/device/integrated_electronics/wirer,
/obj/item/device/integrated_electronics/debugger, //Vorestation edit adding debugger to toolbelt can hold list
)
/obj/item/weapon/storage/belt/utility/full
@@ -86,7 +87,6 @@
/obj/item/weapon/weldingtool,
/obj/item/weapon/crowbar,
/obj/item/weapon/wirecutters,
/obj/item/device/t_scanner
)
/obj/item/weapon/storage/belt/utility/chief
@@ -10,24 +10,25 @@
/obj/item/weapon/storage/firstaid
name = "first aid kit"
desc = "It's an emergency medical kit for those serious boo-boos."
icon = 'icons/obj/storage_vr.dmi'
icon_state = "firstaid"
throw_speed = 2
throw_range = 8
max_storage_space = ITEMSIZE_COST_SMALL * 7 // 14
var/list/icon_variety
// var/list/icon_variety // VOREStation edit
/obj/item/weapon/storage/firstaid/initialize()
. = ..()
if(icon_variety)
icon_state = pick(icon_variety)
icon_variety = null
// if(icon_variety) // VOREStation edit
// icon_state = pick(icon_variety)
// icon_variety = null
/obj/item/weapon/storage/firstaid/fire
name = "fire first aid kit"
desc = "It's an emergency medical kit for when the toxins lab <i>spontaneously</i> burns down."
icon_state = "ointment"
item_state_slots = list(slot_r_hand_str = "firstaid-ointment", slot_l_hand_str = "firstaid-ointment")
icon_variety = list("ointment","firefirstaid")
// icon_variety = list("ointment","firefirstaid") // VOREStation edit
starts_with = list(
/obj/item/device/healthanalyzer,
/obj/item/weapon/reagent_containers/hypospray/autoinjector,
@@ -55,7 +56,7 @@
desc = "Used to treat when one has a high amount of toxins in their body."
icon_state = "antitoxin"
item_state_slots = list(slot_r_hand_str = "firstaid-toxin", slot_l_hand_str = "firstaid-toxin")
icon_variety = list("antitoxin","antitoxfirstaid","antitoxfirstaid2","antitoxfirstaid3")
// icon_variety = list("antitoxin","antitoxfirstaid","antitoxfirstaid2","antitoxfirstaid3") // VOREStation edit
starts_with = list(
/obj/item/weapon/reagent_containers/syringe/antitoxin,
/obj/item/weapon/reagent_containers/syringe/antitoxin,
@@ -70,7 +71,7 @@
name = "oxygen deprivation first aid kit"
desc = "A box full of oxygen goodies."
icon_state = "o2"
item_state_slots = list(slot_r_hand_str = "firstaid-o2", slot_l_hand_str = "firstaid-o2")
item_state_slots = list(slot_r_hand_str = "firstaid-o2", slot_l_hand_str = "firstaid-o2")
starts_with = list(
/obj/item/weapon/reagent_containers/pill/dexalin,
/obj/item/weapon/reagent_containers/pill/dexalin,
@@ -116,6 +117,7 @@
/obj/item/weapon/storage/firstaid/surgery
name = "surgery kit"
desc = "Contains tools for surgery. Has precise foam fitting for safe transport and automatically sterilizes the content between uses."
icon = 'icons/obj/storage.dmi' // VOREStation edit
icon_state = "surgerykit"
item_state = "firstaid-surgery"
max_w_class = ITEMSIZE_NORMAL
@@ -152,6 +154,7 @@
/obj/item/weapon/storage/firstaid/clotting
name = "clotting kit"
desc = "Contains chemicals to stop bleeding."
icon_state = "clottingkit" // VOREStation edit
max_storage_space = ITEMSIZE_COST_SMALL * 7
starts_with = list(/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/clotting = 8)
+8 -5
View File
@@ -19,16 +19,19 @@
var/obj/item/weapon/cell/bcell = null
var/hitcost = 240
/obj/item/weapon/melee/baton/suicide_act(mob/user)
var/datum/gender/TU = gender_datums[user.get_visible_gender()]
user.visible_message("<span class='suicide'>\The [user] is putting the live [name] in [TU.his] mouth! It looks like [TU.he] [TU.is] trying to commit suicide.</span>")
return (FIRELOSS)
/obj/item/weapon/melee/baton/New()
..()
update_icon()
return
/obj/item/weapon/melee/baton/get_cell()
return bcell
/obj/item/weapon/melee/baton/suicide_act(mob/user)
var/datum/gender/TU = gender_datums[user.get_visible_gender()]
user.visible_message("<span class='suicide'>\The [user] is putting the live [name] in [TU.his] mouth! It looks like [TU.he] [TU.is] trying to commit suicide.</span>")
return (FIRELOSS)
/obj/item/weapon/melee/baton/MouseDrop(obj/over_object as obj)
if(!canremove)
return
@@ -1,4 +1,4 @@
/obj/item/weapon/tank/emergency/phoron_double
/obj/item/weapon/tank/emergency/phoron/double
name = "double emergency phoron tank"
desc = "Contains dangerous phoron. Do not inhale. Warning: extremely flammable."
icon = 'icons/obj/tank_vr.dmi'
@@ -8,7 +8,7 @@
gauge_cap = 3
volume = 10
/obj/item/weapon/tank/emergency/phoron_double/New()
/obj/item/weapon/tank/emergency/phoron/double/New()
..()
air_contents.adjust_gas("phoron", (10*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C))
@@ -41,6 +41,8 @@
icon = 'icons/obj/tank_vr.dmi'
icon_override = 'icons/mob/back_vr.dmi'
icon_state = "phoron_vox"
gauge_cap = 3
gauge_icon = "indicator_double"
/obj/item/weapon/tank/emergency
icon = 'icons/obj/tank_vr.dmi'
+4
View File
@@ -5,8 +5,12 @@
icon_state = "taperoll"
w_class = ITEMSIZE_TINY
toolspeed = 2 //It is now used in surgery as a not awful, but probably dangerous option, due to speed.
/obj/item/weapon/tape_roll/attack(var/mob/living/carbon/human/H, var/mob/user)
if(istype(H))
if(user.a_intent == I_HELP)
return
var/can_place = 0
if(istype(user, /mob/living/silicon/robot))
can_place = 1
+5 -2
View File
@@ -776,6 +776,9 @@
acti_sound = 'sound/effects/sparks4.ogg'
deac_sound = 'sound/effects/sparks4.ogg'
/obj/item/weapon/weldingtool/electric/unloaded/New()
cell_type = null
/obj/item/weapon/weldingtool/electric/New()
..()
if(cell_type == null)
@@ -786,8 +789,8 @@
power_supply = new /obj/item/weapon/cell/device(src)
update_icon()
/obj/item/weapon/weldingtool/electric/unloaded/New()
cell_type = null
/obj/item/weapon/weldingtool/electric/get_cell()
return power_supply
/obj/item/weapon/weldingtool/electric/examine(mob/user)
if(get_dist(src, user) > 1)
+3
View File
@@ -163,3 +163,6 @@
/obj/proc/show_message(msg, type, alt, alt_type)//Message, type of message (1 or 2), alternative message, alt message type (1 or 2)
return
/obj/proc/get_cell()
return
+1 -1
View File
@@ -2,7 +2,7 @@
/obj/structure/catwalk
name = "catwalk"
desc = "Cats really don't like these things."
plane = TURF_PLANE
plane = DECAL_PLANE
layer = ABOVE_UTILITY
icon = 'icons/turf/catwalks.dmi'
icon_state = "catwalk"
@@ -71,6 +71,7 @@
/mob/living/simple_animal/hostile/alien/sentinel,
/mob/living/simple_animal/hostile/alien/queen,
/mob/living/simple_animal/otie/feral,
/mob/living/simple_animal/otie/red,
/mob/living/simple_animal/hostile/corrupthound))
return ..()
@@ -101,6 +102,11 @@
desc = "VARMAcorp experimental hostile environment adaptive breeding development kit. WARNING, DO NOT RELEASE IN WILD!"
starts_with = list(/mob/living/simple_animal/otie/cotie/phoron)
/obj/structure/largecrate/animal/otie/phoron/initialize()
starts_with = list(pick(/mob/living/simple_animal/otie/cotie/phoron;2,
/mob/living/simple_animal/otie/red/friendly;0.5))
return ..()
/obj/structure/largecrate/animal/otie/attack_hand(mob/living/carbon/human/M as mob)//I just couldn't decide between the icons lmao
if(taped == 1)
playsound(src, 'sound/items/poster_ripped.ogg', 50, 1)
+1
View File
@@ -20,6 +20,7 @@ GLOBAL_LIST_BOILERPLATE(all_janitorial_carts, /obj/structure/janitorialcart)
/obj/structure/janitorialcart/New()
create_reagents(300)
..()
/obj/structure/janitorialcart/examine(mob/user)
@@ -6,15 +6,6 @@
icon = 'icons/obj/abductor.dmi'
density = TRUE
anchored = TRUE
var/interaction_message = null
/obj/structure/prop/alien/attack_hand(mob/living/user) // Used to tell the player that this isn't useful for anything.
if(!istype(user))
return FALSE
if(!interaction_message)
return ..()
else
to_chat(user, interaction_message)
/obj/structure/prop/alien/computer
name = "alien console"
@@ -0,0 +1,215 @@
//A series(?) of prisms for PoIs. The base one only works for beams.
/obj/structure/prop/prism
name = "prismatic turret"
desc = "A raised, externally powered 'turret'. It seems to have a massive crystal ring around its base."
description_info = "This device is capable of redirecting any beam projectile."
icon = 'icons/obj/props/prism.dmi'
icon_state = "prism"
density = TRUE
anchored = TRUE
layer = 3.1 //Layer over projectiles.
plane = -10 //Layer over projectiles.
var/rotation_lock = 0 // Can you rotate the prism at all?
var/free_rotate = 1 // Does the prism rotate in any direction, or only in the eight standard compass directions?
var/external_control_lock = 0 // Does the prism only rotate from the controls of an external switch?
var/degrees_from_north = 0 // How far is it rotated clockwise?
var/compass_directions = list("North" = 0, "South" = 180, "East" = 90, "West" = 270, "Northwest" = 315, "Northeast" = 45, "Southeast" = 135, "Southwest" = 225)
var/interaction_sound = 'sound/mecha/mechmove04.ogg'
var/redirect_type = /obj/item/projectile/beam
var/dialID = null
var/obj/structure/prop/prismcontrol/remote_dial = null
interaction_message = "<span class='notice'>The prismatic turret seems to be able to rotate.</span>"
/obj/structure/prop/prism/initialize()
if(degrees_from_north)
animate(src, transform = turn(NORTH, degrees_from_north), time = 3)
/obj/structure/prop/prism/Destroy()
if(remote_dial)
remote_dial.my_turrets -= src
remote_dial = null
..()
/obj/structure/prop/prism/proc/reset_rotation()
var/degrees_to_rotate = -1 * degrees_from_north
animate(src, transform = turn(src.transform, degrees_to_rotate), time = 2)
/obj/structure/prop/prism/attack_hand(mob/living/user)
..()
if(rotation_lock)
to_chat(user, "<span class='warning'>\The [src] is locked at its current bearing.</span>")
return
if(external_control_lock)
to_chat(user, "<span class='warning'>\The [src]'s motors resist your efforts to rotate it. You may need to find some form of controller.</span>")
return
var/confirm = input("Do you want to try to rotate \the [src]?", "[name]") in list("Yes", "No")
if(confirm == "No")
visible_message(\
"<span class='notice'>[user.name] decides not to try turning \the [src].</span>",\
"<span class='notice'>You decide not to try turning \the [src].</span>")
return
var/new_bearing
if(free_rotate)
new_bearing = input("What bearing do you want to rotate \the [src] to?", "[name]") as num
new_bearing = round(new_bearing)
if(new_bearing <= -1 || new_bearing > 360)
to_chat(user, "<span class='warning'>Rotating \the [src] [new_bearing] degrees would be a waste of time.</span>")
return
else
var/choice = input("What point do you want to set \the [src] to?", "[name]") as null|anything in compass_directions
new_bearing = round(compass_directions[choice])
var/rotate_degrees = new_bearing - degrees_from_north
if(new_bearing == 360) // Weird artifact.
new_bearing = 0
degrees_from_north = new_bearing
var/two_stage = 0
if(rotate_degrees == 180 || rotate_degrees == -180)
two_stage = 1
var/multiplier = pick(-1, 1)
rotate_degrees = multiplier * (rotate_degrees / 2)
playsound(src, interaction_sound, 50, 1)
if(two_stage)
animate(src, transform = turn(src.transform, rotate_degrees), time = 3)
spawn(3)
animate(src, transform = turn(src.transform, rotate_degrees), time = 3)
else
animate(src, transform = turn(src.transform, rotate_degrees), time = 6) //Can't update transform because it will reset the angle.
/obj/structure/prop/prism/proc/rotate_auto(var/new_bearing)
if(rotation_lock)
visible_message("<span class='notice'>\The [src] shudders.</span>")
playsound(src, 'sound/effects/clang.ogg', 50, 1)
return
visible_message("<span class='notice'>\The [src] rotates to a bearing of [new_bearing].</span>")
var/rotate_degrees = new_bearing - degrees_from_north
if(new_bearing == 360)
new_bearing = 0
degrees_from_north = new_bearing
var/two_stage = 0
if(rotate_degrees == 180 || rotate_degrees == -180)
two_stage = 1
var/multiplier = pick(-1, 1)
rotate_degrees = multiplier * (rotate_degrees / 2)
playsound(src, interaction_sound, 50, 1)
if(two_stage)
animate(src, transform = turn(src.transform, rotate_degrees), time = 3)
spawn(3)
animate(src, transform = turn(src.transform, rotate_degrees), time = 3)
else
animate(src, transform = turn(src.transform, rotate_degrees), time = 6)
/obj/structure/prop/prism/bullet_act(var/obj/item/projectile/Proj)
if(istype(Proj, redirect_type))
visible_message("<span class='danger'>\The [src] redirects \the [Proj]!</span>")
flick("[initial(icon_state)]+glow", src)
var/new_x = (1 * round(10 * cos(degrees_from_north - 90))) + x //Vectors vectors vectors.
var/new_y = (-1 * round(10 * sin(degrees_from_north - 90))) + y
var/turf/curloc = get_turf(src)
Proj.penetrating += 1 // Needed for the beam to get out of the turret.
Proj.redirect(new_x, new_y, curloc, null)
/obj/structure/prop/prism/incremental
free_rotate = 0
description_info = "This device is capable of redirecting any beam projectile, but only locks to specific positions in rotation."
/obj/structure/prop/prism/incremental/externalcont
external_control_lock = 1
description_info = "This device is capable of redirecting any beam projectile, but can only be rotated by a control dial to specific positions."
/obj/structure/prop/prism/externalcont
external_control_lock = 1
description_info = "This device is capable of redirecting any beam projectile, but can only be rotated by an external control dial."
/obj/structure/prop/prismcontrol
name = "prismatic dial"
desc = "A large dial with a crystalline ring."
icon = 'icons/obj/props/prism.dmi'
icon_state = "dial"
density = FALSE
anchored = TRUE
interaction_message = "<span class='notice'>The dial pulses as your hand nears it.</span>"
var/list/my_turrets = list()
var/dialID = null
/obj/structure/prop/prismcontrol/attack_hand(mob/living/user)
..()
var/confirm = input("Do you want to try to rotate \the [src]?", "[name]") in list("Yes", "No")
if(confirm == "No")
visible_message(\
"<span class='notice'>[user.name] decides not to try turning \the [src].</span>",\
"<span class='notice'>You decide not to try turning \the [src].</span>")
return
if(!my_turrets || !my_turrets.len)
to_chat(user, "<span class='notice'>\The [src] doesn't seem to do anything.</span>")
return
var/free_rotate = 1
var/list/compass_directions = list()
for(var/obj/structure/prop/prism/P in my_turrets)
if(!P.free_rotate) //Doesn't use bearing, it uses compass points.
free_rotate = 0
compass_directions |= P.compass_directions
var/new_bearing
if(free_rotate)
new_bearing = input("What bearing do you want to rotate \the [src] to?", "[name]") as num
new_bearing = round(new_bearing)
if(new_bearing <= -1 || new_bearing > 360)
to_chat(user, "<span class='warning'>Rotating \the [src] [new_bearing] degrees would be a waste of time.</span>")
return
else
var/choice = input("What point do you want to set \the [src] to?", "[name]") as null|anything in compass_directions
new_bearing = round(compass_directions[choice])
confirm = input("Are you certain you want to rotate \the [src]?", "[name]") in list("Yes", "No")
if(confirm == "No")
visible_message(\
"<span class='notice'>[user.name] decides not to try turning \the [src].</span>",\
"<span class='notice'>You decide not to try turning \the [src].</span>")
return
to_chat(user, "<span class='notice'>\The [src] clicks into place.</span>")
for(var/obj/structure/prop/prism/P in my_turrets)
P.rotate_auto(new_bearing)
/obj/structure/prop/prismcontrol/initialize()
..()
if(my_turrets.len) //Preset controls.
for(var/obj/structure/prop/prism/P in my_turrets)
P.remote_dial = src
return
spawn()
for(var/obj/structure/prop/prism/P in orange(src, world.view)) //Don't search a huge area.
if(P.dialID == dialID && !P.remote_dial && P.external_control_lock)
my_turrets |= P
P.remote_dial = src
/obj/structure/prop/prismcontrol/Destroy()
for(var/obj/structure/prop/prism/P in my_turrets)
P.remote_dial = null
my_turrets = list()
..()
@@ -0,0 +1,53 @@
//A locking mechanism that pulses when hit by a projectile. The base one responds to high-power lasers.
/obj/structure/prop/lock
name = "weird lock"
desc = "An esoteric object that responds to.. something."
icon = 'icons/obj/props/prism.dmi'
icon_state = "lock"
var/enabled = 0
var/lockID = null
var/list/linked_objects = list()
/obj/structure/prop/lock/Destroy()
if(linked_objects.len)
for(var/obj/O in linked_objects)
if(istype(O, /obj/machinery/door/blast/puzzle))
var/obj/machinery/door/blast/puzzle/P = O
P.locks -= src
linked_objects -= P
..()
/obj/structure/prop/lock/proc/toggle_lock()
enabled = !enabled
if(enabled)
icon_state = "[initial(icon_state)]-active"
else
icon_state = "[initial(icon_state)]"
/obj/structure/prop/lock/projectile
name = "beam lock"
desc = "An esoteric object that responds to high intensity light."
var/projectile_key = /obj/item/projectile/beam
var/timed = 0
var/timing = 0
var/time_limit = 1500 // In ticks. Ten is one second.
interaction_message = "<span class='notice'>The object remains inert to your touch.</span>"
/obj/structure/prop/lock/projectile/bullet_act(var/obj/item/projectile/Proj)
if(!istype(Proj, projectile_key) || timing)
return
if(istype(Proj, /obj/item/projectile/beam/heavylaser/cannon) || istype(Proj, /obj/item/projectile/beam/emitter) || (Proj.damage >= 80 && Proj.damtype == BURN))
toggle_lock()
visible_message("<span class='notice'>\The [src] [enabled ? "disengages" : "engages"] its locking mechanism.</span>")
if(timed)
timing = 1
spawn(time_limit)
toggle_lock()
@@ -0,0 +1,18 @@
//The base 'prop' for PoIs or other large junk.
/obj/structure/prop
name = "something"
desc = "My description is broken, bug a developer."
icon = 'icons/obj/structures.dmi'
icon_state = "safe"
density = TRUE
anchored = TRUE
var/interaction_message = null
/obj/structure/prop/attack_hand(mob/living/user) // Used to tell the player that this isn't useful for anything.
if(!istype(user))
return FALSE
if(!interaction_message)
return ..()
else
to_chat(user, interaction_message)
@@ -0,0 +1,92 @@
// An indestructible blast door that can only be opened once its puzzle requirements are completed.
/obj/machinery/door/blast/puzzle
name = "puzzle door"
desc = "A large, virtually indestructible door that will not open unless certain requirements are met."
icon_state_open = "pdoor0"
icon_state_opening = "pdoorc0"
icon_state_closed = "pdoor1"
icon_state_closing = "pdoorc1"
icon_state = "pdoor1"
explosion_resistance = 100
maxhealth = 9999999 //No.
var/list/locks = list()
var/lockID = null
var/checkrange_mult = 1
/obj/machinery/door/blast/puzzle/proc/check_locks()
for(var/obj/structure/prop/lock/L in locks)
if(!L.enabled)
return 0
return 1
/obj/machinery/door/blast/puzzle/bullet_act(var/obj/item/projectile/Proj)
visible_message("<span class='cult'>\The [src] is completely unaffected by \the [Proj].</span>")
qdel(Proj) //No piercing. No.
/obj/machinery/door/blast/puzzle/ex_act(severity)
visible_message("<span class='cult'>\The [src] is completely unaffected by the blast.</span>")
return
/obj/machinery/door/blast/puzzle/initialize()
. = ..()
implicit_material = get_material_by_name("dungeonium")
if(locks.len)
return
var/check_range = world.view * checkrange_mult
for(var/obj/structure/prop/lock/L in orange(src, check_range))
if(L.lockID == lockID)
L.linked_objects |= src
locks |= L
/obj/machinery/door/blast/puzzle/Destroy()
if(locks.len)
for(var/obj/structure/prop/lock/L in locks)
L.linked_objects -= src
locks -= L
..()
/obj/machinery/door/blast/puzzle/attack_hand(mob/user as mob)
if(check_locks())
force_toggle(1, user)
else
to_chat(user, "<span class='notice'>\The [src] does not respond to your touch.</span>")
/obj/machinery/door/blast/puzzle/attackby(obj/item/weapon/C as obj, mob/user as mob)
if(istype(C, /obj/item/weapon))
if(C.pry == 1 && (user.a_intent != I_HURT || (stat & BROKEN)))
if(istype(C,/obj/item/weapon/material/twohanded/fireaxe))
var/obj/item/weapon/material/twohanded/fireaxe/F = C
if(!F.wielded)
to_chat(user, "<span class='warning'>You need to be wielding \the [F] to do that.</span>")
return
if(check_locks())
force_toggle(1, user)
else
to_chat(user, "<span class='notice'>[src]'s arcane workings resist your effort.</span>")
return
else if(src.density && (user.a_intent == I_HURT))
var/obj/item/weapon/W = C
user.setClickCooldown(user.get_attack_speed(W))
if(W.damtype == BRUTE || W.damtype == BURN)
user.do_attack_animation(src)
user.visible_message("<span class='danger'>\The [user] hits \the [src] with \the [W] with no visible effect.</span>")
else if(istype(C, /obj/item/weapon/plastique))
to_chat(user, "<span class='danger'>On contacting \the [src], a flash of light envelops \the [C] as it is turned to ash. Oh.</span>")
qdel(C)
return 0
/obj/machinery/door/blast/puzzle/attack_generic(var/mob/user, var/damage)
if(check_locks())
force_toggle(1, user)
/obj/machinery/door/blast/puzzle/attack_alien(var/mob/user)
if(check_locks())
force_toggle(1, user)
+88 -1
View File
@@ -10,4 +10,91 @@
/obj/effect/floor_decal/industrial/outline/red
name = "red outline"
color = COLOR_RED
color = COLOR_RED
/obj/effect/floor_decal/borderfloor/shifted
icon_state = "borderfloor_shifted"
/obj/effect/floor_decal/borderfloorblack/shifted
icon_state = "borderfloor_shifted"
/obj/effect/floor_decal/borderfloorwhite/shifted
icon_state = "borderfloor_shifted"
/obj/effect/floor_decal/corner/beige/border/shifted
icon_state = "bordercolor_shifted"
/obj/effect/floor_decal/corner/black/border/shifted
icon_state = "bordercolor_shifted"
/obj/effect/floor_decal/corner/blue/border/shifted
icon_state = "bordercolor_shifted"
/obj/effect/floor_decal/corner/brown/border/shifted
icon_state = "bordercolor_shifted"
/obj/effect/floor_decal/corner/green/border/shifted
icon_state = "bordercolor_shifted"
/obj/effect/floor_decal/corner/grey/border/shifted
icon_state = "bordercolor_shifted"
/obj/effect/floor_decal/corner/lightgrey/border/shifted
icon_state = "bordercolor_shifted"
/obj/effect/floor_decal/corner/lightorange
name = "orange corner"
color = "#ed983d"
/obj/effect/floor_decal/corner/lightorange/diagonal
icon_state = "corner_white_diagonal"
/obj/effect/floor_decal/corner/lightorange/full
icon_state = "corner_white_full"
/obj/effect/floor_decal/corner/lightorange/three_quarters
icon_state = "corner_white_three_quarters"
/obj/effect/floor_decal/corner/lightorange/border
icon_state = "bordercolor"
/obj/effect/floor_decal/corner/lightorange/border/shifted
icon_state = "bordercolor_shifted"
/obj/effect/floor_decal/corner/lightorange/bordercorner
icon_state = "bordercolorcorner"
/obj/effect/floor_decal/corner/lightorange/bordercorner2
icon_state = "bordercolorcorner2"
/obj/effect/floor_decal/corner/lightorange/borderfull
icon_state = "bordercolorfull"
/obj/effect/floor_decal/corner/lightorange/bordercee
icon_state = "bordercolorcee"
/obj/effect/floor_decal/corner/lime/border/shifted
icon_state = "bordercolor_shifted"
/obj/effect/floor_decal/corner/mauve/border/shifted
icon_state = "bordercolor_shifted"
/obj/effect/floor_decal/corner/orange/border/shifted
icon_state = "bordercolor_shifted"
/obj/effect/floor_decal/corner/paleblue/border/shifted
icon_state = "bordercolor_shifted"
/obj/effect/floor_decal/corner/pink/border/shifted
icon_state = "bordercolor_shifted"
/obj/effect/floor_decal/corner/purple/border/shifted
icon_state = "bordercolor_shifted"
/obj/effect/floor_decal/corner/red/border/shifted
icon_state = "bordercolor_shifted"
/obj/effect/floor_decal/corner/white/border/shifted
icon_state = "bordercolor_shifted"
/obj/effect/floor_decal/corner/yellow/border/shifted
icon_state = "bordercolor_shifted"
@@ -12,6 +12,9 @@
/turf/simulated/wall/dungeon/ex_act()
return
/turf/simulated/wall/dungeon/take_damage() //These things are suppose to be unbreakable
return
/turf/simulated/wall/solidrock //for more stylish anti-cheese.
name = "solid rock"
desc = "This rock seems dense, impossible to drill."
@@ -37,4 +40,7 @@
return
/turf/simulated/wall/solidrock/ex_act()
return
/turf/simulated/wall/solidrock/take_damage() //These things are suppose to be unbreakable
return
@@ -9,6 +9,51 @@
attack_tile(C, L) // Be on help intent if you want to decon something.
return
if(istype(C, /obj/item/stack/tile/roofing))
var/expended_tile = FALSE // To track the case. If a ceiling is built in a multiz zlevel, it also necessarily roofs it against weather
var/turf/T = GetAbove(src)
var/obj/item/stack/tile/roofing/R = C
// Patch holes in the ceiling
if(T)
if(istype(T, /turf/simulated/open) || istype(T, /turf/space))
// Must be build adjacent to an existing floor/wall, no floating floors
var/list/cardinalTurfs = list() // Up a Z level
for(var/dir in cardinal)
var/turf/B = get_step(T, dir)
if(B)
cardinalTurfs += B
var/turf/simulated/A = locate(/turf/simulated/floor) in cardinalTurfs
if(!A)
A = locate(/turf/simulated/wall) in cardinalTurfs
if(!A)
to_chat(user, "<span class='warning'>There's nothing to attach the ceiling to!</span>")
return
if(R.use(1)) // Cost of roofing tiles is 1:1 with cost to place lattice and plating
T.ReplaceWithLattice()
T.ChangeTurf(/turf/simulated/floor)
playsound(src, 'sound/weapons/Genhit.ogg', 50, 1)
user.visible_message("<span class='notice'>[user] patches a hole in the ceiling.</span>", "<span class='notice'>You patch a hole in the ceiling.</span>")
expended_tile = TRUE
else
to_chat(user, "<span class='warning'>There aren't any holes in the ceiling to patch here.</span>")
return
// Create a ceiling to shield from the weather
if(src.outdoors)
for(var/dir in cardinal)
var/turf/A = get_step(src, dir)
if(A && !A.outdoors)
if(expended_tile || R.use(1))
src.outdoors = FALSE
SSplanets.unallocateTurf(src)
playsound(src, 'sound/weapons/Genhit.ogg', 50, 1)
user.visible_message("<span class='notice'>[user] roofs a tile, shielding it from the elements.</span>", "<span class='notice'>You roof this tile, shielding it from the elements.</span>")
break
return
if(flooring)
if(istype(C, /obj/item/weapon))
try_deconstruct_tile(C, user)
@@ -1,5 +1,4 @@
var/list/turf_edge_cache = list()
var/list/outdoor_turfs = list()
/turf/
// If greater than 0, this turf will apply edge overlays on top of other turfs cardinally adjacent to it, if those adjacent turfs are of a different icon_state,
@@ -24,24 +23,21 @@ var/list/outdoor_turfs = list()
/turf/simulated/floor/New()
if(outdoors)
outdoor_turfs.Add(src)
SSplanets.addTurf(src)
..()
/turf/simulated/floor/Destroy()
if(outdoors)
planet_controller.unallocateTurf(src)
SSplanets.removeTurf(src)
return ..()
/turf/simulated/proc/make_outdoors()
outdoors = TRUE
outdoor_turfs.Add(src)
SSplanets.addTurf(src)
/turf/simulated/proc/make_indoors()
outdoors = FALSE
if(planet_controller)
planet_controller.unallocateTurf(src)
else // This is happening during map gen, if there's no planet_controller (hopefully).
outdoor_turfs -= src
SSplanets.removeTurf(src)
/turf/simulated/post_change()
..()
+1 -1
View File
@@ -14,7 +14,7 @@
/turf/simulated/sky/initialize()
. = ..()
outdoor_turfs.Add(src)
SSplanets.addTurf(src)
set_light(2, 2, "#FFFFFF")
/turf/simulated/sky/north
+62 -32
View File
@@ -84,16 +84,16 @@
if(rotting)
if(reinf_material)
user << "<span class='danger'>\The [reinf_material.display_name] feels porous and crumbly.</span>"
to_chat(user, "<span class='danger'>\The [reinf_material.display_name] feels porous and crumbly.</span>")
else
user << "<span class='danger'>\The [material.display_name] crumbles under your touch!</span>"
to_chat(user, "<span class='danger'>\The [material.display_name] crumbles under your touch!</span>")
dismantle_wall()
return 1
if(..()) return 1
if(!can_open)
user << "<span class='notice'>You push the wall, but nothing happens.</span>"
to_chat(user, "<span class='notice'>You push the wall, but nothing happens.</span>")
playsound(src, 'sound/weapons/Genhit.ogg', 25, 1)
else
toggle_open(user)
@@ -138,28 +138,58 @@
user.setClickCooldown(user.get_attack_speed(W))
if (!user.)
user << "<span class='warning'>You don't have the dexterity to do this!</span>"
to_chat(user, "<span class='warning'>You don't have the dexterity to do this!</span>")
return
//get the user's location
if(!istype(user.loc, /turf)) return //can't do this stuff whilst inside objects and such
if(!istype(user.loc, /turf))
return //can't do this stuff whilst inside objects and such
if(W)
radiate()
if(is_hot(W))
burn(is_hot(W))
if(istype(W, /obj/item/stack/tile/roofing))
var/expended_tile = FALSE // To track the case. If a ceiling is built in a multiz zlevel, it also necessarily roofs it against weather
var/turf/T = GetAbove(src)
var/obj/item/stack/tile/roofing/R = W
// Place plating over a wall
if(T)
if(istype(T, /turf/simulated/open) || istype(T, /turf/space))
if(R.use(1)) // Cost of roofing tiles is 1:1 with cost to place lattice and plating
T.ReplaceWithLattice()
T.ChangeTurf(/turf/simulated/floor)
playsound(src, 'sound/weapons/Genhit.ogg', 50, 1)
user.visible_message("<span class='notice'>[user] patches a hole in the ceiling.</span>", "<span class='notice'>You patch a hole in the ceiling.</span>")
expended_tile = TRUE
else
to_chat(user, "<span class='warning'>There aren't any holes in the ceiling to patch here.</span>")
return
// Create a ceiling to shield from the weather
if(outdoors)
if(expended_tile || R.use(1)) // Don't need to check adjacent turfs for a wall, we're building on one
outdoors = FALSE
SSplanets.unallocateTurf(src)
if(!expended_tile) // Would've already played a sound
playsound(src, 'sound/weapons/Genhit.ogg', 50, 1)
user.visible_message("<span class='notice'>[user] roofs \the [src], shielding it from the elements.</span>", "<span class='notice'>You roof \the [src] tile, shielding it from the elements.</span>")
return
if(locate(/obj/effect/overlay/wallrot) in src)
if(istype(W, /obj/item/weapon/weldingtool) )
var/obj/item/weapon/weldingtool/WT = W
if( WT.remove_fuel(0,user) )
user << "<span class='notice'>You burn away the fungi with \the [WT].</span>"
to_chat(user, "<span class='notice'>You burn away the fungi with \the [WT].</span>")
playsound(src, WT.usesound, 10, 1)
for(var/obj/effect/overlay/wallrot/WR in src)
qdel(WR)
return
else if(!is_sharp(W) && W.force >= 10 || W.force >= 20)
user << "<span class='notice'>\The [src] crumbles away under the force of your [W.name].</span>"
to_chat(user, "<span class='notice'>\The [src] crumbles away under the force of your [W.name].</span>")
src.dismantle_wall(1)
return
@@ -179,7 +209,7 @@
var/obj/item/weapon/melee/energy/blade/EB = W
EB.spark_system.start()
user << "<span class='notice'>You slash \the [src] with \the [EB]; the thermite ignites!</span>"
to_chat(user, "<span class='notice'>You slash \the [src] with \the [EB]; the thermite ignites!</span>")
playsound(src, "sparks", 50, 1)
playsound(src, 'sound/weapons/blade1.ogg', 50, 1)
@@ -196,13 +226,13 @@
return
if(WT.remove_fuel(0,user))
user << "<span class='notice'>You start repairing the damage to [src].</span>"
to_chat(user, "<span class='notice'>You start repairing the damage to [src].</span>")
playsound(src.loc, WT.usesound, 100, 1)
if(do_after(user, max(5, damage / 5) * WT.toolspeed) && WT && WT.isOn())
user << "<span class='notice'>You finish repairing the damage to [src].</span>"
to_chat(user, "<span class='notice'>You finish repairing the damage to [src].</span>")
take_damage(-damage)
else
user << "<span class='notice'>You need more welding fuel to complete this task.</span>"
to_chat(user, "<span class='notice'>You need more welding fuel to complete this task.</span>")
return
user.update_examine_panel(src)
return
@@ -219,7 +249,7 @@
if(!WT.isOn())
return
if(!WT.remove_fuel(0,user))
user << "<span class='notice'>You need more welding fuel to complete this task.</span>"
to_chat(user, "<span class='notice'>You need more welding fuel to complete this task.</span>")
return
dismantle_verb = "cutting"
dismantle_sound = W.usesound
@@ -236,7 +266,7 @@
if(dismantle_verb)
user << "<span class='notice'>You begin [dismantle_verb] through the outer plating.</span>"
to_chat(user, "<span class='notice'>You begin [dismantle_verb] through the outer plating.</span>")
if(dismantle_sound)
playsound(src, dismantle_sound, 100, 1)
@@ -246,7 +276,7 @@
if(!do_after(user,cut_delay * W.toolspeed))
return
user << "<span class='notice'>You remove the outer plating.</span>"
to_chat(user, "<span class='notice'>You remove the outer plating.</span>")
dismantle_wall()
user.visible_message("<span class='warning'>The wall was torn open by [user]!</span>")
return
@@ -259,24 +289,24 @@
playsound(src, W.usesound, 100, 1)
construction_stage = 5
user.update_examine_panel(src)
user << "<span class='notice'>You cut through the outer grille.</span>"
to_chat(user, "<span class='notice'>You cut through the outer grille.</span>")
update_icon()
return
if(5)
if (istype(W, /obj/item/weapon/screwdriver))
user << "<span class='notice'>You begin removing the support lines.</span>"
to_chat(user, "<span class='notice'>You begin removing the support lines.</span>")
playsound(src, W.usesound, 100, 1)
if(!do_after(user,40 * W.toolspeed) || !istype(src, /turf/simulated/wall) || construction_stage != 5)
return
construction_stage = 4
user.update_examine_panel(src)
update_icon()
user << "<span class='notice'>You unscrew the support lines.</span>"
to_chat(user, "<span class='notice'>You unscrew the support lines.</span>")
return
else if (istype(W, /obj/item/weapon/wirecutters))
construction_stage = 6
user.update_examine_panel(src)
user << "<span class='notice'>You mend the outer grille.</span>"
to_chat(user, "<span class='notice'>You mend the outer grille.</span>")
playsound(src, W.usesound, 100, 1)
update_icon()
return
@@ -289,51 +319,51 @@
if(WT.remove_fuel(0,user))
cut_cover=1
else
user << "<span class='notice'>You need more welding fuel to complete this task.</span>"
to_chat(user, "<span class='notice'>You need more welding fuel to complete this task.</span>")
return
else if (istype(W, /obj/item/weapon/pickaxe/plasmacutter))
cut_cover = 1
if(cut_cover)
user << "<span class='notice'>You begin slicing through the metal cover.</span>"
to_chat(user, "<span class='notice'>You begin slicing through the metal cover.</span>")
playsound(src, W.usesound, 100, 1)
if(!do_after(user, 60 * W.toolspeed) || !istype(src, /turf/simulated/wall) || construction_stage != 4)
return
construction_stage = 3
user.update_examine_panel(src)
update_icon()
user << "<span class='notice'>You press firmly on the cover, dislodging it.</span>"
to_chat(user, "<span class='notice'>You press firmly on the cover, dislodging it.</span>")
return
else if (istype(W, /obj/item/weapon/screwdriver))
user << "<span class='notice'>You begin screwing down the support lines.</span>"
to_chat(user, "<span class='notice'>You begin screwing down the support lines.</span>")
playsound(src, W.usesound, 100, 1)
if(!do_after(user,40 * W.toolspeed) || !istype(src, /turf/simulated/wall) || construction_stage != 4)
return
construction_stage = 5
user.update_examine_panel(src)
update_icon()
user << "<span class='notice'>You screw down the support lines.</span>"
to_chat(user, "<span class='notice'>You screw down the support lines.</span>")
return
if(3)
if (istype(W, /obj/item/weapon/crowbar))
user << "<span class='notice'>You struggle to pry off the cover.</span>"
to_chat(user, "<span class='notice'>You struggle to pry off the cover.</span>")
playsound(src, W.usesound, 100, 1)
if(!do_after(user,100 * W.toolspeed) || !istype(src, /turf/simulated/wall) || construction_stage != 3)
return
construction_stage = 2
user.update_examine_panel(src)
update_icon()
user << "<span class='notice'>You pry off the cover.</span>"
to_chat(user, "<span class='notice'>You pry off the cover.</span>")
return
if(2)
if (istype(W, /obj/item/weapon/wrench))
user << "<span class='notice'>You start loosening the anchoring bolts which secure the support rods to their frame.</span>"
to_chat(user, "<span class='notice'>You start loosening the anchoring bolts which secure the support rods to their frame.</span>")
playsound(src, W.usesound, 100, 1)
if(!do_after(user,40 * W.toolspeed) || !istype(src, /turf/simulated/wall) || construction_stage != 2)
return
construction_stage = 1
user.update_examine_panel(src)
update_icon()
user << "<span class='notice'>You remove the bolts anchoring the support rods.</span>"
to_chat(user, "<span class='notice'>You remove the bolts anchoring the support rods.</span>")
return
if(1)
var/cut_cover
@@ -342,28 +372,28 @@
if( WT.remove_fuel(0,user) )
cut_cover=1
else
user << "<span class='notice'>You need more welding fuel to complete this task.</span>"
to_chat(user, "<span class='notice'>You need more welding fuel to complete this task.</span>")
return
else if(istype(W, /obj/item/weapon/pickaxe/plasmacutter))
cut_cover = 1
if(cut_cover)
user << "<span class='notice'>You begin slicing through the support rods.</span>"
to_chat(user, "<span class='notice'>You begin slicing through the support rods.</span>")
playsound(src, W.usesound, 100, 1)
if(!do_after(user,70 * W.toolspeed) || !istype(src, /turf/simulated/wall) || construction_stage != 1)
return
construction_stage = 0
user.update_examine_panel(src)
update_icon()
user << "<span class='notice'>The slice through the support rods.</span>"
to_chat(user, "<span class='notice'>The slice through the support rods.</span>")
return
if(0)
if(istype(W, /obj/item/weapon/crowbar))
user << "<span class='notice'>You struggle to pry off the outer sheath.</span>"
to_chat(user, "<span class='notice'>You struggle to pry off the outer sheath.</span>")
playsound(src, W.usesound, 100, 1)
if(!do_after(user,100 * W.toolspeed) || !istype(src, /turf/simulated/wall) || !user || !W || !T )
return
if(user.loc == T && user.get_active_hand() == W )
user << "<span class='notice'>You pry off the outer sheath.</span>"
to_chat(user, "<span class='notice'>You pry off the outer sheath.</span>")
dismantle_wall()
return
+1
View File
@@ -19,6 +19,7 @@
..() // To get the edges.
icon_state = water_state
var/image/floorbed_sprite = image(icon = 'icons/turf/outdoors.dmi', icon_state = under_state)
underlays.Cut() // To clear the old underlay, so the list doesn't expand infinitely
underlays.Add(floorbed_sprite)
update_icon_edge()
+31 -5
View File
@@ -33,18 +33,18 @@
/turf/space/attackby(obj/item/C as obj, mob/user as mob)
if (istype(C, /obj/item/stack/rods))
if(istype(C, /obj/item/stack/rods))
var/obj/structure/lattice/L = locate(/obj/structure/lattice, src)
if(L)
return
var/obj/item/stack/rods/R = C
if (R.use(1))
user << "<span class='notice'>Constructing support lattice ...</span>"
to_chat(user, "<span class='notice'>Constructing support lattice ...</span>")
playsound(src, 'sound/weapons/Genhit.ogg', 50, 1)
ReplaceWithLattice()
return
if (istype(C, /obj/item/stack/tile/floor))
if(istype(C, /obj/item/stack/tile/floor))
var/obj/structure/lattice/L = locate(/obj/structure/lattice, src)
if(L)
var/obj/item/stack/tile/floor/S = C
@@ -56,7 +56,33 @@
ChangeTurf(/turf/simulated/floor/airless)
return
else
user << "<span class='warning'>The plating is going to need some support.</span>"
to_chat(user, "<span class='warning'>The plating is going to need some support.</span>")
if(istype(C, /obj/item/stack/tile/roofing))
var/turf/T = GetAbove(src)
var/obj/item/stack/tile/roofing/R = C
// Patch holes in the ceiling
if(T)
if(istype(T, /turf/simulated/open) || istype(T, /turf/space))
// Must be build adjacent to an existing floor/wall, no floating floors
var/turf/simulated/A = locate(/turf/simulated/floor) in T.CardinalTurfs()
if(!A)
A = locate(/turf/simulated/wall) in T.CardinalTurfs()
if(!A)
to_chat(user, "<span class='warning'>There's nothing to attach the ceiling to!</span>")
return
if(R.use(1)) // Cost of roofing tiles is 1:1 with cost to place lattice and plating
T.ReplaceWithLattice()
T.ChangeTurf(/turf/simulated/floor)
playsound(src, 'sound/weapons/Genhit.ogg', 50, 1)
user.visible_message("<span class='notice'>[user] expands the ceiling.</span>", "<span class='notice'>You expand the ceiling.</span>")
else
to_chat(user, "<span class='warning'>There aren't any holes in the ceiling to patch here.</span>")
return
// Space shouldn't have weather of the sort planets with atmospheres do.
// If that's changed, then you'll want to swipe the rest of the roofing code from code/game/turfs/simulated/floor_attackby.dm
return
@@ -64,7 +90,7 @@
/turf/space/Entered(atom/movable/A as mob|obj)
if(movement_disabled)
usr << "<span class='warning'>Movement is admin-disabled.</span>" //This is to identify lag problems
to_chat(usr, "<span class='warning'>Movement is admin-disabled.</span>") //This is to identify lag problems
return
..()
if ((!(A) || src != A.loc)) return
+2
View File
@@ -40,6 +40,7 @@
var/old_affecting_lights = affecting_lights
var/old_lighting_overlay = lighting_overlay
var/old_corners = corners
var/old_outdoors = outdoors
//world << "Replacing [src.type] with [N]"
@@ -108,3 +109,4 @@
lighting_build_overlay()
else
lighting_clear_overlay()
outdoors = old_outdoors
+2 -4
View File
@@ -1,7 +1,5 @@
// This is a wall you surround the area of your "planet" with, that makes the atmosphere inside stay within bounds, even if canisters
// are opened or other strange things occur.
var/list/planetary_walls = list()
/turf/unsimulated/wall/planetary
name = "railroading"
desc = "Choo choo!"
@@ -21,10 +19,10 @@ var/list/planetary_walls = list()
/turf/unsimulated/wall/planetary/New()
..()
planetary_walls.Add(src)
SSplanets.addTurf(src)
/turf/unsimulated/wall/planetary/Destroy()
planetary_walls.Remove(src)
SSplanets.removeTurf(src)
..()
/turf/unsimulated/wall/planetary/proc/set_temperature(var/new_temperature)
+3 -1
View File
@@ -659,11 +659,13 @@ var/list/admin_verbs_event_manager = list(
set desc = "Cause an explosion of varying strength at your location."
var/turf/epicenter = mob.loc
var/list/choices = list("Small Bomb", "Medium Bomb", "Big Bomb", "Custom Bomb")
var/list/choices = list("Small Bomb", "Medium Bomb", "Big Bomb", "Custom Bomb", "Cancel")
var/choice = input("What size explosion would you like to produce?") in choices
switch(choice)
if(null)
return 0
if("Cancel")
return 0
if("Small Bomb")
explosion(epicenter, 1, 2, 3, 3)
if("Medium Bomb")
+2 -2
View File
@@ -12,7 +12,7 @@
else if(is_antag && !is_admin) // Is an antag, and not an admin, meaning we need to check if their antag type allows AOOC.
var/datum/antagonist/A = get_antag_data(usr.mind.special_role)
if(!A || !A.can_use_aooc)
if(!A || !A.can_speak_aooc || !A.can_hear_aooc)
to_chat(usr, "<span class='warning'>Sorry, but your antagonist type is not allowed to speak in AOOC.</span>")
return
@@ -36,7 +36,7 @@
var/datum/antagonist/A = null
if(M.mind) // Observers don't have minds, but they should still see AOOC.
A = get_antag_data(M.mind.special_role)
if((M.mind && M.mind.special_role && A && A.can_use_aooc) || isobserver(M)) // Antags must have their type be allowed to AOOC to see AOOC. This prevents, say, ERT from seeing AOOC.
if((M.mind && M.mind.special_role && A && A.can_hear_aooc) || isobserver(M)) // Antags must have their type be allowed to AOOC to see AOOC. This prevents, say, ERT from seeing AOOC.
to_chat(M, "<span class='ooc'><span class='aooc'>[create_text_tag("aooc", "Antag-OOC:", M.client)] <EM>[player_display]:</EM> <span class='message'>[msg]</span></span></span>")
log_aooc(msg,src)
+2 -2
View File
@@ -637,7 +637,7 @@
if(!check_rights(R_DEBUG))
return
var/datum/planet/planet = input(usr, "Which planet do you want to modify the weather on?", "Change Weather") in planet_controller.planets
var/datum/planet/planet = input(usr, "Which planet do you want to modify the weather on?", "Change Weather") in SSplanets.planets
var/datum/weather/new_weather = input(usr, "What weather do you want to change to?", "Change Weather") as null|anything in planet.weather_holder.allowed_weather_types
if(new_weather)
planet.weather_holder.change_weather(new_weather)
@@ -653,7 +653,7 @@
if(!check_rights(R_DEBUG))
return
var/datum/planet/planet = input(usr, "Which planet do you want to modify time on?", "Change Time") in planet_controller.planets
var/datum/planet/planet = input(usr, "Which planet do you want to modify time on?", "Change Time") in SSplanets.planets
var/datum/time/current_time_datum = planet.current_time
var/new_hour = input(usr, "What hour do you want to change to?", "Change Time", text2num(current_time_datum.show_time("hh"))) as null|num
+184
View File
@@ -0,0 +1,184 @@
/obj/item/weapon/deadringer
name = "silver pocket watch"
desc = "A fancy silver-plated digital pocket watch. Looks expensive."
icon = 'icons/obj/deadringer.dmi'
icon_state = "deadringer"
w_class = ITEMSIZE_SMALL
slot_flags = SLOT_ID | SLOT_BELT | SLOT_TIE
origin_tech = list(TECH_ILLEGAL = 3)
var/activated = 0
var/timer = 0
var/bruteloss_prev = 999999
var/fireloss_prev = 999999
var/mob/living/carbon/human/corpse = null
var/mob/living/carbon/human/watchowner = null
/obj/item/weapon/deadringer/New()
..()
processing_objects |= src
/obj/item/weapon/deadringer/Destroy() //just in case some smartass tries to stay invisible by destroying the watch
uncloak()
processing_objects -= src
..()
/obj/item/weapon/deadringer/dropped()
if(timer > 20)
uncloak()
watchowner = null
return
/obj/item/weapon/deadringer/attack_self(var/mob/living/user as mob)
var/mob/living/H = src.loc
if (!istype(H, /mob/living/carbon/human))
to_chat(H,"<font color='blue'>You have no clue what to do with this thing.</font>")
return
if(!activated)
if(timer == 0)
to_chat(H, "<font color='blue'>You press a small button on [src]'s side. It starts to hum quietly.</font>")
bruteloss_prev = H.getBruteLoss()
fireloss_prev = H.getFireLoss()
activated = 1
return
else
to_chat(H,"<font color='blue'>You press a small button on [src]'s side. It buzzes a little.</font>")
return
if(activated)
to_chat(H,"<font color='blue'>You press a small button on [src]'s side. It stops humming.</font>")
activated = 0
return
/obj/item/weapon/deadringer/process()
if(activated)
if (ismob(src.loc))
var/mob/living/carbon/human/H = src.loc
watchowner = H
if(H.getBruteLoss() > bruteloss_prev || H.getFireLoss() > fireloss_prev)
deathprevent()
activated = 0
if(watchowner.isSynthetic())
to_chat(watchowner, "<font color='blue'>You fade into nothingness! [src]'s screen blinks, being unable to copy your synthetic body!</font>")
else
to_chat(watchowner, "<font color='blue'>You fade into nothingness, leaving behind a fake body!</font>")
icon_state = "deadringer_cd"
timer = 50
return
if(timer > 0)
timer--
if(timer == 20)
uncloak()
if(corpse)
new /obj/effect/effect/smoke/chem(corpse.loc)
qdel(corpse)
if(timer == 0)
icon_state = "deadringer"
return
/obj/item/weapon/deadringer/proc/deathprevent()
for(var/mob/living/simple_animal/D in oviewers(7, src))
D.LoseTarget()
watchowner.emote("deathgasp")
watchowner.invisibility = 85
watchowner.alpha = 127
makeacorpse(watchowner)
for(var/mob/living/simple_animal/D in oviewers(7, src))
D.LoseTarget()
return
/obj/item/weapon/deadringer/proc/uncloak()
if(watchowner)
watchowner.invisibility = 0
watchowner.alpha = 255
playsound(get_turf(src), 'sound/effects/uncloak.ogg', 35, 1, -1)
return
/obj/item/weapon/deadringer/proc/makeacorpse(var/mob/living/carbon/human/H)
if(H.isSynthetic())
return
corpse = new /mob/living/carbon/human(H.loc)
corpse.setDNA(H.dna.Clone())
corpse.death(1) //Kills the new mob
var/obj/item/clothing/temp = null
if(H.get_equipped_item(slot_w_uniform))
corpse.equip_to_slot_or_del(new /obj/item/clothing/under/chameleon/changeling(corpse), slot_w_uniform)
temp = corpse.get_equipped_item(slot_w_uniform)
var/obj/item/clothing/c_type = H.get_equipped_item(slot_w_uniform)
temp.disguise(c_type.type)
temp.canremove = 0
if(H.get_equipped_item(slot_wear_suit))
corpse.equip_to_slot_or_del(new /obj/item/clothing/suit/chameleon/changeling(corpse), slot_wear_suit)
temp = corpse.get_equipped_item(slot_wear_suit)
var/obj/item/clothing/c_type = H.get_equipped_item(slot_wear_suit)
temp.disguise(c_type.type)
temp.canremove = 0
if(H.get_equipped_item(slot_shoes))
corpse.equip_to_slot_or_del(new /obj/item/clothing/shoes/chameleon/changeling(corpse), slot_shoes)
temp = corpse.get_equipped_item(slot_shoes)
var/obj/item/clothing/c_type = H.get_equipped_item(slot_shoes)
temp.disguise(c_type.type)
temp.canremove = 0
if(H.get_equipped_item(slot_gloves))
corpse.equip_to_slot_or_del(new /obj/item/clothing/gloves/chameleon/changeling(corpse), slot_gloves)
temp = corpse.get_equipped_item(slot_gloves)
var/obj/item/clothing/c_type = H.get_equipped_item(slot_gloves)
temp.disguise(c_type.type)
temp.canremove = 0
if(H.get_equipped_item(slot_l_ear))
temp = H.get_equipped_item(slot_l_ear)
corpse.equip_to_slot_or_del(new temp.type(corpse), slot_l_ear)
temp = corpse.get_equipped_item(slot_l_ear)
temp.canremove = 0
if(H.get_equipped_item(slot_glasses))
corpse.equip_to_slot_or_del(new /obj/item/clothing/glasses/chameleon/changeling(corpse), slot_glasses)
temp = corpse.get_equipped_item(slot_glasses)
var/obj/item/clothing/c_type = H.get_equipped_item(slot_glasses)
temp.disguise(c_type.type)
temp.canremove = 0
if(H.get_equipped_item(slot_wear_mask))
corpse.equip_to_slot_or_del(new /obj/item/clothing/mask/chameleon/changeling(corpse), slot_wear_mask)
temp = corpse.get_equipped_item(slot_wear_mask)
var/obj/item/clothing/c_type = H.get_equipped_item(slot_wear_mask)
temp.disguise(c_type.type)
temp.canremove = 0
if(H.get_equipped_item(slot_head))
corpse.equip_to_slot_or_del(new /obj/item/clothing/head/chameleon/changeling(corpse), slot_head)
temp = corpse.get_equipped_item(slot_head)
var/obj/item/clothing/c_type = H.get_equipped_item(slot_head)
temp.disguise(c_type.type)
temp.canremove = 0
if(H.get_equipped_item(slot_belt))
corpse.equip_to_slot_or_del(new /obj/item/weapon/storage/belt/chameleon/changeling(corpse), slot_belt)
temp = corpse.get_equipped_item(slot_belt)
var/obj/item/clothing/c_type = H.get_equipped_item(slot_belt)
temp.disguise(c_type.type)
temp.canremove = 0
if(H.get_equipped_item(slot_back))
corpse.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/chameleon/changeling(corpse), slot_back)
temp = corpse.get_equipped_item(slot_back)
var/obj/item/clothing/c_type = H.get_equipped_item(slot_back)
temp.disguise(c_type.type)
temp.canremove = 0
corpse.identifying_gender = H.identifying_gender
corpse.flavor_texts = H.flavor_texts.Copy()
corpse.real_name = H.real_name
corpse.name = H.name
corpse.set_species(corpse.dna.species)
corpse.change_hair(H.h_style)
corpse.change_facial_hair(H.f_style)
corpse.change_hair_color(H.r_hair, H.g_hair, H.b_hair)
corpse.change_facial_hair_color(H.r_facial, H.g_facial, H.b_facial)
corpse.change_skin_color(H.r_skin, H.g_skin, H.b_skin)
corpse.adjustFireLoss(H.getFireLoss())
corpse.adjustBruteLoss(H.getBruteLoss())
corpse.UpdateAppearance()
corpse.regenerate_icons()
for(var/obj/item/organ/internal/I in corpse.internal_organs)
var/obj/item/organ/internal/G = I
G.Destroy()
return
+3 -4
View File
@@ -250,9 +250,8 @@
return
/obj/effect/beam/i_beam/Destroy()
. = ..()
if(master.first == src)
master.first = null
if(next)
qdel(next)
next = null
..()
if(next && !next.gc_destroyed)
qdel_null(next)
@@ -71,8 +71,8 @@ datum/preferences/proc/set_biological_gender(var/gender)
. += "<b>Nickname:</b> "
. += "<a href='?src=\ref[src];nickname=1'><b>[pref.nickname]</b></a>"
. += "<br>"
. += "<b>Biological Gender:</b> <a href='?src=\ref[src];bio_gender=1'><b>[gender2text(pref.biological_gender)]</b></a><br>"
. += "<b>Gender Identity:</b> <a href='?src=\ref[src];id_gender=1'><b>[gender2text(pref.identifying_gender)]</b></a><br>"
. += "<b>Biological Sex:</b> <a href='?src=\ref[src];bio_gender=1'><b>[gender2text(pref.biological_gender)]</b></a><br>"
. += "<b>Pronouns:</b> <a href='?src=\ref[src];id_gender=1'><b>[gender2text(pref.identifying_gender)]</b></a><br>"
. += "<b>Age:</b> <a href='?src=\ref[src];age=1'>[pref.age]</a><br>"
. += "<b>Spawn Point</b>: <a href='?src=\ref[src];spawnpoint=1'>[pref.spawnpoint]</a><br>"
if(config.allow_Metadata)
@@ -111,13 +111,13 @@ datum/preferences/proc/set_biological_gender(var/gender)
return TOPIC_NOACTION
else if(href_list["bio_gender"])
var/new_gender = input(user, "Choose your character's biological gender:", "Character Preference", pref.biological_gender) as null|anything in get_genders()
var/new_gender = input(user, "Choose your character's biological sex:", "Character Preference", pref.biological_gender) as null|anything in get_genders()
if(new_gender && CanUseTopic(user))
pref.set_biological_gender(new_gender)
return TOPIC_REFRESH_UPDATE_PREVIEW
else if(href_list["id_gender"])
var/new_gender = input(user, "Choose your character's identifying gender:", "Character Preference", pref.identifying_gender) as null|anything in all_genders_define_list
var/new_gender = input(user, "Choose your character's pronouns:", "Character Preference", pref.identifying_gender) as null|anything in all_genders_define_list
if(new_gender && CanUseTopic(user))
pref.identifying_gender = new_gender
return TOPIC_REFRESH
@@ -158,4 +158,4 @@ datum/preferences/proc/set_biological_gender(var/gender)
return possible_genders
possible_genders = possible_genders.Copy()
possible_genders |= NEUTER
return possible_genders
return possible_genders
@@ -36,6 +36,7 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O
S["synth_red"] >> pref.r_synth
S["synth_green"] >> pref.g_synth
S["synth_blue"] >> pref.b_synth
S["synth_markings"] >> pref.synth_markings
pref.preview_icon = null
S["bgstate"] >> pref.bgstate
@@ -65,6 +66,7 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O
S["synth_red"] << pref.r_synth
S["synth_green"] << pref.g_synth
S["synth_blue"] << pref.b_synth
S["synth_markings"] << pref.synth_markings
S["bgstate"] << pref.bgstate
/datum/category_item/player_setup_item/general/body/sanitize_character(var/savefile/S)
@@ -120,6 +122,7 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O
character.r_synth = pref.r_synth
character.g_synth = pref.g_synth
character.b_synth = pref.b_synth
character.synth_markings = pref.synth_markings
// Destroy/cyborgize organs and limbs.
for(var/name in list(BP_HEAD, BP_L_HAND, BP_R_HAND, BP_L_ARM, BP_R_ARM, BP_L_FOOT, BP_R_FOOT, BP_L_LEG, BP_R_LEG, BP_GROIN, BP_TORSO))
@@ -305,6 +308,7 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O
. += "<br>"
. += "<br>"
. += "<b>Allow Synth markings:</b> <a href='?src=\ref[src];synth_markings=1'><b>[pref.synth_markings ? "Yes" : "No"]</b></a><br>"
. += "<b>Allow Synth color:</b> <a href='?src=\ref[src];synth_color=1'><b>[pref.synth_color ? "Yes" : "No"]</b></a><br>"
if(pref.synth_color)
. += "<a href='?src=\ref[src];synth2_color=1'>Change Color</a> <font face='fixedsys' size='3' color='#[num2hex(pref.r_synth, 2)][num2hex(pref.g_synth, 2)][num2hex(pref.b_synth, 2)]'><table style='display:inline;' bgcolor='#[num2hex(pref.r_synth, 2)][num2hex(pref.g_synth, 2)][num2hex(pref.b_synth, 2)]'><tr><td>__</td></tr></table></font> "
@@ -709,6 +713,10 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O
pref.b_synth = hex2num(copytext(new_color, 6, 8))
return TOPIC_REFRESH_UPDATE_PREVIEW
else if(href_list["synth_markings"])
pref.synth_markings = !pref.synth_markings
return TOPIC_REFRESH_UPDATE_PREVIEW
else if(href_list["cycle_bg"])
pref.bgstate = next_in_list(pref.bgstate, pref.bgstate_options)
return TOPIC_REFRESH_UPDATE_PREVIEW
@@ -241,6 +241,46 @@ datum/gear/suit/duster
path = /obj/item/clothing/accessory/poncho/roles/cloak/hop
allowed_roles = list("Head of Personnel")
/datum/gear/suit/roles/poncho/cloak/cargo
display_name = "cloak, cargo"
path = /obj/item/clothing/accessory/poncho/roles/cloak/cargo
allowed_roles = list("Cargo Technician","Quartermaster")
/datum/gear/suit/roles/poncho/cloak/mining
display_name = "cloak, cargo"
path = /obj/item/clothing/accessory/poncho/roles/cloak/mining
allowed_roles = list("Quartermaster","Shaft Miner")
/datum/gear/suit/roles/poncho/cloak/security
display_name = "cloak, security"
path = /obj/item/clothing/accessory/poncho/roles/cloak/security
allowed_roles = list("Head of Security","Detective","Warden","Security Officer")
/datum/gear/suit/roles/poncho/cloak/service
display_name = "cloak, service"
path = /obj/item/clothing/accessory/poncho/roles/cloak/service
allowed_roles = list("Head of Personnel","Bartender","Botanist","Janitor","Chef","Librarian")
/datum/gear/suit/roles/poncho/cloak/engineer
display_name = "cloak, engineer"
path = /obj/item/clothing/accessory/poncho/roles/cloak/engineer
allowed_roles = list("Chief Engineer","Station Engineer")
/datum/gear/suit/roles/poncho/cloak/atmos
display_name = "cloak, atmos"
path = /obj/item/clothing/accessory/poncho/roles/cloak/atmos
allowed_roles = list("Chief Engineer","Atmospheric Technician")
/datum/gear/suit/roles/poncho/cloak/research
display_name = "cloak, science"
path = /obj/item/clothing/accessory/poncho/roles/cloak/research
allowed_roles = list("Research Director","Scientist", "Roboticist", "Xenobiologist")
/datum/gear/suit/roles/poncho/cloak/medical
display_name = "cloak, medical"
path = /obj/item/clothing/accessory/poncho/roles/cloak/medical
allowed_roles = list("Medical Doctor","Chief Medical Officer","Chemist","Paramedic","Geneticist", "Psychiatrist")
/datum/gear/suit/unathi_robe
display_name = "roughspun robe"
path = /obj/item/clothing/suit/unathi/robe
@@ -116,22 +116,28 @@
path = /obj/item/weapon/cell/device
/datum/gear/utility/implant
exploitable = 1
/* VOREStation Edit - Make languages great again
/datum/gear/utility/implant/eal //This does nothing if you don't actually know EAL.
display_name = "implant, language, EAL"
path = /obj/item/weapon/implant/language/eal
cost = 2
slot = "implant"
exploitable = 1*/
exploitable = 1
/datum/gear/utility/implant/tracking
display_name = "implant, tracking"
path = /obj/item/weapon/implant/tracking/weak
cost = 0 //VOREStation Edit. Changed cost to 0
slot = "implant"
exploitable = 1
/* VOREStation Edit - Make languages great again
/datum/gear/utility/implant/language
cost = 2
exploitable = 0
/datum/gear/utility/implant/language/eal
display_name = "vocal synthesizer, EAL"
description = "A surgically implanted vocal synthesizer which allows the owner to speak EAL, if they know it."
path = /obj/item/weapon/implant/language/eal
/datum/gear/utility/implant/language/skrellian
display_name = "vocal synthesizer, Skrellian"
description = "A surgically implanted vocal synthesizer which allows the owner to speak Common Skrellian, if they know it."
path = /obj/item/weapon/implant/language/skrellian
*/
/datum/gear/utility/pen
display_name = "Fountain Pen"
path = /obj/item/weapon/pen/fountain
+1
View File
@@ -60,6 +60,7 @@ datum/preferences
var/r_synth //Used with synth_color to color synth parts that normaly can't be colored.
var/g_synth //Same as above
var/b_synth //Same as above
var/synth_markings = 0 //Enable/disable markings on synth parts.
//Some faction information.
var/home_system = "Unset" //System of birth.
+2 -1
View File
@@ -253,7 +253,8 @@
var/mob/living/carbon/human/H = user
if(slot && slot == slot_gloves)
if(H.gloves)
var/obj/item/clothing/gloves/G = H.gloves
if(istype(G))
ring = H.gloves
if(ring.glove_level >= src.glove_level)
to_chat(user, "You are unable to wear \the [src] as \the [H.gloves] are in the way.")
+2 -2
View File
@@ -9,8 +9,8 @@
/obj/item/clothing/head/helmet/combat/USDF
name = "marine helmet"
desc = "If you wanna to keep your brain inside yo' head, you'd best put this on!"
icon_state = "UNSC_helm"
item_state = "UNSC_helm"
icon_state = "unsc_helm"
item_state = "unsc_helm"
icon = 'icons/obj/clothing/hats_vr.dmi'
icon_override = 'icons/mob/head_vr.dmi'
+6
View File
@@ -20,27 +20,32 @@
/obj/item/clothing/head/pin/pink
icon_state = "pinkpin"
addblends = null
name = "pink hair hat"
/obj/item/clothing/head/pin/clover
icon_state = "cloverpin"
name = "clover pin"
addblends = null
desc = "A hair pin in the shape of a clover leaf."
/obj/item/clothing/head/pin/butterfly
icon_state = "butterflypin"
name = "butterfly pin"
addblends = null
desc = "A hair pin in the shape of a bright blue butterfly."
/obj/item/clothing/head/pin/magnetic
icon_state = "magnetpin"
name = "magnetic 'pin'"
addblends = null
desc = "Finally, a hair pin even a Morpheus chassis can use."
matter = list(DEFAULT_WALL_MATERIAL = 10)
/obj/item/clothing/head/pin/flower
name = "red flower pin"
icon_state = "hairflower"
addblends = null
desc = "Smells nice."
/obj/item/clothing/head/pin/flower/blue
@@ -82,6 +87,7 @@
/obj/item/clothing/head/pin/bow/big/red
icon_state = "redribbon"
name = "red ribbon"
addblends = null
/obj/item/clothing/head/powdered_wig
name = "powdered wig"
+6
View File
@@ -28,6 +28,12 @@
return gas_filtered
/obj/item/clothing/mask/gas/clear
name = "gas mask"
desc = "A face-covering mask with a transparent faceplate that can be connected to an air supply."
icon_state = "gas_clear"
flags_inv = null
/obj/item/clothing/mask/gas/half
name = "face mask"
desc = "A compact, durable gas mask that can be connected to an air supply."
@@ -104,14 +104,14 @@
interface_name = "mounted chem injector"
interface_desc = "Dispenses loaded chemicals via an arm-mounted injector."
var/max_reagent_volume = 10 //Regen to this volume
var/max_reagent_volume = 20 //Regen to this volume
var/chems_to_use = 5 //Per injection
charges = list(
list("inaprovaline", "inaprovaline", 0, 10),
list("tricordrazine", "tricordrazine", 0, 10),
list("tramadol", "tramadol", 0, 10),
list("dexalin plus", "dexalinp", 0, 10)
list("inaprovaline", "inaprovaline", 0, 20),
list("dylovene", "dylovene", 0, 20),
list("paracetamol", "paracetamol", 0, 20),
list("dexalin", "dexalin", 0, 20)
)
/obj/item/rig_module/rescue_pharm/process()
+1 -1
View File
@@ -60,7 +60,7 @@
/obj/item/clothing/suit/armor/combat/USDF
name = "marine body armor"
desc = "When I joined the Corps, we didn't have any fancy-schmanzy armor. We had sticks! Two sticks, and a rock for the whole platoonand we had to <i>share</i> the rock!"
icon_state = "UNSC_armor"
icon_state = "unsc_armor"
icon = 'icons/obj/clothing/suits_vr.dmi'
icon_override = 'icons/mob/suit_vr.dmi'
body_parts_covered = UPPER_TORSO|LOWER_TORSO // ToDo: Break up the armor into smaller bits.
@@ -128,6 +128,7 @@
/obj/item/clothing/suit/syndicatefake
name = "red space suit replica"
icon = 'icons/obj/clothing/spacesuits.dmi'
icon_state = "syndicate"
desc = "A plastic replica of the syndicate space suit, you'll look just like a real murderous syndicate agent in this! This is a toy, it is not made for use in space!"
w_class = ITEMSIZE_NORMAL
+1 -1
View File
@@ -78,7 +78,7 @@
name = "Radiation Hood"
icon_state = "rad"
desc = "A hood with radiation protective properties. Label: Made with lead, do not eat insulation"
// flags_inv = BLOCKHAIR
flags_inv = BLOCKHAIR
item_flags = THICKMATERIAL
body_parts_covered = HEAD|FACE|EYES
armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 60, rad = 100)
@@ -121,8 +121,8 @@
* Cloak
*/
/obj/item/clothing/accessory/poncho/roles/cloak
name = "brown cloak"
desc = "An elaborate brown cloak."
name = "quartermaster's cloak"
desc = "An elaborate brown and gold cloak."
icon_state = "qmcloak"
item_state = "qmcloak"
body_parts_covered = null
@@ -169,6 +169,54 @@
icon_state = "capcloak"
item_state = "capcloak"
/obj/item/clothing/accessory/poncho/roles/cloak/cargo
name = "brown cloak"
desc = "A simple brown and black cloak."
icon_state = "cargocloak"
item_state = "cargocloak"
/obj/item/clothing/accessory/poncho/roles/cloak/mining
name = "trimmed purple cloak"
desc = "A trimmed purple and brown cloak."
icon_state = "miningcloak"
item_state = "miningcloak"
/obj/item/clothing/accessory/poncho/roles/cloak/security
name = "red cloak"
desc = "A simple red and black cloak."
icon_state = "seccloak"
item_state = "seccloak"
/obj/item/clothing/accessory/poncho/roles/cloak/service
name = "green cloak"
desc = "A simple green and blue cloak."
icon_state = "servicecloak"
item_state = "servicecloak"
/obj/item/clothing/accessory/poncho/roles/cloak/engineer
name = "gold cloak"
desc = "A simple gold and brown cloak."
icon_state = "engicloak"
item_state = "engicloak"
/obj/item/clothing/accessory/poncho/roles/cloak/atmos
name = "yellow cloak"
desc = "A trimmed yellow and blue cloak."
icon_state = "atmoscloak"
item_state = "atmoscloak"
/obj/item/clothing/accessory/poncho/roles/cloak/research
name = "purple cloak"
desc = "A simple purple and white cloak."
icon_state = "scicloak"
item_state = "scicloak"
/obj/item/clothing/accessory/poncho/roles/cloak/medical
name = "blue cloak"
desc = "A simple blue and white cloak."
icon_state = "medcloak"
item_state = "medcloak"
/obj/item/clothing/accessory/hawaii
name = "flower-pattern shirt"
desc = "You probably need some welder googles to look at this."
-11
View File
@@ -51,17 +51,6 @@
kill()
return
/** Checks if any living humans are in a given area! */
/datum/event/atmos_leak/proc/is_area_occupied(var/area/myarea)
// Testing suggests looping over human_mob_list is quicker than looping over area contents
for(var/mob/living/carbon/human/H in human_mob_list)
if(H.stat >= DEAD) //Conditions for exclusion here, like if disconnected people start blocking it.
continue
var/area/A = get_area(H)
if(A == myarea) //The loc of a turf is the area it is in.
return 1
return 0
/datum/event/atmos_leak/announce()
command_announcement.Announce("Warning, hazardous [gas_data.name[gas_type]] gas leak detected in \the [target_area], evacuate the area and contain the damage!", "Hazard Alert")

Some files were not shown because too many files have changed in this diff Show More