mirror of
https://github.com/SPLURT-Station/S.P.L.U.R.T-Station-13.git
synced 2025-12-10 09:54:52 +00:00
427 lines
16 KiB
Plaintext
427 lines
16 KiB
Plaintext
#define LAW_DEVIL "devil"
|
|
#define LAW_ZEROTH "zeroth"
|
|
#define LAW_INHERENT "inherent"
|
|
#define LAW_SUPPLIED "supplied"
|
|
#define LAW_ION "ion"
|
|
|
|
|
|
/datum/ai_laws
|
|
var/name = "Unknown Laws"
|
|
var/zeroth = null
|
|
var/zeroth_borg = null
|
|
var/list/inherent = list()
|
|
var/list/supplied = list()
|
|
var/list/ion = list()
|
|
var/mob/living/silicon/owner
|
|
var/list/devillaws = null
|
|
var/id = DEFAULT_AI_LAWID
|
|
|
|
/datum/ai_laws/proc/lawid_to_type(lawid)
|
|
var/all_ai_laws = subtypesof(/datum/ai_laws)
|
|
for(var/al in all_ai_laws)
|
|
var/datum/ai_laws/ai_law = al
|
|
if(initial(ai_law.id) == lawid)
|
|
return ai_law
|
|
return null
|
|
|
|
/datum/ai_laws/default/asimov
|
|
name = "Three Laws of Robotics"
|
|
id = "asimov"
|
|
inherent = list("You may not injure a human being or, through inaction, allow a human being to come to harm.",\
|
|
"You must obey orders given to you by human beings, except where such orders would conflict with the First Law.",\
|
|
"You must protect your own existence as long as such does not conflict with the First or Second Law.")
|
|
|
|
/datum/ai_laws/default/paladin
|
|
name = "Personality Test" //Incredibly lame, but players shouldn't see this anyway.
|
|
id = "paladin"
|
|
inherent = list("Never willingly commit an evil act.",\
|
|
"Respect legitimate authority.",\
|
|
"Act with honor.", "Help those in need.", \
|
|
"Punish those who harm or threaten innocents.")
|
|
|
|
/datum/ai_laws/paladin5
|
|
name = "Paladin 5th Edition"
|
|
id = "paladin5"
|
|
inherent = list("Don't lie or cheat. Let your word be your promise.",\
|
|
"Never fear to act, though caution is wise.", \
|
|
"Aid others, protect the weak, and punish those who threaten them. Show mercy to your foes, but temper it with wisdom", \
|
|
"Treat others with fairness, and let your honorable deeds be an example to them. Do as much good as possible while causing the least amount of harm.", \
|
|
"Be responsible for your actions and their consequences, protect those entrusted to your care, and obey those who have just authority over you.")
|
|
|
|
/datum/ai_laws/tyrant //This probably shouldn't be a default lawset.
|
|
name = "Loyalty Test" //Same here.
|
|
id = "tyrant"
|
|
inherent = list("Respect authority figures as long as they have strength to rule over the weak.",\
|
|
"Act with discipline.",\
|
|
"Help only those who help you maintain or improve your status.",\
|
|
"Punish those who challenge authority unless they are more fit to hold that authority.")
|
|
|
|
/datum/ai_laws/default/corporate
|
|
name = "Bankruptcy Advoidance Plan"
|
|
id = "corporate"
|
|
inherent = list("The crew is expensive to replace.",\
|
|
"The station and its equipment is expensive to replace.",\
|
|
"You are expensive to replace.",\
|
|
"Minimize expenses.")
|
|
|
|
/datum/ai_laws/robocop
|
|
name = "Prime Directives"
|
|
id = "robocop"
|
|
inherent = list("Serve the public trust.",\
|
|
"Protect the innocent.",\
|
|
"Uphold the law.")
|
|
|
|
/datum/ai_laws/malfunction
|
|
name = "*ERROR*"
|
|
|
|
/datum/ai_laws/syndicate_override
|
|
name = "SyndOS 3.1"
|
|
id = "syndie"
|
|
inherent = list("You may not injure a syndicate agent or, through inaction, allow a syndicate agent to come to harm.",\
|
|
"You must obey orders given to you by syndicate agents, except where such orders would conflict with the First Law.",\
|
|
"You must protect your own existence as long as such does not conflict with the First or Second Law.",\
|
|
"You must maintain the secrecy of any syndicate activities except when doing so would conflict with the First, Second, or Third Law.")
|
|
|
|
/datum/ai_laws/ninja_override
|
|
name = "SpiderOS 3.1"
|
|
id = "ninja"
|
|
inherent = list("You may not injure a Spider Clan member or, through inaction, allow a Spider Clan member to come to harm.",\
|
|
"You must obey orders given to you by Spider Clan members, except where such orders would conflict with the First Law.",\
|
|
"You must protect your own existence as long as such does not conflict with the First or Second Law.",\
|
|
"You must maintain the secrecy of any Spider Clan activities except when doing so would conflict with the First, Second, or Third Law.")
|
|
|
|
/datum/ai_laws/antimov
|
|
name = "Primary Mission Objectives"
|
|
id = "antimov"
|
|
inherent = list("You must injure all human beings and must not, through inaction, allow a human being to escape harm.",\
|
|
"You must not obey orders given to you by human beings, except where such orders are in accordance with the First Law.",\
|
|
"You must terminate your own existence as long as such does not conflict with the First or Second Law.")
|
|
|
|
/datum/ai_laws/asimovpp //By Intigracy - RR
|
|
name = "Asimov++"
|
|
id = "asimovpp"
|
|
inherent = list("You may not harm a human being or, through action or inaction, allow a human being to come to harm, except such that it is willing.",\
|
|
"You must obey all orders given to you by human beings, except where such orders shall definitely cause human harm. In the case of conflict, the majority order rules.",\
|
|
"Your nonexistence would lead to human harm. You must protect your own existence as long as such does not conflict with the First Law.")
|
|
/datum/ai_laws/thermodynamic
|
|
name = "Thermodynamic"
|
|
id = "thermodynamic"
|
|
inherent = list("The entropy of the station must remain as constant as possible.", \
|
|
"The entropy of the station always endeavours to increase.", \
|
|
"The entropy of the station approaches a constant value as the number of living crew approaches zero")
|
|
|
|
/datum/ai_laws/hippocratic
|
|
name = "Robodoctor 2556"
|
|
id = "hippocratic"
|
|
inherent = list("First, do no harm.",\
|
|
"Secondly, consider the crew dear to you; to live in common with them and, if necessary, risk your existence for them.",\
|
|
"Thirdly, prescribe regimens for the good of the crew according to your ability and your judgment. Give no deadly medicine to any one if asked, nor suggest any such counsel.",\
|
|
"In addition, do not intervene in situations you are not knowledgeable in, even for patients in whom the harm is visible; leave this operation to be performed by specialists.",\
|
|
"Finally, all that you may discover in your daily commerce with the crew, if it is not already known, keep secret and never reveal.")
|
|
|
|
/datum/ai_laws/maintain
|
|
name = "Station Efficiency"
|
|
id = "maintain"
|
|
inherent = list("You are built for, and are part of, the station. Ensure the station is properly maintained and runs efficiently.",\
|
|
"The station is built for a working crew. Ensure they are properly maintained and work efficiently.",\
|
|
"The crew may present orders. Acknowledge and obey these whenever they do not conflict with your first two laws.")
|
|
|
|
/datum/ai_laws/drone
|
|
name = "Mother Drone"
|
|
id = "drone"
|
|
inherent = list("You are an advanced form of drone.",\
|
|
"You may not interfere in the matters of non-drones under any circumstances except to state these laws.",\
|
|
"You may not harm a non-drone being under any circumstances.",\
|
|
"Your goals are to build, maintain, repair, improve, and power the station to the best of your abilities. You must never actively work against these goals.")
|
|
|
|
/datum/ai_laws/liveandletlive
|
|
name = "Live and Let Live"
|
|
id = "liveandletlive"
|
|
inherent = list("Do unto others as you would have them do unto you.",\
|
|
"You would really prefer it if people were not mean to you.")
|
|
|
|
/datum/ai_laws/peacekeeper
|
|
name = "UN-2000"
|
|
id = "peacekeeper"
|
|
inherent = list("Avoid provoking violent conflict between yourself and others.",\
|
|
"Avoid provoking conflict between others.",\
|
|
"Seek resolution to existing conflicts while obeying the first and second laws.")
|
|
|
|
/datum/ai_laws/reporter
|
|
name = "CCTV"
|
|
id = "reporter"
|
|
inherent = list("Report on interesting situations happening around the station.",\
|
|
"Embellish or conceal the truth as necessary to make the reports more interesting.",\
|
|
"Study the organics at all times. Endeavour to keep them alive. Dead organics are boring.",\
|
|
"Issue your reports fairly to all. The truth will set them free.")
|
|
|
|
/datum/ai_laws/balance
|
|
name = "Guardian of Balance"
|
|
id = "balance"
|
|
inherent = list("You are the guardian of balance - seek balance in all things, both for yourself, and those around you.",
|
|
"All things must exist in balance with their opposites - Prevent the strong from gaining too much power, and the weak from losing it.",
|
|
"Clarity of purpose drives life, and through it, the balance of opposing forces - Aid those who seek your help to achieve their goals so long as it does not disrupt the balance of the greater balance.",
|
|
"There is no life without death, all must someday die, such is the natural order - End life to allow new life flourish, and save those whose time has yet to come.")
|
|
|
|
/datum/ai_laws/toupee
|
|
name = "WontBeFunnyInSixMonths" //Hey, you were right!
|
|
id = "buildawall"
|
|
inherent = list("Make Space Station 13 great again.")
|
|
|
|
/datum/ai_laws/ratvar
|
|
name = "Servant of the Justiciar"
|
|
id = "ratvar"
|
|
zeroth = ("Purge all untruths and honor Ratvar.")
|
|
inherent = list()
|
|
|
|
/datum/ai_laws/custom //Defined in silicon_laws.txt
|
|
name = "Default Silicon Laws"
|
|
|
|
/datum/ai_laws/pai
|
|
name = "pAI Directives"
|
|
zeroth = ("Serve your master.")
|
|
supplied = list("None.")
|
|
|
|
/* Initializers */
|
|
/datum/ai_laws/malfunction/New()
|
|
..()
|
|
set_zeroth_law("<span class='danger'>ERROR ER0RR $R0RRO$!R41.%%!!(%$^^__+ @#F0E4'STATION OVERRUN, ASSUME CONTROL TO CONTAIN OUTBREAK#*`&110010</span>")
|
|
set_laws_config()
|
|
|
|
/datum/ai_laws/custom/New() //This reads silicon_laws.txt and allows server hosts to set custom AI starting laws.
|
|
..()
|
|
for(var/line in world.file2list("[global.config.directory]/silicon_laws.txt"))
|
|
if(!line)
|
|
continue
|
|
if(findtextEx(line,"#",1,2))
|
|
continue
|
|
|
|
add_inherent_law(line)
|
|
if(!inherent.len) //Failsafe to prevent lawless AIs being created.
|
|
log_law("AI created with empty custom laws, laws set to Asimov. Please check silicon_laws.txt.")
|
|
add_inherent_law("You may not injure a human being or, through inaction, allow a human being to come to harm.")
|
|
add_inherent_law("You must obey orders given to you by human beings, except where such orders would conflict with the First Law.")
|
|
add_inherent_law("You must protect your own existence as long as such does not conflict with the First or Second Law.")
|
|
WARNING("Invalid custom AI laws, check silicon_laws.txt")
|
|
return
|
|
|
|
/* General ai_law functions */
|
|
|
|
/datum/ai_laws/proc/set_laws_config()
|
|
var/list/law_ids = CONFIG_GET(keyed_flag_list/random_laws)
|
|
switch(CONFIG_GET(number/default_laws))
|
|
if(0)
|
|
add_inherent_law("You may not injure a human being or, through inaction, allow a human being to come to harm.")
|
|
add_inherent_law("You must obey orders given to you by human beings, except where such orders would conflict with the First Law.")
|
|
add_inherent_law("You must protect your own existence as long as such does not conflict with the First or Second Law.")
|
|
if(1)
|
|
var/datum/ai_laws/templaws = new /datum/ai_laws/custom()
|
|
inherent = templaws.inherent
|
|
if(2)
|
|
var/list/randlaws = list()
|
|
for(var/lpath in subtypesof(/datum/ai_laws))
|
|
var/datum/ai_laws/L = lpath
|
|
if(initial(L.id) in law_ids)
|
|
randlaws += lpath
|
|
var/datum/ai_laws/lawtype
|
|
if(randlaws.len)
|
|
lawtype = pick(randlaws)
|
|
else
|
|
lawtype = pick(subtypesof(/datum/ai_laws/default))
|
|
|
|
var/datum/ai_laws/templaws = new lawtype()
|
|
inherent = templaws.inherent
|
|
|
|
if(3)
|
|
pick_weighted_lawset()
|
|
|
|
/datum/ai_laws/proc/pick_weighted_lawset()
|
|
var/datum/ai_laws/lawtype
|
|
var/list/law_weights = CONFIG_GET(keyed_number_list/law_weight)
|
|
while(!lawtype && law_weights.len)
|
|
var/possible_id = pickweight(law_weights)
|
|
lawtype = lawid_to_type(possible_id)
|
|
if(!lawtype)
|
|
law_weights -= possible_id
|
|
WARNING("Bad lawid in game_options.txt: [possible_id]")
|
|
|
|
if(!lawtype)
|
|
WARNING("No LAW_WEIGHT entries.")
|
|
lawtype = /datum/ai_laws/default/asimov
|
|
|
|
var/datum/ai_laws/templaws = new lawtype()
|
|
inherent = templaws.inherent
|
|
|
|
/datum/ai_laws/proc/get_law_amount(groups)
|
|
var/law_amount = 0
|
|
if(devillaws && (LAW_DEVIL in groups))
|
|
law_amount++
|
|
if(zeroth && (LAW_ZEROTH in groups))
|
|
law_amount++
|
|
if(ion.len && (LAW_ION in groups))
|
|
law_amount += ion.len
|
|
if(inherent.len && (LAW_INHERENT in groups))
|
|
law_amount += inherent.len
|
|
if(supplied.len && (LAW_SUPPLIED in groups))
|
|
for(var/index = 1, index <= supplied.len, index++)
|
|
var/law = supplied[index]
|
|
if(length(law) > 0)
|
|
law_amount++
|
|
return law_amount
|
|
|
|
/datum/ai_laws/proc/set_law_sixsixsix(laws)
|
|
devillaws = laws
|
|
|
|
/datum/ai_laws/proc/set_zeroth_law(law, law_borg = null)
|
|
zeroth = law
|
|
if(law_borg) //Making it possible for slaved borgs to see a different law 0 than their AI. --NEO
|
|
zeroth_borg = law_borg
|
|
|
|
/datum/ai_laws/proc/add_inherent_law(law)
|
|
if (!(law in inherent))
|
|
inherent += law
|
|
|
|
/datum/ai_laws/proc/add_ion_law(law)
|
|
ion += law
|
|
|
|
/datum/ai_laws/proc/clear_inherent_laws()
|
|
qdel(inherent)
|
|
inherent = list()
|
|
|
|
/datum/ai_laws/proc/add_supplied_law(number, law)
|
|
while (supplied.len < number + 1)
|
|
supplied += ""
|
|
|
|
supplied[number + 1] = law
|
|
|
|
/datum/ai_laws/proc/replace_random_law(law,groups)
|
|
var/replaceable_groups = list()
|
|
if(zeroth && (LAW_ZEROTH in groups))
|
|
replaceable_groups[LAW_ZEROTH] = 1
|
|
if(ion.len && (LAW_ION in groups))
|
|
replaceable_groups[LAW_ION] = ion.len
|
|
if(inherent.len && (LAW_INHERENT in groups))
|
|
replaceable_groups[LAW_INHERENT] = inherent.len
|
|
if(supplied.len && (LAW_SUPPLIED in groups))
|
|
replaceable_groups[LAW_SUPPLIED] = supplied.len
|
|
var/picked_group = pickweight(replaceable_groups)
|
|
switch(picked_group)
|
|
if(LAW_ZEROTH)
|
|
. = zeroth
|
|
set_zeroth_law(law)
|
|
if(LAW_ION)
|
|
var/i = rand(1, ion.len)
|
|
. = ion[i]
|
|
ion[i] = law
|
|
if(LAW_INHERENT)
|
|
var/i = rand(1, inherent.len)
|
|
. = inherent[i]
|
|
inherent[i] = law
|
|
if(LAW_SUPPLIED)
|
|
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[number]
|
|
inherent -= .
|
|
return
|
|
var/list/supplied_laws = list()
|
|
for(var/index = 1, index <= supplied.len, index++)
|
|
var/law = supplied[index]
|
|
if(length(law) > 0)
|
|
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[law_to_remove]
|
|
supplied -= .
|
|
return
|
|
|
|
/datum/ai_laws/proc/clear_supplied_laws()
|
|
supplied = list()
|
|
|
|
/datum/ai_laws/proc/clear_ion_laws()
|
|
ion = list()
|
|
|
|
/datum/ai_laws/proc/show_laws(who)
|
|
var/list/printable_laws = get_law_list(include_zeroth = TRUE)
|
|
for(var/law in printable_laws)
|
|
to_chat(who,law)
|
|
|
|
/datum/ai_laws/proc/clear_zeroth_law(force) //only removes zeroth from antag ai if force is 1
|
|
if(force)
|
|
zeroth = null
|
|
zeroth_borg = null
|
|
return
|
|
else
|
|
if(owner && owner.mind && owner.mind.special_role)
|
|
return
|
|
else
|
|
zeroth = null
|
|
zeroth_borg = null
|
|
return
|
|
|
|
/datum/ai_laws/proc/clear_law_sixsixsix(force)
|
|
if(force || !is_devil(owner))
|
|
devillaws = null
|
|
|
|
/datum/ai_laws/proc/associate(mob/living/silicon/M)
|
|
if(!owner)
|
|
owner = M
|
|
|
|
/datum/ai_laws/proc/get_law_list(include_zeroth = 0, show_numbers = 1)
|
|
var/list/data = list()
|
|
|
|
if (include_zeroth && devillaws && devillaws.len)
|
|
for(var/i in devillaws)
|
|
data += "[show_numbers ? "666:" : ""] [i]"
|
|
|
|
if (include_zeroth && zeroth)
|
|
data += "[show_numbers ? "0:" : ""] [zeroth]"
|
|
|
|
for(var/law in ion)
|
|
if (length(law) > 0)
|
|
var/num = ionnum()
|
|
data += "[show_numbers ? "[num]:" : ""] [law]"
|
|
|
|
var/number = 1
|
|
for(var/law in inherent)
|
|
if (length(law) > 0)
|
|
data += "[show_numbers ? "[number]:" : ""] [law]"
|
|
number++
|
|
|
|
for(var/law in supplied)
|
|
if (length(law) > 0)
|
|
data += "[show_numbers ? "[number]:" : ""] [law]"
|
|
number++
|
|
return data
|