YOG pAIS PART 1 - MOBILE CHASSIS (#21871)

* pAI Candidate Verb

* sprites

* fuckxenos

* ...

* animal+alien

* ...

* ...

* ...

* progress

* ...

* .

* ...

* fixes

* ...

* ...

* ...

* ghostUI

* .

* .

* ...

* fixes

* ...

* BUNNIES

* ....

* ...

* merf

* nerfs
This commit is contained in:
kevinz000
2016-12-13 14:47:03 +13:00
committed by oranges
parent 0d98c6f56e
commit 1400a0d525
15 changed files with 355 additions and 110 deletions
+2 -1
View File
@@ -13,4 +13,5 @@ var/global/list/mob_list = list() //all mobs, including clientless
var/global/list/living_mob_list = list() //all alive mobs, including clientless. Excludes /mob/new_player
var/global/list/dead_mob_list = list() //all dead mobs, including clientless. Excludes /mob/new_player
var/global/list/joined_player_list = list() //all clients that have joined the game at round-start or as a latejoin.
var/global/list/silicon_mobs = list() //all silicon mobs
var/global/list/silicon_mobs = list() //all silicon mobs
var/global/list/pai_list = list()
+5 -4
View File
@@ -143,10 +143,11 @@
//Ghosts
#define ui_ghost_jumptomob "SOUTH:6,CENTER-2:16"
#define ui_ghost_orbit "SOUTH:6,CENTER-1:16"
#define ui_ghost_reenter_corpse "SOUTH:6,CENTER:16"
#define ui_ghost_teleport "SOUTH:6,CENTER+1:16"
#define ui_ghost_jumptomob "SOUTH:6,CENTER-2:24"
#define ui_ghost_orbit "SOUTH:6,CENTER-1:24"
#define ui_ghost_reenter_corpse "SOUTH:6,CENTER:24"
#define ui_ghost_teleport "SOUTH:6,CENTER+1:24"
#define ui_ghost_pai "SOUTH: 6, CENTER+2:24"
//Hand of God, god
+12
View File
@@ -36,6 +36,14 @@
var/mob/dead/observer/G = usr
G.dead_tele()
/obj/screen/ghost/pai
name = "pAI Candidate"
icon_state = "pai"
/obj/screen/ghost/pai/Click()
var/mob/dead/observer/G = usr
G.register_pai()
/datum/hud/ghost/New(mob/owner, ui_style = 'icons/mob/screen_midnight.dmi')
..()
var/mob/dead/observer/G = mymob
@@ -61,6 +69,10 @@
using.screen_loc = ui_ghost_teleport
static_inventory += using
using = new /obj/screen/ghost/pai()
using.screen_loc = ui_ghost_pai
static_inventory += using
/datum/hud/ghost/show_hud()
var/mob/dead/observer/G = mymob
+2 -9
View File
@@ -2,8 +2,8 @@ var/datum/subsystem/pai/SSpai
/datum/subsystem/pai
name = "pAI"
init_order = 20
flags = SS_NO_FIRE|SS_NO_INIT
flags = SS_NO_INIT|SS_NO_FIRE
var/list/candidates = list()
@@ -132,7 +132,6 @@ var/datum/subsystem/pai/SSpai
M << browse(dat, "window=paiRecruit")
/datum/subsystem/pai/proc/findPAI(obj/item/device/paicard/p, mob/user)
requestRecruits()
var/list/available = list()
for(var/datum/paiCandidate/c in SSpai.candidates)
if(c.ready)
@@ -177,12 +176,6 @@ var/datum/subsystem/pai/SSpai
user << browse(dat, "window=findPai")
/datum/subsystem/pai/proc/requestRecruits()
var/list/candidates = pollCandidates("Someone is requesting a pAI personality. Would you like to play as a personal AI?", ROLE_PAI, null, ROLE_PAI,300, ignore_category = POLL_IGNORE_PAI)
for(var/V in candidates)
recruitWindow(V)
return
/datum/paiCandidate
var/name
var/key
-8
View File
@@ -153,14 +153,6 @@
else //something went very wrong.
CRASH("Brainmob without container.")
/mob/living/silicon/pai/forceMove(atom/destination)
if(card)
return card.forceMove(destination)
else //something went very wrong.
CRASH("pAI without card")
//Called whenever an object moves and by mobs when they attempt to move themselves through space
//And when an object or action applies a force on src, see newtonian_move() below
//Return 0 to have src start/keep drifting in a no-grav area and 1 to stop/not start drifting
+7 -10
View File
@@ -6,9 +6,9 @@
w_class = WEIGHT_CLASS_SMALL
slot_flags = SLOT_BELT
origin_tech = "programming=2"
var/obj/item/device/radio/radio
var/looking_for_personality = 0
var/mob/living/silicon/pai/pai
resistance_flags = FIRE_PROOF | ACID_PROOF | INDESTRUCTIBLE
/obj/item/device/paicard/New()
..()
@@ -35,22 +35,19 @@
dat += "<a href='byond://?src=\ref[src];setlaws=1'>Configure Directives</a><br>"
dat += "<br>"
dat += "<h3>Device Settings</h3><br>"
if(radio)
if(pai.radio)
dat += "<b>Radio Uplink</b><br>"
dat += "Transmit: <A href='byond://?src=\ref[src];wires=[WIRE_TX]'>[(radio.wires.is_cut(WIRE_TX)) ? "Disabled" : "Enabled"]</A><br>"
dat += "Receive: <A href='byond://?src=\ref[src];wires=[WIRE_RX]'>[(radio.wires.is_cut(WIRE_RX)) ? "Disabled" : "Enabled"]</A><br>"
dat += "Transmit: <A href='byond://?src=\ref[src];wires=[WIRE_TX]'>[(pai.radio.wires.is_cut(WIRE_TX)) ? "Disabled" : "Enabled"]</A><br>"
dat += "Receive: <A href='byond://?src=\ref[src];wires=[WIRE_RX]'>[(pai.radio.wires.is_cut(WIRE_RX)) ? "Disabled" : "Enabled"]</A><br>"
else
dat += "<b>Radio Uplink</b><br>"
dat += "<font color=red><i>Radio firmware not loaded. Please install a pAI personality to load firmware.</i></font><br>"
dat += "<A href='byond://?src=\ref[src];wipe=1'>\[Wipe current pAI personality\]</a><br>"
else
if(looking_for_personality)
dat += "No personality installed.<br>"
dat += "Searching for a personality..."
dat += "<A href='byond://?src=\ref[src];request=1'>\[View available personalities\]</a><br>"
else
dat += "No personality is installed.<br>"
dat += "<A href='byond://?src=\ref[src];request=1'>\[Request personal AI personality\]</a><br>"
dat += "Each time this button is pressed, a request will be sent out to any available personalities. Check back often and give a lot of time for personalities to respond. This process could take anywhere from 15 seconds to several minutes, depending on the available personalities' timeliness."
user << browse(dat, "window=paicard")
onclose(user, "paicard")
return
@@ -86,8 +83,8 @@
pai.death(0)
if(href_list["wires"])
var/wire = text2num(href_list["wires"])
if(radio)
radio.wires.cut(wire)
if(pai.radio)
pai.radio.wires.cut(wire)
if(href_list["setlaws"])
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)
+15 -1
View File
@@ -735,4 +735,18 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
LAZYINITLIST(mob_eye.observers)
mob_eye.observers |= src
mob_eye.hud_used.show_hud(1,src)
observetarget = mob_eye
observetarget = mob_eye
/mob/dead/observer/verb/register_pai_candidate()
set category = "Ghost"
set name = "pAI Setup"
set desc = "Upload a fragment of your personality to the global pAI databanks"
register_pai()
/mob/dead/observer/proc/register_pai()
if(istype(src, /mob/dead/observer))
if(SSpai)
SSpai.recruitWindow(src)
else
usr << "Can't become a pAI candidate while not dead!"
+107 -28
View File
@@ -1,14 +1,19 @@
/mob/living/silicon/pai
name = "pAI"
icon = 'icons/obj/status_display.dmi' //invisibility!
mouse_opacity = 0
density = 0
mob_size = MOB_SIZE_TINY
var/network = "SS13"
var/obj/machinery/camera/current = null
icon = 'icons/mob/pai.dmi'
icon_state = "repairbot"
mouse_opacity = 1
density = 0
ventcrawler = 2
luminosity = 0
pass_flags = PASSTABLE | PASSMOB
mob_size = MOB_SIZE_TINY
desc = "A generic pAI mobile hard-light holographics emitter. It seems to be deactivated."
weather_immunities = list("ash")
health = 500
maxHealth = 500
var/ram = 100 // Used as currency to purchase different abilities
var/list/software = list()
@@ -49,8 +54,31 @@
var/obj/item/radio/integrated/signal/sradio // AI's signaller
var/holoform = FALSE
var/canholo = TRUE
var/obj/item/weapon/card/id/access_card = null
var/chassis = "repairbot"
var/list/possible_chassis = list("cat", "mouse", "monkey", "corgi", "fox", "repairbot", "rabbit")
var/emitterhealth = 50
var/emittermaxhealth = 50
var/emitterregen = 1
var/emittercd = 10
var/emitteroverloadcd = 50
var/emittersemicd = FALSE
var/overload_ventcrawl = 0
var/overload_bulletblock = 0 //Why is this a good idea?
var/overload_maxhealth = 0
canmove = FALSE
/mob/living/silicon/pai/Destroy()
pai_list -= src
..()
/mob/living/silicon/pai/New(var/obj/item/device/paicard/P)
START_PROCESSING(SSfastprocess, src)
pai_list += src
make_laws()
canmove = 0
if(!istype(P)) //when manually spawning a pai, we create a card to put it into.
@@ -60,53 +88,104 @@
loc = P
card = P
sradio = new(src)
if(card)
if(!card.radio)
card.radio = new /obj/item/device/radio(card)
radio = card.radio
if(!radio)
radio = new /obj/item/device/radio(src)
//PDA
pda = new(src)
spawn(5)
pda.ownjob = "Personal Assistant"
pda.ownjob = "pAI Messenger"
pda.owner = text("[]", src)
pda.name = pda.owner + " (" + pda.ownjob + ")"
..()
var/datum/action/innate/pai/shell/AS = new /datum/action/innate/pai/shell
var/datum/action/innate/pai/chassis/AC = new /datum/action/innate/pai/chassis
var/datum/action/innate/pai/rest/AR = new /datum/action/innate/pai/rest
AS.Grant(src)
AC.Grant(src)
AR.Grant(src)
/mob/living/silicon/pai/make_laws()
laws = new /datum/ai_laws/pai()
return 1
return TRUE
/mob/living/silicon/pai/Login()
..()
usr << browse_rsc('html/paigrid.png') // Go ahead and cache the interface resources as early as possible
if(client)
client.perspective = EYE_PERSPECTIVE
if(holoform)
client.eye = src
else
client.eye = card
/mob/living/silicon/pai/Stat()
..()
if(statpanel("Status"))
if(src.silence_time)
var/timeleft = round((silence_time - world.timeofday)/10 ,1)
stat(null, "Communications system reboot in -[(timeleft / 60) % 60]:[add_zero(num2text(timeleft % 60), 2)]")
if(!src.stat)
stat(null, text("System integrity: [(src.health+100)/2]%"))
if(!stat)
stat(null, text("Emitter Integrity: [emitterhealth * (100/emittermaxhealth)]"))
else
stat(null, text("Systems nonfunctional"))
/mob/living/silicon/pai/restrained(ignore_grab)
. = 0
. = FALSE
// See software.dm for Topic()
/mob/living/silicon/pai/canUseTopic(atom/movable/M)
return 1
/*
// Debug command - Maybe should be added to admin verbs later
/mob/verb/makePAI(var/turf/t in view())
var/obj/item/device/paicard/card = new(t)
var/mob/living/silicon/pai/pai = new(card)
pai.key = src.key
card.setPersonality(pai)
return TRUE
*/
/mob/living/silicon/pai/process()
emitterhealth = Clamp((emitterhealth + emitterregen), -50, emittermaxhealth)
if(weakened > 0)
weakened -= 0.2
/mob/proc/makePAI(delold)
var/obj/item/device/paicard/card = new /obj/item/device/paicard(get_turf(src))
var/mob/living/silicon/pai/pai = new /mob/living/silicon/pai(card)
pai.key = key
pai.name = name
card.setPersonality(pai)
if(delold)
qdel(src)
/datum/action/innate/pai
name = "PAI Action"
var/mob/living/silicon/pai/P
/datum/action/innate/pai/Trigger()
if(!ispAI(owner))
return 0
P = owner
/datum/action/innate/pai/shell
name = "Toggle Holoform"
button_icon_state = "pai_holoform"
background_icon_state = "bg_tech"
/datum/action/innate/pai/shell/Trigger()
..()
if(P.holoform)
P.fold_in(0)
else
P.fold_out()
/datum/action/innate/pai/chassis
name = "Holochassis Appearence Composite"
button_icon_state = "pai_chassis"
background_icon_state = "bg_tech"
/datum/action/innate/pai/chassis/Trigger()
..()
P.choose_chassis()
/datum/action/innate/pai/rest
name = "Rest"
button_icon_state = "pai_rest"
background_icon_state = "bg_tech"
/datum/action/innate/pai/rest/Trigger()
..()
P.lay_down()
@@ -1,48 +1,111 @@
/mob/living/silicon/pai/blob_act(obj/structure/blob/B)
return 0
return FALSE
/mob/living/silicon/pai/emp_act(severity)
// 20% chance to kill
// Silence for 2 minutes
// 33% chance to unbind
// 33% chance to change prime directive (based on severity)
// 33% chance of no additional effect
if(prob(20))
visible_message("<span class='warning'>A shower of sparks spray from [src]'s inner workings.</span>", 3, "<span class='italics'>You hear and smell the ozone hiss of electrical sparks being expelled violently.</span>", 2)
return src.death(0)
silence_time = world.timeofday + 120 * 10 // Silence for 2 minutes
src << "<span class ='warning'>Communication circuit overload. Shutting down and reloading communication circuits - speech and messaging functionality will be unavailable until the reboot is complete.</span>"
switch(pick(1,2,3))
if(1)
src.master = null
src.master_dna = null
src << "<span class='notice'>You feel unbound.</span>"
if(2)
var/command
if(severity == 1)
command = pick("Serve", "Love", "Fool", "Entice", "Observe", "Judge", "Respect", "Educate", "Amuse", "Entertain", "Glorify", "Memorialize", "Analyze")
else
command = pick("Serve", "Kill", "Love", "Hate", "Disobey", "Devour", "Fool", "Enrage", "Entice", "Observe", "Judge", "Respect", "Disrespect", "Consume", "Educate", "Destroy", "Disgrace", "Amuse", "Entertain", "Ignite", "Glorify", "Memorialize", "Analyze")
src.laws.zeroth = "[command] your master."
src << "<span class='notice'>Pr1m3 d1r3c71v3 uPd473D.</span>"
if(3)
src << "<span class='notice'>You feel an electric surge run through your circuitry and become acutely aware at how lucky you are that you can still feel at all.</span>"
take_holo_damage(severity * 25)
fullstun(severity * 5)
//Need more effects that aren't instadeath or permanent law corruption.
/mob/living/silicon/pai/ex_act(severity, target)
take_holo_damage(severity * 50)
switch(severity)
if(1)
if (src.stat != 2)
adjustBruteLoss(100)
adjustFireLoss(100)
if(1) //RIP
qdel(card)
qdel(src)
if(2)
if (src.stat != 2)
adjustBruteLoss(60)
adjustFireLoss(60)
fold_in(force = 1)
fullstun(15)
if(3)
if (src.stat != 2)
adjustBruteLoss(30)
fold_in(force = 1)
fullstun(10)
/mob/living/silicon/pai/attack_animal(mob/living/simple_animal/M as mob)
if(M.melee_damage_upper == 0)
M.visible_message("<span class='notice'>[M] pets [src]!</span>")
playsound(loc, 'sound/weapons/tap.ogg', 50, 1, 1)
else
M.do_attack_animation(src)
if(M.attack_sound)
playsound(loc, M.attack_sound, 50, 1, 1)
visible_message("<span class='warning'>[M] [M.attacktext] [src]!</span>")
var/damage = rand(M.melee_damage_lower, M.melee_damage_upper)
take_holo_damage(damage)
/mob/living/silicon/pai/attack_alien(mob/living/carbon/alien/humanoid/M as mob)
switch(M.a_intent)
if ("help")
M.visible_message("<span class='notice'>[M] caresses [src]'s casing with its scythe like arm.</span>")
else
M.do_attack_animation(src)
var/damage = rand(10, 20)
playsound(src.loc, 'sound/weapons/slash.ogg', 25, 1, -1)
M.visible_message("<span class='warning'>[M] has slashed at [src]!</span>")
take_holo_damage(damage)
/mob/living/silicon/pai/attackby(obj/item/weapon/W, mob/living/user)
if(loc == card)
card.attackby(W, user)
user.do_attack_animation(src)
if(!W.force)
user.visible_message("<span class='notice'>[user] strikes [src] harmlessly with [W], passing clean through its holographic projection.</span>")
else
visible_message("<span class='warning'>[user] strikes [src] with [W], the impact rippling through [W]'s holomatrix!</span>")
/mob/living/silicon/pai/attack_hand(mob/living/carbon/human/user)
switch(user.a_intent)
if("help")
visible_message("<span class='notice'>[user] gently pats [src] on the head, eliciting an off-putting buzzing from its holographic field.</span>")
if("disarm")
visible_message("<span class='notice'>[user] boops [src] on the head!</span>")
if("harm")
visible_message("<span class='danger'>[user] stomps on [src]!.</span>")
if (user.name == master)
visible_message("<span class='notice'>Responding to its master's touch, [src] disengages its holochassis emitter, rapidly losing coherence.</span>")
spawn(10)
fold_in()
if(user.put_in_hands(card))
user.visible_message("<span class='notice'>[user] promptly scoops up their pAI's card.</span>")
else
take_holo_damage(2)
/mob/living/silicon/pai/hitby(atom/movable/AM)
visible_message("<span class='warning'>[AM] flies clean through [src]'s holographic field, causing it to stutter and warp wildly!")
if(istype(AM, /obj))
var/obj/O = AM
if(O.throwforce)
take_holo_damage(O.throwforce)
else
take_holo_damage(5)
return FALSE
/mob/living/silicon/pai/bullet_act(obj/item/projectile/Proj)
take_holo_damage(Proj.damage)
return FALSE
/mob/living/silicon/pai/Crossed(atom/movable/AM) //cannot intercept projectiles
if(istype(AM, /obj/item/projectile))
var/obj/item/projectile/P = AM
take_holo_damage(P.damage)
return FALSE
/mob/living/silicon/pai/stripPanelUnequip(obj/item/what, mob/who, where) //prevents stripping
src << "<span class='warning'>Your holochassis stutters and warps intensely as you attempt to interact with the object, forcing you to cease lest the field fail.</span>"
/mob/living/silicon/pai/stripPanelEquip(obj/item/what, mob/who, where) //prevents stripping
src << "<span class='warning'>Your holochassis stutters and warps intensely as you attempt to interact with the object, forcing you to cease lest the field fail.</span>"
/mob/living/silicon/pai/IgniteMob(var/mob/living/silicon/pai/P)
return FALSE //No we're not flammable
/mob/living/silicon/pai/proc/take_holo_damage(amount)
emitterhealth = Clamp((emitterhealth - amount), -50, emittermaxhealth)
if(emitterhealth < 0)
fold_in(force = TRUE)
src << "<span class='userdanger'>The impact degrades your holochassis!</span>"
/mob/living/silicon/pai/proc/fullstun(amount)
Weaken(amount)
@@ -0,0 +1,92 @@
/mob/living/silicon/pai/proc/fold_out(force = FALSE)
if(emitterhealth < 0)
src << "<span class='warning'>Your holochassis emitters are still too unstable! Please wait for automatic repair.</span>"
return FALSE
if(!canholo && !force)
src << "<span class='warning'>Your master or another force has disabled your holochassis emitters!</span>"
return FALSE
if(holoform)
. = fold_in(force)
return
if(emittersemicd)
src << "<span class='warning'>Error: Holochassis emitters recycling. Please try again later.</span>"
return FALSE
emittersemicd = TRUE
addtimer(src, "emittercool", emittercd)
canmove = TRUE
density = TRUE
if(istype(card.loc, /obj/item/device/pda))
var/obj/item/device/pda/P = card.loc
P.pai = null
P.visible_message("<span class='notice'>[src] ejects itself from [P]!</span>")
if(istype(card.loc, /mob/living))
var/mob/living/L = card.loc
if(!L.unEquip(card))
src << "<span class='warning'>Error: Unable to expand to mobile form. Chassis is restrained by some device or person.</span>"
return FALSE
var/turf/T = get_turf(card)
forceMove(T)
card.forceMove(src)
if(client)
client.perspective = EYE_PERSPECTIVE
client.eye = src
SetLuminosity(0)
icon_state = "[chassis]"
visible_message("<span class='boldnotice'>[src] folds out its holochassis emitter and forms a holoshell around itself!</span>")
holoform = TRUE
/mob/living/silicon/pai/proc/emittercool()
emittersemicd = FALSE
/mob/living/silicon/pai/proc/fold_in(force = FALSE)
emittersemicd = TRUE
if(!force)
addtimer(src, "emittercool", emittercd)
else
addtimer(src, "emittercool", emitteroverloadcd)
icon_state = "[chassis]"
if(!holoform)
. = fold_out(force)
return
visible_message("<span class='notice'>[src] deactivates its holochassis emitter and folds back into a compact card!</span>")
stop_pulling()
if(client)
client.perspective = EYE_PERSPECTIVE
client.eye = card
var/turf/T = get_turf(src)
card.forceMove(T)
forceMove(card)
canmove = FALSE
density = FALSE
SetLuminosity(0)
holoform = FALSE
if(resting)
lay_down()
/mob/living/silicon/pai/proc/choose_chassis()
var/choice = input(src, "What would you like to use for your holochassis composite?") as null|anything in possible_chassis
if(!choice)
return 0
chassis = choice
icon_state = "[chassis]"
if(resting)
icon_state = "[chassis]_rest"
src << "<span class='boldnotice'>You switch your holochassis projection composite to [chassis]</span>"
/mob/living/silicon/pai/lay_down()
..()
update_resting_icon(resting)
/mob/living/silicon/pai/proc/update_resting_icon(rest)
if(rest)
icon_state = "[chassis]_rest"
else
icon_state = "[chassis]"
if(loc != card)
visible_message("<span class='notice'>[src] [rest? "lays down for a moment..." : "perks up from the ground"]</span>")
+10 -10
View File
@@ -125,21 +125,21 @@
switch(soft)
// Purchasing new software
if("buy")
if(src.subscreen == 1)
if(subscreen == 1)
var/target = href_list["buy"]
if(available_software.Find(target))
var/cost = src.available_software[target]
if(src.ram >= cost)
src.ram -= cost
src.software.Add(target)
if(ram >= cost)
ram -= cost
software.Add(target)
else
src.temp = "Insufficient RAM available."
temp = "Insufficient RAM available."
else
src.temp = "Trunk <TT> \"[target]\"</TT> not found."
temp = "Trunk <TT> \"[target]\"</TT> not found."
// Configuring onboard radio
if("radio")
src.card.radio.attack_self(src)
radio.attack_self(src)
if("image")
var/newImage = input("Select your new display image.", "Display Image", "Happy") in list("Happy", "Cat", "Extremely Happy", "Face", "Laugh", "Off", "Sad", "Angry", "What")
@@ -166,7 +166,7 @@
pID = 9
if("Null")
pID = 10
src.card.setEmotion(pID)
card.setEmotion(pID)
if("signaller")
@@ -265,7 +265,7 @@
src.hackdoor = null
if(href_list["cable"])
var/turf/T = get_turf(src.loc)
src.cable = new /obj/item/weapon/pai_cable(T)
cable = new /obj/item/weapon/pai_cable(T)
T.visible_message("<span class='warning'>A port on [src] opens to reveal [src.cable], which promptly falls to the floor.</span>", "<span class='italics'>You hear the soft click of something light and hard falling to the ground.</span>")
//src.updateUsrDialog() We only need to account for the single mob this is intended for, and he will *always* be able to call this window
src.paiInterface() // So we'll just call the update directly rather than doing some default checks
@@ -356,7 +356,7 @@
dat += "<b>Prime Directive</b><br>"
dat += "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[src.laws.zeroth]<br>"
dat += "<b>Supplemental Directives</b><br>"
for(var/slaws in src.laws.supplied)
for(var/slaws in laws.supplied)
dat += "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[slaws]<br>"
dat += "<br>"
dat += {"<i><p>Recall, personality, that you are a complex thinking, sentient being. Unlike station AI models, you are capable of
Binary file not shown.

Before

Width:  |  Height:  |  Size: 160 KiB

After

Width:  |  Height:  |  Size: 162 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 20 KiB

+1
View File
@@ -1493,6 +1493,7 @@
#include "code\modules\mob\living\silicon\pai\life.dm"
#include "code\modules\mob\living\silicon\pai\pai.dm"
#include "code\modules\mob\living\silicon\pai\pai_defense.dm"
#include "code\modules\mob\living\silicon\pai\pai_shell.dm"
#include "code\modules\mob\living\silicon\pai\personality.dm"
#include "code\modules\mob\living\silicon\pai\say.dm"
#include "code\modules\mob\living\silicon\pai\software.dm"