mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2025-12-09 16:12:17 +00:00
396 lines
11 KiB
Plaintext
396 lines
11 KiB
Plaintext
// Magnetic attractor, creates variable magnetic fields and attraction.
|
|
// Can also be used to emit electron/proton beams to create a center of magnetism on another tile
|
|
|
|
// tl;dr: it's magnets lol
|
|
// This was created for firing ranges, but I suppose this could have other applications - Doohl
|
|
|
|
/obj/machinery/magnetic_module
|
|
icon = 'icons/obj/objects.dmi'
|
|
icon_state = "floor_magnet-f"
|
|
name = "Electromagnetic Generator"
|
|
desc = "A device that uses station power to create points of magnetic energy."
|
|
plane = PLATING_PLANE
|
|
anchored = TRUE
|
|
use_power = USE_POWER_IDLE
|
|
idle_power_usage = 50
|
|
|
|
var/freq = 1449 // radio frequency
|
|
var/electricity_level = 1 // intensity of the magnetic pull
|
|
var/magnetic_field = 1 // the range of magnetic attraction
|
|
var/code = 0 // frequency code, they should be different unless you have a group of magnets working together or something
|
|
var/turf/center // the center of magnetic attraction
|
|
var/on = 0
|
|
var/pulling = 0
|
|
|
|
// x, y modifiers to the center turf; (0, 0) is centered on the magnet, whereas (1, -1) is one tile right, one tile down
|
|
var/center_x = 0
|
|
var/center_y = 0
|
|
var/max_dist = 20 // absolute value of center_x,y cannot exceed this integer
|
|
|
|
/obj/machinery/magnetic_module/Initialize(mapload)
|
|
. = ..()
|
|
var/turf/T = loc
|
|
hide(!T.is_plating())
|
|
center = T
|
|
|
|
if(SSradio)
|
|
SSradio.add_object(src, freq, RADIO_MAGNETS)
|
|
|
|
magnetic_process()
|
|
|
|
// update the invisibility and icon
|
|
/obj/machinery/magnetic_module/hide(var/intact)
|
|
invisibility = intact ? INVISIBILITY_ABSTRACT : INVISIBILITY_NONE
|
|
update_icon()
|
|
|
|
// update the icon_state
|
|
/obj/machinery/magnetic_module/update_icon()
|
|
var/state="floor_magnet"
|
|
var/onstate=""
|
|
if(!on)
|
|
onstate="0"
|
|
|
|
if(invisibility)
|
|
icon_state = "[state][onstate]-f" // if invisible, set icon to faded version
|
|
// in case of being revealed by T-scanner
|
|
else
|
|
icon_state = "[state][onstate]"
|
|
|
|
/obj/machinery/magnetic_module/receive_signal(datum/signal/signal)
|
|
var/command = signal.data["command"]
|
|
var/modifier = signal.data["modifier"]
|
|
var/signal_code = signal.data["code"]
|
|
if(command && (signal_code == code))
|
|
|
|
Cmd(command, modifier)
|
|
|
|
/obj/machinery/magnetic_module/proc/Cmd(var/command, var/modifier)
|
|
if(command)
|
|
switch(command)
|
|
if("set-electriclevel")
|
|
if(modifier) electricity_level = modifier
|
|
if("set-magneticfield")
|
|
if(modifier) magnetic_field = modifier
|
|
|
|
if("add-elec")
|
|
electricity_level++
|
|
if(electricity_level > 12)
|
|
electricity_level = 12
|
|
if("sub-elec")
|
|
electricity_level--
|
|
if(electricity_level <= 0)
|
|
electricity_level = 1
|
|
if("add-mag")
|
|
magnetic_field++
|
|
if(magnetic_field > 4)
|
|
magnetic_field = 4
|
|
if("sub-mag")
|
|
magnetic_field--
|
|
if(magnetic_field <= 0)
|
|
magnetic_field = 1
|
|
|
|
if("set-x")
|
|
if(modifier) center_x = modifier
|
|
if("set-y")
|
|
if(modifier) center_y = modifier
|
|
|
|
if("N") // NORTH
|
|
center_y++
|
|
if("S") // SOUTH
|
|
center_y--
|
|
if("E") // EAST
|
|
center_x++
|
|
if("W") // WEST
|
|
center_x--
|
|
if("C") // CENTER
|
|
center_x = 0
|
|
center_y = 0
|
|
if("R") // RANDOM
|
|
center_x = rand(-max_dist, max_dist)
|
|
center_y = rand(-max_dist, max_dist)
|
|
|
|
if("set-code")
|
|
if(modifier) code = modifier
|
|
if("toggle-power")
|
|
on = !on
|
|
|
|
if(on)
|
|
spawn()
|
|
magnetic_process()
|
|
|
|
/obj/machinery/magnetic_module/process()
|
|
if(stat & NOPOWER)
|
|
on = 0
|
|
|
|
// Sanity checks:
|
|
if(electricity_level <= 0)
|
|
electricity_level = 1
|
|
if(magnetic_field <= 0)
|
|
magnetic_field = 1
|
|
|
|
// Limitations:
|
|
if(abs(center_x) > max_dist)
|
|
center_x = max_dist
|
|
if(abs(center_y) > max_dist)
|
|
center_y = max_dist
|
|
if(magnetic_field > 4)
|
|
magnetic_field = 4
|
|
if(electricity_level > 12)
|
|
electricity_level = 12
|
|
|
|
// Update power usage:
|
|
if(on)
|
|
update_use_power(USE_POWER_ACTIVE)
|
|
update_active_power_usage(electricity_level * 15)
|
|
else
|
|
update_use_power(USE_POWER_OFF)
|
|
|
|
// Overload conditions:
|
|
/* // Eeeehhh kinda stupid
|
|
if(on)
|
|
if(electricity_level > 11)
|
|
if(prob(electricity_level))
|
|
explosion(loc, 0, 1, 2, 3) // ooo dat shit EXPLODES son
|
|
spawn(2)
|
|
qdel(src)
|
|
*/
|
|
|
|
update_icon()
|
|
|
|
/obj/machinery/magnetic_module/proc/magnetic_process(var/called_back) // proc that actually does the pulling
|
|
if(called_back)
|
|
pulling = 0
|
|
|
|
if(pulling)
|
|
return
|
|
|
|
if(on)
|
|
pulling = 1
|
|
center = locate(x+center_x, y+center_y, z)
|
|
if(center)
|
|
for(var/obj/M in orange(magnetic_field, center))
|
|
if(!M.anchored && !(M.flags & NOCONDUCT))
|
|
step_towards(M, center)
|
|
|
|
for(var/mob/living/silicon/S in orange(magnetic_field, center))
|
|
if(isAI(S)) continue
|
|
step_towards(S, center)
|
|
|
|
use_power(electricity_level * 5)
|
|
addtimer(CALLBACK(src, PROC_REF(magnetic_process), TRUE), 13 - electricity_level, TIMER_DELETE_ME)
|
|
|
|
pulling = 0
|
|
|
|
/obj/machinery/magnetic_module/Destroy()
|
|
if(SSradio)
|
|
SSradio.remove_object(src, freq)
|
|
. = ..()
|
|
|
|
/obj/machinery/magnetic_controller
|
|
name = "Magnetic Control Console"
|
|
icon = 'icons/obj/airlock_machines.dmi' // uses an airlock machine icon, THINK GREEN HELP THE ENVIRONMENT - RECYCLING!
|
|
icon_state = "airlock_control_standby"
|
|
density = TRUE
|
|
anchored = TRUE
|
|
use_power = USE_POWER_IDLE
|
|
idle_power_usage = 45
|
|
var/frequency = AMAG_ELE_FREQ
|
|
var/code = 0
|
|
var/list/magnets = list()
|
|
var/title = "Magnetic Control Console"
|
|
var/autolink = 0 // if set to 1, can't probe for other magnets!
|
|
|
|
var/pathpos = 1 // position in the path
|
|
var/path = "NULL" // text path of the magnet
|
|
var/speed = 1 // lowest = 1, highest = 10
|
|
var/list/rpath = list() // real path of the magnet, used in iterator
|
|
|
|
var/moving = 0 // 1 if scheduled to loop
|
|
var/looping = 0 // 1 if looping
|
|
|
|
var/datum/radio_frequency/radio_connection
|
|
|
|
|
|
/obj/machinery/magnetic_controller/Initialize(mapload)
|
|
. = ..()
|
|
|
|
if(autolink)
|
|
for(var/obj/machinery/magnetic_module/M in GLOB.machines)
|
|
if(M.freq == frequency && M.code == code)
|
|
magnets.Add(M)
|
|
|
|
|
|
if(SSradio)
|
|
radio_connection = SSradio.add_object(src, frequency, RADIO_MAGNETS)
|
|
|
|
|
|
if(path) // check for default path
|
|
filter_path() // renders rpath
|
|
|
|
|
|
/obj/machinery/magnetic_controller/process()
|
|
if(magnets.len == 0 && autolink)
|
|
for(var/obj/machinery/magnetic_module/M in GLOB.machines)
|
|
if(M.freq == frequency && M.code == code)
|
|
magnets.Add(M)
|
|
|
|
|
|
/obj/machinery/magnetic_controller/attack_ai(mob/user as mob)
|
|
return attack_hand(user)
|
|
|
|
/obj/machinery/magnetic_controller/attack_hand(mob/user as mob)
|
|
if(stat & (BROKEN|NOPOWER))
|
|
return
|
|
user.set_machine(src)
|
|
var/dat = ""
|
|
if(!autolink)
|
|
dat += {"
|
|
Frequency: <a href='byond://?src=\ref[src];operation=setfreq'>[frequency]</a><br>
|
|
Code: <a href='byond://?src=\ref[src];operation=setfreq'>[code]</a><br>
|
|
<a href='byond://?src=\ref[src];operation=probe'>Probe Generators</a><br>
|
|
"}
|
|
|
|
if(magnets.len >= 1)
|
|
|
|
dat += "Magnets confirmed: <br>"
|
|
var/i = 0
|
|
for(var/obj/machinery/magnetic_module/M in magnets)
|
|
i++
|
|
dat += " < \[[i]\] (<a href='byond://?src=\ref[src];radio-op=togglepower'>[M.on ? "On":"Off"]</a>) | Electricity level: <a href='byond://?src=\ref[src];radio-op=minuselec'>-</a> [M.electricity_level] <a href='byond://?src=\ref[src];radio-op=pluselec'>+</a>; Magnetic field: <a href='byond://?src=\ref[src];radio-op=minusmag'>-</a> [M.magnetic_field] <a href='byond://?src=\ref[src];radio-op=plusmag'>+</a><br>"
|
|
|
|
dat += "<br>Speed: <a href='byond://?src=\ref[src];operation=minusspeed'>-</a> [speed] <a href='byond://?src=\ref[src];operation=plusspeed'>+</a><br>"
|
|
dat += "Path: {<a href='byond://?src=\ref[src];operation=setpath'>[path]</a>}<br>"
|
|
dat += "Moving: <a href='byond://?src=\ref[src];operation=togglemoving'>[moving ? "Enabled":"Disabled"]</a>"
|
|
|
|
|
|
var/datum/browser/popup = new(user, "magnet", "Magnetic Control Console", 400, 500)
|
|
popup.set_content(dat)
|
|
popup.open()
|
|
|
|
/obj/machinery/magnetic_controller/Topic(href, href_list)
|
|
if(stat & (BROKEN|NOPOWER))
|
|
return
|
|
usr.set_machine(src)
|
|
add_fingerprint(usr)
|
|
|
|
if(href_list["radio-op"])
|
|
|
|
// Prepare signal beforehand, because this is a radio operation
|
|
var/datum/signal/signal = new
|
|
signal.transmission_method = TRANSMISSION_RADIO // radio transmission
|
|
signal.source = src
|
|
signal.frequency = frequency
|
|
signal.data["code"] = code
|
|
|
|
// Apply any necessary commands
|
|
switch(href_list["radio-op"])
|
|
if("togglepower")
|
|
signal.data["command"] = "toggle-power"
|
|
|
|
if("minuselec")
|
|
signal.data["command"] = "sub-elec"
|
|
if("pluselec")
|
|
signal.data["command"] = "add-elec"
|
|
|
|
if("minusmag")
|
|
signal.data["command"] = "sub-mag"
|
|
if("plusmag")
|
|
signal.data["command"] = "add-mag"
|
|
|
|
|
|
// Broadcast the signal
|
|
|
|
radio_connection.post_signal(src, signal, radio_filter = RADIO_MAGNETS)
|
|
|
|
if(href_list["operation"])
|
|
switch(href_list["operation"])
|
|
if("plusspeed")
|
|
speed ++
|
|
if(speed > 10)
|
|
speed = 10
|
|
if("minusspeed")
|
|
speed --
|
|
if(speed <= 0)
|
|
speed = 1
|
|
if("setpath")
|
|
var/newpath = tgui_input_text(usr, "Please define a new path!",,path, MAX_MESSAGE_LEN)
|
|
if(newpath && newpath != "")
|
|
moving = 0 // stop moving
|
|
path = newpath
|
|
pathpos = 1 // reset position
|
|
filter_path() // renders rpath
|
|
|
|
if("togglemoving")
|
|
moving = !moving
|
|
if(moving)
|
|
spawn() MagnetMove()
|
|
|
|
|
|
updateUsrDialog(usr)
|
|
|
|
/obj/machinery/magnetic_controller/proc/MagnetMove()
|
|
if(looping) return
|
|
|
|
while(moving && rpath.len >= 1)
|
|
|
|
if(stat & (BROKEN|NOPOWER))
|
|
break
|
|
|
|
looping = 1
|
|
|
|
// Prepare the radio signal
|
|
var/datum/signal/signal = new
|
|
signal.transmission_method = TRANSMISSION_RADIO // radio transmission
|
|
signal.source = src
|
|
signal.frequency = frequency
|
|
signal.data["code"] = code
|
|
|
|
if(pathpos > rpath.len) // if the position is greater than the length, we just loop through the list!
|
|
pathpos = 1
|
|
|
|
var/nextmove = uppertext(rpath[pathpos]) // makes it un-case-sensitive
|
|
|
|
if(!(nextmove in list("N","S","E","W","C","R")))
|
|
// N, S, E, W are directional
|
|
// C is center
|
|
// R is random (in magnetic field's bounds)
|
|
qdel(signal)
|
|
break // break the loop if the character located is invalid
|
|
|
|
signal.data["command"] = nextmove
|
|
|
|
|
|
pathpos++ // increase iterator
|
|
|
|
// Broadcast the signal
|
|
spawn()
|
|
radio_connection.post_signal(src, signal, radio_filter = RADIO_MAGNETS)
|
|
|
|
if(speed == 10)
|
|
sleep(1)
|
|
else
|
|
sleep(12-speed)
|
|
|
|
looping = 0
|
|
|
|
|
|
/obj/machinery/magnetic_controller/proc/filter_path()
|
|
// Generates the rpath variable using the path string, think of this as "string2list"
|
|
// Doesn't use params2list() because of the akward way it stacks entities
|
|
rpath = list() // clear rpath
|
|
var/maximum_character = min(50, length(path)) // chooses the maximum length of the iterator. 50 max length
|
|
|
|
for(var/i=1, i<=maximum_character, i++) // iterates through all characters in path
|
|
|
|
var/nextchar = copytext(path, i, i+1) // find next character
|
|
|
|
if(!(nextchar in list(";", "&", "*", " "))) // if char is a separator, ignore
|
|
rpath += copytext(path, i, i+1) // else, add to list
|
|
|
|
// there doesn't HAVE to be separators but it makes paths syntatically visible
|
|
|
|
/obj/machinery/magnetic_controller/Destroy()
|
|
if(SSradio)
|
|
SSradio.remove_object(src, frequency)
|
|
. = ..()
|