Merge pull request #9983 from Ghommie/Ghommie-cit408

refactoring altclick interaction to allow parent calls without forcing the turf contents stat menu open.
This commit is contained in:
Lin
2019-12-10 23:52:31 +00:00
committed by Archie
parent 7ed460e9fe
commit b0779fe2d7
96 changed files with 10279 additions and 10117 deletions
+2
View File
@@ -52,9 +52,11 @@
edit_emitter(user)
/obj/effect/sound_emitter/AltClick(mob/user)
. = ..()
if(check_rights_for(user.client, R_SOUNDS))
activate(user)
to_chat(user, "<span class='notice'>Sound emitter activated.</span>")
return TRUE
/obj/effect/sound_emitter/proc/edit_emitter(mob/user)
var/dat = ""
@@ -180,9 +180,11 @@
access_display(user)
/obj/item/clockwork/slab/AltClick(mob/living/user)
. = ..()
if(is_servant_of_ratvar(user) && linking && user.canUseTopic(src, BE_CLOSE, ismonkey(user)))
linking = null
to_chat(user, "<span class='notice'>Object link canceled.</span>")
return TRUE
/obj/item/clockwork/slab/proc/access_display(mob/living/user)
if(!is_servant_of_ratvar(user))
@@ -5,7 +5,7 @@
ShiftClickOn(A)
return
if(modifiers["alt"])
AltClickNoInteract(src, A)
altclick_listed_turf(A)
return
if(iscarbon(A))
@@ -838,11 +838,11 @@
return FALSE
/obj/machinery/airalarm/AltClick(mob/user)
..()
. = ..()
if(!user.canUseTopic(src, !issilicon(user)) || !isturf(loc))
return
else
togglelock(user)
togglelock(user)
return TRUE
/obj/machinery/airalarm/proc/togglelock(mob/living/user)
if(stat & (NOPOWER|BROKEN))
@@ -1,342 +1,341 @@
// Quick overview:
//
// Pipes combine to form pipelines
// Pipelines and other atmospheric objects combine to form pipe_networks
// Note: A single pipe_network represents a completely open space
//
// Pipes -> Pipelines
// Pipelines + Other Objects -> Pipe network
#define PIPE_VISIBLE_LEVEL 2
#define PIPE_HIDDEN_LEVEL 1
/obj/machinery/atmospherics
anchored = TRUE
move_resist = INFINITY //Moving a connected machine without actually doing the normal (dis)connection things will probably cause a LOT of issues.
idle_power_usage = 0
active_power_usage = 0
power_channel = ENVIRON
layer = GAS_PIPE_HIDDEN_LAYER //under wires
resistance_flags = FIRE_PROOF
max_integrity = 200
obj_flags = CAN_BE_HIT | ON_BLUEPRINTS
var/nodealert = 0
var/can_unwrench = 0
var/initialize_directions = 0
var/pipe_color
var/piping_layer = PIPING_LAYER_DEFAULT
var/pipe_flags = NONE
var/global/list/iconsetids = list()
var/global/list/pipeimages = list()
var/image/pipe_vision_img = null
var/device_type = 0
var/list/obj/machinery/atmospherics/nodes
var/construction_type
var/pipe_state //icon_state as a pipe item
var/on = FALSE
/obj/machinery/atmospherics/examine(mob/user)
. = ..()
if(is_type_in_list(src, GLOB.ventcrawl_machinery) && isliving(user))
var/mob/living/L = user
if(L.ventcrawler)
. += "<span class='notice'>Alt-click to crawl through it.</span>"
/obj/machinery/atmospherics/New(loc, process = TRUE, setdir)
if(!isnull(setdir))
setDir(setdir)
if(pipe_flags & PIPING_CARDINAL_AUTONORMALIZE)
normalize_cardinal_directions()
nodes = new(device_type)
if (!armor)
armor = list("melee" = 25, "bullet" = 10, "laser" = 10, "energy" = 100, "bomb" = 0, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 70)
..()
if(process)
SSair.atmos_machinery += src
SetInitDirections()
/obj/machinery/atmospherics/Destroy()
for(var/i in 1 to device_type)
nullifyNode(i)
SSair.atmos_machinery -= src
dropContents()
if(pipe_vision_img)
qdel(pipe_vision_img)
return ..()
//return QDEL_HINT_FINDREFERENCE
/obj/machinery/atmospherics/proc/destroy_network()
return
/obj/machinery/atmospherics/proc/build_network()
// Called to build a network from this node
return
/obj/machinery/atmospherics/proc/nullifyNode(i)
if(nodes[i])
var/obj/machinery/atmospherics/N = nodes[i]
N.disconnect(src)
nodes[i] = null
/obj/machinery/atmospherics/proc/getNodeConnects()
var/list/node_connects = list()
node_connects.len = device_type
for(var/i in 1 to device_type)
for(var/D in GLOB.cardinals)
if(D & GetInitDirections())
if(D in node_connects)
continue
node_connects[i] = D
break
return node_connects
/obj/machinery/atmospherics/proc/normalize_cardinal_directions()
switch(dir)
if(SOUTH)
setDir(NORTH)
if(WEST)
setDir(EAST)
//this is called just after the air controller sets up turfs
/obj/machinery/atmospherics/proc/atmosinit(list/node_connects)
if(!node_connects) //for pipes where order of nodes doesn't matter
node_connects = getNodeConnects()
for(var/i in 1 to device_type)
for(var/obj/machinery/atmospherics/target in get_step(src,node_connects[i]))
if(can_be_node(target, i))
nodes[i] = target
break
update_icon()
/obj/machinery/atmospherics/proc/setPipingLayer(new_layer)
piping_layer = (pipe_flags & PIPING_DEFAULT_LAYER_ONLY) ? PIPING_LAYER_DEFAULT : new_layer
update_icon()
/obj/machinery/atmospherics/proc/can_be_node(obj/machinery/atmospherics/target, iteration)
return connection_check(target, piping_layer)
//Find a connecting /obj/machinery/atmospherics in specified direction
/obj/machinery/atmospherics/proc/findConnecting(direction, prompted_layer)
for(var/obj/machinery/atmospherics/target in get_step(src, direction))
if(target.initialize_directions & get_dir(target,src))
if(connection_check(target, prompted_layer))
return target
/obj/machinery/atmospherics/proc/connection_check(obj/machinery/atmospherics/target, given_layer)
if(isConnectable(target, given_layer) && target.isConnectable(src, given_layer) && (target.initialize_directions & get_dir(target,src)))
return TRUE
return FALSE
/obj/machinery/atmospherics/proc/isConnectable(obj/machinery/atmospherics/target, given_layer)
if(isnull(given_layer))
given_layer = piping_layer
if((target.piping_layer == given_layer) || (target.pipe_flags & PIPING_ALL_LAYER))
return TRUE
return FALSE
/obj/machinery/atmospherics/proc/pipeline_expansion()
return nodes
/obj/machinery/atmospherics/proc/SetInitDirections()
return
/obj/machinery/atmospherics/proc/GetInitDirections()
return initialize_directions
/obj/machinery/atmospherics/proc/returnPipenet()
return
/obj/machinery/atmospherics/proc/returnPipenetAir()
return
/obj/machinery/atmospherics/proc/setPipenet()
return
/obj/machinery/atmospherics/proc/replacePipenet()
return
/obj/machinery/atmospherics/proc/disconnect(obj/machinery/atmospherics/reference)
if(istype(reference, /obj/machinery/atmospherics/pipe))
var/obj/machinery/atmospherics/pipe/P = reference
P.destroy_network()
nodes[nodes.Find(reference)] = null
update_icon()
/obj/machinery/atmospherics/attackby(obj/item/W, mob/user, params)
if(istype(W, /obj/item/pipe)) //lets you autodrop
var/obj/item/pipe/pipe = W
if(user.dropItemToGround(pipe))
pipe.setPipingLayer(piping_layer) //align it with us
return TRUE
else
return ..()
/obj/machinery/atmospherics/wrench_act(mob/living/user, obj/item/I)
if(!can_unwrench(user))
return ..()
var/turf/T = get_turf(src)
if (level==1 && isturf(T) && T.intact)
to_chat(user, "<span class='warning'>You must remove the plating first!</span>")
return TRUE
var/datum/gas_mixture/int_air = return_air()
var/datum/gas_mixture/env_air = loc.return_air()
add_fingerprint(user)
var/unsafe_wrenching = FALSE
var/internal_pressure = int_air.return_pressure()-env_air.return_pressure()
to_chat(user, "<span class='notice'>You begin to unfasten \the [src]...</span>")
if (internal_pressure > 2*ONE_ATMOSPHERE)
to_chat(user, "<span class='warning'>As you begin unwrenching \the [src] a gush of air blows in your face... maybe you should reconsider?</span>")
unsafe_wrenching = TRUE //Oh dear oh dear
if(I.use_tool(src, user, 20, volume=50))
user.visible_message( \
"[user] unfastens \the [src].", \
"<span class='notice'>You unfasten \the [src].</span>", \
"<span class='italics'>You hear ratchet.</span>")
investigate_log("was <span class='warning'>REMOVED</span> by [key_name(usr)]", INVESTIGATE_ATMOS)
//You unwrenched a pipe full of pressure? Let's splat you into the wall, silly.
if(unsafe_wrenching)
unsafe_pressure_release(user, internal_pressure)
deconstruct(TRUE)
return TRUE
/obj/machinery/atmospherics/proc/can_unwrench(mob/user)
return can_unwrench
// Throws the user when they unwrench a pipe with a major difference between the internal and environmental pressure.
/obj/machinery/atmospherics/proc/unsafe_pressure_release(mob/user, pressures = null)
if(!user)
return
if(!pressures)
var/datum/gas_mixture/int_air = return_air()
var/datum/gas_mixture/env_air = loc.return_air()
pressures = int_air.return_pressure() - env_air.return_pressure()
user.visible_message("<span class='danger'>[user] is sent flying by pressure!</span>","<span class='userdanger'>The pressure sends you flying!</span>")
// if get_dir(src, user) is not 0, target is the edge_target_turf on that dir
// otherwise, edge_target_turf uses a random cardinal direction
// range is pressures / 250
// speed is pressures / 1250
user.throw_at(get_edge_target_turf(user, get_dir(src, user) || pick(GLOB.cardinals)), pressures / 250, pressures / 1250)
/obj/machinery/atmospherics/deconstruct(disassembled = TRUE)
if(!(flags_1 & NODECONSTRUCT_1))
if(can_unwrench)
var/obj/item/pipe/stored = new construction_type(loc, null, dir, src)
stored.setPipingLayer(piping_layer)
if(!disassembled)
stored.obj_integrity = stored.max_integrity * 0.5
transfer_fingerprints_to(stored)
..()
/obj/machinery/atmospherics/proc/getpipeimage(iconset, iconstate, direction, col=rgb(255,255,255), piping_layer=2)
//Add identifiers for the iconset
if(iconsetids[iconset] == null)
iconsetids[iconset] = num2text(iconsetids.len + 1)
//Generate a unique identifier for this image combination
var/identifier = iconsetids[iconset] + "_[iconstate]_[direction]_[col]_[piping_layer]"
if((!(. = pipeimages[identifier])))
var/image/pipe_overlay
pipe_overlay = . = pipeimages[identifier] = image(iconset, iconstate, dir = direction)
pipe_overlay.color = col
PIPING_LAYER_SHIFT(pipe_overlay, piping_layer)
/obj/machinery/atmospherics/on_construction(obj_color, set_layer)
if(can_unwrench)
add_atom_colour(obj_color, FIXED_COLOUR_PRIORITY)
pipe_color = obj_color
setPipingLayer(set_layer)
var/turf/T = get_turf(src)
level = T.intact ? 2 : 1
atmosinit()
var/list/nodes = pipeline_expansion()
for(var/obj/machinery/atmospherics/A in nodes)
A.atmosinit()
A.addMember(src)
build_network()
/obj/machinery/atmospherics/Entered(atom/movable/AM)
if(istype(AM, /mob/living))
var/mob/living/L = AM
L.ventcrawl_layer = piping_layer
return ..()
/obj/machinery/atmospherics/singularity_pull(S, current_size)
if(current_size >= STAGE_FIVE)
deconstruct(FALSE)
return ..()
#define VENT_SOUND_DELAY 30
/obj/machinery/atmospherics/relaymove(mob/living/user, direction)
direction &= initialize_directions
if(!direction || !(direction in GLOB.cardinals)) //cant go this way.
return
if(user in buckled_mobs)// fixes buckle ventcrawl edgecase fuck bug
return
var/obj/machinery/atmospherics/target_move = findConnecting(direction, user.ventcrawl_layer)
if(target_move)
if(target_move.can_crawl_through())
if(is_type_in_typecache(target_move, GLOB.ventcrawl_machinery))
user.forceMove(target_move.loc) //handle entering and so on.
user.visible_message("<span class='notice'>You hear something squeezing through the ducts...</span>", "<span class='notice'>You climb out the ventilation system.")
else
var/list/pipenetdiff = returnPipenets() ^ target_move.returnPipenets()
if(pipenetdiff.len)
user.update_pipe_vision(target_move)
user.forceMove(target_move)
user.client.eye = target_move //Byond only updates the eye every tick, This smooths out the movement
if(world.time - user.last_played_vent > VENT_SOUND_DELAY)
user.last_played_vent = world.time
playsound(src, 'sound/machines/ventcrawl.ogg', 50, 1, -3)
else if(is_type_in_typecache(src, GLOB.ventcrawl_machinery) && can_crawl_through()) //if we move in a way the pipe can connect, but doesn't - or we're in a vent
user.forceMove(loc)
user.visible_message("<span class='notice'>You hear something squeezing through the ducts...</span>", "<span class='notice'>You climb out the ventilation system.")
user.canmove = FALSE
addtimer(VARSET_CALLBACK(user, canmove, TRUE), 1)
/obj/machinery/atmospherics/AltClick(mob/living/L)
if(is_type_in_list(src, GLOB.ventcrawl_machinery))
L.handle_ventcrawl(src)
return
..()
/obj/machinery/atmospherics/proc/can_crawl_through()
return TRUE
/obj/machinery/atmospherics/proc/returnPipenets()
return list()
/obj/machinery/atmospherics/update_remote_sight(mob/user)
user.sight |= (SEE_TURFS|BLIND)
//Used for certain children of obj/machinery/atmospherics to not show pipe vision when mob is inside it.
/obj/machinery/atmospherics/proc/can_see_pipes()
return TRUE
/obj/machinery/atmospherics/proc/update_layer()
// Quick overview:
//
// Pipes combine to form pipelines
// Pipelines and other atmospheric objects combine to form pipe_networks
// Note: A single pipe_network represents a completely open space
//
// Pipes -> Pipelines
// Pipelines + Other Objects -> Pipe network
#define PIPE_VISIBLE_LEVEL 2
#define PIPE_HIDDEN_LEVEL 1
/obj/machinery/atmospherics
anchored = TRUE
move_resist = INFINITY //Moving a connected machine without actually doing the normal (dis)connection things will probably cause a LOT of issues.
idle_power_usage = 0
active_power_usage = 0
power_channel = ENVIRON
layer = GAS_PIPE_HIDDEN_LAYER //under wires
resistance_flags = FIRE_PROOF
max_integrity = 200
obj_flags = CAN_BE_HIT | ON_BLUEPRINTS
var/nodealert = 0
var/can_unwrench = 0
var/initialize_directions = 0
var/pipe_color
var/piping_layer = PIPING_LAYER_DEFAULT
var/pipe_flags = NONE
var/global/list/iconsetids = list()
var/global/list/pipeimages = list()
var/image/pipe_vision_img = null
var/device_type = 0
var/list/obj/machinery/atmospherics/nodes
var/construction_type
var/pipe_state //icon_state as a pipe item
var/on = FALSE
/obj/machinery/atmospherics/examine(mob/user)
. = ..()
if(is_type_in_list(src, GLOB.ventcrawl_machinery) && isliving(user))
var/mob/living/L = user
if(L.ventcrawler)
. += "<span class='notice'>Alt-click to crawl through it.</span>"
/obj/machinery/atmospherics/New(loc, process = TRUE, setdir)
if(!isnull(setdir))
setDir(setdir)
if(pipe_flags & PIPING_CARDINAL_AUTONORMALIZE)
normalize_cardinal_directions()
nodes = new(device_type)
if (!armor)
armor = list("melee" = 25, "bullet" = 10, "laser" = 10, "energy" = 100, "bomb" = 0, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 70)
..()
if(process)
SSair.atmos_machinery += src
SetInitDirections()
/obj/machinery/atmospherics/Destroy()
for(var/i in 1 to device_type)
nullifyNode(i)
SSair.atmos_machinery -= src
dropContents()
if(pipe_vision_img)
qdel(pipe_vision_img)
return ..()
//return QDEL_HINT_FINDREFERENCE
/obj/machinery/atmospherics/proc/destroy_network()
return
/obj/machinery/atmospherics/proc/build_network()
// Called to build a network from this node
return
/obj/machinery/atmospherics/proc/nullifyNode(i)
if(nodes[i])
var/obj/machinery/atmospherics/N = nodes[i]
N.disconnect(src)
nodes[i] = null
/obj/machinery/atmospherics/proc/getNodeConnects()
var/list/node_connects = list()
node_connects.len = device_type
for(var/i in 1 to device_type)
for(var/D in GLOB.cardinals)
if(D & GetInitDirections())
if(D in node_connects)
continue
node_connects[i] = D
break
return node_connects
/obj/machinery/atmospherics/proc/normalize_cardinal_directions()
switch(dir)
if(SOUTH)
setDir(NORTH)
if(WEST)
setDir(EAST)
//this is called just after the air controller sets up turfs
/obj/machinery/atmospherics/proc/atmosinit(list/node_connects)
if(!node_connects) //for pipes where order of nodes doesn't matter
node_connects = getNodeConnects()
for(var/i in 1 to device_type)
for(var/obj/machinery/atmospherics/target in get_step(src,node_connects[i]))
if(can_be_node(target, i))
nodes[i] = target
break
update_icon()
/obj/machinery/atmospherics/proc/setPipingLayer(new_layer)
piping_layer = (pipe_flags & PIPING_DEFAULT_LAYER_ONLY) ? PIPING_LAYER_DEFAULT : new_layer
update_icon()
/obj/machinery/atmospherics/proc/can_be_node(obj/machinery/atmospherics/target, iteration)
return connection_check(target, piping_layer)
//Find a connecting /obj/machinery/atmospherics in specified direction
/obj/machinery/atmospherics/proc/findConnecting(direction, prompted_layer)
for(var/obj/machinery/atmospherics/target in get_step(src, direction))
if(target.initialize_directions & get_dir(target,src))
if(connection_check(target, prompted_layer))
return target
/obj/machinery/atmospherics/proc/connection_check(obj/machinery/atmospherics/target, given_layer)
if(isConnectable(target, given_layer) && target.isConnectable(src, given_layer) && (target.initialize_directions & get_dir(target,src)))
return TRUE
return FALSE
/obj/machinery/atmospherics/proc/isConnectable(obj/machinery/atmospherics/target, given_layer)
if(isnull(given_layer))
given_layer = piping_layer
if((target.piping_layer == given_layer) || (target.pipe_flags & PIPING_ALL_LAYER))
return TRUE
return FALSE
/obj/machinery/atmospherics/proc/pipeline_expansion()
return nodes
/obj/machinery/atmospherics/proc/SetInitDirections()
return
/obj/machinery/atmospherics/proc/GetInitDirections()
return initialize_directions
/obj/machinery/atmospherics/proc/returnPipenet()
return
/obj/machinery/atmospherics/proc/returnPipenetAir()
return
/obj/machinery/atmospherics/proc/setPipenet()
return
/obj/machinery/atmospherics/proc/replacePipenet()
return
/obj/machinery/atmospherics/proc/disconnect(obj/machinery/atmospherics/reference)
if(istype(reference, /obj/machinery/atmospherics/pipe))
var/obj/machinery/atmospherics/pipe/P = reference
P.destroy_network()
nodes[nodes.Find(reference)] = null
update_icon()
/obj/machinery/atmospherics/attackby(obj/item/W, mob/user, params)
if(istype(W, /obj/item/pipe)) //lets you autodrop
var/obj/item/pipe/pipe = W
if(user.dropItemToGround(pipe))
pipe.setPipingLayer(piping_layer) //align it with us
return TRUE
else
return ..()
/obj/machinery/atmospherics/wrench_act(mob/living/user, obj/item/I)
if(!can_unwrench(user))
return ..()
var/turf/T = get_turf(src)
if (level==1 && isturf(T) && T.intact)
to_chat(user, "<span class='warning'>You must remove the plating first!</span>")
return TRUE
var/datum/gas_mixture/int_air = return_air()
var/datum/gas_mixture/env_air = loc.return_air()
add_fingerprint(user)
var/unsafe_wrenching = FALSE
var/internal_pressure = int_air.return_pressure()-env_air.return_pressure()
to_chat(user, "<span class='notice'>You begin to unfasten \the [src]...</span>")
if (internal_pressure > 2*ONE_ATMOSPHERE)
to_chat(user, "<span class='warning'>As you begin unwrenching \the [src] a gush of air blows in your face... maybe you should reconsider?</span>")
unsafe_wrenching = TRUE //Oh dear oh dear
if(I.use_tool(src, user, 20, volume=50))
user.visible_message( \
"[user] unfastens \the [src].", \
"<span class='notice'>You unfasten \the [src].</span>", \
"<span class='italics'>You hear ratchet.</span>")
investigate_log("was <span class='warning'>REMOVED</span> by [key_name(usr)]", INVESTIGATE_ATMOS)
//You unwrenched a pipe full of pressure? Let's splat you into the wall, silly.
if(unsafe_wrenching)
unsafe_pressure_release(user, internal_pressure)
deconstruct(TRUE)
return TRUE
/obj/machinery/atmospherics/proc/can_unwrench(mob/user)
return can_unwrench
// Throws the user when they unwrench a pipe with a major difference between the internal and environmental pressure.
/obj/machinery/atmospherics/proc/unsafe_pressure_release(mob/user, pressures = null)
if(!user)
return
if(!pressures)
var/datum/gas_mixture/int_air = return_air()
var/datum/gas_mixture/env_air = loc.return_air()
pressures = int_air.return_pressure() - env_air.return_pressure()
user.visible_message("<span class='danger'>[user] is sent flying by pressure!</span>","<span class='userdanger'>The pressure sends you flying!</span>")
// if get_dir(src, user) is not 0, target is the edge_target_turf on that dir
// otherwise, edge_target_turf uses a random cardinal direction
// range is pressures / 250
// speed is pressures / 1250
user.throw_at(get_edge_target_turf(user, get_dir(src, user) || pick(GLOB.cardinals)), pressures / 250, pressures / 1250)
/obj/machinery/atmospherics/deconstruct(disassembled = TRUE)
if(!(flags_1 & NODECONSTRUCT_1))
if(can_unwrench)
var/obj/item/pipe/stored = new construction_type(loc, null, dir, src)
stored.setPipingLayer(piping_layer)
if(!disassembled)
stored.obj_integrity = stored.max_integrity * 0.5
transfer_fingerprints_to(stored)
..()
/obj/machinery/atmospherics/proc/getpipeimage(iconset, iconstate, direction, col=rgb(255,255,255), piping_layer=2)
//Add identifiers for the iconset
if(iconsetids[iconset] == null)
iconsetids[iconset] = num2text(iconsetids.len + 1)
//Generate a unique identifier for this image combination
var/identifier = iconsetids[iconset] + "_[iconstate]_[direction]_[col]_[piping_layer]"
if((!(. = pipeimages[identifier])))
var/image/pipe_overlay
pipe_overlay = . = pipeimages[identifier] = image(iconset, iconstate, dir = direction)
pipe_overlay.color = col
PIPING_LAYER_SHIFT(pipe_overlay, piping_layer)
/obj/machinery/atmospherics/on_construction(obj_color, set_layer)
if(can_unwrench)
add_atom_colour(obj_color, FIXED_COLOUR_PRIORITY)
pipe_color = obj_color
setPipingLayer(set_layer)
var/turf/T = get_turf(src)
level = T.intact ? 2 : 1
atmosinit()
var/list/nodes = pipeline_expansion()
for(var/obj/machinery/atmospherics/A in nodes)
A.atmosinit()
A.addMember(src)
build_network()
/obj/machinery/atmospherics/Entered(atom/movable/AM)
if(istype(AM, /mob/living))
var/mob/living/L = AM
L.ventcrawl_layer = piping_layer
return ..()
/obj/machinery/atmospherics/singularity_pull(S, current_size)
if(current_size >= STAGE_FIVE)
deconstruct(FALSE)
return ..()
#define VENT_SOUND_DELAY 30
/obj/machinery/atmospherics/relaymove(mob/living/user, direction)
direction &= initialize_directions
if(!direction || !(direction in GLOB.cardinals)) //cant go this way.
return
if(user in buckled_mobs)// fixes buckle ventcrawl edgecase fuck bug
return
var/obj/machinery/atmospherics/target_move = findConnecting(direction, user.ventcrawl_layer)
if(target_move)
if(target_move.can_crawl_through())
if(is_type_in_typecache(target_move, GLOB.ventcrawl_machinery))
user.forceMove(target_move.loc) //handle entering and so on.
user.visible_message("<span class='notice'>You hear something squeezing through the ducts...</span>", "<span class='notice'>You climb out the ventilation system.")
else
var/list/pipenetdiff = returnPipenets() ^ target_move.returnPipenets()
if(pipenetdiff.len)
user.update_pipe_vision(target_move)
user.forceMove(target_move)
user.client.eye = target_move //Byond only updates the eye every tick, This smooths out the movement
if(world.time - user.last_played_vent > VENT_SOUND_DELAY)
user.last_played_vent = world.time
playsound(src, 'sound/machines/ventcrawl.ogg', 50, 1, -3)
else if(is_type_in_typecache(src, GLOB.ventcrawl_machinery) && can_crawl_through()) //if we move in a way the pipe can connect, but doesn't - or we're in a vent
user.forceMove(loc)
user.visible_message("<span class='notice'>You hear something squeezing through the ducts...</span>", "<span class='notice'>You climb out the ventilation system.")
user.canmove = FALSE
addtimer(VARSET_CALLBACK(user, canmove, TRUE), 1)
/obj/machinery/atmospherics/AltClick(mob/living/L)
if(is_type_in_typecache(src, GLOB.ventcrawl_machinery))
return L.handle_ventcrawl(src)
return ..()
/obj/machinery/atmospherics/proc/can_crawl_through()
return TRUE
/obj/machinery/atmospherics/proc/returnPipenets()
return list()
/obj/machinery/atmospherics/update_remote_sight(mob/user)
user.sight |= (SEE_TURFS|BLIND)
//Used for certain children of obj/machinery/atmospherics to not show pipe vision when mob is inside it.
/obj/machinery/atmospherics/proc/can_see_pipes()
return TRUE
/obj/machinery/atmospherics/proc/update_layer()
layer = initial(layer) + (piping_layer - PIPING_LAYER_DEFAULT) * PIPING_LAYER_LCHANGE
@@ -43,6 +43,7 @@
return ..()
/obj/machinery/atmospherics/components/binary/pump/AltClick(mob/user)
. = ..()
var/area/A = get_area(src)
var/turf/T = get_turf(src)
if(user.canUseTopic(src, BE_CLOSE, FALSE,))
@@ -50,6 +51,7 @@
to_chat(user,"<span class='notice'>You maximize the pressure on the [src].</span>")
investigate_log("Pump, [src.name], was maximized by [key_name(usr)] at [x], [y], [z], [A]", INVESTIGATE_ATMOS)
message_admins("Pump, [src.name], was maximized by [ADMIN_LOOKUPFLW(usr)] at [ADMIN_COORDJMP(T)], [A]")
return TRUE
/obj/machinery/atmospherics/components/binary/pump/Destroy()
SSradio.remove_object(src,frequency)
@@ -31,6 +31,7 @@
return ..()
/obj/machinery/atmospherics/components/trinary/mixer/AltClick(mob/user)
. = ..()
var/area/A = get_area(src)
var/turf/T = get_turf(src)
if(user.canUseTopic(src, BE_CLOSE, FALSE,))
@@ -38,6 +39,7 @@
to_chat(user,"<span class='notice'>You maximize the pressure on the [src].</span>")
investigate_log("Mixer, [src.name], was maximized by [key_name(usr)] at [x], [y], [z], [A]", INVESTIGATE_ATMOS)
message_admins("Mixer, [src.name], was maximized by [ADMIN_LOOKUPFLW(usr)] at [ADMIN_COORDJMP(T)], [A]")
return TRUE
//node 3 is the outlet, nodes 1 & 2 are intakes
@@ -1,430 +1,446 @@
/obj/machinery/atmospherics/components/unary/cryo_cell
name = "cryo cell"
icon = 'icons/obj/cryogenics.dmi'
icon_state = "pod-off"
density = TRUE
max_integrity = 350
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 100, "bomb" = 0, "bio" = 100, "rad" = 100, "fire" = 30, "acid" = 30)
layer = ABOVE_WINDOW_LAYER
state_open = FALSE
circuit = /obj/item/circuitboard/machine/cryo_tube
pipe_flags = PIPING_ONE_PER_TURF | PIPING_DEFAULT_LAYER_ONLY
occupant_typecache = list(/mob/living/carbon, /mob/living/simple_animal)
var/autoeject = FALSE
var/volume = 100
var/efficiency = 1
var/sleep_factor = 0.00125
var/unconscious_factor = 0.001
var/heat_capacity = 20000
var/conduction_coefficient = 0.3
var/obj/item/reagent_containers/glass/beaker = null
var/reagent_transfer = 0
var/obj/item/radio/radio
var/radio_key = /obj/item/encryptionkey/headset_med
var/radio_channel = RADIO_CHANNEL_MEDICAL
var/running_anim = FALSE
var/escape_in_progress = FALSE
var/message_cooldown
var/breakout_time = 300
/obj/machinery/atmospherics/components/unary/cryo_cell/Initialize()
. = ..()
initialize_directions = dir
radio = new(src)
radio.keyslot = new radio_key
radio.subspace_transmission = TRUE
radio.canhear_range = 0
radio.recalculateChannels()
/obj/machinery/atmospherics/components/unary/cryo_cell/on_construction()
..(dir, dir)
/obj/machinery/atmospherics/components/unary/cryo_cell/RefreshParts()
var/C
for(var/obj/item/stock_parts/matter_bin/M in component_parts)
C += M.rating
efficiency = initial(efficiency) * C
sleep_factor = initial(sleep_factor) * C
unconscious_factor = initial(unconscious_factor) * C
heat_capacity = initial(heat_capacity) / C
conduction_coefficient = initial(conduction_coefficient) * C
/obj/machinery/atmospherics/components/unary/cryo_cell/Destroy()
QDEL_NULL(radio)
QDEL_NULL(beaker)
return ..()
/obj/machinery/atmospherics/components/unary/cryo_cell/contents_explosion(severity, target)
..()
if(beaker)
beaker.ex_act(severity, target)
/obj/machinery/atmospherics/components/unary/cryo_cell/handle_atom_del(atom/A)
..()
if(A == beaker)
beaker = null
updateUsrDialog()
/obj/machinery/atmospherics/components/unary/cryo_cell/on_deconstruction()
if(beaker)
beaker.forceMove(drop_location())
beaker = null
/obj/machinery/atmospherics/components/unary/cryo_cell/update_icon()
cut_overlays()
if(panel_open)
add_overlay("pod-panel")
if(state_open)
icon_state = "pod-open"
return
if(occupant)
var/image/occupant_overlay
if(ismonkey(occupant)) // Monkey
occupant_overlay = image(CRYOMOBS, "monkey")
else if(isalienadult(occupant))
if(isalienroyal(occupant)) // Queen and prae
occupant_overlay = image(CRYOMOBS, "alienq")
else if(isalienhunter(occupant)) // Hunter
occupant_overlay = image(CRYOMOBS, "alienh")
else if(isaliensentinel(occupant)) // Sentinel
occupant_overlay = image(CRYOMOBS, "aliens")
else // Drone or other
occupant_overlay = image(CRYOMOBS, "aliend")
else if(ishuman(occupant) || islarva(occupant) || (isanimal(occupant) && !ismegafauna(occupant))) // Mobs that are smaller than cryotube
occupant_overlay = image(occupant.icon, occupant.icon_state)
occupant_overlay.copy_overlays(occupant)
else
occupant_overlay = image(CRYOMOBS, "generic")
occupant_overlay.dir = SOUTH
occupant_overlay.pixel_y = 22
if(on && !running_anim && is_operational())
icon_state = "pod-on"
running_anim = TRUE
run_anim(TRUE, occupant_overlay)
else
icon_state = "pod-off"
add_overlay(occupant_overlay)
add_overlay("cover-off")
else if(on && is_operational())
icon_state = "pod-on"
add_overlay("cover-on")
else
icon_state = "pod-off"
add_overlay("cover-off")
/obj/machinery/atmospherics/components/unary/cryo_cell/proc/run_anim(anim_up, image/occupant_overlay)
if(!on || !occupant || !is_operational())
running_anim = FALSE
return
cut_overlays()
if(occupant_overlay.pixel_y != 23) // Same effect as occupant_overlay.pixel_y == 22 || occupant_overlay.pixel_y == 24
anim_up = occupant_overlay.pixel_y == 22 // Same effect as if(occupant_overlay.pixel_y == 22) anim_up = TRUE ; if(occupant_overlay.pixel_y == 24) anim_up = FALSE
if(anim_up)
occupant_overlay.pixel_y++
else
occupant_overlay.pixel_y--
add_overlay(occupant_overlay)
add_overlay("cover-on")
addtimer(CALLBACK(src, .proc/run_anim, anim_up, occupant_overlay), 7, TIMER_UNIQUE)
/obj/machinery/atmospherics/components/unary/cryo_cell/process()
..()
if(!on)
return
if(!is_operational())
on = FALSE
update_icon()
return
if(!occupant)
return
var/mob/living/mob_occupant = occupant
if(mob_occupant.stat == DEAD) // We don't bother with dead people.
return
if(mob_occupant.health >= mob_occupant.getMaxHealth()) // Don't bother with fully healed people.
on = FALSE
update_icon()
playsound(src, 'sound/machines/cryo_warning.ogg', volume) // Bug the doctors.
var/msg = "Patient fully restored."
if(autoeject) // Eject if configured.
msg += " Auto ejecting patient now."
open_machine()
radio.talk_into(src, msg, radio_channel)
return
var/datum/gas_mixture/air1 = airs[1]
if(air1.gases.len)
if(mob_occupant.bodytemperature < T0C) // Sleepytime. Why? More cryo magic.
mob_occupant.Sleeping((mob_occupant.bodytemperature * sleep_factor) * 2000)
mob_occupant.Unconscious((mob_occupant.bodytemperature * unconscious_factor) * 2000)
if(beaker)
if(reagent_transfer == 0) // Magically transfer reagents. Because cryo magic.
beaker.reagents.trans_to(occupant, 1, efficiency * 0.25) // Transfer reagents.
beaker.reagents.reaction(occupant, VAPOR)
air1.gases[/datum/gas/oxygen] -= max(0,air1.gases[/datum/gas/oxygen] - 2 / efficiency) //Let's use gas for this
GAS_GARBAGE_COLLECT(air1.gases)
if(++reagent_transfer >= 10 * efficiency) // Throttle reagent transfer (higher efficiency will transfer the same amount but consume less from the beaker).
reagent_transfer = 0
return 1
/obj/machinery/atmospherics/components/unary/cryo_cell/process_atmos()
..()
if(!on)
return
var/datum/gas_mixture/air1 = airs[1]
if(!nodes[1] || !airs[1] || !air1.gases.len || air1.gases[/datum/gas/oxygen] < 5) // Turn off if the machine won't work.
on = FALSE
update_icon()
return
if(occupant)
var/mob/living/mob_occupant = occupant
var/cold_protection = 0
var/temperature_delta = air1.temperature - mob_occupant.bodytemperature // The only semi-realistic thing here: share temperature between the cell and the occupant.
if(ishuman(occupant))
var/mob/living/carbon/human/H = occupant
cold_protection = H.get_thermal_protection(air1.temperature, TRUE)
if(abs(temperature_delta) > 1)
var/air_heat_capacity = air1.heat_capacity()
var/heat = ((1 - cold_protection) * 0.1 + conduction_coefficient) * temperature_delta * (air_heat_capacity * heat_capacity / (air_heat_capacity + heat_capacity))
air1.temperature = max(air1.temperature - heat / air_heat_capacity, TCMB)
mob_occupant.adjust_bodytemperature(heat / heat_capacity, TCMB)
air1.gases[/datum/gas/oxygen] = max(0,air1.gases[/datum/gas/oxygen] - 0.5 / efficiency) // Magically consume gas? Why not, we run on cryo magic.
GAS_GARBAGE_COLLECT(air1.gases)
/obj/machinery/atmospherics/components/unary/cryo_cell/power_change()
..()
update_icon()
/obj/machinery/atmospherics/components/unary/cryo_cell/relaymove(mob/user)
if(message_cooldown <= world.time)
message_cooldown = world.time + 50
to_chat(user, "<span class='warning'>[src]'s door won't budge!</span>")
/obj/machinery/atmospherics/components/unary/cryo_cell/open_machine(drop = 0)
if(!state_open && !panel_open)
on = FALSE
..()
for(var/mob/M in contents) //only drop mobs
M.forceMove(get_turf(src))
if(isliving(M))
var/mob/living/L = M
L.update_canmove()
occupant = null
update_icon()
/obj/machinery/atmospherics/components/unary/cryo_cell/close_machine(mob/living/carbon/user)
if((isnull(user) || istype(user)) && state_open && !panel_open)
..(user)
return occupant
/obj/machinery/atmospherics/components/unary/cryo_cell/container_resist(mob/living/user)
user.changeNext_move(CLICK_CD_BREAKOUT)
user.last_special = world.time + CLICK_CD_BREAKOUT
user.visible_message("<span class='notice'>You see [user] kicking against the glass of [src]!</span>", \
"<span class='notice'>You struggle inside [src], kicking the release with your foot... (this will take about [DisplayTimeText(breakout_time)].)</span>", \
"<span class='italics'>You hear a thump from [src].</span>")
if(do_after(user, breakout_time, target = src))
if(!user || user.stat != CONSCIOUS || user.loc != src )
return
user.visible_message("<span class='warning'>[user] successfully broke out of [src]!</span>", \
"<span class='notice'>You successfully break out of [src]!</span>")
open_machine()
/obj/machinery/atmospherics/components/unary/cryo_cell/examine(mob/user)
. = ..()
if(occupant)
if(on)
. += "Someone's inside [src]!"
else
. += "You can barely make out a form floating in [src]."
else
. += "[src] seems empty."
/obj/machinery/atmospherics/components/unary/cryo_cell/MouseDrop_T(mob/target, mob/user)
if(user.stat || user.lying || !Adjacent(user) || !user.Adjacent(target) || !iscarbon(target) || !user.IsAdvancedToolUser())
return
if (target.IsKnockdown() || target.IsStun() || target.IsSleeping() || target.IsUnconscious())
close_machine(target)
else
user.visible_message("<b>[user]</b> starts shoving [target] inside [src].", "<span class='notice'>You start shoving [target] inside [src].</span>")
if (do_after(user, 25, target=target))
close_machine(target)
/obj/machinery/atmospherics/components/unary/cryo_cell/attackby(obj/item/I, mob/user, params)
if(istype(I, /obj/item/reagent_containers/glass))
. = 1 //no afterattack
if(beaker)
to_chat(user, "<span class='warning'>A beaker is already loaded into [src]!</span>")
return
if(!user.transferItemToLoc(I, src))
return
beaker = I
user.visible_message("[user] places [I] in [src].", \
"<span class='notice'>You place [I] in [src].</span>")
var/reagentlist = pretty_string_from_reagent_list(I.reagents.reagent_list)
log_game("[key_name(user)] added an [I] to cryo containing [reagentlist]")
return
if(!on && !occupant && !state_open && (default_deconstruction_screwdriver(user, "pod-off", "pod-off", I)) \
|| default_change_direction_wrench(user, I) \
|| default_pry_open(I) \
|| default_deconstruction_crowbar(I))
update_icon()
return
else if(istype(I, /obj/item/screwdriver))
to_chat(user, "<span class='notice'>You can't access the maintenance panel while the pod is " \
+ (on ? "active" : (occupant ? "full" : "open")) + ".</span>")
return
return ..()
/obj/machinery/atmospherics/components/unary/cryo_cell/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.notcontained_state)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
ui = new(user, src, ui_key, "cryo", name, 400, 550, master_ui, state)
ui.open()
/obj/machinery/atmospherics/components/unary/cryo_cell/ui_data()
var/list/data = list()
data["isOperating"] = on
data["hasOccupant"] = occupant ? TRUE : FALSE
data["isOpen"] = state_open
data["autoEject"] = autoeject
data["occupant"] = list()
if(occupant)
var/mob/living/mob_occupant = occupant
data["occupant"]["name"] = mob_occupant.name
switch(mob_occupant.stat)
if(CONSCIOUS)
data["occupant"]["stat"] = "Conscious"
data["occupant"]["statstate"] = "good"
if(SOFT_CRIT)
data["occupant"]["stat"] = "Conscious"
data["occupant"]["statstate"] = "average"
if(UNCONSCIOUS)
data["occupant"]["stat"] = "Unconscious"
data["occupant"]["statstate"] = "average"
if(DEAD)
data["occupant"]["stat"] = "Dead"
data["occupant"]["statstate"] = "bad"
data["occupant"]["health"] = round(mob_occupant.health, 1)
data["occupant"]["maxHealth"] = mob_occupant.maxHealth
data["occupant"]["minHealth"] = HEALTH_THRESHOLD_DEAD
data["occupant"]["bruteLoss"] = round(mob_occupant.getBruteLoss(), 1)
data["occupant"]["oxyLoss"] = round(mob_occupant.getOxyLoss(), 1)
data["occupant"]["toxLoss"] = round(mob_occupant.getToxLoss(), 1)
data["occupant"]["fireLoss"] = round(mob_occupant.getFireLoss(), 1)
data["occupant"]["bodyTemperature"] = round(mob_occupant.bodytemperature, 1)
if(mob_occupant.bodytemperature < TCRYO)
data["occupant"]["temperaturestatus"] = "good"
else if(mob_occupant.bodytemperature < T0C)
data["occupant"]["temperaturestatus"] = "average"
else
data["occupant"]["temperaturestatus"] = "bad"
var/datum/gas_mixture/air1 = airs[1]
data["cellTemperature"] = round(air1.temperature, 1)
data["isBeakerLoaded"] = beaker ? TRUE : FALSE
var/beakerContents = list()
if(beaker && beaker.reagents && beaker.reagents.reagent_list.len)
for(var/datum/reagent/R in beaker.reagents.reagent_list)
beakerContents += list(list("name" = R.name, "volume" = R.volume))
data["beakerContents"] = beakerContents
return data
/obj/machinery/atmospherics/components/unary/cryo_cell/ui_act(action, params)
if(..())
return
switch(action)
if("power")
if(on)
on = FALSE
else if(!state_open)
on = TRUE
. = TRUE
if("door")
if(state_open)
close_machine()
else
open_machine()
. = TRUE
if("autoeject")
autoeject = !autoeject
. = TRUE
if("ejectbeaker")
if(beaker)
beaker.forceMove(drop_location())
if(Adjacent(usr) && !issilicon(usr))
usr.put_in_hands(beaker)
beaker = null
. = TRUE
update_icon()
/obj/machinery/atmospherics/components/unary/cryo_cell/update_remote_sight(mob/living/user)
return // we don't see the pipe network while inside cryo.
/obj/machinery/atmospherics/components/unary/cryo_cell/get_remote_view_fullscreens(mob/user)
user.overlay_fullscreen("remote_view", /obj/screen/fullscreen/impaired, 1)
/obj/machinery/atmospherics/components/unary/cryo_cell/can_crawl_through()
return // can't ventcrawl in or out of cryo.
/obj/machinery/atmospherics/components/unary/cryo_cell/can_see_pipes()
return 0 // you can't see the pipe network when inside a cryo cell.
/obj/machinery/atmospherics/components/unary/cryo_cell/return_temperature()
var/datum/gas_mixture/G = airs[1]
if(G.total_moles() > 10)
return G.temperature
return ..()
/obj/machinery/atmospherics/components/unary/cryo_cell/default_change_direction_wrench(mob/user, obj/item/wrench/W)
. = ..()
if(.)
SetInitDirections()
var/obj/machinery/atmospherics/node = nodes[1]
if(node)
node.disconnect(src)
nodes[1] = null
nullifyPipenet(parents[1])
atmosinit()
node = nodes[1]
if(node)
node.atmosinit()
node.addMember(src)
build_network()
#undef CRYOMOBS
/obj/machinery/atmospherics/components/unary/cryo_cell
name = "cryo cell"
icon = 'icons/obj/cryogenics.dmi'
icon_state = "pod-off"
density = TRUE
max_integrity = 350
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 100, "bomb" = 0, "bio" = 100, "rad" = 100, "fire" = 30, "acid" = 30)
layer = ABOVE_WINDOW_LAYER
state_open = FALSE
circuit = /obj/item/circuitboard/machine/cryo_tube
pipe_flags = PIPING_ONE_PER_TURF | PIPING_DEFAULT_LAYER_ONLY
occupant_typecache = list(/mob/living/carbon, /mob/living/simple_animal)
var/autoeject = FALSE
var/volume = 100
var/efficiency = 1
var/sleep_factor = 0.00125
var/unconscious_factor = 0.001
var/heat_capacity = 20000
var/conduction_coefficient = 0.3
var/obj/item/reagent_containers/glass/beaker = null
var/reagent_transfer = 0
var/obj/item/radio/radio
var/radio_key = /obj/item/encryptionkey/headset_med
var/radio_channel = RADIO_CHANNEL_MEDICAL
var/running_anim = FALSE
var/escape_in_progress = FALSE
var/message_cooldown
var/breakout_time = 300
/obj/machinery/atmospherics/components/unary/cryo_cell/Initialize()
. = ..()
initialize_directions = dir
radio = new(src)
radio.keyslot = new radio_key
radio.subspace_transmission = TRUE
radio.canhear_range = 0
radio.recalculateChannels()
/obj/machinery/atmospherics/components/unary/cryo_cell/on_construction()
..(dir, dir)
/obj/machinery/atmospherics/components/unary/cryo_cell/RefreshParts()
var/C
for(var/obj/item/stock_parts/matter_bin/M in component_parts)
C += M.rating
efficiency = initial(efficiency) * C
sleep_factor = initial(sleep_factor) * C
unconscious_factor = initial(unconscious_factor) * C
heat_capacity = initial(heat_capacity) / C
conduction_coefficient = initial(conduction_coefficient) * C
/obj/machinery/atmospherics/components/unary/cryo_cell/Destroy()
QDEL_NULL(radio)
QDEL_NULL(beaker)
return ..()
/obj/machinery/atmospherics/components/unary/cryo_cell/contents_explosion(severity, target)
..()
if(beaker)
beaker.ex_act(severity, target)
/obj/machinery/atmospherics/components/unary/cryo_cell/handle_atom_del(atom/A)
..()
if(A == beaker)
beaker = null
updateUsrDialog()
/obj/machinery/atmospherics/components/unary/cryo_cell/on_deconstruction()
if(beaker)
beaker.forceMove(drop_location())
beaker = null
/obj/machinery/atmospherics/components/unary/cryo_cell/update_icon()
cut_overlays()
if(panel_open)
add_overlay("pod-panel")
if(state_open)
icon_state = "pod-open"
return
if(occupant)
var/image/occupant_overlay
if(ismonkey(occupant)) // Monkey
occupant_overlay = image(CRYOMOBS, "monkey")
else if(isalienadult(occupant))
if(isalienroyal(occupant)) // Queen and prae
occupant_overlay = image(CRYOMOBS, "alienq")
else if(isalienhunter(occupant)) // Hunter
occupant_overlay = image(CRYOMOBS, "alienh")
else if(isaliensentinel(occupant)) // Sentinel
occupant_overlay = image(CRYOMOBS, "aliens")
else // Drone or other
occupant_overlay = image(CRYOMOBS, "aliend")
else if(ishuman(occupant) || islarva(occupant) || (isanimal(occupant) && !ismegafauna(occupant))) // Mobs that are smaller than cryotube
occupant_overlay = image(occupant.icon, occupant.icon_state)
occupant_overlay.copy_overlays(occupant)
else
occupant_overlay = image(CRYOMOBS, "generic")
occupant_overlay.dir = SOUTH
occupant_overlay.pixel_y = 22
if(on && !running_anim && is_operational())
icon_state = "pod-on"
running_anim = TRUE
run_anim(TRUE, occupant_overlay)
else
icon_state = "pod-off"
add_overlay(occupant_overlay)
add_overlay("cover-off")
else if(on && is_operational())
icon_state = "pod-on"
add_overlay("cover-on")
else
icon_state = "pod-off"
add_overlay("cover-off")
/obj/machinery/atmospherics/components/unary/cryo_cell/proc/run_anim(anim_up, image/occupant_overlay)
if(!on || !occupant || !is_operational())
running_anim = FALSE
return
cut_overlays()
if(occupant_overlay.pixel_y != 23) // Same effect as occupant_overlay.pixel_y == 22 || occupant_overlay.pixel_y == 24
anim_up = occupant_overlay.pixel_y == 22 // Same effect as if(occupant_overlay.pixel_y == 22) anim_up = TRUE ; if(occupant_overlay.pixel_y == 24) anim_up = FALSE
if(anim_up)
occupant_overlay.pixel_y++
else
occupant_overlay.pixel_y--
add_overlay(occupant_overlay)
add_overlay("cover-on")
addtimer(CALLBACK(src, .proc/run_anim, anim_up, occupant_overlay), 7, TIMER_UNIQUE)
/obj/machinery/atmospherics/components/unary/cryo_cell/process()
..()
if(!on)
return
if(!is_operational())
on = FALSE
update_icon()
return
if(!occupant)
return
var/mob/living/mob_occupant = occupant
if(mob_occupant.stat == DEAD) // We don't bother with dead people.
return
if(mob_occupant.health >= mob_occupant.getMaxHealth()) // Don't bother with fully healed people.
on = FALSE
update_icon()
playsound(src, 'sound/machines/cryo_warning.ogg', volume) // Bug the doctors.
var/msg = "Patient fully restored."
if(autoeject) // Eject if configured.
msg += " Auto ejecting patient now."
open_machine()
radio.talk_into(src, msg, radio_channel)
return
var/datum/gas_mixture/air1 = airs[1]
if(air1.gases.len)
if(mob_occupant.bodytemperature < T0C) // Sleepytime. Why? More cryo magic.
mob_occupant.Sleeping((mob_occupant.bodytemperature * sleep_factor) * 2000)
mob_occupant.Unconscious((mob_occupant.bodytemperature * unconscious_factor) * 2000)
if(beaker)
if(reagent_transfer == 0) // Magically transfer reagents. Because cryo magic.
beaker.reagents.trans_to(occupant, 1, efficiency * 0.25) // Transfer reagents.
beaker.reagents.reaction(occupant, VAPOR)
air1.gases[/datum/gas/oxygen] -= max(0,air1.gases[/datum/gas/oxygen] - 2 / efficiency) //Let's use gas for this
GAS_GARBAGE_COLLECT(air1.gases)
if(++reagent_transfer >= 10 * efficiency) // Throttle reagent transfer (higher efficiency will transfer the same amount but consume less from the beaker).
reagent_transfer = 0
return 1
/obj/machinery/atmospherics/components/unary/cryo_cell/process_atmos()
..()
if(!on)
return
var/datum/gas_mixture/air1 = airs[1]
if(!nodes[1] || !airs[1] || !air1.gases.len || air1.gases[/datum/gas/oxygen] < 5) // Turn off if the machine won't work.
on = FALSE
update_icon()
return
if(occupant)
var/mob/living/mob_occupant = occupant
var/cold_protection = 0
var/temperature_delta = air1.temperature - mob_occupant.bodytemperature // The only semi-realistic thing here: share temperature between the cell and the occupant.
if(ishuman(occupant))
var/mob/living/carbon/human/H = occupant
cold_protection = H.get_thermal_protection(air1.temperature, TRUE)
if(abs(temperature_delta) > 1)
var/air_heat_capacity = air1.heat_capacity()
var/heat = ((1 - cold_protection) * 0.1 + conduction_coefficient) * temperature_delta * (air_heat_capacity * heat_capacity / (air_heat_capacity + heat_capacity))
air1.temperature = max(air1.temperature - heat / air_heat_capacity, TCMB)
mob_occupant.adjust_bodytemperature(heat / heat_capacity, TCMB)
air1.gases[/datum/gas/oxygen] = max(0,air1.gases[/datum/gas/oxygen] - 0.5 / efficiency) // Magically consume gas? Why not, we run on cryo magic.
GAS_GARBAGE_COLLECT(air1.gases)
/obj/machinery/atmospherics/components/unary/cryo_cell/power_change()
..()
update_icon()
/obj/machinery/atmospherics/components/unary/cryo_cell/relaymove(mob/user)
if(message_cooldown <= world.time)
message_cooldown = world.time + 50
to_chat(user, "<span class='warning'>[src]'s door won't budge!</span>")
/obj/machinery/atmospherics/components/unary/cryo_cell/open_machine(drop = 0)
if(!state_open && !panel_open)
on = FALSE
..()
for(var/mob/M in contents) //only drop mobs
M.forceMove(get_turf(src))
if(isliving(M))
var/mob/living/L = M
L.update_canmove()
occupant = null
update_icon()
/obj/machinery/atmospherics/components/unary/cryo_cell/close_machine(mob/living/carbon/user)
if((isnull(user) || istype(user)) && state_open && !panel_open)
..(user)
return occupant
/obj/machinery/atmospherics/components/unary/cryo_cell/container_resist(mob/living/user)
user.changeNext_move(CLICK_CD_BREAKOUT)
user.last_special = world.time + CLICK_CD_BREAKOUT
user.visible_message("<span class='notice'>You see [user] kicking against the glass of [src]!</span>", \
"<span class='notice'>You struggle inside [src], kicking the release with your foot... (this will take about [DisplayTimeText(breakout_time)].)</span>", \
"<span class='italics'>You hear a thump from [src].</span>")
if(do_after(user, breakout_time, target = src))
if(!user || user.stat != CONSCIOUS || user.loc != src )
return
user.visible_message("<span class='warning'>[user] successfully broke out of [src]!</span>", \
"<span class='notice'>You successfully break out of [src]!</span>")
open_machine()
/obj/machinery/atmospherics/components/unary/cryo_cell/examine(mob/user)
. = ..()
if(occupant)
if(on)
. += "Someone's inside [src]!"
else
. += "You can barely make out a form floating in [src]."
else
. += "[src] seems empty."
/obj/machinery/atmospherics/components/unary/cryo_cell/MouseDrop_T(mob/target, mob/user)
if(user.stat || user.lying || !Adjacent(user) || !user.Adjacent(target) || !iscarbon(target) || !user.IsAdvancedToolUser())
return
if (target.IsKnockdown() || target.IsStun() || target.IsSleeping() || target.IsUnconscious())
close_machine(target)
else
user.visible_message("<b>[user]</b> starts shoving [target] inside [src].", "<span class='notice'>You start shoving [target] inside [src].</span>")
if (do_after(user, 25, target=target))
close_machine(target)
/obj/machinery/atmospherics/components/unary/cryo_cell/attackby(obj/item/I, mob/user, params)
if(istype(I, /obj/item/reagent_containers/glass))
. = 1 //no afterattack
if(beaker)
to_chat(user, "<span class='warning'>A beaker is already loaded into [src]!</span>")
return
if(!user.transferItemToLoc(I, src))
return
beaker = I
user.visible_message("[user] places [I] in [src].", \
"<span class='notice'>You place [I] in [src].</span>")
var/reagentlist = pretty_string_from_reagent_list(I.reagents.reagent_list)
log_game("[key_name(user)] added an [I] to cryo containing [reagentlist]")
return
if(!on && !occupant && !state_open && (default_deconstruction_screwdriver(user, "pod-off", "pod-off", I)) \
|| default_change_direction_wrench(user, I) \
|| default_pry_open(I) \
|| default_deconstruction_crowbar(I))
update_icon()
return
else if(istype(I, /obj/item/screwdriver))
to_chat(user, "<span class='notice'>You can't access the maintenance panel while the pod is " \
+ (on ? "active" : (occupant ? "full" : "open")) + ".</span>")
return
return ..()
/obj/machinery/atmospherics/components/unary/cryo_cell/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.notcontained_state)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
ui = new(user, src, ui_key, "cryo", name, 400, 550, master_ui, state)
ui.open()
/obj/machinery/atmospherics/components/unary/cryo_cell/ui_data()
var/list/data = list()
data["isOperating"] = on
data["hasOccupant"] = occupant ? TRUE : FALSE
data["isOpen"] = state_open
data["autoEject"] = autoeject
data["occupant"] = list()
if(occupant)
var/mob/living/mob_occupant = occupant
data["occupant"]["name"] = mob_occupant.name
switch(mob_occupant.stat)
if(CONSCIOUS)
data["occupant"]["stat"] = "Conscious"
data["occupant"]["statstate"] = "good"
if(SOFT_CRIT)
data["occupant"]["stat"] = "Conscious"
data["occupant"]["statstate"] = "average"
if(UNCONSCIOUS)
data["occupant"]["stat"] = "Unconscious"
data["occupant"]["statstate"] = "average"
if(DEAD)
data["occupant"]["stat"] = "Dead"
data["occupant"]["statstate"] = "bad"
data["occupant"]["health"] = round(mob_occupant.health, 1)
data["occupant"]["maxHealth"] = mob_occupant.maxHealth
data["occupant"]["minHealth"] = HEALTH_THRESHOLD_DEAD
data["occupant"]["bruteLoss"] = round(mob_occupant.getBruteLoss(), 1)
data["occupant"]["oxyLoss"] = round(mob_occupant.getOxyLoss(), 1)
data["occupant"]["toxLoss"] = round(mob_occupant.getToxLoss(), 1)
data["occupant"]["fireLoss"] = round(mob_occupant.getFireLoss(), 1)
data["occupant"]["bodyTemperature"] = round(mob_occupant.bodytemperature, 1)
if(mob_occupant.bodytemperature < TCRYO)
data["occupant"]["temperaturestatus"] = "good"
else if(mob_occupant.bodytemperature < T0C)
data["occupant"]["temperaturestatus"] = "average"
else
data["occupant"]["temperaturestatus"] = "bad"
var/datum/gas_mixture/air1 = airs[1]
data["cellTemperature"] = round(air1.temperature, 1)
data["isBeakerLoaded"] = beaker ? TRUE : FALSE
var/beakerContents = list()
if(beaker && beaker.reagents && beaker.reagents.reagent_list.len)
for(var/datum/reagent/R in beaker.reagents.reagent_list)
beakerContents += list(list("name" = R.name, "volume" = R.volume))
data["beakerContents"] = beakerContents
return data
/obj/machinery/atmospherics/components/unary/cryo_cell/ui_act(action, params)
if(..())
return
switch(action)
if("power")
if(on)
on = FALSE
else if(!state_open)
on = TRUE
. = TRUE
if("door")
if(state_open)
close_machine()
else
open_machine()
. = TRUE
if("autoeject")
autoeject = !autoeject
. = TRUE
if("ejectbeaker")
if(beaker)
beaker.forceMove(drop_location())
if(Adjacent(usr) && !issilicon(usr))
usr.put_in_hands(beaker)
beaker = null
. = TRUE
update_icon()
/obj/machinery/atmospherics/components/unary/cryo_cell/CtrlClick(mob/user)
if(user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK) && !state_open)
on = !on
update_icon()
return ..()
/obj/machinery/atmospherics/components/unary/cryo_cell/AltClick(mob/user)
. = ..()
if(user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK))
if(state_open)
close_machine()
else
open_machine()
update_icon()
return TRUE
/obj/machinery/atmospherics/components/unary/cryo_cell/update_remote_sight(mob/living/user)
return // we don't see the pipe network while inside cryo.
/obj/machinery/atmospherics/components/unary/cryo_cell/get_remote_view_fullscreens(mob/user)
user.overlay_fullscreen("remote_view", /obj/screen/fullscreen/impaired, 1)
/obj/machinery/atmospherics/components/unary/cryo_cell/can_crawl_through()
return // can't ventcrawl in or out of cryo.
/obj/machinery/atmospherics/components/unary/cryo_cell/can_see_pipes()
return 0 // you can't see the pipe network when inside a cryo cell.
/obj/machinery/atmospherics/components/unary/cryo_cell/return_temperature()
var/datum/gas_mixture/G = airs[1]
if(G.total_moles() > 10)
return G.temperature
return ..()
/obj/machinery/atmospherics/components/unary/cryo_cell/default_change_direction_wrench(mob/user, obj/item/wrench/W)
. = ..()
if(.)
SetInitDirections()
var/obj/machinery/atmospherics/node = nodes[1]
if(node)
node.disconnect(src)
nodes[1] = null
nullifyPipenet(parents[1])
atmosinit()
node = nodes[1]
if(node)
node.atmosinit()
node.addMember(src)
build_network()
#undef CRYOMOBS
@@ -217,13 +217,15 @@
min_temperature = max(T0C - (initial(min_temperature) + L * 15), TCMB) //73.15K with T1 stock parts
/obj/machinery/atmospherics/components/unary/thermomachine/freezer/AltClick(mob/living/user)
. = ..()
var/area/A = get_area(src)
var/turf/T = get_turf(src)
if(!istype(user) || !user.canUseTopic(src, BE_CLOSE))
return
target_temperature = min_temperature
target_temperature = min_temperature
investigate_log("was set to [target_temperature] K by [key_name(usr)]", INVESTIGATE_ATMOS)
message_admins("[src.name] was minimized by [ADMIN_LOOKUPFLW(usr)] at [ADMIN_COORDJMP(T)], [A]")
return TRUE
/obj/machinery/atmospherics/components/unary/thermomachine/heater
name = "heater"
@@ -247,6 +249,7 @@
max_temperature = T20C + (initial(max_temperature) * L) //573.15K with T1 stock parts
/obj/machinery/atmospherics/components/unary/thermomachine/heater/AltClick(mob/living/user)
. = ..()
var/area/A = get_area(src)
var/turf/T = get_turf(src)
if(!istype(user) || !user.canUseTopic(src, BE_CLOSE))
@@ -254,3 +257,4 @@
target_temperature = max_temperature
investigate_log("was set to [target_temperature] K by [key_name(usr)]", INVESTIGATE_ATMOS)
message_admins("[src.name] was maximized by [ADMIN_LOOKUPFLW(usr)] at [ADMIN_COORDJMP(T)], [A]")
return TRUE
@@ -1,154 +1,156 @@
/obj/machinery/portable_atmospherics
name = "portable_atmospherics"
icon = 'icons/obj/atmos.dmi'
use_power = NO_POWER_USE
max_integrity = 250
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 100, "bomb" = 0, "bio" = 100, "rad" = 100, "fire" = 60, "acid" = 30)
anchored = FALSE
var/datum/gas_mixture/air_contents
var/obj/machinery/atmospherics/components/unary/portables_connector/connected_port
var/obj/item/tank/holding
var/volume = 0
var/maximum_pressure = 90 * ONE_ATMOSPHERE
/obj/machinery/portable_atmospherics/New()
..()
SSair.atmos_machinery += src
air_contents = new
air_contents.volume = volume
air_contents.temperature = T20C
return 1
/obj/machinery/portable_atmospherics/Destroy()
SSair.atmos_machinery -= src
disconnect()
qdel(air_contents)
air_contents = null
return ..()
/obj/machinery/portable_atmospherics/process_atmos()
if(!connected_port) // Pipe network handles reactions if connected.
air_contents.react(src)
else
update_icon()
/obj/machinery/portable_atmospherics/return_air()
return air_contents
/obj/machinery/portable_atmospherics/proc/connect(obj/machinery/atmospherics/components/unary/portables_connector/new_port)
//Make sure not already connected to something else
if(connected_port || !new_port || new_port.connected_device)
return FALSE
//Make sure are close enough for a valid connection
if(new_port.loc != get_turf(src))
return FALSE
//Perform the connection
connected_port = new_port
connected_port.connected_device = src
var/datum/pipeline/connected_port_parent = connected_port.parents[1]
connected_port_parent.reconcile_air()
anchored = TRUE //Prevent movement
pixel_x = new_port.pixel_x
pixel_y = new_port.pixel_y
return TRUE
/obj/machinery/portable_atmospherics/Move()
. = ..()
if(.)
disconnect()
/obj/machinery/portable_atmospherics/proc/disconnect()
if(!connected_port)
return FALSE
anchored = FALSE
connected_port.connected_device = null
connected_port = null
pixel_x = 0
pixel_y = 0
return TRUE
/obj/machinery/portable_atmospherics/portableConnectorReturnAir()
return air_contents
/obj/machinery/portable_atmospherics/AltClick(mob/living/user)
if(!istype(user) || !user.canUseTopic(src, BE_CLOSE, !ismonkey(user)))
return
if(holding)
to_chat(user, "<span class='notice'>You remove [holding] from [src].</span>")
replace_tank(user, TRUE)
/obj/machinery/portable_atmospherics/examine(mob/user)
. = ..()
if(holding)
. += "<span class='notice'>\The [src] contains [holding]. Alt-click [src] to remove it.</span>"
. += "<span class='notice'>Click [src] with another gas tank to hot swap [holding].</span>"
/obj/machinery/portable_atmospherics/proc/replace_tank(mob/living/user, close_valve, obj/item/tank/new_tank)
if(holding)
holding.forceMove(drop_location())
if(Adjacent(user) && !issilicon(user))
user.put_in_hands(holding)
if(new_tank)
holding = new_tank
else
holding = null
update_icon()
return TRUE
/obj/machinery/portable_atmospherics/attackby(obj/item/W, mob/user, params)
if(istype(W, /obj/item/tank))
if(!(stat & BROKEN))
var/obj/item/tank/T = W
if(!user.transferItemToLoc(T, src))
return
to_chat(user, "<span class='notice'>[holding ? "In one smooth motion you pop [holding] out of [src]'s connector and replace it with [T]" : "You insert [T] into [src]"].</span>")
replace_tank(user, FALSE, T)
update_icon()
else if(istype(W, /obj/item/wrench))
if(!(stat & BROKEN))
if(connected_port)
disconnect()
W.play_tool_sound(src)
user.visible_message( \
"[user] disconnects [src].", \
"<span class='notice'>You unfasten [src] from the port.</span>", \
"<span class='italics'>You hear a ratchet.</span>")
update_icon()
return
else
var/obj/machinery/atmospherics/components/unary/portables_connector/possible_port = locate(/obj/machinery/atmospherics/components/unary/portables_connector) in loc
if(!possible_port)
to_chat(user, "<span class='notice'>Nothing happens.</span>")
return
if(!connect(possible_port))
to_chat(user, "<span class='notice'>[name] failed to connect to the port.</span>")
return
W.play_tool_sound(src)
user.visible_message( \
"[user] connects [src].", \
"<span class='notice'>You fasten [src] to the port.</span>", \
"<span class='italics'>You hear a ratchet.</span>")
update_icon()
else
return ..()
/obj/machinery/portable_atmospherics/analyzer_act(mob/living/user, obj/item/I)
atmosanalyzer_scan(air_contents, user, src)
/obj/machinery/portable_atmospherics/attacked_by(obj/item/I, mob/user)
if(I.force < 10 && !(stat & BROKEN))
take_damage(0)
else
investigate_log("was smacked with \a [I] by [key_name(user)].", INVESTIGATE_ATMOS)
add_fingerprint(user)
..()
/obj/machinery/portable_atmospherics
name = "portable_atmospherics"
icon = 'icons/obj/atmos.dmi'
use_power = NO_POWER_USE
max_integrity = 250
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 100, "bomb" = 0, "bio" = 100, "rad" = 100, "fire" = 60, "acid" = 30)
anchored = FALSE
var/datum/gas_mixture/air_contents
var/obj/machinery/atmospherics/components/unary/portables_connector/connected_port
var/obj/item/tank/holding
var/volume = 0
var/maximum_pressure = 90 * ONE_ATMOSPHERE
/obj/machinery/portable_atmospherics/New()
..()
SSair.atmos_machinery += src
air_contents = new
air_contents.volume = volume
air_contents.temperature = T20C
return 1
/obj/machinery/portable_atmospherics/Destroy()
SSair.atmos_machinery -= src
disconnect()
qdel(air_contents)
air_contents = null
return ..()
/obj/machinery/portable_atmospherics/process_atmos()
if(!connected_port) // Pipe network handles reactions if connected.
air_contents.react(src)
else
update_icon()
/obj/machinery/portable_atmospherics/return_air()
return air_contents
/obj/machinery/portable_atmospherics/proc/connect(obj/machinery/atmospherics/components/unary/portables_connector/new_port)
//Make sure not already connected to something else
if(connected_port || !new_port || new_port.connected_device)
return FALSE
//Make sure are close enough for a valid connection
if(new_port.loc != get_turf(src))
return FALSE
//Perform the connection
connected_port = new_port
connected_port.connected_device = src
var/datum/pipeline/connected_port_parent = connected_port.parents[1]
connected_port_parent.reconcile_air()
anchored = TRUE //Prevent movement
pixel_x = new_port.pixel_x
pixel_y = new_port.pixel_y
return TRUE
/obj/machinery/portable_atmospherics/Move()
. = ..()
if(.)
disconnect()
/obj/machinery/portable_atmospherics/proc/disconnect()
if(!connected_port)
return FALSE
anchored = FALSE
connected_port.connected_device = null
connected_port = null
pixel_x = 0
pixel_y = 0
return TRUE
/obj/machinery/portable_atmospherics/portableConnectorReturnAir()
return air_contents
/obj/machinery/portable_atmospherics/AltClick(mob/living/user)
. = ..()
if(!istype(user) || !user.canUseTopic(src, BE_CLOSE, !ismonkey(user)))
return
if(holding)
to_chat(user, "<span class='notice'>You remove [holding] from [src].</span>")
replace_tank(user, TRUE)
return TRUE
/obj/machinery/portable_atmospherics/examine(mob/user)
. = ..()
if(holding)
. += "<span class='notice'>\The [src] contains [holding]. Alt-click [src] to remove it.</span>"
. += "<span class='notice'>Click [src] with another gas tank to hot swap [holding].</span>"
/obj/machinery/portable_atmospherics/proc/replace_tank(mob/living/user, close_valve, obj/item/tank/new_tank)
if(holding)
holding.forceMove(drop_location())
if(Adjacent(user) && !issilicon(user))
user.put_in_hands(holding)
if(new_tank)
holding = new_tank
else
holding = null
update_icon()
return TRUE
/obj/machinery/portable_atmospherics/attackby(obj/item/W, mob/user, params)
if(istype(W, /obj/item/tank))
if(!(stat & BROKEN))
var/obj/item/tank/T = W
if(!user.transferItemToLoc(T, src))
return
to_chat(user, "<span class='notice'>[holding ? "In one smooth motion you pop [holding] out of [src]'s connector and replace it with [T]" : "You insert [T] into [src]"].</span>")
replace_tank(user, FALSE, T)
update_icon()
else if(istype(W, /obj/item/wrench))
if(!(stat & BROKEN))
if(connected_port)
disconnect()
W.play_tool_sound(src)
user.visible_message( \
"[user] disconnects [src].", \
"<span class='notice'>You unfasten [src] from the port.</span>", \
"<span class='italics'>You hear a ratchet.</span>")
update_icon()
return
else
var/obj/machinery/atmospherics/components/unary/portables_connector/possible_port = locate(/obj/machinery/atmospherics/components/unary/portables_connector) in loc
if(!possible_port)
to_chat(user, "<span class='notice'>Nothing happens.</span>")
return
if(!connect(possible_port))
to_chat(user, "<span class='notice'>[name] failed to connect to the port.</span>")
return
W.play_tool_sound(src)
user.visible_message( \
"[user] connects [src].", \
"<span class='notice'>You fasten [src] to the port.</span>", \
"<span class='italics'>You hear a ratchet.</span>")
update_icon()
else
return ..()
/obj/machinery/portable_atmospherics/analyzer_act(mob/living/user, obj/item/I)
atmosanalyzer_scan(air_contents, user, src)
/obj/machinery/portable_atmospherics/attacked_by(obj/item/I, mob/user)
if(I.force < 10 && !(stat & BROKEN))
take_damage(0)
else
investigate_log("was smacked with \a [I] by [key_name(user)].", INVESTIGATE_ATMOS)
add_fingerprint(user)
..()
+2
View File
@@ -76,12 +76,14 @@
to_chat(user, "<span class='notice'>[src] linked to [C].</span>")
/obj/item/supplypod_beacon/AltClick(mob/user)
. = ..()
if (!user.canUseTopic(src, !issilicon(user)))
return
if (express_console)
unlink_console()
else
to_chat(user, "<span class='notice'>There is no linked console!</span>")
return TRUE
/obj/item/supplypod_beacon/attackby(obj/item/W, mob/user)
if(istype(W, /obj/item/pen)) //give a tag that is visible from the linked express console
+5 -7
View File
@@ -269,16 +269,14 @@ BLIND // can't see anything
H.update_suit_sensors()
/obj/item/clothing/under/AltClick(mob/user)
if(..())
return 1
. = ..()
if(!istype(user) || !user.canUseTopic(src, BE_CLOSE, ismonkey(user)))
return
if(attached_accessory)
remove_accessory(user)
else
if(attached_accessory)
remove_accessory(user)
else
rolldown()
rolldown()
return TRUE
/obj/item/clothing/under/verb/jumpsuit_adjust()
set name = "Adjust Jumpsuit Style"
+441 -443
View File
@@ -1,443 +1,441 @@
//Glasses
/obj/item/clothing/glasses
name = "glasses"
icon = 'icons/obj/clothing/glasses.dmi'
w_class = WEIGHT_CLASS_SMALL
flags_cover = GLASSESCOVERSEYES
slot_flags = ITEM_SLOT_EYES
strip_delay = 20
equip_delay_other = 25
resistance_flags = NONE
materials = list(MAT_GLASS = 250)
var/vision_flags = 0
var/darkness_view = 2//Base human is 2
var/invis_view = SEE_INVISIBLE_LIVING //admin only for now
var/invis_override = 0 //Override to allow glasses to set higher than normal see_invis
var/lighting_alpha
var/list/icon/current = list() //the current hud icons
var/vision_correction = 0 //does wearing these glasses correct some of our vision defects?
var/glass_colour_type //colors your vision when worn
/obj/item/clothing/glasses/suicide_act(mob/living/carbon/user)
user.visible_message("<span class='suicide'>[user] is stabbing \the [src] into [user.p_their()] eyes! It looks like [user.p_theyre()] trying to commit suicide!</span>")
return BRUTELOSS
/obj/item/clothing/glasses/examine(mob/user)
. = ..()
if(glass_colour_type && ishuman(user))
. += "<span class='notice'>Alt-click to toggle its colors.</span>"
/obj/item/clothing/glasses/visor_toggling()
..()
if(visor_vars_to_toggle & VISOR_VISIONFLAGS)
vision_flags ^= initial(vision_flags)
if(visor_vars_to_toggle & VISOR_DARKNESSVIEW)
darkness_view ^= initial(darkness_view)
if(visor_vars_to_toggle & VISOR_INVISVIEW)
invis_view ^= initial(invis_view)
/obj/item/clothing/glasses/weldingvisortoggle(mob/user)
. = ..()
if(. && user)
user.update_sight()
//called when thermal glasses are emped.
/obj/item/clothing/glasses/proc/thermal_overload()
if(ishuman(src.loc))
var/mob/living/carbon/human/H = src.loc
if(!(HAS_TRAIT(H, TRAIT_BLIND)))
if(H.glasses == src)
to_chat(H, "<span class='danger'>[src] overloads and blinds you!</span>")
H.flash_act(visual = 1)
H.blind_eyes(3)
H.blur_eyes(5)
H.adjust_eye_damage(5)
/obj/item/clothing/glasses/meson
name = "optical meson scanner"
desc = "Used by engineering and mining staff to see basic structural and terrain layouts through walls, regardless of lighting conditions."
icon_state = "meson"
item_state = "meson"
darkness_view = 2
vision_flags = SEE_TURFS
lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE
glass_colour_type = /datum/client_colour/glass_colour/lightgreen
/obj/item/clothing/glasses/meson/suicide_act(mob/living/carbon/user)
user.visible_message("<span class='suicide'>[user] is putting \the [src] to [user.p_their()] eyes and overloading the brightness! It looks like [user.p_theyre()] trying to commit suicide!</span>")
return BRUTELOSS
/obj/item/clothing/glasses/meson/prescription
name = "prescription optical meson scanner"
desc = "Used by engineering and mining staff to see basic structural and terrain layouts through walls, regardless of lighting conditions. This one has prescription lens fitted in."
vision_correction = 1
/obj/item/clothing/glasses/meson/night
name = "night vision meson scanner"
desc = "An optical meson scanner fitted with an amplified visible light spectrum overlay, providing greater visual clarity in darkness."
icon_state = "nvgmeson"
item_state = "nvgmeson"
darkness_view = 8
lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE
glass_colour_type = /datum/client_colour/glass_colour/green
/obj/item/clothing/glasses/meson/gar
name = "gar mesons"
icon_state = "garm"
item_state = "garm"
desc = "Do the impossible, see the invisible!"
force = 10
throwforce = 10
throw_speed = 4
attack_verb = list("sliced")
hitsound = 'sound/weapons/bladeslice.ogg'
sharpness = IS_SHARP
/obj/item/clothing/glasses/science
name = "science goggles"
desc = "A pair of snazzy goggles used to protect against chemical spills. Fitted with an analyzer for scanning items and reagents."
icon_state = "purple"
item_state = "glasses"
clothing_flags = SCAN_REAGENTS //You can see reagents while wearing science goggles
actions_types = list(/datum/action/item_action/toggle_research_scanner)
glass_colour_type = /datum/client_colour/glass_colour/purple
resistance_flags = ACID_PROOF
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 100)
/obj/item/clothing/glasses/science/item_action_slot_check(slot)
if(slot == SLOT_GLASSES)
return 1
/obj/item/clothing/glasses/night
name = "night vision goggles"
desc = "You can totally see in the dark now!"
icon_state = "night"
item_state = "glasses"
darkness_view = 8
lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE
glass_colour_type = /datum/client_colour/glass_colour/green
/obj/item/clothing/glasses/night/prescription
name = "prescription night vision goggles"
desc = "NVGs but for those with nearsightedness."
vision_correction = 1
/obj/item/clothing/glasses/science/suicide_act(mob/living/carbon/user)
user.visible_message("<span class='suicide'>[user] is tightening \the [src]'s straps around [user.p_their()] neck! It looks like [user.p_theyre()] trying to commit suicide!</span>")
return OXYLOSS
/obj/item/clothing/glasses/eyepatch
name = "eyepatch"
desc = "Yarr."
icon_state = "eyepatch"
item_state = "eyepatch"
/obj/item/clothing/glasses/monocle
name = "monocle"
desc = "Such a dapper eyepiece!"
icon_state = "monocle"
item_state = "headset" // lol
/obj/item/clothing/glasses/material
name = "optical material scanner"
desc = "Very confusing glasses."
icon_state = "material"
item_state = "glasses"
vision_flags = SEE_OBJS
glass_colour_type = /datum/client_colour/glass_colour/lightblue
/obj/item/clothing/glasses/material/mining
name = "optical material scanner"
desc = "Used by miners to detect ores deep within the rock."
icon_state = "material"
item_state = "glasses"
darkness_view = 0
/obj/item/clothing/glasses/material/mining/gar
name = "gar material scanner"
icon_state = "garm"
item_state = "garm"
desc = "Do the impossible, see the invisible!"
force = 10
throwforce = 20
throw_speed = 4
attack_verb = list("sliced")
hitsound = 'sound/weapons/bladeslice.ogg'
sharpness = IS_SHARP
vision_correction = 1
glass_colour_type = /datum/client_colour/glass_colour/lightgreen
/obj/item/clothing/glasses/regular
name = "prescription glasses"
desc = "Made by Nerd. Co."
icon_state = "glasses"
item_state = "glasses"
vision_correction = 1 //corrects nearsightedness
/obj/item/clothing/glasses/regular/jamjar
name = "jamjar glasses"
desc = "Also known as Virginity Protectors."
icon_state = "jamjar_glasses"
item_state = "jamjar_glasses"
/obj/item/clothing/glasses/regular/hipster
name = "prescription glasses"
desc = "Made by Uncool. Co."
icon_state = "hipster_glasses"
item_state = "hipster_glasses"
//Here lies green glasses, so ugly they died. RIP
/obj/item/clothing/glasses/sunglasses
name = "sunglasses"
desc = "Strangely ancient technology used to help provide rudimentary eye cover. Enhanced shielding blocks flashes."
icon_state = "sun"
item_state = "sunglasses"
darkness_view = 1
flash_protect = 1
tint = 1
glass_colour_type = /datum/client_colour/glass_colour/gray
dog_fashion = /datum/dog_fashion/head
/obj/item/clothing/glasses/sunglasses/reagent
name = "beer goggles"
desc = "A pair of sunglasses outfitted with apparatus to scan reagents."
clothing_flags = SCAN_REAGENTS
/obj/item/clothing/glasses/sunglasses/garb
name = "black gar glasses"
desc = "Go beyond impossible and kick reason to the curb!"
icon_state = "garb"
item_state = "garb"
force = 10
throwforce = 10
throw_speed = 4
attack_verb = list("sliced")
hitsound = 'sound/weapons/bladeslice.ogg'
sharpness = IS_SHARP
/obj/item/clothing/glasses/sunglasses/garb/supergarb
name = "black giga gar glasses"
desc = "Believe in us humans."
icon_state = "supergarb"
item_state = "garb"
force = 12
throwforce = 12
/obj/item/clothing/glasses/garb
name = "plain black gar glasses"
desc = "Go beyond impossible and kick reason to the curb! Doesn't seem to have flash protection and doesn't seem sharp either."
icon_state = "garb"
item_state = "garb"
/obj/item/clothing/glasses/garb/supergarb
name = "plain black giga gar glasses"
desc = "Believe in us humans. Also doesn't seem to have flash protection and doesn't seem sharp either."
icon_state = "supergarb"
/obj/item/clothing/glasses/sunglasses/gar
name = "gar glasses"
desc = "Just who the hell do you think I am?!"
icon_state = "gar"
item_state = "gar"
force = 10
throwforce = 10
throw_speed = 4
attack_verb = list("sliced")
hitsound = 'sound/weapons/bladeslice.ogg'
sharpness = IS_SHARP
glass_colour_type = /datum/client_colour/glass_colour/orange
/obj/item/clothing/glasses/sunglasses/gar/supergar
name = "giga gar glasses"
desc = "We evolve past the person we were a minute before. Little by little we advance with each turn. That's how a drill works!"
icon_state = "supergar"
item_state = "gar"
force = 12
throwforce = 12
glass_colour_type = /datum/client_colour/glass_colour/red
/obj/item/clothing/glasses/welding
name = "welding goggles"
desc = "Protects the eyes from welders; approved by the mad scientist association."
icon_state = "welding-g"
item_state = "welding-g"
actions_types = list(/datum/action/item_action/toggle)
materials = list(MAT_METAL = 250)
flash_protect = 2
tint = 2
visor_vars_to_toggle = VISOR_FLASHPROTECT | VISOR_TINT
flags_cover = GLASSESCOVERSEYES
visor_flags_inv = HIDEEYES
glass_colour_type = /datum/client_colour/glass_colour/gray
/obj/item/clothing/glasses/welding/attack_self(mob/user)
weldingvisortoggle(user)
/obj/item/clothing/glasses/sunglasses/blindfold
name = "blindfold"
desc = "Covers the eyes, preventing sight."
icon_state = "blindfold"
item_state = "blindfold"
flash_protect = 2
tint = 3 // to make them blind
/obj/item/clothing/glasses/sunglasses/blindfold/equipped(mob/living/carbon/human/user, slot)
. = ..()
if(slot == SLOT_GLASSES)
user.become_blind("blindfold_[REF(src)]")
/obj/item/clothing/glasses/sunglasses/blindfold/dropped(mob/living/carbon/human/user)
..()
user.cure_blind("blindfold_[REF(src)]")
/obj/item/clothing/glasses/sunglasses/big
desc = "Strangely ancient technology used to help provide rudimentary eye cover. Larger than average enhanced shielding blocks flashes."
icon_state = "bigsunglasses"
item_state = "bigsunglasses"
/obj/item/clothing/glasses/thermal
name = "optical thermal scanner"
desc = "Thermals in the shape of glasses."
icon_state = "thermal"
item_state = "glasses"
vision_flags = SEE_MOBS
lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE
flash_protect = 0
glass_colour_type = /datum/client_colour/glass_colour/red
/obj/item/clothing/glasses/thermal/emp_act(severity)
. = ..()
if(. & EMP_PROTECT_SELF)
return
thermal_overload()
/obj/item/clothing/glasses/thermal/syndi //These are now a traitor item, concealed as mesons. -Pete
name = "chameleon thermals"
desc = "A pair of thermal optic goggles with an onboard chameleon generator."
flash_protect = -1
var/datum/action/item_action/chameleon/change/chameleon_action
/obj/item/clothing/glasses/thermal/syndi/New()
..()
chameleon_action = new(src)
chameleon_action.chameleon_type = /obj/item/clothing/glasses
chameleon_action.chameleon_name = "Glasses"
chameleon_action.chameleon_blacklist = typecacheof(/obj/item/clothing/glasses/changeling, only_root_path = TRUE)
chameleon_action.initialize_disguises()
/obj/item/clothing/glasses/thermal/syndi/emp_act(severity)
. = ..()
if(. & EMP_PROTECT_SELF)
return
chameleon_action.emp_randomise()
/obj/item/clothing/glasses/thermal/monocle
name = "thermoncle"
desc = "Never before has seeing through walls felt so gentlepersonly."
icon_state = "thermoncle"
flags_1 = null //doesn't protect eyes because it's a monocle, duh
/obj/item/clothing/glasses/thermal/monocle/examine(mob/user) //Different examiners see a different description!
var/desk = desc
if(user.gender == MALE)
desc = replacetext(desc, "person", "man")
else if(user.gender == FEMALE)
desc = replacetext(desc, "person", "woman")
. = ..()
desc = desk
/obj/item/clothing/glasses/thermal/eyepatch
name = "optical thermal eyepatch"
desc = "An eyepatch with built-in thermal optics."
icon_state = "eyepatch"
item_state = "eyepatch"
/obj/item/clothing/glasses/cold
name = "cold goggles"
desc = "A pair of goggles meant for low temperatures."
icon_state = "cold"
item_state = "cold"
/obj/item/clothing/glasses/heat
name = "heat goggles"
desc = "A pair of goggles meant for high temperatures."
icon_state = "heat"
item_state = "heat"
/obj/item/clothing/glasses/orange
name = "orange glasses"
desc = "A sweet pair of orange shades."
icon_state = "orangeglasses"
item_state = "orangeglasses"
glass_colour_type = /datum/client_colour/glass_colour/lightorange
/obj/item/clothing/glasses/red
name = "red glasses"
desc = "Hey, you're looking good, senpai!"
icon_state = "redglasses"
item_state = "redglasses"
glass_colour_type = /datum/client_colour/glass_colour/red
/obj/item/clothing/glasses/godeye
name = "eye of god"
desc = "A strange eye, said to have been torn from an omniscient creature that used to roam the wastes."
icon_state = "godeye"
item_state = "godeye"
vision_flags = SEE_TURFS|SEE_MOBS|SEE_OBJS
darkness_view = 8
clothing_flags = SCAN_REAGENTS
lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE
resistance_flags = LAVA_PROOF | FIRE_PROOF
/obj/item/clothing/glasses/godeye/Initialize()
. = ..()
ADD_TRAIT(src, TRAIT_NODROP, EYE_OF_GOD_TRAIT)
/obj/item/clothing/glasses/godeye/attackby(obj/item/W as obj, mob/user as mob, params)
if(istype(W, src) && W != src && W.loc == user)
if(W.icon_state == "godeye")
W.icon_state = "doublegodeye"
W.item_state = "doublegodeye"
W.desc = "A pair of strange eyes, said to have been torn from an omniscient creature that used to roam the wastes. There's no real reason to have two, but that isn't stopping you."
if(iscarbon(user))
var/mob/living/carbon/C = user
C.update_inv_wear_mask()
else
to_chat(user, "<span class='notice'>The eye winks at you and vanishes into the abyss, you feel really unlucky.</span>")
qdel(src)
..()
/obj/item/clothing/glasses/AltClick(mob/user)
if(glass_colour_type && ishuman(user))
var/mob/living/carbon/human/H = user
if(H.client)
if(H.client.prefs)
if(src == H.glasses)
H.client.prefs.uses_glasses_colour = !H.client.prefs.uses_glasses_colour
if(H.client.prefs.uses_glasses_colour)
to_chat(H, "You will now see glasses colors.")
else
to_chat(H, "You will no longer see glasses colors.")
H.update_glasses_color(src, 1)
else
return ..()
/obj/item/clothing/glasses/proc/change_glass_color(mob/living/carbon/human/H, datum/client_colour/glass_colour/new_color_type)
var/old_colour_type = glass_colour_type
if(!new_color_type || ispath(new_color_type)) //the new glass colour type must be null or a path.
glass_colour_type = new_color_type
if(H && H.glasses == src)
if(old_colour_type)
H.remove_client_colour(old_colour_type)
if(glass_colour_type)
H.update_glasses_color(src, 1)
/mob/living/carbon/human/proc/update_glasses_color(obj/item/clothing/glasses/G, glasses_equipped)
if(client && client.prefs.uses_glasses_colour && glasses_equipped)
add_client_colour(G.glass_colour_type)
else
remove_client_colour(G.glass_colour_type)
//Glasses
/obj/item/clothing/glasses
name = "glasses"
icon = 'icons/obj/clothing/glasses.dmi'
w_class = WEIGHT_CLASS_SMALL
flags_cover = GLASSESCOVERSEYES
slot_flags = ITEM_SLOT_EYES
strip_delay = 20
equip_delay_other = 25
resistance_flags = NONE
materials = list(MAT_GLASS = 250)
var/vision_flags = 0
var/darkness_view = 2//Base human is 2
var/invis_view = SEE_INVISIBLE_LIVING //admin only for now
var/invis_override = 0 //Override to allow glasses to set higher than normal see_invis
var/lighting_alpha
var/list/icon/current = list() //the current hud icons
var/vision_correction = 0 //does wearing these glasses correct some of our vision defects?
var/glass_colour_type //colors your vision when worn
/obj/item/clothing/glasses/suicide_act(mob/living/carbon/user)
user.visible_message("<span class='suicide'>[user] is stabbing \the [src] into [user.p_their()] eyes! It looks like [user.p_theyre()] trying to commit suicide!</span>")
return BRUTELOSS
/obj/item/clothing/glasses/examine(mob/user)
. = ..()
if(glass_colour_type && ishuman(user))
. += "<span class='notice'>Alt-click to toggle its colors.</span>"
/obj/item/clothing/glasses/visor_toggling()
..()
if(visor_vars_to_toggle & VISOR_VISIONFLAGS)
vision_flags ^= initial(vision_flags)
if(visor_vars_to_toggle & VISOR_DARKNESSVIEW)
darkness_view ^= initial(darkness_view)
if(visor_vars_to_toggle & VISOR_INVISVIEW)
invis_view ^= initial(invis_view)
/obj/item/clothing/glasses/weldingvisortoggle(mob/user)
. = ..()
if(. && user)
user.update_sight()
//called when thermal glasses are emped.
/obj/item/clothing/glasses/proc/thermal_overload()
if(ishuman(src.loc))
var/mob/living/carbon/human/H = src.loc
if(!(HAS_TRAIT(H, TRAIT_BLIND)))
if(H.glasses == src)
to_chat(H, "<span class='danger'>[src] overloads and blinds you!</span>")
H.flash_act(visual = 1)
H.blind_eyes(3)
H.blur_eyes(5)
H.adjust_eye_damage(5)
/obj/item/clothing/glasses/meson
name = "optical meson scanner"
desc = "Used by engineering and mining staff to see basic structural and terrain layouts through walls, regardless of lighting conditions."
icon_state = "meson"
item_state = "meson"
darkness_view = 2
vision_flags = SEE_TURFS
lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE
glass_colour_type = /datum/client_colour/glass_colour/lightgreen
/obj/item/clothing/glasses/meson/suicide_act(mob/living/carbon/user)
user.visible_message("<span class='suicide'>[user] is putting \the [src] to [user.p_their()] eyes and overloading the brightness! It looks like [user.p_theyre()] trying to commit suicide!</span>")
return BRUTELOSS
/obj/item/clothing/glasses/meson/prescription
name = "prescription optical meson scanner"
desc = "Used by engineering and mining staff to see basic structural and terrain layouts through walls, regardless of lighting conditions. This one has prescription lens fitted in."
vision_correction = 1
/obj/item/clothing/glasses/meson/night
name = "night vision meson scanner"
desc = "An optical meson scanner fitted with an amplified visible light spectrum overlay, providing greater visual clarity in darkness."
icon_state = "nvgmeson"
item_state = "nvgmeson"
darkness_view = 8
lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE
glass_colour_type = /datum/client_colour/glass_colour/green
/obj/item/clothing/glasses/meson/gar
name = "gar mesons"
icon_state = "garm"
item_state = "garm"
desc = "Do the impossible, see the invisible!"
force = 10
throwforce = 10
throw_speed = 4
attack_verb = list("sliced")
hitsound = 'sound/weapons/bladeslice.ogg'
sharpness = IS_SHARP
/obj/item/clothing/glasses/science
name = "science goggles"
desc = "A pair of snazzy goggles used to protect against chemical spills. Fitted with an analyzer for scanning items and reagents."
icon_state = "purple"
item_state = "glasses"
clothing_flags = SCAN_REAGENTS //You can see reagents while wearing science goggles
actions_types = list(/datum/action/item_action/toggle_research_scanner)
glass_colour_type = /datum/client_colour/glass_colour/purple
resistance_flags = ACID_PROOF
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 100)
/obj/item/clothing/glasses/science/item_action_slot_check(slot)
if(slot == SLOT_GLASSES)
return 1
/obj/item/clothing/glasses/night
name = "night vision goggles"
desc = "You can totally see in the dark now!"
icon_state = "night"
item_state = "glasses"
darkness_view = 8
lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE
glass_colour_type = /datum/client_colour/glass_colour/green
/obj/item/clothing/glasses/night/prescription
name = "prescription night vision goggles"
desc = "NVGs but for those with nearsightedness."
vision_correction = 1
/obj/item/clothing/glasses/science/suicide_act(mob/living/carbon/user)
user.visible_message("<span class='suicide'>[user] is tightening \the [src]'s straps around [user.p_their()] neck! It looks like [user.p_theyre()] trying to commit suicide!</span>")
return OXYLOSS
/obj/item/clothing/glasses/eyepatch
name = "eyepatch"
desc = "Yarr."
icon_state = "eyepatch"
item_state = "eyepatch"
/obj/item/clothing/glasses/monocle
name = "monocle"
desc = "Such a dapper eyepiece!"
icon_state = "monocle"
item_state = "headset" // lol
/obj/item/clothing/glasses/material
name = "optical material scanner"
desc = "Very confusing glasses."
icon_state = "material"
item_state = "glasses"
vision_flags = SEE_OBJS
glass_colour_type = /datum/client_colour/glass_colour/lightblue
/obj/item/clothing/glasses/material/mining
name = "optical material scanner"
desc = "Used by miners to detect ores deep within the rock."
icon_state = "material"
item_state = "glasses"
darkness_view = 0
/obj/item/clothing/glasses/material/mining/gar
name = "gar material scanner"
icon_state = "garm"
item_state = "garm"
desc = "Do the impossible, see the invisible!"
force = 10
throwforce = 20
throw_speed = 4
attack_verb = list("sliced")
hitsound = 'sound/weapons/bladeslice.ogg'
sharpness = IS_SHARP
vision_correction = 1
glass_colour_type = /datum/client_colour/glass_colour/lightgreen
/obj/item/clothing/glasses/regular
name = "prescription glasses"
desc = "Made by Nerd. Co."
icon_state = "glasses"
item_state = "glasses"
vision_correction = 1 //corrects nearsightedness
/obj/item/clothing/glasses/regular/jamjar
name = "jamjar glasses"
desc = "Also known as Virginity Protectors."
icon_state = "jamjar_glasses"
item_state = "jamjar_glasses"
/obj/item/clothing/glasses/regular/hipster
name = "prescription glasses"
desc = "Made by Uncool. Co."
icon_state = "hipster_glasses"
item_state = "hipster_glasses"
//Here lies green glasses, so ugly they died. RIP
/obj/item/clothing/glasses/sunglasses
name = "sunglasses"
desc = "Strangely ancient technology used to help provide rudimentary eye cover. Enhanced shielding blocks flashes."
icon_state = "sun"
item_state = "sunglasses"
darkness_view = 1
flash_protect = 1
tint = 1
glass_colour_type = /datum/client_colour/glass_colour/gray
dog_fashion = /datum/dog_fashion/head
/obj/item/clothing/glasses/sunglasses/reagent
name = "beer goggles"
desc = "A pair of sunglasses outfitted with apparatus to scan reagents."
clothing_flags = SCAN_REAGENTS
/obj/item/clothing/glasses/sunglasses/garb
name = "black gar glasses"
desc = "Go beyond impossible and kick reason to the curb!"
icon_state = "garb"
item_state = "garb"
force = 10
throwforce = 10
throw_speed = 4
attack_verb = list("sliced")
hitsound = 'sound/weapons/bladeslice.ogg'
sharpness = IS_SHARP
/obj/item/clothing/glasses/sunglasses/garb/supergarb
name = "black giga gar glasses"
desc = "Believe in us humans."
icon_state = "supergarb"
item_state = "garb"
force = 12
throwforce = 12
/obj/item/clothing/glasses/garb
name = "plain black gar glasses"
desc = "Go beyond impossible and kick reason to the curb! Doesn't seem to have flash protection and doesn't seem sharp either."
icon_state = "garb"
item_state = "garb"
/obj/item/clothing/glasses/garb/supergarb
name = "plain black giga gar glasses"
desc = "Believe in us humans. Also doesn't seem to have flash protection and doesn't seem sharp either."
icon_state = "supergarb"
/obj/item/clothing/glasses/sunglasses/gar
name = "gar glasses"
desc = "Just who the hell do you think I am?!"
icon_state = "gar"
item_state = "gar"
force = 10
throwforce = 10
throw_speed = 4
attack_verb = list("sliced")
hitsound = 'sound/weapons/bladeslice.ogg'
sharpness = IS_SHARP
glass_colour_type = /datum/client_colour/glass_colour/orange
/obj/item/clothing/glasses/sunglasses/gar/supergar
name = "giga gar glasses"
desc = "We evolve past the person we were a minute before. Little by little we advance with each turn. That's how a drill works!"
icon_state = "supergar"
item_state = "gar"
force = 12
throwforce = 12
glass_colour_type = /datum/client_colour/glass_colour/red
/obj/item/clothing/glasses/welding
name = "welding goggles"
desc = "Protects the eyes from welders; approved by the mad scientist association."
icon_state = "welding-g"
item_state = "welding-g"
actions_types = list(/datum/action/item_action/toggle)
materials = list(MAT_METAL = 250)
flash_protect = 2
tint = 2
visor_vars_to_toggle = VISOR_FLASHPROTECT | VISOR_TINT
flags_cover = GLASSESCOVERSEYES
visor_flags_inv = HIDEEYES
glass_colour_type = /datum/client_colour/glass_colour/gray
/obj/item/clothing/glasses/welding/attack_self(mob/user)
weldingvisortoggle(user)
/obj/item/clothing/glasses/sunglasses/blindfold
name = "blindfold"
desc = "Covers the eyes, preventing sight."
icon_state = "blindfold"
item_state = "blindfold"
flash_protect = 2
tint = 3 // to make them blind
/obj/item/clothing/glasses/sunglasses/blindfold/equipped(mob/living/carbon/human/user, slot)
. = ..()
if(slot == SLOT_GLASSES)
user.become_blind("blindfold_[REF(src)]")
/obj/item/clothing/glasses/sunglasses/blindfold/dropped(mob/living/carbon/human/user)
..()
user.cure_blind("blindfold_[REF(src)]")
/obj/item/clothing/glasses/sunglasses/big
desc = "Strangely ancient technology used to help provide rudimentary eye cover. Larger than average enhanced shielding blocks flashes."
icon_state = "bigsunglasses"
item_state = "bigsunglasses"
/obj/item/clothing/glasses/thermal
name = "optical thermal scanner"
desc = "Thermals in the shape of glasses."
icon_state = "thermal"
item_state = "glasses"
vision_flags = SEE_MOBS
lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE
flash_protect = 0
glass_colour_type = /datum/client_colour/glass_colour/red
/obj/item/clothing/glasses/thermal/emp_act(severity)
. = ..()
if(. & EMP_PROTECT_SELF)
return
thermal_overload()
/obj/item/clothing/glasses/thermal/syndi //These are now a traitor item, concealed as mesons. -Pete
name = "chameleon thermals"
desc = "A pair of thermal optic goggles with an onboard chameleon generator."
flash_protect = -1
var/datum/action/item_action/chameleon/change/chameleon_action
/obj/item/clothing/glasses/thermal/syndi/New()
..()
chameleon_action = new(src)
chameleon_action.chameleon_type = /obj/item/clothing/glasses
chameleon_action.chameleon_name = "Glasses"
chameleon_action.chameleon_blacklist = typecacheof(/obj/item/clothing/glasses/changeling, only_root_path = TRUE)
chameleon_action.initialize_disguises()
/obj/item/clothing/glasses/thermal/syndi/emp_act(severity)
. = ..()
if(. & EMP_PROTECT_SELF)
return
chameleon_action.emp_randomise()
/obj/item/clothing/glasses/thermal/monocle
name = "thermoncle"
desc = "Never before has seeing through walls felt so gentlepersonly."
icon_state = "thermoncle"
flags_1 = null //doesn't protect eyes because it's a monocle, duh
/obj/item/clothing/glasses/thermal/monocle/examine(mob/user) //Different examiners see a different description!
var/desk = desc
if(user.gender == MALE)
desc = replacetext(desc, "person", "man")
else if(user.gender == FEMALE)
desc = replacetext(desc, "person", "woman")
. = ..()
desc = desk
/obj/item/clothing/glasses/thermal/eyepatch
name = "optical thermal eyepatch"
desc = "An eyepatch with built-in thermal optics."
icon_state = "eyepatch"
item_state = "eyepatch"
/obj/item/clothing/glasses/cold
name = "cold goggles"
desc = "A pair of goggles meant for low temperatures."
icon_state = "cold"
item_state = "cold"
/obj/item/clothing/glasses/heat
name = "heat goggles"
desc = "A pair of goggles meant for high temperatures."
icon_state = "heat"
item_state = "heat"
/obj/item/clothing/glasses/orange
name = "orange glasses"
desc = "A sweet pair of orange shades."
icon_state = "orangeglasses"
item_state = "orangeglasses"
glass_colour_type = /datum/client_colour/glass_colour/lightorange
/obj/item/clothing/glasses/red
name = "red glasses"
desc = "Hey, you're looking good, senpai!"
icon_state = "redglasses"
item_state = "redglasses"
glass_colour_type = /datum/client_colour/glass_colour/red
/obj/item/clothing/glasses/godeye
name = "eye of god"
desc = "A strange eye, said to have been torn from an omniscient creature that used to roam the wastes."
icon_state = "godeye"
item_state = "godeye"
vision_flags = SEE_TURFS|SEE_MOBS|SEE_OBJS
darkness_view = 8
clothing_flags = SCAN_REAGENTS
lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE
resistance_flags = LAVA_PROOF | FIRE_PROOF
/obj/item/clothing/glasses/godeye/Initialize()
. = ..()
ADD_TRAIT(src, TRAIT_NODROP, EYE_OF_GOD_TRAIT)
/obj/item/clothing/glasses/godeye/attackby(obj/item/W as obj, mob/user as mob, params)
if(istype(W, src) && W != src && W.loc == user)
if(W.icon_state == "godeye")
W.icon_state = "doublegodeye"
W.item_state = "doublegodeye"
W.desc = "A pair of strange eyes, said to have been torn from an omniscient creature that used to roam the wastes. There's no real reason to have two, but that isn't stopping you."
if(iscarbon(user))
var/mob/living/carbon/C = user
C.update_inv_wear_mask()
else
to_chat(user, "<span class='notice'>The eye winks at you and vanishes into the abyss, you feel really unlucky.</span>")
qdel(src)
..()
/obj/item/clothing/glasses/AltClick(mob/user)
. = ..()
if(glass_colour_type && ishuman(user))
var/mob/living/carbon/human/H = user
if(H.client?.prefs && src == H.glasses)
H.client.prefs.uses_glasses_colour = !H.client.prefs.uses_glasses_colour
if(H.client.prefs.uses_glasses_colour)
to_chat(H, "You will now see glasses colors.")
else
to_chat(H, "You will no longer see glasses colors.")
H.update_glasses_color(src, 1)
return TRUE
/obj/item/clothing/glasses/proc/change_glass_color(mob/living/carbon/human/H, datum/client_colour/glass_colour/new_color_type)
var/old_colour_type = glass_colour_type
if(!new_color_type || ispath(new_color_type)) //the new glass colour type must be null or a path.
glass_colour_type = new_color_type
if(H && H.glasses == src)
if(old_colour_type)
H.remove_client_colour(old_colour_type)
if(glass_colour_type)
H.update_glasses_color(src, 1)
/mob/living/carbon/human/proc/update_glasses_color(obj/item/clothing/glasses/G, glasses_equipped)
if(client && client.prefs.uses_glasses_colour && glasses_equipped)
add_client_colour(G.glass_colour_type)
else
remove_client_colour(G.glass_colour_type)
+160 -158
View File
@@ -1,159 +1,161 @@
/obj/item/clothing/head/hardhat
name = "hard hat"
desc = "A piece of headgear used in dangerous working conditions to protect the head. Comes with a built-in flashlight."
icon_state = "hardhat0_yellow"
item_state = "hardhat0_yellow"
var/brightness_on = 4 //luminosity when on
light_color = "#FFCC66"
var/power_on = 0.8
var/on = FALSE
item_color = "yellow" //Determines used sprites: hardhat[on]_[item_color] and hardhat[on]_[item_color]2 (lying down sprite)
armor = list("melee" = 15, "bullet" = 5, "laser" = 20,"energy" = 10, "bomb" = 20, "bio" = 10, "rad" = 20, "fire" = 100, "acid" = 50)
flags_inv = 0
actions_types = list(/datum/action/item_action/toggle_helmet_light)
resistance_flags = FIRE_PROOF
dynamic_hair_suffix = "+generic"
dog_fashion = /datum/dog_fashion/head
/obj/item/clothing/head/hardhat/attack_self(mob/living/user)
toggle_helmet_light(user)
/obj/item/clothing/head/hardhat/proc/toggle_helmet_light(mob/living/user)
on = !on
if(on)
turn_on(user)
else
turn_off(user)
update_icon()
/obj/item/clothing/head/hardhat/update_icon()
icon_state = "hardhat[on]_[item_color]"
item_state = "hardhat[on]_[item_color]"
if(ishuman(loc))
var/mob/living/carbon/human/H = loc
H.update_inv_head()
for(var/X in actions)
var/datum/action/A = X
A.UpdateButtonIcon(force = TRUE)
/obj/item/clothing/head/hardhat/proc/turn_on(mob/user)
set_light(brightness_on, power_on)
/obj/item/clothing/head/hardhat/proc/turn_off(mob/user)
set_light(0)
/obj/item/clothing/head/hardhat/orange
icon_state = "hardhat0_orange"
item_state = "hardhat0_orange"
item_color = "orange"
dog_fashion = null
/obj/item/clothing/head/hardhat/red
icon_state = "hardhat0_red"
item_state = "hardhat0_red"
item_color = "red"
dog_fashion = null
name = "firefighter helmet"
clothing_flags = STOPSPRESSUREDAMAGE
heat_protection = HEAD
max_heat_protection_temperature = FIRE_HELM_MAX_TEMP_PROTECT
cold_protection = HEAD
min_cold_protection_temperature = FIRE_HELM_MIN_TEMP_PROTECT
/obj/item/clothing/head/hardhat/white
icon_state = "hardhat0_white"
item_state = "hardhat0_white"
item_color = "white"
clothing_flags = STOPSPRESSUREDAMAGE
heat_protection = HEAD
max_heat_protection_temperature = FIRE_HELM_MAX_TEMP_PROTECT
cold_protection = HEAD
min_cold_protection_temperature = FIRE_HELM_MIN_TEMP_PROTECT
dog_fashion = /datum/dog_fashion/head
/obj/item/clothing/head/hardhat/dblue
icon_state = "hardhat0_dblue"
item_state = "hardhat0_dblue"
item_color = "dblue"
dog_fashion = null
/obj/item/clothing/head/hardhat/atmos
icon_state = "hardhat0_atmos"
item_state = "hardhat0_atmos"
item_color = "atmos"
dog_fashion = null
name = "atmospheric technician's firefighting helmet"
desc = "A firefighter's helmet, able to keep the user cool in any situation."
clothing_flags = STOPSPRESSUREDAMAGE | THICKMATERIAL | BLOCK_GAS_SMOKE_EFFECT
flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDEFACIALHAIR|HIDESNOUT
heat_protection = HEAD
max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT
cold_protection = HEAD
min_cold_protection_temperature = FIRE_HELM_MIN_TEMP_PROTECT
mutantrace_variation = MUTANTRACE_VARIATION
/obj/item/clothing/head/hardhat/weldhat
name = "welding hard hat"
desc = "A piece of headgear used in dangerous working conditions to protect the head. Comes with a built-in flashlight AND welding shield! The bulb seems a little smaller though."
brightness_on = 3 //Needs a little bit of tradeoff
dog_fashion = null
actions_types = list(/datum/action/item_action/toggle_helmet_light, /datum/action/item_action/toggle_welding_screen)
flash_protect = 2
tint = 2
flags_inv = HIDEEYES | HIDEFACE
flags_cover = HEADCOVERSEYES | HEADCOVERSMOUTH
visor_vars_to_toggle = VISOR_FLASHPROTECT | VISOR_TINT
visor_flags_inv = HIDEEYES | HIDEFACE
visor_flags_cover = HEADCOVERSEYES | HEADCOVERSMOUTH
/obj/item/clothing/head/hardhat/weldhat/Initialize()
. = ..()
update_icon()
/obj/item/clothing/head/hardhat/weldhat/attack_self(mob/living/user)
toggle_helmet_light(user)
/obj/item/clothing/head/hardhat/weldhat/AltClick(mob/user)
if(user.canUseTopic(src, BE_CLOSE))
toggle_welding_screen(user)
/obj/item/clothing/head/hardhat/weldhat/proc/toggle_welding_screen(mob/living/user)
if(weldingvisortoggle(user))
playsound(src, 'sound/mecha/mechmove03.ogg', 30, TRUE) //Visors don't just come from nothing
update_icon()
/obj/item/clothing/head/hardhat/weldhat/worn_overlays(isinhands)
. = ..()
if(!isinhands)
. += mutable_appearance('icons/mob/head.dmi', "weldhelmet")
if(!up)
. += mutable_appearance('icons/mob/head.dmi', "weldvisor")
/obj/item/clothing/head/hardhat/weldhat/update_icon()
cut_overlays()
if(!up)
add_overlay("weldvisor")
..()
/obj/item/clothing/head/hardhat/weldhat/orange
icon_state = "hardhat0_orange"
item_state = "hardhat0_orange"
item_color = "orange"
/obj/item/clothing/head/hardhat/weldhat/white
desc = "A piece of headgear used in dangerous working conditions to protect the head. Comes with a built-in flashlight AND welding shield!" //This bulb is not smaller
icon_state = "hardhat0_white"
item_state = "hardhat0_white"
brightness_on = 4 //Boss always takes the best stuff
item_color = "white"
clothing_flags = STOPSPRESSUREDAMAGE
heat_protection = HEAD
max_heat_protection_temperature = FIRE_HELM_MAX_TEMP_PROTECT
cold_protection = HEAD
min_cold_protection_temperature = FIRE_HELM_MIN_TEMP_PROTECT
/obj/item/clothing/head/hardhat/weldhat/dblue
icon_state = "hardhat0_dblue"
item_state = "hardhat0_dblue"
/obj/item/clothing/head/hardhat
name = "hard hat"
desc = "A piece of headgear used in dangerous working conditions to protect the head. Comes with a built-in flashlight."
icon_state = "hardhat0_yellow"
item_state = "hardhat0_yellow"
var/brightness_on = 4 //luminosity when on
light_color = "#FFCC66"
var/power_on = 0.8
var/on = FALSE
item_color = "yellow" //Determines used sprites: hardhat[on]_[item_color] and hardhat[on]_[item_color]2 (lying down sprite)
armor = list("melee" = 15, "bullet" = 5, "laser" = 20,"energy" = 10, "bomb" = 20, "bio" = 10, "rad" = 20, "fire" = 100, "acid" = 50)
flags_inv = 0
actions_types = list(/datum/action/item_action/toggle_helmet_light)
resistance_flags = FIRE_PROOF
dynamic_hair_suffix = "+generic"
dog_fashion = /datum/dog_fashion/head
/obj/item/clothing/head/hardhat/attack_self(mob/living/user)
toggle_helmet_light(user)
/obj/item/clothing/head/hardhat/proc/toggle_helmet_light(mob/living/user)
on = !on
if(on)
turn_on(user)
else
turn_off(user)
update_icon()
/obj/item/clothing/head/hardhat/update_icon()
icon_state = "hardhat[on]_[item_color]"
item_state = "hardhat[on]_[item_color]"
if(ishuman(loc))
var/mob/living/carbon/human/H = loc
H.update_inv_head()
for(var/X in actions)
var/datum/action/A = X
A.UpdateButtonIcon(force = TRUE)
/obj/item/clothing/head/hardhat/proc/turn_on(mob/user)
set_light(brightness_on, power_on)
/obj/item/clothing/head/hardhat/proc/turn_off(mob/user)
set_light(0)
/obj/item/clothing/head/hardhat/orange
icon_state = "hardhat0_orange"
item_state = "hardhat0_orange"
item_color = "orange"
dog_fashion = null
/obj/item/clothing/head/hardhat/red
icon_state = "hardhat0_red"
item_state = "hardhat0_red"
item_color = "red"
dog_fashion = null
name = "firefighter helmet"
clothing_flags = STOPSPRESSUREDAMAGE
heat_protection = HEAD
max_heat_protection_temperature = FIRE_HELM_MAX_TEMP_PROTECT
cold_protection = HEAD
min_cold_protection_temperature = FIRE_HELM_MIN_TEMP_PROTECT
/obj/item/clothing/head/hardhat/white
icon_state = "hardhat0_white"
item_state = "hardhat0_white"
item_color = "white"
clothing_flags = STOPSPRESSUREDAMAGE
heat_protection = HEAD
max_heat_protection_temperature = FIRE_HELM_MAX_TEMP_PROTECT
cold_protection = HEAD
min_cold_protection_temperature = FIRE_HELM_MIN_TEMP_PROTECT
dog_fashion = /datum/dog_fashion/head
/obj/item/clothing/head/hardhat/dblue
icon_state = "hardhat0_dblue"
item_state = "hardhat0_dblue"
item_color = "dblue"
dog_fashion = null
/obj/item/clothing/head/hardhat/atmos
icon_state = "hardhat0_atmos"
item_state = "hardhat0_atmos"
item_color = "atmos"
dog_fashion = null
name = "atmospheric technician's firefighting helmet"
desc = "A firefighter's helmet, able to keep the user cool in any situation."
clothing_flags = STOPSPRESSUREDAMAGE | THICKMATERIAL | BLOCK_GAS_SMOKE_EFFECT
flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDEFACIALHAIR|HIDESNOUT
heat_protection = HEAD
max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT
cold_protection = HEAD
min_cold_protection_temperature = FIRE_HELM_MIN_TEMP_PROTECT
mutantrace_variation = MUTANTRACE_VARIATION
/obj/item/clothing/head/hardhat/weldhat
name = "welding hard hat"
desc = "A piece of headgear used in dangerous working conditions to protect the head. Comes with a built-in flashlight AND welding shield! The bulb seems a little smaller though."
brightness_on = 3 //Needs a little bit of tradeoff
dog_fashion = null
actions_types = list(/datum/action/item_action/toggle_helmet_light, /datum/action/item_action/toggle_welding_screen)
flash_protect = 2
tint = 2
flags_inv = HIDEEYES | HIDEFACE
flags_cover = HEADCOVERSEYES | HEADCOVERSMOUTH
visor_vars_to_toggle = VISOR_FLASHPROTECT | VISOR_TINT
visor_flags_inv = HIDEEYES | HIDEFACE
visor_flags_cover = HEADCOVERSEYES | HEADCOVERSMOUTH
/obj/item/clothing/head/hardhat/weldhat/Initialize()
. = ..()
update_icon()
/obj/item/clothing/head/hardhat/weldhat/attack_self(mob/living/user)
toggle_helmet_light(user)
/obj/item/clothing/head/hardhat/weldhat/AltClick(mob/user)
. = ..()
if(user.canUseTopic(src, BE_CLOSE))
toggle_welding_screen(user)
return TRUE
/obj/item/clothing/head/hardhat/weldhat/proc/toggle_welding_screen(mob/living/user)
if(weldingvisortoggle(user))
playsound(src, 'sound/mecha/mechmove03.ogg', 30, TRUE) //Visors don't just come from nothing
update_icon()
/obj/item/clothing/head/hardhat/weldhat/worn_overlays(isinhands)
. = ..()
if(!isinhands)
. += mutable_appearance('icons/mob/head.dmi', "weldhelmet")
if(!up)
. += mutable_appearance('icons/mob/head.dmi', "weldvisor")
/obj/item/clothing/head/hardhat/weldhat/update_icon()
cut_overlays()
if(!up)
add_overlay("weldvisor")
..()
/obj/item/clothing/head/hardhat/weldhat/orange
icon_state = "hardhat0_orange"
item_state = "hardhat0_orange"
item_color = "orange"
/obj/item/clothing/head/hardhat/weldhat/white
desc = "A piece of headgear used in dangerous working conditions to protect the head. Comes with a built-in flashlight AND welding shield!" //This bulb is not smaller
icon_state = "hardhat0_white"
item_state = "hardhat0_white"
brightness_on = 4 //Boss always takes the best stuff
item_color = "white"
clothing_flags = STOPSPRESSUREDAMAGE
heat_protection = HEAD
max_heat_protection_temperature = FIRE_HELM_MAX_TEMP_PROTECT
cold_protection = HEAD
min_cold_protection_temperature = FIRE_HELM_MIN_TEMP_PROTECT
/obj/item/clothing/head/hardhat/weldhat/dblue
icon_state = "hardhat0_dblue"
item_state = "hardhat0_dblue"
item_color = "dblue"
+297 -297
View File
@@ -1,297 +1,297 @@
//defines the drill hat's yelling setting
#define DRILL_DEFAULT "default"
#define DRILL_SHOUTING "shouting"
#define DRILL_YELLING "yelling"
#define DRILL_CANADIAN "canadian"
//Chef
/obj/item/clothing/head/chefhat
name = "chef's hat"
item_state = "chef"
icon_state = "chef"
desc = "The commander in chef's head wear."
strip_delay = 10
equip_delay_other = 10
dynamic_hair_suffix = ""
dog_fashion = /datum/dog_fashion/head/chef
/obj/item/clothing/head/chefhat/suicide_act(mob/user)
user.visible_message("<span class='suicide'>[user] is donning [src]! It looks like [user.p_theyre()] trying to become a chef.</span>")
user.say("Bork Bork Bork!", forced = "chef hat suicide")
sleep(20)
user.visible_message("<span class='suicide'>[user] climbs into an imaginary oven!</span>")
user.say("BOOORK!", forced = "chef hat suicide")
playsound(user, 'sound/machines/ding.ogg', 50, 1)
return(FIRELOSS)
//Captain
/obj/item/clothing/head/caphat
name = "captain's hat"
desc = "It's good being the king."
icon_state = "captain"
item_state = "that"
flags_inv = 0
armor = list("melee" = 40, "bullet" = 30, "laser" = 30, "energy" = 10, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50)
strip_delay = 60
dog_fashion = /datum/dog_fashion/head/captain
//Captain: This is no longer space-worthy
/obj/item/clothing/head/caphat/parade
name = "captain's parade cap"
desc = "Worn only by Captains with an abundance of class."
icon_state = "capcap"
dog_fashion = null
/obj/item/clothing/head/caphat/beret
name = "captain's beret"
desc = "A beret fit for a leader."
icon_state = "capberet"
dynamic_hair_suffix = ""
dog_fashion = null
//Head of Personnel
/obj/item/clothing/head/hopcap
name = "head of personnel's cap"
icon_state = "hopcap"
desc = "The symbol of true bureaucratic micromanagement."
armor = list("melee" = 30, "bullet" = 25, "laser" = 25, "energy" = 10, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50)
dog_fashion = /datum/dog_fashion/head/hop
/obj/item/clothing/head/hopcap/beret
name = "head of personnel's beret"
desc = "The symbol of true bureaucratic micromanagement, although in a fancy form."
icon_state = "hopberet"
dynamic_hair_suffix = ""
dog_fashion = null
//Chaplain
/obj/item/clothing/head/nun_hood
name = "nun hood"
desc = "Maximum piety in this star system."
icon_state = "nun_hood"
flags_inv = HIDEHAIR
flags_cover = HEADCOVERSEYES
//Detective
/obj/item/clothing/head/fedora/det_hat
name = "detective's fedora"
desc = "There's only one man who can sniff out the dirty stench of crime, and he's likely wearing this hat."
armor = list("melee" = 25, "bullet" = 5, "laser" = 25, "energy" = 10, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 30, "acid" = 50)
icon_state = "detective"
var/candy_cooldown = 0
pocket_storage_component_path = /datum/component/storage/concrete/pockets/small/detective
dog_fashion = /datum/dog_fashion/head/detective
/obj/item/clothing/head/fedora/det_hat/Initialize()
. = ..()
new /obj/item/reagent_containers/food/drinks/flask/det(src)
/obj/item/clothing/head/fedora/det_hat/examine(mob/user)
. = ..()
. += "<span class='notice'>Alt-click to take a candy corn.</span>"
/obj/item/clothing/head/fedora/det_hat/AltClick(mob/user)
if(user.canUseTopic(src, BE_CLOSE, ismonkey(user)))
..()
if(loc == user)
if(candy_cooldown < world.time)
var/obj/item/reagent_containers/food/snacks/candy_corn/CC = new /obj/item/reagent_containers/food/snacks/candy_corn(src)
user.put_in_hands(CC)
to_chat(user, "You slip a candy corn from your hat.")
candy_cooldown = world.time+1200
else
to_chat(user, "You just took a candy corn! You should wait a couple minutes, lest you burn through your stash.")
//Mime
/obj/item/clothing/head/beret
name = "beret"
desc = "A beret, a mime's favorite headwear."
icon_state = "beret"
dog_fashion = /datum/dog_fashion/head/beret
dynamic_hair_suffix = ""
/obj/item/clothing/head/beret/black
name = "black beret"
desc = "A black beret, perfect for war veterans and dark, brooding, anti-hero mimes."
icon_state = "beretblack"
/obj/item/clothing/head/beret/highlander
desc = "That was white fabric. <i>Was.</i>"
dog_fashion = null //THIS IS FOR SLAUGHTER, NOT PUPPIES
/obj/item/clothing/head/beret/highlander/Initialize()
. = ..()
ADD_TRAIT(src, TRAIT_NODROP, HIGHLANDER)
//Security
/obj/item/clothing/head/HoS
name = "head of security cap"
desc = "The robust standard-issue cap of the Head of Security. For showing the officers who's in charge."
icon_state = "hoscap"
armor = list("melee" = 40, "bullet" = 30, "laser" = 25, "energy" = 10, "bomb" = 25, "bio" = 10, "rad" = 0, "fire" = 50, "acid" = 60)
strip_delay = 80
dynamic_hair_suffix = ""
/obj/item/clothing/head/HoS/syndicate
name = "syndicate cap"
desc = "A black cap fit for a high ranking syndicate officer."
/obj/item/clothing/head/HoS/beret
name = "head of security beret"
desc = "A robust beret for the Head of Security, for looking stylish while not sacrificing protection."
icon_state = "hosberetblack"
/obj/item/clothing/head/HoS/beret/syndicate
name = "syndicate beret"
desc = "A black beret with thick armor padding inside. Stylish and robust."
/obj/item/clothing/head/warden
name = "warden's police hat"
desc = "It's a special armored hat issued to the Warden of a security force. Protects the head from impacts."
icon_state = "policehelm"
armor = list("melee" = 40, "bullet" = 30, "laser" = 30, "energy" = 10, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 30, "acid" = 60)
strip_delay = 60
dog_fashion = /datum/dog_fashion/head/warden
/obj/item/clothing/head/warden/drill
name = "warden's campaign hat"
desc = "A special armored campaign hat with the security insignia emblazoned on it. Uses reinforced fabric to offer sufficient protection. Has the letters 'FMJ' enscribed on its side."
icon_state = "wardendrill"
item_state = "wardendrill"
dog_fashion = null
var/mode = DRILL_DEFAULT
/obj/item/clothing/head/warden/drill/screwdriver_act(mob/living/carbon/human/user, obj/item/I)
if(..())
return TRUE
switch(mode)
if(DRILL_DEFAULT)
to_chat(user, "<span class='notice'>You set the voice circuit to the middle position.</span>")
mode = DRILL_SHOUTING
if(DRILL_SHOUTING)
to_chat(user, "<span class='notice'>You set the voice circuit to the last position.</span>")
mode = DRILL_YELLING
if(DRILL_YELLING)
to_chat(user, "<span class='notice'>You set the voice circuit to the first position.</span>")
mode = DRILL_DEFAULT
if(DRILL_CANADIAN)
to_chat(user, "<span class='danger'>You adjust voice circuit but nothing happens, probably because it's broken.</span>")
return TRUE
/obj/item/clothing/head/warden/drill/wirecutter_act(mob/living/user, obj/item/I)
if(mode != DRILL_CANADIAN)
to_chat(user, "<span class='danger'>You broke the voice circuit!</span>")
mode = DRILL_CANADIAN
return TRUE
/obj/item/clothing/head/warden/drill/equipped(mob/M, slot)
. = ..()
if (slot == SLOT_HEAD)
RegisterSignal(M, COMSIG_MOB_SAY, .proc/handle_speech)
else
UnregisterSignal(M, COMSIG_MOB_SAY)
/obj/item/clothing/head/warden/drill/dropped(mob/M)
. = ..()
UnregisterSignal(M, COMSIG_MOB_SAY)
/obj/item/clothing/head/warden/drill/proc/handle_speech(datum/source, mob/speech_args)
var/message = speech_args[SPEECH_MESSAGE]
if(message[1] != "*")
switch (mode)
if(DRILL_SHOUTING)
message += "!"
if(DRILL_YELLING)
message += "!!"
if(DRILL_CANADIAN)
message = " [message]"
var/list/canadian_words = strings("canadian_replacement.json", "canadian")
for(var/key in canadian_words)
var/value = canadian_words[key]
if(islist(value))
value = pick(value)
message = replacetextEx(message, " [uppertext(key)]", " [uppertext(value)]")
message = replacetextEx(message, " [capitalize(key)]", " [capitalize(value)]")
message = replacetextEx(message, " [key]", " [value]")
if(prob(30))
message += pick(", eh?", ", EH?")
speech_args[SPEECH_MESSAGE] = message
/obj/item/clothing/head/beret/sec
name = "security beret"
desc = "A robust beret with the security insignia emblazoned on it. Uses reinforced fabric to offer sufficient protection."
icon_state = "beret_badge"
armor = list("melee" = 40, "bullet" = 30, "laser" = 30,"energy" = 10, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50)
strip_delay = 60
dog_fashion = null
/obj/item/clothing/head/beret/sec/navyhos
name = "head of security's beret"
desc = "A special beret with the Head of Security's insignia emblazoned on it. A symbol of excellence, a badge of courage, a mark of distinction."
icon_state = "hosberet"
/obj/item/clothing/head/beret/sec/navywarden
name = "warden's beret"
desc = "A special beret with the Warden's insignia emblazoned on it. For wardens with class."
icon_state = "wardenberet"
armor = list("melee" = 40, "bullet" = 30, "laser" = 30, "energy" = 10, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50)
strip_delay = 60
/obj/item/clothing/head/beret/sec/navyofficer
desc = "A special beret with the security insignia emblazoned on it. For officers with class."
icon_state = "officerberet"
/obj/item/clothing/head/beret/sec/bitch
name = "security's bitch beret"
desc = "A softer beret with the word 'BITCH' embroidered on it in pink thread."
icon_state = "bitchberet"
//Curator
/obj/item/clothing/head/fedora/curator
name = "treasure hunter's fedora"
desc = "You got red text today kid, but it doesn't mean you have to like it."
icon_state = "curator"
//Chief Medical Officer
/obj/item/clothing/head/beret/cmo
name = "chief medical officer's beret"
desc = "A fancy beret with a green cross, signifying your status in the station's medbay."
icon_state = "cmoberet"
//Research Director
/obj/item/clothing/head/beret/rd
name = "research director's beret"
desc = "A beret worn only by highly intelligent people."
icon_state = "rdberet"
//Chief Engineer
/obj/item/clothing/head/beret/ce
name = "chief engineer's beret"
desc = "A beret that will surely make you look way cooler than a hard hat, although lack of protection is the price."
icon_state = "ceberet"
//Quartermaster
/obj/item/clothing/head/beret/qm
name = "quartermaster's beret"
desc = "This headwear shows off your Cargonian leadership"
icon_state = "qmberet"
/obj/item/clothing/head/beret/durathread
name = "durathread beret"
desc = "A beret made from durathread, its resilient fibres provide some protection to the wearer."
icon_state = "beretdurathread"
item_color = null
armor = list("melee" = 25, "bullet" = 10, "laser" = 20,"energy" = 10, "bomb" = 30, "bio" = 15, "rad" = 20, "fire" = 100, "acid" = 50)
#undef DRILL_DEFAULT
#undef DRILL_SHOUTING
#undef DRILL_YELLING
#undef DRILL_CANADIAN
//defines the drill hat's yelling setting
#define DRILL_DEFAULT "default"
#define DRILL_SHOUTING "shouting"
#define DRILL_YELLING "yelling"
#define DRILL_CANADIAN "canadian"
//Chef
/obj/item/clothing/head/chefhat
name = "chef's hat"
item_state = "chef"
icon_state = "chef"
desc = "The commander in chef's head wear."
strip_delay = 10
equip_delay_other = 10
dynamic_hair_suffix = ""
dog_fashion = /datum/dog_fashion/head/chef
/obj/item/clothing/head/chefhat/suicide_act(mob/user)
user.visible_message("<span class='suicide'>[user] is donning [src]! It looks like [user.p_theyre()] trying to become a chef.</span>")
user.say("Bork Bork Bork!", forced = "chef hat suicide")
sleep(20)
user.visible_message("<span class='suicide'>[user] climbs into an imaginary oven!</span>")
user.say("BOOORK!", forced = "chef hat suicide")
playsound(user, 'sound/machines/ding.ogg', 50, 1)
return(FIRELOSS)
//Captain
/obj/item/clothing/head/caphat
name = "captain's hat"
desc = "It's good being the king."
icon_state = "captain"
item_state = "that"
flags_inv = 0
armor = list("melee" = 40, "bullet" = 30, "laser" = 30, "energy" = 10, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50)
strip_delay = 60
dog_fashion = /datum/dog_fashion/head/captain
//Captain: This is no longer space-worthy
/obj/item/clothing/head/caphat/parade
name = "captain's parade cap"
desc = "Worn only by Captains with an abundance of class."
icon_state = "capcap"
dog_fashion = null
/obj/item/clothing/head/caphat/beret
name = "captain's beret"
desc = "A beret fit for a leader."
icon_state = "capberet"
dynamic_hair_suffix = ""
dog_fashion = null
//Head of Personnel
/obj/item/clothing/head/hopcap
name = "head of personnel's cap"
icon_state = "hopcap"
desc = "The symbol of true bureaucratic micromanagement."
armor = list("melee" = 30, "bullet" = 25, "laser" = 25, "energy" = 10, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50)
dog_fashion = /datum/dog_fashion/head/hop
/obj/item/clothing/head/hopcap/beret
name = "head of personnel's beret"
desc = "The symbol of true bureaucratic micromanagement, although in a fancy form."
icon_state = "hopberet"
dynamic_hair_suffix = ""
dog_fashion = null
//Chaplain
/obj/item/clothing/head/nun_hood
name = "nun hood"
desc = "Maximum piety in this star system."
icon_state = "nun_hood"
flags_inv = HIDEHAIR
flags_cover = HEADCOVERSEYES
//Detective
/obj/item/clothing/head/fedora/det_hat
name = "detective's fedora"
desc = "There's only one man who can sniff out the dirty stench of crime, and he's likely wearing this hat."
armor = list("melee" = 25, "bullet" = 5, "laser" = 25, "energy" = 10, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 30, "acid" = 50)
icon_state = "detective"
var/candy_cooldown = 0
pocket_storage_component_path = /datum/component/storage/concrete/pockets/small/detective
dog_fashion = /datum/dog_fashion/head/detective
/obj/item/clothing/head/fedora/det_hat/Initialize()
. = ..()
new /obj/item/reagent_containers/food/drinks/flask/det(src)
/obj/item/clothing/head/fedora/det_hat/examine(mob/user)
. = ..()
. += "<span class='notice'>Alt-click to take a candy corn.</span>"
/obj/item/clothing/head/fedora/det_hat/AltClick(mob/user)
. = ..()
if(loc == user && user.canUseTopic(src, BE_CLOSE, ismonkey(user)))
if(candy_cooldown < world.time)
var/obj/item/reagent_containers/food/snacks/candy_corn/CC = new /obj/item/reagent_containers/food/snacks/candy_corn(src)
user.put_in_hands(CC)
to_chat(user, "You slip a candy corn from your hat.")
candy_cooldown = world.time+1200
else
to_chat(user, "You just took a candy corn! You should wait a couple minutes, lest you burn through your stash.")
return TRUE
//Mime
/obj/item/clothing/head/beret
name = "beret"
desc = "A beret, a mime's favorite headwear."
icon_state = "beret"
dog_fashion = /datum/dog_fashion/head/beret
dynamic_hair_suffix = ""
/obj/item/clothing/head/beret/black
name = "black beret"
desc = "A black beret, perfect for war veterans and dark, brooding, anti-hero mimes."
icon_state = "beretblack"
/obj/item/clothing/head/beret/highlander
desc = "That was white fabric. <i>Was.</i>"
dog_fashion = null //THIS IS FOR SLAUGHTER, NOT PUPPIES
/obj/item/clothing/head/beret/highlander/Initialize()
. = ..()
ADD_TRAIT(src, TRAIT_NODROP, HIGHLANDER)
//Security
/obj/item/clothing/head/HoS
name = "head of security cap"
desc = "The robust standard-issue cap of the Head of Security. For showing the officers who's in charge."
icon_state = "hoscap"
armor = list("melee" = 40, "bullet" = 30, "laser" = 25, "energy" = 10, "bomb" = 25, "bio" = 10, "rad" = 0, "fire" = 50, "acid" = 60)
strip_delay = 80
dynamic_hair_suffix = ""
/obj/item/clothing/head/HoS/syndicate
name = "syndicate cap"
desc = "A black cap fit for a high ranking syndicate officer."
/obj/item/clothing/head/HoS/beret
name = "head of security beret"
desc = "A robust beret for the Head of Security, for looking stylish while not sacrificing protection."
icon_state = "hosberetblack"
/obj/item/clothing/head/HoS/beret/syndicate
name = "syndicate beret"
desc = "A black beret with thick armor padding inside. Stylish and robust."
/obj/item/clothing/head/warden
name = "warden's police hat"
desc = "It's a special armored hat issued to the Warden of a security force. Protects the head from impacts."
icon_state = "policehelm"
armor = list("melee" = 40, "bullet" = 30, "laser" = 30, "energy" = 10, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 30, "acid" = 60)
strip_delay = 60
dog_fashion = /datum/dog_fashion/head/warden
/obj/item/clothing/head/warden/drill
name = "warden's campaign hat"
desc = "A special armored campaign hat with the security insignia emblazoned on it. Uses reinforced fabric to offer sufficient protection. Has the letters 'FMJ' enscribed on its side."
icon_state = "wardendrill"
item_state = "wardendrill"
dog_fashion = null
var/mode = DRILL_DEFAULT
/obj/item/clothing/head/warden/drill/screwdriver_act(mob/living/carbon/human/user, obj/item/I)
if(..())
return TRUE
switch(mode)
if(DRILL_DEFAULT)
to_chat(user, "<span class='notice'>You set the voice circuit to the middle position.</span>")
mode = DRILL_SHOUTING
if(DRILL_SHOUTING)
to_chat(user, "<span class='notice'>You set the voice circuit to the last position.</span>")
mode = DRILL_YELLING
if(DRILL_YELLING)
to_chat(user, "<span class='notice'>You set the voice circuit to the first position.</span>")
mode = DRILL_DEFAULT
if(DRILL_CANADIAN)
to_chat(user, "<span class='danger'>You adjust voice circuit but nothing happens, probably because it's broken.</span>")
return TRUE
/obj/item/clothing/head/warden/drill/wirecutter_act(mob/living/user, obj/item/I)
if(mode != DRILL_CANADIAN)
to_chat(user, "<span class='danger'>You broke the voice circuit!</span>")
mode = DRILL_CANADIAN
return TRUE
/obj/item/clothing/head/warden/drill/equipped(mob/M, slot)
. = ..()
if (slot == SLOT_HEAD)
RegisterSignal(M, COMSIG_MOB_SAY, .proc/handle_speech)
else
UnregisterSignal(M, COMSIG_MOB_SAY)
/obj/item/clothing/head/warden/drill/dropped(mob/M)
. = ..()
UnregisterSignal(M, COMSIG_MOB_SAY)
/obj/item/clothing/head/warden/drill/proc/handle_speech(datum/source, mob/speech_args)
var/message = speech_args[SPEECH_MESSAGE]
if(message[1] != "*")
switch (mode)
if(DRILL_SHOUTING)
message += "!"
if(DRILL_YELLING)
message += "!!"
if(DRILL_CANADIAN)
message = " [message]"
var/list/canadian_words = strings("canadian_replacement.json", "canadian")
for(var/key in canadian_words)
var/value = canadian_words[key]
if(islist(value))
value = pick(value)
message = replacetextEx(message, " [uppertext(key)]", " [uppertext(value)]")
message = replacetextEx(message, " [capitalize(key)]", " [capitalize(value)]")
message = replacetextEx(message, " [key]", " [value]")
if(prob(30))
message += pick(", eh?", ", EH?")
speech_args[SPEECH_MESSAGE] = message
/obj/item/clothing/head/beret/sec
name = "security beret"
desc = "A robust beret with the security insignia emblazoned on it. Uses reinforced fabric to offer sufficient protection."
icon_state = "beret_badge"
armor = list("melee" = 40, "bullet" = 30, "laser" = 30,"energy" = 10, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50)
strip_delay = 60
dog_fashion = null
/obj/item/clothing/head/beret/sec/navyhos
name = "head of security's beret"
desc = "A special beret with the Head of Security's insignia emblazoned on it. A symbol of excellence, a badge of courage, a mark of distinction."
icon_state = "hosberet"
/obj/item/clothing/head/beret/sec/navywarden
name = "warden's beret"
desc = "A special beret with the Warden's insignia emblazoned on it. For wardens with class."
icon_state = "wardenberet"
armor = list("melee" = 40, "bullet" = 30, "laser" = 30, "energy" = 10, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50)
strip_delay = 60
/obj/item/clothing/head/beret/sec/navyofficer
desc = "A special beret with the security insignia emblazoned on it. For officers with class."
icon_state = "officerberet"
/obj/item/clothing/head/beret/sec/bitch
name = "security's bitch beret"
desc = "A softer beret with the word 'BITCH' embroidered on it in pink thread."
icon_state = "bitchberet"
//Curator
/obj/item/clothing/head/fedora/curator
name = "treasure hunter's fedora"
desc = "You got red text today kid, but it doesn't mean you have to like it."
icon_state = "curator"
//Chief Medical Officer
/obj/item/clothing/head/beret/cmo
name = "chief medical officer's beret"
desc = "A fancy beret with a green cross, signifying your status in the station's medbay."
icon_state = "cmoberet"
//Research Director
/obj/item/clothing/head/beret/rd
name = "research director's beret"
desc = "A beret worn only by highly intelligent people."
icon_state = "rdberet"
//Chief Engineer
/obj/item/clothing/head/beret/ce
name = "chief engineer's beret"
desc = "A beret that will surely make you look way cooler than a hard hat, although lack of protection is the price."
icon_state = "ceberet"
//Quartermaster
/obj/item/clothing/head/beret/qm
name = "quartermaster's beret"
desc = "This headwear shows off your Cargonian leadership"
icon_state = "qmberet"
/obj/item/clothing/head/beret/durathread
name = "durathread beret"
desc = "A beret made from durathread, its resilient fibres provide some protection to the wearer."
icon_state = "beretdurathread"
item_color = null
armor = list("melee" = 25, "bullet" = 10, "laser" = 20,"energy" = 10, "bomb" = 30, "bio" = 15, "rad" = 20, "fire" = 100, "acid" = 50)
#undef DRILL_DEFAULT
#undef DRILL_SHOUTING
#undef DRILL_YELLING
#undef DRILL_CANADIAN
+142 -142
View File
@@ -1,142 +1,142 @@
/obj/item/clothing/head/soft
name = "cargo cap"
desc = "It's a baseball hat in a tasteless yellow colour."
icon_state = "cargosoft"
item_state = "helmet"
item_color = "cargo"
dog_fashion = /datum/dog_fashion/head/cargo_tech
var/flipped = 0
/obj/item/clothing/head/soft/dropped()
src.icon_state = "[item_color]soft"
src.flipped=0
..()
/obj/item/clothing/head/soft/verb/flipcap()
set category = "Object"
set name = "Flip cap"
flip(usr)
/obj/item/clothing/head/soft/AltClick(mob/user)
..()
if(!user.canUseTopic(src, BE_CLOSE, ismonkey(user)))
return
else
flip(user)
/obj/item/clothing/head/soft/proc/flip(mob/user)
if(!user.incapacitated())
src.flipped = !src.flipped
if(src.flipped)
icon_state = "[item_color]soft_flipped"
to_chat(user, "<span class='notice'>You flip the hat backwards.</span>")
else
icon_state = "[item_color]soft"
to_chat(user, "<span class='notice'>You flip the hat back in normal position.</span>")
usr.update_inv_head() //so our mob-overlays update
/obj/item/clothing/head/soft/examine(mob/user)
. = ..()
. += "<span class='notice'>Alt-click the cap to flip it [flipped ? "forwards" : "backwards"].</span>"
/obj/item/clothing/head/soft/red
name = "red cap"
desc = "It's a baseball hat in a tasteless red colour."
icon_state = "redsoft"
item_color = "red"
dog_fashion = null
/obj/item/clothing/head/soft/blue
name = "blue cap"
desc = "It's a baseball hat in a tasteless blue colour."
icon_state = "bluesoft"
item_color = "blue"
dog_fashion = null
/obj/item/clothing/head/soft/green
name = "green cap"
desc = "It's a baseball hat in a tasteless green colour."
icon_state = "greensoft"
item_color = "green"
dog_fashion = null
/obj/item/clothing/head/soft/yellow
name = "yellow cap"
desc = "It's a baseball hat in a tasteless yellow colour."
icon_state = "yellowsoft"
item_color = "yellow"
dog_fashion = null
/obj/item/clothing/head/soft/grey
name = "grey cap"
desc = "It's a baseball hat in a tasteful grey colour."
icon_state = "greysoft"
item_color = "grey"
dog_fashion = null
/obj/item/clothing/head/soft/orange
name = "orange cap"
desc = "It's a baseball hat in a tasteless orange colour."
icon_state = "orangesoft"
item_color = "orange"
dog_fashion = null
/obj/item/clothing/head/soft/mime
name = "white cap"
desc = "It's a baseball hat in a tasteless white colour."
icon_state = "mimesoft"
item_color = "mime"
dog_fashion = null
/obj/item/clothing/head/soft/purple
name = "purple cap"
desc = "It's a baseball hat in a tasteless purple colour."
icon_state = "purplesoft"
item_color = "purple"
dog_fashion = null
/obj/item/clothing/head/soft/black
name = "black cap"
desc = "It's a baseball hat in a tasteless black colour."
icon_state = "blacksoft"
item_color = "black"
dog_fashion = null
/obj/item/clothing/head/soft/rainbow
name = "rainbow cap"
desc = "It's a baseball hat in a bright rainbow of colors."
icon_state = "rainbowsoft"
item_color = "rainbow"
dog_fashion = null
/obj/item/clothing/head/soft/sec
name = "security cap"
desc = "It's a robust baseball hat in tasteful red colour."
icon_state = "secsoft"
item_color = "sec"
armor = list("melee" = 30, "bullet" = 25, "laser" = 25, "energy" = 10, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 20, "acid" = 50)
strip_delay = 60
dog_fashion = null
/obj/item/clothing/head/soft/emt
name = "paramedic cap"
desc = "It's a baseball hat with a dark turquoise color and a reflective cross on the top."
icon_state = "emtsoft"
item_color = "emt"
dog_fashion = null
/obj/item/clothing/head/soft/baseball
name = "baseball cap"
desc = "It's a robust baseball hat, this one belongs to syndicate major league team."
icon_state = "baseballsoft"
item_color = "baseballsoft"
item_state = "baseballsoft"
flags_inv = HIDEEYES|HIDEFACE
armor = list("melee" = 35, "bullet" = 35, "laser" = 25, "energy" = 10, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 20, "acid" = 90)
strip_delay = 90 //You dont take a Major Leage cap
dog_fashion = null
/obj/item/clothing/head/soft
name = "cargo cap"
desc = "It's a baseball hat in a tasteless yellow colour."
icon_state = "cargosoft"
item_state = "helmet"
item_color = "cargo"
dog_fashion = /datum/dog_fashion/head/cargo_tech
var/flipped = 0
/obj/item/clothing/head/soft/dropped()
src.icon_state = "[item_color]soft"
src.flipped=0
..()
/obj/item/clothing/head/soft/verb/flipcap()
set category = "Object"
set name = "Flip cap"
flip(usr)
/obj/item/clothing/head/soft/AltClick(mob/user)
. = ..()
if(!user.canUseTopic(src, BE_CLOSE, ismonkey(user)))
return
flip(user)
return TRUE
/obj/item/clothing/head/soft/proc/flip(mob/user)
if(!user.incapacitated())
src.flipped = !src.flipped
if(src.flipped)
icon_state = "[item_color]soft_flipped"
to_chat(user, "<span class='notice'>You flip the hat backwards.</span>")
else
icon_state = "[item_color]soft"
to_chat(user, "<span class='notice'>You flip the hat back in normal position.</span>")
usr.update_inv_head() //so our mob-overlays update
/obj/item/clothing/head/soft/examine(mob/user)
. = ..()
. += "<span class='notice'>Alt-click the cap to flip it [flipped ? "forwards" : "backwards"].</span>"
/obj/item/clothing/head/soft/red
name = "red cap"
desc = "It's a baseball hat in a tasteless red colour."
icon_state = "redsoft"
item_color = "red"
dog_fashion = null
/obj/item/clothing/head/soft/blue
name = "blue cap"
desc = "It's a baseball hat in a tasteless blue colour."
icon_state = "bluesoft"
item_color = "blue"
dog_fashion = null
/obj/item/clothing/head/soft/green
name = "green cap"
desc = "It's a baseball hat in a tasteless green colour."
icon_state = "greensoft"
item_color = "green"
dog_fashion = null
/obj/item/clothing/head/soft/yellow
name = "yellow cap"
desc = "It's a baseball hat in a tasteless yellow colour."
icon_state = "yellowsoft"
item_color = "yellow"
dog_fashion = null
/obj/item/clothing/head/soft/grey
name = "grey cap"
desc = "It's a baseball hat in a tasteful grey colour."
icon_state = "greysoft"
item_color = "grey"
dog_fashion = null
/obj/item/clothing/head/soft/orange
name = "orange cap"
desc = "It's a baseball hat in a tasteless orange colour."
icon_state = "orangesoft"
item_color = "orange"
dog_fashion = null
/obj/item/clothing/head/soft/mime
name = "white cap"
desc = "It's a baseball hat in a tasteless white colour."
icon_state = "mimesoft"
item_color = "mime"
dog_fashion = null
/obj/item/clothing/head/soft/purple
name = "purple cap"
desc = "It's a baseball hat in a tasteless purple colour."
icon_state = "purplesoft"
item_color = "purple"
dog_fashion = null
/obj/item/clothing/head/soft/black
name = "black cap"
desc = "It's a baseball hat in a tasteless black colour."
icon_state = "blacksoft"
item_color = "black"
dog_fashion = null
/obj/item/clothing/head/soft/rainbow
name = "rainbow cap"
desc = "It's a baseball hat in a bright rainbow of colors."
icon_state = "rainbowsoft"
item_color = "rainbow"
dog_fashion = null
/obj/item/clothing/head/soft/sec
name = "security cap"
desc = "It's a robust baseball hat in tasteful red colour."
icon_state = "secsoft"
item_color = "sec"
armor = list("melee" = 30, "bullet" = 25, "laser" = 25, "energy" = 10, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 20, "acid" = 50)
strip_delay = 60
dog_fashion = null
/obj/item/clothing/head/soft/emt
name = "paramedic cap"
desc = "It's a baseball hat with a dark turquoise color and a reflective cross on the top."
icon_state = "emtsoft"
item_color = "emt"
dog_fashion = null
/obj/item/clothing/head/soft/baseball
name = "baseball cap"
desc = "It's a robust baseball hat, this one belongs to syndicate major league team."
icon_state = "baseballsoft"
item_color = "baseballsoft"
item_state = "baseballsoft"
flags_inv = HIDEEYES|HIDEFACE
armor = list("melee" = 35, "bullet" = 35, "laser" = 25, "energy" = 10, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 20, "acid" = 90)
strip_delay = 90 //You dont take a Major Leage cap
dog_fashion = null
+42 -42
View File
@@ -1,42 +1,42 @@
/obj/item/clothing/mask/breath
desc = "A close-fitting mask that can be connected to an air supply."
name = "breath mask"
icon_state = "breath"
item_state = "m_mask"
body_parts_covered = 0
clothing_flags = ALLOWINTERNALS
visor_flags = ALLOWINTERNALS
w_class = WEIGHT_CLASS_SMALL
gas_transfer_coefficient = 0.1
permeability_coefficient = 0.5
actions_types = list(/datum/action/item_action/adjust)
flags_cover = MASKCOVERSMOUTH
visor_flags_cover = MASKCOVERSMOUTH
resistance_flags = NONE
mutantrace_variation = MUTANTRACE_VARIATION
/obj/item/clothing/mask/breath/suicide_act(mob/living/carbon/user)
user.visible_message("<span class='suicide'>[user] is wrapping \the [src]'s tube around [user.p_their()] neck! It looks like [user.p_theyre()] trying to commit suicide!</span>")
return OXYLOSS
/obj/item/clothing/mask/breath/attack_self(mob/user)
adjustmask(user)
/obj/item/clothing/mask/breath/AltClick(mob/user)
..()
if(!user.canUseTopic(src, BE_CLOSE, ismonkey(user)))
return
else
adjustmask(user)
/obj/item/clothing/mask/breath/examine(mob/user)
. = ..()
. += "<span class='notice'>Alt-click [src] to adjust it.</span>"
/obj/item/clothing/mask/breath/medical
desc = "A close-fitting sterile mask that can be connected to an air supply."
name = "medical mask"
icon_state = "medical"
item_state = "m_mask"
permeability_coefficient = 0.01
equip_delay_other = 10
/obj/item/clothing/mask/breath
desc = "A close-fitting mask that can be connected to an air supply."
name = "breath mask"
icon_state = "breath"
item_state = "m_mask"
body_parts_covered = 0
clothing_flags = ALLOWINTERNALS
visor_flags = ALLOWINTERNALS
w_class = WEIGHT_CLASS_SMALL
gas_transfer_coefficient = 0.1
permeability_coefficient = 0.5
actions_types = list(/datum/action/item_action/adjust)
flags_cover = MASKCOVERSMOUTH
visor_flags_cover = MASKCOVERSMOUTH
resistance_flags = NONE
mutantrace_variation = MUTANTRACE_VARIATION
/obj/item/clothing/mask/breath/suicide_act(mob/living/carbon/user)
user.visible_message("<span class='suicide'>[user] is wrapping \the [src]'s tube around [user.p_their()] neck! It looks like [user.p_theyre()] trying to commit suicide!</span>")
return OXYLOSS
/obj/item/clothing/mask/breath/attack_self(mob/user)
adjustmask(user)
/obj/item/clothing/mask/breath/AltClick(mob/user)
. = ..()
if(!user.canUseTopic(src, BE_CLOSE, ismonkey(user)))
return
adjustmask(user)
return TRUE
/obj/item/clothing/mask/breath/examine(mob/user)
. = ..()
. += "<span class='notice'>Alt-click [src] to adjust it.</span>"
/obj/item/clothing/mask/breath/medical
desc = "A close-fitting sterile mask that can be connected to an air supply."
name = "medical mask"
icon_state = "medical"
item_state = "m_mask"
permeability_coefficient = 0.01
equip_delay_other = 10
@@ -865,3 +865,126 @@
strip_delay = 130
max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT
actions_types = list()
/*
CYDONIAN ARMOR THAT IS RGB AND STUFF WOOOOOOOOOO
*/
/obj/item/clothing/head/helmet/space/hardsuit/lavaknight
name = "cydonian helmet"
desc = "A helmet designed with both form and function in mind, it protects the user against physical trauma and hazardous conditions while also having polychromic light strips."
icon_state = "knight_cydonia"
item_state = "knight_yellow"
item_color = null
max_heat_protection_temperature = FIRE_SUIT_MAX_TEMP_PROTECT
resistance_flags = FIRE_PROOF | LAVA_PROOF
heat_protection = HEAD
armor = list(melee = 50, bullet = 10, laser = 10, energy = 10, bomb = 50, bio = 100, rad = 50, fire = 100, acid = 100)
brightness_on = 7
allowed = list(/obj/item/flashlight, /obj/item/tank/internals, /obj/item/resonator, /obj/item/mining_scanner, /obj/item/t_scanner/adv_mining_scanner, /obj/item/gun/energy/kinetic_accelerator)
var/energy_color = "#35FFF0"
var/obj/item/clothing/suit/space/hardsuit/lavaknight/linkedsuit = null
mutantrace_variation = NO_MUTANTRACE_VARIATION
/obj/item/clothing/head/helmet/space/hardsuit/lavaknight/Initialize()
. = ..()
if(istype(loc, /obj/item/clothing/suit/space/hardsuit/lavaknight))
var/obj/item/clothing/suit/space/hardsuit/lavaknight/S = loc
energy_color = S.energy_color
update_icon()
/obj/item/clothing/head/helmet/space/hardsuit/lavaknight/attack_self(mob/user)
on = !on
if(on)
set_light(brightness_on)
else
set_light(0)
for(var/X in actions)
var/datum/action/A = X
A.UpdateButtonIcon()
/obj/item/clothing/head/helmet/space/hardsuit/lavaknight/update_icon()
var/mutable_appearance/helm_overlay = mutable_appearance(icon, "knight_cydonia_overlay")
if(energy_color)
helm_overlay.color = energy_color
cut_overlays() //So that it doesn't keep stacking overlays non-stop on top of each other
add_overlay(helm_overlay)
/obj/item/clothing/head/helmet/space/hardsuit/lavaknight/worn_overlays(isinhands = FALSE, icon_file)
. = ..()
if(!isinhands)
var/mutable_appearance/energy_overlay = mutable_appearance(icon_file, "knight_cydonia_overlay", ABOVE_LIGHTING_LAYER)
energy_overlay.plane = ABOVE_LIGHTING_LAYER
energy_overlay.color = energy_color
. += energy_overlay
/obj/item/clothing/suit/space/hardsuit/lavaknight
icon_state = "knight_cydonia"
name = "cydonian armor"
desc = "A suit designed with both form and function in mind, it protects the user against physical trauma and hazardous conditions while also having polychromic light strips."
item_state = "swat_suit"
max_heat_protection_temperature = FIRE_SUIT_MAX_TEMP_PROTECT
resistance_flags = FIRE_PROOF | LAVA_PROOF
armor = list(melee = 50, bullet = 10, laser = 10, energy = 10, bomb = 50, bio = 100, rad = 50, fire = 100, acid = 100)
allowed = list(/obj/item/flashlight, /obj/item/tank/internals, /obj/item/storage/bag/ore, /obj/item/pickaxe)
helmettype = /obj/item/clothing/head/helmet/space/hardsuit/lavaknight
heat_protection = CHEST|GROIN|LEGS|FEET|ARMS|HANDS
tauric = TRUE //Citadel Add for tauric hardsuits
var/energy_color = "#35FFF0"
/obj/item/clothing/suit/space/hardsuit/lavaknight/Initialize()
..()
light_color = energy_color
set_light(1)
update_icon()
/obj/item/clothing/suit/space/hardsuit/lavaknight/update_icon()
var/mutable_appearance/suit_overlay = mutable_appearance(icon, "knight_cydonia_overlay")
if(energy_color)
suit_overlay.color = energy_color
cut_overlays() //So that it doesn't keep stacking overlays non-stop on top of each other
add_overlay(suit_overlay)
/obj/item/clothing/suit/space/hardsuit/lavaknight/worn_overlays(isinhands = FALSE, icon_file)
. = ..()
if(!isinhands)
var/mutable_appearance/energy_overlay = mutable_appearance(icon_file, "knight_cydonia_overlay", ABOVE_LIGHTING_LAYER)
energy_overlay.plane = ABOVE_LIGHTING_LAYER
energy_overlay.color = energy_color
. += energy_overlay
/obj/item/clothing/suit/space/hardsuit/lavaknight/AltClick(mob/living/user)
. = ..()
if(!in_range(src, user) || !istype(user))
return
if(user.incapacitated())
to_chat(user, "<span class='warning'>You can't do that right now!</span>")
return TRUE
if(alert("Are you sure you want to recolor your armor stripes?", "Confirm Repaint", "Yes", "No") == "Yes")
var/energy_color_input = input(usr,"","Choose Energy Color",energy_color) as color|null
if(energy_color_input)
energy_color = sanitize_hexcolor(energy_color_input, desired_format=6, include_crunch=1)
user.update_inv_wear_suit()
if(helmet)
var/obj/item/clothing/head/helmet/space/hardsuit/lavaknight/H = helmet
H.energy_color = energy_color
user.update_inv_head()
H.update_icon()
update_icon()
user.update_inv_wear_suit()
light_color = energy_color
update_light()
return TRUE
/obj/item/clothing/suit/space/hardsuit/lavaknight/examine(mob/user)
. = ..()
. += "<span class='notice'>Alt-click to recolor it.</span>"
+3 -3
View File
@@ -92,11 +92,11 @@
//Toggle exosuits for different aesthetic styles (hoodies, suit jacket buttons, etc)
/obj/item/clothing/suit/toggle/AltClick(mob/user)
..()
. = ..()
if(!user.canUseTopic(src, BE_CLOSE, ismonkey(user)))
return
else
suit_toggle(user)
suit_toggle(user)
return TRUE
/obj/item/clothing/suit/toggle/ui_action_click()
suit_toggle()
@@ -67,10 +67,12 @@
return
/obj/item/clothing/accessory/AltClick(mob/user)
. = ..()
if(istype(user) && user.canUseTopic(src, BE_CLOSE, ismonkey(user)))
if(initial(above_suit))
above_suit = !above_suit
to_chat(user, "[src] will be worn [above_suit ? "above" : "below"] your suit.")
return TRUE
/obj/item/clothing/accessory/examine(mob/user)
. = ..()
+219 -217
View File
@@ -1,217 +1,219 @@
//CONTAINS: Detective's Scanner
// TODO: Split everything into easy to manage procs.
/obj/item/detective_scanner
name = "forensic scanner"
desc = "Used to remotely scan objects and biomass for DNA and fingerprints. Can print a report of the findings."
icon = 'icons/obj/device.dmi'
icon_state = "forensicnew"
w_class = WEIGHT_CLASS_SMALL
item_state = "electronic"
lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi'
righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi'
flags_1 = CONDUCT_1
item_flags = NOBLUDGEON
slot_flags = ITEM_SLOT_BELT
var/scanning = FALSE
var/list/log = list()
var/range = 8
var/view_check = TRUE
actions_types = list(/datum/action/item_action/displayDetectiveScanResults)
/datum/action/item_action/displayDetectiveScanResults
name = "Display Forensic Scanner Results"
/datum/action/item_action/displayDetectiveScanResults/Trigger()
var/obj/item/detective_scanner/scanner = target
if(istype(scanner))
scanner.displayDetectiveScanResults(usr)
/obj/item/detective_scanner/attack_self(mob/user)
if(log.len && !scanning)
scanning = TRUE
to_chat(user, "<span class='notice'>Printing report, please wait...</span>")
addtimer(CALLBACK(src, .proc/PrintReport), 100)
else
to_chat(user, "<span class='notice'>The scanner has no logs or is in use.</span>")
/obj/item/detective_scanner/attack(mob/living/M, mob/user)
return
/obj/item/detective_scanner/proc/PrintReport()
// Create our paper
var/obj/item/paper/P = new(get_turf(src))
P.name = "paper- 'Scanner Report'"
P.info = "<center><font size='6'><B>Scanner Report</B></font></center><HR><BR>"
P.info += jointext(log, "<BR>")
P.info += "<HR><B>Notes:</B><BR>"
P.info_links = P.info
P.updateinfolinks()
if(ismob(loc))
var/mob/M = loc
M.put_in_hands(P)
to_chat(M, "<span class='notice'>Report printed. Log cleared.</span>")
// Clear the logs
log = list()
scanning = FALSE
/obj/item/detective_scanner/afterattack(atom/A, mob/user, params)
. = ..()
scan(A, user)
return FALSE
/obj/item/detective_scanner/proc/scan(atom/A, mob/user)
set waitfor = 0
if(!scanning)
// Can remotely scan objects and mobs.
if((get_dist(A, user) > range) || (!(A in view(range, user)) && view_check) || (loc != user))
return
scanning = TRUE
user.visible_message("\The [user] points the [src.name] at \the [A] and performs a forensic scan.")
to_chat(user, "<span class='notice'>You scan \the [A]. The scanner is now analysing the results...</span>")
// GATHER INFORMATION
//Make our lists
var/list/fingerprints = list()
var/list/blood = list()
var/list/fibers = list()
var/list/reagents = list()
var/target_name = A.name
// Start gathering
if(A.blood_DNA && A.blood_DNA.len)
blood = A.blood_DNA.Copy()
if(A.suit_fibers && A.suit_fibers.len)
fibers = A.suit_fibers.Copy()
if(ishuman(A))
var/mob/living/carbon/human/H = A
if(!H.gloves)
fingerprints += md5(H.dna.uni_identity)
else if(!ismob(A))
if(A.fingerprints && A.fingerprints.len)
fingerprints = A.fingerprints.Copy()
// Only get reagents from non-mobs.
if(A.reagents && A.reagents.reagent_list.len)
for(var/datum/reagent/R in A.reagents.reagent_list)
reagents[R.name] = R.volume
// Get blood data from the blood reagent.
if(istype(R, /datum/reagent/blood))
if(R.data["blood_DNA"] && R.data["blood_type"])
var/blood_DNA = R.data["blood_DNA"]
var/blood_type = R.data["blood_type"]
LAZYINITLIST(blood)
blood[blood_DNA] = blood_type
// We gathered everything. Create a fork and slowly display the results to the holder of the scanner.
var/found_something = FALSE
add_log("<B>[STATION_TIME_TIMESTAMP("hh:mm:ss")][get_timestamp()] - [target_name]</B>", 0)
// Fingerprints
if(length(fingerprints))
sleep(3 SECONDS)
add_log("<span class='info'><B>Prints:</B></span>")
for(var/finger in fingerprints)
add_log("[finger]")
found_something = TRUE
// Blood
if (length(blood))
sleep(3 SECONDS)
add_log("<span class='info'><B>Blood:</B></span>")
found_something = TRUE
for(var/B in blood)
add_log("Type: <font color='red'>[blood[B]]</font> DNA: <font color='red'>[B]</font>")
//Fibers
if(length(fibers))
sleep(3 SECONDS)
add_log("<span class='info'><B>Fibers:</B></span>")
for(var/fiber in fibers)
add_log("[fiber]")
found_something = TRUE
//Reagents
if(length(reagents))
sleep(3 SECONDS)
add_log("<span class='info'><B>Reagents:</B></span>")
for(var/R in reagents)
add_log("Reagent: <font color='red'>[R]</font> Volume: <font color='red'>[reagents[R]]</font>")
found_something = TRUE
// Get a new user
var/mob/holder = null
if(ismob(src.loc))
holder = src.loc
if(!found_something)
add_log("<I># No forensic traces found #</I>", 0) // Don't display this to the holder user
if(holder)
to_chat(holder, "<span class='warning'>Unable to locate any fingerprints, materials, fibers, or blood on \the [target_name]!</span>")
else
if(holder)
to_chat(holder, "<span class='notice'>You finish scanning \the [target_name].</span>")
add_log("---------------------------------------------------------", 0)
scanning = FALSE
return
/obj/item/detective_scanner/proc/add_log(msg, broadcast = TRUE)
if(scanning)
if(broadcast && ismob(loc))
var/mob/M = loc
to_chat(M, msg)
log += "&nbsp;&nbsp;[msg]"
else
CRASH("[src] [REF(src)] is adding a log when it was never put in scanning mode!")
/proc/get_timestamp()
return time2text(world.time + 432000, ":ss")
/obj/item/detective_scanner/AltClick(mob/living/user)
// Best way for checking if a player can use while not incapacitated, etc
if(!user.canUseTopic(src, be_close=TRUE))
return
if(!LAZYLEN(log))
to_chat(user, "<span class='notice'>Cannot clear logs, the scanner has no logs.</span>")
return
if(scanning)
to_chat(user, "<span class='notice'>Cannot clear logs, the scanner is in use.</span>")
return
to_chat(user, "<span class='notice'>The scanner logs are cleared.</span>")
log = list()
/obj/item/detective_scanner/examine(mob/user)
. = ..()
if(LAZYLEN(log) && !scanning)
. += "<span class='notice'>Alt-click to clear scanner logs.</span>"
/obj/item/detective_scanner/proc/displayDetectiveScanResults(mob/living/user)
// No need for can-use checks since the action button should do proper checks
if(!LAZYLEN(log))
to_chat(user, "<span class='notice'>Cannot display logs, the scanner has no logs.</span>")
return
if(scanning)
to_chat(user, "<span class='notice'>Cannot display logs, the scanner is in use.</span>")
return
to_chat(user, "<span class='notice'><B>Scanner Report</B></span>")
for(var/iterLog in log)
to_chat(user, iterLog)
//CONTAINS: Detective's Scanner
// TODO: Split everything into easy to manage procs.
/obj/item/detective_scanner
name = "forensic scanner"
desc = "Used to remotely scan objects and biomass for DNA and fingerprints. Can print a report of the findings."
icon = 'icons/obj/device.dmi'
icon_state = "forensicnew"
w_class = WEIGHT_CLASS_SMALL
item_state = "electronic"
lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi'
righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi'
flags_1 = CONDUCT_1
item_flags = NOBLUDGEON
slot_flags = ITEM_SLOT_BELT
var/scanning = FALSE
var/list/log = list()
var/range = 8
var/view_check = TRUE
actions_types = list(/datum/action/item_action/displayDetectiveScanResults)
/datum/action/item_action/displayDetectiveScanResults
name = "Display Forensic Scanner Results"
/datum/action/item_action/displayDetectiveScanResults/Trigger()
var/obj/item/detective_scanner/scanner = target
if(istype(scanner))
scanner.displayDetectiveScanResults(usr)
/obj/item/detective_scanner/attack_self(mob/user)
if(log.len && !scanning)
scanning = TRUE
to_chat(user, "<span class='notice'>Printing report, please wait...</span>")
addtimer(CALLBACK(src, .proc/PrintReport), 100)
else
to_chat(user, "<span class='notice'>The scanner has no logs or is in use.</span>")
/obj/item/detective_scanner/attack(mob/living/M, mob/user)
return
/obj/item/detective_scanner/proc/PrintReport()
// Create our paper
var/obj/item/paper/P = new(get_turf(src))
P.name = "paper- 'Scanner Report'"
P.info = "<center><font size='6'><B>Scanner Report</B></font></center><HR><BR>"
P.info += jointext(log, "<BR>")
P.info += "<HR><B>Notes:</B><BR>"
P.info_links = P.info
P.updateinfolinks()
if(ismob(loc))
var/mob/M = loc
M.put_in_hands(P)
to_chat(M, "<span class='notice'>Report printed. Log cleared.</span>")
// Clear the logs
log = list()
scanning = FALSE
/obj/item/detective_scanner/afterattack(atom/A, mob/user, params)
. = ..()
scan(A, user)
return FALSE
/obj/item/detective_scanner/proc/scan(atom/A, mob/user)
set waitfor = 0
if(!scanning)
// Can remotely scan objects and mobs.
if((get_dist(A, user) > range) || (!(A in view(range, user)) && view_check) || (loc != user))
return
scanning = TRUE
user.visible_message("\The [user] points the [src.name] at \the [A] and performs a forensic scan.")
to_chat(user, "<span class='notice'>You scan \the [A]. The scanner is now analysing the results...</span>")
// GATHER INFORMATION
//Make our lists
var/list/fingerprints = list()
var/list/blood = list()
var/list/fibers = list()
var/list/reagents = list()
var/target_name = A.name
// Start gathering
if(A.blood_DNA && A.blood_DNA.len)
blood = A.blood_DNA.Copy()
if(A.suit_fibers && A.suit_fibers.len)
fibers = A.suit_fibers.Copy()
if(ishuman(A))
var/mob/living/carbon/human/H = A
if(!H.gloves)
fingerprints += md5(H.dna.uni_identity)
else if(!ismob(A))
if(A.fingerprints && A.fingerprints.len)
fingerprints = A.fingerprints.Copy()
// Only get reagents from non-mobs.
if(A.reagents && A.reagents.reagent_list.len)
for(var/datum/reagent/R in A.reagents.reagent_list)
reagents[R.name] = R.volume
// Get blood data from the blood reagent.
if(istype(R, /datum/reagent/blood))
if(R.data["blood_DNA"] && R.data["blood_type"])
var/blood_DNA = R.data["blood_DNA"]
var/blood_type = R.data["blood_type"]
LAZYINITLIST(blood)
blood[blood_DNA] = blood_type
// We gathered everything. Create a fork and slowly display the results to the holder of the scanner.
var/found_something = FALSE
add_log("<B>[STATION_TIME_TIMESTAMP("hh:mm:ss")][get_timestamp()] - [target_name]</B>", 0)
// Fingerprints
if(length(fingerprints))
sleep(3 SECONDS)
add_log("<span class='info'><B>Prints:</B></span>")
for(var/finger in fingerprints)
add_log("[finger]")
found_something = TRUE
// Blood
if (length(blood))
sleep(3 SECONDS)
add_log("<span class='info'><B>Blood:</B></span>")
found_something = TRUE
for(var/B in blood)
add_log("Type: <font color='red'>[blood[B]]</font> DNA: <font color='red'>[B]</font>")
//Fibers
if(length(fibers))
sleep(3 SECONDS)
add_log("<span class='info'><B>Fibers:</B></span>")
for(var/fiber in fibers)
add_log("[fiber]")
found_something = TRUE
//Reagents
if(length(reagents))
sleep(3 SECONDS)
add_log("<span class='info'><B>Reagents:</B></span>")
for(var/R in reagents)
add_log("Reagent: <font color='red'>[R]</font> Volume: <font color='red'>[reagents[R]]</font>")
found_something = TRUE
// Get a new user
var/mob/holder = null
if(ismob(src.loc))
holder = src.loc
if(!found_something)
add_log("<I># No forensic traces found #</I>", 0) // Don't display this to the holder user
if(holder)
to_chat(holder, "<span class='warning'>Unable to locate any fingerprints, materials, fibers, or blood on \the [target_name]!</span>")
else
if(holder)
to_chat(holder, "<span class='notice'>You finish scanning \the [target_name].</span>")
add_log("---------------------------------------------------------", 0)
scanning = FALSE
return
/obj/item/detective_scanner/proc/add_log(msg, broadcast = TRUE)
if(scanning)
if(broadcast && ismob(loc))
var/mob/M = loc
to_chat(M, msg)
log += "&nbsp;&nbsp;[msg]"
else
CRASH("[src] [REF(src)] is adding a log when it was never put in scanning mode!")
/proc/get_timestamp()
return time2text(world.time + 432000, ":ss")
/obj/item/detective_scanner/AltClick(mob/living/user)
. = ..()
// Best way for checking if a player can use while not incapacitated, etc
if(!user.canUseTopic(src, be_close=TRUE))
return
. = TRUE
if(!LAZYLEN(log))
to_chat(user, "<span class='notice'>Cannot clear logs, the scanner has no logs.</span>")
return
if(scanning)
to_chat(user, "<span class='notice'>Cannot clear logs, the scanner is in use.</span>")
return
to_chat(user, "<span class='notice'>The scanner logs are cleared.</span>")
log = list()
/obj/item/detective_scanner/examine(mob/user)
. = ..()
if(LAZYLEN(log) && !scanning)
. += "<span class='notice'>Alt-click to clear scanner logs.</span>"
/obj/item/detective_scanner/proc/displayDetectiveScanResults(mob/living/user)
// No need for can-use checks since the action button should do proper checks
if(!LAZYLEN(log))
to_chat(user, "<span class='notice'>Cannot display logs, the scanner has no logs.</span>")
return
if(scanning)
to_chat(user, "<span class='notice'>Cannot display logs, the scanner is in use.</span>")
return
to_chat(user, "<span class='notice'><B>Scanner Report</B></span>")
for(var/iterLog in log)
to_chat(user, iterLog)
@@ -186,8 +186,10 @@
..()
/obj/machinery/microwave/AltClick(mob/user)
. = ..()
if(user.canUseTopic(src, !issilicon(usr)))
cook()
return TRUE
/obj/machinery/microwave/ui_interact(mob/user)
. = ..()
+2
View File
@@ -130,9 +130,11 @@
update_icon()
/obj/item/toy/cards/singlecard/cas/AltClick(mob/living/user)
. = ..()
if(!ishuman(user) || !user.canUseTopic(src, BE_CLOSE))
return
Flip()
return TRUE
/obj/item/toy/cards/singlecard/cas/update_icon()
if(flipped)
+4 -3
View File
@@ -180,10 +180,11 @@
else
return ..()
//this helps you not blow up so easily by overriding unlocking which results in an immediate boom.
/obj/structure/closet/crate/secure/loot/AltClick(mob/living/user)
if(!user.canUseTopic(src, BE_CLOSE))
return
return attack_hand(user) //this helps you not blow up so easily by overriding unlocking which results in an immediate boom.
if(user.canUseTopic(src, BE_CLOSE))
attack_hand(user)
return TRUE
/obj/structure/closet/crate/secure/loot/attackby(obj/item/W, mob/user)
if(locked)
@@ -59,6 +59,7 @@ GLOBAL_LIST_INIT(marker_beacon_colors, list(
/obj/item/stack/marker_beacon/AltClick(mob/living/user)
if(!istype(user) || !user.canUseTopic(src, BE_CLOSE))
return
. = TRUE
var/input_color = input(user, "Choose a color.", "Beacon Color") as null|anything in GLOB.marker_beacon_colors
if(!istype(user) || !user.canUseTopic(src, BE_CLOSE))
return
@@ -128,9 +129,10 @@ GLOBAL_LIST_INIT(marker_beacon_colors, list(
return ..()
/obj/structure/marker_beacon/AltClick(mob/living/user)
..()
. = ..()
if(!istype(user) || !user.canUseTopic(src, BE_CLOSE))
return
. = TRUE
var/input_color = input(user, "Choose a color.", "Beacon Color") as null|anything in GLOB.marker_beacon_colors
if(!istype(user) || !user.canUseTopic(src, BE_CLOSE))
return
@@ -29,6 +29,7 @@
/mob/living/simple_animal/hostile/guardian/bomb/AltClickOn(atom/movable/A)
if(!istype(A))
altclick_listed_turf(A)
return
if(loc == summoner)
to_chat(src, "<span class='danger'><B>You must be manifested to create bombs!</span></B>")
@@ -105,8 +105,9 @@
/mob/living/simple_animal/hostile/guardian/healer/AltClickOn(atom/movable/A)
if(!istype(A))
altclick_listed_turf(A)
return
if(src.loc == summoner)
if(loc == summoner)
to_chat(src, "<span class='danger'><B>You must be manifested to warp a target!</span></B>")
return
if(!beacon)
@@ -267,6 +267,7 @@ Difficulty: Medium
/mob/living/simple_animal/hostile/megafauna/dragon/AltClickOn(atom/movable/A)
if(!istype(A))
altclick_listed_turf(A)
return
if(swoop_cooldown >= world.time)
to_chat(src, "<span class='warning'>You need to wait 20 seconds between swoop attacks!</span>")
@@ -442,7 +442,7 @@ Difficulty: Normal
/mob/living/simple_animal/hostile/megafauna/hierophant/AltClickOn(atom/A) //player control handler(don't give this to a player holy fuck)
if(!istype(A) || get_dist(A, src) <= 2)
return
return altclick_listed_turf(A)
blink(A)
//Hierophant overlays
+1
View File
@@ -8,6 +8,7 @@ GLOBAL_LIST_INIT(ventcrawl_machinery, typecacheof(list(
/mob/living/proc/handle_ventcrawl(atom/A)
if(!ventcrawler || !Adjacent(A))
return
. = TRUE //return value to stop the client from being shown the turf contents stat tab on alt-click.
if(stat)
to_chat(src, "You must be conscious to do this!")
return
@@ -126,7 +126,7 @@
portable_drive.verb_pickup()
/obj/item/modular_computer/AltClick(mob/user)
..()
. = ..()
if(issilicon(user))
return
@@ -142,7 +142,7 @@
return
if(ai_slot)
ai_slot.try_eject(null, user)
return TRUE
// Gets IDs/access levels from card slot. Would be useful when/if PDAs would become modular PCs.
/obj/item/modular_computer/GetAccess()
@@ -86,8 +86,8 @@
/obj/item/modular_computer/laptop/AltClick(mob/user)
if(screen_on) // Close it.
try_toggle_open(user)
else
return ..()
return TRUE
return ..()
/obj/item/modular_computer/laptop/proc/toggle_open(mob/living/user=null)
if(screen_on)
@@ -92,8 +92,9 @@
cpu.eject_card()
/obj/machinery/modular_computer/AltClick(mob/user)
. = ..()
if(cpu)
cpu.AltClick(user)
return cpu.AltClick(user)
//ATTACK HAND IGNORING PARENT RETURN VALUE
// On-click handling. Turns on the computer if it's off and opens the GUI.
+2
View File
@@ -122,6 +122,7 @@
. += "<span class='notice'>Alt-click [src] to fold it into a paper plane.</span>"
/obj/item/paper/AltClick(mob/living/carbon/user, obj/item/I)
. = ..()
if(!istype(user) || !user.canUseTopic(src, BE_CLOSE, ismonkey(user), NO_TK))
return
to_chat(user, "<span class='notice'>You fold [src] into the shape of a plane!</span>")
@@ -134,3 +135,4 @@
I = new plane_type(user, src)
user.put_in_hands(I)
return TRUE
+215 -214
View File
@@ -1,214 +1,215 @@
#define CAMERA_PICTURE_SIZE_HARD_LIMIT 21
/obj/item/camera
name = "camera"
icon = 'icons/obj/items_and_weapons.dmi'
desc = "A polaroid camera."
icon_state = "camera"
item_state = "camera"
lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi'
righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi'
light_color = LIGHT_COLOR_WHITE
light_power = FLASH_LIGHT_POWER
w_class = WEIGHT_CLASS_SMALL
flags_1 = CONDUCT_1
slot_flags = ITEM_SLOT_NECK
materials = list(MAT_METAL = 50, MAT_GLASS = 150)
var/flash_enabled = TRUE
var/state_on = "camera"
var/state_off = "camera_off"
var/pictures_max = 10
var/pictures_left = 10
var/on = TRUE
var/cooldown = 64
var/blending = FALSE //lets not take pictures while the previous is still processing!
var/see_ghosts = CAMERA_NO_GHOSTS //for the spoop of it
var/obj/item/disk/holodisk/disk
var/sound/custom_sound
var/silent = FALSE
var/picture_size_x = 2
var/picture_size_y = 2
var/picture_size_x_min = 1
var/picture_size_y_min = 1
var/picture_size_x_max = 4
var/picture_size_y_max = 4
/obj/item/camera/attack_self(mob/user)
if(!disk)
return
to_chat(user, "<span class='notice'>You eject [disk] out the back of [src].</span>")
user.put_in_hands(disk)
disk = null
/obj/item/camera/examine(mob/user)
. = ..()
. += "<span class='notice'>Alt-click to change its focusing, allowing you to set how big of an area it will capture.</span>"
/obj/item/camera/AltClick(mob/user)
if(!user.canUseTopic(src, BE_CLOSE))
return
var/desired_x = input(user, "How high do you want the camera to shoot, between [picture_size_x_min] and [picture_size_x_max]?", "Zoom", picture_size_x) as num
var/desired_y = input(user, "How wide do you want the camera to shoot, between [picture_size_y_min] and [picture_size_y_max]?", "Zoom", picture_size_y) as num
picture_size_x = min(CLAMP(desired_x, picture_size_x_min, picture_size_x_max), CAMERA_PICTURE_SIZE_HARD_LIMIT)
picture_size_y = min(CLAMP(desired_y, picture_size_y_min, picture_size_y_max), CAMERA_PICTURE_SIZE_HARD_LIMIT)
/obj/item/camera/attack(mob/living/carbon/human/M, mob/user)
return
/obj/item/camera/attackby(obj/item/I, mob/user, params)
if(istype(I, /obj/item/camera_film))
if(pictures_left)
to_chat(user, "<span class='notice'>[src] still has some film in it!</span>")
return
if(!user.temporarilyRemoveItemFromInventory(I))
return
to_chat(user, "<span class='notice'>You insert [I] into [src].</span>")
qdel(I)
pictures_left = pictures_max
return
if(istype(I, /obj/item/disk/holodisk))
if (!disk)
if(!user.transferItemToLoc(I, src))
to_chat(user, "<span class='warning'>[I] is stuck to your hand!</span>")
return TRUE
to_chat(user, "<span class='notice'>You slide [I] into the back of [src].</span>")
disk = I
else
to_chat(user, "<span class='warning'>There's already a disk inside [src].</span>")
return TRUE //no afterattack
..()
/obj/item/camera/examine(mob/user)
. = ..()
. += "It has [pictures_left] photos left."
//user can be atom or mob
/obj/item/camera/proc/can_target(atom/target, mob/user, prox_flag)
if(!on || blending || !pictures_left)
return FALSE
var/turf/T = get_turf(target)
if(!T)
return FALSE
if(istype(user))
if(isAI(user) && !GLOB.cameranet.checkTurfVis(T))
return FALSE
else if(user.client && !(get_turf(target) in get_hear(user.client.view, user)))
return FALSE
else if(!(get_turf(target) in get_hear(world.view, user)))
return FALSE
else //user is an atom
if(!(get_turf(target) in view(world.view, user)))
return FALSE
return TRUE
/obj/item/camera/afterattack(atom/target, mob/user, flag)
if (disk)
if(ismob(target))
if (disk.record)
QDEL_NULL(disk.record)
disk.record = new
var/mob/M = target
disk.record.caller_name = M.name
disk.record.set_caller_image(M)
else
to_chat(user, "<span class='warning'>Invalid holodisk target.</span>")
return
if(!can_target(target, user, flag))
return
on = FALSE
var/realcooldown = cooldown
var/mob/living/carbon/human/H = user
if (HAS_TRAIT(H, TRAIT_PHOTOGRAPHER))
realcooldown *= 0.5
addtimer(CALLBACK(src, .proc/cooldown), realcooldown)
icon_state = state_off
INVOKE_ASYNC(src, .proc/captureimage, target, user, flag, picture_size_x - 1, picture_size_y - 1)
/obj/item/camera/proc/cooldown()
UNTIL(!blending)
icon_state = state_on
on = TRUE
/obj/item/camera/proc/show_picture(mob/user, datum/picture/selection)
var/obj/item/photo/P = new(src, selection)
P.show(user)
to_chat(user, P.desc)
qdel(P)
/obj/item/camera/proc/captureimage(atom/target, mob/user, flag, size_x = 1, size_y = 1)
if(flash_enabled)
flash_lighting_fx(8, light_power, light_color)
blending = TRUE
var/turf/target_turf = get_turf(target)
if(!isturf(target_turf))
blending = FALSE
return FALSE
size_x = CLAMP(size_x, 0, CAMERA_PICTURE_SIZE_HARD_LIMIT)
size_y = CLAMP(size_y, 0, CAMERA_PICTURE_SIZE_HARD_LIMIT)
var/list/desc = list("This is a photo of an area of [size_x+1] meters by [size_y+1] meters.")
var/ai_user = isAI(user)
var/list/seen
var/list/viewlist = (user && user.client)? getviewsize(user.client.view) : getviewsize(world.view)
var/viewr = max(viewlist[1], viewlist[2]) + max(size_x, size_y)
var/viewc = user.client? user.client.eye : target
seen = get_hear(viewr, viewc)
var/list/turfs = list()
var/list/mobs = list()
var/blueprints = FALSE
var/clone_area = SSmapping.RequestBlockReservation(size_x * 2 + 1, size_y * 2 + 1)
for(var/turf/T in block(locate(target_turf.x - size_x, target_turf.y - size_y, target_turf.z), locate(target_turf.x + size_x, target_turf.y + size_y, target_turf.z)))
if((ai_user && GLOB.cameranet.checkTurfVis(T)) || (T in seen))
turfs += T
for(var/mob/M in T)
mobs += M
if(locate(/obj/item/areaeditor/blueprints) in T)
blueprints = TRUE
for(var/i in mobs)
var/mob/M = i
desc += M.get_photo_description(src)
var/psize_x = (size_x * 2 + 1) * world.icon_size
var/psize_y = (size_y * 2 + 1) * world.icon_size
var/get_icon = camera_get_icon(turfs, target_turf, psize_x, psize_y, clone_area, size_x, size_y, (size_x * 2 + 1), (size_y * 2 + 1))
qdel(clone_area)
var/icon/temp = icon('icons/effects/96x96.dmi',"")
temp.Blend("#000", ICON_OVERLAY)
temp.Scale(psize_x, psize_y)
temp.Blend(get_icon, ICON_OVERLAY)
var/datum/picture/P = new("picture", desc.Join(" "), temp, null, psize_x, psize_y, blueprints)
after_picture(user, P, flag)
blending = FALSE
/obj/item/camera/proc/after_picture(mob/user, datum/picture/picture, proximity_flag)
printpicture(user, picture)
/obj/item/camera/proc/printpicture(mob/user, datum/picture/picture) //Normal camera proc for creating photos
var/obj/item/photo/p = new(get_turf(src), picture)
if(in_range(src, user)) //needed because of TK
user.put_in_hands(p)
pictures_left--
to_chat(user, "<span class='notice'>[pictures_left] photos left.</span>")
var/customize = alert(user, "Do you want to customize the photo?", "Customization", "Yes", "No")
if(customize == "Yes")
var/name1 = stripped_input(user, "Set a name for this photo, or leave blank. 32 characters max.", "Name", max_length = 32)
var/desc1 = stripped_input(user, "Set a description to add to photo, or leave blank. 128 characters max.", "Caption", max_length = 128)
var/caption = stripped_input(user, "Set a caption for this photo, or leave blank. 256 characters max.", "Caption", max_length = 256)
if(name1)
picture.picture_name = name1
if(desc1)
picture.picture_desc = "[desc1] - [picture.picture_desc]"
if(caption)
picture.caption = caption
p.set_picture(picture, TRUE, TRUE)
if(CONFIG_GET(flag/picture_logging_camera))
picture.log_to_file()
#define CAMERA_PICTURE_SIZE_HARD_LIMIT 21
/obj/item/camera
name = "camera"
icon = 'icons/obj/items_and_weapons.dmi'
desc = "A polaroid camera."
icon_state = "camera"
item_state = "camera"
lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi'
righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi'
light_color = LIGHT_COLOR_WHITE
light_power = FLASH_LIGHT_POWER
w_class = WEIGHT_CLASS_SMALL
flags_1 = CONDUCT_1
slot_flags = ITEM_SLOT_NECK
materials = list(MAT_METAL = 50, MAT_GLASS = 150)
var/flash_enabled = TRUE
var/state_on = "camera"
var/state_off = "camera_off"
var/pictures_max = 10
var/pictures_left = 10
var/on = TRUE
var/cooldown = 64
var/blending = FALSE //lets not take pictures while the previous is still processing!
var/see_ghosts = CAMERA_NO_GHOSTS //for the spoop of it
var/obj/item/disk/holodisk/disk
var/sound/custom_sound
var/silent = FALSE
var/picture_size_x = 2
var/picture_size_y = 2
var/picture_size_x_min = 1
var/picture_size_y_min = 1
var/picture_size_x_max = 4
var/picture_size_y_max = 4
/obj/item/camera/attack_self(mob/user)
if(!disk)
return
to_chat(user, "<span class='notice'>You eject [disk] out the back of [src].</span>")
user.put_in_hands(disk)
disk = null
/obj/item/camera/examine(mob/user)
. = ..()
. += "<span class='notice'>Alt-click to change its focusing, allowing you to set how big of an area it will capture.</span>"
/obj/item/camera/AltClick(mob/user)
. = ..()
if(!user.canUseTopic(src, BE_CLOSE))
return
var/desired_x = input(user, "How high do you want the camera to shoot, between [picture_size_x_min] and [picture_size_x_max]?", "Zoom", picture_size_x) as num
var/desired_y = input(user, "How wide do you want the camera to shoot, between [picture_size_y_min] and [picture_size_y_max]?", "Zoom", picture_size_y) as num
picture_size_x = min(CLAMP(desired_x, picture_size_x_min, picture_size_x_max), CAMERA_PICTURE_SIZE_HARD_LIMIT)
picture_size_y = min(CLAMP(desired_y, picture_size_y_min, picture_size_y_max), CAMERA_PICTURE_SIZE_HARD_LIMIT)
return TRUE
/obj/item/camera/attack(mob/living/carbon/human/M, mob/user)
return
/obj/item/camera/attackby(obj/item/I, mob/user, params)
if(istype(I, /obj/item/camera_film))
if(pictures_left)
to_chat(user, "<span class='notice'>[src] still has some film in it!</span>")
return
if(!user.temporarilyRemoveItemFromInventory(I))
return
to_chat(user, "<span class='notice'>You insert [I] into [src].</span>")
qdel(I)
pictures_left = pictures_max
return
if(istype(I, /obj/item/disk/holodisk))
if (!disk)
if(!user.transferItemToLoc(I, src))
to_chat(user, "<span class='warning'>[I] is stuck to your hand!</span>")
return TRUE
to_chat(user, "<span class='notice'>You slide [I] into the back of [src].</span>")
disk = I
else
to_chat(user, "<span class='warning'>There's already a disk inside [src].</span>")
return TRUE //no afterattack
..()
/obj/item/camera/examine(mob/user)
. = ..()
. += "It has [pictures_left] photos left."
//user can be atom or mob
/obj/item/camera/proc/can_target(atom/target, mob/user, prox_flag)
if(!on || blending || !pictures_left)
return FALSE
var/turf/T = get_turf(target)
if(!T)
return FALSE
if(istype(user))
if(isAI(user) && !GLOB.cameranet.checkTurfVis(T))
return FALSE
else if(user.client && !(get_turf(target) in get_hear(user.client.view, user)))
return FALSE
else if(!(get_turf(target) in get_hear(world.view, user)))
return FALSE
else //user is an atom
if(!(get_turf(target) in view(world.view, user)))
return FALSE
return TRUE
/obj/item/camera/afterattack(atom/target, mob/user, flag)
if (disk)
if(ismob(target))
if (disk.record)
QDEL_NULL(disk.record)
disk.record = new
var/mob/M = target
disk.record.caller_name = M.name
disk.record.set_caller_image(M)
else
to_chat(user, "<span class='warning'>Invalid holodisk target.</span>")
return
if(!can_target(target, user, flag))
return
on = FALSE
var/realcooldown = cooldown
var/mob/living/carbon/human/H = user
if (HAS_TRAIT(H, TRAIT_PHOTOGRAPHER))
realcooldown *= 0.5
addtimer(CALLBACK(src, .proc/cooldown), realcooldown)
icon_state = state_off
INVOKE_ASYNC(src, .proc/captureimage, target, user, flag, picture_size_x - 1, picture_size_y - 1)
/obj/item/camera/proc/cooldown()
UNTIL(!blending)
icon_state = state_on
on = TRUE
/obj/item/camera/proc/show_picture(mob/user, datum/picture/selection)
var/obj/item/photo/P = new(src, selection)
P.show(user)
to_chat(user, P.desc)
qdel(P)
/obj/item/camera/proc/captureimage(atom/target, mob/user, flag, size_x = 1, size_y = 1)
if(flash_enabled)
flash_lighting_fx(8, light_power, light_color)
blending = TRUE
var/turf/target_turf = get_turf(target)
if(!isturf(target_turf))
blending = FALSE
return FALSE
size_x = CLAMP(size_x, 0, CAMERA_PICTURE_SIZE_HARD_LIMIT)
size_y = CLAMP(size_y, 0, CAMERA_PICTURE_SIZE_HARD_LIMIT)
var/list/desc = list("This is a photo of an area of [size_x+1] meters by [size_y+1] meters.")
var/ai_user = isAI(user)
var/list/seen
var/list/viewlist = (user && user.client)? getviewsize(user.client.view) : getviewsize(world.view)
var/viewr = max(viewlist[1], viewlist[2]) + max(size_x, size_y)
var/viewc = user.client? user.client.eye : target
seen = get_hear(viewr, viewc)
var/list/turfs = list()
var/list/mobs = list()
var/blueprints = FALSE
var/clone_area = SSmapping.RequestBlockReservation(size_x * 2 + 1, size_y * 2 + 1)
for(var/turf/T in block(locate(target_turf.x - size_x, target_turf.y - size_y, target_turf.z), locate(target_turf.x + size_x, target_turf.y + size_y, target_turf.z)))
if((ai_user && GLOB.cameranet.checkTurfVis(T)) || (T in seen))
turfs += T
for(var/mob/M in T)
mobs += M
if(locate(/obj/item/areaeditor/blueprints) in T)
blueprints = TRUE
for(var/i in mobs)
var/mob/M = i
desc += M.get_photo_description(src)
var/psize_x = (size_x * 2 + 1) * world.icon_size
var/psize_y = (size_y * 2 + 1) * world.icon_size
var/get_icon = camera_get_icon(turfs, target_turf, psize_x, psize_y, clone_area, size_x, size_y, (size_x * 2 + 1), (size_y * 2 + 1))
qdel(clone_area)
var/icon/temp = icon('icons/effects/96x96.dmi',"")
temp.Blend("#000", ICON_OVERLAY)
temp.Scale(psize_x, psize_y)
temp.Blend(get_icon, ICON_OVERLAY)
var/datum/picture/P = new("picture", desc.Join(" "), temp, null, psize_x, psize_y, blueprints)
after_picture(user, P, flag)
blending = FALSE
/obj/item/camera/proc/after_picture(mob/user, datum/picture/picture, proximity_flag)
printpicture(user, picture)
/obj/item/camera/proc/printpicture(mob/user, datum/picture/picture) //Normal camera proc for creating photos
var/obj/item/photo/p = new(get_turf(src), picture)
if(in_range(src, user)) //needed because of TK
user.put_in_hands(p)
pictures_left--
to_chat(user, "<span class='notice'>[pictures_left] photos left.</span>")
var/customize = alert(user, "Do you want to customize the photo?", "Customization", "Yes", "No")
if(customize == "Yes")
var/name1 = stripped_input(user, "Set a name for this photo, or leave blank. 32 characters max.", "Name", max_length = 32)
var/desc1 = stripped_input(user, "Set a description to add to photo, or leave blank. 128 characters max.", "Caption", max_length = 128)
var/caption = stripped_input(user, "Set a caption for this photo, or leave blank. 256 characters max.", "Caption", max_length = 256)
if(name1)
picture.picture_name = name1
if(desc1)
picture.picture_desc = "[desc1] - [picture.picture_desc]"
if(caption)
picture.caption = caption
p.set_picture(picture, TRUE, TRUE)
if(CONFIG_GET(flag/picture_logging_camera))
picture.log_to_file()
+3 -3
View File
@@ -748,11 +748,11 @@
return FALSE
/obj/machinery/power/apc/AltClick(mob/user)
..()
. = ..()
if(!user.canUseTopic(src, !issilicon(user)) || !isturf(loc))
return
else
togglelock(user)
togglelock(user)
return TRUE
/obj/machinery/power/apc/proc/togglelock(mob/living/user)
if(obj_flags & EMAGGED)
@@ -222,10 +222,11 @@
spread = 2
/obj/item/gun/ballistic/shotgun/automatic/combat/compact/AltClick(mob/living/user)
. = ..()
if(!istype(user) || !user.canUseTopic(src, BE_CLOSE, ismonkey(user)))
return
toggle_stock(user)
. = ..()
return TRUE
/obj/item/gun/ballistic/shotgun/automatic/combat/compact/examine(mob/user)
. = ..()
@@ -286,8 +287,10 @@
to_chat(user, "You switch to tube A.")
/obj/item/gun/ballistic/shotgun/automatic/dual_tube/AltClick(mob/living/user)
. = ..()
if(!istype(user) || !user.canUseTopic(src, BE_CLOSE, ismonkey(user)))
return
pump()
return TRUE
// DOUBLE BARRELED SHOTGUN and IMPROVISED SHOTGUN are in revolver.dm
@@ -442,10 +442,11 @@
return final_list
/obj/machinery/chem_dispenser/AltClick(mob/living/user)
. = ..()
if(!istype(user) || !user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK))
return
replace_beaker(user)
return
return TRUE
/obj/machinery/chem_dispenser/drinks/Initialize()
. = ..()
@@ -29,10 +29,11 @@
icon_state = "mixer0b"
/obj/machinery/chem_heater/AltClick(mob/living/user)
. = ..()
if(!istype(user) || !user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK))
return
replace_beaker(user)
return
return TRUE
/obj/machinery/chem_heater/proc/replace_beaker(mob/living/user, obj/item/reagent_containers/new_beaker)
if(beaker)
@@ -237,10 +237,11 @@
return ..()
/obj/machinery/computer/pandemic/AltClick(mob/living/user)
. = ..()
if(!istype(user) || !user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK))
return
replace_beaker(user)
return
return TRUE
/obj/machinery/computer/pandemic/proc/replace_beaker(mob/living/user, obj/item/reagent_containers/new_beaker)
if(beaker)
@@ -344,8 +344,10 @@
return FALSE
/obj/item/hypospray/mkii/AltClick(mob/user)
. = ..()
if(vial)
vial.attack_self(user)
return TRUE
// Gunna allow this for now, still really don't approve - Pooj
/obj/item/hypospray/mkii/emag_act(mob/user)
@@ -88,13 +88,25 @@
if(reagents.total_volume && user.canUseTopic(src, BE_CLOSE))
to_chat(user, "<span class='notice'>You start squeezing the liquids out of \the [src]...</span>")
if(do_after(user, action_speed, TRUE, src))
to_chat(user, "<span class='notice'>You squeeze \the [src] dry.</span>")
var/atom/react_loc = get_turf(src)
if(ismob(react_loc))
react_loc = react_loc.loc
if(react_loc)
reagents.reaction(react_loc, TOUCH)
reagents.clear_reagents()
var/msg = "You squeeze \the [src]"
var/obj/item/target
if(Adjacent(user)) //Allows the user to drain the reagents into a beaker if adjacent (no telepathy).
for(var/obj/item/I in user.held_items)
if(I == src)
continue
if(I.is_open_container() && !I.reagents.holder_full())
target = I
break
if(!target)
msg += " dry"
reagents.reaction(get_turf(src), TOUCH)
reagents.clear_reagents()
else
msg += "'s liquids into \the [target]"
reagents.trans_to(target, reagents.total_volume)
to_chat(user, "<span class='notice'>[msg].</span>")
return TRUE
/obj/item/reagent_containers/rag/towel
name = "towel"
@@ -177,4 +189,4 @@
extinguish_efficiency = 5
action_speed = 15
damp_threshold = 0.8
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 20, "bio" = 20, "rad" = 20, "fire" = 50, "acid" = 50) //items don't provide armor to wearers unlike clothing yet.
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 20, "bio" = 20, "rad" = 20, "fire" = 50, "acid" = 50) //items don't provide armor to wearers unlike clothing yet.
@@ -14,6 +14,7 @@
return
if(disk)
eject()
return TRUE
/obj/item/nanite_hijacker/examine(mob/user)
. = ..()
@@ -35,6 +35,7 @@
update_icon()
else
to_chat(user, "<span class='warning'>Access denied.</span>")
return TRUE
/obj/item/nanite_remote/emag_act(mob/user)
if(obj_flags & EMAGGED)
@@ -276,14 +276,15 @@ GLOBAL_VAR_INIT(hhmysteryRoomNumber, 1337)
promptExit(user)
/turf/closed/indestructible/hoteldoor/AltClick(mob/user)
. = ..()
if(get_dist(get_turf(src), get_turf(user)) <= 1)
to_chat(user, "<span class='notice'>You peak through the door's bluespace peephole...</span>")
user.reset_perspective(parentSphere)
user.set_machine(src)
var/datum/action/peepholeCancel/PHC = new
user.overlay_fullscreen("remote_view", /obj/screen/fullscreen/impaired, 1)
PHC.Grant(user)
. = ..()
if(get_dist(get_turf(src), get_turf(user)) <= 1)
to_chat(user, "<span class='notice'>You peak through the door's bluespace peephole...</span>")
user.reset_perspective(parentSphere)
user.set_machine(src)
var/datum/action/peepholeCancel/PHC = new
user.overlay_fullscreen("remote_view", /obj/screen/fullscreen/impaired, 1)
PHC.Grant(user)
return TRUE
/turf/closed/indestructible/hoteldoor/check_eye(mob/user)
if(get_dist(get_turf(src), get_turf(user)) >= 2)
+79 -78
View File
@@ -1,78 +1,79 @@
/obj/vehicle/ridden
name = "ridden vehicle"
can_buckle = TRUE
max_buckled_mobs = 1
buckle_lying = FALSE
default_driver_move = FALSE
var/legs_required = 1
var/arms_required = 0 //why not?
/obj/vehicle/ridden/Initialize()
. = ..()
LoadComponent(/datum/component/riding)
/obj/vehicle/ridden/examine(mob/user)
. = ..()
if(key_type)
if(!inserted_key)
. += "<span class='notice'>Put a key inside it by clicking it with the key.</span>"
else
. += "<span class='notice'>Alt-click [src] to remove the key.</span>"
/obj/vehicle/ridden/generate_action_type(actiontype)
var/datum/action/vehicle/ridden/A = ..()
. = A
if(istype(A))
A.vehicle_ridden_target = src
/obj/vehicle/ridden/post_unbuckle_mob(mob/living/M)
remove_occupant(M)
return ..()
/obj/vehicle/ridden/post_buckle_mob(mob/living/M)
add_occupant(M)
if(M.get_num_legs() < legs_required)
to_chat(M, "<span class='warning'>You don't have enough legs to operate the pedals!</span>")
unbuckle_mob(M)
return ..()
/obj/vehicle/ridden/attackby(obj/item/I, mob/user, params)
if(key_type && !is_key(inserted_key) && is_key(I))
if(user.transferItemToLoc(I, src))
to_chat(user, "<span class='notice'>You insert \the [I] into \the [src].</span>")
if(inserted_key) //just in case there's an invalid key
inserted_key.forceMove(drop_location())
inserted_key = I
else
to_chat(user, "<span class='notice'>[I] seems to be stuck to your hand!</span>")
return
return ..()
/obj/vehicle/ridden/AltClick(mob/user)
if(inserted_key && user.canUseTopic(src, BE_CLOSE, ismonkey(user)))
if(!is_occupant(user))
to_chat(user, "<span class='notice'>You must be riding the [src] to remove [src]'s key!</span>")
return
to_chat(user, "<span class='notice'>You remove \the [inserted_key] from \the [src].</span>")
inserted_key.forceMove(drop_location())
user.put_in_hands(inserted_key)
inserted_key = null
return ..()
/obj/vehicle/ridden/driver_move(mob/user, direction)
if(key_type && !is_key(inserted_key))
to_chat(user, "<span class='warning'>[src] has no key inserted!</span>")
return FALSE
var/datum/component/riding/R = GetComponent(/datum/component/riding)
R.handle_ride(user, direction)
return ..()
/obj/vehicle/ridden/user_buckle_mob(mob/living/M, mob/user, check_loc = TRUE)
if(!in_range(user, src) || !in_range(M, src))
return FALSE
. = ..(M, user, FALSE)
/obj/vehicle/ridden/buckle_mob(mob/living/M, force = FALSE, check_loc = TRUE)
if(!force && occupant_amount() >= max_occupants)
return FALSE
return ..()
/obj/vehicle/ridden
name = "ridden vehicle"
can_buckle = TRUE
max_buckled_mobs = 1
buckle_lying = FALSE
default_driver_move = FALSE
var/legs_required = 1
var/arms_required = 0 //why not?
/obj/vehicle/ridden/Initialize()
. = ..()
LoadComponent(/datum/component/riding)
/obj/vehicle/ridden/examine(mob/user)
. = ..()
if(key_type)
if(!inserted_key)
. += "<span class='notice'>Put a key inside it by clicking it with the key.</span>"
else
. += "<span class='notice'>Alt-click [src] to remove the key.</span>"
/obj/vehicle/ridden/generate_action_type(actiontype)
var/datum/action/vehicle/ridden/A = ..()
. = A
if(istype(A))
A.vehicle_ridden_target = src
/obj/vehicle/ridden/post_unbuckle_mob(mob/living/M)
remove_occupant(M)
return ..()
/obj/vehicle/ridden/post_buckle_mob(mob/living/M)
add_occupant(M)
if(M.get_num_legs() < legs_required)
to_chat(M, "<span class='warning'>You don't have enough legs to operate the pedals!</span>")
unbuckle_mob(M)
return ..()
/obj/vehicle/ridden/attackby(obj/item/I, mob/user, params)
if(key_type && !is_key(inserted_key) && is_key(I))
if(user.transferItemToLoc(I, src))
to_chat(user, "<span class='notice'>You insert \the [I] into \the [src].</span>")
if(inserted_key) //just in case there's an invalid key
inserted_key.forceMove(drop_location())
inserted_key = I
else
to_chat(user, "<span class='notice'>[I] seems to be stuck to your hand!</span>")
return
return ..()
/obj/vehicle/ridden/AltClick(mob/user)
. = ..()
if(inserted_key && user.canUseTopic(src, BE_CLOSE, ismonkey(user)))
if(!is_occupant(user))
to_chat(user, "<span class='notice'>You must be riding the [src] to remove [src]'s key!</span>")
return
to_chat(user, "<span class='notice'>You remove \the [inserted_key] from \the [src].</span>")
inserted_key.forceMove(drop_location())
user.put_in_hands(inserted_key)
inserted_key = null
return TRUE
/obj/vehicle/ridden/driver_move(mob/user, direction)
if(key_type && !is_key(inserted_key))
to_chat(user, "<span class='warning'>[src] has no key inserted!</span>")
return FALSE
var/datum/component/riding/R = GetComponent(/datum/component/riding)
R.handle_ride(user, direction)
return ..()
/obj/vehicle/ridden/user_buckle_mob(mob/living/M, mob/user, check_loc = TRUE)
if(!in_range(user, src) || !in_range(M, src))
return FALSE
. = ..(M, user, FALSE)
/obj/vehicle/ridden/buckle_mob(mob/living/M, force = FALSE, check_loc = TRUE)
if(!force && occupant_amount() >= max_occupants)
return FALSE
return ..()
+2
View File
@@ -94,6 +94,7 @@
qdel(src)
/obj/vehicle/ridden/scooter/skateboard/AltClick(mob/user)
. = ..()
var/datum/component/riding/R = src.GetComponent(/datum/component/riding)
if (!adjusted_speed)
R.vehicle_move_delay = 0
@@ -103,6 +104,7 @@
R.vehicle_move_delay = 1
to_chat(user, "<span class='notice'>You adjust the wheels on [src] to make it go slower.</span>")
adjusted_speed = FALSE
return TRUE
//CONSTRUCTION
/obj/item/scooter_frame