mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-26 14:39:58 +01:00
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:
@@ -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()
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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,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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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!"
|
||||
|
||||
@@ -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>")
|
||||
|
||||
@@ -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 += " [src.laws.zeroth]<br>"
|
||||
dat += "<b>Supplemental Directives</b><br>"
|
||||
for(var/slaws in src.laws.supplied)
|
||||
for(var/slaws in laws.supplied)
|
||||
dat += " [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 |
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 |
@@ -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"
|
||||
|
||||
Reference in New Issue
Block a user