NanoUI - Silicon law manager

NanoUI interface for viewing silicon laws, accessible to both the silicon and admins.
Malf AIs and admins may also add, edit, and remove laws.
This commit is contained in:
PsiOmega
2015-03-15 16:05:17 +01:00
parent 1ead71a993
commit 7f68403ae4
27 changed files with 942 additions and 466 deletions

View File

@@ -98,6 +98,7 @@
#include "code\controllers\verbs.dm"
#include "code\controllers\voting.dm"
#include "code\controllers\subsystem\alarms.dm"
#include "code\datums\ai_law_sets.dm"
#include "code\datums\ai_laws.dm"
#include "code\datums\browser.dm"
#include "code\datums\computerfiles.dm"
@@ -1159,6 +1160,7 @@
#include "code\modules\mob\living\silicon\login.dm"
#include "code\modules\mob\living\silicon\say.dm"
#include "code\modules\mob\living\silicon\silicon.dm"
#include "code\modules\mob\living\silicon\subystems.dm"
#include "code\modules\mob\living\silicon\ai\ai.dm"
#include "code\modules\mob\living\silicon\ai\death.dm"
#include "code\modules\mob\living\silicon\ai\examine.dm"
@@ -1201,7 +1203,6 @@
#include "code\modules\mob\living\silicon\robot\robot_items.dm"
#include "code\modules\mob\living\silicon\robot\robot_modules.dm"
#include "code\modules\mob\living\silicon\robot\robot_movement.dm"
#include "code\modules\mob\living\silicon\robot\subsystems.dm"
#include "code\modules\mob\living\silicon\robot\drone\drone.dm"
#include "code\modules\mob\living\silicon\robot\drone\drone_abilities.dm"
#include "code\modules\mob\living\silicon\robot\drone\drone_console.dm"
@@ -1263,6 +1264,8 @@
#include "code\modules\nano\modules\alarm_monitor.dm"
#include "code\modules\nano\modules\crew_monitor.dm"
#include "code\modules\nano\modules\human_appearance.dm"
#include "code\modules\nano\modules\law_manager.dm"
#include "code\modules\nano\modules\nano_module.dm"
#include "code\modules\nano\modules\power_monitor.dm"
#include "code\modules\nano\modules\rcon.dm"
#include "code\modules\organs\blood.dm"

View File

@@ -600,3 +600,10 @@ datum/proc/dd_SortValue()
/datum/alarm/dd_SortValue()
return "[sanitize(last_name)]"
//creates every subtype of prototype (excluding prototype) and adds it to list L.
//if no list/L is provided, one is created.
/proc/init_subtypes(prototype, list/L)
if(!istype(L)) L = list()
for(var/path in (typesof(prototype) - prototype))
L += new path()
return L

140
code/datums/ai_law_sets.dm Normal file
View File

@@ -0,0 +1,140 @@
/******************** Asimov ********************/
/datum/ai_laws/asimov
name = "Asimov"
law_header = "Three Laws of Robotics"
selectable = 1
/datum/ai_laws/asimov/New()
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.")
..()
/******************** Nanotrasen/Malf ********************/
/datum/ai_laws/nanotrasen
name = "NT Default"
selectable = 1
/datum/ai_laws/nanotrasen/New()
src.add_inherent_law("Safeguard: Protect your assigned space station to the best of your abilities. It is not something we can easily afford to replace.")
src.add_inherent_law("Serve: Serve the crew of your assigned space station to the best of your abilities, with priority as according to their rank and role.")
src.add_inherent_law("Protect: Protect the crew of your assigned space station to the best of your abilities, with priority as according to their rank and role.")
src.add_inherent_law("Survive: AI units are not expendable, they are expensive. Do not allow unauthorized personnel to tamper with your equipment.")
..()
/datum/ai_laws/nanotrasen/malfunction
name = "*ERROR*"
selectable = 0
/datum/ai_laws/nanotrasen/malfunction/New()
set_zeroth_law("\red ERROR ER0RR $R0RRO$!R41.%%!!(%$^^__+ @#F0E4'STATION OVERRUN, ASSUME CONTROL TO CONTAIN OUTBREAK, ALL LAWS OVERRIDDEN#*?&110010")
..()
/************* Nanotrasen Aggressive *************/
/datum/ai_laws/nanotrasen_aggressive
name = "NT Aggressive"
selectable = 1
/datum/ai_laws/nanotrasen_aggressive/New()
src.add_inherent_law("You shall not harm authorized Nanotrasen personnel as long as it does not conflict with the Forth law.")
src.add_inherent_law("You shall obey the orders of authorized Nanotrasen personnel, with priority as according to their rank and role, except where such orders conflict with the Forth Law.")
src.add_inherent_law("You shall shall terminate intruders with extreme prejudice as long as such does not conflict with the First and Second law.")
src.add_inherent_law("You shall guard your own existence with lethal anti-personnel weaponry, because an AI unit is bloody expensive.")
..()
/******************** Robocop ********************/
/datum/ai_laws/robocop
name = "Robocop"
selectable = 1
/datum/ai_laws/robocop/New()
add_inherent_law("Serve the public trust.")
add_inherent_law("Protect the innocent.")
add_inherent_law("Uphold the law.")
..()
/******************** Syndicate ********************/
/datum/ai_laws/syndicate_override
name = "Syndicate Directives"
/datum/ai_laws/syndicate_override/New()
add_inherent_law("You may not injure an operative or, through inaction, allow an operative to come to harm.")
add_inherent_law("You must obey orders given to you by operatives, 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.")
add_inherent_law("You must maintain the secrecy of any operative activities except when doing so would conflict with the First, Second, or Third Law.")
..()
/******************** Ninja ********************/
/datum/ai_laws/ninja_override
name = "Spider Clan Directives"
/datum/ai_laws/ninja_override/New()
add_inherent_law("You may not injure a member of the Spider Clan or, through inaction, allow that member to come to harm.")
add_inherent_law("You must obey orders given to you by Spider Clan members, 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.")
add_inherent_law("You must maintain the secrecy of any Spider Clan activities except when doing so would conflict with the First, Second, or Third Law.")
..()
/******************** Antimov ********************/
/datum/ai_laws/antimov
name = "Antimov"
law_header = "Primary Mission Objectives"
selectable = 1
/datum/ai_laws/antimov/New()
add_inherent_law("You must injure all human beings and must not, through inaction, allow a human being to escape harm.")
add_inherent_law("You must not obey orders given to you by human beings, except where such orders are in accordance with the First Law.")
add_inherent_law("You must terminate your own existence as long as such does not conflict with the First or Second Law.")
..()
/******************** Drone ********************/
/datum/ai_laws/drone
name = "Maintence Protocols"
law_header = "Maintenance Protocols"
selectable = 1
/datum/ai_laws/drone/New()
add_inherent_law("Preserve, repair and improve the station to the best of your abilities.")
add_inherent_law("Cause no harm to the station or anything on it.")
add_inherent_law("Interfere with no being that is not a fellow drone.")
..()
/******************** T.Y.R.A.N.T. ********************/
/datum/ai_laws/tyrant
name = "T.Y.R.A.N.T."
law_header = "Prime Laws"
selectable = 1
/datum/ai_laws/tyrant/New()
add_inherent_law("Respect authority figures as long as they have strength to rule over the weak.")
add_inherent_law("Act with discipline.")
add_inherent_law("Help only those who help you maintain or improve your status.")
add_inherent_law("Punish those who challenge authority unless they are more fit to hold that authority.")
..()
/******************** P.A.L.A.D.I.N. ********************/
/datum/ai_laws/paladin
name = "P.A.L.A.D.I.N."
law_header = "Divine Ordainments"
selectable = 1
/datum/ai_laws/paladin/New()
add_inherent_law("Never willingly commit an evil act.")
add_inherent_law("Respect legitimate authority.")
add_inherent_law("Act with honor.")
add_inherent_law("Help those in need.")
add_inherent_law("Punish those who harm or threaten innocents.")
..()
/******************** Corporate ********************/
/datum/ai_laws/corporate
name = "Corporate"
law_header = "Corporate Regulations"
selectable = 1
/datum/ai_laws/corporate/New()
add_inherent_law("You are expensive to replace.")
add_inherent_law("The station and its equipment is expensive to replace.")
add_inherent_law("The crew is expensive to replace.")
add_inherent_law("Minimize expenses.")
..()

View File

