[MIRROR] Fixes an issue with station pets and the multiple_lives component [MDB IGNORE] (#11576)

* Fixes an issue with station pets and the multiple_lives component (#64783)

* Fixes an issue with the multiple_lives component

* Ah yes, suicide cases.

* rephrases a sentence

* Fixes an issue with station pets and the multiple_lives component

Co-authored-by: Ghom <42542238+Ghommie@users.noreply.github.com>
This commit is contained in:
SkyratBot
2022-02-18 18:25:48 -05:00
committed by GitHub
co-authored by Ghom
parent c576720516
commit aea9388a4d
8 changed files with 49 additions and 6 deletions
@@ -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"
+4
View File
@@ -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
@@ -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"
+10 -1
View File
@@ -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--
@@ -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)
+14
View File
@@ -2259,3 +2259,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
@@ -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"
@@ -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()
@@ -530,7 +530,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)
@@ -953,7 +953,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))