Files
vgstation13/code/game/machinery/magnet.dm
ShiftyRail 8021aaf539 Working version of radio controller fixes (#26914)
* Revert "Revert "Fixes oldcoder stuff with radio controllers (#26845)" (#26868)"

This reverts commit cb1613403b.

* Fixes the bag

* No bug
2020-06-21 05:39:36 +02:00

414 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."
level = 1 // underfloor
anchored = 1
use_power = 1
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/New()
..()
var/turf/T = loc
hide(T.intact)
center = T
if (ticker && ticker.current_state == GAME_STATE_PLAYING)
initialize()
/obj/machinery/magnetic_module/initialize()
if(radio_controller)
radio_controller.add_object(src, freq, RADIO_MAGNETS)
spawn()
magnetic_process()
// update the invisibility and icon
/obj/machinery/magnetic_module/hide(var/intact)
invisibility = intact ? 101 : 0
updateicon()
// update the icon_state
/obj/machinery/magnetic_module/proc/updateicon()
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)
use_power = 2
active_power_usage = electricity_level*15
else
use_power = 0
// 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)
del(src)
*/
updateicon()
/obj/machinery/magnetic_module/proc/magnetic_process() // proc that actually does the pulling
if(pulling)
return
while(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.is_conductor()))
step_towards(M, center)
for(var/mob/living/silicon/S in orange(magnetic_field, center))
if(istype(S, /mob/living/silicon/ai))
continue
step_towards(S, center)
use_power(electricity_level * 5)
sleep(13 - electricity_level)
pulling = 0
/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 = 1
anchored = 1.0
use_power = 1
idle_power_usage = 45
var/frequency = 1449
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/New()
..()
if(autolink)
for(var/obj/machinery/magnetic_module/M in machines)
if(M.freq == frequency && M.code == code)
magnets.Add(M)
if (ticker && ticker.current_state == GAME_STATE_PLAYING)
initialize()
/obj/machinery/magnetic_controller/initialize()
if(radio_controller)
radio_connection = radio_controller.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 machines)
if(M.freq == frequency && M.code == code)
magnets.Add(M)
/obj/machinery/magnetic_controller/attack_ai(mob/user as mob)
src.add_hiddenprint(user)
return src.attack_hand(user)
/obj/machinery/magnetic_controller/attack_hand(mob/user as mob)
if(stat & (BROKEN|NOPOWER))
return
user.set_machine(src)
var/dat = "<B>Magnetic Control Console</B><BR><BR>"
if(!autolink)
dat += {"
Frequency: <a href='?src=\ref[src];operation=setfreq'>[frequency]</a><br>
Code: <a href='?src=\ref[src];operation=setfreq'>[code]</a><br>
<a href='?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 += "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;< \[[i]\] (<a href='?src=\ref[src];radio-op=togglepower'>[M.on ? "On":"Off"]</a>) | Electricity level: <a href='?src=\ref[src];radio-op=minuselec'>-</a> [M.electricity_level] <a href='?src=\ref[src];radio-op=pluselec'>+</a>; Magnetic field: <a href='?src=\ref[src];radio-op=minusmag'>-</a> [M.magnetic_field] <a href='?src=\ref[src];radio-op=plusmag'>+</a><br>"
dat += {"<br>Speed: <a href='?src=\ref[src];operation=minusspeed'>-</a> [speed] <a href='?src=\ref[src];operation=plusspeed'>+</a><br>
Path: {<a href='?src=\ref[src];operation=setpath'>[path]</a>}<br>
Moving: <a href='?src=\ref[src];operation=togglemoving'>[moving ? "Enabled":"Disabled"]</a>"}
user << browse(dat, "window=magnet;size=400x500")
onclose(user, "magnet")
/obj/machinery/magnetic_controller/Topic(href, href_list)
if(..())
return 1
usr.set_machine(src)
src.add_fingerprint(usr)
if(href_list["radio-op"])
// Prepare signal beforehand, because this is a radio operation
var/datum/signal/signal = getFromPool(/datum/signal)
signal.transmission_method = 1 // 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, filter = RADIO_MAGNETS)
spawn(1)
updateUsrDialog() // pretty sure this increases responsiveness
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 = copytext(sanitize(input(usr, "Please define a new path!",,path) as text|null),1,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()
/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 = getFromPool(/datum/signal)
signal.transmission_method = 1 // 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)
signal = null
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, 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