Merge pull request #12036 from kevinz000/electrochromatic_windows
Electrochromatic (dim-on-demand) windows
This commit is contained in:
@@ -42,6 +42,13 @@ SUBSYSTEM_DEF(mapping)
|
||||
|
||||
var/stat_map_name = "Loading..."
|
||||
|
||||
/// Lookup list for random generated IDs.
|
||||
var/list/random_generated_ids_by_original = list()
|
||||
/// next id for separating obfuscated ids.
|
||||
var/obfuscation_next_id = 1
|
||||
/// "secret" key
|
||||
var/obfuscation_secret
|
||||
|
||||
//dlete dis once #39770 is resolved
|
||||
/datum/controller/subsystem/mapping/proc/HACK_LoadMapConfig()
|
||||
if(!config)
|
||||
@@ -52,6 +59,10 @@ SUBSYSTEM_DEF(mapping)
|
||||
#endif
|
||||
stat_map_name = config.map_name
|
||||
|
||||
/datum/controller/subsystem/mapping/PreInit()
|
||||
if(!obfuscation_secret)
|
||||
obfuscation_secret = md5(GUID()) //HAH! Guess this!
|
||||
|
||||
/datum/controller/subsystem/mapping/Initialize(timeofday)
|
||||
HACK_LoadMapConfig()
|
||||
if(initialized)
|
||||
@@ -568,3 +579,15 @@ GLOBAL_LIST_EMPTY(the_station_areas)
|
||||
LM.load()
|
||||
if(GLOB.stationroom_landmarks.len)
|
||||
seedStation() //I'm sure we can trust everyone not to insert a 1x1 rooms which loads a landmark which loads a landmark which loads a la...
|
||||
|
||||
/**
|
||||
* Generates an obfuscated but constant id for an original id for cases where you don't want players codediving for an id.
|
||||
* WARNING: MAKE SURE PLAYERS ARE NOT ABLE TO ACCESS THIS. To save performance, it's just secret + an incrementing number. Very guessable if you know what the secret is.
|
||||
*/
|
||||
/datum/controller/subsystem/mapping/proc/get_obfuscated_id(original, id_type = "GENERAL")
|
||||
if(!original)
|
||||
return //no.
|
||||
var/key = "[original]%[id_type]"
|
||||
if(random_generated_ids_by_original[key])
|
||||
return random_generated_ids_by_original[key]
|
||||
. = random_generated_ids_by_original[key] = "[obfuscation_secret]%[obfuscation_next_id++]"
|
||||
|
||||
@@ -260,6 +260,15 @@
|
||||
subcategory = CAT_TOOL
|
||||
category = CAT_MISC
|
||||
|
||||
/datum/crafting_recipe/electrochromatic_kit
|
||||
name = "Electrochromatic Kit"
|
||||
result = /obj/item/electronics/electrochromatic_kit
|
||||
reqs = list(/obj/item/stack/sheet/metal = 1,
|
||||
/obj/item/stack/cable_coil = 1)
|
||||
time = 5
|
||||
subcategory = CAT_TOOL
|
||||
category = CAT_MISC
|
||||
|
||||
////////////
|
||||
//Vehicles//
|
||||
////////////
|
||||
|
||||
@@ -16,6 +16,9 @@
|
||||
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF
|
||||
|
||||
/obj/machinery/button/Initialize(mapload, ndir = 0, built = 0)
|
||||
if(istext(id) && mapload)
|
||||
if(copytext(id, 1, 2) == "!")
|
||||
id = SSmapping.get_obfuscated_id(id)
|
||||
. = ..()
|
||||
if(built)
|
||||
setDir(ndir)
|
||||
@@ -260,6 +263,11 @@
|
||||
req_access = list()
|
||||
id = 1
|
||||
|
||||
/obj/machinery/button/electrochromatic
|
||||
name = "window dim control"
|
||||
desc = "Controls linked electrochromatic windows"
|
||||
device_type = /obj/item/assembly/control/electrochromatic
|
||||
|
||||
/obj/item/wallframe/button
|
||||
name = "button frame"
|
||||
desc = "Used for building buttons."
|
||||
|
||||
@@ -726,13 +726,12 @@
|
||||
to_chat(usr, "<span class='warning'>A color that dark on an object like this? Surely not...</span>")
|
||||
return FALSE
|
||||
|
||||
target.add_atom_colour(paint_color, WASHABLE_COLOUR_PRIORITY)
|
||||
|
||||
if(istype(target, /obj/structure/window))
|
||||
if(color_hex2num(paint_color) < 255)
|
||||
target.set_opacity(255)
|
||||
else
|
||||
target.set_opacity(initial(target.opacity))
|
||||
var/obj/structure/window/W = target
|
||||
W.spraycan_paint(paint_color)
|
||||
else
|
||||
target.add_atom_colour(paint_color, WASHABLE_COLOUR_PRIORITY)
|
||||
|
||||
. = use_charges(user, 2)
|
||||
var/fraction = min(1, . / reagents.maximum_volume)
|
||||
|
||||
14
code/game/objects/items/devices/electrochromatic_kit.dm
Normal file
14
code/game/objects/items/devices/electrochromatic_kit.dm
Normal file
@@ -0,0 +1,14 @@
|
||||
/obj/item/electronics/electrochromatic_kit
|
||||
name = "electrochromatic kit"
|
||||
desc = "A kit for upgrading a window into an electrochromatic one."
|
||||
/// Electrochromatic ID
|
||||
var/id
|
||||
|
||||
/obj/item/electronics/electrochromatic_kit/attack_self(mob/user)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
var/new_id = input(user, "Set this kit's electrochromatic ID", "Set ID", id) as text|null
|
||||
if(isnull(new_id))
|
||||
return
|
||||
id = new_id
|
||||
@@ -1,3 +1,18 @@
|
||||
#define NOT_ELECTROCHROMATIC 0
|
||||
#define ELECTROCHROMATIC_OFF 1
|
||||
#define ELECTROCHROMATIC_DIMMED 2
|
||||
|
||||
GLOBAL_LIST_EMPTY(electrochromatic_window_lookup)
|
||||
|
||||
/proc/do_electrochromatic_toggle(new_status, id)
|
||||
var/list/windows = GLOB.electrochromatic_window_lookup["[id]"]
|
||||
if(!windows)
|
||||
return
|
||||
var/obj/structure/window/W //define outside for performance because obviously this matters.
|
||||
for(var/i in windows)
|
||||
W = i
|
||||
new_status? W.electrochromatic_dim() : W.electrochromatic_off()
|
||||
|
||||
/obj/structure/window
|
||||
name = "window"
|
||||
desc = "A window."
|
||||
@@ -28,8 +43,15 @@
|
||||
rad_insulation = RAD_VERY_LIGHT_INSULATION
|
||||
rad_flags = RAD_PROTECT_CONTENTS
|
||||
|
||||
/// Electrochromatic status
|
||||
var/electrochromatic_status = NOT_ELECTROCHROMATIC
|
||||
/// Electrochromatic ID. Set the first character to ! to replace with a SSmapping generated pseudorandom obfuscated ID for mapping purposes.
|
||||
var/electrochromatic_id
|
||||
|
||||
/obj/structure/window/examine(mob/user)
|
||||
. = ..()
|
||||
if(electrochromatic_status != NOT_ELECTROCHROMATIC)
|
||||
. += "<span class='notice'>The window has electrochromatic circuitry on it.</span>"
|
||||
if(reinf)
|
||||
if(anchored && state == WINDOW_SCREWED_TO_FRAME)
|
||||
. += "<span class='notice'>The window is <b>screwed</b> to the frame.</span>"
|
||||
@@ -52,6 +74,10 @@
|
||||
if(reinf && anchored)
|
||||
state = WINDOW_SCREWED_TO_FRAME
|
||||
|
||||
if(mapload && electrochromatic_id)
|
||||
if(copytext(electrochromatic_id, 1, 2) == "!")
|
||||
electrochromatic_id = SSmapping.get_obfuscated_id(electrochromatic_id)
|
||||
|
||||
ini_dir = dir
|
||||
air_update_turf(1)
|
||||
|
||||
@@ -62,6 +88,12 @@
|
||||
real_explosion_block = explosion_block
|
||||
explosion_block = EXPLOSION_BLOCK_PROC
|
||||
|
||||
if(electrochromatic_status != NOT_ELECTROCHROMATIC)
|
||||
var/old = electrochromatic_status
|
||||
make_electrochromatic()
|
||||
if(old == ELECTROCHROMATIC_DIMMED)
|
||||
electrochromatic_dim()
|
||||
|
||||
/obj/structure/window/ComponentInitialize()
|
||||
. = ..()
|
||||
AddComponent(/datum/component/simple_rotation,ROTATION_ALTCLICK | ROTATION_CLOCKWISE | ROTATION_COUNTERCLOCKWISE | ROTATION_VERBS ,null,CALLBACK(src, .proc/can_be_rotated),CALLBACK(src,.proc/after_rotation))
|
||||
@@ -177,6 +209,24 @@
|
||||
to_chat(user, "<span class='warning'>[src] is already in good condition!</span>")
|
||||
return
|
||||
|
||||
if(istype(I, /obj/item/electronics/electrochromatic_kit) && user.a_intent == INTENT_HELP)
|
||||
var/obj/item/electronics/electrochromatic_kit/K = I
|
||||
if(electrochromatic_status != NOT_ELECTROCHROMATIC)
|
||||
to_chat(user, "<span class='warning'>[src] is already electrochromatic!</span>")
|
||||
return
|
||||
if(anchored)
|
||||
to_chat(user, "<span class='warning'>[src] must not be attached to the floor!</span>")
|
||||
return
|
||||
if(!K.id)
|
||||
to_chat(user, "<span class='warning'>[K] has no ID set!</span>")
|
||||
return
|
||||
if(!user.temporarilyRemoveItemFromInventory(K))
|
||||
to_chat(user, "<span class='warning'>[K] is stuck to your hand!</span>")
|
||||
return
|
||||
user.visible_message("<span class='notice'>[user] upgrades [src] with [I].</span>", "<span class='notice'>You upgrade [src] with [I].</span>")
|
||||
make_electrochromatic(K.id)
|
||||
qdel(K)
|
||||
|
||||
if(!(flags_1&NODECONSTRUCT_1))
|
||||
if(istype(I, /obj/item/screwdriver))
|
||||
I.play_tool_sound(src, 75)
|
||||
@@ -224,6 +274,91 @@
|
||||
air_update_turf(TRUE)
|
||||
update_nearby_icons()
|
||||
|
||||
/obj/structure/window/proc/spraycan_paint(paint_color)
|
||||
if(color_hex2num(paint_color) < 255)
|
||||
set_opacity(255)
|
||||
else
|
||||
set_opacity(initial(opacity))
|
||||
add_atom_colour(paint_color, WASHABLE_COLOUR_PRIORITY)
|
||||
|
||||
/obj/structure/window/proc/electrochromatic_dim()
|
||||
if(electrochromatic_status == ELECTROCHROMATIC_DIMMED)
|
||||
return
|
||||
electrochromatic_status = ELECTROCHROMATIC_DIMMED
|
||||
animate(src, color = "#222222", time = 2)
|
||||
set_opacity(TRUE)
|
||||
|
||||
/obj/structure/window/proc/electrochromatic_off()
|
||||
if(electrochromatic_status == ELECTROCHROMATIC_OFF)
|
||||
return
|
||||
electrochromatic_status = ELECTROCHROMATIC_OFF
|
||||
var/current = color
|
||||
update_atom_colour()
|
||||
var/newcolor = color
|
||||
color = current
|
||||
animate(src, color = newcolor, time = 2)
|
||||
|
||||
/obj/structure/window/proc/remove_electrochromatic()
|
||||
electrochromatic_off()
|
||||
electrochromatic_status = NOT_ELECTROCHROMATIC
|
||||
if(!electrochromatic_id)
|
||||
return
|
||||
var/list/L = GLOB.electrochromatic_window_lookup["[electrochromatic_id]"]
|
||||
if(L)
|
||||
L -= src
|
||||
electrochromatic_id = null
|
||||
|
||||
/obj/structure/window/vv_edit_var(var_name, var_value)
|
||||
var/check_status
|
||||
if(var_name == NAMEOF(src, electrochromatic_id))
|
||||
if(electrochromatic_id && GLOB.electrochromatic_window_lookup["[electrochromatic_id]"])
|
||||
GLOB.electrochromatic_window_lookup[electrochromatic_id] -= src
|
||||
if(var_name == NAMEOF(src, electrochromatic_status))
|
||||
check_status = TRUE
|
||||
. = ..() //do this first incase it runtimes.
|
||||
if(var_name == NAMEOF(src, electrochromatic_id))
|
||||
if((electrochromatic_status != NOT_ELECTROCHROMATIC) && electrochromatic_id)
|
||||
LAZYINITLIST(GLOB.electrochromatic_window_lookup[electrochromatic_id])
|
||||
GLOB.electrochromatic_window_lookup[electrochromatic_id] += src
|
||||
if(check_status)
|
||||
if(electrochromatic_status == NOT_ELECTROCHROMATIC)
|
||||
remove_electrochromatic()
|
||||
return
|
||||
else if(electrochromatic_status == ELECTROCHROMATIC_OFF)
|
||||
if(!electrochromatic_id)
|
||||
return
|
||||
else
|
||||
make_electrochromatic()
|
||||
electrochromatic_off()
|
||||
return
|
||||
else if(electrochromatic_status == ELECTROCHROMATIC_DIMMED)
|
||||
if(!electrochromatic_id)
|
||||
return
|
||||
else
|
||||
make_electrochromatic()
|
||||
electrochromatic_dim()
|
||||
return
|
||||
else
|
||||
remove_electrochromatic()
|
||||
|
||||
/obj/structure/window/proc/make_electrochromatic(new_id = electrochromatic_id)
|
||||
remove_electrochromatic()
|
||||
if(!new_id)
|
||||
CRASH("Attempted to make electrochromatic with null ID.")
|
||||
electrochromatic_id = new_id
|
||||
electrochromatic_status = ELECTROCHROMATIC_OFF
|
||||
LAZYINITLIST(GLOB.electrochromatic_window_lookup["[electrochromatic_id]"])
|
||||
GLOB.electrochromatic_window_lookup[electrochromatic_id] |= src
|
||||
|
||||
/obj/structure/window/update_atom_colour()
|
||||
if((electrochromatic_status != ELECTROCHROMATIC_OFF) && (electrochromatic_status != ELECTROCHROMATIC_DIMMED))
|
||||
return FALSE
|
||||
. = ..()
|
||||
if(color && (color_hex2num(color) < 255))
|
||||
set_opacity(255)
|
||||
else
|
||||
set_opacity(FALSE)
|
||||
|
||||
/obj/structure/window/proc/check_state(checked_state)
|
||||
if(state == checked_state)
|
||||
return TRUE
|
||||
@@ -263,7 +398,6 @@
|
||||
if(BURN)
|
||||
playsound(src, 'sound/items/Welder.ogg', 100, 1)
|
||||
|
||||
|
||||
/obj/structure/window/deconstruct(disassembled = TRUE)
|
||||
if(QDELETED(src))
|
||||
return
|
||||
@@ -272,6 +406,9 @@
|
||||
if(!(flags_1 & NODECONSTRUCT_1))
|
||||
for(var/obj/item/shard/debris in spawnDebris(drop_location()))
|
||||
transfer_fingerprints_to(debris) // transfer fingerprints to shards only
|
||||
if(electrochromatic_status != NOT_ELECTROCHROMATIC) //eh fine keep your kit.
|
||||
new /obj/item/electronics/electrochromatic_kit(drop_location())
|
||||
// Intentionally not setting the ID so you can't decon one to know all of the IDs.
|
||||
qdel(src)
|
||||
update_nearby_icons()
|
||||
|
||||
@@ -315,9 +452,9 @@
|
||||
density = FALSE
|
||||
air_update_turf(1)
|
||||
update_nearby_icons()
|
||||
remove_electrochromatic()
|
||||
return ..()
|
||||
|
||||
|
||||
/obj/structure/window/Move()
|
||||
var/turf/T = loc
|
||||
. = ..()
|
||||
@@ -731,7 +868,6 @@
|
||||
set_opacity(TRUE)
|
||||
queue_smooth(src)
|
||||
|
||||
|
||||
/obj/structure/window/paperframe/attackby(obj/item/W, mob/user)
|
||||
if(W.get_temperature())
|
||||
fire_act(W.get_temperature())
|
||||
@@ -749,3 +885,7 @@
|
||||
return
|
||||
..()
|
||||
update_icon()
|
||||
|
||||
#undef NOT_ELECTROCHROMATIC
|
||||
#undef ELECTROCHROMATIC_OFF
|
||||
#undef ELECTROCHROMATIC_DIMMED
|
||||
|
||||
@@ -3,14 +3,35 @@
|
||||
desc = "A small electronic device able to control a blast door remotely."
|
||||
icon_state = "control"
|
||||
attachable = TRUE
|
||||
var/id = null
|
||||
var/can_change_id = 0
|
||||
/// Our ID. Make the first character ! if you want to obfuscate it as a mapper via randomization.
|
||||
var/id
|
||||
/// Can the ID be changed if used in hand?
|
||||
var/can_change_id = FALSE
|
||||
/// Show ID?
|
||||
var/show_id = TRUE
|
||||
var/cooldown = FALSE //Door cooldowns
|
||||
|
||||
/obj/item/assembly/control/Initialize(mapload)
|
||||
if(mapload && id)
|
||||
if(copytext(id, 1, 2) == "!")
|
||||
id = SSmapping.get_obfuscated_id(id)
|
||||
return ..()
|
||||
|
||||
/obj/item/assembly/control/examine(mob/user)
|
||||
. = ..()
|
||||
if(id)
|
||||
if(id && show_id)
|
||||
. += "<span class='notice'>Its channel ID is '[id]'.</span>"
|
||||
if(can_change_id)
|
||||
. += "<span class='notice'>Use in hand to change ID.</span>"
|
||||
|
||||
/obj/item/assembly/control/attack_self(mob/living/user)
|
||||
. = ..()
|
||||
if(!can_change_id)
|
||||
return
|
||||
var/new_id
|
||||
new_id = input(user, "Set ID", "Set ID", show_id? id : null) as text|null
|
||||
if(!isnull(new_id)) //0/"" is considered !, so check null instead of just !.
|
||||
id = new_id
|
||||
|
||||
/obj/item/assembly/control/activate()
|
||||
cooldown = TRUE
|
||||
@@ -22,7 +43,6 @@
|
||||
INVOKE_ASYNC(M, openclose ? /obj/machinery/door/poddoor.proc/open : /obj/machinery/door/poddoor.proc/close)
|
||||
addtimer(VARSET_CALLBACK(src, cooldown, FALSE), 10)
|
||||
|
||||
|
||||
/obj/item/assembly/control/airlock
|
||||
name = "airlock controller"
|
||||
desc = "A small electronic device able to control an airlock remotely."
|
||||
@@ -123,7 +143,6 @@
|
||||
|
||||
addtimer(VARSET_CALLBACK(src, cooldown, FALSE), 50)
|
||||
|
||||
|
||||
/obj/item/assembly/control/crematorium
|
||||
name = "crematorium controller"
|
||||
desc = "An evil-looking remote controller for a crematorium."
|
||||
@@ -135,3 +154,14 @@
|
||||
C.cremate(usr)
|
||||
|
||||
addtimer(VARSET_CALLBACK(src, cooldown, FALSE), 50)
|
||||
|
||||
/obj/item/assembly/control/electrochromatic
|
||||
name = "electrochromatic window controller"
|
||||
desc = "Toggles linked electrochromatic windows."
|
||||
can_change_id = TRUE
|
||||
/// Stores our status to prevent windows from desyncing.
|
||||
var/on = FALSE
|
||||
|
||||
/obj/item/assembly/control/electrochromatic/activate()
|
||||
on = !on
|
||||
do_electrochromatic_toggle(on, id)
|
||||
|
||||
@@ -74,3 +74,11 @@
|
||||
materials = list(/datum/material/glass = 20)
|
||||
build_path = /obj/item/stock_parts/cell/emergency_light
|
||||
category = list("initial", "Electronics")
|
||||
|
||||
/datum/design/electrochromatic_control
|
||||
name = "Electrochromatic Control Circuit"
|
||||
id = "electrochromatic_control_circuit"
|
||||
build_type = AUTOLATHE
|
||||
materials = list(/datum/material/iron = 100, /datum/material/glass = 100)
|
||||
build_path = /obj/item/assembly/control/electrochromatic
|
||||
category = list("initial", "Electronics")
|
||||
|
||||
Reference in New Issue
Block a user