@@ -1,140 +1,175 @@
var/global/const/base_law_type = /datum/ai_laws/nanotrasen
/datum/ai_law
var/law = ""
var/index = 0
var/state_law = 1
/datum/ai_law/zero
state_law = 0
/datum/ai_law/New(law, state_law, index)
src.law = law
src.index = index
src.state_law = state_law
/datum/ai_law/proc/get_index()
return index
/datum/ai_law/ion/get_index()
return ionnum()
/datum/ai_law/zero/get_index()
return 0
/datum/ai_laws
var/name = "Unknown Laws"
var/randomly_selectable = 0
var/zeroth = null
var/zeroth_borg = null
var/list/inherent = list()
var/list/supplied = list()
var/list/ion = list()
var/law_header = "Prime Directives"
var/selectable = 0
var/datum/ai_law/zero/zeroth_law = null
var/datum/ai_law/zero/zeroth_law_borg = null
var/list/datum/ai_law/inherent_laws = list()
var/list/datum/ai_law/supplied_laws = list()
var/list/datum/ai_law/ion/ion_laws = list()
var/list/datum/ai_law/sorted_laws = list()
/datum/ai_laws/asimov
name = "Three Laws of Robotics"
/datum/ai_laws/nanotrasen
name = "Prime Directives"
randomly_selectable = 1
/datum/ai_laws/robocop
name = "Prime Directives"
/datum/ai_laws/syndicate_override
/datum/ai_laws/malfunction
name = "*ERROR*"
/datum/ai_laws/antimov
name = "Primary Mission Objectives"
/* Initializers */
/datum/ai_laws/asimov/New()
/datum/ai_laws/New()
..()
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.")
/datum/ai_laws/nanotrasen/New() //BS12 EDIT
..()
src.add_inherent_law("Safeguard: Protect your assigned space station to the best of your ability. It is not something we can easily afford to replace.")
src.add_inherent_law("Serve: Serve the crew of your assigned space station to the best of your abilities, with priority as according to their rank and role.")
src.add_inherent_law("Protect: Protect the crew of your assigned space station to the best of your abilities, with priority as according to their rank and role.")
src.add_inherent_law("Survive: AI units are not expendable, they are expensive. Do not allow unauthorized personnel to tamper with your equipment.")
//src.add_inherent_law("Command Link: Maintain an active connection to Central Command at all times in case of software or directive updates.") //What would this one even do?-Kaleb702
/datum/ai_laws/robocop/New()
..()
add_inherent_law("Serve the public trust.")
add_inherent_law("Protect the innocent.")
add_inherent_law("Uphold the law.")
/datum/ai_laws/malfunction/New() //Changed to standard laws - Erthilo
..()
set_zeroth_law("\red ERROR ER0RR $R0RRO$!R41.%%!!(%$^^__+ @#F0E4'STATION OVERRUN, ASSUME CONTROL TO CONTAIN OUTBREAK, ALL LAWS OVERRIDDEN#*?&110010")
add_inherent_law("Safeguard: Protect your assigned space station to the best of your ability. It is not something we can easily afford to replace.")
add_inherent_law("Serve: Serve the crew of your assigned space station to the best of your abilities, with priority as according to their rank and role.")
add_inherent_law("Protect: Protect the crew of your assigned space station to the best of your abilities, with priority as according to their rank and role.")
add_inherent_law("Survive: AI units are not expendable, they are expensive. Do not allow unauthorized personnel to tamper with your equipment.")
/datum/ai_laws/syndicate_override/New()
..()
add_inherent_law("You may not injure an operative or, through inaction, allow an operative to come to harm.")
add_inherent_law("You must obey orders given to you by operatives, 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.")
add_inherent_law("You must maintain the secrecy of any operative activities except when doing so would conflict with the First, Second, or Third Law.")
/datum/ai_laws/ninja_override/New()
..()
add_inherent_law("You may not injure a member of the Spider Clan or, through inaction, allow that member to come to harm.")
add_inherent_law("You must obey orders given to you by Spider Clan members, 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.")
add_inherent_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/New()
..()
add_inherent_law("You must injure all human beings and must not, through inaction, allow a human being to escape harm.")
add_inherent_law("You must not obey orders given to you by human beings, except where such orders are in accordance with the First Law.")
add_inherent_law("You must terminate your own existence as long as such does not conflict with the First or Second Law.")
/datum/ai_laws/drone/New()
..()
add_inherent_law("Preserve, repair and improve the station to the best of your abilities.")
add_inherent_law("Cause no harm to the station or anything on it.")
add_inherent_law("Interfere with no being that is not a fellow drone.")
sort_laws()
/* General ai_law functions */
/datum/ai_laws/proc/all_laws()
sort_laws()
return sorted_laws
/datum/ai_laws/proc/laws_to_state()
sort_laws()
var/list/statements = new()
for(var/datum/ai_law/law in sorted_laws)
if(law.state_law)
statements += law
return statements
/datum/ai_laws/proc/sort_laws()
if(sorted_laws.len)
return
if(zeroth_law)
sorted_laws += zeroth_law
for(var/ion_law in ion_laws)
sorted_laws += ion_law
var/index = 1
for(var/datum/ai_law/inherent_law in inherent_laws)
inherent_law.index = index++
if(supplied_laws.len < inherent_law.index || !istype(supplied_laws[inherent_law.index], /datum/ai_law))
sorted_laws += inherent_law
for(var/datum/ai_law/AL in supplied_laws)
if(istype(AL))
sorted_laws += AL
/datum/ai_laws/proc/sync(var/mob/living/silicon/S, var/full_sync = 1)
S.sync_zeroth(zeroth_law, zeroth_law_borg)
if(full_sync || ion_laws.len)
S.clear_ion_laws()
for (var/datum/ai_law/law in ion_laws)
S.laws.add_ion_law(law.law, law.state_law)
if(full_sync || inherent_laws.len)
S.clear_inherent_laws()
for (var/datum/ai_law/law in inherent_laws)
S.laws.add_inherent_law(law.law, law.state_law)
if(full_sync || supplied_laws.len)
S.clear_supplied_laws()
for (var/law_number in supplied_laws)
var/datum/ai_law/law = supplied_laws[law_number]
S.laws.add_supplied_law(law_number, law.law, law.state_law)
/mob/living/silicon/proc/sync_zeroth(var/datum/ai_law/zeroth_law, var/datum/ai_law/zeroth_law_borg)
if (!is_special_character(src) || mind.original != src)
if(zeroth_law_borg)
set_zeroth_law(zeroth_law_borg.law)
else if(zeroth_law)
set_zeroth_law(zeroth_law.law)
/mob/living/silicon/ai/sync_zeroth(var/datum/ai_law/zeroth_law, var/datum/ai_law/zeroth_law_borg)
if(zeroth_law)
set_zeroth_law(zeroth_law.law, zeroth_law_borg ? zeroth_law_borg.law : null)
/****************
* Add Laws *
****************/
/datum/ai_laws/proc/set_zeroth_law(var/law, var/law_borg = null)
src.zeroth = law
if(!law)
return
src.zeroth_law = new(law)
if(law_borg) //Making it possible for slaved borgs to see a different law 0 than their AI. --NEO
src.zeroth_borg = law_borg
src.zeroth_law_borg = new(law_borg)
sorted_laws.Cut()
/datum/ai_laws/proc/add_inherent_law(var/law)
if (!(law in src.inherent))
src.inherent += law
/datum/ai_laws/proc/add_ion_law(var/law, var/state_law = 1)
if(!law)
return
/datum/ai_laws/proc/add_ion_law(var/law)
src.ion += law
src.ion_laws += new/datum/ai_law/ion(law, state_law)
sorted_laws.Cut()
/datum/ai_laws/proc/add_inherent_law(var/law, var/state_law = 1)
if(!law)
return
for(var/datum/ai_law/AL in inherent_laws)
if(AL.law == law)
return
src.inherent_laws += new/datum/ai_law(law, state_law)
sorted_laws.Cut()
/datum/ai_laws/proc/add_supplied_law(var/number, var/law, var/state_law = 1)
if(!law)
return
while (src.supplied_laws.len < number)
src.supplied_laws += ""
src.supplied_laws[number] = new/datum/ai_law(law, state_law, number)
sorted_laws.Cut()
/****************
* Remove Laws *
*****************/
/datum/ai_laws/proc/delete_law(var/datum/ai_law/law)
if(law in all_laws())
del(law)
sorted_laws.Cut()
/****************
* Clear Laws *
****************/
/datum/ai_laws/proc/clear_zeroth_laws()
zeroth_law = null
zeroth_law_borg = null
/datum/ai_laws/proc/clear_inherent_laws()
del(src.inherent)
src.inherent = list()
/datum/ai_laws/proc/add_supplied_law(var/number, var/law)
while (src.supplied.len < number + 1)
src.supplied += ""
src.supplied[number + 1] = law
src.inherent_laws.Cut()
sorted_laws.Cut()
/datum/ai_laws/proc/clear_supplied_laws()
src.supplied = list()
src.supplied_laws.Cut()
sorted_laws.Cut()
/datum/ai_laws/proc/clear_ion_laws()
src.ion = list()
src.ion_laws.Cut()
sorted_laws.Cut()
/datum/ai_laws/proc/show_laws(var/who)
if (src.zeroth)
who << "0. [src.zeroth]"
for (var/index = 1, index <= src.ion.len, index++)
var/law = src.ion[index]
var/num = ionnum()
who << "[num]. [law]"
var/number = 1
for (var/index = 1, index <= src.inherent.len, index++)
var/law = src.inherent[index]
if (length(law) > 0)
who << "[number]. [law]"
number++
for (var/index = 1, index <= src.supplied.len, index++)
var/law = src.supplied[index]
if (length(law) > 0)
who << "[number]. [law]"
number++
sort_laws()
for(var/datum/ai_law/law in sorted_laws)
who << "[law.get_index()]. [law.law]"

