mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-01-28 10:01:58 +00:00
* No roundstart playable MULEs / Trampling requires hacking (#76837) ## About The Pull Request Prevailing feedback has been: - The player base cannot be trusted to control MULEbots. - It should be clearer what bots can and can't do. The former is easy to fix. The latter is sort of a matter for policy but I'm going to investigate giving bots a rudimentary laws system. Plus that sounds much more controversial than this so I am going to atomise this outside of that PR. MULEbots can still be set to allow sentience by cargo technicians, but don't start that way. ADDITIONALLY this PR just changes it so that MULEbots do not crush people unless: - They have been emagged. - Their safety wire has been cut. Either means works, so it's not too hard to access for nefarious purposes, but hard to do to yourself. Otherwise they just slow down for a few seconds instead. Also fixed an unrelated name bug while I was there. Closes #76926 ## Why It's Good For The Game Players would take them, not deliver any cargo, and repeatedly ask people to lie down in front of them. Plus Tram has 5 of the things which is frankly too many to be wandering around the bar. ## Changelog 🆑 balance: You can't possess a MULE as soon as the round starts, someone will have to give you permission. balance: MULEbots no longer crush prone characters unless they have been hacked (or emagged). fix: Bots can put numbers in their names, what with being robots. admin: Adds attack logging when certain wires are cut (for instance: MULEbot safeties) /🆑 * No roundstart playable MULEs / Trampling requires hacking * add missing arg --------- Co-authored-by: Jacquerel <hnevard@gmail.com> Co-authored-by: Pinta <68373373+softcerv@users.noreply.github.com> Co-authored-by: Giz <13398309+vinylspiders@users.noreply.github.com>
119 lines
4.7 KiB
Plaintext
119 lines
4.7 KiB
Plaintext
/datum/wires/robot
|
|
holder_type = /mob/living/silicon/robot
|
|
proper_name = "Cyborg"
|
|
randomize = TRUE
|
|
|
|
/datum/wires/robot/New(atom/holder)
|
|
wires = list(
|
|
WIRE_AI, WIRE_CAMERA,
|
|
WIRE_LAWSYNC, WIRE_LOCKDOWN,
|
|
WIRE_RESET_MODEL
|
|
)
|
|
add_duds(2)
|
|
..()
|
|
|
|
/datum/wires/robot/interactable(mob/user)
|
|
if(!..())
|
|
return FALSE
|
|
var/mob/living/silicon/robot/R = holder
|
|
if(R.wiresexposed)
|
|
return TRUE
|
|
|
|
/datum/wires/robot/get_status()
|
|
var/mob/living/silicon/robot/R = holder
|
|
var/list/status = list()
|
|
status += "The law sync module is [R.lawupdate ? "on" : "off"]."
|
|
status += "The intelligence link display shows [R.connected_ai ? R.connected_ai.name : "NULL"]."
|
|
status += "The camera light is [!isnull(R.builtInCamera) && R.builtInCamera.status ? "on" : "off"]."
|
|
status += "The lockdown indicator is [R.lockcharge ? "on" : "off"]."
|
|
status += "There is a star symbol above the [get_color_of_wire(WIRE_RESET_MODEL)] wire."
|
|
return status
|
|
|
|
/datum/wires/robot/on_pulse(wire, user)
|
|
var/mob/living/silicon/robot/R = holder
|
|
switch(wire)
|
|
if(WIRE_AI) // Pulse to pick a new AI.
|
|
if(!R.emagged)
|
|
var/new_ai
|
|
if(user)
|
|
new_ai = select_active_ai(user, R.z)
|
|
else
|
|
new_ai = select_active_ai(R, R.z)
|
|
R.notify_ai(AI_NOTIFICATION_CYBORG_DISCONNECTED)
|
|
if(new_ai && (new_ai != R.connected_ai))
|
|
R.set_connected_ai(new_ai)
|
|
log_silicon("[key_name(usr)] synced [key_name(R)] [R.connected_ai ? "from [key_name(R.connected_ai)]": ""] to [key_name(new_ai)]")
|
|
if(R.shell)
|
|
R.undeploy() //If this borg is an AI shell, disconnect the controlling AI and assign ti to a new AI
|
|
R.notify_ai(AI_NOTIFICATION_AI_SHELL)
|
|
else
|
|
R.notify_ai(TRUE)
|
|
if(WIRE_CAMERA) // Pulse to disable the camera.
|
|
if(!QDELETED(R.builtInCamera) && !R.scrambledcodes)
|
|
R.builtInCamera.toggle_cam(usr, FALSE)
|
|
R.visible_message(span_notice("[R]'s camera lens focuses loudly."), span_notice("Your camera lens focuses loudly."))
|
|
log_silicon("[key_name(usr)] toggled [key_name(R)]'s camera to [R.builtInCamera.status ? "on" : "off"] via pulse")
|
|
if(WIRE_LAWSYNC) // Forces a law update if possible.
|
|
if(R.lawupdate)
|
|
R.visible_message(span_notice("[R] gently chimes."), span_notice("LawSync protocol engaged."))
|
|
log_silicon("[key_name(usr)] forcibly synced [key_name(R)]'s laws via pulse")
|
|
// TODO, log the laws they gained here
|
|
R.lawsync()
|
|
R.show_laws()
|
|
if(WIRE_LOCKDOWN)
|
|
R.SetLockdown(!R.lockcharge) // Toggle
|
|
log_silicon("[key_name(usr)] [!R.lockcharge ? "locked down" : "released"] [key_name(R)] via pulse")
|
|
|
|
if(WIRE_RESET_MODEL)
|
|
if(R.has_model())
|
|
R.visible_message(span_notice("[R]'s model servos twitch."), span_notice("Your model display flickers."))
|
|
|
|
/datum/wires/robot/on_cut(wire, mend, source)
|
|
var/mob/living/silicon/robot/R = holder
|
|
switch(wire)
|
|
if(WIRE_AI) // Cut the AI wire to reset AI control.
|
|
if(!mend)
|
|
R.notify_ai(AI_NOTIFICATION_CYBORG_DISCONNECTED)
|
|
log_silicon("[key_name(usr)] cut AI wire on [key_name(R)][R.connected_ai ? " and disconnected from [key_name(R.connected_ai)]": ""]")
|
|
if(R.shell)
|
|
R.undeploy()
|
|
R.set_connected_ai(null)
|
|
R.logevent("AI connection fault [mend?"cleared":"detected"]")
|
|
if(WIRE_LAWSYNC) // Cut the law wire, and the borg will no longer receive law updates from its AI. Repair and it will re-sync.
|
|
if(mend)
|
|
if(!R.emagged)
|
|
R.lawupdate = TRUE
|
|
log_silicon("[key_name(usr)] enabled [key_name(R)]'s lawsync via wire")
|
|
else if(!R.deployed) //AI shells must always have the same laws as the AI
|
|
R.lawupdate = FALSE
|
|
log_silicon("[key_name(usr)] disabled [key_name(R)]'s lawsync via wire")
|
|
R.logevent("Lawsync Module fault [mend ? "cleared" : "detected"]")
|
|
if (WIRE_CAMERA) // Disable the camera.
|
|
if(!QDELETED(R.builtInCamera) && !R.scrambledcodes)
|
|
R.builtInCamera.status = mend
|
|
R.builtInCamera.toggle_cam(usr, 0)
|
|
R.visible_message(span_notice("[R]'s camera lens focuses loudly."), span_notice("Your camera lens focuses loudly."))
|
|
R.logevent("Camera Module fault [mend?"cleared":"detected"]")
|
|
log_silicon("[key_name(usr)] [mend ? "enabled" : "disabled"] [key_name(R)]'s camera via wire")
|
|
if(WIRE_LOCKDOWN) // Simple lockdown.
|
|
R.SetLockdown(!mend)
|
|
R.logevent("Motor Controller fault [mend?"cleared":"detected"]")
|
|
log_silicon("[key_name(usr)] [!R.lockcharge ? "locked down" : "released"] [key_name(R)] via wire")
|
|
if(WIRE_RESET_MODEL)
|
|
if(R.has_model() && !mend)
|
|
R.ResetModel()
|
|
log_silicon("[key_name(usr)] reset [key_name(R)]'s module via wire")
|
|
|
|
/datum/wires/robot/can_reveal_wires(mob/user)
|
|
if(HAS_TRAIT(user, TRAIT_KNOW_CYBORG_WIRES))
|
|
return TRUE
|
|
|
|
return ..()
|
|
|
|
/datum/wires/robot/always_reveal_wire(color)
|
|
// Always reveal the reset model wire.
|
|
if(color == get_color_of_wire(WIRE_RESET_MODEL))
|
|
return TRUE
|
|
|
|
return ..()
|