whitelist updates (#19288)

* whitelist updates

* migrate things to module

* .

* some more

* robot IDs are now handled by module

* special ids

* .

* .

* .

* .

* .

* .

* move that

* .

* initial

* admin whitelist TGUI

* .

* .

* lol
This commit is contained in:
Kashargul
2026-03-21 01:16:13 +01:00
committed by GitHub
parent a6b6ccb167
commit 418bc73c80
52 changed files with 742 additions and 378 deletions
+20 -12
View File
@@ -67,14 +67,14 @@
.["target"]["active_restrictions"] = target.restrict_modules_to
var/list/possible_restrictions = list()
for(var/entry in GLOB.robot_modules)
if(!target.restrict_modules_to.Find(entry))
if(!(target.restrict_modules_to?.Find(entry)))
possible_restrictions += entry
.["target"]["possible_restrictions"] = possible_restrictions
// Target section for options once a module has been selected
if(target.module)
.["target"]["active"] = target.icon_selected
.["target"]["sprite"] = sanitize_css_class_name("[target.sprite_datum.type]")
.["target"]["sprite_size"] = spritesheet.icon_size_id(.["target"]["sprite"] + "S")
.["target"]["sprite_size"] = spritesheet?.icon_size_id(.["target"]["sprite"] + "S")
.["target"]["modules"] = get_target_items(user)
var/list/module_options = list()
for(var/module in GLOB.robot_modules)
@@ -185,10 +185,16 @@
target.crisis_override = !target.crisis_override
return TRUE
if("add_restriction")
target.restrict_modules_to |= params["new_restriction"]
var/new_restriction = params["new_restriction"]
if(!(new_restriction in GLOB.robot_modules))
return FALSE
LAZYOR(target.restrict_modules_to, new_restriction)
return TRUE
if("remove_restriction")
target.restrict_modules_to -= params["rem_restriction"]
var/rem_restriction = params["rem_restriction"]
if(!(rem_restriction in GLOB.robot_modules))
return FALSE
LAZYREMOVE(target.restrict_modules_to, rem_restriction)
return TRUE
if("select_source")
if(source)
@@ -196,13 +202,15 @@
var/module_type = GLOB.robot_modules[params["new_source"]]
if(ispath(module_type, /obj/item/robot_module/robot/syndicate))
source = new /mob/living/silicon/robot/syndicate(null)
else if(ispath(module_type, /obj/item/robot_module/robot/malf))
source = new /mob/living/silicon/robot/malf(null)
else
source = new /mob/living/silicon/robot(null)
source.modtype = params["new_source"]
var/obj/item/robot_module/robot/robot_type = new module_type(source)
source.sprite_datum = pick(SSrobot_sprites.get_module_sprites(source.modtype, source))
source.update_icon()
source.emag_items = 1
source.emag_items = TRUE
if(!istype(robot_type, /obj/item/robot_module/robot))
QDEL_NULL(source)
return TRUE
@@ -291,7 +299,7 @@
new module_type(source)
source.sprite_datum = target.sprite_datum
source.update_icon()
source.emag_items = 1
source.emag_items = TRUE
// Target
target.uneq_all()
target.hud_used?.update_robot_modules_display(TRUE)
@@ -599,25 +607,25 @@
if(!our_ai)
our_ai = select_active_ai_with_fewest_borgs()
if(our_ai)
target.lawupdate = 1
target.lawupdate = TRUE
target.connect_to_ai(our_ai)
return TRUE
if("disconnect_ai")
if(target.is_slaved())
target.disconnect_from_ai()
target.lawupdate = 0
target.lawupdate = FALSE
return TRUE
if("toggle_emag")
if(target.emagged)
target.emagged = 0
target.emagged = FALSE
target.clear_supplied_laws()
target.clear_inherent_laws()
target.laws = new using_map.default_law_type
to_chat(target, span_danger("Laws updated!\n") + target.laws.get_formatted_laws())
target.hud_used?.update_robot_modules_display()
else
target.emagged = 1
target.lawupdate = 0
target.emagged = TRUE
target.lawupdate = FALSE
target.disconnect_from_ai()
target.clear_supplied_laws()
target.clear_inherent_laws()
@@ -639,7 +647,7 @@
var/list/source_list = list()
source_list["model"] = source.module
source_list["sprite"] = sanitize_css_class_name("[source.sprite_datum.type]")
source_list["sprite_size"] = spritesheet.icon_size_id(source_list["sprite"] + "S")
source_list["sprite_size"] = spritesheet?.icon_size_id(source_list["sprite"] + "S")
var/list/source_items = list()
for(var/obj/item in (source.module.modules | source.module.emag))
var/exists
+4 -2
View File
@@ -85,7 +85,7 @@ GLOBAL_LIST_INIT(ai_verbs_default, list(
var/override_CPURate = 0 // Bonus/Penalty CPU generation rate. For use by admins/testers.
var/datum/ai_icon/selected_sprite // The selected icon set
var/custom_sprite = 0 // Whether the selected icon is custom
var/custom_sprite = FALSE // Whether the selected icon is custom
var/carded
// Multicam Vars
@@ -97,6 +97,7 @@ GLOBAL_LIST_INIT(ai_verbs_default, list(
var/max_multicams = 6
can_be_antagged = TRUE
var/idcard_type = /obj/item/card/id/synthetic
/mob/living/silicon/ai/proc/add_ai_verbs()
add_verb(src, GLOB.ai_verbs_default)
@@ -185,6 +186,7 @@ GLOBAL_LIST_INIT(ai_verbs_default, list(
GLOB.ai_list += src
. = ..()
init_id(idcard_type)
new /obj/machinery/ai_powersupply(src)
@@ -283,7 +285,7 @@ GLOBAL_LIST_INIT(ai_verbs_default, list(
if(Entry[1] == src.ckey && Entry[2] == src.real_name)
icon = CUSTOM_ITEM_SYNTH
custom_sprite = 1
custom_sprite = TRUE
selected_sprite = new/datum/ai_icon("Custom", "[src.ckey]-ai", "4", "[ckey]-ai-crash", "#FFFFFF", "#FFFFFF", "#FFFFFF")
else
selected_sprite = GLOB.default_ai_icon
+2 -1
View File
@@ -13,7 +13,7 @@
can_pull_size = ITEMSIZE_SMALL
can_pull_mobs = MOB_PULL_SMALLER
idcard_type = /obj/item/card/id
var/idcard_type = /obj/item/card/id
var/idaccessible = 0
var/network = "SS13"
@@ -105,6 +105,7 @@
//////////////////////////////////////////////////////////////////////////////////////////////////
/mob/living/silicon/pai/Initialize(mapload)
. = ..()
init_id(idcard_type)
card = loc
if(!istype(card))
@@ -29,7 +29,7 @@ GLOBAL_LIST_EMPTY(robot_custom_icons)
return
var/sprite_owner = GLOB.robot_custom_icons[sprite_name]
if(sprite_owner && sprite_owner == ckey)
custom_sprite = 1
custom_sprite = TRUE
icon = CUSTOM_ITEM_SYNTH
if(icon_state == "robot")
icon_state = "[ckey]-[sprite_name]-Standard" //Compliant with robot.dm line 236 ~Mech
@@ -32,7 +32,7 @@ GLOBAL_LIST_EMPTY(mob_hat_cache)
gender = NEUTER
pass_flags = PASSTABLE
braintype = "Drone"
lawupdate = 0
lawupdate = FALSE
density = TRUE
req_access = list(ACCESS_ENGINE, ACCESS_ROBOTICS)
integrated_light_power = 3
@@ -276,8 +276,8 @@ GLOBAL_LIST_EMPTY(mob_hat_cache)
var/time = time2text(world.realtime,"hh:mm:ss")
GLOB.lawchanges.Add("[time] " + span_bold(":") + " [user.name]([user.key]) emagged [name]([key])")
emagged = 1
lawupdate = 0
emagged = TRUE
lawupdate = FALSE
connected_ai = null
clear_supplied_laws()
clear_inherent_laws()
@@ -359,7 +359,7 @@ GLOBAL_LIST_EMPTY(mob_hat_cache)
if(player.mob && player.mob.mind)
player.mob.mind.transfer_to(src)
lawupdate = 0
lawupdate = FALSE
to_chat(src, span_infoplain(span_bold("Systems rebooted") + " Loading base pattern maintenance protocol... " + span_bold("loaded") + "."))
full_law_reset()
welcome_drone()
@@ -13,12 +13,12 @@
gender = NEUTER
pass_flags = PASSTABLE
braintype = "Drone"
lawupdate = 0
lawupdate = FALSE
density = TRUE
idcard_type = /obj/item/card/id/syndicate
req_access = list(999)
integrated_light_power = 3
local_transmit = 0
can_pick_shell = FALSE
can_pull_size = ITEMSIZE_NO_CONTAINER
can_pull_mobs = MOB_PULL_SMALLER
@@ -54,13 +54,13 @@
if(lights_on)
cell_use_power(30) // 30W light. Normal lights would use ~15W, but increased for balance reasons.
has_power = 1
has_power = TRUE
else
if (has_power)
to_chat(src, span_red("You are now running on emergency backup power."))
has_power = 0
has_power = FALSE
if(lights_on) // Light is on but there is no power!
lights_on = 0
lights_on = FALSE
set_light(0)
/mob/living/silicon/robot/handle_regular_status_updates()
+31 -23
View File
@@ -15,13 +15,13 @@
blocks_emissive = EMISSIVE_BLOCK_UNIQUE
var/lights_on = 0 // Is our integrated light on?
var/lights_on = FALSE // Is our integrated light on?
var/grabbable = FALSE //disables/enables pick-up mechanics.
var/robot_light_col = "#FFFFFF"
var/used_power_this_tick = 0
var/sight_mode = 0
var/custom_name = ""
var/custom_sprite = 0 //Due to all the sprites involved, a var for our custom borgs may be best
var/custom_sprite = FALSE //Due to all the sprites involved, a var for our custom borgs may be best
var/sprite_name = null // The name of the borg, for the purposes of custom icon sprite indexing.
var/crisis //Admin-settable for combat module use.
var/crisis_override = 0
@@ -72,7 +72,7 @@
var/scrubbing = FALSE //Floor cleaning enabled
// Subtype limited modules or admin restrictions
var/list/restrict_modules_to = list()
var/list/restrict_modules_to
// Components are basically robot organs.
var/list/components = list()
@@ -81,12 +81,12 @@
var/obj/item/pda/ai/rbPDA = null
var/opened = 0
var/emagged = 0
var/emag_items = 0
var/wiresexposed = 0
var/locked = 1
var/has_power = 1
var/opened = FALSE
var/emagged = FALSE
var/emag_items = FALSE
var/wiresexposed = FALSE
var/locked = TRUE
var/has_power = TRUE
var/list/req_access = list(ACCESS_ROBOTICS)
var/ident = 0
//var/list/laws = list()
@@ -102,11 +102,11 @@
var/killswitch_time = 60
var/weapon_lock = 0
var/weaponlock_time = 120
var/lawupdate = 1 //Cyborgs will sync their laws with their AI by default
var/lawupdate = TRUE //Cyborgs will sync their laws with their AI by default
var/lockcharge //Used when looking to see if a borg is locked down.
var/lockdown = 0 //Controls whether or not the borg is actually locked down.
var/speed = 0 //Cause sec borgs gotta go fast //No they dont!
var/scrambledcodes = 0 // Used to determine if a borg shows up on the robotics console. Setting to one hides them.
var/scrambledcodes = FALSE // Used to determine if a borg shows up on the robotics console. Setting to one hides them.
var/tracking_entities = 0 //The number of known entities currently accessing the internal camera
var/braintype = JOB_CYBORG
@@ -256,12 +256,10 @@
additional_law_channels["Binary"] = "#b"
var/new_ai = select_active_ai_with_fewest_borgs()
if(new_ai)
lawupdate = 1
lawupdate = TRUE
connect_to_ai(new_ai)
else
lawupdate = 0
lawupdate = FALSE
/mob/living/silicon/robot/SetName(pickedName as text)
custom_name = pickedName
@@ -375,7 +373,7 @@
if(new_sprites && new_sprites.len)
module_sprites = new_sprites.Copy()
//Custom_sprite check and entry
if (custom_sprite == 1)
if (custom_sprite)
module_sprites["Custom"] = "[ckey]-[sprite_name]-[modtype]" //Made compliant with custom_sprites.dm line 32. (src.) was apparently redundant as it's implied. ~Mech
icontype = "Custom"
else
@@ -851,8 +849,7 @@
hands.icon_state = get_hud_module_icon()
if(notify)
notify_ai(ROBOT_NOTIFICATION_MODULE_RESET, module.name)
module.Reset(src)
QDEL_NULL(module)
module.reset_module(src)
icon_selected = FALSE
updatename("Default")
has_recoloured = FALSE
@@ -1106,11 +1103,11 @@
/mob/living/silicon/robot/proc/UnlinkSelf()
disconnect_from_ai()
lawupdate = 0
lawupdate = FALSE
lockcharge = 0
lockdown = 0
canmove = 1
scrambledcodes = 1
scrambledcodes = TRUE
//Disconnect it's camera so it's not so easily tracked.
if(src.camera)
src.camera.clear_all_networks()
@@ -1261,7 +1258,7 @@
if(locked)
if(prob(90))
to_chat(user, span_filter_notice("You emag the cover lock."))
locked = 0
locked = FALSE
else
to_chat(user, span_filter_warning("You fail to emag the cover lock."))
to_chat(src, span_filter_warning("Hack attempt detected."))
@@ -1298,9 +1295,9 @@
sleep(6)
if(prob(50))
emagged = 1
emagged = TRUE
robotact.update_static_data_for_all_viewers()
lawupdate = 0
lawupdate = FALSE
disconnect_from_ai()
to_chat(user, span_filter_notice("You emag [src]'s interface."))
message_admins("[key_name_admin(user)] emagged cyborg [key_name_admin(src)]. Laws overridden.")
@@ -1652,4 +1649,15 @@
/mob/living/silicon/robot/proc/get_ui_theme()
if(emagged)
return "syndicate"
if(module?.ui_theme)
return module.ui_theme
return ui_theme
/mob/living/silicon/robot/handle_special_unlocks()
if(!module)
return
module.handle_special_unlocks(src)
/mob/living/silicon/robot/proc/scramble_hardware(var/chance)
if(prob(chance)) //Small chance to spawn with a scrambled
emag_items = TRUE
@@ -1,11 +1,14 @@
/* Other, unaffiliated modules */
/obj/item/robot_module/robot/malf
hide_on_manifest = TRUE
ui_theme = "malfunction"
idcard_type = /obj/item/card/id/lost
// The module that borgs on the surface have. Generally has a lot of useful tools in exchange for questionable loyalty to the crew.
/obj/item/robot_module/robot/lost
/obj/item/robot_module/robot/malf/lost
name = "lost robot module"
hide_on_manifest = TRUE
/obj/item/robot_module/robot/lost/create_equipment(var/mob/living/silicon/robot/robot)
/obj/item/robot_module/robot/malf/lost/create_equipment(var/mob/living/silicon/robot/robot)
..()
// Sec
src.modules += new /obj/item/melee/robotic/baton/shocker(src)
@@ -36,16 +39,22 @@
src.modules += new /obj/item/dogborg/sleeper/lost(src)
src.modules += new /obj/item/dogborg/pounce(src)
/obj/item/robot_module/robot/lost/adjust_gps(obj/item/gps/robot/robot_gps)
/obj/item/robot_module/robot/malf/lost/adjust_gps(obj/item/gps/robot/robot_gps)
robot_gps.long_range = TRUE
robot_gps.hide_signal = TRUE
robot_gps.can_hide_signal = TRUE
/obj/item/robot_module/robot/gravekeeper
name = "gravekeeper robot module"
hide_on_manifest = TRUE
/obj/item/robot_module/robot/malf/lost/handle_special_unlocks(mob/living/silicon/robot/owner_robot)
if(!owner_robot.emag_items)
owner_robot.scramble_hardware(20)
if (owner_robot.churn_count == 5)
emag += new /obj/item/self_repair_system/advanced(src)
owner_robot.hud_used.update_robot_modules_display()
/obj/item/robot_module/robot/gravekeeper/create_equipment(var/mob/living/silicon/robot/robot)
/obj/item/robot_module/robot/malf/gravekeeper
name = "gravekeeper robot module"
/obj/item/robot_module/robot/malf/gravekeeper/create_equipment(var/mob/living/silicon/robot/robot)
..()
// For fending off animals and looters
src.modules += new /obj/item/melee/robotic/baton/shocker(src)
@@ -76,3 +85,10 @@
// For uwu
src.modules += new /obj/item/dogborg/sleeper/compactor/generic(src)
src.emag += new /obj/item/dogborg/pounce(src)
/obj/item/robot_module/robot/malf/gravekeeper/handle_special_unlocks(mob/living/silicon/robot/owner_robot)
if(!owner_robot.emag_items)
owner_robot.scramble_hardware(10)
if (owner_robot.churn_count == 5)
emag += new /obj/item/self_repair_system/advanced(src)
owner_robot.hud_used.update_robot_modules_display()
@@ -0,0 +1,2 @@
/obj/item/robot_module/proc/handle_special_unlocks()
return
@@ -34,6 +34,8 @@
// Bookkeeping
var/list/original_languages = list()
var/list/added_networks = list()
var/ui_theme
var/idcard_type = /obj/item/card/id/synthetic
/obj/item/robot_module/proc/hide_on_manifest()
. = hide_on_manifest
@@ -68,19 +70,25 @@
I.canremove = FALSE
/obj/item/robot_module/proc/create_equipment(var/mob/living/silicon/robot/robot)
robot.init_id(idcard_type)
return
/obj/item/robot_module/proc/Reset(var/mob/living/silicon/robot/R)
remove_camera_networks(R)
remove_languages(R)
remove_subsystems(R)
remove_status_flags(R)
// Reset the module and delete it
/obj/item/robot_module/proc/reset_module(var/mob/living/silicon/robot/robot)
remove_camera_networks(robot)
remove_languages(robot)
remove_subsystems(robot)
remove_status_flags(robot)
if(R.radio)
R.radio.recalculateChannels()
R.set_default_module_icon()
if(robot.radio)
robot.radio.recalculateChannels()
robot.set_default_module_icon()
R.scrubbing = FALSE
robot.scrubbing = FALSE
modules -= robot.idcard
QDEL_NULL(robot.idcard)
robot.module = null
qdel(src)
/obj/item/robot_module/Destroy()
QDEL_LIST(modules)
@@ -630,6 +638,7 @@
networks = list(NETWORK_MINE)
supported_upgrades = list(/obj/item/borg/upgrade/restricted/pka, /obj/item/borg/upgrade/restricted/diamonddrill, /obj/item/borg/upgrade/restricted/adv_scanner, /obj/item/borg/upgrade/restricted/adv_snatcher, /obj/item/borg/upgrade/restricted/adv_mailbag)
pto_type = PTO_CARGO
idcard_type = /obj/item/card/id/synthetic/borg
/obj/item/robot_module/robot/miner/create_equipment(var/mob/living/silicon/robot/robot)
..()
@@ -641,7 +650,13 @@
src.modules += new /obj/item/storage/bag/sheetsnatcher/borg(src)
src.modules += new /obj/item/gripper/miner(src)
src.modules += new /obj/item/mining_scanner/robot(src)
src.modules += new /obj/item/card/id/cargo/miner/borg(src)
var/obj/item/card/id/robot_id = robot.idcard
robot_id.name = "\improper Synthetic Miner ID"
robot_id.initial_sprite_stack = list("base-stamp", "top-brown", "stamp-n", "stripe-purple")
robot_id.reset_icon()
robot_id.forceMove(src)
src.modules += robot_id
src.modules += new /obj/item/mail_scanner(src)
src.modules += new /obj/item/storage/bag/mail/borg(src)
src.modules += new /obj/item/destTagger(src)
@@ -822,3 +837,9 @@
src.modules += new /obj/item/storage/bag/ore(src)
src.modules += new /obj/item/storage/bag/sheetsnatcher/borg(src)
src.emag += new /obj/item/pickaxe/diamonddrill(src)
/obj/item/robot_module/drone/talon
name = "talon drone module"
idcard_type = /obj/item/card/id/talon
channels = list(CHANNEL_TALON = 1)
networks = list(NETWORK_TALON_SHIP)
@@ -1,12 +1,14 @@
/obj/item/robot_module/drone/swarm
name = "swarm drone module"
var/id
var/obj/item/card/id/drone_id
idcard_type = /obj/item/card/id/syndicate
/obj/item/robot_module/drone/swarm/create_equipment(var/mob/living/silicon/robot/robot)
..()
id = robot.idcard
src.modules += id
var/obj/item/card/id/robot_id = robot.idcard
robot_id.forceMove(src)
src.modules += robot_id
src.modules += new /obj/item/rcd/electric/mounted/borg/swarm(src)
src.modules += new /obj/item/flash/robot(src)
@@ -18,7 +18,8 @@
LANGUAGE_TERMINUS = 1,
LANGUAGE_ZADDAT = 0
)
var/id
ui_theme = "syndicate"
idcard_type = /obj/item/card/id/syndicate
// All syndie modules get these, and the base borg items (flash, crowbar, etc).
/obj/item/robot_module/robot/syndicate/create_equipment(var/mob/living/silicon/robot/robot)
@@ -34,20 +35,15 @@
src.modules += jetpack
robot.internals = jetpack
var/obj/id = robot.idcard
id.forceMove(src)
src.modules += id
var/obj/item/card/id/robot_id = robot.idcard
robot_id.forceMove(src)
src.modules += robot_id
/obj/item/robot_module/robot/syndicate/adjust_gps(obj/item/gps/robot/robot_gps)
robot_gps.long_range = TRUE
robot_gps.hide_signal = TRUE
robot_gps.can_hide_signal = TRUE
/obj/item/robot_module/robot/syndicate/Destroy()
src.modules -= id
id = null
return ..()
// Gets a big shield and a gun that shoots really fast to scare the opposing force.
/obj/item/robot_module/robot/syndicate/protector
name = "protector robot module"
@@ -35,23 +35,27 @@
var/mob/living/silicon/robot/R = host
var/list/modules = list()
var/list/whitelisted = list()
if(R.module)
modules = list(R.modtype)
selected_module = R.modtype
else
if(LAZYLEN(R.restrict_modules_to) > 0)
modules.Add(R.restrict_modules_to)
if(LAZYLEN(R.restrict_modules_to))
modules += R.restrict_modules_to
else if(R.shell)
modules.Add(GLOB.shell_module_types)
modules += GLOB.shell_module_types
else
modules.Add(GLOB.robot_module_types)
modules += GLOB.robot_module_types
if(R.crisis || GLOB.security_level >= SEC_LEVEL_RED || R.crisis_override)
to_chat(R, span_red("Crisis mode active. Combat module available."))
modules |= GLOB.emergency_module_types
for(var/module_name in GLOB.whitelisted_module_types)
if(is_borg_whitelisted(R, module_name))
modules |= module_name
if(!(module_name in modules))
modules += module_name
whitelisted += module_name
data["possible_modules"] = modules
data["whitelisted_modules"] = whitelisted
data["mind_name"] = R.mind.name
data["theme"] = R.get_ui_theme()
@@ -107,12 +111,12 @@
switch(action)
if("pick_module")
if(R.module)
return
return FALSE
var/new_module = params["value"]
if(!(new_module in GLOB.robot_modules))
return
return FALSE
if(!is_borg_whitelisted(R, new_module))
return
return FALSE
selected_module = new_module
if(sprite_datum)
var/new_datum
@@ -122,30 +126,30 @@
new_datum = S
break
sprite_datum = new_datum
. = TRUE
return TRUE
if("pick_icon")
var/sprite = params["value"]
if(!sprite)
return
return FALSE
var/list/module_sprites = SSrobot_sprites.get_module_sprites(selected_module, R)
for(var/datum/robot_sprite/S in module_sprites)
if(S.name == sprite)
sprite_datum = S
break
. = TRUE
return TRUE
if("rename")
var/name = params["value"]
if(name)
new_name = sanitizeSafe(name, MAX_NAME_LEN)
R.sprite_name = new_name
. = TRUE
return TRUE
if("confirm")
R.apply_name(new_name)
R.apply_module(sprite_datum, selected_module)
R.update_multibelly()
R.transform_module()
close_ui()
. = TRUE
return TRUE
/mob/living/silicon/robot/proc/apply_name(var/new_name)
if(!custom_name)
@@ -20,6 +20,7 @@
/obj/item/robot_module/robot/exploration
can_be_pushed = 0
idcard_type = /obj/item/card/id/synthetic/borg
/obj/item/robot_module/robot/exploration/create_equipment(mob/living/silicon/robot/robot)
..()
@@ -32,6 +33,11 @@
src.modules += new /obj/item/shield_projector/line/exploborg(src)
src.modules += new /obj/item/roller_holder(src)
src.modules += new /obj/item/self_repair_system(src)
src.modules += new /obj/item/card/id/exploration/borg(src)
var/obj/item/card/id/robot_id = robot.idcard
robot_id.name = "\improper Synthetic Exploration ID"
robot_id.initial_sprite_stack = list("base-stamp", "top-olive", "stamp-n")
robot_id.reset_icon()
robot_id.forceMove(src)
src.emag += new /obj/item/melee/robotic/jaws/big/explojaws(src)
@@ -1,40 +1,10 @@
/mob/living/silicon/robot/gravekeeper
lawupdate = 0
scrambledcodes = 1
/mob/living/silicon/robot/malf/gravekeeper
icon_state = "drone-lost"
modtype = "Gravekeeper"
lawchannel = "State"
braintype = "Drone"
idcard_type = /obj/item/card/id/lost
icon_selected = FALSE
can_be_antagged = FALSE
restrict_modules_to = list("Gravekeeper")
ui_theme = "malfunction"
/mob/living/silicon/robot/gravekeeper/init()
aiCamera = new/obj/item/camera/siliconcam/robot_camera(src)
mmi = new /obj/item/mmi/digital/robot(src) // Explicitly a drone.
module = new /obj/item/robot_module/robot/gravekeeper(src)
cut_overlays()
init_id()
updatename("Gravekeeper")
if(!cell)
cell = new /obj/item/cell/high(src) // 15k cell, as recharging stations are a lot more rare on the Surface.
/mob/living/silicon/robot/malf/gravekeeper/init()
..()
module = new /obj/item/robot_module/robot/malf/gravekeeper(src)
laws = new /datum/ai_laws/gravekeeper()
playsound(src, 'sound/mecha/nominalsyndi.ogg', 75, 0)
/mob/living/silicon/robot/gravekeeper/proc/scramble_hardware(var/chance)
if(prob(chance)) //Small chance to spawn with a scrambled
emag_items = 1
/mob/living/silicon/robot/gravekeeper/handle_special_unlocks()
if(!emag_items)
scramble_hardware(10)
if (churn_count == 5)
module.emag += new /obj/item/self_repair_system/advanced(module)
hud_used.update_robot_modules_display()
@@ -1,72 +1,49 @@
/mob/living/silicon/robot/lost
lawupdate = 0
scrambledcodes = 1
/mob/living/silicon/robot/malf/lost
icon_state = "drone-lost"
modtype = "Lost"
lawchannel = "State"
braintype = "Drone"
idcard_type = /obj/item/card/id/lost
icon_selected = FALSE
restrict_modules_to = list("Lost")
var/law_retries = 5
ui_theme = "malfunction"
/mob/living/silicon/robot/lost/init()
aiCamera = new/obj/item/camera/siliconcam/robot_camera(src)
mmi = new /obj/item/mmi/digital/robot(src) // Explicitly a drone.
module = new /obj/item/robot_module/robot/lost(src)
cut_overlays()
init_id()
updatename("Lost")
if(!cell)
cell = new /obj/item/cell/high(src) // 15k cell, as recharging stations are a lot more rare on the Surface.
/mob/living/silicon/robot/malf/lost/init()
..()
module = new /obj/item/robot_module/robot/malf/lost(src)
scramble_hardware(20)
playsound(src, 'sound/mecha/nominalsyndi.ogg', 75, 0)
/mob/living/silicon/robot/lost/speech_bubble_appearance()
/mob/living/silicon/robot/malf/lost/speech_bubble_appearance()
return "synthetic_evil"
/mob/living/silicon/robot/lost/proc/scramble_hardware(var/chance)
if(prob(chance)) //Small chance to spawn with a scrambled
emag_items = 1
/mob/living/silicon/robot/lost/proc/apply_new_laws()
/mob/living/silicon/robot/malf/lost/proc/apply_new_laws()
return
/mob/living/silicon/robot/lost/randomlaws
/mob/living/silicon/robot/malf/lost/randomlaws
/mob/living/silicon/robot/lost/randomlaws/apply_new_laws()
/mob/living/silicon/robot/malf/lost/randomlaws/apply_new_laws()
var/old_name = laws?.name
laws = give_random_lawset()
if(old_name == laws.name)
apply_new_laws()
/mob/living/silicon/robot/lost/randomlaws/init()
/mob/living/silicon/robot/malf/lost/randomlaws/init()
..()
apply_new_laws()
/mob/living/silicon/robot/lost/randomlaws/vore
/mob/living/silicon/robot/malf/lost/randomlaws/vore
/mob/living/silicon/robot/lost/randomlaws/vore/apply_new_laws()
/mob/living/silicon/robot/malf/lost/randomlaws/vore/apply_new_laws()
var/old_name = laws?.name
laws = give_random_lawset_vore(100)
if(old_name == laws.name)
apply_new_laws()
/mob/living/silicon/robot/lost/randomlaws/mixed
/mob/living/silicon/robot/malf/lost/randomlaws/mixed
/mob/living/silicon/robot/lost/randomlaws/mixed/apply_new_laws()
/mob/living/silicon/robot/malf/lost/randomlaws/mixed/apply_new_laws()
var/old_name = laws?.name
laws = give_random_lawset_vore(60)
if(old_name == laws.name)
apply_new_laws()
/mob/living/silicon/robot/lost/randomlaws/repick_laws()
/mob/living/silicon/robot/malf/lost/randomlaws/repick_laws()
while(law_retries)
var/confirm = tgui_alert(src, "Do you want to keep your laws or reroll? (For specific laws, feel free to ahelp and we'll see what we can do)", "Confirm laws", list("Keep", "Reroll ([law_retries])"))
if(findtext(confirm, regex("Reroll \\(\[0-9\]*\\)", "")))
@@ -180,7 +157,7 @@
return
/mob/living/silicon/proc/give_random_lawset_vore(var/vore_chance = 100)
/mob/living/silicon/proc/give_random_lawset_vore(vore_chance = 100)
// Decide what kind of laws we want to draw from.
var/law_class = pick(
prob(25);"good",
@@ -332,12 +309,3 @@
return new /datum/ai_laws/foreign_tsc_aggressive()
if(5) // Manicial laugher here.
return new /datum/ai_laws/tyrant()
return
/mob/living/silicon/robot/lost/handle_special_unlocks()
if(!emag_items)
scramble_hardware(20)
if (churn_count == 5)
module.emag += new /obj/item/self_repair_system/advanced(module)
hud_used.update_robot_modules_display()
@@ -0,0 +1,22 @@
/mob/living/silicon/robot/malf
lawupdate = FALSE
scrambledcodes = TRUE
modtype = "Malf"
lawchannel = "State"
braintype = "Drone"
ui_theme = "malfunction"
/mob/living/silicon/robot/malf/init()
aiCamera = new/obj/item/camera/siliconcam/robot_camera(src)
if(!restrict_modules_to)
restrict_modules_to = GLOB.malf_module_types
mmi = new /obj/item/mmi/digital/robot(src) // Explicitly a drone.
updatename(modtype)
if(!cell)
cell = new /obj/item/cell/high(src) // 15k cell, as recharging stations are a lot more rare on the Surface.
playsound(src, 'sound/mecha/nominalsyndi.ogg', 75, 0)
@@ -1,23 +1,20 @@
/mob/living/silicon/robot/syndicate
lawupdate = 0
scrambledcodes = 1
emagged = 1
lawupdate = FALSE
scrambledcodes = TRUE
emagged = TRUE
modtype = "Syndicate"
lawchannel = "State"
braintype = "Drone"
idcard_type = /obj/item/card/id/syndicate
icon_selected = FALSE
restrict_modules_to = list("Protector", "Mechanist", "Combat Medic", "Ninja")
ui_theme = "syndicate"
/mob/living/silicon/robot/syndicate/init()
aiCamera = new/obj/item/camera/siliconcam/robot_camera(src)
if(!restrict_modules_to)
restrict_modules_to = GLOB.antag_module_types
mmi = new /obj/item/mmi/digital/robot(src) // Explicitly a drone.
cut_overlays()
init_id()
updatename("Syndicate")
updatename(modtype)
if(!cell)
cell = new /obj/item/cell/robot_syndi(src) // 25k cell, because Antag.
@@ -36,28 +33,24 @@
module = new /obj/item/robot_module/robot/syndicate/protector(src)
modtype = "Protector"
restrict_modules_to = list("Protector")
updatename("Protector")
/mob/living/silicon/robot/syndicate/mechanist/init()
..()
module = new /obj/item/robot_module/robot/syndicate/mechanist(src)
modtype = "Mechanist"
restrict_modules_to = list("Mechanist")
updatename("Mechanist")
/mob/living/silicon/robot/syndicate/combat_medic/init()
..()
module = new /obj/item/robot_module/robot/syndicate/combat_medic(src)
modtype = "Combat Medic"
restrict_modules_to = list("Combat Medic")
updatename("Combat Medic")
/mob/living/silicon/robot/syndicate/ninja/init()
..()
module = new /obj/item/robot_module/robot/syndicate/ninja(src)
modtype = "Ninja"
restrict_modules_to = list("Ninja")
updatename("Ninja")
/mob/living/silicon/robot/syndicate/speech_bubble_appearance()
return "synthetic_evil"
@@ -21,7 +21,6 @@
color = "#68a2f2"
cell = /obj/item/cell/mech
idcard_type = /obj/item/card/id/platform
module = /obj/item/robot_module/robot/platform
lawupdate = FALSE
@@ -14,6 +14,7 @@
"Stripe" = "stripe",
"Vertical Stripe" = "stripe_vertical"
)
idcard_type = /obj/item/card/id/platform
// Only show on manifest if they have a player.
/obj/item/robot_module/robot/platform/hide_on_manifest()
+3 -3
View File
@@ -23,7 +23,6 @@
var/list/access_rights
var/obj/item/card/id/idcard
var/idcard_type = /obj/item/card/id/synthetic
var/sensor_type = 0 //VOREStation add - silicon omni "is sensor on or nah"
@@ -36,7 +35,6 @@
if(!is_decoy)
add_language(LANGUAGE_GALCOM)
apply_default_language(GLOB.all_languages[LANGUAGE_GALCOM])
init_id()
init_subsystems()
AddElement(/datum/element/footstep, FOOTSTEP_MOB_SHOE, 1, -6)
@@ -55,7 +53,9 @@
clear_subsystems()
return ..()
/mob/living/silicon/proc/init_id()
/mob/living/silicon/proc/init_id(idcard_type)
if(!idcard_type)
return
if(idcard)
return
idcard = new idcard_type(src)
+4 -4
View File
@@ -130,7 +130,7 @@ GLOBAL_LIST_EMPTY(apcs)
var/lastused_total = 0
var/main_status = APC_EXTERNAL_POWER_NOTCONNECTED
var/mob/living/silicon/ai/hacker = null // Malfunction var. If set AI hacked the APC and has full control.
var/wiresexposed = 0
var/wiresexposed = FALSE
powernet = 0 // set so that APCs aren't found as powernet nodes //Hackish, Horrible, was like this before I changed it :(
var/debug= 0
var/autoflag= 0 // 0 = off, 1= eqp and lights off, 2 = eqp off, 3 = all on.
@@ -742,12 +742,12 @@ GLOBAL_LIST_EMPTY(apcs)
var/allcut = wires.is_all_cut()
if(beenhit >= pick(3, 4) && wiresexposed != 1)
wiresexposed = 1
if(beenhit >= pick(3, 4) && !wiresexposed)
wiresexposed = TRUE
update_icon()
visible_message(span_warning("The [name]'s cover flies open, exposing the wires!"))
else if(wiresexposed == 1 && allcut == 0)
else if(wiresexposed && allcut == 0)
wires.cut_all()
update_icon()
visible_message(span_warning("The [name]'s wires are shredded!"))
+60 -45
View File
@@ -381,11 +381,11 @@ GLOBAL_LIST_EMPTY(pending_discord_registrations)
return "Smite [smite_name] sent!"
#define VALID_ACTIONS list("add", "remove", "list", "help")
#define VALID_KINDS list("job", "species")
#define VALID_KINDS list("job", "species", "language", "robot")
#define VALID_USAGE "whitelist \[[list2text(VALID_ACTIONS, ", ")]\] \[[list2text(VALID_KINDS, ", ")]\] <ckey> (role)"
/datum/tgs_chat_command/whitelist
name = "whitelist"
help_text = "allows the management of player whitelists.\nUsage: whitelist \[add, remove, list\] \[job, species\] <ckey> (role)"
help_text = "allows the management of player whitelists.\nUsage: whitelist \[add, remove, list\] \[job, species, language, robot\] <ckey> (role)"
admin_only = TRUE
/datum/tgs_chat_command/whitelist/Run(datum/tgs_chat_user/sender, params)
@@ -411,7 +411,12 @@ GLOBAL_LIST_EMPTY(pending_discord_registrations)
for(var/datum/job/our_job in GLOB.job_master.occupations)
if(our_job.whitelist_only)
whitelist_jobs += our_job.title
message.text = "The following jobs and species have a whitelist:\nJobs: [english_list(whitelist_jobs)]\nSpecies: [english_list(GLOB.whitelisted_species)]"
var/list/whitelisted_language = list()
for(var/language, value in GLOB.all_languages)
var/datum/language/current_lang = value
if(current_lang.flags & WHITELISTED)
whitelisted_language += language
message.text = "The following jobs and species have a whitelist:\nJobs: [english_list(whitelist_jobs)]\nSpecies: [english_list(GLOB.whitelisted_species)]\nLanguages: [english_list(whitelisted_language)]\nRobot Modules: [english_list(GLOB.whitelisted_module_types)]"
return message
message_as_list.Cut(1, 2)
@@ -429,7 +434,7 @@ GLOBAL_LIST_EMPTY(pending_discord_registrations)
return message
var/ckey = message_as_list[1]
if(!istext(ckey))
if(ckey != ckey(ckey))
message.text = "```Third param must be a valid ckey.```"
return message
@@ -449,21 +454,37 @@ GLOBAL_LIST_EMPTY(pending_discord_registrations)
// Resolve the action
switch(action)
if("add")
if(kind == "job")
var/datum/job/job = GLOB.job_master.GetJob(role)
if(!job)
message.text = "Error, invalid job entered. Check spelling and capitalization."
return message
if(!job.whitelist_only)
message.text = "Error, job \"[role]\" is not a whitelist job."
return message
if(kind == "species")
if(!(role in GLOB.playable_species))
message.text = "Error, invalid species entered. Check spelling and capitalization."
return message
if(!(role in GLOB.whitelisted_species))
message.text = "Error, species \"[role]\" is not a whitelist species."
return message
switch(kind)
if("job")
var/datum/job/job = GLOB.job_master.GetJob(role)
if(!job)
message.text = "Error, invalid job entered. Check spelling and capitalization."
return message
if(!job.whitelist_only)
message.text = "Error, job \"[role]\" is not a whitelist job."
return message
if("species")
if(!(role in GLOB.playable_species))
message.text = "Error, invalid species entered. Check spelling and capitalization."
return message
if(!(role in GLOB.whitelisted_species))
message.text = "Error, species \"[role]\" is not a whitelist species."
return message
if("language")
var/datum/language/chosen_language = GLOB.all_languages[role]
if(!chosen_language)
message.text = "Error, invalid language entered. Check spelling and capitalization."
return message
if(!(chosen_language.flags & WHITELISTED))
message.text = "Error, language \"[role]\" is not a whitelist language."
return message
if("robot")
if(!(role in GLOB.robot_modules))
message.text = "Error, invalid robot module entered. Check spelling and capitalization."
return message
if(!(role in GLOB.whitelisted_module_types))
message.text = "Error, robot module \"[role]\" is not a whitelist robot module."
return message
var/datum/db_query/command_add = SSdbcore.NewQuery(
"INSERT INTO [format_table_name("whitelist")] (ckey, kind, entry) VALUES (:ckey, :kind, :entry)",
@@ -476,21 +497,18 @@ GLOBAL_LIST_EMPTY(pending_discord_registrations)
return message
qdel(command_add)
var/list/our_whitelists
if(kind == "job")
our_whitelists = GLOB.job_whitelist[ckey]
if(!our_whitelists)
our_whitelists = list()
GLOB.job_whitelist[ckey] = our_whitelists
switch(kind)
if("job")
LAZYOR(GLOB.job_whitelist[ckey], role)
if(kind == "species")
our_whitelists = GLOB.alien_whitelist[ckey]
if(!our_whitelists)
our_whitelists = list()
GLOB.alien_whitelist[ckey] = our_whitelists
if("species")
LAZYOR(GLOB.alien_whitelist[ckey], role)
if(our_whitelists)
our_whitelists |= role
if("language")
LAZYOR(GLOB.language_whitelist[ckey], role)
if("robot")
LAZYOR(GLOB.robot_whitelist[ckey], role)
if("remove")
var/datum/db_query/command_remove = SSdbcore.NewQuery(
@@ -504,21 +522,18 @@ GLOBAL_LIST_EMPTY(pending_discord_registrations)
return message
qdel(command_remove)
var/list/our_whitelists
if(kind == "job")
our_whitelists = GLOB.job_whitelist[ckey]
if(!our_whitelists)
our_whitelists = list()
GLOB.job_whitelist[ckey] = our_whitelists
switch(kind)
if("job")
LAZYREMOVE(GLOB.job_whitelist[ckey], role)
if(kind == "species")
our_whitelists = GLOB.alien_whitelist[ckey]
if(!our_whitelists)
our_whitelists = list()
GLOB.alien_whitelist[ckey] = our_whitelists
if("species")
LAZYREMOVE(GLOB.alien_whitelist[ckey], role)
if(our_whitelists && (role in our_whitelists))
our_whitelists -= role
if("language")
LAZYREMOVE(GLOB.language_whitelist[ckey], role)
if("robot")
LAZYREMOVE(GLOB.robot_whitelist[ckey], role)
// Listing all whitelists for a specific ckey
if("list")