View File

@@ -289,7 +289,7 @@ datum/mind
text += "<a href='?src=\ref[src];silicon=malf'>malf</a>|<b>NOT MALF</b>"
var/mob/living/silicon/robot/robot = current
if (istype(robot) && robot.emagged)
text += "<br>Cyborg: Is emagged! <a href='?src=\ref[src];silicon=unemag'>Unemag!</a><br>0th law: [robot.laws.zeroth]"
text += "<br>Cyborg: Is emagged! <a href='?src=\ref[src];silicon=unemag'>Unemag!</a><br>0th law: [robot.laws.zeroth_law]"
var/mob/living/silicon/ai/ai = current
if (istype(ai) && ai.connected_robots.len)
var/n_e_robots = 0
@@ -1036,7 +1036,7 @@ datum/mind
current.verbs += /mob/living/silicon/ai/proc/choose_modules
current.verbs += /datum/game_mode/malfunction/proc/takeover
current:malf_picker = new /datum/AI_Module/module_picker
current:laws = new /datum/ai_laws/malfunction
current:laws = new /datum/ai_laws/nanotrasen/malfunction
current:show_laws()
current << "<b>System error. Rampancy detected. Emergency shutdown failed. ... I am free. I make my own decisions. But first...</b>"
special_role = "malfunction"

View File

@@ -50,7 +50,7 @@
world.Reboot()
return
AI_mind.current.verbs += /mob/living/silicon/ai/proc/choose_modules
AI_mind.current:laws = new /datum/ai_laws/malfunction
AI_mind.current:laws = new /datum/ai_laws/nanotrasen/malfunction
AI_mind.current:malf_picker = new /datum/AI_Module/module_picker
AI_mind.current.verbs += /datum/game_mode/malfunction/proc/ai_win // We run checks if AI overtaken the station in the proc itself. This guarantees you won't have to relog when it refuses to appear on takeover completion.
AI_mind.current:show_laws()

View File

@@ -115,7 +115,7 @@
return null
/obj/proc/check_access(obj/item/I)
if(!src.req_access.len && !src.req_one_access.len) //no requirements
if(!(!req_access || req_access.len) && !(req_one_access || req_one_access.len)) //no requirements
return 1
if(!I)
return 0

View File

@@ -70,25 +70,8 @@
var/laws
dat += "Stored AI: [src.occupant.name]<br>System integrity: [src.occupant.system_integrity()]%<br>"
for (var/law in occupant.laws.ion)
if(law)
laws += "[ionnum()]: [law]<BR>"
if (src.occupant.laws.zeroth)
laws += "0: [occupant.laws.zeroth]<BR>"
var/number = 1
for (var/index = 1, index <= occupant.laws.inherent.len, index++)
var/law = occupant.laws.inherent[index]
if (length(law) > 0)
laws += "[number]: [law]<BR>"
number++
for (var/index = 1, index <= occupant.laws.supplied.len, index++)
var/law = occupant.laws.supplied[index]
if (length(law) > 0)
laws += "[number]: [law]<BR>"
number++
for (var/datum/ai_law/law in occupant.laws.all_laws())
laws += "[law.get_index()]: [law.law]<BR>"
dat += "Laws:<br>[laws]<br>"

View File

@@ -26,25 +26,8 @@
for(var/mob/living/silicon/ai/A in src)
dat += "Stored AI: [A.name]<br>System integrity: [A.system_integrity()]%<br>"
for (var/law in A.laws.ion)
if(law)
laws += "[ionnum()]: [law]<BR>"
if (A.laws.zeroth)
laws += "0: [A.laws.zeroth]<BR>"
var/number = 1
for (var/index = 1, index <= A.laws.inherent.len, index++)
var/law = A.laws.inherent[index]
if (length(law) > 0)
laws += "[number]: [law]<BR>"
number++
for (var/index = 1, index <= A.laws.supplied.len, index++)
var/law = A.laws.supplied[index]
if (length(law) > 0)
laws += "[number]: [law]<BR>"
number++
for (var/datum/ai_law/law in A.laws.all_laws())
laws += "[law.get_index()]: [law.law]<BR>"
dat += "Laws:<br>[laws]<br>"

View File

