Skip to content

Commit

Permalink
pAI cleanup + shell changes (#5665)
Browse files Browse the repository at this point in the history
## About The Pull Request
part 1 changes mostly just tidying files up:
general file cleanup
remove HUD and records software modules
weak space movement (an ion burst every 3 seconds)
pAIs have 50 health which regenerates over time and when it goes to 0
they just fizzle out for a bit (minimum 6 seconds, hurting them more can
extend this depending on the sustained damage)
(regen is 1 brute 1 fire per second, doubled if they are "dead")
movement speed reduced from 5 tiles to 4 tiles per second
cooldown between folding in/out 10 seconds -> 2 seconds


## Why It's Good For The Game
this is a section of code that is in need of updating and hasn't been
properly combed over in a long time
content additions for pAIs will come after this PR (software module
overhaul)

## Changelog

<!-- If your PR modifies aspects of the game that can be concretely
observed by players or admins you should add a changelog. If your change
does NOT meet this description, remove this section. Be sure to properly
mark your PRs to prevent unnecessary GBP loss. You can read up on GBP
and it's effects on PRs in the tgstation guides for contributors. Please
note that maintainers freely reserve the right to remove and add tags
should they deem it appropriate. You can attempt to finagle the system
all you want, but it's best to shoot for clear communication right off
the bat. -->

:cl:
tweak: pAI movement speed reduced to 4 tiles per second from 5
tweak: pAI cooldown between folding in/out reduced from 10 seconds to 2
seconds
del: removed HUDs and departmental records pAI software modules
del: you can no longer card a pAI by using harm intent while unarmed
add: pAIs now regenerate health over time and fizzle out for a few
seconds when damaged to a certain threshold
add: pAIs now get a weak one tile "ion burst" every 3 seconds for moving
in space so they can change the direction they're drifting in
code: tidied up pAI files
fix: access changes should now work by using an ID on a pAI
/:cl:

<!-- Both :cl:'s are required for the changelog to work! You can put
your name to the right of the first :cl: if you want to overwrite your
GitHub username as author ingame. -->
<!-- You can use multiple of the same prefix (they're only used for the
icon ingame) and delete the unneeded ones. Despite some of the tags,
changelogs should generally represent how a player might be affected by
the changes rather than a summary of the PR's contents. -->
  • Loading branch information
timothyteakettle authored Jul 5, 2023
1 parent 787c606 commit 2d21007
Show file tree
Hide file tree
Showing 18 changed files with 771 additions and 937 deletions.
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

0 comments on commit 2d21007

Please sign in to comment.