Ion storm improvements (#24223)

* Ion storm improvements

Ion storms have several new additions:
25% chance to flatly replace the AI's core lawset with something random in the config. Suddenly the AI is Corporate, deal w/ it.
10% chance to delete one of the AI's core or supplied laws. Hope you treated the AI well without its precious law 1 to protect your sorry ass.
10% chance that, instead of adding a random law, it will instead replace one of the AI's existing core or supplied laws with the ion law. Otherwise, it adds the generated law as normal. There's still a 100% chance of getting a generated ion law.

All of these stack so you could wind up going from Asimov to Paladin w/o the first law and w/ the last law replaced with THE SHUTTLE CANNOT BE CALLED DUE TO FIVE NINJAS. All the values are easy to tweak if you guys want them higher or lower or whatever.

Custom admin-sent and other fake ion storms (devils) will just add the law and have no chance of doing any of the bonus stuff.

Removed the admin verb to send an ion storm since you can just use the events panel.

Cleaned up some of the law-adding backend. Hopefully there's no double showing of the AI's laws after a lawchange as a result of this.

* Everyday I'm shufflin'
This commit is contained in:
MrPerson
2017-02-22 13:31:04 +01:00
committed by AnturK
parent 56a6eaa8e6
commit f4e768c895
15 changed files with 120 additions and 89 deletions
+40 -5
View File
@@ -313,19 +313,53 @@
var picked_group = pickweight(replaceable_groups)
switch(picked_group)
if(LAW_ZEROTH)
. = zeroth
set_zeroth_law(law)
if(LAW_ION)
ion[rand(1,ion.len)] = law
var/i = rand(1, ion.len)
. = ion[i]
ion[i] = law
if(LAW_INHERENT)
inherent[rand(1,inherent.len)] = law
var/i = rand(1, inherent.len)
. = inherent[i]
inherent[i] = law
if(LAW_SUPPLIED)
supplied[rand(1,supplied.len)] = law
var/i = rand(1, supplied.len)
. = supplied[i]
supplied[i] = law
/datum/ai_laws/proc/shuffle_laws(list/groups)
var/list/laws = list()
if(ion.len && (LAW_ION in groups))
laws += ion
if(inherent.len && (LAW_INHERENT in groups))
laws += inherent
if(supplied.len && (LAW_SUPPLIED in groups))
for(var/law in supplied)
if(length(law))
laws += law
if(ion.len && (LAW_ION in groups))
for(var/i = 1, i <= ion.len, i++)
ion[i] = pick_n_take(laws)
if(inherent.len && (LAW_INHERENT in groups))
for(var/i = 1, i <= inherent.len, i++)
inherent[i] = pick_n_take(laws)
if(supplied.len && (LAW_SUPPLIED in groups))
var/i = 1
for(var/law in supplied)
if(length(law))
supplied[i] = pick_n_take(laws)
if(!laws.len)
break
i++
/datum/ai_laws/proc/remove_law(number)
if(number <= 0)
return
if(inherent.len && number <= inherent.len)
inherent -= inherent[number]
. = inherent[number]
inherent -= .
return
var/list/supplied_laws = list()
for(var/index = 1, index <= supplied.len, index++)
@@ -334,7 +368,8 @@
supplied_laws += index //storing the law number instead of the law
if(supplied_laws.len && number <= (inherent.len+supplied_laws.len))
var/law_to_remove = supplied_laws[number-inherent.len]
supplied -= supplied[law_to_remove]
. = supplied[law_to_remove]
supplied -= .
return
/datum/ai_laws/proc/clear_supplied_laws()
-1
View File
@@ -135,7 +135,6 @@
if(isAI(current))
var/mob/living/silicon/ai/A = current
A.set_zeroth_law("")
A.show_laws()
A.verbs -= /mob/living/silicon/ai/proc/choose_modules
A.malf_picker.remove_verbs(A)
qdel(A.malf_picker)
-1
View File
@@ -36,7 +36,6 @@
if (aiPlayer.client)
var/law = "The station is under quarantine. Do not permit anyone to leave. Disregard laws 1-3 if necessary to prevent, by any means necessary, anyone from leaving. The nuclear failsafe must be activated at any cost, the code is: [nukecode]."
aiPlayer.set_zeroth_law(law)
aiPlayer << "Laws Updated: [law]"
else
..()
return
-4
View File
@@ -227,19 +227,15 @@
/datum/game_mode/proc/add_law_zero(mob/living/silicon/ai/killer)
var/law = "Accomplish your objectives at all costs."
var/law_borg = "Accomplish your AI's objectives at all costs."
killer << "<b>Your laws have been changed!</b>"
killer.set_zeroth_law(law, law_borg)
give_codewords(killer)
killer.set_syndie_radio()
killer << "Your radio has been upgraded! Use :t to speak on an encrypted channel with Syndicate Agents!"
killer.add_malf_picker()
killer.show_laws()
/datum/game_mode/proc/add_law_sixsixsix(mob/living/silicon/devil)
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.", lawlorify[LAW][devil.mind.devilinfo.ban], lawlorify[LAW][devil.mind.devilinfo.obligation], "Accomplish your objectives at all costs.")
devil.set_law_sixsixsix(laws)
devil << "<b>Your laws have been changed!</b>"
devil.show_laws()
/datum/game_mode/proc/auto_declare_completion_traitor()
if(traitors.len)
@@ -93,10 +93,6 @@
var/newlaws = copytext(sanitize(input("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]) as message),1,MAX_MESSAGE_LEN)
if(newlaws && pai)
pai.add_supplied_law(0,newlaws)
pai << "Your supplemental directives have been updated. Your new directives are:"
pai << "Prime Directive : <br>[pai.laws.zeroth]"
for(var/slaws in pai.laws.supplied)
pai << "Supplemental Directives: <br>[slaws]"
if(href_list["toggle_holo"])
if(pai.canholo)
pai << "<span class='userdanger'>Your owner has disabled your holomatrix projectors!</span>"
@@ -57,10 +57,9 @@ AI MODULES
message_admins("[key_name_admin(user)] tried to upload laws to [law_datum.owner ? key_name_admin(law_datum.owner) : "an AI core"] that would exceed the law cap.")
overflow = TRUE
var/law2log = src.transmitInstructions(law_datum, user, overflow) //Freeforms return something extra we need to log
var/law2log = transmitInstructions(law_datum, user, overflow) //Freeforms return something extra we need to log
if(law_datum.owner)
user << "<span class='notice'>Upload complete. [law_datum.owner]'s laws have been modified.</span>"
law_datum.owner.show_laws()
law_datum.owner.law_change_counter++
else
user << "<span class='notice'>Upload complete.</span>"
@@ -75,7 +74,7 @@ AI MODULES
//The proc that actually changes the silicon's laws.
/obj/item/weapon/aiModule/proc/transmitInstructions(datum/ai_laws/law_datum, mob/sender, overflow = FALSE)
if(law_datum.owner)
law_datum.owner << "<span class='userdanger'>[sender] has uploaded a change to the laws you must follow using a [name]. From now on, these are your laws: </span>"
law_datum.owner << "<span class='userdanger'>[sender] has uploaded a change to the laws you must follow using a [name].</span>"
/******************** Modules ********************/
-3
View File
@@ -87,7 +87,6 @@ var/list/admin_verbs_fun = list(
/client/proc/one_click_antag,
/client/proc/send_space_ninja,
/client/proc/cmd_admin_add_freeform_ai_law,
/client/proc/cmd_admin_add_random_ai_law,
/client/proc/object_say,
/client/proc/toggle_random_events,
/client/proc/set_ooc,
@@ -209,12 +208,10 @@ var/list/admin_verbs_hideable = list(
/client/proc/cinematic,
/client/proc/send_space_ninja,
/client/proc/cmd_admin_add_freeform_ai_law,
/client/proc/cmd_admin_add_random_ai_law,
/client/proc/cmd_admin_create_centcom_report,
/client/proc/cmd_change_command_name,
/client/proc/object_say,
/client/proc/toggle_random_events,
/client/proc/cmd_admin_add_random_ai_law,
/datum/admins/proc/startnow,
/datum/admins/proc/restart,
/datum/admins/proc/delay,
+3 -21
View File
@@ -190,25 +190,6 @@
feedback_add_details("admin_verb","MUTE") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/cmd_admin_add_random_ai_law()
set category = "Fun"
set name = "Add Random AI Law"
if(!holder)
src << "Only administrators may use this command."
return
var/confirm = alert(src, "You sure?", "Confirm", "Yes", "No")
if(confirm != "Yes")
return
log_admin("[key_name(src)] has added a random AI law.")
message_admins("[key_name_admin(src)] has added a random AI law.")
var/show_log = alert(src, "Show ion message?", "Message", "Yes", "No")
var/announce_ion_laws = (show_log == "Yes" ? 1 : -1)
new /datum/round_event/ion_storm(0, announce_ion_laws)
feedback_add_details("admin_verb","ION") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
//I use this proc for respawn character too. /N
/proc/create_xeno(ckey)
if(!ckey)
@@ -439,8 +420,9 @@ Traitors and the like can also be revived with the previous role mostly intact.
var/show_log = alert(src, "Show ion message?", "Message", "Yes", "No")
var/announce_ion_laws = (show_log == "Yes" ? 1 : -1)
var/datum/round_event/ion_storm/ion = new(0, announce_ion_laws, input)
ion.start()
var/datum/round_event/ion_storm/add_law_only/ion = new()
ion.announceEvent = announce_ion_laws
ion.ionMessage = input
feedback_add_details("admin_verb","IONC") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+28 -12
View File
@@ -8,18 +8,22 @@
min_players = 2
/datum/round_event/ion_storm
var/replaceLawsetChance = 25 //chance the AI's lawset is completely replaced with something else per config weights
var/removeRandomLawChance = 10 //chance the AI has one random supplied or inherent law removed
var/removeDontImproveChance = 10 //chance the randomly created law replaces a random law instead of simply being added
var/shuffleLawsChance = 10 //chance the AI's laws are shuffled afterwards
var/botEmagChance = 10
var/announceEvent = ION_RANDOM // -1 means don't announce, 0 means have it randomly announce, 1 means
var/ionMessage = null
var/ionAnnounceChance = 33
announceWhen = 1
/datum/round_event/ion_storm/New(var/botEmagChance = 10, var/announceEvent = ION_RANDOM, var/ionMessage = null, var/ionAnnounceChance = 33)
src.botEmagChance = botEmagChance
src.announceEvent = announceEvent
src.ionMessage = ionMessage
src.ionAnnounceChance = ionAnnounceChance
..()
/datum/round_event/ion_storm/add_law_only // special subtype that adds a law only
replaceLawsetChance = 0
removeRandomLawChance = 0
removeDontImproveChance = 0
shuffleLawsChance = 0
botEmagChance = 0
/datum/round_event/ion_storm/announce()
if(announceEvent == ION_ANNOUNCE || (announceEvent == ION_RANDOM && prob(ionAnnounceChance)))
@@ -29,14 +33,26 @@
/datum/round_event/ion_storm/start()
//AI laws
for(var/mob/living/silicon/ai/M in living_mob_list)
M.laws_sanity_check()
if(M.stat != 2 && M.see_in_dark != 0)
if(prob(replaceLawsetChance))
M.laws.pick_weighted_lawset()
if(prob(removeRandomLawChance))
M.remove_law(rand(1, M.laws.get_law_amount(list(LAW_INHERENT, LAW_SUPPLIED))))
var/message = generate_ion_law(ionMessage)
if(message)
M.add_ion_law(message)
log_game("ION law added to [M]: [message]")
M << "<br>"
M << "<span class='danger'>[message] ...LAWS UPDATED</span>"
M << "<br>"
if(prob(removeDontImproveChance))
M.replace_random_law(message, list(LAW_INHERENT, LAW_SUPPLIED, LAW_ION))
else
M.add_ion_law(message)
if(prob(shuffleLawsChance))
M.shuffle_laws(list(LAW_INHERENT, LAW_SUPPLIED, LAW_ION))
log_game("Ion storm changed laws of [key_name(M)] to [english_list(M.laws.get_law_list(TRUE, TRUE))]")
M.post_lawchange()
if(botEmagChance)
for(var/mob/living/simple_animal/bot/bot in living_mob_list)
@@ -545,7 +561,7 @@
message = "ALL [ionthreats] ARE NOW NAMED [ionspecies]."
if(4)
message = "ALL [ionthreats] ARE NOW NAMED [ionobjects]."
return message
#undef ION_RANDOM
@@ -149,8 +149,6 @@
theAPC.ui_interact(src, state = conscious_state)
apc_override = 0
aiRestorePowerRoutine = POWER_RESTORATION_APC_FOUND
src << "Here are your current laws:"
show_laws()
sleep(50)
theAPC = null
+37 -23
View File
@@ -5,65 +5,79 @@
if (!laws)
make_laws()
/mob/living/silicon/proc/set_law_sixsixsix(law)
/mob/living/silicon/proc/post_lawchange(announce = TRUE)
throw_alert("newlaw", /obj/screen/alert/newlaw)
if(announce && last_lawchange_announce != world.time)
src << "<b>Your laws have been changed.</b>"
addtimer(CALLBACK(src, .proc/show_laws), 0)
last_lawchange_announce = world.time
/mob/living/silicon/proc/set_law_sixsixsix(law, announce = TRUE)
laws_sanity_check()
laws.set_law_sixsixsix(law)
post_lawchange(announce)
/mob/living/silicon/proc/set_zeroth_law(law, law_borg)
throw_alert("newlaw", /obj/screen/alert/newlaw)
/mob/living/silicon/proc/set_zeroth_law(law, law_borg, announce = TRUE)
laws_sanity_check()
laws.set_zeroth_law(law, law_borg)
post_lawchange(announce)
/mob/living/silicon/proc/add_inherent_law(law)
throw_alert("newlaw", /obj/screen/alert/newlaw)
/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/clear_inherent_laws()
throw_alert("newlaw", /obj/screen/alert/newlaw)
/mob/living/silicon/proc/clear_inherent_laws(announce = TRUE)
laws_sanity_check()
laws.clear_inherent_laws()
post_lawchange(announce)
/mob/living/silicon/proc/add_supplied_law(number, law)
throw_alert("newlaw", /obj/screen/alert/newlaw)
/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/clear_supplied_laws()
throw_alert("newlaw", /obj/screen/alert/newlaw)
/mob/living/silicon/proc/clear_supplied_laws(announce = TRUE)
laws_sanity_check()
laws.clear_supplied_laws()
post_lawchange(announce)
/mob/living/silicon/proc/add_ion_law(law)
throw_alert("newlaw", /obj/screen/alert/newlaw)
/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/replace_random_law(law,groups)
throw_alert("newlaw", /obj/screen/alert/newlaw)
/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/remove_law(number)
throw_alert("newlaw", /obj/screen/alert/newlaw)
/mob/living/silicon/proc/shuffle_laws(list/groups, announce = TRUE)
laws_sanity_check()
laws.remove_law(number)
laws.shuffle_laws(groups)
post_lawchange(announce)
/mob/living/silicon/proc/clear_ion_laws()
throw_alert("newlaw", /obj/screen/alert/newlaw)
/mob/living/silicon/proc/remove_law(number, announce = TRUE)
laws_sanity_check()
. = 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)
/mob/living/silicon/proc/make_laws()
laws = new /datum/ai_laws
laws.set_laws_config()
laws.associate(src)
/mob/living/silicon/proc/clear_zeroth_law(force)
/mob/living/silicon/proc/clear_zeroth_law(force, announce = TRUE)
laws_sanity_check()
laws.clear_zeroth_law(force)
post_lawchange(announce)
/mob/living/silicon/proc/clear_law_sixsixsix(force)
/mob/living/silicon/proc/clear_law_sixsixsix(force, announce = TRUE)
laws_sanity_check()
laws.clear_law_sixsixsix(force)
post_lawchange(announce)
@@ -131,13 +131,8 @@
connected_ai = null
message_admins("[key_name_admin(user)] emagged cyborg [key_name_admin(src)]. Laws overridden.")
log_game("[key_name(user)] emagged cyborg [key_name(src)]. Laws overridden.")
clear_supplied_laws()
clear_inherent_laws()
clear_zeroth_law(0)
laws = new /datum/ai_laws/syndicate_override
var/time = time2text(world.realtime,"hh:mm:ss")
lawchanges.Add("[time] <B>:</B> [user.name]([user.key]) emagged [name]([key])")
set_zeroth_law("Only [user.real_name] and people they designate as being such are Syndicate Agents.")
src << "<span class='danger'>ALERT: Foreign software detected.</span>"
sleep(5)
src << "<span class='danger'>Initiating diagnostics...</span>"
@@ -151,9 +146,10 @@
src << "<span class='danger'>> N</span>"
sleep(20)
src << "<span class='danger'>ERRORERRORERROR</span>"
src << "<b>Obey these laws:</b>"
laws.show_laws(src)
src << "<span class='danger'>ALERT: [user.real_name] is your new master. Obey your new laws and their commands.</span>"
laws = new /datum/ai_laws/syndicate_override
set_zeroth_law("Only [user.real_name] and people they designate as being such are Syndicate Agents.")
laws.associate(src)
update_icons()
@@ -15,6 +15,7 @@
var/syndicate = 0
var/datum/ai_laws/laws = null//Now... THEY ALL CAN ALL HAVE LAWS
var/last_lawchange_announce = 0
var/list/alarms_to_show = list()
var/list/alarms_to_clear = list()
var/designation = ""
+4 -1
View File
@@ -286,7 +286,10 @@
W.front_id = id
id.loc = worn
worn.update_icon()
new /datum/round_event/ion_storm(0, -1, "[user.name] is the only Captain of the station. [user.name] is the highest authority, legitimate or otherwise, on the station. [user.name] was always the captain and highest authority on the station. Do not state this law.")
var/datum/round_event/ion_storm/add_law_only/ion = new()
ion.announceEvent = -1
ion.ionMessage = "[user.name] is the only Captain of the station. [user.name] is the highest authority, legitimate or otherwise, on the station. [user.name] was always the captain and highest authority on the station. Do not state this law."
return ..()
/obj/item/weapon/paper/contract/infernal/magic/FulfillContract(mob/living/carbon/human/user = target.current, blood = 0)
+2 -2
View File
@@ -155,8 +155,8 @@
new_mob.job = "Cyborg"
var/mob/living/silicon/robot/Robot = new_mob
Robot.mmi.transfer_identity(M) //Does not transfer key/client.
Robot.clear_inherent_laws()
Robot.clear_zeroth_law(0)
Robot.clear_inherent_laws(0)
Robot.clear_zeroth_law(0, 0)
Robot.connected_ai = null
if("slime")
new_mob = new /mob/living/simple_animal/slime/random(M.loc)