Skip to content

Commit

Permalink
adds a component for putting a mob in an object, utilizes it in pAI c…
Browse files Browse the repository at this point in the history
…ode (#5700)
  • Loading branch information
timothyteakettle authored Jul 17, 2023
1 parent 07155e8 commit 062dd60
Show file tree
Hide file tree
Showing 5 changed files with 100 additions and 35 deletions.
1 change: 1 addition & 0 deletions citadel.dme
Original file line number Diff line number Diff line change
Expand Up @@ -722,6 +722,7 @@
#include "code\datums\components\gps_signal.dm"
#include "code\datums\components\horror_aura.dm"
#include "code\datums\components\jousting.dm"
#include "code\datums\components\object_transform.dm"
#include "code\datums\components\orbiter.dm"
#include "code\datums\components\simple_access.dm"
#include "code\datums\components\slaved_atom_to_loc.dm"
Expand Down
33 changes: 33 additions & 0 deletions code/datums/components/object_transform.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/datum/component/object_transform
var/obj/transformed_object
var/to_object_text
var/to_mob_text

/datum/component/object_transform/Initialize(_transformed_object, _to_object_text, _to_mob_text)
transformed_object = _transformed_object
to_object_text = _to_object_text
to_mob_text = _to_mob_text
put_in_object(TRUE)

/datum/component/object_transform/proc/swap_object(new_object)
. = transformed_object
var/mob/owner = parent
if(parent in transformed_object.contents)
owner.forceMove(transformed_object.loc)
transformed_object = new_object
put_in_object()

/datum/component/object_transform/proc/put_in_object(silent = FALSE)
var/mob/owner = parent
transformed_object.forceMove(owner.loc)
owner.forceMove(transformed_object)
if(!silent && length(to_object_text))
owner.visible_message("<b>[owner]</b> [to_object_text]")

/datum/component/object_transform/proc/put_in_mob(silent = FALSE)
var/mob/owner = parent
owner.forceMove(transformed_object.loc)
transformed_object.forceMove(parent)
if(!silent && length(to_mob_text))
owner.visible_message("<b>[owner]</b> [to_mob_text]")

49 changes: 22 additions & 27 deletions code/modules/mob/living/silicon/pai/mobility.dm
Original file line number Diff line number Diff line change
@@ -1,36 +1,28 @@
/mob/living/silicon/pai/restrained()
if(istype(src.loc,/obj/item/paicard))
if(src.loc == shell)
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)
// we can't close up if already inside our shell
if(src.loc == shell)
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)
// Move us into the shell and move the shell to the ground.
transform_component.put_in_object()

update_perspective()
set_resting(FALSE)
update_mobility()
Expand All @@ -40,34 +32,37 @@
/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))
// stops unfolding in hardsuits and vore bellies, if implanted you explode out
if(istype(shell.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)
else if(istype(shell.loc,/mob))
var/mob/holder = shell.loc
var/datum/belly/inside_belly = check_belly(shell)
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)
if(shell in affecting.implants)
affecting.take_damage(rand(30,50))
affecting.implants -= card
affecting.implants -= shell
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.drop_item_to_ground(shell, INV_OP_FORCE)
else if(istype(shell.loc,/obj/item/pda))
var/obj/item/pda/holder = shell.loc
holder.pai = null

forceMove(card.loc)
card.forceMove(src)
// handle the actual object stuffing via the component
transform_component.put_in_mob()

update_perspective()

card.screen_loc = null
var/obj/item/paicard/card = shell
if(istype(card))
card.screen_loc = null

var/turf/T = get_turf(src)
if(istype(T))
Expand Down
46 changes: 41 additions & 5 deletions code/modules/mob/living/silicon/pai/pai.dm
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,8 @@
var/ram = 100 // Used as currency to purchase different abilities
var/list/software = list()
var/userDNA // The DNA string of our assigned user
var/obj/item/paicard/card // The card we inhabit
var/obj/item/shell // The shell we inhabit
var/obj/item/paicard/card // The card we belong to, it is not always our shell, but it is linked to us regardless
var/obj/item/radio/radio // Our primary radio
var/obj/item/communicator/integrated/communicator // Our integrated communicator.
var/obj/item/pda/ai/pai/pda = null // Our integrated PDA
Expand Down Expand Up @@ -105,14 +106,20 @@
// space movement related
var/last_space_movement = 0

// transformation component
var/datum/component/object_transform/transform_component

/mob/living/silicon/pai/Initialize(mapload)
. = ..()
card = loc
shell = loc
if(istype(shell, /obj/item/paicard))
card = loc
sradio = new(src)
communicator = new(src)
if(card)
if(!card.radio)
card.radio = new /obj/item/radio(src.card)
if(shell)
transform_component = AddComponent(/datum/component/object_transform, shell, "neatly folds inwards, compacting down to a rectangular card", "folds outwards, expanding into a mobile form.")
if(card && !card.radio)
card.radio = new /obj/item/radio(src.card)
radio = card.radio

add_verb(src, /mob/living/silicon/pai/proc/choose_chassis)
Expand Down Expand Up @@ -199,3 +206,32 @@
new_people_eaten += M.size_multiplier
people_eaten = min(1, new_people_eaten)

// changing the shell
/mob/living/silicon/pai/proc/switch_shell(var/obj/item/new_shell)
// we're on cooldown or we are dead
if(!can_action())
return FALSE

last_special = world.time + 20

// setup transform text
if(istype(new_shell, /obj/item/paicard))
transform_component.to_object_text = "neatly folds inwards, compacting down to a rectangular card"
else
transform_component.to_object_text = "neatly folds inwards, compacting down into their shell"

// swap the shell, if the old shell is our card we keep it, otherwise we delete it because it's not important
shell = new_shell
var/obj/item/old_shell = transform_component.swap_object(new_shell)
if(istype(old_shell, /obj/item/paicard))
old_shell.forceMove(src)
else
QDEL_NULL(old_shell)

// some sanity stuff because this is also putting us inside an object so we want to interrupt a couple of possible things such as pulling, resting, eating, viewing camera
release_vore_contents()
stop_pulling()
update_perspective()
set_resting(FALSE)
update_mobility()
remove_verb(src, /mob/living/silicon/pai/proc/pai_nom)
6 changes: 3 additions & 3 deletions code/modules/mob/living/silicon/pai/verbs.dm
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
if(!can_action())
return
// to fold out we need to be in the card
if(src.loc != card)
if(src.loc != shell)
return

open_up()
Expand All @@ -22,7 +22,7 @@
if(!can_action())
return
// to fold up we need to not be in the card already
if(src.loc == card)
if(src.loc == shell)
return

close_up()
Expand Down Expand Up @@ -66,7 +66,7 @@
set category = "IC"

// Pass lying down or getting up to our pet human, if we're in a hardsuit.
if(istype(src.loc,/obj/item/paicard))
if(src.loc == shell)
set_resting(FALSE)
var/obj/item/hardsuit/hardsuit = src.get_hardsuit()
if(istype(hardsuit))
Expand Down

0 comments on commit 062dd60

Please sign in to comment.