Skip to content

Commit

Permalink
Fixes an issue with station pets and the multiple_lives component (tg…
Browse files Browse the repository at this point in the history
…station#64783)

* Fixes an issue with the multiple_lives component

* Ah yes, suicide cases.

* rephrases a sentence
  • Loading branch information
Ghommie committed Feb 18, 2022
1 parent abc13fb commit 4ed169b
Show file tree
Hide file tree
Showing 8 changed files with 49 additions and 6 deletions.
4 changes: 4 additions & 0 deletions code/__DEFINES/dcs/signals/signals_mob/signals_mob_living.dm
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,10 @@
///from base of mob/living/death(): (gibbed)
#define COMSIG_LIVING_DEATH "living_death"

///from base of mob/living/Write_Memory(): (dead, gibbed)
#define COMSIG_LIVING_WRITE_MEMORY "living_write_memory"
#define COMPONENT_DONT_WRITE_MEMORY (1<<0)

/// from /proc/healthscan(): (list/scan_results, advanced, mob/user, mode)
/// Consumers are allowed to mutate the scan_results list to add extra information
#define COMSIG_LIVING_HEALTHSCAN "living_healthscan"
Expand Down
4 changes: 4 additions & 0 deletions code/__DEFINES/traits.dm
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,8 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai
#define TRAIT_SPARRING "sparring"
/// The user is currently challenging an elite mining mob. Prevents him from challenging another until he's either lost or won.
#define TRAIT_ELITE_CHALLENGER "elite_challenger"
/// For living mobs. It signals that the mob shouldn't have their data written in an external json for persistence.
#define TRAIT_DONT_WRITE_MEMORY "dont_write_memory"

#define TRAIT_NOBLEED "nobleed" //This carbon doesn't bleed
/// This atom can ignore the "is on a turf" check for simple AI datum attacks, allowing them to attack from bags or lockers as long as any other conditions are met
Expand Down Expand Up @@ -767,6 +769,8 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai
#define DRONE_SHY_TRAIT "drone_shy"
/// Pacifism trait given by stabilized light pink extracts.
#define STABILIZED_LIGHT_PINK_TRAIT "stabilized_light_pink"
/// Given by the multiple_lives component to the previous body of the mob upon death.
#define EXPIRED_LIFE_TRAIT "expired_life"
/// Trait given to a ghost when they orbit something.
#define GHOST_ORBITING_TRAIT "ghost_orbiting"

Expand Down
11 changes: 10 additions & 1 deletion code/datums/components/multiple_lives.dm
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,24 @@
/datum/component/multiple_lives/RegisterWithParent()
RegisterSignal(parent, COMSIG_LIVING_DEATH, .proc/respawn)
RegisterSignal(parent, COMSIG_PARENT_EXAMINE, .proc/on_examine)
RegisterSignal(parent, COMSIG_LIVING_WRITE_MEMORY, .proc/on_write_memory)

/datum/component/multiple_lives/UnregisterFromParent()
UnregisterSignal(parent, list(COMSIG_LIVING_DEATH, COMSIG_PARENT_EXAMINE))
UnregisterSignal(parent, list(COMSIG_LIVING_DEATH, COMSIG_PARENT_EXAMINE, COMSIG_LIVING_WRITE_MEMORY))

/// Stops a dying station pet from overriding persistence data before we respawn it and thus causing issues.
/datum/component/multiple_lives/proc/on_write_memory(mob/living/source, dead, gibbed)
if(dead && !source.suiciding)
return COMPONENT_DONT_WRITE_MEMORY

/datum/component/multiple_lives/proc/respawn(mob/living/source, gibbed)
SIGNAL_HANDLER
if(source.suiciding) //Freed from this mortail coil.
qdel(src)
return
//Gives the old mob this trait in case it gets revived, so we won't end up eventually overriding data
//that would be read by the current holder when he respawns if the old corpse is ever revived.
ADD_TRAIT(source, TRAIT_DONT_WRITE_MEMORY, EXPIRED_LIFE_TRAIT)
var/mob/living/respawned_mob = new source.type (source.drop_location())
source.mind?.transfer_to(respawned_mob)
lives_left--
Expand Down
5 changes: 4 additions & 1 deletion code/modules/mob/living/carbon/human/monkey/monkey.dm
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,10 @@
relic_hat = json["relic_hat"]
relic_mask = json["relic_hat"]

/mob/living/carbon/human/species/monkey/punpun/proc/Write_Memory(dead, gibbed)
/mob/living/carbon/human/species/monkey/punpun/Write_Memory(dead, gibbed)
. = ..()
if(!.)
return
var/json_file = file("data/npc_saves/Punpun.json")
var/list/file_data = list()
if(gibbed)
Expand Down
14 changes: 14 additions & 0 deletions code/modules/mob/living/living.dm
Original file line number Diff line number Diff line change
Expand Up @@ -2196,3 +2196,17 @@
span_userdanger("You're thrown violently into [lattice], smashing through it and punching straight through!"))
apply_damage(rand(5,10), BRUTE, BODY_ZONE_CHEST)
lattice.deconstruct(FALSE)

