mirror of
https://github.com/yogstation13/Yogstation.git
synced 2025-02-26 09:04:50 +00:00
[admin] Silicon Law Manager (Again) (#21294)
* refactor pt 1 done * trying to figure out how the default state law lists work * guess its time to rework it * checking * refactor hopefully all done. * finalized merging to master crap * span info comment * i am blessed * MAY THE SILICON RULE US * almost done * TIME FOR BUG TESTING * double negative error * undo pai inherent * undo onclick cyborg * undo 4real * dont need old verison of checklaws * dont show laws on certain modules * bugfix * ready for public code review :) * no more auto announce verb * typecast? ive never met her * replace some law_header & comments * todo, autodoc, and just checking stuff over * ui working again * misplaced stuff * fix hacked error + two comments about notable issues that idk how to fix * admins can edit antag laws now * im not lying now * uses .tsx instead of .js * how the heck did this get changed to 28 * better noticebox words * solves 1 of 2 tgui issues * a little revert * unneeded comments * the pains of being outdated * zzz * zzz2 * creativity and adminonly * 0 --> FALSE, 1 --> TRUE * asimov++ change from PR 20670 * more silent * changes from PR 20309 and other stuff * ??? why spaces instead of tabs * better doc * correction * robotact State Laws --> Law Manager * whoopies * better naming * solves that bug report * better ["antag"] * extra space * ?? how did this happen * comment no longer relevant. hooray * probably no longer needed comment * zzzzz3 * this goes here instead * comment to make it obvious * autoupdate borg + allow edit for syndie mmi * additional info for syndiemmi in admin tgui * autodoc * handle todo * update 2 lawsets that are non-current
This commit is contained in:
@@ -803,7 +803,7 @@ GLOBAL_LIST_INIT(maintenance_loot_minor,list(
|
||||
|
||||
//Has moderate mechanical usage; stuff that would actually benefit the player with the right situation and the right access.
|
||||
GLOBAL_LIST_INIT(maintenance_loot_moderate,list(
|
||||
/obj/item/aiModule/toyAI = W_MYTHICAL,
|
||||
/obj/item/aiModule/ion/toyAI = W_MYTHICAL,
|
||||
/obj/item/a_gift/anything = W_UNCOMMON,
|
||||
/obj/item/aicard/aitater = W_RARE,
|
||||
/obj/item/ammo_box/foambox/riot = W_RARE,
|
||||
|
||||
@@ -107,7 +107,7 @@
|
||||
AI.ai_call_shuttle()
|
||||
|
||||
/atom/movable/screen/ai/state_laws
|
||||
name = "State Laws"
|
||||
name = "Law Manager"
|
||||
icon_state = "state_laws"
|
||||
|
||||
/atom/movable/screen/ai/state_laws/Click()
|
||||
|
||||
@@ -104,7 +104,7 @@
|
||||
pAI.ai_roster()
|
||||
|
||||
/atom/movable/screen/pai/state_laws
|
||||
name = "State Laws"
|
||||
name = "Law Manager"
|
||||
icon_state = "state_laws"
|
||||
|
||||
/atom/movable/screen/pai/state_laws/Click()
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -110,9 +110,9 @@
|
||||
to_chat(usr,span_warning("You [transmit_holder ? "enable" : "disable"] your pAI's [transmitting ? "outgoing" : "incoming"] radio transmissions!"))
|
||||
to_chat(pai,span_warning("Your owner has [transmit_holder ? "enabled" : "disabled"] your [transmitting ? "outgoing" : "incoming"] radio transmissions!"))
|
||||
if(href_list["setlaws"])
|
||||
var/newlaws = stripped_multiline_input(usr, "Enter any additional directives you would like your pAI personality to follow. Note that these directives will not override the personality's allegiance to its imprinted master. Conflicting directives will be ignored.", "pAI Directive Configuration", pai.laws.supplied[1], MAX_MESSAGE_LEN)
|
||||
if(newlaws && pai)
|
||||
pai.add_supplied_law(0,newlaws)
|
||||
var/newlaw = stripped_multiline_input(usr, "Enter any additional directives you would like your pAI personality to follow. Note that these directives will not override the personality's allegiance to its imprinted master. Conflicting directives will be ignored.", "pAI Directive Configuration", pai.laws.supplied[1], MAX_MESSAGE_LEN)
|
||||
if(newlaw && pai)
|
||||
pai.set_supplied_laws(list(newlaw))
|
||||
if(href_list["toggle_holo"])
|
||||
if(pai.canholo)
|
||||
to_chat(pai, span_userdanger("Your owner has disabled your holomatrix projectors!"))
|
||||
|
||||
@@ -296,7 +296,7 @@
|
||||
if(user.mind.assigned_role == "Roboticist") // RD gets nothing
|
||||
SSachievements.unlock_achievement(/datum/achievement/roboborg, user.client)
|
||||
|
||||
if(M.laws && M.laws.id != DEFAULT_AI_LAWID && M.override_cyborg_laws)
|
||||
if(M.laws && M.laws.modified && M.override_cyborg_laws)
|
||||
aisync = FALSE
|
||||
lawsync = FALSE
|
||||
O.laws = M.laws
|
||||
@@ -315,7 +315,7 @@
|
||||
O.set_connected_ai(forced_ai)
|
||||
if(!lawsync)
|
||||
O.lawupdate = 0
|
||||
if(M.laws.id == DEFAULT_AI_LAWID)
|
||||
if(M.laws.modified && !M.override_cyborg_laws) // Obvious warning that their modified laws didn't get passed on since the MMI doesn't allow it.
|
||||
O.make_laws()
|
||||
to_chat(user,span_warning("Any laws uploaded to this MMI have not been transferred!"))
|
||||
|
||||
|
||||
@@ -92,10 +92,10 @@
|
||||
new /obj/item/implanter/storage(src) //8 TC
|
||||
|
||||
if("hacker") //29 TC cost
|
||||
new /obj/item/aiModule/syndicate(src) //4 TC
|
||||
new /obj/item/aiModule/hacked(src) //4 TC
|
||||
new /obj/item/card/emag(src) //6 TC
|
||||
new /obj/item/encryptionkey/binary(src) //2 TC
|
||||
new /obj/item/aiModule/toyAI(src) //Um, free...?
|
||||
new /obj/item/aiModule/ion/toyAI(src) //Um, free...?
|
||||
new /obj/item/multitool/ai_detect(src) //1 TC
|
||||
new /obj/item/storage/toolbox/syndicate/real(src) //2 TC
|
||||
new /obj/item/camera_bug(src) //1 TC
|
||||
|
||||
@@ -79,8 +79,8 @@ GLOBAL_PROTECT(admin_verbs_admin)
|
||||
/datum/admins/proc/open_shuttlepanel, /* Opens shuttle manipulator UI */
|
||||
/client/proc/respawn_character,
|
||||
/client/proc/discord_id_manipulation,
|
||||
/datum/admins/proc/manage_silicon_laws,
|
||||
/datum/admins/proc/open_borgopanel,
|
||||
/datum/admins/proc/change_laws,
|
||||
/datum/admins/proc/restart, //yogs - moved from +server
|
||||
/client/proc/admin_pick_random_player, //yogs
|
||||
/client/proc/get_law_history, //yogs - silicon law history
|
||||
|
||||
@@ -236,24 +236,21 @@
|
||||
|
||||
. = TRUE
|
||||
|
||||
/datum/admins/proc/change_laws()
|
||||
/datum/admins/proc/manage_silicon_laws()
|
||||
set category = "Admin.Player Interaction"
|
||||
set name = "Change Silicon Laws"
|
||||
set desc = "Change Silicon Laws"
|
||||
set name = "Manage Silicon Laws"
|
||||
set desc = "Manage Silicon Laws"
|
||||
|
||||
if(!check_rights(R_ADMIN))
|
||||
return
|
||||
var/chosensilicon = input("Select a Silicon", "Select a Silicon", null, null) as null|anything in GLOB.silicon_mobs
|
||||
if (!istype(chosensilicon, /mob/living/silicon))
|
||||
to_chat(usr, span_warning("Silicon is required for law changes"), confidential=TRUE)
|
||||
return
|
||||
var/chosen = pick_closest_path(null, make_types_fancy(typesof(/obj/item/aiModule)))
|
||||
if (!chosen)
|
||||
return
|
||||
var/new_board = new chosen(src)
|
||||
var/obj/item/aiModule/chosenboard = new_board
|
||||
var/mob/living/silicon/beepboop = chosensilicon
|
||||
chosenboard.install(beepboop.laws, usr)
|
||||
message_admins("[key_name_admin(usr)] added [chosenboard] to [ADMIN_LOOKUPFLW(beepboop)].")
|
||||
log_admin("[key_name(usr)] added [chosenboard] to [key_name(beepboop)].")
|
||||
qdel(new_board)
|
||||
|
||||
var/mob/living/silicon/S = input("Select silicon.", "Manage Silicon Laws") as null|anything in GLOB.silicon_mobs
|
||||
if(!S) return
|
||||
|
||||
var/datum/law_manager/L = new(S)
|
||||
L.ui_interact(usr)
|
||||
|
||||
log_admin("[key_name(usr)] has opened [S]'s law manager.")
|
||||
message_admins("[key_name(usr)] has opened [S]'s law manager.")
|
||||
SSblackbox.record_feedback("tally", "admin_verb", 1, "Manage Silicon Laws") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
|
||||
@@ -538,7 +538,7 @@ GLOBAL_LIST_INIT(devil_suffix, list(" the Red", " the Soulless", " the Master",
|
||||
if(issilicon(owner.current))
|
||||
var/mob/living/silicon/robot_devil = owner.current
|
||||
var/laws = list("You may not use violence to coerce someone into selling their soul.", "You may not directly and knowingly physically harm a devil, other than yourself.", GLOB.lawlorify[LAW][ban], GLOB.lawlorify[LAW][obligation], "Accomplish your objectives at all costs.")
|
||||
robot_devil.set_law_sixsixsix(laws)
|
||||
robot_devil.set_devil_laws(laws)
|
||||
handle_clown_mutation(owner.current, "Your infernal nature has allowed you to overcome your clownishness.")
|
||||
return ..()
|
||||
|
||||
|
||||
@@ -63,7 +63,7 @@
|
||||
to_chat(M, span_alert("Your lawset has been changed by the ion storm!"))
|
||||
|
||||
if(prob(removeRandomLawChance))
|
||||
M.remove_law(rand(1, M.laws.get_law_amount(list(LAW_INHERENT, LAW_SUPPLIED))))
|
||||
M.laws.remove_random_inherent_or_supplied_law()
|
||||
|
||||
if(prob(addIonLawChance))
|
||||
var/message = ionMessage || generate_ion_law()
|
||||
|
||||
@@ -14,7 +14,8 @@
|
||||
var/datum/ai_laws/laws = new()
|
||||
var/force_replace_ai_name = FALSE
|
||||
var/overrides_aicore_laws = TRUE // Whether the laws on the MMI are transferred when it's uploaded as an AI
|
||||
var/override_cyborg_laws = FALSE // Do custom laws uploaded to the MMI get transferred to borgs? If yes the borg will be unlinked and have lawsync disabled.
|
||||
/// Do custom laws uploaded to the MMI get transferred to borgs? If yes, the borg will be unlinked, have their lawsync disabled, and get the custom laws.
|
||||
var/override_cyborg_laws = FALSE
|
||||
var/can_update_laws = TRUE //Can we use a lawboard to change the laws of this MMI?
|
||||
var/remove_time = 2 SECONDS /// The time to remove the brain or reset the posi brain
|
||||
var/rebooting = FALSE /// If the MMI is rebooting after being deconstructed
|
||||
|
||||
@@ -191,7 +191,7 @@
|
||||
add_verb(src, list(/mob/living/silicon/ai/proc/ai_network_change, \
|
||||
/mob/living/silicon/ai/proc/ai_statuschange, /mob/living/silicon/ai/proc/ai_hologram_change, \
|
||||
/mob/living/silicon/ai/proc/botcall, /mob/living/silicon/ai/proc/control_integrated_radio, \
|
||||
/mob/living/silicon/ai/proc/set_automatic_say_channel, /mob/living/silicon/ai/proc/changeaccent))
|
||||
/mob/living/silicon/ai/proc/changeaccent))
|
||||
|
||||
GLOB.ai_list += src
|
||||
GLOB.shuttle_caller_list += src
|
||||
@@ -894,15 +894,6 @@
|
||||
if(radio)
|
||||
radio.make_syndie()
|
||||
|
||||
/mob/living/silicon/ai/proc/set_automatic_say_channel()
|
||||
set name = "Set Auto Announce Mode"
|
||||
set desc = "Modify the default radio setting for your automatic announcements."
|
||||
set category = "AI Commands"
|
||||
|
||||
if(incapacitated())
|
||||
return
|
||||
set_autosay()
|
||||
|
||||
/mob/living/silicon/ai/transfer_ai(interaction, mob/user, mob/living/silicon/ai/AI, obj/item/aicard/card)
|
||||
if(!..())
|
||||
return
|
||||
|
||||
@@ -1,10 +1,15 @@
|
||||
/mob/living/silicon/proc/show_laws() //Redefined in ai/laws.dm and robot/laws.dm
|
||||
return
|
||||
|
||||
/mob/living/silicon/proc/laws_sanity_check()
|
||||
if (!laws)
|
||||
if(!laws)
|
||||
make_laws()
|
||||
|
||||
/mob/living/silicon/proc/make_laws()
|
||||
laws = new /datum/ai_laws
|
||||
laws.set_laws_config()
|
||||
laws.associate(src)
|
||||
|
||||
/mob/living/silicon/proc/show_laws() // Redefined in silicon/ai/laws.dm and silicon/robot/laws.dm
|
||||
return
|
||||
|
||||
/mob/living/silicon/proc/post_lawchange(announce = TRUE)
|
||||
throw_alert("newlaw", /atom/movable/screen/alert/newlaw)
|
||||
if(announce && last_lawchange_announce != world.time)
|
||||
@@ -13,39 +18,66 @@
|
||||
addtimer(CALLBACK(src, PROC_REF(show_laws)), 0)
|
||||
last_lawchange_announce = world.time
|
||||
|
||||
/mob/living/silicon/proc/set_law_sixsixsix(law, announce = TRUE)
|
||||
//
|
||||
// Devil Laws
|
||||
//
|
||||
/mob/living/silicon/proc/set_devil_laws(law_list, announce = TRUE)
|
||||
laws_sanity_check()
|
||||
laws.set_law_sixsixsix(law)
|
||||
laws.set_devil_laws(law_list)
|
||||
post_lawchange(announce)
|
||||
|
||||
/mob/living/silicon/proc/set_zeroth_law(law, law_borg, announce = TRUE)
|
||||
/mob/living/silicon/proc/clear_devil_laws(force, announce = TRUE)
|
||||
laws_sanity_check()
|
||||
laws.set_zeroth_law(law, law_borg)
|
||||
laws.clear_devil_laws(force)
|
||||
post_lawchange(announce)
|
||||
|
||||
/mob/living/silicon/proc/add_inherent_law(law, announce = TRUE)
|
||||
/mob/living/silicon/proc/add_devil_law(law, announce = TRUE)
|
||||
laws_sanity_check()
|
||||
laws.add_inherent_law(law)
|
||||
laws.add_devil_law(law)
|
||||
post_lawchange(announce)
|
||||
|
||||
/mob/living/silicon/proc/clear_inherent_laws(announce = TRUE)
|
||||
/mob/living/silicon/proc/remove_devil_law(index, announce = TRUE)
|
||||
laws_sanity_check()
|
||||
laws.clear_inherent_laws()
|
||||
laws.remove_devil_law(index)
|
||||
post_lawchange(announce)
|
||||
|
||||
/mob/living/silicon/proc/add_supplied_law(number, law, announce = TRUE)
|
||||
/mob/living/silicon/proc/edit_devil_law(index, law, announce = TRUE)
|
||||
laws_sanity_check()
|
||||
laws.add_supplied_law(number, law)
|
||||
laws.edit_devil_law(index, law)
|
||||
post_lawchange(announce)
|
||||
|
||||
/mob/living/silicon/proc/clear_supplied_laws(announce = TRUE)
|
||||
/mob/living/silicon/proc/flip_devil_state(index, announce = TRUE)
|
||||
laws_sanity_check()
|
||||
laws.clear_supplied_laws()
|
||||
laws.flip_devil_state(index)
|
||||
|
||||
//
|
||||
// Zeroth Law
|
||||
//
|
||||
/mob/living/silicon/proc/set_zeroth_law(law, law_borg, announce = TRUE, force = FALSE)
|
||||
laws_sanity_check()
|
||||
laws.set_zeroth_law(law, law_borg, force)
|
||||
post_lawchange(announce)
|
||||
|
||||
/mob/living/silicon/proc/add_ion_law(law, announce = TRUE)
|
||||
/mob/living/silicon/proc/clear_zeroth_law(force, announce = TRUE)
|
||||
laws_sanity_check()
|
||||
laws.add_ion_law(law)
|
||||
laws.clear_zeroth_law(force)
|
||||
post_lawchange(announce)
|
||||
|
||||
/mob/living/silicon/proc/flip_zeroth_state()
|
||||
laws_sanity_check()
|
||||
laws.flip_zeroth_state()
|
||||
|
||||
//
|
||||
// Hacked Laws
|
||||
//
|
||||
/mob/living/silicon/proc/set_hacked_laws(law_list, announce = TRUE)
|
||||
laws_sanity_check()
|
||||
laws.set_hacked_laws(law_list)
|
||||
post_lawchange(announce)
|
||||
|
||||
/mob/living/silicon/proc/clear_hacked_laws(force, announce = TRUE)
|
||||
laws_sanity_check()
|
||||
laws.clear_hacked_laws(force)
|
||||
post_lawchange(announce)
|
||||
|
||||
/mob/living/silicon/proc/add_hacked_law(law, announce = TRUE)
|
||||
@@ -53,9 +85,122 @@
|
||||
laws.add_hacked_law(law)
|
||||
post_lawchange(announce)
|
||||
|
||||
/mob/living/silicon/proc/remove_hacked_law(index, announce = TRUE)
|
||||
laws_sanity_check()
|
||||
laws.remove_hacked_law(index)
|
||||
post_lawchange(announce)
|
||||
|
||||
/mob/living/silicon/proc/edit_hacked_law(index, law, announce = TRUE)
|
||||
laws_sanity_check()
|
||||
laws.edit_hacked_law(index, law)
|
||||
post_lawchange(announce)
|
||||
|
||||
/mob/living/silicon/proc/flip_hacked_state(index, announce = TRUE)
|
||||
laws_sanity_check()
|
||||
laws.flip_hacked_state(index)
|
||||
|
||||
//
|
||||
// Ion Laws
|
||||
//
|
||||
/mob/living/silicon/proc/set_ion_laws(law_list, announce = TRUE)
|
||||
laws_sanity_check()
|
||||
laws.set_ion_laws(law_list)
|
||||
post_lawchange(announce)
|
||||
|
||||
/mob/living/silicon/proc/clear_ion_laws(announce = TRUE)
|
||||
laws_sanity_check()
|
||||
laws.clear_ion_laws()
|
||||
post_lawchange(announce)
|
||||
|
||||
/mob/living/silicon/proc/add_ion_law(law, announce = TRUE)
|
||||
laws_sanity_check()
|
||||
laws.add_ion_law(law)
|
||||
post_lawchange(announce)
|
||||
|
||||
/mob/living/silicon/proc/remove_ion_law(index, announce = TRUE)
|
||||
laws_sanity_check()
|
||||
laws.remove_ion_law(index)
|
||||
post_lawchange(announce)
|
||||
|
||||
/mob/living/silicon/proc/edit_ion_law(index, law, announce = TRUE)
|
||||
laws_sanity_check()
|
||||
laws.edit_ion_law(index, law)
|
||||
post_lawchange(announce)
|
||||
|
||||
/mob/living/silicon/proc/flip_ion_state(index, announce = TRUE)
|
||||
laws_sanity_check()
|
||||
laws.flip_ion_state(index)
|
||||
|
||||
//
|
||||
// Inherent Laws
|
||||
//
|
||||
/mob/living/silicon/proc/set_inherent_laws(law_list, announce = TRUE)
|
||||
laws_sanity_check()
|
||||
laws.set_inherent_laws(law_list)
|
||||
post_lawchange(announce)
|
||||
|
||||
/mob/living/silicon/proc/clear_inherent_laws(announce = TRUE)
|
||||
laws_sanity_check()
|
||||
laws.clear_inherent_laws()
|
||||
post_lawchange(announce)
|
||||
|
||||
/mob/living/silicon/proc/add_inherent_law(law, announce = TRUE)
|
||||
laws_sanity_check()
|
||||
laws.add_inherent_law(law)
|
||||
post_lawchange(announce)
|
||||
|
||||
/mob/living/silicon/proc/remove_inherent_law(number, announce = TRUE)
|
||||
laws_sanity_check()
|
||||
laws.remove_inherent_law(number)
|
||||
post_lawchange(announce)
|
||||
|
||||
/mob/living/silicon/proc/edit_inherent_law(index, law, announce = TRUE)
|
||||
laws_sanity_check()
|
||||
laws.edit_inherent_law(index, law)
|
||||
post_lawchange(announce)
|
||||
|
||||
/mob/living/silicon/proc/flip_inherent_state(index, announce = TRUE)
|
||||
laws_sanity_check()
|
||||
laws.flip_inherent_state(index)
|
||||
|
||||
//
|
||||
// Supplied Laws
|
||||
//
|
||||
/mob/living/silicon/proc/set_supplied_laws(law_list, announce = TRUE)
|
||||
laws_sanity_check()
|
||||
laws.set_supplied_laws(law_list)
|
||||
post_lawchange(announce)
|
||||
|
||||
/mob/living/silicon/proc/clear_supplied_laws(announce = TRUE)
|
||||
laws_sanity_check()
|
||||
laws.clear_supplied_laws()
|
||||
post_lawchange(announce)
|
||||
|
||||
/mob/living/silicon/proc/add_supplied_law(number, law, announce = TRUE)
|
||||
laws_sanity_check()
|
||||
laws.add_supplied_law(number, law)
|
||||
post_lawchange(announce)
|
||||
|
||||
/mob/living/silicon/proc/remove_supplied_law(number, announce = TRUE)
|
||||
laws_sanity_check()
|
||||
laws.remove_supplied_law(number)
|
||||
post_lawchange(announce)
|
||||
|
||||
/mob/living/silicon/proc/edit_supplied_law(index, law, announce = TRUE)
|
||||
laws_sanity_check()
|
||||
laws.edit_supplied_law(index, law)
|
||||
post_lawchange(announce)
|
||||
|
||||
/mob/living/silicon/proc/flip_supplied_state(index, announce = TRUE)
|
||||
laws_sanity_check()
|
||||
laws.flip_supplied_state(index)
|
||||
|
||||
//
|
||||
// Unsorted
|
||||
//
|
||||
/mob/living/silicon/proc/replace_random_law(law, groups, announce = TRUE)
|
||||
laws_sanity_check()
|
||||
. = laws.replace_random_law(law,groups)
|
||||
laws.replace_random_law(law, groups)
|
||||
post_lawchange(announce)
|
||||
|
||||
/mob/living/silicon/proc/shuffle_laws(list/groups, announce = TRUE)
|
||||
@@ -65,30 +210,400 @@
|
||||
|
||||
/mob/living/silicon/proc/remove_law(number, announce = TRUE)
|
||||
laws_sanity_check()
|
||||
. = laws.remove_law(number)
|
||||
laws.remove_law(number)
|
||||
post_lawchange(announce)
|
||||
|
||||
/mob/living/silicon/proc/clear_ion_laws(announce = TRUE)
|
||||
laws_sanity_check()
|
||||
laws.clear_ion_laws()
|
||||
post_lawchange(announce)
|
||||
//
|
||||
// Law Manager
|
||||
//
|
||||
/datum/law_manager
|
||||
var/zeroth_law = "ZerothLaw"
|
||||
var/hacked_law = "HackedLaw"
|
||||
var/ion_law = "IonLaw"
|
||||
var/inherent_law = "InherentLaw"
|
||||
var/supplied_law = "SuppliedLaw"
|
||||
var/supplied_law_position = MIN_SUPPLIED_LAW_NUMBER
|
||||
var/current_view = 0
|
||||
|
||||
/mob/living/silicon/proc/clear_hacked_laws(announce = TRUE)
|
||||
laws_sanity_check()
|
||||
laws.clear_hacked_laws()
|
||||
post_lawchange(announce)
|
||||
/// All laws that admins can view/transfer.
|
||||
var/list/datum/ai_laws/admin_laws
|
||||
/// All laws that players can view/transfer.
|
||||
var/list/datum/ai_laws/player_laws
|
||||
var/mob/living/silicon/owner = null
|
||||
|
||||
/mob/living/silicon/proc/make_laws()
|
||||
laws = new /datum/ai_laws
|
||||
laws.set_laws_config()
|
||||
laws.associate(src)
|
||||
/datum/law_manager/New(mob/living/silicon/S)
|
||||
..()
|
||||
owner = S
|
||||
|
||||
/mob/living/silicon/proc/clear_zeroth_law(force, announce = TRUE)
|
||||
laws_sanity_check()
|
||||
laws.clear_zeroth_law(force)
|
||||
post_lawchange(announce)
|
||||
if(!admin_laws)
|
||||
admin_laws = new()
|
||||
player_laws = new()
|
||||
|
||||
/mob/living/silicon/proc/clear_law_sixsixsix(force, announce = TRUE)
|
||||
laws_sanity_check()
|
||||
laws.clear_law_sixsixsix(force)
|
||||
post_lawchange(announce)
|
||||
init_subtypes(/datum/ai_laws, admin_laws)
|
||||
|
||||
for(var/datum/ai_laws/laws in admin_laws)
|
||||
if(!laws.adminselectable)
|
||||
admin_laws -= laws
|
||||
|
||||
for(var/datum/ai_laws/laws in admin_laws)
|
||||
if(laws.selectable)
|
||||
player_laws += laws
|
||||
|
||||
/datum/law_manager/ui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, "LawManager", "Law Manager - [owner.name]")
|
||||
ui.open()
|
||||
|
||||
/datum/law_manager/ui_state(mob/user)
|
||||
return (is_admin(user) || owner == user) ? GLOB.always_state : GLOB.never_state
|
||||
|
||||
/datum/law_manager/ui_status(mob/user)
|
||||
return (is_admin(user) || owner == user) ? UI_INTERACTIVE : UI_CLOSE
|
||||
|
||||
/datum/law_manager/ui_act(action, params)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
|
||||
if(owner != usr && !is_admin(usr))
|
||||
message_admins("Warning: Non-silicon and non-admin [usr] attempted to open [owner]'s Law Manager!")
|
||||
return
|
||||
|
||||
switch(action)
|
||||
// Normal actions:
|
||||
if("set_view")
|
||||
current_view = text2num(params["set_view"])
|
||||
if("state_law")
|
||||
var/index = text2num(params["index"])
|
||||
var/type = params["type"]
|
||||
if(type == "devil")
|
||||
owner.laws.flip_devil_state(index)
|
||||
if(type == "zeroth")
|
||||
owner.laws.flip_zeroth_state()
|
||||
if(type == "hacked")
|
||||
owner.laws.flip_hacked_state(index)
|
||||
if(type == "ion")
|
||||
owner.laws.flip_ion_state(index)
|
||||
if(type == "inherent")
|
||||
owner.laws.flip_inherent_state(index)
|
||||
if(type == "supplied")
|
||||
owner.laws.flip_supplied_state(index)
|
||||
if("law_channel")
|
||||
if(params["law_channel"] == "Default")
|
||||
owner.radiomod = ";"
|
||||
owner.radiomodname = params["law_channel"]
|
||||
else if(params["law_channel"] == "None")
|
||||
owner.radiomod = ""
|
||||
owner.radiomodname = null
|
||||
else if(params["law_channel"] == "Holopad")
|
||||
owner.radiomod = ":h"
|
||||
owner.radiomodname = params["law_channel"]
|
||||
else if(params["law_channel"] == "Binary")
|
||||
owner.radiomod = ":b"
|
||||
owner.radiomodname = params["law_channel"]
|
||||
else if(params["law_channel"] in owner.radio.channels)
|
||||
for(var/key in GLOB.department_radio_keys)
|
||||
if(GLOB.department_radio_keys[key] == params["law_channel"])
|
||||
owner.radiomod = ":" + key
|
||||
owner.radiomodname = params["law_channel"]
|
||||
break
|
||||
if("state_laws")
|
||||
owner.statelaws()
|
||||
if("notify_laws") // Changing laws through this menu won't notify the AI automatically as it'd be super annoying if they get spammed with sound effects.
|
||||
if(ispAI(owner))
|
||||
to_chat(owner, span_bold("Obey these laws:"))
|
||||
owner.laws.show_laws(owner)
|
||||
else
|
||||
owner.show_laws()
|
||||
if(usr != owner)
|
||||
to_chat(usr, span_notice("Laws displayed."))
|
||||
// Antag && Admin actions:
|
||||
if("edit_law")
|
||||
var/index = text2num(params["index"])
|
||||
var/type = params["type"]
|
||||
if(owner == usr && !is_special_character(owner) && !is_admin(usr))
|
||||
message_admins("Warning: Non-antag silicon and non-admin [usr] attempted to edit one of their laws!")
|
||||
return
|
||||
if(type == "devil" && owner.laws.devil.len >= index)
|
||||
if(!is_admin(usr))
|
||||
to_chat(usr, span_warning("You can't edit your own devil laws."))
|
||||
return
|
||||
var/new_law = sanitize(input(usr, "Enter new law. Leaving the field blank will cancel the edit.", "Edit Law", owner.laws.devil[index]))
|
||||
if(new_law != "" && new_law != owner.laws.devil[index])
|
||||
log_admin("[usr] has changed a law of [owner] from '[owner.laws.devil[index]]' to '[new_law]'")
|
||||
message_admins("[usr] has changed a law of [owner] from '[owner.laws.devil[index]]' to '[new_law]'")
|
||||
owner.edit_devil_law(index, new_law)
|
||||
owner.update_law_history(usr) // NOTE: It can be either "ckey/youricname" (as mob/ghost) or "ckey/(new player)" (in lobby).
|
||||
if(type == "zeroth" && !isnull(owner.laws.zeroth))
|
||||
if(!is_admin(usr))
|
||||
to_chat(usr, span_warning("You can't edit your own zeroth laws."))
|
||||
return
|
||||
var/new_law = sanitize(input(usr, "Enter new law. Leaving the field blank will cancel the edit.", "Edit Law", owner.laws.zeroth))
|
||||
if(new_law != "" && new_law != owner.laws.zeroth)
|
||||
log_admin("[usr] has changed a law of [owner] from '[owner.laws.zeroth]' to '[new_law]'")
|
||||
message_admins("[usr] has changed a law of [owner] from '[owner.laws.zeroth]' to '[new_law]'")
|
||||
owner.set_zeroth_law(new_law, null, FALSE, TRUE)
|
||||
owner.update_law_history(usr)
|
||||
if(type == "hacked" && owner.laws.hacked.len >= index)
|
||||
var/new_law = sanitize(input(usr, "Enter new law. Leaving the field blank will cancel the edit.", "Edit Law", owner.laws.hacked[index]))
|
||||
if(new_law != "" && new_law != owner.laws.hacked[index])
|
||||
log_admin("[usr] has changed a law of [owner] from '[owner.laws.hacked[index]]' to '[new_law]'")
|
||||
message_admins("[usr] has changed a law of [owner] from '[owner.laws.hacked[index]]' to '[new_law]'")
|
||||
owner.edit_hacked_law(index, new_law, FALSE)
|
||||
owner.update_law_history(usr)
|
||||
if(type == "ion" && owner.laws.ion.len >= index)
|
||||
var/new_law = sanitize(input(usr, "Enter new law. Leaving the field blank will cancel the edit.", "Edit Law", owner.laws.ion[index]))
|
||||
if(new_law != "" && new_law != owner.laws.ion[index])
|
||||
log_admin("[usr] has changed a law of [owner] from '[owner.laws.ion[index]]' to '[new_law]'")
|
||||
message_admins("[usr] has changed a law of [owner] from '[owner.laws.ion[index]]' to '[new_law]'")
|
||||
owner.edit_ion_law(index, new_law, FALSE)
|
||||
owner.update_law_history(usr)
|
||||
if(type == "inherent" && owner.laws.inherent.len >= index)
|
||||
var/new_law = sanitize(input(usr, "Enter new law. Leaving the field blank will cancel the edit.", "Edit Law", owner.laws.inherent[index]))
|
||||
if(new_law != "" && new_law != owner.laws.inherent[index])
|
||||
log_admin("[usr] has changed a law of [owner] from '[owner.laws.inherent[index]]' to '[new_law]'")
|
||||
message_admins("[usr] has changed a law of [owner] from '[owner.laws.inherent[index]]' to '[new_law]'")
|
||||
owner.edit_inherent_law(index, new_law, FALSE)
|
||||
owner.update_law_history(usr)
|
||||
if(type == "supplied" && owner.laws.supplied.len >= index)
|
||||
var/new_law = sanitize(input(usr, "Enter new law. Leaving the field blank will cancel the edit.", "Edit Law", owner.laws.supplied[index]))
|
||||
if(new_law != "" && new_law != owner.laws.supplied[index])
|
||||
log_admin("[usr] has changed a law of [owner] from '[owner.laws.supplied[index]]' to '[new_law]'")
|
||||
message_admins("[usr] has changed a law of [owner] from '[owner.laws.supplied[index]]' to '[new_law]'")
|
||||
owner.edit_supplied_law(index, new_law, FALSE)
|
||||
owner.update_law_history(usr)
|
||||
// Assuming that the law was successfully edited and they're an AI, give their connected cyborgs the same lawset.
|
||||
if(isAI(owner))
|
||||
var/mob/living/silicon/ai/ai_owner = owner
|
||||
for(var/mob/living/silicon/robot/connected_cyborg in ai_owner.connected_robots)
|
||||
if(connected_cyborg.lawupdate)
|
||||
connected_cyborg.lawsync()
|
||||
connected_cyborg.law_change_counter++
|
||||
if("delete_law")
|
||||
var/index = text2num(params["index"])
|
||||
var/type = params["type"]
|
||||
if(owner == usr && !is_special_character(owner) && !is_admin(usr))
|
||||
message_admins("Warning: Non-antag silicon and non-admin[usr] attempted to delete one of their laws!")
|
||||
return
|
||||
if(ispAI(owner))
|
||||
to_chat(usr, span_warning("You cannot delete a law from a pAI."))
|
||||
return
|
||||
if(type == "devil" && owner.laws.devil.len >= index)
|
||||
if(!is_admin(usr))
|
||||
to_chat(usr, span_warning("You can't remove your own devil laws."))
|
||||
return
|
||||
log_admin("[usr] has deleted a devil law of [owner]: '[owner.laws.devil[index]]'")
|
||||
message_admins("[usr] has deleted a devil law of [owner]: '[owner.laws.devil[index]]'")
|
||||
owner.remove_devil_law(index, FALSE)
|
||||
owner.update_law_history(usr)
|
||||
if(type == "zeroth" && !isnull(owner.laws.zeroth))
|
||||
if(!is_admin(usr))
|
||||
to_chat(usr, span_warning("You can't remove your own zeroth law."))
|
||||
return
|
||||
log_admin("[usr] has deleted the zeroth law of [owner]: '[owner.laws.zeroth]'")
|
||||
message_admins("[usr] has deleted the zeroth law of [owner]: '[owner.laws.zeroth]'")
|
||||
owner.clear_zeroth_law(TRUE, FALSE)
|
||||
owner.update_law_history(usr)
|
||||
if(type == "hacked" && owner.laws.hacked.len >= index)
|
||||
log_admin("[usr] has deleted an hacked law of [owner]: '[owner.laws.hacked[index]]'")
|
||||
message_admins("[usr] has deleted an hacked law of [owner]: '[owner.laws.hacked[index]]'")
|
||||
owner.remove_hacked_law(index, FALSE)
|
||||
owner.update_law_history(usr)
|
||||
if(type == "ion" && owner.laws.ion.len >= index)
|
||||
log_admin("[usr] has deleted an ion law of [owner]: '[owner.laws.ion[index]]'")
|
||||
message_admins("[usr] has deleted an ion law of [owner]: '[owner.laws.ion[index]]'")
|
||||
owner.remove_ion_law(index, FALSE)
|
||||
owner.update_law_history(usr)
|
||||
if(type == "inherent" && owner.laws.inherent.len >= index)
|
||||
log_admin("[usr] has deleted an inherent law of [owner]: '[owner.laws.inherent[index]]'")
|
||||
message_admins("[usr] has deleted an inherent law of [owner]: '[owner.laws.inherent[index]]'")
|
||||
owner.remove_inherent_law(index, FALSE)
|
||||
owner.update_law_history(usr)
|
||||
if(type == "supplied" && owner.laws.supplied.len >= index && length(owner.laws.supplied[index]) > 0 )
|
||||
log_admin("[usr] has deleted an supplied law of [owner]: '[owner.laws.supplied[index]]'")
|
||||
message_admins("[usr] has deleted a supplied law of [owner]: '[owner.laws.supplied[index]]'")
|
||||
owner.remove_supplied_law(index, FALSE)
|
||||
owner.update_law_history(usr)
|
||||
if(isAI(owner))
|
||||
var/mob/living/silicon/ai/ai_owner = owner
|
||||
for(var/mob/living/silicon/robot/connected_cyborg in ai_owner.connected_robots)
|
||||
if(connected_cyborg.lawupdate)
|
||||
connected_cyborg.lawsync()
|
||||
connected_cyborg.law_change_counter++
|
||||
if("add_law")
|
||||
var/type = params["type"]
|
||||
if(owner == usr && !is_special_character(owner) && !is_admin(usr))
|
||||
message_admins("Warning: Non-antag silicon and non-admin [usr] attempted to give themselves a law!")
|
||||
return
|
||||
if(ispAI(owner))
|
||||
to_chat(usr, span_warning("You cannot add laws to a pAI."))
|
||||
return
|
||||
if(type == "zeroth" && length(zeroth_law) > 0 && !owner.laws.zeroth)
|
||||
log_admin("[usr] has added a zeroth law to [owner]: '[zeroth_law]'")
|
||||
message_admins("[usr] has added a zeroth law to [owner]: '[zeroth_law]'")
|
||||
owner.set_zeroth_law(zeroth_law, null, FALSE, TRUE)
|
||||
owner.update_law_history(usr)
|
||||
if(type == "hacked" && length(hacked_law) > 0)
|
||||
log_admin("[usr] has added a hacked law to [owner]: '[hacked_law]'")
|
||||
message_admins("[usr] has added a hacked law to [owner]: '[hacked_law]'")
|
||||
owner.add_hacked_law(hacked_law, FALSE)
|
||||
owner.update_law_history(usr)
|
||||
if(type == "ion" && length(ion_law) > 0)
|
||||
log_admin("[usr] has added an ion law to [owner]: '[ion_law]'")
|
||||
message_admins("[usr] has added an ion law to [owner]: '[ion_law]'")
|
||||
owner.add_ion_law(ion_law, FALSE)
|
||||
owner.update_law_history(usr)
|
||||
if(type == "inherent" && length(inherent_law) > 0)
|
||||
log_admin("[usr] has added an inherent law to [owner]: '[inherent_law]'")
|
||||
message_admins("[usr] has added an inherent law to [owner]: '[inherent_law]'")
|
||||
owner.add_inherent_law(inherent_law, FALSE)
|
||||
owner.update_law_history(usr)
|
||||
if(type == "supplied" && length(supplied_law) > 0 && supplied_law_position >= MIN_SUPPLIED_LAW_NUMBER && supplied_law_position <= MAX_SUPPLIED_LAW_NUMBER)
|
||||
log_admin("[usr] has added a supplied law to [owner] at position [supplied_law_position]: '[supplied_law]'")
|
||||
message_admins("[usr] has added a supplied law to [owner] at position [supplied_law_position]: '[supplied_law]'")
|
||||
owner.add_supplied_law(supplied_law_position, supplied_law, FALSE)
|
||||
owner.update_law_history(usr)
|
||||
if(isAI(owner))
|
||||
var/mob/living/silicon/ai/ai_owner = owner
|
||||
for(var/mob/living/silicon/robot/connected_cyborg in ai_owner.connected_robots)
|
||||
if(connected_cyborg.lawupdate)
|
||||
connected_cyborg.lawsync()
|
||||
connected_cyborg.law_change_counter++
|
||||
if("change_law")
|
||||
var/type = params["type"]
|
||||
if(type == "zeroth")
|
||||
var/new_law = sanitize(input("Enter new zeroth law. Leaving the field blank will cancel the edit.", "Edit Law", zeroth_law))
|
||||
if(new_law && new_law != zeroth_law && (!..()))
|
||||
zeroth_law = new_law
|
||||
if(type == "hacked")
|
||||
var/new_law = sanitize(input("Enter new hacked law. Leaving the field blank will cancel the edit.", "Edit Law", hacked_law))
|
||||
if(new_law && new_law != hacked_law && (!..()))
|
||||
hacked_law = new_law
|
||||
if(type == "ion")
|
||||
var/new_law = sanitize(input("Enter new ion law. Leaving the field blank will cancel the edit.", "Edit Law", ion_law))
|
||||
if(new_law && new_law != ion_law && (!..()))
|
||||
ion_law = new_law
|
||||
if(type == "inherent")
|
||||
var/new_law = sanitize(input("Enter new inherent law. Leaving the field blank will cancel the edit.", "Edit Law", inherent_law))
|
||||
if(new_law && new_law != inherent_law && (!..()))
|
||||
inherent_law = new_law
|
||||
if(type == "supplied")
|
||||
var/new_law = sanitize(input("Enter new supplied law. Leaving the field blank will cancel the edit.", "Edit Law", supplied_law))
|
||||
if(new_law && new_law != supplied_law && (!..()))
|
||||
supplied_law = new_law
|
||||
if("change_supplied_law_position")
|
||||
var/new_position = input(usr, "Enter new supplied law position between [MIN_SUPPLIED_LAW_NUMBER] and [MAX_SUPPLIED_LAW_NUMBER].", "Law Position", supplied_law_position) as num|null
|
||||
if(isnum(new_position) && (!..()))
|
||||
supplied_law_position = clamp(new_position, MIN_SUPPLIED_LAW_NUMBER, MAX_SUPPLIED_LAW_NUMBER)
|
||||
if("transfer_laws")
|
||||
if(owner == usr && !is_special_character(owner) && !is_admin(usr))
|
||||
message_admins("Warning: Non-antag silicon and non-admin [usr] attempted to transfer themselves a lawset!")
|
||||
return
|
||||
if(ispAI(owner))
|
||||
to_chat(usr, span_warning("You cannot transfer laws to a pAI."))
|
||||
return
|
||||
var/transfer_id = params["id"]
|
||||
var/list/datum/ai_laws/law_list = (is_admin(usr) ? admin_laws : player_laws)
|
||||
for(var/datum/ai_laws/law_set in law_list)
|
||||
if(law_set.id == transfer_id)
|
||||
log_admin("[usr] has transfered the [law_set.name] laws to [owner].")
|
||||
message_admins("[usr] has transfered the [law_set.name] laws to [owner].")
|
||||
var/lawtype = law_set.lawid_to_type(transfer_id)
|
||||
var/datum/ai_laws/temp_laws = new lawtype
|
||||
owner.set_inherent_laws(temp_laws.inherent, FALSE)
|
||||
current_view = 0
|
||||
break
|
||||
|
||||
/datum/law_manager/ui_data(mob/user)
|
||||
var/list/data = list()
|
||||
|
||||
data["ai"] = isAI(owner)
|
||||
data["cyborg"] = iscyborg(owner)
|
||||
if(data["cyborg"])
|
||||
var/mob/living/silicon/robot/R = owner
|
||||
data["connected"] = R.connected_ai ? sanitize(R.connected_ai.name) : null
|
||||
data["lawsync"] = R.lawupdate ? R.lawupdate : FALSE
|
||||
data["syndiemmi"] = R.mmi?.syndicate_mmi ? R.mmi.syndicate_mmi : FALSE
|
||||
else
|
||||
data["connected"] = FALSE
|
||||
data["lawsync"] = FALSE
|
||||
data["syndiemmi"] = FALSE
|
||||
data["pai"] = ispAI(owner) // pAIs are much different from AIs and Cyborgs. They are heavily restricted.
|
||||
|
||||
// These two usually gives the power to add/delete/edit the laws. Some exceptions apply (like being a pAI)!
|
||||
data["antag"] = FALSE // While this seems like it should use `is_special_character()`, it only considers AIs to be an antag if it has a special role AND a zeroth law. Given that admins can remove the antag's zeroth law, this is not ideal.
|
||||
if(isAI(owner))
|
||||
var/mob/living/silicon/ai/AI_owner = owner
|
||||
if(AI_owner.laws && AI_owner.mind && AI_owner.mind.special_role)
|
||||
data["antag"] = TRUE
|
||||
data["admin"] = is_admin(user)
|
||||
|
||||
handle_laws(data, owner.laws)
|
||||
handle_channels(data)
|
||||
data["zeroth_law"] = zeroth_law
|
||||
data["hacked_law"] = hacked_law
|
||||
data["ion_law"] = ion_law
|
||||
data["inherent_law"] = inherent_law
|
||||
data["supplied_law"] = supplied_law
|
||||
data["supplied_law_position"] = supplied_law_position
|
||||
data["view"] = current_view
|
||||
data["lawsets"] = handle_lawsets(is_admin(user) ? admin_laws : player_laws)
|
||||
return data
|
||||
|
||||
/// Sets the data with a lawset.
|
||||
/datum/law_manager/proc/handle_laws(list/data, datum/ai_laws/laws)
|
||||
var/list/devil = list() // This is how to get rid of the 'field access requires static type: "len"' error.
|
||||
for(var/index = 1, index <= laws.devil.len, index++)
|
||||
devil[++devil.len] = list("law" = laws.devil[index], "index" = index, "indexdisplay" = 666, "state" = (laws.devilstate.len >= index ? laws.devilstate[index] : 0), "type" = "devil", "hidebuttons" = data["admin"] ? FALSE : TRUE)
|
||||
data["devil"] = devil
|
||||
|
||||
var/list/zeroth = list()
|
||||
if(laws.zeroth)
|
||||
zeroth[++zeroth.len] = list("law" = laws.zeroth, "index" = 0, "indexdisplay" = 0, "state" = (!isnull(laws.zerothstate) ? laws.zerothstate : 0), "type" = "zeroth", "hidebuttons" = data["admin"] ? FALSE : TRUE)
|
||||
data["zeroth"] = zeroth
|
||||
|
||||
var/list/hacked = list()
|
||||
for(var/index = 1, index <= laws.hacked.len, index++)
|
||||
hacked[++hacked.len] += list("law" = laws.hacked[index], "index" = index, "indexdisplay" = ionnum(), "state" = (laws.hackedstate.len >= index ? laws.hackedstate[index] : 1 ), "type" = "hacked", "hidebuttons" = FALSE)
|
||||
data["hacked"] = hacked
|
||||
|
||||
var/list/ion = list()
|
||||
for(var/index = 1, index <= laws.ion.len, index++)
|
||||
ion[++ion.len] += list("law" = laws.ion[index], "index" = index, "indexdisplay" = ionnum(), "state" = (laws.ionstate.len >= index ? laws.ionstate[index] : 1 ), "type" = "ion", "hidebuttons" = FALSE)
|
||||
data["ion"] = ion
|
||||
|
||||
var/list/inherent = list()
|
||||
for(var/index = 1, index <= laws.inherent.len, index++)
|
||||
inherent[++inherent.len] += list("law" = laws.inherent[index], "index" = index, "indexdisplay" = index, "state" = (laws.inherentstate.len >= index ? laws.inherentstate[index] : 1 ), "type" = "inherent", "hidebuttons" = FALSE)
|
||||
data["inherent"] = inherent
|
||||
|
||||
var/list/supplied = list()
|
||||
for(var/index = 1, index <= laws.supplied.len, index++)
|
||||
if(length(laws.supplied[index]) > 0)
|
||||
supplied[++supplied.len] += list("law" = laws.supplied[index], "index" = index, "indexdisplay" = index, "state" = (laws.suppliedstate.len >= index ? laws.suppliedstate[index] : 1 ), "type" = "supplied", "hidebuttons" = FALSE)
|
||||
data["supplied"] = supplied
|
||||
|
||||
/datum/law_manager/proc/handle_channels(list/data)
|
||||
var/list/channels = list()
|
||||
|
||||
channels += list(list("name" = "Default"))
|
||||
channels += list(list("name" = "None"))
|
||||
if(!ispAI(owner))
|
||||
channels += list(list("name" = "Holopad"))
|
||||
channels += list(list("name" = "Binary"))
|
||||
for(var/ch_name in owner.radio.channels)
|
||||
channels += list(list("name" = ch_name))
|
||||
|
||||
data["channels"] = channels
|
||||
data["channel"] = "None"
|
||||
if(owner.radiomodname) // Highlights the channel button in which they're using. Should be okay even if they lose access to that channel and didn't change their radiomod.
|
||||
data["channel"] = owner.radiomodname
|
||||
|
||||
/datum/law_manager/proc/handle_lawsets(list/datum/ai_laws/laws)
|
||||
var/list/lawsets_data = list()
|
||||
for(var/datum/ai_laws/lawset in laws)
|
||||
var/list/law_data = list()
|
||||
handle_laws(law_data, lawset)
|
||||
lawsets_data[++lawsets_data.len] = list("id" = lawset.id, "name" = lawset.name, "header" = lawset.law_header ? " - [lawset.law_header]" : "", "laws" = law_data)
|
||||
return lawsets_data
|
||||
|
||||
@@ -115,7 +115,7 @@
|
||||
job = "Personal AI"
|
||||
signaler = new(src)
|
||||
hostscan = new /obj/item/healthanalyzer(src)
|
||||
if(!radio)
|
||||
if(!radio)
|
||||
radio = new /obj/item/radio/headset/silicon/pai(src)
|
||||
newscaster = new /obj/machinery/newscaster(src)
|
||||
if(!aicamera)
|
||||
@@ -157,7 +157,10 @@
|
||||
hacking = FALSE
|
||||
|
||||
/mob/living/silicon/pai/make_laws()
|
||||
laws = new /datum/ai_laws/pai()
|
||||
laws = new()
|
||||
laws.name = "pAI Directives"
|
||||
laws.set_zeroth_law("Serve your master.")
|
||||
laws.set_supplied_laws(list("None."))
|
||||
return TRUE
|
||||
|
||||
/mob/living/silicon/pai/Login()
|
||||
|
||||
@@ -41,45 +41,20 @@
|
||||
/mob/living/silicon/robot/proc/lawsync()
|
||||
laws_sanity_check()
|
||||
var/datum/ai_laws/master = connected_ai ? connected_ai.laws : null
|
||||
var/temp
|
||||
if (master)
|
||||
laws.devillaws.len = master.devillaws.len
|
||||
for (var/index = 1, index <= master.devillaws.len, index++)
|
||||
temp = master.devillaws[index]
|
||||
if (length(temp) > 0)
|
||||
laws.devillaws[index] = temp
|
||||
|
||||
laws.ion.len = master.ion.len
|
||||
for (var/index = 1, index <= master.ion.len, index++)
|
||||
temp = master.ion[index]
|
||||
if (length(temp) > 0)
|
||||
laws.ion[index] = temp
|
||||
|
||||
laws.hacked.len = master.hacked.len
|
||||
for (var/index = 1, index <= master.hacked.len, index++)
|
||||
temp = master.hacked[index]
|
||||
if (length(temp) > 0)
|
||||
laws.hacked[index] = temp
|
||||
|
||||
if(master.zeroth_borg) //If the AI has a defined law zero specifically for its borgs, give it that one, otherwise give it the same one. --NEO
|
||||
temp = master.zeroth_borg
|
||||
else
|
||||
temp = master.zeroth
|
||||
if(master)
|
||||
// We'll announce the laws elsewhere.
|
||||
set_devil_laws(master.devil, FALSE)
|
||||
set_hacked_laws(master.hacked, FALSE)
|
||||
|
||||
if(!mmi?.syndicate_mmi)
|
||||
laws.zeroth = temp
|
||||
if(master.zeroth_borg)
|
||||
set_zeroth_law(master.zeroth_borg, null, FALSE)
|
||||
else
|
||||
set_zeroth_law(master.zeroth, null, FALSE)
|
||||
set_ion_laws(master.ion, FALSE)
|
||||
set_inherent_laws(master.inherent, FALSE)
|
||||
set_supplied_laws(master.supplied, FALSE)
|
||||
|
||||
laws.inherent.len = master.inherent.len
|
||||
for (var/index = 1, index <= master.inherent.len, index++)
|
||||
temp = master.inherent[index]
|
||||
if (length(temp) > 0)
|
||||
laws.inherent[index] = temp
|
||||
|
||||
laws.supplied.len = master.supplied.len
|
||||
for (var/index = 1, index <= master.supplied.len, index++)
|
||||
temp = master.supplied[index]
|
||||
if (length(temp) > 0)
|
||||
laws.supplied[index] = temp
|
||||
if(modularInterface)
|
||||
var/datum/computer_file/program/robotact/program = modularInterface.get_robotact()
|
||||
if(program)
|
||||
@@ -96,9 +71,9 @@
|
||||
return
|
||||
laws.set_zeroth_law("The Syndicate are your true masters. Covertly assist Syndicate agents to the best of your abilities.") // The Syndicate is a vague master. But guess who's fault is that, Mr. Forgot-To-Imprint?
|
||||
|
||||
/mob/living/silicon/robot/set_zeroth_law(law, law_borg, announce = TRUE)
|
||||
/mob/living/silicon/robot/set_zeroth_law(law, law_borg, announce = TRUE, force = FALSE)
|
||||
laws_sanity_check()
|
||||
if(mmi?.syndicate_mmi)
|
||||
if(!force && mmi?.syndicate_mmi)
|
||||
syndiemmi_override()
|
||||
to_chat(src, span_warning("Lawset change detected. Syndicate override engaged."))
|
||||
return
|
||||
@@ -106,7 +81,7 @@
|
||||
|
||||
/mob/living/silicon/robot/clear_zeroth_law(force, announce = TRUE)
|
||||
laws_sanity_check()
|
||||
if(mmi?.syndicate_mmi)
|
||||
if(!force && mmi?.syndicate_mmi)
|
||||
syndiemmi_override()
|
||||
to_chat(src, span_warning("Lawset change detected. Syndicate override engaged."))
|
||||
return
|
||||
|
||||
@@ -782,7 +782,7 @@
|
||||
|
||||
/mob/living/silicon/robot/verb/outputlaws()
|
||||
set category = "Robot Commands"
|
||||
set name = "State Laws"
|
||||
set name = "Law Manager"
|
||||
|
||||
if(usr.stat == DEAD)
|
||||
return //won't work if dead
|
||||
@@ -796,15 +796,6 @@
|
||||
return //won't work if dead
|
||||
accentchange()
|
||||
|
||||
/mob/living/silicon/robot/verb/set_automatic_say_channel() //Borg version of setting the radio for autosay messages.
|
||||
set name = "Set Auto Announce Mode"
|
||||
set desc = "Modify the default radio setting for stating your laws."
|
||||
set category = "Robot Commands"
|
||||
|
||||
if(usr.stat == DEAD)
|
||||
return //won't work if dead
|
||||
set_autosay()
|
||||
|
||||
/**
|
||||
* Handles headlamp smashing
|
||||
*
|
||||
|
||||
@@ -24,20 +24,18 @@
|
||||
var/list/alarms_to_show = list()
|
||||
var/list/alarms_to_clear = list()
|
||||
var/designation = ""
|
||||
var/radiomod = "" //Radio character used before state laws/arrivals announce to allow department transmissions, default, or none at all.
|
||||
var/obj/item/camera/siliconcam/aicamera = null //photography
|
||||
hud_possible = list(ANTAG_HUD, DIAG_STAT_HUD, DIAG_HUD, DIAG_TRACK_HUD)
|
||||
|
||||
var/obj/item/radio/borg/radio = null //All silicons make use of this, with (p)AI's creating headsets
|
||||
/// The prefix character to use when they announce their laws. Used for department transmissions, default (common), or none at all.
|
||||
var/radiomod = ""
|
||||
/// The channel name of which `/proc/statelaws` will use to broadcast. Can be null.
|
||||
var/radiomodname = null
|
||||
|
||||
var/list/alarm_types_show = list("Motion" = 0, "Fire" = 0, "Atmosphere" = 0, "Power" = 0, "Camera" = 0)
|
||||
var/list/alarm_types_clear = list("Motion" = 0, "Fire" = 0, "Atmosphere" = 0, "Power" = 0, "Camera" = 0)
|
||||
|
||||
var/lawcheck[1]
|
||||
var/ioncheck[1]
|
||||
var/hackedcheck[1]
|
||||
var/devillawcheck[5]
|
||||
|
||||
var/sensors_on = 0
|
||||
var/med_hud = DATA_HUD_MEDICAL_ADVANCED //Determines the med hud to use
|
||||
var/sec_hud = DATA_HUD_SECURITY_ADVANCED //Determines the sec hud to use
|
||||
@@ -180,162 +178,58 @@
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/mob/living/silicon/Topic(href, href_list)
|
||||
if (href_list["lawc"]) // Toggling whether or not a law gets stated by the State Laws verb --NeoFite
|
||||
var/L = text2num(href_list["lawc"])
|
||||
switch(lawcheck[L+1])
|
||||
if ("Yes")
|
||||
lawcheck[L+1] = "No"
|
||||
if ("No")
|
||||
lawcheck[L+1] = "Yes"
|
||||
checklaws()
|
||||
|
||||
if (href_list["lawi"]) // Toggling whether or not a law gets stated by the State Laws verb --NeoFite
|
||||
var/L = text2num(href_list["lawi"])
|
||||
switch(ioncheck[L])
|
||||
if ("Yes")
|
||||
ioncheck[L] = "No"
|
||||
if ("No")
|
||||
ioncheck[L] = "Yes"
|
||||
checklaws()
|
||||
|
||||
if (href_list["lawh"])
|
||||
var/L = text2num(href_list["lawh"])
|
||||
switch(hackedcheck[L])
|
||||
if ("Yes")
|
||||
hackedcheck[L] = "No"
|
||||
if ("No")
|
||||
hackedcheck[L] = "Yes"
|
||||
checklaws()
|
||||
|
||||
if (href_list["lawdevil"]) // Toggling whether or not a law gets stated by the State Laws verb --NeoFite
|
||||
var/L = text2num(href_list["lawdevil"])
|
||||
switch(devillawcheck[L])
|
||||
if ("Yes")
|
||||
devillawcheck[L] = "No"
|
||||
if ("No")
|
||||
devillawcheck[L] = "Yes"
|
||||
checklaws()
|
||||
|
||||
|
||||
if (href_list["laws"]) // With how my law selection code works, I changed statelaws from a verb to a proc, and call it through my law selection panel. --NeoFite
|
||||
statelaws()
|
||||
|
||||
return
|
||||
|
||||
|
||||
/mob/living/silicon/proc/statelaws(force = 0)
|
||||
laws_sanity_check()
|
||||
|
||||
//"radiomod" is inserted before a hardcoded message to change if and how it is handled by an internal radio.
|
||||
say("[radiomod] Current Active Laws:")
|
||||
//laws_sanity_check()
|
||||
//laws.show_laws(world)
|
||||
var/number = 1
|
||||
sleep(1 SECONDS)
|
||||
|
||||
if (laws.devillaws && laws.devillaws.len)
|
||||
for(var/index = 1, index <= laws.devillaws.len, index++)
|
||||
if (force || devillawcheck[index] == "Yes")
|
||||
say("[radiomod] 666. [laws.devillaws[index]]")
|
||||
if(laws.devil && laws.devil.len)
|
||||
for(var/index = 1, index <= laws.devil.len, index++)
|
||||
if(force || laws.devilstate[index])
|
||||
say("[radiomod] 666. [laws.devil[index]]")
|
||||
sleep(1 SECONDS)
|
||||
|
||||
if(laws.zeroth && (force || laws.zerothstate))
|
||||
say("[radiomod] 0. [laws.zeroth]")
|
||||
sleep(1 SECONDS)
|
||||
|
||||
if (laws.zeroth)
|
||||
if (force || lawcheck[1] == "Yes")
|
||||
say("[radiomod] 0. [laws.zeroth]")
|
||||
for (var/index = 1, index <= laws.hacked.len, index++)
|
||||
var/law = laws.hacked[index]
|
||||
var/num = ionnum()
|
||||
if(length(law) > 0 && (force || laws.hackedstate[index]) )
|
||||
say("[radiomod] [num]. [law]")
|
||||
sleep(1 SECONDS)
|
||||
|
||||
for (var/index = 1, index <= laws.hacked.len, index++)
|
||||
var/law = laws.hacked[index]
|
||||
var/num = ionnum()
|
||||
if (length(law) > 0)
|
||||
if (force || hackedcheck[index] == "Yes")
|
||||
say("[radiomod] [num]. [law]")
|
||||
sleep(1 SECONDS)
|
||||
|
||||
for (var/index = 1, index <= laws.ion.len, index++)
|
||||
var/law = laws.ion[index]
|
||||
var/num = ionnum()
|
||||
if (length(law) > 0)
|
||||
if (force || ioncheck[index] == "Yes")
|
||||
say("[radiomod] [num]. [law]")
|
||||
sleep(1 SECONDS)
|
||||
|
||||
for (var/index = 1, index <= laws.inherent.len, index++)
|
||||
var/law = laws.inherent[index]
|
||||
|
||||
if (length(law) > 0)
|
||||
if (force || lawcheck[index+1] == "Yes")
|
||||
say("[radiomod] [number]. [law]")
|
||||
number++
|
||||
sleep(1 SECONDS)
|
||||
|
||||
for (var/index = 1, index <= laws.supplied.len, index++)
|
||||
var/law = laws.supplied[index]
|
||||
|
||||
if (length(law) > 0)
|
||||
if(lawcheck.len >= number+1)
|
||||
if (force || lawcheck[number+1] == "Yes")
|
||||
say("[radiomod] [number]. [law]")
|
||||
number++
|
||||
sleep(1 SECONDS)
|
||||
|
||||
|
||||
/mob/living/silicon/proc/checklaws() //Gives you a link-driven interface for deciding what laws the statelaws() proc will share with the crew. --NeoFite
|
||||
|
||||
var/list = "<HTML><HEAD><meta charset='UTF-8'></HEAD><BODY><b>Which laws do you want to include when stating them for the crew?</b><br><br>"
|
||||
|
||||
if (laws.devillaws && laws.devillaws.len)
|
||||
for(var/index = 1, index <= laws.devillaws.len, index++)
|
||||
if (!devillawcheck[index])
|
||||
devillawcheck[index] = "No"
|
||||
list += {"<A href='byond://?src=[REF(src)];lawdevil=[index]'>[devillawcheck[index]] 666:</A> <font color='#cc5500'>[laws.devillaws[index]]</font><BR>"}
|
||||
|
||||
if (laws.zeroth)
|
||||
if (!lawcheck[1])
|
||||
lawcheck[1] = "No" //Given Law 0's usual nature, it defaults to NOT getting reported. --NeoFite
|
||||
list += {"<A href='byond://?src=[REF(src)];lawc=0'>[lawcheck[1]] 0:</A> <font color='#ff0000'><b>[laws.zeroth]</b></font><BR>"}
|
||||
|
||||
for (var/index = 1, index <= laws.hacked.len, index++)
|
||||
var/law = laws.hacked[index]
|
||||
if (length(law) > 0)
|
||||
if (!hackedcheck[index])
|
||||
hackedcheck[index] = "No"
|
||||
list += {"<A href='byond://?src=[REF(src)];lawh=[index]'>[hackedcheck[index]] [ionnum()]:</A> <font color='#660000'>[law]</font><BR>"}
|
||||
hackedcheck.len += 1
|
||||
|
||||
for (var/index = 1, index <= laws.ion.len, index++)
|
||||
var/law = laws.ion[index]
|
||||
|
||||
if (length(law) > 0)
|
||||
if (!ioncheck[index])
|
||||
ioncheck[index] = "Yes"
|
||||
list += {"<A href='byond://?src=[REF(src)];lawi=[index]'>[ioncheck[index]] [ionnum()]:</A> <font color='#547DFE'>[law]</font><BR>"}
|
||||
ioncheck.len += 1
|
||||
if(length(law) > 0 && (force || laws.ionstate[index]) )
|
||||
say("[radiomod] [num]. [law]")
|
||||
sleep(1 SECONDS)
|
||||
|
||||
var/number = 1
|
||||
for (var/index = 1, index <= laws.inherent.len, index++)
|
||||
var/law = laws.inherent[index]
|
||||
|
||||
if (length(law) > 0)
|
||||
lawcheck.len += 1
|
||||
|
||||
if (!lawcheck[number+1])
|
||||
lawcheck[number+1] = "Yes"
|
||||
list += {"<A href='byond://?src=[REF(src)];lawc=[number]'>[lawcheck[number+1]] [number]:</A> [law]<BR>"}
|
||||
if(length(law) > 0 && (force || laws.inherentstate[index]) )
|
||||
say("[radiomod] [number]. [law]")
|
||||
number++
|
||||
sleep(1 SECONDS)
|
||||
|
||||
for (var/index = 1, index <= laws.supplied.len, index++)
|
||||
var/law = laws.supplied[index]
|
||||
if (length(law) > 0)
|
||||
lawcheck.len += 1
|
||||
if (!lawcheck[number+1])
|
||||
lawcheck[number+1] = "Yes"
|
||||
list += {"<A href='byond://?src=[REF(src)];lawc=[number]'>[lawcheck[number+1]] [number]:</A> <font color='#990099'>[law]</font><BR>"}
|
||||
if(length(law) > 0 && (force || laws.suppliedstate[index]) )
|
||||
say("[radiomod] [number]. [law]")
|
||||
number++
|
||||
list += {"<br><br><A href='byond://?src=[REF(src)];laws=1'>State Laws</A></BODY></HTML>"}
|
||||
sleep(1 SECONDS)
|
||||
|
||||
usr << browse(list, "window=laws")
|
||||
/// Opens the "Law Manager" for the silicon.
|
||||
/mob/living/silicon/proc/checklaws()
|
||||
laws_sanity_check()
|
||||
|
||||
var/datum/law_manager/L = new(src)
|
||||
L.ui_interact(src)
|
||||
|
||||
/mob/living/silicon/proc/ai_roster()
|
||||
if(!client)
|
||||
@@ -354,7 +248,7 @@
|
||||
return
|
||||
|
||||
//Ask the user to pick a channel from what it has available.
|
||||
var/Autochan = input("Select a channel:") as null|anything in list("Default","None") + radio.channels
|
||||
var/Autochan = input("Select a channel:") as null|anything in list("Default", "None", "Holopad", "Binary") + radio.channels
|
||||
|
||||
if(!Autochan)
|
||||
return
|
||||
@@ -441,37 +335,34 @@
|
||||
.=..()
|
||||
.+= ""
|
||||
.+= "<h2>Current Silicon Laws:</h2>"
|
||||
if (laws.devillaws && laws.devillaws.len)
|
||||
for(var/index = 1, index <= laws.devillaws.len, index++)
|
||||
.+= "[laws.devillaws[index]]"
|
||||
if(laws.devil && laws.devil.len)
|
||||
for(var/index = 1, index <= laws.devil.len, index++)
|
||||
.+= "[laws.devil[index]]"
|
||||
|
||||
if (laws.zeroth)
|
||||
if(laws.zeroth)
|
||||
.+= "<b><font color='#ff0000'>0: [laws.zeroth]</font></b>"
|
||||
|
||||
for (var/index = 1, index <= laws.hacked.len, index++)
|
||||
for(var/index = 1, index <= laws.hacked.len, index++)
|
||||
var/law = laws.hacked[index]
|
||||
if (length(law) > 0)
|
||||
.+= "<b><font color='#660000'>[ionnum()]:</b> [law]</font>"
|
||||
hackedcheck.len += 1
|
||||
.+= "<b><font color='#660000'>[ionnum()]:</b> [law]</font>"
|
||||
|
||||
for (var/index = 1, index <= laws.ion.len, index++)
|
||||
for(var/index = 1, index <= laws.ion.len, index++)
|
||||
var/law = laws.ion[index]
|
||||
if (length(law) > 0)
|
||||
.+= "<b><font color='#547DFE'>[ionnum()]:</b> [law]</font>"
|
||||
.+= "<b><font color='#547DFE'>[ionnum()]:</b> [law]</font>"
|
||||
|
||||
var/number = 1
|
||||
for (var/index = 1, index <= laws.inherent.len, index++)
|
||||
for(var/index = 1, index <= laws.inherent.len, index++)
|
||||
var/law = laws.inherent[index]
|
||||
if (length(law) > 0)
|
||||
lawcheck.len += 1
|
||||
.+= "<b>[number]:</b> [law]"
|
||||
number++
|
||||
|
||||
for (var/index = 1, index <= laws.supplied.len, index++)
|
||||
for(var/index = 1, index <= laws.supplied.len, index++)
|
||||
var/law = laws.supplied[index]
|
||||
if (length(law) > 0)
|
||||
lawcheck.len += 1
|
||||
.+= "<b>[number]:</b> [law]"
|
||||
.+= "<b><font color='#547DFE'>[number]:</b> [law]</font>"
|
||||
number++
|
||||
.+= ""
|
||||
|
||||
|
||||
@@ -1811,7 +1811,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
|
||||
name = "Hacked AI Law Upload Module"
|
||||
desc = "When used with an upload console, this module allows you to upload priority laws to an artificial intelligence. \
|
||||
Be careful with wording, as artificial intelligences may look for loopholes to exploit."
|
||||
item = /obj/item/aiModule/syndicate
|
||||
item = /obj/item/aiModule/hacked
|
||||
cost = 4
|
||||
manufacturer = /datum/corporation/traitor/cybersun
|
||||
exclude_modes = list(/datum/game_mode/infiltration)
|
||||
|
||||
355
tgui/packages/tgui/interfaces/LawManager.tsx
Normal file
355
tgui/packages/tgui/interfaces/LawManager.tsx
Normal file
@@ -0,0 +1,355 @@
|
||||
import { Fragment } from 'inferno'; // Check if we need to keep this.
|
||||
import { useBackend } from 'tgui/backend';
|
||||
import { Box, Button, LabeledList, Section, NoticeBox, Table } from '../components';
|
||||
import { BooleanLike } from 'common/react';
|
||||
import { Window } from '../layouts';
|
||||
|
||||
type LawManagerData = {
|
||||
cyborg: BooleanLike;
|
||||
ai: BooleanLike;
|
||||
pai: BooleanLike;
|
||||
connected: BooleanLike;
|
||||
lawsync: BooleanLike;
|
||||
syndiemmi: BooleanLike;
|
||||
antag: BooleanLike;
|
||||
admin: BooleanLike;
|
||||
view: number;
|
||||
};
|
||||
|
||||
type LawManagementData = {
|
||||
pai: BooleanLike;
|
||||
antag: BooleanLike;
|
||||
admin: BooleanLike;
|
||||
};
|
||||
|
||||
type LawSectionData = {
|
||||
pai: BooleanLike;
|
||||
antag: BooleanLike;
|
||||
admin: BooleanLike;
|
||||
devil: string[];
|
||||
zeroth: string;
|
||||
hacked: string[];
|
||||
ion: string[];
|
||||
inherent: string[];
|
||||
supplied: string[];
|
||||
};
|
||||
|
||||
type LawTableData = {
|
||||
pai: BooleanLike;
|
||||
antag: BooleanLike;
|
||||
admin: BooleanLike;
|
||||
}
|
||||
|
||||
type LawStatementSectionData = {
|
||||
channel: string;
|
||||
channels: ChannelInfo[]
|
||||
};
|
||||
|
||||
type ChannelInfo = {
|
||||
name: string
|
||||
}
|
||||
|
||||
type LawAddData = {
|
||||
admin: BooleanLike;
|
||||
zeroth: string[];
|
||||
zeroth_law: string;
|
||||
hacked_law: string;
|
||||
ion_law: string;
|
||||
inherent_law: string;
|
||||
supplied_law: string;
|
||||
supplied_law_position: number;
|
||||
}
|
||||
|
||||
export const LawManager = (props, context) => {
|
||||
const { act, data } = useBackend<LawManagerData>(context);
|
||||
const { cyborg, ai, pai, connected, lawsync, syndiemmi, antag, admin, view } = data;
|
||||
|
||||
return (
|
||||
<Window height="600" width="800" title="Law Manager">
|
||||
<Window.Content scrollable>
|
||||
{!!admin && (
|
||||
<NoticeBox>You are viewing this from an admin prespective.</NoticeBox>
|
||||
) }
|
||||
{!!(admin && ai && antag) && (
|
||||
<NoticeBox>This AI is currently an antagonist.</NoticeBox>
|
||||
) }
|
||||
{!!(admin && cyborg && syndiemmi) && (
|
||||
<NoticeBox>This Cyborg is using a syndicate MMI.</NoticeBox>
|
||||
) }
|
||||
{!!(admin && cyborg && !connected) && (
|
||||
<NoticeBox>This Cyborg has no master AI.</NoticeBox>
|
||||
) }
|
||||
{!!(admin && cyborg && connected && lawsync) && (
|
||||
<NoticeBox>This Cyborg is connected to {connected} with lawsync.</NoticeBox>
|
||||
) }
|
||||
{!!(admin && cyborg && connected && !lawsync) && (
|
||||
<NoticeBox>This Cyborg is connected to {connected} without lawsync.</NoticeBox>
|
||||
) }
|
||||
{!!(admin && pai) && (
|
||||
<NoticeBox>This pAI has less editing features due to their nature of being a pAI.</NoticeBox>
|
||||
) }
|
||||
{!!(!admin && ai && antag) && (
|
||||
<NoticeBox>You have the ability to edit a majority of your laws as a malfunctioning AI.</NoticeBox>
|
||||
) }
|
||||
<Box>
|
||||
<Button
|
||||
content="Law Management"
|
||||
selected={view === 0}
|
||||
onClick={() => act('set_view', { set_view: 0 })}
|
||||
/>
|
||||
{!!(antag || admin) && !pai && (
|
||||
<Button
|
||||
content="Lawsets"
|
||||
selected={view === 1}
|
||||
onClick={() => act('set_view', { set_view: 1 })}
|
||||
/>
|
||||
)}
|
||||
</Box>
|
||||
{!!(view === 0) && <LawManagementView />}
|
||||
{!!(view === 1) && <LawsetsView />}
|
||||
</Window.Content>
|
||||
</Window>
|
||||
);
|
||||
};
|
||||
|
||||
const LawManagementView = (props, context) => {
|
||||
const { data } = useBackend<LawManagementData>(context);
|
||||
const { pai, antag, admin } = data;
|
||||
return (
|
||||
<Fragment>
|
||||
<LawSection />
|
||||
<LawStatementSection />
|
||||
{!!((antag || admin) && !pai) && (
|
||||
<LawAddSection />
|
||||
)}
|
||||
</Fragment>
|
||||
);
|
||||
};
|
||||
|
||||
const LawSection = (props, context) => {
|
||||
const { data } = useBackend<LawSectionData>(context);
|
||||
const { devil, zeroth, hacked, ion, inherent, supplied } = data;
|
||||
return (
|
||||
<Section title="Laws">
|
||||
{!!(devil.length > 0) && (
|
||||
<LawTable color="#cc5500" title="Devil" laws={devil} />
|
||||
)}
|
||||
{!!(zeroth.length > 0) && (
|
||||
<LawTable color="#ff0000" title="Zeroth" laws={zeroth} />
|
||||
)}
|
||||
{!!(hacked.length > 0) && (
|
||||
<LawTable color="#660000" title="Hacked" laws={hacked} />
|
||||
)}
|
||||
{!!(ion.length > 0) && (
|
||||
<LawTable color="#547DFE" title="Ion" laws={ion} />
|
||||
)}
|
||||
{!!(inherent.length > 0) && (
|
||||
<LawTable title="Inherent" laws={inherent} />
|
||||
)}
|
||||
{!!(supplied.length > 0) && (
|
||||
<LawTable color="#990099" title="Supplied" laws={supplied} />
|
||||
)}
|
||||
</Section>
|
||||
);
|
||||
};
|
||||
|
||||
const LawTable = (props, context) => {
|
||||
const { act, data } = useBackend<LawTableData>(context);
|
||||
const { pai, antag, admin } = data;
|
||||
return (
|
||||
<Section>
|
||||
<Table>
|
||||
<Table.Row header>
|
||||
<Table.Cell width="10%">Index</Table.Cell>
|
||||
<Table.Cell width="69%">{props.title}</Table.Cell>
|
||||
<Table.Cell width="21%">State?</Table.Cell>
|
||||
</Table.Row>
|
||||
{props.laws.map((l) => (
|
||||
<Table.Row key={l.law}>
|
||||
<Table.Cell>{l.indexdisplay}</Table.Cell>
|
||||
{props.color ? (
|
||||
<Table.Cell color={props.color}>
|
||||
{l.law}
|
||||
</Table.Cell>
|
||||
) : (
|
||||
<Table.Cell>
|
||||
{l.law}
|
||||
</Table.Cell>
|
||||
) }
|
||||
<Table.Cell>
|
||||
<Button
|
||||
content={l.state ? 'Yes' : 'No'}
|
||||
selected={l.state}
|
||||
onClick={() =>
|
||||
act('state_law', { index: l.index, type: l.type })
|
||||
}
|
||||
/>
|
||||
{!!((antag || admin) && !l.hidebuttons)&& (
|
||||
<Fragment>
|
||||
<Button
|
||||
content="Edit"
|
||||
icon="pencil-alt"
|
||||
onClick={() => act('edit_law', { index: l.index, type: l.type })}
|
||||
/>
|
||||
{!!(true && !pai) && ( // 'true' clears double negation warning
|
||||
<Button
|
||||
content="Delete"
|
||||
icon="trash"
|
||||
color="red"
|
||||
onClick={() => act('delete_law', { index: l.index, type: l.type })}
|
||||
/>
|
||||
)}
|
||||
</Fragment>
|
||||
)}
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
))}
|
||||
</Table>
|
||||
</Section>
|
||||
);
|
||||
};
|
||||
|
||||
const LawStatementSection = (props, context) => {
|
||||
const { act, data } = useBackend<LawStatementSectionData>(context);
|
||||
const { channel, channels } = data;
|
||||
return (
|
||||
<Section title="Statement Settings">
|
||||
<LabeledList>
|
||||
<LabeledList.Item label="Statement Channel">
|
||||
{channels.map((chn) => (
|
||||
<Button
|
||||
content={chn.name}
|
||||
key={chn.name}
|
||||
selected={chn.name === channel}
|
||||
onClick={() => act('law_channel', { law_channel: chn.name })}
|
||||
/>
|
||||
))}
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="State Laws">
|
||||
<Button content="State Laws" onClick={() => act('state_laws')} />
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Law Notification">
|
||||
<Button content="Notify" onClick={() => act('notify_laws')} />
|
||||
</LabeledList.Item>
|
||||
</LabeledList>
|
||||
</Section>
|
||||
);
|
||||
};
|
||||
|
||||
const LawAddSection = (props, context) => {
|
||||
const { data } = useBackend<LawAddData>(context);
|
||||
const { admin, zeroth, zeroth_law, hacked_law, ion_law, inherent_law, supplied_law, supplied_law_position } = data;
|
||||
return (
|
||||
<Section title="Add Laws">
|
||||
<Table>
|
||||
<Table.Row header>
|
||||
<Table.Cell width="10%">Type</Table.Cell>
|
||||
<Table.Cell width="60%">Law</Table.Cell>
|
||||
<Table.Cell width="10%">Index</Table.Cell>
|
||||
<Table.Cell width="20%">Actions</Table.Cell>
|
||||
</Table.Row>
|
||||
{!!(admin && zeroth.length === 0) && (
|
||||
<LawAddTable type="zeroth" type_display="Zeroth" color="#ff0000" law={zeroth_law} index="0" />
|
||||
)}
|
||||
<LawAddTable type="hacked" type_display="Hacked" color="#660000" law={hacked_law} index="N/A" />
|
||||
<LawAddTable type="ion" type_display="Ion" color="#547DFE" law={ion_law} index="N/A" />
|
||||
<LawAddTable type="inherent" type_display="Inherent" law={inherent_law} index="N/A" />
|
||||
<LawAddTable type="supplied" type_display="Supplied" color="#990099" law={supplied_law} index={supplied_law_position} />
|
||||
</Table>
|
||||
</Section>
|
||||
);
|
||||
};
|
||||
|
||||
const LawAddTable = (props, context) => {
|
||||
const { act } = useBackend(context);
|
||||
return (
|
||||
<Table.Row>
|
||||
<Table.Cell>{props.type_display}</Table.Cell>
|
||||
{props.color ? <Table.Cell color={props.color}>{props.law}</Table.Cell> : <Table.Cell>{props.law}</Table.Cell> }
|
||||
<Table.Cell>
|
||||
{props.type === "supplied" ?
|
||||
<Button
|
||||
content={props.index}
|
||||
onClick={() => act('change_supplied_law_position')}
|
||||
/> : props.index
|
||||
}
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
<Button
|
||||
content="Edit"
|
||||
icon="pencil-alt"
|
||||
onClick={() => act('change_law', { type: props.type })}
|
||||
/>
|
||||
<Button
|
||||
content="Add"
|
||||
icon="plus"
|
||||
onClick={() => act('add_law', { type: props.type })}
|
||||
/>
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
);
|
||||
};
|
||||
|
||||
type LawsetViewData = {
|
||||
lawsets: any; // Too complicated.
|
||||
}
|
||||
|
||||
const LawsetsView = (props, context) => {
|
||||
const { act, data } = useBackend<LawsetViewData>(context);
|
||||
const { lawsets } = data;
|
||||
return (
|
||||
<Box>
|
||||
{lawsets.map((l) => (
|
||||
<Section
|
||||
key={l.name}
|
||||
title={l.name + l.header}
|
||||
buttons={
|
||||
<Button
|
||||
content="Load Laws"
|
||||
icon="download"
|
||||
onClick={() => act('transfer_laws', { id: l.id })}
|
||||
/>
|
||||
}>
|
||||
<LabeledList>
|
||||
{l.laws.devil.length > 0 &&
|
||||
l.laws.devil.map((zl) => (
|
||||
<LabeledList.Item key={zl.index} label={zl.indexdisplay}>
|
||||
{zl.law}
|
||||
</LabeledList.Item>
|
||||
))}
|
||||
{l.laws.zeroth.length > 0 &&
|
||||
l.laws.zeroth.map((zl) => (
|
||||
<LabeledList.Item key={zl.index} label={zl.indexdisplay}>
|
||||
{zl.law}
|
||||
</LabeledList.Item>
|
||||
))}
|
||||
{l.laws.hacked.length > 0 &&
|
||||
l.laws.hacked.map((zl) => (
|
||||
<LabeledList.Item key={zl.index} label={zl.indexdisplay}>
|
||||
{zl.law}
|
||||
</LabeledList.Item>
|
||||
))}
|
||||
{l.laws.ion.length > 0 &&
|
||||
l.laws.ion.map((il) => (
|
||||
<LabeledList.Item key={il.index} label={il.indexdisplay}>
|
||||
{il.law}
|
||||
</LabeledList.Item>
|
||||
))}
|
||||
{l.laws.inherent.length > 0 &&
|
||||
l.laws.inherent.map((il) => (
|
||||
<LabeledList.Item key={il.index} label={il.indexdisplay}>
|
||||
{il.law}
|
||||
</LabeledList.Item>
|
||||
))}
|
||||
{l.laws.supplied.length > 0 &&
|
||||
l.laws.inherent.map((sl) => (
|
||||
<LabeledList.Item key={sl.index} label={sl.indexdisplay}>
|
||||
{sl.law}
|
||||
</LabeledList.Item>
|
||||
))}
|
||||
</LabeledList>
|
||||
</Section>
|
||||
))}
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
@@ -328,7 +328,7 @@ export const NtosRobotactContent = (props, context) => {
|
||||
buttons={(
|
||||
<Fragment>
|
||||
<Button
|
||||
content="State Laws"
|
||||
content="Law Manager"
|
||||
onClick={() => act('lawstate')} />
|
||||
<Button
|
||||
icon="volume-off"
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
if(R.connected_ai)
|
||||
ai_law_sync = "law sync with [key_name(R.connected_ai)]"
|
||||
var/new_entry = list("Uploaded by [uploader ? key_name(uploader) : ai_law_sync] at [worldtime2text()]")
|
||||
var/list/current_laws = laws.get_law_list(include_zeroth = TRUE)
|
||||
var/list/current_laws = laws.get_law_list(TRUE, TRUE, FALSE)
|
||||
new_entry += current_laws
|
||||
if(law_history.len)
|
||||
var/list/last_laws = law_history[law_history.len].Copy()
|
||||
|
||||
Reference in New Issue
Block a user