Merge pull request #11451 from Loganbacca/wireless

Wireless controller for machinery connections
This commit is contained in:
PsiOmegaDelta
2015-11-27 07:59:59 +01:00
16 changed files with 699 additions and 47 deletions
+4
View File
@@ -49,6 +49,7 @@
#include "code\_helpers\mobs.dm"
#include "code\_helpers\names.dm"
#include "code\_helpers\sanitize_values.dm"
#include "code\_helpers\spawn_sync.dm"
#include "code\_helpers\text.dm"
#include "code\_helpers\time.dm"
#include "code\_helpers\turfs.dm"
@@ -141,6 +142,7 @@
#include "code\controllers\Processes\ticker.dm"
#include "code\controllers\Processes\turf.dm"
#include "code\controllers\Processes\vote.dm"
#include "code\controllers\Processes\wireless.dm"
#include "code\controllers\ProcessScheduler\core\_stubs.dm"
#include "code\controllers\ProcessScheduler\core\process.dm"
#include "code\controllers\ProcessScheduler\core\processScheduler.dm"
@@ -1833,6 +1835,8 @@
#include "code\modules\virus2\helpers.dm"
#include "code\modules\virus2\isolator.dm"
#include "code\modules\virus2\items_devices.dm"
#include "code\modules\wireless\devices.dm"
#include "code\modules\wireless\interfaces.dm"
#include "code\modules\xgm\xgm_gas_data.dm"
#include "code\modules\xgm\xgm_gas_mixture.dm"
#include "code\ZAS\_docs.dm"
+86
View File
@@ -0,0 +1,86 @@
//-------------------------------
/*
Spawn sync helper
Helps syncronize spawn()ing multiple processes in loops.
Example for using this:
//Create new spawn_sync datum
var/datum/spawn_sync/sync = new()
for(var/obj/O in list)
//Call start_worker(), passing it first the object, then a string of the name of the proc you want called, then
// any and all arguments you want passed to the proc.
sync.start_worker(O, "do_something", arg1, arg2)
//Finally call wait_until_done()
sync.wait_until_done()
//Once all the workers have completed, or the failsafe has triggered, the code will continue. By default the
// failsafe is roughly 10 seconds (100 checks).
*/
//-------------------------------
/datum/spawn_sync
var/count = 1
var/failsafe = 100 //how many checks before the failsafe triggers and the helper stops waiting
//Opens a thread counter
/datum/spawn_sync/proc/open()
count++
//Closes a thread counter
/datum/spawn_sync/proc/close()
count--
//Finalizes the spawn sync by removing the original starting count
/datum/spawn_sync/proc/finalize()
close()
//Resets the counter if you want to utilize the same datum multiple times
// Optional: pass the number of checks you want for the failsafe
/datum/spawn_sync/proc/reset(var/safety = 100)
count = 1
failsafe = safety
//Check if all threads have returned
// Returns 0 if not all threads have completed
// Returns 1 if all threads have completed
/datum/spawn_sync/proc/check()
safety_check()
return count > 0 ? 1 : 0
//Failsafe in case something breaks horribly
/datum/spawn_sync/proc/safety_check()
failsafe--
if(failsafe < 1)
count = 0
//Set failsafe check count in case you need more time for the workers to return
/datum/spawn_sync/proc/set_failsafe(var/safety)
failsafe = safety
/datum/spawn_sync/proc/start_worker()
//Extract the thread run proc and it's arguments from the variadic args list.
ASSERT(args.len > 0)
var/obj = args[1]
var/thread_proc = args[2]
//dispatch a new thread
open()
spawn()
//Utilise try/catch keywords here so the code continues even if an error occurs.
try
call(obj, thread_proc)(arglist(args.Copy(3)))
catch(var/exception/e)
error("[e] on [e.file]:[e.line]")
close()
/datum/spawn_sync/proc/wait_until_done()
finalize()
//Create a while loop to check if the sync is complete yet, it will return once all the spawn threads have
// completed, or the failsafe has expired.
while(check())
//Add a sleep call to delay each check.
sleep(1)
+71
View File
@@ -0,0 +1,71 @@
//-------------------------------
/*
Wireless controller
Used for connecting devices to each other (i.e. machinery, doors, emitters, etc.)
Unlike the radio controller, the wireless controller does not pass communications between devices. Once the devices
have been connected they call each others procs directly, they do not use the wireless controller to communicate.
See code\modules\wireless\interfaces.dm for details of how to connect devices.
*/
//-------------------------------
var/datum/controller/process/wireless/wirelessProcess
/datum/controller/process/wireless
var/list/receiver_list
var/list/pending_connections
var/list/retry_connections
var/list/failed_connections
/datum/controller/process/wireless/setup()
name = "wireless"
schedule_interval = 50
pending_connections = new()
retry_connections = new()
failed_connections = new()
receiver_list = new()
wirelessProcess = src
/datum/controller/process/wireless/proc/add_device(var/datum/wifi/receiver/R)
if(receiver_list)
receiver_list |= R
else
receiver_list = new()
receiver_list |= R
/datum/controller/process/wireless/proc/remove_device(var/datum/wifi/receiver/R)
if(receiver_list)
receiver_list -= R
/datum/controller/process/wireless/proc/add_request(var/datum/connection_request/C)
if(pending_connections)
pending_connections += C
else
pending_connections = new()
pending_connections += C
/datum/controller/process/wireless/doWork()
//process any connection requests waiting to be retried
if(retry_connections.len > 0)
//any that fail are moved into the failed connections list
process_queue(retry_connections, failed_connections)
//process any pending connection requests
if(pending_connections.len > 0)
//any that fail are moved to the retry queue
process_queue(pending_connections, retry_connections)
/datum/controller/process/wireless/proc/process_queue(var/list/process_conections, var/list/unsuccesful_connections)
for(var/datum/connection_request/C in process_conections)
var/target_found = 0
for(var/datum/wifi/receiver/R in receiver_list)
if(R.id == C.id)
var/datum/wifi/sender/S = C.source
S.connect_device(R)
R.connect_device(S)
target_found = 1
process_conections -= C
if(!target_found)
unsuccesful_connections += C
SCHECK
+4 -1
View File
@@ -25,7 +25,7 @@
usr.client.debug_variables(antag)
message_admins("Admin [key_name_admin(usr)] is debugging the [antag.role_text] template.")
/client/proc/debug_controller(controller in list("Master","Ticker","Ticker Process","Air","Jobs","Sun","Radio","Supply","Shuttles","Emergency Shuttle","Configuration","pAI", "Cameras", "Transfer Controller", "Gas Data","Event","Plants","Alarm","Nano","Chemistry"))
/client/proc/debug_controller(controller in list("Master","Ticker","Ticker Process","Air","Jobs","Sun","Radio","Supply","Shuttles","Emergency Shuttle","Configuration","pAI", "Cameras", "Transfer Controller", "Gas Data","Event","Plants","Alarm","Nano","Chemistry","Wireless"))
set category = "Debug"
set name = "Debug Controller"
set desc = "Debug the various periodic loop controllers for the game (be careful!)"
@@ -92,5 +92,8 @@
if("Chemistry")
debug_variables(chemistryProcess)
feedback_add_details("admin_verb", "DChem")
if("Wireless")
debug_variables(wirelessProcess)
feedback_add_details("admin_verb", "DWifi")
message_admins("Admin [key_name_admin(usr)] is debugging the [controller] controller.")
return
+115 -2
View File
@@ -5,14 +5,127 @@
desc = "A remote control switch for something."
var/id = null
var/active = 0
var/operating = 0
anchored = 1.0
use_power = 1
idle_power_usage = 2
active_power_usage = 4
var/_wifi_id
var/datum/wifi/sender/button/wifi_sender
/obj/machinery/button/initialize()
..()
update_icon()
if(_wifi_id)
wifi_sender = new(_wifi_id, src)
/obj/machinery/button/Destroy()
qdel(wifi_sender)
wifi_sender = null
return..()
/obj/machinery/button/attack_ai(mob/user as mob)
return src.attack_hand(user)
return attack_hand(user)
/obj/machinery/button/attackby(obj/item/weapon/W, mob/user as mob)
return src.attack_hand(user)
return attack_hand(user)
/obj/machinery/button/attack_hand(mob/living/user)
..()
activate(user)
/obj/machinery/button/proc/activate(mob/living/user)
if(operating || !istype(wifi_sender))
return
operating = 1
active = 1
use_power(5)
update_icon()
wifi_sender.activate(user)
sleep(10)
active = 0
update_icon()
operating = 0
/obj/machinery/button/update_icon()
if(active)
icon_state = "launcheract"
else
icon_state = "launcherbtt"
//alternate button with the same functionality, except has a lightswitch sprite instead
/obj/machinery/button/alternate
icon = 'icons/obj/power.dmi'
icon_state = "light0"
/obj/machinery/button/alternate/update_icon()
icon_state = "light[active]"
//Toggle button with two states (on and off) and calls seperate procs for each state
/obj/machinery/button/toggle/activate(mob/living/user)
if(operating || !istype(wifi_sender))
return
operating = 1
active = !active
use_power(5)
if(active)
wifi_sender.activate(user)
else
wifi_sender.deactivate(user)
update_icon()
operating = 0
/obj/machinery/button/toggle/alternate
icon = 'icons/obj/power.dmi'
icon_state = "light0"
/obj/machinery/button/toggle/alternate/update_icon()
icon_state = "light[active]"
//-------------------------------
// Mass Driver Button
// Passes the activate call to a mass driver wifi sender
//-------------------------------
/obj/machinery/button/mass_driver
var/datum/wifi/sender/mass_driver/sender
/obj/machinery/button/mass_driver/initialize()
..()
sender = new(_wifi_id, src)
/obj/machinery/button/mass_driver/activate(mob/living/user)
if(active || !istype(wifi_sender))
return
active = 1
use_power(5)
update_icon()
sender.cycle()
active = 0
update_icon()
//-------------------------------
// Door Button
//-------------------------------
/obj/machinery/button/toggle/door
var/datum/wifi/sender/door/sender
/obj/machinery/button/toggle/door/initialize()
..()
sender = new(_wifi_id, src)
/obj/machinery/button/toggle/door/activate(mob/living/user)
if(operating || !istype(sender))
return
operating = 1
active = !active
use_power(5)
update_icon()
if(!active)
sender.open()
else
sender.close()
operating = 0
+9
View File
@@ -34,6 +34,9 @@
var/open_sound_powered = 'sound/machines/airlock.ogg'
var/open_sound_unpowered = 'sound/machines/airlock_creaking.ogg'
var/_wifi_id
var/datum/wifi/receiver/button/door/wifi_receiver
/obj/machinery/door/airlock/attack_generic(var/mob/user, var/damage)
if(stat & (BROKEN|NOPOWER))
if(damage >= 10)
@@ -1037,9 +1040,15 @@ About the new airlock wires panel:
src.closeOther = A
break
//wireless connection
if(_wifi_id)
wifi_receiver = new(_wifi_id, src)
/obj/machinery/door/airlock/Destroy()
qdel(wires)
wires = null
qdel(wifi_receiver)
wifi_receiver = null
return ..()
// Most doors will never be deconstructed over the course of a round,
+14 -1
View File
@@ -28,6 +28,19 @@
//turning this off prevents awkward zone geometry in places like medbay lobby, for example.
block_air_zones = 0
var/_wifi_id
var/datum/wifi/receiver/button/door/wifi_receiver
/obj/machinery/door/blast/initialize()
..()
if(_wifi_id)
wifi_receiver = new(_wifi_id, src)
/obj/machinery/door/airlock/Destroy()
qdel(wifi_receiver)
wifi_receiver = null
return ..()
// Proc: Bumped()
// Parameters: 1 (AM - Atom that tried to walk through this object)
// Description: If we are open returns zero, otherwise returns result of parent function.
@@ -144,7 +157,7 @@
if(stat & BROKEN)
stat &= ~BROKEN
/obj/machinery/door/blast/CanPass(atom/movable/mover, turf/target, height=0, air_group=0)
if(air_group) return 1
return ..()
+12
View File
@@ -15,6 +15,8 @@
use_power = 1
idle_power_usage = 2
flags = PROXMOVE
var/_wifi_id
var/datum/wifi/receiver/button/flasher/wifi_receiver
/obj/machinery/flasher/portable //Portable version of the flasher. Only flashes when anchored
name = "portable flasher"
@@ -25,6 +27,16 @@
base_state = "pflash"
density = 1
/obj/machinery/flasher/initialize()
..()
if(_wifi_id)
wifi_receiver = new(_wifi_id, src)
/obj/machinery/flasher/Destroy()
qdel(wifi_receiver)
wifi_receiver = null
return ..()
/obj/machinery/flasher/power_change()
..()
if ( !(stat & NOPOWER) )
+12
View File
@@ -12,6 +12,18 @@
var/lit = 0
var/id = null
var/on_icon = "sign_on"
var/_wifi_id
var/datum/wifi/receiver/button/holosign/wifi_receiver
/obj/machinery/holosign/initialize()
..()
if(_wifi_id)
wifi_receiver = new(_wifi_id, src)
/obj/machinery/holosign/Destroy()
qdel(wifi_receiver)
wifi_receiver = null
return ..()
/obj/machinery/holosign/proc/toggle()
if (stat & (BROKEN|NOPOWER))
+66 -42
View File
@@ -4,11 +4,32 @@
icon = 'icons/obj/stationobjs.dmi'
icon_state = "igniter1"
var/id = null
var/on = 1.0
anchored = 1.0
var/on = 0
anchored = 1
use_power = 1
idle_power_usage = 2
active_power_usage = 4
var/_wifi_id
var/datum/wifi/receiver/button/igniter/wifi_receiver
/obj/machinery/igniter/New()
..()
update_icon()
/obj/machinery/igniter/initialize()
..()
update_icon()
if(_wifi_id)
wifi_receiver = new(_wifi_id, src)
/obj/machinery/igniter/update_icon()
..()
icon_state = "igniter[on]"
/obj/machinery/igniter/Destroy()
qdel(wifi_receiver)
wifi_receiver = null
return ..()
/obj/machinery/igniter/attack_ai(mob/user as mob)
return src.attack_hand(user)
@@ -17,29 +38,25 @@
if(..())
return
add_fingerprint(user)
use_power(50)
src.on = !( src.on )
src.icon_state = text("igniter[]", src.on)
ignite()
return
/obj/machinery/igniter/process() //ugh why is this even in process()?
if (src.on && !(stat & NOPOWER) )
if (on && powered() )
var/turf/location = src.loc
if (isturf(location))
location.hotspot_expose(1000,500,1)
return 1
/obj/machinery/igniter/New()
..()
icon_state = "igniter[on]"
/obj/machinery/igniter/power_change()
..()
if(!( stat & NOPOWER) )
icon_state = "igniter[src.on]"
else
icon_state = "igniter0"
update_icon()
/obj/machinery/igniter/proc/ignite()
use_power(50)
on = !on
update_icon()
// Wall mounted remote-control igniter.
@@ -56,50 +73,59 @@
use_power = 1
idle_power_usage = 2
active_power_usage = 4
var/_wifi_id
var/datum/wifi/receiver/button/sparker/wifi_receiver
/obj/machinery/sparker/New()
/obj/machinery/sparker/initialize()
..()
if(_wifi_id)
wifi_receiver = new(_wifi_id, src)
/obj/machinery/sparker/Destroy()
qdel(wifi_receiver)
wifi_receiver = null
return ..()
/obj/machinery/sparker/update_icon()
..()
if(disable)
icon_state = "migniter-d"
else if(powered())
icon_state = "migniter"
// src.sd_SetLuminosity(2)
else
icon_state = "migniter-p"
// src.sd_SetLuminosity(0)
/obj/machinery/sparker/power_change()
..()
if ( !(stat & NOPOWER) && disable == 0 )
icon_state = "[base_state]"
// src.sd_SetLuminosity(2)
else
icon_state = "[base_state]-p"
// src.sd_SetLuminosity(0)
update_icon()
/obj/machinery/sparker/attackby(obj/item/weapon/W as obj, mob/user as mob)
if (istype(W, /obj/item/weapon/screwdriver))
add_fingerprint(user)
src.disable = !src.disable
if (src.disable)
disable = !disable
if(disable)
user.visible_message("<span class='warning'>[user] has disabled the [src]!</span>", "<span class='warning'>You disable the connection to the [src].</span>")
icon_state = "[base_state]-d"
if (!src.disable)
else if(!disable)
user.visible_message("<span class='warning'>[user] has reconnected the [src]!</span>", "<span class='warning'>You fix the connection to the [src].</span>")
if(src.powered())
icon_state = "[base_state]"
else
icon_state = "[base_state]-p"
update_icon()
/obj/machinery/sparker/attack_ai()
if (src.anchored)
return src.ignite()
if (anchored)
return ignite()
else
return
/obj/machinery/sparker/proc/ignite()
if (!(powered()))
if (!powered())
return
if ((src.disable) || (src.last_spark && world.time < src.last_spark + 50))
if (disable || (last_spark && world.time < last_spark + 50))
return
flick("[base_state]-spark", src)
flick("migniter-spark", src)
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
s.set_up(2, 1, src)
s.start()
@@ -132,15 +158,13 @@
icon_state = "launcheract"
for(var/obj/machinery/sparker/M in machines)
if (M.id == src.id)
if (M.id == id)
spawn( 0 )
M.ignite()
for(var/obj/machinery/igniter/M in machines)
if(M.id == src.id)
use_power(50)
M.on = !( M.on )
M.icon_state = text("igniter[]", M.on)
if(M.id == id)
M.ignite()
sleep(50)
+11
View File
@@ -14,7 +14,18 @@
var/code = 1.0
var/id = 1.0
var/drive_range = 50 //this is mostly irrelevant since current mass drivers throw into space, but you could make a lower-range mass driver for interstation transport or something I guess.
var/_wifi_id
var/datum/wifi/receiver/button/mass_driver/wifi_receiver
/obj/machinery/mass_driver/initialize()
..()
if(_wifi_id)
wifi_receiver = new(_wifi_id, src)
/obj/machinery/mass_driver/Destroy()
qdel(wifi_receiver)
wifi_receiver = null
return ..()
/obj/machinery/mass_driver/proc/drive(amount)
if(stat & (BROKEN|NOPOWER))
+10
View File
@@ -186,11 +186,21 @@
var/cremating = 0
var/id = 1
var/locked = 0
var/_wifi_id
var/datum/wifi/receiver/button/crematorium/wifi_receiver
/obj/structure/crematorium/initialize()
..()
if(_wifi_id)
wifi_receiver = new(_wifi_id, src)
/obj/structure/crematorium/Destroy()
if(connected)
qdel(connected)
connected = null
if(wifi_receiver)
qdel(wifi_receiver)
wifi_receiver = null
return ..()
/obj/structure/crematorium/proc/update()
+7 -1
View File
@@ -24,6 +24,8 @@
var/state = 0
var/locked = 0
var/_wifi_id
var/datum/wifi/receiver/button/emitter/wifi_receiver
/obj/machinery/power/emitter/verb/rotate()
set name = "Rotate"
@@ -40,12 +42,16 @@
..()
if(state == 2 && anchored)
connect_to_network()
if(_wifi_id)
wifi_receiver = new(_wifi_id, src)
/obj/machinery/power/emitter/Destroy()
message_admins("Emitter deleted at ([x],[y],[z] - <A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[x];Y=[y];Z=[z]'>JMP</a>)",0,1)
log_game("Emitter deleted at ([x],[y],[z])")
investigate_log("<font color='red'>deleted</font> at ([x],[y],[z])","singulo")
..()
qdel(wifi_receiver)
wifi_receiver = null
return ..()
/obj/machinery/power/emitter/update_icon()
if (active && powernet && avail(active_power_usage))
+164
View File
@@ -0,0 +1,164 @@
//-------------------------------
// Buttons
// Sender: intended to be used by buttons, when the button is pressed it will call activate() on all connected /button
// receivers.
// Receiver: does whatever the subtype does. deactivate() by default calls activate(), so you will have to override in
// it in a subtype if you want it to do something.
//-------------------------------
/datum/wifi/sender/button/proc/activate(mob/living/user)
for(var/datum/wifi/receiver/button/B in connected_devices)
B.activate(user)
/datum/wifi/sender/button/proc/deactivate(mob/living/user)
for(var/datum/wifi/receiver/button/B in connected_devices)
B.deactivate(user)
/datum/wifi/receiver/button/proc/activate(mob/living/user)
/datum/wifi/receiver/button/proc/deactivate(mob/living/user)
activate(user) //override this if you want deactivate to actually do something
//-------------------------------
// Doors
// Sender: sends an open/close request to all connected /door receivers. Utilises spawn_sync to trigger all doors to
// open at approximately the same time. Waits until all doors have finished opening before returning.
// Receiver: will try to open/close the parent door when activate/deactivate is called.
//-------------------------------
/datum/wifi/sender/door/proc/open()
var/datum/spawn_sync/S = new()
for(var/datum/wifi/receiver/button/door/D in connected_devices)
S.start_worker(D, "activate")
S.wait_until_done()
return
/datum/wifi/sender/door/proc/close()
var/datum/spawn_sync/S = new()
for(var/datum/wifi/receiver/button/door/D in connected_devices)
S.start_worker(D, "deactivate")
S.wait_until_done()
return
/datum/wifi/receiver/button/door/activate()
var/obj/machinery/door/D = parent
if(istype(D) && D.can_open())
D.open()
/datum/wifi/receiver/button/door/deactivate()
var/obj/machinery/door/D = parent
if(istype(D) && D.can_close())
D.close()
//-------------------------------
// Emitter
// Activates/deactivates the parent emitter.
//-------------------------------
/datum/wifi/receiver/button/emitter/activate(mob/living/user)
..()
var/obj/machinery/power/emitter/E = parent
if(istype(E) && !E.active)
E.activate(user) //if the emitter is not active, trigger the activate proc to toggle it
/datum/wifi/receiver/button/emitter/deactivate(mob/living/user)
var/obj/machinery/power/emitter/E = parent
if(istype(E) && E.active)
E.activate(user) //if the emitter is active, trigger the activate proc to toggle it
//-------------------------------
// Crematorium
// Triggers cremate() on the parent /crematorium.
//-------------------------------
/datum/wifi/receiver/button/crematorium/activate(mob/living/user)
..()
var/obj/structure/crematorium/C = parent
if(istype(C))
C.cremate(user)
//-------------------------------
// Mounted Flash
// Triggers flash() on the parent /flasher.
//-------------------------------
/datum/wifi/receiver/button/flasher/activate(mob/living/user)
..()
var/obj/machinery/flasher/F = parent
if(istype(F))
F.flash()
//-------------------------------
// Holosign
// Turns the parent /holosign on/off.
//-------------------------------
/datum/wifi/receiver/button/holosign/activate(mob/living/user)
..()
var/obj/machinery/holosign/H = parent
if(istype(H) && !H.lit)
H.toggle()
/datum/wifi/receiver/button/holosign/deactivate(mob/living/user)
var/obj/machinery/holosign/H = parent
if(istype(H) && H.lit)
H.toggle()
//-------------------------------
// Igniter
// Turns the parent /igniter on/off.
//-------------------------------
/datum/wifi/receiver/button/igniter/activate(mob/living/user)
..()
var/obj/machinery/igniter/I = parent
if(istype(I))
if(!I.on)
I.ignite()
/datum/wifi/receiver/button/igniter/deactivate(mob/living/user)
if(istype(parent, /obj/machinery/igniter))
var/obj/machinery/igniter/I = parent
if(I.on)
I.ignite()
//-------------------------------
// Sparker
// Triggers the parent /sparker to ignite().
//-------------------------------
/datum/wifi/receiver/button/sparker/activate(mob/living/user)
..()
var/obj/machinery/sparker/S = parent
if(istype(S))
S.ignite()
//-------------------------------
// Mass Driver
// Sender: carries out a sequence of first opening all connected doors, then activating all connected mass drivers,
// then closes all connected doors. It will wait before continuing the sequence after opening/closing the doors.
// Receiver: Triggers the parent mass dirver to activate.
//-------------------------------
/datum/wifi/sender/mass_driver/proc/cycle()
var/datum/spawn_sync/S = new()
//tell all doors to open
for(var/datum/wifi/receiver/button/door/D in connected_devices)
S.start_worker(D, "activate")
S.wait_until_done()
S.reset()
//tell all mass drivers to launch
for(var/datum/wifi/receiver/button/mass_driver/M in connected_devices)
spawn()
M.activate()
sleep(20)
//tell all doors to close
S.reset()
for(var/datum/wifi/receiver/button/door/D in connected_devices)
S.start_worker(D, "deactivate")
S.wait_until_done()
return
/datum/wifi/receiver/button/mass_driver/activate(mob/living/user)
..()
var/obj/machinery/mass_driver/M = parent
if(istype(M))
M.drive()
+110
View File
@@ -0,0 +1,110 @@
//-------------------------------
/*
Interfaces
These are the datums that an object needs to connect via the wireless controller. You will need a /wifi/receiver to
allow other devices to connect to your device and send it instructions. You will need a /wifi/sender to send signals
to other devices with wifi receivers. You can have multiple devices (senders and receivers) if you program your
device to handle them.
Each wifi interface has one "id". This identifies which devices can connect to each other. Multiple senders can
connect to multiple receivers as long as they have the same id.
Variants are found in devices.dm
To add a receiver to an object:
Add the following variables to the object:
var/_wifi_id << variable that can be configured on the map, this is passed to the receiver later
var/datum/wifi/receiver/subtype/wifi_receiver << the receiver (and subtype itself)
Add or modify the objects initialize() proc to include:
if(_wifi_id) << only creates a wifi receiver if an id is set
wifi_receiver = new(_wifi_id, src) << this needs to be in initialize() as New() is usually too
early, and the receiver will try to connect to the controller
before it is setup.
Add or modify the objects Destroy() proc to include:
qdel(wifi_receiver)
wifi_receiver = null
Senders are setup the same way, except with a var/datum/wifi/sender/subtype/wifi_sender variable instead of (or in
addition to) a /wifi/receiver variable.
You will however need to call the /wifi/senders code to pass commands onto any connected receivers.
Example:
/obj/machinery/button/attack_hand()
wifi_sender.activate()
*/
//-------------------------------
//-------------------------------
// Wifi
//-------------------------------
/datum/wifi
var/obj/parent
var/list/connected_devices
var/id
/datum/wifi/New(var/new_id, var/obj/O)
connected_devices = new()
id = new_id
if(istype(O))
parent = O
/datum/wifi/Destroy(var/wifi/device)
parent = null
for(var/datum/wifi/D in connected_devices)
D.disconnect_device(src)
disconnect_device(D)
return ..()
/datum/wifi/proc/connect_device(var/datum/wifi/device)
if(connected_devices)
connected_devices |= device
else
connected_devices = new()
connected_devices |= device
/datum/wifi/proc/disconnect_device(var/datum/wifi/device)
if(connected_devices)
connected_devices -= device
//-------------------------------
// Receiver
//-------------------------------
/datum/wifi/receiver/New()
..()
if(wirelessProcess)
wirelessProcess.add_device(src)
/datum/wifi/receiver/Destroy()
if(wirelessProcess)
wirelessProcess.remove_device(src)
return ..()
//-------------------------------
// Sender
//-------------------------------
/datum/wifi/sender/New()
..()
send_connection_request()
/datum/wifi/sender/proc/set_target(var/new_target)
id = new_target
/datum/wifi/sender/proc/send_connection_request()
var/datum/connection_request/C = new(src, id)
wirelessProcess.add_request(C)
//-------------------------------
// Connection request
//-------------------------------
/datum/connection_request
var/datum/wifi/sender/source //wifi/sender object creating the request
var/id //id tag of the target device(s) to try to connect to
/datum/connection_request/New(var/datum/wifi/sender/sender, var/receiver)
if(istype(sender))
source = sender
id = receiver
+4
View File
@@ -0,0 +1,4 @@
author: Loganbacca
delete-after: True
changes:
- rscadd: "Added a backend (wireless) system for communication between machinery and other devices."