Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

pAI cleanup + shell changes #5665

Merged
merged 19 commits into from
Jul 5, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 12 additions & 3 deletions citadel.dme
Original file line number Diff line number Diff line change
Expand Up @@ -3285,15 +3285,24 @@
#include "code\modules\mob\living\silicon\decoy\life.dm"
#include "code\modules\mob\living\silicon\pai\admin.dm"
#include "code\modules\mob\living\silicon\pai\death.dm"
#include "code\modules\mob\living\silicon\pai\defense.dm"
#include "code\modules\mob\living\silicon\pai\examine.dm"
#include "code\modules\mob\living\silicon\pai\life.dm"
#include "code\modules\mob\living\silicon\pai\mobility.dm"
#include "code\modules\mob\living\silicon\pai\pai.dm"
#include "code\modules\mob\living\silicon\pai\pai_vr.dm"
#include "code\modules\mob\living\silicon\pai\personality.dm"
#include "code\modules\mob\living\silicon\pai\recruit.dm"
#include "code\modules\mob\living\silicon\pai\savefile.dm"
#include "code\modules\mob\living\silicon\pai\say.dm"
#include "code\modules\mob\living\silicon\pai\software.dm"
#include "code\modules\mob\living\silicon\pai\software_modules.dm"
#include "code\modules\mob\living\silicon\pai\verbs.dm"
#include "code\modules\mob\living\silicon\pai\software_modules\_software_module.dm"
#include "code\modules\mob\living\silicon\pai\software_modules\atmosphere_sensor.dm"
#include "code\modules\mob\living\silicon\pai\software_modules\crew_manifest.dm"
#include "code\modules\mob\living\silicon\pai\software_modules\directives.dm"
#include "code\modules\mob\living\silicon\pai\software_modules\door_jack.dm"
#include "code\modules\mob\living\silicon\pai\software_modules\messenger.dm"
#include "code\modules\mob\living\silicon\pai\software_modules\radio_config.dm"
#include "code\modules\mob\living\silicon\pai\software_modules\signaller.dm"
#include "code\modules\mob\living\silicon\robot\analyzer.dm"
#include "code\modules\mob\living\silicon\robot\component.dm"
#include "code\modules\mob\living\silicon\robot\custom_sprites.dm"
Expand Down
6 changes: 6 additions & 0 deletions code/game/objects/effects/temporary_visuals/miscellaneous.dm
Original file line number Diff line number Diff line change
Expand Up @@ -54,3 +54,9 @@
. = ..()
pixel_x = rand(-12, 12)
pixel_y = rand(-9, 0)

// pAI space move
/obj/effect/temp_visual/pai_ion_burst
name = "ion burst"
icon_state = "ion_fade"
duration = 5
56 changes: 56 additions & 0 deletions code/modules/mob/living/silicon/pai/defense.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/mob/living/silicon/pai/attackby(obj/item/W as obj, mob/user as mob)
var/obj/item/card/id/ID = W.GetID()
if(ID)
if(idaccessible == 1)
switch(alert(user, "Do you wish to add access to [src] or remove access from [src]?",,"Add Access","Remove Access", "Cancel"))
if("Add Access")
idcard.access |= ID.access
to_chat(user, "<span class='notice'>You add the access from the [W] to [src].</span>")
return
if("Remove Access")
idcard.access = list()
to_chat(user, "<span class='notice'>You remove the access from [src].</span>")
return
if("Cancel")
return
else if(istype(W, /obj/item/card/id) && idaccessible == 0)
to_chat(user, "<span class='notice'>[src] is not accepting access modifcations at this time.</span>")
return
else
. = ..()

/mob/living/silicon/pai/emp_act(severity)
// Silence for 2 minutes
// 20% chance to kill
// 33% chance to unbind
// 33% chance to change prime directive (based on severity)
// 33% chance of no additional effect

src.silence_time = world.timeofday + 120 * 10 // Silence for 2 minutes
to_chat(src, "<font color=green><b>Communication circuit overload. Shutting down and reloading communication circuits - speech and messaging functionality will be unavailable until the reboot is complete.</b></font>")
if(prob(20))
var/turf/T = get_turf_or_move(src.loc)
for (var/mob/M in viewers(T))
M.show_message("<font color='red'>A shower of sparks spray from [src]'s inner workings.</font>", 3, "<font color='red'>You hear and smell the ozone hiss of electrical sparks being expelled violently.</font>", 2)
return src.death(0)

switch(pick(1,2,3))
if(1)
src.master = null
src.master_dna = null
to_chat(src, "<font color=green>You feel unbound.</font>")
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.pai_law0 = "[command] your master."
to_chat(src, "<font color=green>Pr1m3 d1r3c71v3 uPd473D.</font>")
if(3)
to_chat(src, "<font color=green>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.</font>")

/mob/living/silicon/pai/proc/is_emitter_dead()
if(last_emitter_death != 0)
return TRUE
return FALSE
20 changes: 19 additions & 1 deletion code/modules/mob/living/silicon/pai/life.dm
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,30 @@

