mirror of
https://github.com/VOREStation/VOREStation.git
synced 2026-08-29 15:08:34 +01:00
Merge branch 'master' into ALRAUNE_STUFF
This commit is contained in:
@@ -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
|
||||
@@ -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"
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
#define INIT_ORDER_HOLOMAPS -5 //VOREStation Add
|
||||
+13
-1
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
@@ -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")
|
||||
|
||||
@@ -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()
|
||||
..()
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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 = ..()
|
||||
|
||||
@@ -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 = ..()
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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)
|
||||
*/
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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
|
||||
*/
|
||||
@@ -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
|
||||
|
||||
/*
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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'
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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>")
|
||||
|
||||
@@ -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 ..()
|
||||
|
||||
@@ -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"
|
||||
@@ -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
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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'
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
-9
@@ -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)
|
||||
@@ -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()
|
||||
..()
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
|
||||
/turf/simulated/sky/initialize()
|
||||
. = ..()
|
||||
outdoor_turfs.Add(src)
|
||||
SSplanets.addTurf(src)
|
||||
set_light(2, 2, "#FFFFFF")
|
||||
|
||||
/turf/simulated/sky/north
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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)
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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)
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.")
|
||||
|
||||
@@ -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'
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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 platoon–and 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
|
||||
|
||||
@@ -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."
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user