mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2025-12-25 01:31:58 +00:00
332 lines
8.2 KiB
Plaintext
332 lines
8.2 KiB
Plaintext
// Wire datums. Created by Giacomand.
|
|
// Was created to replace a horrible case of copy and pasted code with no care for maintability.
|
|
// Goodbye Door wires, Cyborg wires, Vending Machine wires, Autolathe wires
|
|
// Protolathe wires, APC wires and Camera wires!
|
|
|
|
#define MAX_FLAG 65535
|
|
|
|
GLOBAL_LIST_EMPTY(same_wires)
|
|
// 12 colours, if you're adding more than 12 wires then add more colours here
|
|
GLOBAL_LIST_INIT(wireColours, list("red", "blue", "green", "black", "orange", "brown", "gold", "gray", "cyan", "navy", "purple", "pink"))
|
|
|
|
/datum/wires
|
|
|
|
var/random = 0 // Will the wires be different for every single instance.
|
|
var/atom/holder = null // The holder
|
|
var/holder_type = null // The holder type; used to make sure that the holder is the correct type.
|
|
var/wire_count = 0 // Max is 16
|
|
var/wires_status = 0 // BITFLAG OF WIRES
|
|
|
|
var/list/wires = list()
|
|
var/list/signallers = list()
|
|
|
|
var/table_options = " align='center'"
|
|
var/row_options1 = " width='80px'"
|
|
var/row_options2 = " width='260px'"
|
|
var/window_x = 370
|
|
var/window_y = 470
|
|
|
|
/datum/wires/New(atom/holder)
|
|
..()
|
|
src.holder = holder
|
|
if(!istype(holder, holder_type))
|
|
CRASH("Our holder is null/the wrong type!")
|
|
|
|
// Generate new wires
|
|
if(random)
|
|
GenerateWires()
|
|
// Get the same wires
|
|
else
|
|
// We don't have any wires to copy yet, generate some and then copy it.
|
|
if(!GLOB.same_wires[holder_type])
|
|
GenerateWires()
|
|
GLOB.same_wires[holder_type] = src.wires.Copy()
|
|
else
|
|
var/list/wires = GLOB.same_wires[holder_type]
|
|
src.wires = wires // Reference the wires list.
|
|
|
|
/datum/wires/Destroy()
|
|
holder = null
|
|
return ..()
|
|
|
|
/datum/wires/proc/GenerateWires()
|
|
var/list/colours_to_pick = GLOB.wireColours.Copy() // Get a copy, not a reference.
|
|
var/list/indexes_to_pick = list()
|
|
//Generate our indexes
|
|
for(var/i = 1; i < MAX_FLAG && i < (1 << wire_count); i += i)
|
|
indexes_to_pick += i
|
|
colours_to_pick.len = wire_count // Downsize it to our specifications.
|
|
|
|
while(colours_to_pick.len && indexes_to_pick.len)
|
|
// Pick and remove a colour
|
|
var/colour = pick_n_take(colours_to_pick)
|
|
|
|
// Pick and remove an index
|
|
var/index = pick_n_take(indexes_to_pick)
|
|
|
|
src.wires[colour] = index
|
|
//wires = shuffle(wires)
|
|
|
|
/datum/wires/proc/get_status()
|
|
return list()
|
|
|
|
/datum/wires/proc/Interact(mob/user)
|
|
if(user && istype(user) && holder && CanUse(user))
|
|
ui_interact(user)
|
|
|
|
/datum/wires/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
|
|
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, force_open)
|
|
if(!ui)
|
|
ui = new(user, src, ui_key, "wires.tmpl", holder.name, window_x, window_y)
|
|
ui.open()
|
|
|
|
/datum/wires/ui_data(mob/user, ui_key = "main", datum/topic_state/state = GLOB.physical_state)
|
|
var/data[0]
|
|
var/list/replace_colours = null
|
|
if(ishuman(user))
|
|
var/mob/living/carbon/human/H = user
|
|
var/obj/item/organ/internal/eyes/eyes = H.get_int_organ(/obj/item/organ/internal/eyes)
|
|
if(eyes && (COLOURBLIND in H.mutations))
|
|
replace_colours = eyes.replace_colours
|
|
|
|
|
|
var/list/W[0]
|
|
for(var/colour in wires)
|
|
var/new_colour = colour
|
|
var/colour_name = colour
|
|
if(colour in replace_colours)
|
|
new_colour = replace_colours[colour]
|
|
if(new_colour in LIST_REPLACE_RENAME)
|
|
colour_name = LIST_REPLACE_RENAME[new_colour]
|
|
else
|
|
colour_name = new_colour
|
|
else
|
|
new_colour = colour
|
|
colour_name = new_colour
|
|
W[++W.len] = list("colour_name" = capitalize(colour_name), "seen_colour" = capitalize(new_colour),"colour" = capitalize(colour), "cut" = IsColourCut(colour), "index" = can_see_wire_index(user) ? GetWireName(GetIndex(colour)) : null, "attached" = IsAttached(colour))
|
|
|
|
if(W.len > 0)
|
|
data["wires"] = W
|
|
|
|
var/list/status = get_status()
|
|
if(replace_colours)
|
|
var/i
|
|
for(i=1, i<=status.len, i++)
|
|
for(var/colour in replace_colours)
|
|
var/new_colour = replace_colours[colour]
|
|
if(new_colour in LIST_REPLACE_RENAME)
|
|
new_colour = LIST_REPLACE_RENAME[new_colour]
|
|
if(findtext(status[i],colour))
|
|
status[i] = replacetext(status[i],colour,new_colour)
|
|
break
|
|
data["status_len"] = status.len
|
|
data["status"] = status
|
|
|
|
return data
|
|
|
|
/datum/wires/nano_host()
|
|
return holder
|
|
|
|
/datum/wires/proc/can_see_wire_index(mob/user)
|
|
if(user.can_admin_interact())
|
|
return TRUE
|
|
else if(istype(user.get_active_hand(), /obj/item/multitool))
|
|
var/obj/item/multitool/M = user.get_active_hand()
|
|
if(M.shows_wire_information)
|
|
return TRUE
|
|
|
|
return FALSE
|
|
|
|
/datum/wires/Topic(href, href_list)
|
|
if(..())
|
|
return 1
|
|
var/mob/L = usr
|
|
if(CanUse(L) && href_list["action"])
|
|
var/obj/item/I = L.get_active_hand()
|
|
var/colour = lowertext(href_list["wire"])
|
|
holder.add_hiddenprint(L)
|
|
switch(href_list["action"])
|
|
if("cut") // Toggles the cut/mend status
|
|
if(istype(I, /obj/item/wirecutters) || L.can_admin_interact())
|
|
if(istype(I))
|
|
playsound(holder, I.usesound, 20, 1)
|
|
CutWireColour(colour)
|
|
else
|
|
to_chat(L, "<span class='error'>You need wirecutters!</span>")
|
|
if("pulse")
|
|
if(istype(I, /obj/item/multitool) || L.can_admin_interact())
|
|
playsound(holder, 'sound/weapons/empty.ogg', 20, 1)
|
|
PulseColour(colour)
|
|
else
|
|
to_chat(L, "<span class='error'>You need a multitool!</span>")
|
|
if("attach")
|
|
if(IsAttached(colour))
|
|
var/obj/item/O = Detach(colour)
|
|
if(O)
|
|
L.put_in_hands(O)
|
|
else
|
|
if(istype(I, /obj/item/assembly/signaler))
|
|
if(L.drop_item())
|
|
Attach(colour, I)
|
|
else
|
|
to_chat(L, "<span class='warning'>[L.get_active_hand()] is stuck to your hand!</span>")
|
|
else
|
|
to_chat(L, "<span class='error'>You need a remote signaller!</span>")
|
|
|
|
SSnanoui.update_uis(src)
|
|
return 1
|
|
|
|
//
|
|
// Overridable Procs
|
|
//
|
|
|
|
// Called when wires cut/mended.
|
|
/datum/wires/proc/UpdateCut(index, mended)
|
|
if(holder)
|
|
SSnanoui.update_uis(holder)
|
|
|
|
// Called when wire pulsed. Add code here.
|
|
/datum/wires/proc/UpdatePulsed(index)
|
|
if(holder)
|
|
SSnanoui.update_uis(holder)
|
|
|
|
/datum/wires/proc/CanUse(mob/L)
|
|
return 1
|
|
|
|
/datum/wires/CanUseTopic(mob/user, datum/topic_state/state)
|
|
if(!CanUse(user))
|
|
return STATUS_CLOSE
|
|
return ..()
|
|
|
|
// Example of use:
|
|
/*
|
|
|
|
#define NAME_WIRE_BOLTED 1
|
|
#define NAME_WIRE_SHOCKED 2
|
|
#define NAME_WIRE_SAFETY 4
|
|
#define NAME_WIRE_POWER 8
|
|
|
|
/datum/wires/door/UpdateCut(var/index, var/mended)
|
|
var/obj/machinery/door/airlock/A = holder
|
|
switch(index)
|
|
if(NAME_WIRE_BOLTED)
|
|
if(!mended)
|
|
A.bolt()
|
|
if(NAME_WIRE_SHOCKED)
|
|
A.shock()
|
|
if(NAME_WIRE_SAFETY)
|
|
A.safety()
|
|
|
|
*/
|
|
|
|
|
|
//
|
|
// Helper Procs
|
|
//
|
|
|
|
/datum/wires/proc/PulseColour(colour)
|
|
PulseIndex(GetIndex(colour))
|
|
|
|
/datum/wires/proc/PulseIndex(index)
|
|
if(IsIndexCut(index))
|
|
return
|
|
UpdatePulsed(index)
|
|
|
|
/datum/wires/proc/GetIndex(colour)
|
|
if(wires[colour])
|
|
var/index = wires[colour]
|
|
return index
|
|
else
|
|
CRASH("[colour] is not a key in wires.")
|
|
|
|
/datum/wires/proc/GetWireName(index)
|
|
return
|
|
|
|
//
|
|
// Is Index/Colour Cut procs
|
|
//
|
|
|
|
/datum/wires/proc/IsColourCut(colour)
|
|
var/index = GetIndex(colour)
|
|
return IsIndexCut(index)
|
|
|
|
/datum/wires/proc/IsIndexCut(index)
|
|
return (index & wires_status)
|
|
|
|
//
|
|
// Signaller Procs
|
|
//
|
|
|
|
/datum/wires/proc/IsAttached(colour)
|
|
if(signallers[colour])
|
|
return 1
|
|
return 0
|
|
|
|
/datum/wires/proc/GetAttached(colour)
|
|
if(signallers[colour])
|
|
return signallers[colour]
|
|
return null
|
|
|
|
/datum/wires/proc/Attach(colour, obj/item/assembly/signaler/S)
|
|
if(colour && S)
|
|
if(!IsAttached(colour))
|
|
signallers[colour] = S
|
|
S.loc = holder
|
|
S.connected = src
|
|
return S
|
|
|
|
/datum/wires/proc/Detach(colour)
|
|
if(colour)
|
|
var/obj/item/assembly/signaler/S = GetAttached(colour)
|
|
if(S)
|
|
signallers -= colour
|
|
S.connected = null
|
|
S.loc = holder.loc
|
|
return S
|
|
|
|
|
|
/datum/wires/proc/Pulse(obj/item/assembly/signaler/S)
|
|
|
|
for(var/colour in signallers)
|
|
if(S == signallers[colour])
|
|
PulseColour(colour)
|
|
break
|
|
|
|
|
|
//
|
|
// Cut Wire Colour/Index procs
|
|
//
|
|
|
|
/datum/wires/proc/CutWireColour(colour)
|
|
var/index = GetIndex(colour)
|
|
CutWireIndex(index)
|
|
|
|
/datum/wires/proc/CutWireIndex(index)
|
|
if(IsIndexCut(index))
|
|
wires_status &= ~index
|
|
UpdateCut(index, 1)
|
|
else
|
|
wires_status |= index
|
|
UpdateCut(index, 0)
|
|
|
|
/datum/wires/proc/RandomCut()
|
|
var/r = rand(1, wires.len)
|
|
CutWireIndex(r)
|
|
|
|
/datum/wires/proc/CutAll()
|
|
for(var/i = 1; i < MAX_FLAG && i < (1 << wire_count); i += i)
|
|
CutWireIndex(i)
|
|
|
|
/datum/wires/proc/IsAllCut()
|
|
if(wires_status == (1 << wire_count) - 1)
|
|
return 1
|
|
return 0
|
|
|
|
//
|
|
//Shuffle and Mend
|
|
//
|
|
|
|
/datum/wires/proc/Shuffle()
|
|
wires_status = 0
|
|
GenerateWires()
|