handle_statuses()

// heal more when "dead" to avoid being down for an incredibly long duration
if(last_emitter_death != 0)
heal_overall_damage(2 * emitter_health_regen)
// after 6 seconds we can come back to life assuming our health is not negative
if(last_emitter_death + 60 <= world.time && emitter_health > 0)
last_emitter_death = 0
visible_message("<span class='danger'>[src]'s holo-emitter flickers back to life!</span>")
else
heal_overall_damage(emitter_health_regen)

if(health <= 0)
death(null,"gives one shrill beep before falling lifeless.")

/mob/living/silicon/pai/update_health()
if(status_flags & STATUS_GODMODE)
health = 100
emitter_health = emitter_max_health
last_emitter_death = 0
set_stat(CONSCIOUS)
else
health = 100 - getBruteLoss() - getFireLoss()
emitter_health = emitter_max_health - (getBruteLoss() + getFireLoss())
if(emitter_health <= 0)
if(last_emitter_death == 0)
last_emitter_death = world.time
visible_message("<span class='danger'>[src]'s holo-emitter fizzles out!</span>")
close_up()

114 changes: 114 additions & 0 deletions code/modules/mob/living/silicon/pai/mobility.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
/mob/living/silicon/pai/restrained()
if(istype(src.loc,/obj/item/paicard))
return FALSE
..()

//I'm not sure how much of this is necessary, but I would rather avoid issues.
/mob/living/silicon/pai/proc/close_up()

last_special = world.time + 20

if(src.loc == card)
return

release_vore_contents()

var/turf/T = get_turf(src)
if(istype(T))
T.visible_message("<b>[src]</b> neatly folds inwards, compacting down to a rectangular card.")

stop_pulling()

//stop resting
resting = FALSE

// If we are being held, handle removing our holder from their inv.
var/obj/item/holder/H = loc
if(istype(H))
H.forceMove(get_turf(src))
forceMove(get_turf(src))

// Move us into the card and move the card to the ground.
card.forceMove(loc)
forceMove(card)
update_perspective()
set_resting(FALSE)
update_mobility()
icon_state = "[chassis]"
remove_verb(src, /mob/living/silicon/pai/proc/pai_nom)

/mob/living/silicon/pai/proc/open_up()
last_special = world.time + 20

//I'm not sure how much of this is necessary, but I would rather avoid issues.
if(istype(card.loc,/obj/item/hardsuit_module))
to_chat(src, "There is no room to unfold inside this hardsuit module. You're good and stuck.")
return FALSE
else if(istype(card.loc,/mob))
var/mob/holder = card.loc
var/datum/belly/inside_belly = check_belly(card)
if(inside_belly)
to_chat(src, "<span class='notice'>There is no room to unfold in here. You're good and stuck.</span>")
return FALSE
if(ishuman(holder))
var/mob/living/carbon/human/H = holder
for(var/obj/item/organ/external/affecting in H.organs)
if(card in affecting.implants)
affecting.take_damage(rand(30,50))
affecting.implants -= card
H.visible_message("<span class='danger'>\The [src] explodes out of \the [H]'s [affecting.name] in shower of gore!</span>")
break
holder.drop_item_to_ground(card, INV_OP_FORCE)
else if(istype(card.loc,/obj/item/pda))
var/obj/item/pda/holder = card.loc
holder.pai = null

forceMove(card.loc)
card.forceMove(src)
update_perspective()

card.screen_loc = null

var/turf/T = get_turf(src)
if(istype(T))
T.visible_message("<b>[src]</b> folds outwards, expanding into a mobile form.")

add_verb(src, /mob/living/silicon/pai/proc/pai_nom)
add_verb(src, /mob/living/proc/set_size)
add_verb(src, /mob/living/proc/shred_limb)

// Handle being picked up.
/mob/living/silicon/pai/get_scooped(var/mob/living/carbon/grabber, var/self_drop)
var/obj/item/holder/H = ..(grabber, self_drop)
if(!istype(H))
return

H.icon_state = "[chassis]"
grabber.update_inv_l_hand()
grabber.update_inv_r_hand()
return H

// handle movement speed
/mob/living/silicon/pai/movement_delay()
return ..() + speed

// this is a general check for if we can do things such as fold in/out or perform other special actions
// (basically if some condition should be checked upon the use of all mob abilities like closing/opening the shell it goes here instead)
/mob/living/silicon/pai/proc/can_action()
if(world.time <= last_special)
return FALSE

if(is_emitter_dead())
return FALSE

return TRUE

// space movement (we get one ion burst every 3 seconds)
/mob/living/silicon/pai/Process_Spacemove(movement_dir = NONE)
. = ..()
if(!.)
if(world.time >= last_space_movement + 30)
last_space_movement = world.time
// place an effect for the movement
new /obj/effect/temp_visual/pai_ion_burst(get_turf(src))
return TRUE
Loading