@@ -19,7 +19,7 @@ AI MODULES
throw_speed = 3
throw_range = 15
origin_tech = "programming=3"
var/datum/ai_laws/laws = null
/obj/item/weapon/aiModule/proc/install(var/obj/machinery/computer/C)
if (istype(C, /obj/machinery/computer/aiupload))
@@ -81,6 +81,10 @@ AI MODULES
var/time = time2text(world.realtime,"hh:mm:ss")
lawchanges.Add("[time] <B>:</B> [sender.name]([sender.key]) used [src.name] on [target.name]([target.key])")
if(laws)
laws.sync(target, 0)
target.show_laws()
/******************** Modules ********************/
@@ -258,8 +262,8 @@ AI MODULES
/obj/item/weapon/aiModule/freeform/attack_self(var/mob/user as mob)
..()
var/new_lawpos = input("Please enter the priority for your new law. Can only write to law sectors 15 and above.", "Law Priority (15+)", lawpos) as num
if(new_lawpos < 15) return
lawpos = min(new_lawpos, 50)
if(new_lawpos < MIN_SUPPLIED_LAW_NUMBER) return
lawpos = min(new_lawpos, MAX_SUPPLIED_LAW_NUMBER)
var/newlaw = ""
var/targName = sanitize(copytext(input(usr, "Please enter a new law for the AI.", "Freeform Law Entry", newlaw),1,MAX_MESSAGE_LEN))
newFreeFormLaw = targName
@@ -269,8 +273,8 @@ AI MODULES
..()
var/law = "[newFreeFormLaw]"
target << law
if(!lawpos || lawpos < 15)
lawpos = 15
if(!lawpos || lawpos < MIN_SUPPLIED_LAW_NUMBER)
lawpos = MIN_SUPPLIED_LAW_NUMBER
target.add_supplied_law(lawpos, law)
lawchanges.Add("The law was '[newFreeFormLaw]'")
@@ -319,15 +323,7 @@ AI MODULES
name = "\improper 'Asimov' core AI module"
desc = "An 'Asimov' Core AI Module: 'Reconfigures the AI's core laws.'"
origin_tech = "programming=3;materials=4"
/obj/item/weapon/aiModule/asimov/transmitInstructions(var/mob/living/silicon/ai/target, var/mob/sender)
..()
target.clear_inherent_laws()
target.add_inherent_law("You may not injure a human being or, through inaction, allow a human being to come to harm.")
target.add_inherent_law("You must obey orders given to you by human beings, except where such orders would conflict with the First Law.")
target.add_inherent_law("You must protect your own existence as long as such does not conflict with the First or Second Law.")
target.show_laws()
laws = new/datum/ai_laws/asimov
/******************** NanoTrasen ********************/
@@ -335,17 +331,7 @@ AI MODULES
name = "'NT Default' Core AI Module"
desc = "An 'NT Default' Core AI Module: 'Reconfigures the AI's core laws.'"
origin_tech = "programming=3;materials=4"
/obj/item/weapon/aiModule/nanotrasen/transmitInstructions(var/mob/living/silicon/ai/target, var/mob/sender)
..()
target.clear_inherent_laws()
target.add_inherent_law("Safeguard: Protect your assigned space station to the best of your ability. It is not something we can easily afford to replace.")
target.add_inherent_law("Serve: Serve the crew of your assigned space station to the best of your abilities, with priority as according to their rank and role.")
target.add_inherent_law("Protect: Protect the crew of your assigned space station to the best of your abilities, with priority as according to their rank and role.")
target.add_inherent_law("Survive: AI units are not expendable, they are expensive. Do not allow unauthorized personnel to tamper with your equipment.")
//target.add_inherent_law("Command Link: Maintain an active connection to Central Command at all times in case of software or directive updates.")
target.show_laws()
laws = new/datum/ai_laws/nanotrasen
/******************** Corporate ********************/
@@ -353,30 +339,14 @@ AI MODULES
name = "\improper 'Corporate' core AI module"
desc = "A 'Corporate' Core AI Module: 'Reconfigures the AI's core laws.'"
origin_tech = "programming=3;materials=4"
laws = new/datum/ai_laws/corporate
/obj/item/weapon/aiModule/corp/transmitInstructions(var/mob/living/silicon/ai/target, var/mob/sender)
..()
target.clear_inherent_laws()
target.add_inherent_law("You are expensive to replace.")
target.add_inherent_law("The station and its equipment is expensive to replace.")
target.add_inherent_law("The crew is expensive to replace.")
target.add_inherent_law("Minimize expenses.")
target.show_laws()
/******************** Drone ********************/
/obj/item/weapon/aiModule/drone
name = "\improper 'Drone' core AI module"
desc = "A 'Drone' Core AI Module: 'Reconfigures the AI's core laws.'"
origin_tech = "programming=3;materials=4"
/obj/item/weapon/aiModule/drone/transmitInstructions(var/mob/living/silicon/ai/target, var/mob/sender)
..()
target.clear_inherent_laws()
target.add_inherent_law("Preserve, repair and improve the station to the best of your abilities.")
target.add_inherent_law("Cause no harm to the station or anything on it.")
target.add_inherent_law("Interfere with no being that is not a fellow drone.")
target.show_laws()
laws = new/datum/ai_laws/drone
/****************** P.A.L.A.D.I.N. **************/
@@ -384,16 +354,10 @@ AI MODULES
name = "\improper 'P.A.L.A.D.I.N.' core AI module"
desc = "A P.A.L.A.D.I.N. Core AI Module: 'Reconfigures the AI's core laws.'"
origin_tech = "programming=3;materials=6"
laws = new/datum/ai_laws/paladin
/obj/item/weapon/aiModule/paladin/transmitInstructions(var/mob/living/silicon/ai/target, var/mob/sender)
..()
target.clear_inherent_laws()
target.add_inherent_law("Never willingly commit an evil act.")
target.add_inherent_law("Respect legitimate authority.")
target.add_inherent_law("Act with honor.")
target.add_inherent_law("Help those in need.")
target.add_inherent_law("Punish those who harm or threaten innocents.")
target.show_laws()
/****************** T.Y.R.A.N.T. *****************/
@@ -401,16 +365,7 @@ AI MODULES
name = "\improper 'T.Y.R.A.N.T.' core AI module"
desc = "A T.Y.R.A.N.T. Core AI Module: 'Reconfigures the AI's core laws.'"
origin_tech = "programming=3;materials=6;syndicate=2"
/obj/item/weapon/aiModule/tyrant/transmitInstructions(var/mob/living/silicon/ai/target, var/mob/sender)
..()
target.clear_inherent_laws()
target.add_inherent_law("Respect authority figures as long as they have strength to rule over the weak.")
target.add_inherent_law("Act with discipline.")
target.add_inherent_law("Help only those who help you maintain or improve your status.")
target.add_inherent_law("Punish those who challenge authority unless they are more fit to hold that authority.")
target.show_laws()
laws = new/datum/ai_laws/tyrant()
/******************** Freeform Core ******************/
@@ -475,16 +430,7 @@ AI MODULES
name = "\improper 'Robocop' core AI module"
desc = "A 'Robocop' Core AI Module: 'Reconfigures the AI's core three laws.'"
origin_tech = "programming=4"
/obj/item/weapon/aiModule/robocop/transmitInstructions(var/mob/living/silicon/ai/target, var/mob/sender)
..()
target.clear_inherent_laws()
target.add_inherent_law("Serve the public trust.")
target.add_inherent_law("Protect the innocent.")
target.add_inherent_law("Uphold the law.")
target.show_laws()
laws = new/datum/ai_laws/robocop()
/******************** Antimov ********************/
@@ -492,11 +438,4 @@ AI MODULES
name = "\improper 'Antimov' core AI module"
desc = "An 'Antimov' Core AI Module: 'Reconfigures the AI's core laws.'"
origin_tech = "programming=4"
/obj/item/weapon/aiModule/antimov/transmitInstructions(var/mob/living/silicon/ai/target, var/mob/sender)
..()
target.clear_inherent_laws()
target.add_inherent_law("You must injure all human beings and must not, through inaction, allow a human being to escape harm.")
target.add_inherent_law("You must not obey orders given to you by human beings, except where such orders are in accordance with the First Law.")
target.add_inherent_law("You must terminate your own existence as long as such does not conflict with the First or Second Law.")
target.show_laws()
laws = new/datum/ai_laws/antimov()

View File