/**
* Proc used by different station pets such as Ian and Poly so that some of their data can persist between rounds.
* This base definition only contains a trait and comsig to stop memory from being (over)written.
* Specific behavior is defined on subtypes that use it.
*/
/mob/living/proc/Write_Memory(dead, gibbed)
SHOULD_CALL_PARENT(TRUE)
if(HAS_TRAIT(src, TRAIT_DONT_WRITE_MEMORY)) //always prevent data from being written.
return FALSE
// for selective behaviors that may or may not prevent data from being written.
if(SEND_SIGNAL(src, COMSIG_LIVING_WRITE_MEMORY, dead, gibbed) & COMPONENT_DONT_WRITE_MEMORY)
return FALSE
return TRUE
7 changes: 5 additions & 2 deletions code/modules/mob/living/simple_animal/friendly/cat.dm
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@
unique_pet = TRUE
var/list/family = list()//var restored from savefile, has count of each child type
var/list/children = list()//Actual mob instances of children
var/cats_deployed = 0
var/static/cats_deployed = 0
var/memory_saved = FALSE
held_state = "cat"

Expand Down Expand Up @@ -158,7 +158,10 @@
if(isnull(family))
family = list()

/mob/living/simple_animal/pet/cat/runtime/proc/Write_Memory(dead)
/mob/living/simple_animal/pet/cat/runtime/Write_Memory(dead, gibbed)
. = ..()
if(!.)
return
var/json_file = file("data/npc_saves/Runtime.json")
var/list/file_data = list()
family = list()
Expand Down
5 changes: 4 additions & 1 deletion code/modules/mob/living/simple_animal/friendly/dog.dm
Original file line number Diff line number Diff line change
Expand Up @@ -525,7 +525,10 @@ GLOBAL_LIST_INIT(strippable_corgi_items, create_strippable_list(list(
if(saved_head)
place_on_head(new saved_head)

/mob/living/simple_animal/pet/dog/corgi/ian/proc/Write_Memory(dead)
/mob/living/simple_animal/pet/dog/corgi/ian/Write_Memory(dead, gibbed)
. = ..()
if(!.)
return
var/json_file = file("data/npc_saves/Ian.json")
var/list/file_data = list()
if(!dead)
Expand Down
5 changes: 4 additions & 1 deletion code/modules/mob/living/simple_animal/parrot.dm
Original file line number Diff line number Diff line change
Expand Up @@ -952,7 +952,10 @@ GLOBAL_LIST_INIT(strippable_parrot_items, create_strippable_list(list(
if(!islist(speech_buffer))
speech_buffer = list()

/mob/living/simple_animal/parrot/poly/proc/Write_Memory(dead)
/mob/living/simple_animal/parrot/poly/Write_Memory(dead, gibbed)
. = ..()
if(!.)
return
var/json_file = file("data/npc_saves/Poly.json")
var/list/file_data = list()
if(islist(speech_buffer))
Expand Down

0 comments on commit 4ed169b

Please sign in to comment.