mirror of
https://github.com/VOREStation/VOREStation.git
synced 2026-08-25 04:57:47 +01:00
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:
@@ -161,16 +161,16 @@ Once in open space, consider disabling nonessential power-consuming electronics
|
||||
|
||||
/mob/living/silicon/robot/drone/talon
|
||||
foreign_droid = TRUE
|
||||
idcard_type = /obj/item/card/id/synthetic/talon
|
||||
module_type = /obj/item/robot_module/drone/talon
|
||||
|
||||
/obj/item/card/id/synthetic/talon
|
||||
/obj/item/card/id/talon
|
||||
name = "\improper Talon synthetic ID"
|
||||
desc = "Access module for Talon synthetics"
|
||||
icon_state = "id-robot"
|
||||
item_state = "tdgreen"
|
||||
assignment = "Talon synthetic"
|
||||
|
||||
/obj/item/card/id/synthetic/talon/Initialize(mapload)
|
||||
/obj/item/card/id/talon/Initialize(mapload)
|
||||
. = ..()
|
||||
access = list(ACCESS_TALON, ACCESS_SYNTH)
|
||||
|
||||
|
||||
@@ -101,6 +101,7 @@ _ADMIN_VERB(verb_path_name, verb_permissions, verb_name, verb_desc, verb_categor
|
||||
#define ADMIN_CATEGORY_SERVER "Server"
|
||||
#define ADMIN_CATEGORY_SERVER_GAME "Server.Game"
|
||||
#define ADMIN_CATEGORY_SERVER_ADMIN "Server.Admin"
|
||||
#define ADMIN_CATEGORY_SERVER_CONFIG "Server.Config"
|
||||
|
||||
// Fun categories
|
||||
#define ADMIN_CATEGORY_FUN_EVENT_KIT "Fun.Event Kit"
|
||||
|
||||
@@ -52,10 +52,13 @@ GLOBAL_LIST_INIT(shell_module_types, list(
|
||||
"Janitor", "Service", "Clown", "Clerical", "Security",
|
||||
"Research", "Command" //"Exploration"
|
||||
))
|
||||
// List of modules available malf borgs
|
||||
GLOBAL_LIST_INIT(malf_module_types, list("Lost", "Gravekeeper"))
|
||||
// List of modules available toantags
|
||||
GLOBAL_LIST_INIT(antag_module_types, list("Protector", "Mechanist", "Combat Medic", "Ninja"))
|
||||
|
||||
// List of whitelisted modules
|
||||
GLOBAL_LIST_INIT(whitelisted_module_types, list(
|
||||
"Lost"
|
||||
))
|
||||
GLOBAL_LIST_INIT(whitelisted_module_types, list("Combat", "Lost", "Gravekeeper", "Protector", "Mechanist", "Combat Medic", "Ninja"))
|
||||
|
||||
// Bomb cap!
|
||||
GLOBAL_VAR_INIT(max_explosion_range, 14)
|
||||
|
||||
@@ -1336,8 +1336,8 @@ GLOBAL_LIST_INIT(robot_modules, list(
|
||||
"Exploration" = /obj/item/robot_module/robot/exploration,
|
||||
"Engineering" = /obj/item/robot_module/robot/engineering,
|
||||
"Janitor" = /obj/item/robot_module/robot/janitor,
|
||||
"Gravekeeper" = /obj/item/robot_module/robot/gravekeeper,
|
||||
"Lost" = /obj/item/robot_module/robot/lost,
|
||||
"Gravekeeper" = /obj/item/robot_module/robot/malf/gravekeeper,
|
||||
"Lost" = /obj/item/robot_module/robot/malf/lost,
|
||||
"Protector" = /obj/item/robot_module/robot/syndicate/protector,
|
||||
"Mechanist" = /obj/item/robot_module/robot/syndicate/mechanist,
|
||||
"Combat Medic" = /obj/item/robot_module/robot/syndicate/combat_medic,
|
||||
|
||||
@@ -187,7 +187,7 @@
|
||||
// Connect the cyborg to AI
|
||||
target.connected_ai = user
|
||||
user.connected_robots += target
|
||||
target.lawupdate = 1
|
||||
target.lawupdate = TRUE
|
||||
target.sync()
|
||||
target.show_laws()
|
||||
user.hacking = 0
|
||||
|
||||
+144
-47
@@ -1,14 +1,16 @@
|
||||
#define WHITELISTFILE "data/whitelist.txt"
|
||||
#define VALID_KINDS list("job", "species", "language", "robot")
|
||||
|
||||
GLOBAL_LIST_EMPTY(whitelist)
|
||||
GLOBAL_LIST_EMPTY(job_whitelist)
|
||||
GLOBAL_LIST_EMPTY(alien_whitelist)
|
||||
GLOBAL_LIST_EMPTY(language_whitelist)
|
||||
GLOBAL_LIST_EMPTY(robot_whitelist)
|
||||
|
||||
// Not yet implemented
|
||||
//ADMIN_VERB(open_whitelist_editor, R_ADMIN, "Open Whitelist Editor", "Opens the editor for alien- and jobwhitelists.", ADMIN_CATEGORY_GAME)
|
||||
// if(user.holder)
|
||||
// user.holder.whitelist_editor = new /datum/whitelist_editor()
|
||||
// user.holder.whitelist_editor.tgui_interact(user.mob)
|
||||
ADMIN_VERB(open_whitelist_editor, R_ADMIN|R_SERVER, "Open Whitelist Editor", "Opens the editor for alien- and jobwhitelists.", ADMIN_CATEGORY_SERVER_CONFIG)
|
||||
if(user.holder)
|
||||
user.holder.whitelist_editor = new /datum/whitelist_editor()
|
||||
user.holder.whitelist_editor.tgui_interact(user.mob)
|
||||
|
||||
/datum/whitelist_editor
|
||||
|
||||
@@ -22,17 +24,33 @@ GLOBAL_LIST_EMPTY(alien_whitelist)
|
||||
ui.open()
|
||||
|
||||
/datum/whitelist_editor/tgui_data(mob/user)
|
||||
var/list/data = list()
|
||||
|
||||
data["alienwhitelist"] = GLOB.alien_whitelist
|
||||
data["jobwhitelist"] = GLOB.job_whitelist
|
||||
var/list/data = list(
|
||||
"alienwhitelist" = GLOB.alien_whitelist,
|
||||
"languagewhitelist" = GLOB.language_whitelist,
|
||||
"robotwhitelist" = GLOB.robot_whitelist,
|
||||
"jobwhitelist" = GLOB.job_whitelist
|
||||
)
|
||||
|
||||
return data
|
||||
|
||||
/datum/whitelist_editor/tgui_static_data(mob/user)
|
||||
var/list/data = list()
|
||||
var/list/whitelist_jobs = list()
|
||||
for(var/datum/job/our_job in GLOB.job_master.occupations)
|
||||
if(our_job.whitelist_only)
|
||||
whitelist_jobs += our_job.title
|
||||
|
||||
data["species_requiring_whitelist"] = 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
|
||||
|
||||
var/list/data = list(
|
||||
"species_with_whitelist" = GLOB.whitelisted_species,
|
||||
"language_with_whitelist" = whitelisted_language,
|
||||
"robot_with_whitelist" = GLOB.whitelisted_module_types,
|
||||
"jobs_with_whitelist" = whitelist_jobs
|
||||
)
|
||||
|
||||
return data
|
||||
|
||||
@@ -44,25 +62,94 @@ GLOBAL_LIST_EMPTY(alien_whitelist)
|
||||
switch(action)
|
||||
if("add_alienwhitelist")
|
||||
if (!CONFIG_GET(flag/sql_enabled))
|
||||
to_chat(ui.user, "This action is not supported while the database is disabled. Please edit [global.config.directory]/alienwhitelist.txt.")
|
||||
to_chat(ui.user, span_warning("This action is not supported while the database is disabled. Please edit [global.config.directory]/alienwhitelist.txt."))
|
||||
return
|
||||
// TODO: Add to database
|
||||
. = TRUE
|
||||
var/ckey = params["ckey"]
|
||||
if(ckey != ckey(ckey))
|
||||
to_chat(ui.user, span_warning("Error, invalid ckey. Did you enter the key?"))
|
||||
return FALSE
|
||||
var/kind = params["type"]
|
||||
if(!(kind in VALID_KINDS))
|
||||
to_chat(ui.user, span_warning("Error, invalid type entered."))
|
||||
return FALSE
|
||||
var/role = params["role"]
|
||||
switch(kind)
|
||||
if("job")
|
||||
var/datum/job/job = GLOB.job_master.GetJob(role)
|
||||
if(!job)
|
||||
to_chat(ui.user, span_warning("Error, invalid job entered. Check spelling and capitalization."))
|
||||
return FALSE
|
||||
if(!job.whitelist_only)
|
||||
to_chat(ui.user, span_warning("Error, job \"[role]\" is not a whitelist job."))
|
||||
return FALSE
|
||||
if("species")
|
||||
if(!(role in GLOB.playable_species))
|
||||
to_chat(ui.user, span_warning("Error, invalid species entered. Check spelling and capitalization."))
|
||||
return FALSE
|
||||
if(!(role in GLOB.whitelisted_species))
|
||||
to_chat(ui.user, span_warning("Error, species \"[role]\" is not a whitelist species."))
|
||||
return FALSE
|
||||
if("language")
|
||||
var/datum/language/chosen_language = GLOB.all_languages[role]
|
||||
if(!chosen_language)
|
||||
to_chat(ui.user, span_warning("Error, invalid language entered. Check spelling and capitalization."))
|
||||
return FALSE
|
||||
if(!(chosen_language.flags & WHITELISTED))
|
||||
to_chat(ui.user, span_warning("Error, language \"[role]\" is not a whitelist language."))
|
||||
return FALSE
|
||||
if("robot")
|
||||
if(!(role in GLOB.robot_modules))
|
||||
to_chat(ui.user, span_warning("Error, invalid robot module entered. Check spelling and capitalization."))
|
||||
return FALSE
|
||||
if(!(role in GLOB.whitelisted_module_types))
|
||||
to_chat(ui.user, span_warning("Error, robot module \"[role]\" is not a whitelist robot module."))
|
||||
return FALSE
|
||||
var/datum/db_query/command_add = SSdbcore.NewQuery(
|
||||
"INSERT INTO [format_table_name("whitelist")] (ckey, kind, entry) VALUES (:ckey, :kind, :entry)",
|
||||
list("ckey" = ckey, "kind" = kind, "entry" = role)
|
||||
)
|
||||
if(!command_add.Execute())
|
||||
log_sql("Error while trying to add [ckey] to the [role] [kind] whitelist.")
|
||||
to_chat(ui.user, span_warning("Error while trying to add [ckey] to the [role] [kind] whitelist. Please review SQL logs."))
|
||||
qdel(command_add)
|
||||
return FALSE
|
||||
qdel(command_add)
|
||||
log_and_message_admins("added [ckey]'s [role] entry to [kind] whitelsit.", ui.user)
|
||||
return TRUE
|
||||
|
||||
if("remove_alienwhitelist")
|
||||
if (!CONFIG_GET(flag/sql_enabled))
|
||||
to_chat(ui.user, "This action is not supported while the database is disabled. Please edit [global.config.directory]/alienwhitelist.txt.")
|
||||
return
|
||||
// TODO: Remove from database
|
||||
. = TRUE
|
||||
return FALSE
|
||||
var/ckey = params["ckey"]
|
||||
if(ckey != ckey(ckey))
|
||||
to_chat(ui.user, span_warning("Error, invalid ckey. Did you enter the key?"))
|
||||
return FALSE
|
||||
var/kind = params["type"]
|
||||
if(!(kind in VALID_KINDS))
|
||||
to_chat(ui.user, span_warning("Error, invalid type entered."))
|
||||
return FALSE
|
||||
var/role = params["role"]
|
||||
var/datum/db_query/command_remove = SSdbcore.NewQuery(
|
||||
"DELETE FROM [format_table_name("whitelist")] WHERE ckey = :ckey AND kind = :kind AND entry = :entry",
|
||||
list("ckey" = ckey, "kind" = kind, "entry" = role)
|
||||
)
|
||||
if(!command_remove.Execute())
|
||||
log_sql("Error while trying to remove [ckey] from the [role] [kind] whitelist.")
|
||||
to_chat(ui.user, span_warning("Error while trying to remove [ckey] from the [role] [kind] whitelist. Please review SQL logs."))
|
||||
qdel(command_remove)
|
||||
return FALSE
|
||||
qdel(command_remove)
|
||||
log_and_message_admins("removed [ckey]'s [role] entry from [kind] whitelsit.", ui.user)
|
||||
return TRUE
|
||||
|
||||
if("reload_alienwhitelist")
|
||||
reload_alienwhitelist()
|
||||
. = TRUE
|
||||
return TRUE
|
||||
|
||||
if("reload_jobwhitelist")
|
||||
reload_jobwhitelist()
|
||||
. = TRUE
|
||||
return TRUE
|
||||
|
||||
/proc/load_whitelist()
|
||||
GLOB.whitelist = world.file2list(WHITELISTFILE)
|
||||
@@ -75,22 +162,24 @@ GLOBAL_LIST_EMPTY(alien_whitelist)
|
||||
|
||||
/proc/load_alienwhitelist(dbfail = FALSE)
|
||||
if (CONFIG_GET(flag/sql_enabled) && !dbfail)
|
||||
var/datum/db_query/query_load_alienwhistelist = SSdbcore.NewQuery("SELECT ckey, entry FROM [format_table_name("whitelist")] WHERE kind = 'species'")
|
||||
var/datum/db_query/query_load_alienwhistelist = SSdbcore.NewQuery("SELECT ckey, entry, kind FROM [format_table_name("whitelist")] WHERE kind IN ('species', 'language', 'robot')")
|
||||
if(!query_load_alienwhistelist.Execute())
|
||||
message_admins("Error loading alienwhitelist from database. Loading from [global.config.directory]/alienwhitelist.txt.")
|
||||
log_sql("Error loading alienwhitelist from database. Loading from [global.config.directory]/alienwhitelist.txt.")
|
||||
load_alienwhitelist(dbfail = TRUE)
|
||||
qdel(query_load_alienwhistelist)
|
||||
return
|
||||
else
|
||||
while(query_load_alienwhistelist.NextRow())
|
||||
var/ckey = query_load_alienwhistelist.item[1]
|
||||
var/entry = query_load_alienwhistelist.item[2]
|
||||
while(query_load_alienwhistelist.NextRow())
|
||||
var/ckey = query_load_alienwhistelist.item[1]
|
||||
var/entry = query_load_alienwhistelist.item[2]
|
||||
switch(query_load_alienwhistelist.item[3])
|
||||
if("species")
|
||||
LAZYADD(GLOB.alien_whitelist[ckey], entry)
|
||||
if("language")
|
||||
LAZYADD(GLOB.language_whitelist[ckey], entry)
|
||||
if("robot")
|
||||
LAZYADD(GLOB.robot_whitelist[ckey], entry)
|
||||
|
||||
var/list/our_whitelists = GLOB.alien_whitelist[ckey]
|
||||
if(!our_whitelists) // Guess this is their first/only whitelist entry
|
||||
our_whitelists = list()
|
||||
GLOB.alien_whitelist[ckey] = our_whitelists
|
||||
our_whitelists += entry
|
||||
qdel(query_load_alienwhistelist)
|
||||
else
|
||||
var/text = file2text("[global.config.directory]/alienwhitelist.txt")
|
||||
@@ -99,19 +188,25 @@ GLOBAL_LIST_EMPTY(alien_whitelist)
|
||||
else
|
||||
var/lines = splittext(text, "\n") // Now we've got a bunch of "ckey = something" strings in a list
|
||||
for(var/line in lines)
|
||||
var/list/left_and_right = splittext(line, " - ") // Split it on the dash into left and right
|
||||
if(LAZYLEN(left_and_right) != 2)
|
||||
var/list/data_entry = splittext(line, " - ") // Split it on the dash into left and right
|
||||
if(LAZYLEN(data_entry) != 3)
|
||||
WARNING("Alien whitelist entry is invalid: [line]") // If we didn't end up with a left and right, the line is bad
|
||||
continue
|
||||
var/key = left_and_right[1]
|
||||
var/key = data_entry[2]
|
||||
if(key != ckey(key))
|
||||
WARNING("Alien whitelist entry appears to have key, not ckey: [line]") // The key contains invalid ckey characters
|
||||
continue
|
||||
var/list/our_whitelists = GLOB.alien_whitelist[key] // Try to see if we have one already and add to it
|
||||
if(!our_whitelists) // Guess this is their first/only whitelist entry
|
||||
our_whitelists = list()
|
||||
GLOB.alien_whitelist[key] = our_whitelists
|
||||
our_whitelists += left_and_right[2]
|
||||
var/type = data_entry[1]
|
||||
switch(type)
|
||||
if("species")
|
||||
LAZYADD(GLOB.alien_whitelist[key], data_entry[3])
|
||||
if("language")
|
||||
LAZYADD(GLOB.language_whitelist[key], data_entry[3])
|
||||
if("robot")
|
||||
LAZYADD(GLOB.robot_whitelist[key], data_entry[3])
|
||||
else
|
||||
WARNING("Alien whitelist entry type is invalid: [line]")
|
||||
return
|
||||
|
||||
#ifdef TESTING
|
||||
var/msg = "Alienwhitelist Built:\n"
|
||||
@@ -124,6 +219,8 @@ GLOBAL_LIST_EMPTY(alien_whitelist)
|
||||
|
||||
/proc/reload_alienwhitelist()
|
||||
GLOB.alien_whitelist.Cut()
|
||||
GLOB.language_whitelist.Cut()
|
||||
GLOB.robot_whitelist.Cut()
|
||||
load_alienwhitelist()
|
||||
|
||||
/proc/is_alien_whitelisted(client/C, var/datum/species/species)
|
||||
@@ -177,11 +274,11 @@ GLOBAL_LIST_EMPTY(alien_whitelist)
|
||||
for(var/line in lines)
|
||||
var/list/left_and_right = splittext(line, " - ") // Split it on the dash into left and right
|
||||
if(LAZYLEN(left_and_right) != 2)
|
||||
warning("Alien whitelist entry is invalid: [line]") // If we didn't end up with a left and right, the line is bad
|
||||
WARNING("Job whitelist entry is invalid: [line]") // If we didn't end up with a left and right, the line is bad
|
||||
continue
|
||||
var/key = left_and_right[1]
|
||||
if(key != ckey(key))
|
||||
warning("Alien whitelist entry appears to have key, not ckey: [line]") // The key contains invalid ckey characters
|
||||
WARNING("Job whitelist entry appears to have key, not ckey: [line]") // The key contains invalid ckey characters
|
||||
continue
|
||||
var/list/our_whitelists = GLOB.job_whitelist[key] // Try to see if we have one already and add to it
|
||||
if(!our_whitelists) // Guess this is their first/only whitelist entry
|
||||
@@ -216,7 +313,7 @@ GLOBAL_LIST_EMPTY(alien_whitelist)
|
||||
var/list/our_whitelists = GLOB.job_whitelist[M.client.ckey]
|
||||
if("All" in our_whitelists)
|
||||
return TRUE
|
||||
if(lowertext(rank) in our_whitelists)
|
||||
if(rank in our_whitelists)
|
||||
return TRUE
|
||||
|
||||
return FALSE
|
||||
@@ -235,7 +332,7 @@ GLOBAL_LIST_EMPTY(alien_whitelist)
|
||||
return TRUE
|
||||
|
||||
//Search the whitelist
|
||||
var/list/our_whitelists = GLOB.alien_whitelist[M.ckey]
|
||||
var/list/our_whitelists = GLOB.language_whitelist[M.ckey]
|
||||
if("All" in our_whitelists)
|
||||
return TRUE
|
||||
if(language.name in our_whitelists)
|
||||
@@ -257,12 +354,11 @@ GLOBAL_LIST_EMPTY(alien_whitelist)
|
||||
return 1
|
||||
|
||||
//If we have a loaded file, search it
|
||||
if(GLOB.alien_whitelist)
|
||||
for (var/s in GLOB.alien_whitelist)
|
||||
if(findtext(s,"[M.ckey] - [module]"))
|
||||
return 1
|
||||
if(findtext(s,"[M.ckey] - All"))
|
||||
return 1
|
||||
var/list/our_whitelists = GLOB.robot_whitelist[M.ckey]
|
||||
if("All" in our_whitelists)
|
||||
return TRUE
|
||||
if(module in our_whitelists)
|
||||
return TRUE
|
||||
|
||||
/proc/whitelist_overrides(client/C)
|
||||
if(!CONFIG_GET(flag/usealienwhitelist))
|
||||
@@ -277,3 +373,4 @@ GLOBAL_LIST_EMPTY(alien_whitelist)
|
||||
return FALSE
|
||||
|
||||
#undef WHITELISTFILE
|
||||
#undef VALID_KINDS
|
||||
|
||||
@@ -114,7 +114,7 @@
|
||||
var/circuit = /obj/item/circuitboard/geiger
|
||||
var/number = 0
|
||||
var/last_tick //used to delay the powercheck
|
||||
var/wiresexposed = 0
|
||||
var/wiresexposed = FALSE
|
||||
mounted = TRUE
|
||||
|
||||
/obj/item/geiger/wall/Initialize(mapload)
|
||||
|
||||
@@ -271,20 +271,18 @@
|
||||
return
|
||||
return
|
||||
|
||||
/obj/item/card/id/cargo/miner/borg
|
||||
/obj/item/card/id/synthetic/borg
|
||||
var/mob/living/silicon/robot/R
|
||||
var/last_robot_loc
|
||||
name = "Robot Miner ID"
|
||||
rank = JOB_SHAFT_MINER
|
||||
|
||||
/obj/item/card/id/cargo/miner/borg/Initialize(mapload)
|
||||
/obj/item/card/id/synthetic/borg/Initialize(mapload)
|
||||
. = ..()
|
||||
if(isrobot(loc?.loc))
|
||||
R = loc.loc
|
||||
registered_name = R.braintype
|
||||
RegisterSignal(src, COMSIG_MOVABLE_ATTEMPTED_MOVE, PROC_REF(check_loc))
|
||||
|
||||
/obj/item/card/id/cargo/miner/borg/proc/check_loc(atom/movable/mover, atom/old_loc, atom/new_loc)
|
||||
/obj/item/card/id/synthetic/borg/proc/check_loc(atom/movable/mover, atom/old_loc, atom/new_loc)
|
||||
SIGNAL_HANDLER
|
||||
if(old_loc == R || old_loc == R.module)
|
||||
last_robot_loc = old_loc
|
||||
@@ -297,7 +295,7 @@
|
||||
if(loc == R)
|
||||
hud_layerise()
|
||||
|
||||
/obj/item/card/id/cargo/miner/borg/Destroy()
|
||||
/obj/item/card/id/synthetic/borg/Destroy()
|
||||
if(R)
|
||||
UnregisterSignal(src, COMSIG_MOVABLE_ATTEMPTED_MOVE)
|
||||
R = null
|
||||
|
||||
@@ -295,39 +295,6 @@
|
||||
initial_sprite_stack = list("base-stamp-silver", "top-olive", "stamp-n", "pips-white")
|
||||
rank = JOB_PATHFINDER
|
||||
|
||||
/obj/item/card/id/exploration/borg
|
||||
var/mob/living/silicon/robot/R
|
||||
var/last_robot_loc
|
||||
name = "Robot Exploration ID"
|
||||
rank = JOB_EXPLORER
|
||||
|
||||
/obj/item/card/id/exploration/borg/Initialize(mapload)
|
||||
. = ..()
|
||||
if(isrobot(loc?.loc))
|
||||
R = loc.loc
|
||||
registered_name = R.braintype
|
||||
RegisterSignal(src, COMSIG_MOVABLE_ATTEMPTED_MOVE, PROC_REF(check_loc))
|
||||
|
||||
/obj/item/card/id/exploration/borg/proc/check_loc(atom/movable/mover, atom/old_loc, atom/new_loc)
|
||||
SIGNAL_HANDLER
|
||||
if(old_loc == R || old_loc == R.module)
|
||||
last_robot_loc = old_loc
|
||||
if(!istype(loc, /obj/machinery) && loc != R && loc != R.module)
|
||||
if(last_robot_loc)
|
||||
forceMove(last_robot_loc)
|
||||
last_robot_loc = null
|
||||
else
|
||||
forceMove(R)
|
||||
if(loc == R)
|
||||
hud_layerise()
|
||||
|
||||
/obj/item/card/id/exploration/borg/Destroy()
|
||||
if(R)
|
||||
UnregisterSignal(src, COMSIG_MOVABLE_ATTEMPTED_MOVE)
|
||||
R = null
|
||||
last_robot_loc = null
|
||||
. = ..()
|
||||
|
||||
//Talon
|
||||
|
||||
/obj/item/card/id/talon
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
|
||||
/obj/structure/ghost_pod/manual/lost_drone/create_occupant(var/mob/M)
|
||||
density = FALSE
|
||||
var/mob/living/silicon/robot/lost/randomlaws/R = new(get_turf(src))
|
||||
var/mob/living/silicon/robot/malf/lost/randomlaws/R = new(get_turf(src))
|
||||
R.adjustBruteLoss(rand(5, 30))
|
||||
R.adjustFireLoss(rand(5, 10))
|
||||
if(M.mind)
|
||||
@@ -47,7 +47,7 @@
|
||||
|
||||
/obj/structure/ghost_pod/automatic/gravekeeper_drone/create_occupant(var/mob/M)
|
||||
density = FALSE
|
||||
var/mob/living/silicon/robot/gravekeeper/R = new(get_turf(src))
|
||||
var/mob/living/silicon/robot/malf/gravekeeper/R = new(get_turf(src))
|
||||
if(M.mind)
|
||||
M.mind.transfer_to(R)
|
||||
// Put this text here before ckey change so that their laws are shown below it, since borg login() shows it.
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
return ..()
|
||||
else
|
||||
density = FALSE
|
||||
var/mob/living/silicon/robot/lost/randomlaws/vore/R = new(get_turf(src))
|
||||
var/mob/living/silicon/robot/malf/lost/randomlaws/vore/R = new(get_turf(src))
|
||||
R.adjustBruteLoss(rand(5, 30))
|
||||
R.adjustFireLoss(rand(5, 10))
|
||||
if(M.mind)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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!"))
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -1 +1 @@
|
||||
some~user - Species
|
||||
species - some~user - Species
|
||||
|
||||
@@ -281,7 +281,7 @@ personally I recommend using the ship's boat if you need to evacuate, but if you
|
||||
|
||||
/mob/living/silicon/robot/drone/talon
|
||||
foreign_droid = TRUE
|
||||
idcard_type = /obj/item/card/id/synthetic/talon
|
||||
module_type = /obj/item/robot_module/drone/talon
|
||||
|
||||
/obj/item/card/id/synthetic/talon
|
||||
name = "\improper Talon synthetic ID"
|
||||
|
||||
@@ -114,8 +114,7 @@ recommend getting yourself introduced to
|
||||
|
||||
A React component is not a regular HTML template. A component is a
|
||||
javascript function, which accepts a `props` object (that contains
|
||||
properties passed to a component) and a `context` object (which is
|
||||
necessary to access UI data) as arguments, and outputs an HTML-like
|
||||
properties passed to a component) and outputs an HTML-like
|
||||
structure.
|
||||
|
||||
So let's create our first React Component. Create a file with a name
|
||||
@@ -127,8 +126,8 @@ import { useBackend } from 'tgui/backend';
|
||||
import { Button, LabeledList, Section } from 'tgui-core/components';
|
||||
import { Window } from 'tgui/layouts';
|
||||
|
||||
export const SampleInterface = (props, context) => {
|
||||
const { act, data } = useBackend(context);
|
||||
export const SampleInterface = (props) => {
|
||||
const { act, data } = useBackend();
|
||||
// Extract `health` and `color` variables from the `data` object.
|
||||
const { health, color } = data;
|
||||
return (
|
||||
@@ -152,7 +151,7 @@ export const SampleInterface = (props, context) => {
|
||||
};
|
||||
```
|
||||
|
||||
Here are the key variables you get from a `useBackend(context)` function:
|
||||
Here are the key variables you get from a `useBackend()` function:
|
||||
|
||||
- `config` is part of core tgui. It contains meta-information about the
|
||||
interface and who uses it, BYOND refs to various objects, and so forth.
|
||||
@@ -249,7 +248,7 @@ import { useBackend } from 'tgui/backend';
|
||||
import { Button, LabeledList, Section } from 'tgui-core/components';
|
||||
import { Window } from 'tgui/layouts';
|
||||
|
||||
export const SampleInterface = (props, context) => {
|
||||
export const SampleInterface = (props) => {
|
||||
return (
|
||||
<Window resizable>
|
||||
<Window.Content scrollable>
|
||||
@@ -259,8 +258,8 @@ export const SampleInterface = (props, context) => {
|
||||
);
|
||||
};
|
||||
|
||||
const HealthStatus = (props, context) => {
|
||||
const { act, data } = useBackend(context);
|
||||
const HealthStatus = (props) => {
|
||||
const { act, data } = useBackend();
|
||||
const { user } = props;
|
||||
const { health, color } = data;
|
||||
return (
|
||||
@@ -311,8 +310,8 @@ import { useBackend } from 'tgui/backend';
|
||||
import { Button, LabeledList, Section } from 'tgui-core/components';
|
||||
import { Window } from 'tgui/layouts';
|
||||
|
||||
export const SampleInterface = (props, context) => {
|
||||
const { act, data } = useBackend(context);
|
||||
export const SampleInterface = (props) => {
|
||||
const { act, data } = useBackend();
|
||||
// Extract `health` and `color` variables from the `data` object.
|
||||
const { health, color } = data;
|
||||
return (
|
||||
|
||||
@@ -45,7 +45,7 @@ export const ModifyRobotNoModule = (props: { target: Target }) => {
|
||||
<Section fill scrollable title="Active Restrictions">
|
||||
<Stack fill>
|
||||
<Stack.Item fillPositionedParent>
|
||||
{target.active_restrictions.map((active_restriction, i) => {
|
||||
{target.active_restrictions?.map((active_restriction, i) => {
|
||||
return (
|
||||
<Button
|
||||
fluid
|
||||
|
||||
@@ -124,8 +124,8 @@ export const ModifyRobotModules = (props: {
|
||||
};
|
||||
|
||||
const SelectionField = (props: {
|
||||
previewImage: string | undefined;
|
||||
previewImageSize: string | undefined;
|
||||
previewImage?: string;
|
||||
previewImageSize?: string | null;
|
||||
searchText: string;
|
||||
onSearchText: React.Dispatch<React.SetStateAction<string>>;
|
||||
action: string;
|
||||
|
||||
@@ -15,7 +15,7 @@ export type Data = {
|
||||
armour_options: Record<string, Comp>;
|
||||
current_gear: Record<string, string>;
|
||||
id_icon: string;
|
||||
access_options: Access[] | undefined;
|
||||
access_options?: Access[];
|
||||
ion_law_nr: string;
|
||||
ion_law: string;
|
||||
zeroth_law: string;
|
||||
@@ -53,10 +53,10 @@ export type Target = {
|
||||
emagged: BooleanLike;
|
||||
active: BooleanLike;
|
||||
crisis_override: BooleanLike;
|
||||
active_restrictions: string[];
|
||||
active_restrictions?: string[];
|
||||
possible_restrictions: string[];
|
||||
sprite: string | undefined;
|
||||
sprite_size: string | undefined;
|
||||
sprite?: string;
|
||||
sprite_size?: string | null;
|
||||
modules: Module[];
|
||||
whitelisted_upgrades: Upgrade[];
|
||||
blacklisted_upgrades: Upgrade[];
|
||||
@@ -66,8 +66,8 @@ export type Target = {
|
||||
restricted_upgrades: Upgrade[];
|
||||
radio_channels: string[];
|
||||
availalbe_channels: string[];
|
||||
pka: PKA | undefined;
|
||||
multibelt: Multibelt[] | undefined;
|
||||
pka?: PKA;
|
||||
multibelt?: Multibelt[];
|
||||
components: Component[];
|
||||
active_access: Access[];
|
||||
};
|
||||
@@ -75,13 +75,13 @@ export type Target = {
|
||||
export type Upgrade = {
|
||||
name: string;
|
||||
path: string;
|
||||
installed: number | undefined;
|
||||
installed?: number;
|
||||
};
|
||||
|
||||
export type Source = {
|
||||
model: string;
|
||||
sprite: string | undefined;
|
||||
sprite_size: string | undefined;
|
||||
sprite?: string;
|
||||
sprite_size?: string | null;
|
||||
modules: Module[];
|
||||
} | null;
|
||||
|
||||
@@ -149,8 +149,8 @@ export type Access = { id: number; name: string };
|
||||
|
||||
export type Lookup = {
|
||||
path: string;
|
||||
selected: string | undefined;
|
||||
active: string | undefined;
|
||||
selected?: string;
|
||||
active?: string;
|
||||
};
|
||||
|
||||
type law_pack = {
|
||||
|
||||
@@ -64,7 +64,9 @@ export const SpriteSection = (props) => {
|
||||
option={filter.sprite}
|
||||
action="pick_icon"
|
||||
selected={selected_chassis ?? pai_chassis}
|
||||
belly={filter.belly}
|
||||
icon={filter.belly ? 'utensils' : undefined}
|
||||
iconColor="lightgray"
|
||||
iconTooltip={'Module has belly sprite.'}
|
||||
/>
|
||||
))}
|
||||
</Stack>
|
||||
|
||||
@@ -7,9 +7,10 @@ import { SelectorElement } from './SelectorElement';
|
||||
export const ModuleSection = (props: {
|
||||
title: string;
|
||||
sortable?: string[];
|
||||
highlighted?: string[];
|
||||
selected?: string;
|
||||
}) => {
|
||||
const { title, sortable, selected } = props;
|
||||
const { title, sortable, highlighted, selected } = props;
|
||||
|
||||
const [searchText, setSearchText] = useState<string>('');
|
||||
|
||||
@@ -39,6 +40,13 @@ export const ModuleSection = (props: {
|
||||
<SelectorElement
|
||||
key={filter}
|
||||
option={filter}
|
||||
icon={
|
||||
highlighted?.includes(filter)
|
||||
? 'circle-exclamation'
|
||||
: undefined
|
||||
}
|
||||
iconTooltip={'Module is whitelisted!'}
|
||||
iconColor="red"
|
||||
action="pick_module"
|
||||
selected={selected}
|
||||
/>
|
||||
|
||||
@@ -1,14 +1,16 @@
|
||||
import { useBackend } from 'tgui/backend';
|
||||
import { Button, Icon, Stack } from 'tgui-core/components';
|
||||
import { Button, Icon, Stack, Tooltip } from 'tgui-core/components';
|
||||
|
||||
export const SelectorElement = (props: {
|
||||
option: string;
|
||||
action: string;
|
||||
selected?: string | null;
|
||||
belly?: boolean;
|
||||
icon?: string;
|
||||
iconTooltip?: string;
|
||||
iconColor?: string;
|
||||
}) => {
|
||||
const { act } = useBackend();
|
||||
const { option, action, selected, belly } = props;
|
||||
const { option, action, selected, icon, iconTooltip, iconColor } = props;
|
||||
|
||||
return (
|
||||
<Stack.Item>
|
||||
@@ -18,14 +20,13 @@ export const SelectorElement = (props: {
|
||||
onClick={() => act(action, { value: option })}
|
||||
>
|
||||
<Stack>
|
||||
<Stack.Item>{option}</Stack.Item>
|
||||
{!!belly && (
|
||||
<>
|
||||
<Stack.Item grow />
|
||||
<Stack.Item>
|
||||
<Icon name="utensils" />
|
||||
</Stack.Item>
|
||||
</>
|
||||
<Stack.Item grow>{option}</Stack.Item>
|
||||
{!!icon && (
|
||||
<Stack.Item>
|
||||
<Tooltip content={iconTooltip}>
|
||||
<Icon name={icon} color={iconColor} />
|
||||
</Tooltip>
|
||||
</Stack.Item>
|
||||
)}
|
||||
</Stack>
|
||||
</Button>
|
||||
|
||||
@@ -77,7 +77,9 @@ export const SpriteSection = (props: {
|
||||
option={filter.sprite}
|
||||
action="pick_icon"
|
||||
selected={selected}
|
||||
belly={filter.belly}
|
||||
icon={filter.belly ? 'utensils' : undefined}
|
||||
iconColor="lightgray"
|
||||
iconTooltip={'Module has belly sprite.'}
|
||||
/>
|
||||
))}
|
||||
</Stack>
|
||||
|
||||
@@ -12,6 +12,7 @@ export const RobotChoose = (props) => {
|
||||
|
||||
const {
|
||||
possible_modules,
|
||||
whitelisted_modules,
|
||||
possible_sprites,
|
||||
selected_module,
|
||||
sprite_datum,
|
||||
@@ -31,6 +32,7 @@ export const RobotChoose = (props) => {
|
||||
<ModuleSection
|
||||
title="Modules"
|
||||
sortable={possible_modules}
|
||||
highlighted={whitelisted_modules}
|
||||
selected={selected_module}
|
||||
/>
|
||||
</Stack.Item>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
export type Data = {
|
||||
possible_modules: string[];
|
||||
whitelisted_modules: string[];
|
||||
mind_name: string;
|
||||
possible_sprites?: spriteOption[];
|
||||
currentName: string;
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
import { useState } from 'react';
|
||||
import { useBackend } from 'tgui/backend';
|
||||
import {
|
||||
Button,
|
||||
Dropdown,
|
||||
Input,
|
||||
LabeledList,
|
||||
Section,
|
||||
Stack,
|
||||
} from 'tgui-core/components';
|
||||
import { capitalize } from 'tgui-core/string';
|
||||
import type { Data } from './types';
|
||||
|
||||
export const WhitelistAddEnttry = (props: {
|
||||
type: string;
|
||||
entries: string[];
|
||||
}) => {
|
||||
const { act } = useBackend<Data>();
|
||||
const { type, entries } = props;
|
||||
const [selectedRole, setSelectedRole] = useState('');
|
||||
const [ckey, setCkey] = useState('');
|
||||
return (
|
||||
<Stack.Item>
|
||||
<Section
|
||||
fill
|
||||
title={capitalize(type)}
|
||||
buttons={
|
||||
<Button
|
||||
disabled={!selectedRole || !ckey}
|
||||
onClick={() =>
|
||||
act('add_alienwhitelist', {
|
||||
ckey: ckey.toLocaleLowerCase(),
|
||||
type: type,
|
||||
role: selectedRole,
|
||||
})
|
||||
}
|
||||
color="green"
|
||||
>
|
||||
Add
|
||||
</Button>
|
||||
}
|
||||
>
|
||||
<LabeledList>
|
||||
<LabeledList.Item label="Role">
|
||||
<Dropdown
|
||||
onSelected={setSelectedRole}
|
||||
options={entries}
|
||||
selected={selectedRole}
|
||||
/>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Ckey">
|
||||
<Stack>
|
||||
<Stack.Item>
|
||||
<Input fluid value={ckey} onChange={setCkey} />
|
||||
</Stack.Item>
|
||||
<Stack.Item>
|
||||
<Button
|
||||
disabled={!ckey}
|
||||
color="red"
|
||||
onClick={() => setCkey('')}
|
||||
>
|
||||
X
|
||||
</Button>
|
||||
</Stack.Item>
|
||||
</Stack>
|
||||
</LabeledList.Item>
|
||||
</LabeledList>
|
||||
</Section>
|
||||
</Stack.Item>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,75 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
import { useBackend } from 'tgui/backend';
|
||||
import {
|
||||
Button,
|
||||
Dropdown,
|
||||
LabeledList,
|
||||
Section,
|
||||
Stack,
|
||||
} from 'tgui-core/components';
|
||||
import { capitalize } from 'tgui-core/string';
|
||||
import type { Data } from './types';
|
||||
|
||||
export const WhitelistRemoveEntry = (props: {
|
||||
type: string;
|
||||
entries: Record<string, string[] | null>;
|
||||
}) => {
|
||||
const { act } = useBackend<Data>();
|
||||
const { type, entries } = props;
|
||||
const [selectedRole, setSelectedRole] = useState('');
|
||||
const [ckey, setCkey] = useState('');
|
||||
|
||||
const ckeys = Object.keys(entries);
|
||||
useEffect(() => {
|
||||
if (!entries[ckey]?.length) {
|
||||
setSelectedRole('');
|
||||
}
|
||||
if (!entries[ckey]) {
|
||||
setCkey('');
|
||||
}
|
||||
}, [entries]);
|
||||
|
||||
function handleCkey(newKey: string) {
|
||||
setCkey(newKey);
|
||||
if (entries[newKey]?.length) {
|
||||
setSelectedRole(entries[newKey][0]);
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<Stack.Item>
|
||||
<Section
|
||||
fill
|
||||
title={capitalize(type)}
|
||||
buttons={
|
||||
<Button
|
||||
disabled={!selectedRole || !ckey}
|
||||
onClick={() =>
|
||||
act('remove_alienwhitelist', {
|
||||
ckey: ckey.toLocaleLowerCase(),
|
||||
type: type,
|
||||
role: selectedRole,
|
||||
})
|
||||
}
|
||||
color="red"
|
||||
>
|
||||
Remove
|
||||
</Button>
|
||||
}
|
||||
>
|
||||
<LabeledList>
|
||||
<LabeledList.Item label="Ckey">
|
||||
<Dropdown onSelected={handleCkey} options={ckeys} selected={ckey} />
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Role">
|
||||
<Dropdown
|
||||
onSelected={setSelectedRole}
|
||||
options={entries[ckey] ?? []}
|
||||
selected={selectedRole}
|
||||
/>
|
||||
</LabeledList.Item>
|
||||
</LabeledList>
|
||||
</Section>
|
||||
</Stack.Item>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,90 @@
|
||||
import { useBackend } from 'tgui/backend';
|
||||
import { Window } from 'tgui/layouts';
|
||||
import { Button, Section, Stack } from 'tgui-core/components';
|
||||
import type { Data } from './types';
|
||||
import { WhitelistAddEnttry } from './WhitelistAddEnttry';
|
||||
import { WhitelistRemoveEntry } from './WhitelistRemoveEntry';
|
||||
|
||||
export const WhitelistEdit = () => {
|
||||
const { data, act } = useBackend<Data>();
|
||||
const {
|
||||
alienwhitelist,
|
||||
languagewhitelist,
|
||||
robotwhitelist,
|
||||
jobwhitelist,
|
||||
species_with_whitelist,
|
||||
language_with_whitelist,
|
||||
robot_with_whitelist,
|
||||
jobs_with_whitelist,
|
||||
} = data;
|
||||
|
||||
const possibleAdds = {
|
||||
species: species_with_whitelist,
|
||||
language: language_with_whitelist,
|
||||
robot: robot_with_whitelist,
|
||||
job: jobs_with_whitelist,
|
||||
};
|
||||
|
||||
const possibleRemovals = {
|
||||
species: alienwhitelist,
|
||||
language: languagewhitelist,
|
||||
robot: robotwhitelist,
|
||||
job: jobwhitelist,
|
||||
};
|
||||
|
||||
return (
|
||||
<Window width={530} height={495} theme="admin">
|
||||
<Window.Content>
|
||||
<Stack vertical fill>
|
||||
<Stack.Item>
|
||||
<Stack>
|
||||
<Stack.Item grow />
|
||||
<Stack.Item>
|
||||
<Button
|
||||
onClick={() => act('reload_alienwhitelist')}
|
||||
tooltip="Reloads the alien whitelist (Species, Languages, Robots)"
|
||||
>
|
||||
Reload Alien Whitelist
|
||||
</Button>
|
||||
</Stack.Item>
|
||||
<Stack.Item>
|
||||
<Button
|
||||
onClick={() => act('reload_jobwhitelist')}
|
||||
tooltip="Reloads the jon whitelist"
|
||||
>
|
||||
Reload Job Whitelist
|
||||
</Button>
|
||||
</Stack.Item>
|
||||
</Stack>
|
||||
</Stack.Item>
|
||||
<Stack.Item grow>
|
||||
<Stack fill>
|
||||
<Stack.Item>
|
||||
<Section fill title="Add">
|
||||
<Stack vertical fill>
|
||||
{Object.entries(possibleAdds).map(([type, value]) => (
|
||||
<Stack.Item key={type}>
|
||||
<WhitelistAddEnttry type={type} entries={value} />
|
||||
</Stack.Item>
|
||||
))}
|
||||
</Stack>
|
||||
</Section>
|
||||
</Stack.Item>
|
||||
<Stack.Item>
|
||||
<Section fill title="Remove">
|
||||
<Stack vertical fill>
|
||||
{Object.entries(possibleRemovals).map(([type, value]) => (
|
||||
<Stack.Item key={type}>
|
||||
<WhitelistRemoveEntry type={type} entries={value} />
|
||||
</Stack.Item>
|
||||
))}
|
||||
</Stack>
|
||||
</Section>
|
||||
</Stack.Item>
|
||||
</Stack>
|
||||
</Stack.Item>
|
||||
</Stack>
|
||||
</Window.Content>
|
||||
</Window>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,11 @@
|
||||
export type Data = {
|
||||
species_with_whitelist: string[];
|
||||
language_with_whitelist: string[];
|
||||
robot_with_whitelist: string[];
|
||||
jobs_with_whitelist: string[];
|
||||
|
||||
alienwhitelist: Record<string, string[] | null>;
|
||||
languagewhitelist: Record<string, string[] | null>;
|
||||
robotwhitelist: Record<string, string[] | null>;
|
||||
jobwhitelist: Record<string, string[] | null>;
|
||||
};
|
||||
@@ -3607,6 +3607,7 @@
|
||||
#include "code\modules\mob\living\silicon\robot\drone\swarm_abilities.dm"
|
||||
#include "code\modules\mob\living\silicon\robot\drone\swarm_items.dm"
|
||||
#include "code\modules\mob\living\silicon\robot\robot_modules\event.dm"
|
||||
#include "code\modules\mob\living\silicon\robot\robot_modules\module.dm"
|
||||
#include "code\modules\mob\living\silicon\robot\robot_modules\station.dm"
|
||||
#include "code\modules\mob\living\silicon\robot\robot_modules\swarm.dm"
|
||||
#include "code\modules\mob\living\silicon\robot\robot_modules\syndicate.dm"
|
||||
@@ -3631,6 +3632,7 @@
|
||||
#include "code\modules\mob\living\silicon\robot\sprites\sprite_organized\xenoborgs.dm"
|
||||
#include "code\modules\mob\living\silicon\robot\subtypes\gravekeeper.dm"
|
||||
#include "code\modules\mob\living\silicon\robot\subtypes\lost_drone.dm"
|
||||
#include "code\modules\mob\living\silicon\robot\subtypes\malf_robot.dm"
|
||||
#include "code\modules\mob\living\silicon\robot\subtypes\syndicate.dm"
|
||||
#include "code\modules\mob\living\silicon\robot\subtypes\exploration\exploration-modules.dm"
|
||||
#include "code\modules\mob\living\silicon\robot\subtypes\exploration\exploration-sprites.dm"
|
||||
|
||||
Reference in New Issue
Block a user