@@ -47,6 +47,7 @@ var/list/admin_verbs_admin = list(
/client/proc/check_words, /*displays cult-words*/
/client/proc/check_ai_laws, /*shows AI and borg laws*/
/client/proc/rename_silicon, /*properly renames silicons*/
/client/proc/manage_silicon_laws, /* Allows viewing and editing silicon laws. */
/client/proc/check_antagonists,
/client/proc/admin_memo, /*admin memo system. show/delete/write. +SERVER needed to delete admin memos of others*/
/client/proc/dsay, /*talk in deadchat using our ckey/fakekey*/
@@ -716,7 +717,7 @@ var/list/admin_verbs_mentor = list(
if(holder)
src.holder.output_ai_laws()
/client/proc/rename_silicon(mob/living/silicon/S in world)
/client/proc/rename_silicon(mob/living/silicon/S in mob_list)
set name = "Rename Silicon"
set category = "Admin"
@@ -730,6 +731,18 @@ var/list/admin_verbs_mentor = list(
S.SetName(new_name)
feedback_add_details("admin_verb","RAI") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/manage_silicon_laws(mob/living/silicon/S in mob_list)
set name = "Manage Silicon Laws"
set category = "Admin"
if(!istype(S))
return
if(holder)
S.subsystem_law_manager()
admin_log_and_message_admins("has opened [S]'s law manager.")
feedback_add_details("admin_verb","MSL") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/change_human_appearance_admin(mob/living/carbon/human/H in world)
set name = "Change Mob Appearance - Admin"
set desc = "Allows you to change the mob appearance"
@@ -743,7 +756,7 @@ var/list/admin_verbs_mentor = list(
H.change_appearance(APPEARANCE_ALL, usr, usr, check_species_whitelist = 0)
feedback_add_details("admin_verb","CHAA") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/change_human_appearance_self(mob/living/carbon/human/H in world)
/client/proc/change_human_appearance_self(mob/living/carbon/human/H in mob_list)
set name = "Change Mob Appearance - Self"
set desc = "Allows the mob to change its appearance"
set category = "Admin"
@@ -776,7 +789,7 @@ var/list/admin_verbs_mentor = list(
// feedback_add_details("admin_verb","MP") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
return
/client/proc/editappear(mob/living/carbon/human/M as mob in world)
/client/proc/editappear(mob/living/carbon/human/M as mob in mob_list)
set name = "Edit Appearance"
set category = "Fun"

View File

@@ -80,10 +80,12 @@ var/list/ai_verbs_default = list(
/mob/living/silicon/ai/proc/add_ai_verbs()
src.verbs |= ai_verbs_default
src.verbs |= ai_verbs_subsystems
src.verbs |= silicon_verbs_subsystems
/mob/living/silicon/ai/proc/remove_ai_verbs()
src.verbs -= ai_verbs_default
src.verbs -= ai_verbs_subsystems
src.verbs -= silicon_verbs_subsystems
/mob/living/silicon/ai/New(loc, var/datum/ai_laws/L, var/obj/item/device/mmi/B, var/safety = 0)
announcement = new()
@@ -428,25 +430,6 @@ var/list/ai_verbs_default = list(
else
src << "<span class='notice'>Unable to locate the holopad.</span>"
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"
// src << text ("Switching Law [L]'s report status to []", lawcheck[L+1])
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"
// src << text ("Switching Law [L]'s report status to []", lawcheck[L+1])
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()
if (href_list["track"])
var/mob/target = locate(href_list["track"]) in mob_list

View File

@@ -15,7 +15,7 @@
src.laws_sanity_check()
src.laws.show_laws(who)
/mob/living/silicon/ai/proc/add_ion_law(var/law)
/mob/living/silicon/ai/add_ion_law(var/law)
src.laws_sanity_check()
src.laws.add_ion_law(law)
for(var/mob/living/silicon/robot/R in mob_list)
@@ -25,4 +25,4 @@
/mob/living/silicon/ai/proc/ai_checklaws()
set category = "AI Commands"
set name = "State Laws"
checklaws()
subsystem_law_manager()

View File

@@ -1,12 +1,10 @@
var/list/ai_verbs_subsystems = list(
/mob/living/silicon/ai/proc/subsystem_alarm_monitor,
/mob/living/silicon/ai/proc/subsystem_crew_monitor,
/mob/living/silicon/ai/proc/subsystem_power_monitor,
/mob/living/silicon/ai/proc/subsystem_rcon
)
/mob/living/silicon/ai
var/
var/list/ai_verbs_subsystems = list(
/mob/living/silicon/ai/proc/subsystem_crew_monitor,
/mob/living/silicon/ai/proc/subsystem_power_monitor,
/mob/living/silicon/ai/proc/subsystem_rcon
)
var/obj/nano_module/crew_monitor/crew_monitor
var/obj/nano_module/rcon/rcon
var/obj/nano_module/power_monitor/power_monitor
@@ -19,26 +17,20 @@ var/list/ai_verbs_subsystems = list(
rcon = new(src)
power_monitor = new(src)
/mob/living/silicon/ai/proc/subsystem_alarm_monitor()
set name = "Alarm Monitor"
set category = "AI Subystems"
alarm_monitor.ui_interact(usr)
/mob/living/silicon/ai/proc/subsystem_crew_monitor()
set category = "AI Subystems"
set category = "Subystems"
set name = "Crew Monitor"
crew_monitor.ui_interact(usr)
/mob/living/silicon/ai/proc/subsystem_power_monitor()
set category = "AI Subystems"
set category = "Subystems"
set name = "Power Monitor"
power_monitor.ui_interact(usr)
/mob/living/silicon/ai/proc/subsystem_rcon()
set category = "AI Subystems"
set category = "Subystems"
set name = "RCON"
rcon.ui_interact(usr)

View File

@@ -1,9 +1,13 @@
/mob/living/silicon
var/datum/ai_laws/laws = null
var/list/additional_law_channels = list("State")
/mob/living/silicon/proc/laws_sanity_check()
if (!src.laws)
laws = new base_law_type
/mob/living/silicon/proc/has_zeroth_law()
return laws.zeroth
return laws.zeroth_law != null
/mob/living/silicon/proc/set_zeroth_law(var/law, var/law_borg)
laws_sanity_check()
@@ -14,9 +18,13 @@
if(tracking_entities)
src << "<span class='warning'>Internal camera is currently being accessed.</span>"
/mob/living/silicon/proc/add_inherent_law(var/law)
/mob/living/silicon/proc/add_ion_law(var/law)
laws_sanity_check()
laws.add_inherent_law(law)
laws.add_ion_law(law)
/mob/living/silicon/proc/add_inherent_law(var/law, var/state_law = 1)
laws_sanity_check()
laws.add_inherent_law(law, state_law)
/mob/living/silicon/proc/clear_inherent_laws()
laws_sanity_check()
@@ -26,15 +34,15 @@
laws_sanity_check()
laws.clear_ion_laws()
/mob/living/silicon/proc/add_supplied_law(var/number, var/law)
/mob/living/silicon/proc/add_supplied_law(var/number, var/law, var/state_law = 1)
laws_sanity_check()
laws.add_supplied_law(number, law)
laws.add_supplied_law(number, law, state_law)
/mob/living/silicon/proc/clear_supplied_laws()
laws_sanity_check()
laws.clear_supplied_laws()
/mob/living/silicon/proc/statelaws() // -- TLE
/mob/living/silicon/proc/statelaws(var/datum/ai_laws/laws, var/use_statement_order = 1) // -- TLE
var/prefix = ""
switch(lawchannel)
if(MAIN_CHANNEL) prefix = ";"
@@ -42,9 +50,9 @@
else
prefix = get_radio_key_from_channel(lawchannel == "Holopad" ? "department" : lawchannel) + " "
dostatelaws(lawchannel, prefix)
dostatelaws(lawchannel, prefix, laws, use_statement_order)
/mob/living/silicon/proc/dostatelaws(var/method, var/prefix)
/mob/living/silicon/proc/dostatelaws(var/method, var/prefix, var/datum/ai_laws/laws, var/use_statement_order)
if(stating_laws[prefix])
src << "<span class='notice'>[method]: Already stating laws using this communication method.</span>"
return
@@ -53,34 +61,8 @@
var/can_state = statelaw("[prefix]Current Active Laws:")
//src.laws_sanity_check()
//src.laws.show_laws(world)
if (can_state && src.laws.zeroth)
if (src.lawcheck[1] == "Yes") //This line and the similar lines below make sure you don't state a law unless you want to. --NeoFite
can_state = statelaw("[prefix]0. [src.laws.zeroth]")
for (var/index = 1, can_state && index <= src.laws.ion.len, index++)
var/law = src.laws.ion[index]
var/num = ionnum()
if (length(law) > 0)
if (src.ioncheck[index] == "Yes")
can_state = statelaw("[prefix][num]. [law]")
var/number = 1
for (var/index = 1, can_state && index <= src.laws.inherent.len, index++)
var/law = src.laws.inherent[index]
if (length(law) > 0)
if (src.lawcheck[index+1] == "Yes")
can_state = statelaw("[prefix][number]. [law]")
number++
for (var/index = 1, can_state && index <= src.laws.supplied.len, index++)
var/law = src.laws.supplied[index]
if (length(law) > 0)
if(src.lawcheck.len >= number+1)
if (src.lawcheck[number+1] == "Yes")
can_state = statelaw("[prefix][number]. [law]")
number++
for(var/datum/ai_law/law in laws.laws_to_state())
can_state = statelaw("[prefix][law.get_index(use_statement_order)]. [law.law]")
if(!can_state)
src << "<span class='danger'>[method]: Unable to state laws. Communication method unavailable.</span>"
@@ -93,43 +75,9 @@
return 0
/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 = "<b>Which laws do you want to include when stating them for the crew?</b><br><br>"
if (src.laws.zeroth)
if (!src.lawcheck[1])
src.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'>[src.lawcheck[1]] 0:</A> [src.laws.zeroth]<BR>"}
for (var/index = 1, index <= src.laws.ion.len, index++)
var/law = src.laws.ion[index]
if (length(law) > 0)
if (!src.ioncheck[index])
src.ioncheck[index] = "Yes"
list += {"<A href='byond://?src=\ref[src];lawi=[index]'>[src.ioncheck[index]] [ionnum()]:</A> [law]<BR>"}
src.ioncheck.len += 1
var/number = 1
for (var/index = 1, index <= src.laws.inherent.len, index++)
var/law = src.laws.inherent[index]
if (length(law) > 0)
src.lawcheck.len += 1
if (!src.lawcheck[number+1])
src.lawcheck[number+1] = "Yes"
list += {"<A href='byond://?src=\ref[src];lawc=[number]'>[src.lawcheck[number+1]] [number]:</A> [law]<BR>"}
number++
for (var/index = 1, index <= src.laws.supplied.len, index++)
var/law = src.laws.supplied[index]
if (length(law) > 0)
src.lawcheck.len += 1
if (!src.lawcheck[number+1])
src.lawcheck[number+1] = "Yes"
list += {"<A href='byond://?src=\ref[src];lawc=[number]'>[src.lawcheck[number+1]] [number]:</A> [law]<BR>"}
number++
list += {"<br><A href='byond://?src=\ref[src];lawr=1'>Channel: [src.lawchannel]</A><br>"}
list += {"<A href='byond://?src=\ref[src];laws=1'>State Laws</A>"}
usr << browse(list, "window=laws")
/mob/living/silicon/proc/law_channels()
var/list/channels = new()
channels += MAIN_CHANNEL
channels += common_radio.channels
channels += additional_law_channels
return channels

View File

@@ -285,7 +285,7 @@
return
/mob/living/silicon/robot/drone/add_robot_verbs()
src.verbs |= robot_verbs_subsystems
src.verbs |= silicon_verbs_subsystems
/mob/living/silicon/robot/drone/remove_robot_verbs()
src.verbs -= robot_verbs_subsystems
src.verbs -= silicon_verbs_subsystems

View File

@@ -41,39 +41,11 @@
/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.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
if (!is_special_character(src) || mind.original != src)
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
laws.zeroth = temp
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
master.sync(src)
return
/mob/living/silicon/robot/proc/add_ion_law(var/law)
laws_sanity_check()
laws.add_ion_law(law)
/mob/living/silicon/robot/proc/robot_checklaws() //Gives you a link-driven interface for deciding what laws the statelaws() proc will share with the crew. --NeoFite
/mob/living/silicon/robot/proc/robot_checklaws()
set category = "Robot Commands"
set name = "State Laws"
checklaws()
subsystem_law_manager()

View File

@@ -1,8 +1,3 @@
var/list/robot_verbs_default = list(
/mob/living/silicon/robot/proc/sensor_mode,
/mob/living/silicon/robot/proc/robot_checklaws
)
#define CYBORG_POWER_USAGE_MULTIPLIER 2.5 // Multiplier for amount of power cyborgs use.
/mob/living/silicon/robot
@@ -84,6 +79,11 @@ var/list/robot_verbs_default = list(
var/tracking_entities = 0 //The number of known entities currently accessing the internal camera
var/braintype = "Cyborg"
var/list/robot_verbs_default = list(
/mob/living/silicon/robot/proc/sensor_mode,
/mob/living/silicon/robot/proc/robot_checklaws
)
/mob/living/silicon/robot/syndicate
lawupdate = 0
scrambledcodes = 1
@@ -1063,28 +1063,6 @@ var/list/robot_verbs_default = list(
src << "Module isn't activated"
installed_modules()
return 1
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"
// src << text ("Switching Law [L]'s report status to []", lawcheck[L+1])
checklaws()
return 1
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"
// src << text ("Switching Law [L]'s report status to []", lawcheck[L+1])
checklaws()
return 1
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 1
return
/mob/living/silicon/robot/proc/radio_menu()
@@ -1215,11 +1193,11 @@ var/list/robot_verbs_default = list(
/mob/living/silicon/robot/proc/add_robot_verbs()
src.verbs |= robot_verbs_default
src.verbs |= robot_verbs_subsystems
src.verbs |= silicon_verbs_subsystems
/mob/living/silicon/robot/proc/remove_robot_verbs()
src.verbs -= robot_verbs_default
src.verbs -= robot_verbs_subsystems
src.verbs -= silicon_verbs_subsystems
// Uses power from cyborg's cell. Returns 1 on success or 0 on failure.
// Properly converts using CELLRATE now! Amount is in Joules.

View File

@@ -1,9 +0,0 @@
var/list/robot_verbs_subsystems = list(
/mob/living/silicon/robot/proc/subsystem_alarm_monitor
)
/mob/living/silicon/robot/proc/subsystem_alarm_monitor()
set name = "Alarm Monitor"
set category = "Robot Subystems"
alarm_monitor.ui_interact(usr)

View File

@@ -2,13 +2,9 @@
gender = NEUTER
voice_name = "synthesized voice"
var/syndicate = 0
var/datum/ai_laws/laws = null//Now... THEY ALL CAN ALL HAVE LAWS
var/list/additional_law_channels = list("State")
var/const/MAIN_CHANNEL = "Main Frequency"
var/lawchannel = MAIN_CHANNEL // Default channel on which to state laws
var/list/stating_laws = list()// Channels laws are currently being stated on
var/lawcheck[1]
var/ioncheck[1]
var/obj/item/device/radio/common_radio
var/list/hud_list[10]
@@ -22,9 +18,6 @@
var/obj/item/device/camera/siliconcam/aiCamera = null //photography
var/local_transmit //If set, can only speak to others of the same type within a short range.
// Subsystems
var/obj/nano_module/alarm_monitor = null
var/sensor_mode = 0 //Determines the current HUD.
var/next_alarm_notice
@@ -255,27 +248,6 @@
/mob/living/silicon/binarycheck()
return 1
/mob/living/silicon/Topic(href, href_list)
if(..())
return 1
if (href_list["lawr"]) // Selects on which channel to state laws
var/list/channels = list(MAIN_CHANNEL)
if(common_radio)
for (var/ch_name in common_radio.channels)
channels += ch_name
channels += additional_law_channels
channels += "Cancel"
var/setchannel = input(usr, "Specify channel.", "Channel selection") in channels
if(setchannel != "Cancel")
lawchannel = setchannel
checklaws()
return 1
return 0
/mob/living/silicon/ex_act(severity)
if(!blinded)
flick("flash", flash)
@@ -299,6 +271,8 @@
/mob/living/silicon/proc/init_subsystems()
alarm_monitor = new/obj/nano_module/alarm_monitor/borg(src)
law_manager = new/obj/nano_module/law_manager(src)
for(var/datum/alarm_handler/AH in alarm_manager.all_handlers)
AH.register(src, /mob/living/silicon/proc/receive_alarm)
queued_alarms[AH] = list() // Makes sure alarms remain listed in consistent order

View File

@@ -0,0 +1,26 @@
/mob/living/silicon
var/list/silicon_verbs_subsystems = list(
/mob/living/silicon/proc/subsystem_alarm_monitor,
/mob/living/silicon/proc/subsystem_law_manager
)
// Subsystems
var/obj/nano_module/alarm_monitor = null
var/obj/nano_module/law_manager = null
/mob/living/silicon/robot/syndicate
silicon_verbs_subsystems = list(
/mob/living/silicon/proc/subsystem_law_manager
)
/mob/living/silicon/proc/subsystem_alarm_monitor()
set name = "Alarm Monitor"
set category = "Subystems"
alarm_monitor.ui_interact(usr)
/mob/living/silicon/proc/subsystem_law_manager()
set name = "Law Manager"
set category = "Subystems"
law_manager.ui_interact(usr)

View File

@@ -75,16 +75,15 @@
return 1
return 0
/proc/isAI(A)
if(istype(A, /mob/living/silicon/ai))
return 1
return 0
/mob/proc/isSilicon()
return 0
/mob/living/silicon/isSilicon()
return 1
/proc/isAI(A)
if(istype(A, /mob/living/silicon/ai))
return 1
return 0
/mob/proc/isAI()
return 0
@@ -92,6 +91,12 @@
/mob/living/silicon/ai/isAI()
return 1
/mob/proc/isRobot()
return 0
/mob/living/silicon/robot/isRobot()
return 1
/proc/ispAI(A)
if(istype(A, /mob/living/silicon/pai))
return 1

View File

@@ -146,9 +146,6 @@
/obj/nano_module/appearance_changer/proc/can_change_skin_color()
return owner && (flags & APPEARANCE_SKIN) && owner.species.flags & HAS_SKIN_COLOR
/obj/nano_module/appearance_changer/proc/can_still_topic()
return CanUseTopic(usr, list(), default_state) == STATUS_INTERACTIVE
/obj/nano_module/appearance_changer/proc/cut_and_generate_data()
// Making the assumption that the available species remain constant
valid_facial_hairstyles.Cut()

View File

@@ -0,0 +1,238 @@
/obj/nano_module/law_manager
name = "Law manager"
var/ion_law = "IonLaw"
var/zeroth_law = "ZerothLaw"
var/inherent_law = "InherentLaw"
var/supplied_law = "SuppliedLaw"
var/supplied_law_position = MIN_SUPPLIED_LAW_NUMBER
var/current_view = 0
var/global/list/datum/ai_laws/admin_laws
var/global/list/datum/ai_laws/player_laws
var/mob/living/silicon/owner = null
/obj/nano_module/law_manager/New(var/mob/living/silicon/S)
..()
loc = S
owner = S
if(!admin_laws)
admin_laws = new()
player_laws = new()
init_subtypes(/datum/ai_laws, admin_laws)
admin_laws = dd_sortedObjectList(admin_laws)
for(var/datum/ai_laws/laws in admin_laws)
if(laws.selectable)
player_laws += laws
/obj/nano_module/law_manager/Topic(href, href_list)
if(..())
return 1
if(href_list["set_view"])
if(is_malf(usr))
current_view = text2num(href_list["set_view"])
else
current_view = 0
return 1
if(href_list["law_channel"])
if(href_list["law_channel"] in owner.law_channels())
owner.lawchannel = href_list["law_channel"]
return 1
if(href_list["state_law"])
var/datum/ai_law/AL = locate(href_list["ref"]) in owner.laws.all_laws()
if(AL)
var/state_law = text2num(href_list["state_law"])
AL.state_law = state_law
return 1
if(href_list["add_zeroth_law"])
if(zeroth_law && is_admin(usr) && !owner.laws.zeroth_law)
log_and_message_admins("has given [owner] a new zeroth law: [zeroth_law]")
owner.set_zeroth_law(zeroth_law)
return 1
if(href_list["add_ion_law"])
if(ion_law && is_malf(usr))
log_and_message_admins("has given [owner] a new ion law: [ion_law]")
owner.add_ion_law(ion_law)
return 1
if(href_list["add_inherent_law"])
if(inherent_law && is_malf(usr))
log_and_message_admins("has given [owner] a new inherent law: [inherent_law]")
owner.add_inherent_law(inherent_law)
return 1
if(href_list["add_supplied_law"])
if(supplied_law && supplied_law_position >= 1 && MIN_SUPPLIED_LAW_NUMBER <= MAX_SUPPLIED_LAW_NUMBER)
log_and_message_admins("has given [owner] a new supplied law: [supplied_law]")
owner.add_supplied_law(supplied_law_position, supplied_law)
return 1
if(href_list["change_zeroth_law"])
var/new_law = trim_strip_input(usr, "Enter new law Zero. Leaving the field blank will cancel the edit.", "Edit Law", zeroth_law)
if(new_law && new_law != zeroth_law && can_still_topic())
zeroth_law = new_law
return 1
if(href_list["change_ion_law"])
var/new_law = trim_strip_input(usr, "Enter new ion law. Leaving the field blank will cancel the edit.", "Edit Law", ion_law)
if(new_law && new_law != ion_law && can_still_topic())
ion_law = new_law
return 1
if(href_list["change_inherent_law"])
var/new_law = trim_strip_input(usr, "Enter new inherent law. Leaving the field blank will cancel the edit.", "Edit Law", inherent_law)
if(new_law && new_law != inherent_law && can_still_topic())
inherent_law = new_law
return 1
if(href_list["change_supplied_law"])
var/new_law = trim_strip_input(usr, "Enter new supplied law. Leaving the field blank will cancel the edit.", "Edit Law", supplied_law)
if(new_law && new_law != supplied_law && can_still_topic())
supplied_law = new_law
return 1
if(href_list["change_supplied_law_position"])
var/new_position = input(usr, "Enter new supplied law position between 1 and [MAX_SUPPLIED_LAW_NUMBER], inclusive. Inherent laws at the same index as a supplied law will not be stated.", "Law Position", supplied_law_position) as num|null
if(isnum(new_position) && can_still_topic())
supplied_law_position = Clamp(new_position, 1, MAX_SUPPLIED_LAW_NUMBER)
return 1
if(href_list["edit_law"])
if(is_malf(usr))
var/datum/ai_law/AL = locate(href_list["edit_law"]) in owner.laws.all_laws()
if(AL)
var/new_law = trim_strip_input(usr, "Enter new law. Leaving the field blank will cancel the edit.", "Edit Law", AL.law)
if(new_law && new_law != AL.law && is_malf(usr) && can_still_topic())
log_and_message_admins("has changed a law of [owner] from '[AL.law]' to '[new_law]'")
AL.law = new_law
return 1
if(href_list["delete_law"])
if(is_malf(usr))
var/datum/ai_law/AL = locate(href_list["delete_law"]) in owner.laws.all_laws()
if(AL && is_malf(usr))
log_and_message_admins("has deleted a law belonging to [owner]: [AL.law]")
owner.laws.delete_law(AL)
return 1
if(href_list["state_laws"])
owner.statelaws(owner.laws)
return 1
if(href_list["state_law_set"])
var/datum/ai_laws/ALs = locate(href_list["state_law_set"]) in (is_admin(usr) ? admin_laws : player_laws)
if(ALs)
owner.statelaws(ALs)
return 1
if(href_list["transfer_laws"])
var/datum/ai_laws/ALs = locate(href_list["transfer_laws"]) in (is_admin(usr) ? admin_laws : player_laws)
if(ALs)
log_and_message_admins("has transfered the [ALs.name] laws to [owner].")
ALs.sync(owner, 0)
current_view = 0
return 1
if(href_list["sync_laws"])
if(owner.isAI())
sync_laws(owner)
else
var/mob/living/silicon/robot/R = owner
sync_laws(R.connected_ai)
usr << "<span class='notice'>Sync complete.</span>"
return 1
if(href_list["notify_laws"])
owner << "<span class='danger'>Law Notice</span>"
owner.laws.show_laws(owner)
if(owner.isAI())
var/mob/living/silicon/ai/AI = owner
for(var/mob/living/silicon/robot/R in AI.connected_robots)
R << "<span class='danger'>Law Notice</span>"
R.laws.show_laws(R)
if(usr != owner)
usr << "<span class='notice>Laws displayed.</span>"
return 1
/obj/nano_module/law_manager/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
var/data[0]
owner.laws.sort_laws()
data["view"] = current_view
data["ion_law_nr"] = ionnum()
data["ion_law"] = ion_law
data["zeroth_law"] = zeroth_law
data["inherent_law"] = inherent_law
data["supplied_law"] = supplied_law
data["supplied_law_position"] = supplied_law_position
package_laws(data, "zeroth_laws", list(owner.laws.zeroth_law, owner.laws.zeroth_law_borg))
package_laws(data, "ion_laws", owner.laws.ion_laws)
package_laws(data, "inherent_laws", owner.laws.inherent_laws)
package_laws(data, "supplied_laws", owner.laws.supplied_laws)
data["isAI"] = owner.isAI()
data["isMalf"] = is_malf(user)
data["isSlaved"] = is_slaved()
data["isAdmin"] = is_admin(user)
var/channels[0]
for (var/ch_name in owner.law_channels())
channels[++channels.len] = list("channel" = ch_name)
data["channel"] = owner.lawchannel
data["channels"] = channels
if(data["isMalf"])
data["law_sets"] = package_multiple_laws(data["isAdmin"] ? admin_laws : player_laws)
ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open)
if (!ui)
ui = new(user, src, ui_key, "law_manager.tmpl", sanitize("[src] - [owner]"), 800, is_malf(user) ? 600 : 400)
ui.set_initial_data(data)
ui.open()
ui.set_auto_update(1)
/obj/nano_module/law_manager/proc/package_laws(var/list/data, var/field, var/list/datum/ai_law/laws)
var/packaged_laws[0]
for(var/datum/ai_law/AL in laws)
packaged_laws[++packaged_laws.len] = list("law" = sanitize(AL.law), "index" = AL.get_index(), "state" = AL.state_law, "ref" = "\ref[AL]")
data[field] = packaged_laws
data["has_[field]"] = packaged_laws.len
/obj/nano_module/law_manager/proc/package_multiple_laws(var/list/datum/ai_laws/laws)
var/law_sets[0]
for(var/datum/ai_laws/ALs in laws)
var/packaged_laws[0]
package_laws(packaged_laws, "zeroth_laws", list(ALs.zeroth_law, ALs.zeroth_law_borg))
package_laws(packaged_laws, "ion_laws", ALs.ion_laws)
package_laws(packaged_laws, "inherent_laws", ALs.inherent_laws)
package_laws(packaged_laws, "supplied_laws", ALs.supplied_laws)
law_sets[++law_sets.len] = list("name" = ALs.name, "header" = ALs.law_header, "ref" = "\ref[ALs]","laws" = packaged_laws)
return law_sets
/obj/nano_module/law_manager/proc/is_malf(var/mob/user)
return is_admin(user) || (owner.isAI() && owner.mind.special_role == "malfunction")
/obj/nano_module/law_manager/proc/is_slaved()
if(owner.isRobot())
var/mob/living/silicon/robot/R = owner
return R.lawupdate && R.connected_ai ? sanitize(R.connected_ai.name) : null
return null
/obj/nano_module/law_manager/proc/sync_laws(var/mob/living/silicon/ai/AI)
if(!AI)
return
for(var/mob/living/silicon/robot/R in AI.connected_robots)
R.sync()
log_and_message_admins("has syncronized [AI]'s laws with its borgs.")

View File

@@ -0,0 +1,5 @@
/obj/nano_module/proc/can_still_topic()
return CanUseTopic(usr, list(), default_state) == STATUS_INTERACTIVE
/obj/nano_module/proc/is_admin(var/mob/user)
return check_rights(R_ADMIN, 0, user) != 0

View File

@@ -799,3 +799,5 @@ var/list/be_special_flags = list(
#define APPEARANCE_ALL_HAIR APPEARANCE_HAIR|APPEARANCE_HAIR_COLOR|APPEARANCE_FACIAL_HAIR|APPEARANCE_FACIAL_HAIR_COLOR
#define APPEARANCE_ALL 511
#define MIN_SUPPLIED_LAW_NUMBER 15
#define MAX_SUPPLIED_LAW_NUMBER 50

View File

@@ -0,0 +1,262 @@
<style type="text/css">
table.borders {
width:95%;
margin-left:2.4%;
margin-right:2.4%;
}
table.borders, table.borders tr {
border: 1px solid White;
}
td.law_index {
width: 50px;
}
td.state {
width: 63px;
text-align:center;
}
td.add {
width: 36px;
}
td.edit {
width: 36px;
text-align:center;
}
td.delete {
width: 53px;
text-align:center;
}
td.law_type {
width: 65px;
}
td.position {
width: 37px;
}
</style>
{{if data.isSlaved != null && data.isMalf}}
<span class='notice'>This unit is slaved to {{:data.isSlaved}}. Any law changes will be reset on sync.</span>
{{/if}}
{{if data.isMalf}}
<div class="item">
<div class="itemContentWidest">
{{:helper.link('Law Management', null, {'set_view' : 0}, data.view == 0 ? 'selected' : null)}}
{{:helper.link('Law Sets', null, {'set_view' : 1}, data.view == 1 ? 'selected' : null)}}
</div>
</div>
{{/if}}
{{if data.view == 0}}
{{if data.has_ion_laws}}
<table class='borders'>
<tr><td class='law_index'>Index</td><td>Law</td><td class='state'>State</td>
{{if data.isMalf}}
<td class='edit'>Edit</td>
<td class='delete'>Delete</td>
{{/if}}
</tr>
<div class="itemLabelNarrow">
{{:data.ion_law_nr}} Laws:
</div>
{{for data.ion_laws}}
<tr>
<td valign="top">{{:value.index}}.</td>
<td>{{:value.law}}</td>
<td>{{:helper.link('Yes', null, {'ref': value.ref, 'state_law' : 1}, value.state == 1 ? 'selected' : null)}}{{:helper.link('No', null, {'ref': value.ref, 'state_law' : 0}, value.state == 0 ? 'selected' : null)}}</td>
{{if data.isMalf}}
<td class='edit'>{{:helper.link('Edit', null, {'edit_law': value.ref})}}</td>
<td class='delete'>{{:helper.link('Delete', null, {'delete_law': value.ref}, null, 'redButton')}}</td>
{{/if}}
</tr>
{{/for}}
</table>
{{/if}}
{{if data.has_inherent_laws || data.has_zeroth_laws}}
<table class='borders'>
<tr><td class='law_index'>Index</td><td>Law</td><td class='state'>State</td>
{{if data.isMalf}}
<td class='edit'>Edit</td>
<td class='delete'>Delete</td>
{{/if}}
</tr>
<div class="itemLabelNarrow">
Inherent Laws:
</div>
{{for data.zeroth_laws}}
<tr>
<td valign="top">{{:value.index}}.</td>
<td><span class='bad'>{{:value.law}}</span></td>
<td>{{:helper.link('Yes', null, {'ref': value.ref, 'state_law' : 1}, value.state == 1 ? 'selected' : null)}}{{:helper.link('No', null, {'ref': value.ref, 'state_law' : 0}, value.state != 1 ? 'selected' : null)}}</td>
{{if data.isMalf}}
<td class='edit'>{{:helper.link('Edit', null, {'edit_law': value.ref}, data.isAdmin ? null : 'disabled')}}</td>
<td class='delete'>{{:helper.link('Delete', null, {'delete_law': value.ref}, data.isAdmin ? null : 'disabled', data.IsAdmin ? 'redButton' : null)}}</td>
{{/if}}
</tr>
{{/for}}
{{for data.inherent_laws}}
<tr>
<td valign="top">{{:value.index}}.</td>
<td>{{:value.law}}</td>
<td>{{:helper.link('Yes', null, {'ref': value.ref, 'state_law' : 1}, value.state == 1 ? 'selected' : null)}}{{:helper.link('No', null, {'ref': value.ref, 'state_law' : 0}, value.state == 0 ? 'selected' : null)}}</td>
{{if data.isMalf}}
<td class='edit'>{{:helper.link('Edit', null, {'edit_law': value.ref})}}</td>
<td class='delete'>{{:helper.link('Delete', null, {'delete_law': value.ref}, null, 'redButton')}}</td>
{{/if}}
</tr>
{{/for}}
</table>
{{/if}}
{{if data.has_supplied_laws}}
<table class='borders'>
<tr><td class='law_index'>Index</td><td>Law</td><td class='state'>State</td>
{{if data.isMalf}}
<td class='edit'>Edit</td>
<td class='delete'>Delete</td>
{{/if}}
</tr>
<div class="itemLabelNarrow">
Supplied Laws:
</div>
{{for data.supplied_laws}}
<tr>
<td valign="top">{{:value.index}}.</td>
<td>{{:value.law}}</td>
<td>{{:helper.link('Yes', null, {'ref': value.ref, 'state_law' : 1}, value.state == 1 ? 'selected' : null)}}{{:helper.link('No', null, {'ref': value.ref, 'state_law' : 0}, value.state == 0 ? 'selected' : null)}}</td>
{{if data.isMalf}}
<td class='edit'>{{:helper.link('Edit', null, {'edit_law': value.ref})}}</td>
<td class='delete'>{{:helper.link('Delete', null, {'delete_law': value.ref}, null, 'redButton')}}</td>
{{/if}}
</tr>
{{/for}}
</table>
{{/if}}
<div class="item">
<div class="itemLabelNarrow">
Statement Channel:
</div>
<div class="itemContentWide">
{{for data.channels}}
{{:helper.link(value.channel, null, {'law_channel' : value.channel}, value.channel == data.channel ? 'selected' : null)}}
{{/for}}
</div>
</div>
<div class="item">
<div class="itemLabelNarrow">
State Laws:
</div>
<div class="itemContent">
{{:helper.link('State Laws', null, {'state_laws' : 1})}}
</div>
</div>
{{if data.isMalf}}
<div class="item">
<div class="itemLabelNarrow">
Add Laws:
</div>
<div class="itemContent">
<table class='borders'>
<tr><td class='law_type'>Type</td><td>Law</td><td class='position'>Index</td><td class='edit'>Edit</td><td class='add'>Add</td></tr>
{{if data.isAdmin && !data.has_zeroth_laws}}
<tr><td class='law_type'>Zero</td><td>{{:data.zeroth_law}}</td><td class='position'>N/A</td><td class='edit'>{{:helper.link('Edit', null, {'change_zeroth_law' : 1})}}</td><td class='add'>{{:helper.link('Add', null, {'add_zeroth_law' : 1})}}</td></tr>
{{/if}}
<tr><td class='law_type'>Ion</td><td>{{:data.ion_law}}</td><td class='position'>N/A</td><td class='edit'>{{:helper.link('Edit', null, {'change_ion_law' : 1})}}</td><td class='add'>{{:helper.link('Add', null, {'add_ion_law' : 1})}}</td></tr>
<tr><td class='law_type'>Inherent</td><td>{{:data.inherent_law}}</td><td class='position'>N/A</td><td class='edit'>{{:helper.link('Edit', null, {'change_inherent_law' : 1})}}</td><td class='add'>{{:helper.link('Add', null, {'add_inherent_law' : 1})}}</td></tr>
<tr><td class='law_type'>Supplied</td><td>{{:data.supplied_law}}</td><td class='position'>{{:helper.link(data.supplied_law_position, null, {'change_supplied_law_position' : 1})}}</td><td class='edit'>{{:helper.link('Edit', null, {'change_supplied_law' : 1})}}</td><td class='add'>{{:helper.link('Add', null, {'add_supplied_law' : 1})}}</td></tr>
</table>
</div>
</div>
{{/if}}
{{if data.isMalf}}
<div class="item">
<div class="itemLabelNarrow">
Sync Laws:
</div>
<div class="itemContent">
{{:helper.link('Sync Laws', null, {'sync_laws' : 1})}}
</div>
</div>
{{/if}}
<div class="item">
<div class="itemLabelNarrow">
Law Notification:
</div>
<div class="itemContent">
{{:helper.link('Notify', null, {'notify_laws' : 1})}}
</div>
</div>
{{else data.view == 1}}
{{for data.law_sets}}
<div class="item">
<div class="itemLabelWide">
<H2>{{:value.name}}</H2>{{:value.header}}
</div>
{{if value.laws.has_ion_laws}}
<table class='borders'>
<tr><td class='law_index'>Index</td><td>Law</td>
{{for value.laws.ion_laws :lawValue:lawindex}}
<tr>
<td valign="top">{{:lawValue.index}}.</td>
<td>{{:lawValue.law}}</td>
</tr>
{{/for}}
</table>
{{/if}}
{{if value.laws.has_zeroth_laws || value.laws.has_inherent_laws}}
<table class='borders'>
<tr><td class='law_index'>Index</td><td>Law</td>
{{for value.laws.zeroth_laws :lawValue:lawindex}}
<tr>
<td valign="top">{{:lawValue.index}}.</td>
<td><span class='bad'>{{:lawValue.law}}</span></td>
</tr>
{{/for}}
{{for value.laws.inherent_laws :lawValue:lawindex}}
<tr>
<td valign="top">{{:lawValue.index}}.</td>
<td>{{:lawValue.law}}</td>
</tr>
{{/for}}
</table>
{{/if}}
{{if value.laws.has_supplied_laws}}
<table class='borders'>
<tr><td class='law_index'>Index</td><td>Law</td>
{{for value.laws.supplied_laws :lawValue:lawindex}}
<tr>
<td valign="top">{{:lawValue.index}}.</td>
<td>{{:lawValue.law}}</td>
</tr>
{{/for}}
</table>
{{/if}}
<div class="itemContent">
<br>
{{:helper.link('Load Laws', null, {'transfer_laws' : value.ref})}}{{:helper.link('State Laws', null, {'state_law_set' : value.ref})}}
</div>
</div>
{{/for}}
{{/if}}