diff --git a/code/__DEFINES/traits/declarations.dm b/code/__DEFINES/traits/declarations.dm index 96642ba3b4c..0f6a4ea6c2e 100644 --- a/code/__DEFINES/traits/declarations.dm +++ b/code/__DEFINES/traits/declarations.dm @@ -1576,4 +1576,7 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai /// Trait specifying that an AI has a remote connection to an integrated circuit #define TRAIT_CONNECTED_TO_CIRCUIT "connected_to_circuit" +/// Mob is artificially spawned rather than being created through more natural means - applied to monkey cubes and such +#define TRAIT_SPAWNED_MOB "spawned_mob" + // END TRAIT DEFINES diff --git a/code/_globalvars/traits/_traits.dm b/code/_globalvars/traits/_traits.dm index d7d8a36a459..288e055d535 100644 --- a/code/_globalvars/traits/_traits.dm +++ b/code/_globalvars/traits/_traits.dm @@ -537,11 +537,12 @@ GLOBAL_LIST_INIT(traits_by_type, list( "TRAIT_SNEAK" = TRAIT_SNEAK, "TRAIT_SNOB" = TRAIT_SNOB, "TRAIT_SOFTSPOKEN" = TRAIT_SOFTSPOKEN, - "TRAIT_SOOTHED_THROAT" = TRAIT_SOOTHED_THROAT, "TRAIT_SOOTHED_HEADACHE" = TRAIT_SOOTHED_HEADACHE, + "TRAIT_SOOTHED_THROAT" = TRAIT_SOOTHED_THROAT, "TRAIT_SOUND_DEBUGGED" = TRAIT_SOUND_DEBUGGED, "TRAIT_SPACEWALK" = TRAIT_SPACEWALK, "TRAIT_SPARRING" = TRAIT_SPARRING, + "TRAIT_SPAWNED_MOB" = TRAIT_SPAWNED_MOB, "TRAIT_SPEAKS_CLEARLY" = TRAIT_SPEAKS_CLEARLY, "TRAIT_SPECIAL_TRAUMA_BOOST" = TRAIT_SPECIAL_TRAUMA_BOOST, "TRAIT_SPELLS_LOTTERY" = TRAIT_SPELLS_LOTTERY, diff --git a/code/datums/mood_events/generic_negative_events.dm b/code/datums/mood_events/generic_negative_events.dm index 56bb17a1b86..0ca1b52a55c 100644 --- a/code/datums/mood_events/generic_negative_events.dm +++ b/code/datums/mood_events/generic_negative_events.dm @@ -570,9 +570,12 @@ /datum/mood_event/see_death/add_effects(mob/dead_mob) if(isnull(dead_mob)) return + if(HAS_TRAIT(dead_mob, TRAIT_SPAWNED_MOB)) + mood_change *= 0.25 + timeout *= 0.2 if(HAS_TRAIT(owner, TRAIT_CULT_HALO) && !HAS_TRAIT(dead_mob, TRAIT_CULT_HALO)) // When cultists get halos, they stop caring about death - mood_change = 4 + mood_change *= -0.5 description = "More souls for the Geometer!" return @@ -603,9 +606,9 @@ description = replacetext(normal_message, "%DEAD_MOB%", get_descriptor(dead_mob)) -/datum/mood_event/see_death/be_refreshed(datum/mood/home, ...) +/datum/mood_event/see_death/be_refreshed(datum/mood/home, mob/dead_mob, ...) // Every time we get refreshed we get worse if not desensitized - if(!HAS_TRAIT(owner, TRAIT_DESENSITIZED)) + if(!HAS_TRAIT(owner, TRAIT_DESENSITIZED) && !HAS_TRAIT(dead_mob, TRAIT_SPAWNED_MOB)) mood_change *= 1.5 return ..() diff --git a/code/game/machinery/syndicatebomb.dm b/code/game/machinery/syndicatebomb.dm index 224345a8f6d..e866fbd84df 100644 --- a/code/game/machinery/syndicatebomb.dm +++ b/code/game/machinery/syndicatebomb.dm @@ -446,7 +446,8 @@ /obj/item/bombcore/badmin/summon/detonate() var/obj/machinery/syndicatebomb/B = loc - spawn_and_random_walk(summon_path, src, amt_summon, walk_chance=50, admin_spawn=TRUE, cardinals_only = FALSE) + for(var/atom/spawned as anything in spawn_and_random_walk(summon_path, src, amt_summon, walk_chance=50, admin_spawn=TRUE, cardinals_only = FALSE)) + ADD_TRAIT(spawned, TRAIT_SPAWNED_MOB, INNATE_TRAIT) qdel(B) qdel(src) diff --git a/code/game/objects/items/food/monkeycube.dm b/code/game/objects/items/food/monkeycube.dm index bfb9ccc0f4e..e2f79791817 100644 --- a/code/game/objects/items/food/monkeycube.dm +++ b/code/game/objects/items/food/monkeycube.dm @@ -31,6 +31,7 @@ var/mob/spammer = get_mob_by_key(fingerprintslast) var/mob/living/bananas = new spawned_mob(drop_location(), TRUE, spammer) // funny that we pass monkey init args to non-monkey mobs, that's totally a future issue if (!QDELETED(bananas)) + ADD_TRAIT(bananas, TRAIT_SPAWNED_MOB, INNATE_TRAIT) if(faction) bananas.faction = faction diff --git a/code/game/objects/items/grenades/spawnergrenade.dm b/code/game/objects/items/grenades/spawnergrenade.dm index e479d7d818a..0c796267578 100644 --- a/code/game/objects/items/grenades/spawnergrenade.dm +++ b/code/game/objects/items/grenades/spawnergrenade.dm @@ -29,6 +29,8 @@ // Spawn some hostile syndicate critters and spread them out var/list/spawned = spawn_and_random_walk(spawner_type, target_turf, deliveryamt, walk_chance = 50, admin_spawn = ((flags_1 & ADMIN_SPAWNED_1) ? TRUE : FALSE)) afterspawn(spawned) + for(var/mob/living/created as anything in spawned) + ADD_TRAIT(created, TRAIT_SPAWNED_MOB, INNATE_TRAIT) qdel(src) diff --git a/code/modules/antagonists/cult/runes.dm b/code/modules/antagonists/cult/runes.dm index 2adffa36596..c0ba25c2b6a 100644 --- a/code/modules/antagonists/cult/runes.dm +++ b/code/modules/antagonists/cult/runes.dm @@ -1025,7 +1025,7 @@ GLOBAL_VAR_INIT(narsie_summon_count, 0) new_human.equipOutfit(/datum/outfit/ghost_cultist) //give them armor new_human.apply_status_effect(/datum/status_effect/cultghost) //ghosts can't summon more ghosts new_human.set_invis_see(SEE_INVISIBLE_OBSERVER) - new_human.add_traits(list(TRAIT_NOBREATH, TRAIT_PERMANENTLY_MORTAL), INNATE_TRAIT) // permanently mortal can be removed once this is a bespoke kind of mob + new_human.add_traits(list(TRAIT_NOBREATH, TRAIT_SPAWNED_MOB, TRAIT_PERMANENTLY_MORTAL), INNATE_TRAIT) // permanently mortal can be removed once this is a bespoke kind of mob ghosts++ playsound(src, 'sound/effects/magic/exit_blood.ogg', 50, TRUE) visible_message(span_warning("A cloud of red mist forms above [src], and from within steps... a [new_human.gender == FEMALE ? "wo":""]man.")) diff --git a/code/modules/reagents/chemistry/recipes.dm b/code/modules/reagents/chemistry/recipes.dm index 01250e80bf0..f1b3dfdbff2 100644 --- a/code/modules/reagents/chemistry/recipes.dm +++ b/code/modules/reagents/chemistry/recipes.dm @@ -230,6 +230,7 @@ else spawned_mob = new mob_class(get_turf(holder.my_atom))//Spawn our specific mob_class spawned_mob.faction |= mob_faction + ADD_TRAIT(spawned_mob, TRAIT_SPAWNED_MOB, INNATE_TRAIT) if(prob(50)) for(var/j in 1 to rand(1, 3)) step(spawned_mob, pick(NORTH,SOUTH,EAST,WEST)) diff --git a/code/modules/recycling/disposal/bin.dm b/code/modules/recycling/disposal/bin.dm index 050ebad7e9b..53c68cc241b 100644 --- a/code/modules/recycling/disposal/bin.dm +++ b/code/modules/recycling/disposal/bin.dm @@ -172,6 +172,7 @@ GLOBAL_VAR_INIT(disposals_animals_spawned, 0) var/rat_cap = CONFIG_GET(number/ratcap) if (LAZYLEN(SSmobs.cheeserats) < rat_cap && prob(33)) var/mob/living/basic/mouse/new_subject = new(king.drop_location()) + ADD_TRAIT(new_subject, TRAIT_SPAWNED_MOB, INNATE_TRAIT) playsound(new_subject, 'sound/mobs/non-humanoids/mouse/mousesqueek.ogg', 100) visible_message(span_warning("[new_subject] climbs out of [src]!")) diff --git a/code/modules/research/xenobiology/xenobio_camera.dm b/code/modules/research/xenobiology/xenobio_camera.dm index 518adc09566..960fa43a61c 100644 --- a/code/modules/research/xenobiology/xenobio_camera.dm +++ b/code/modules/research/xenobiology/xenobio_camera.dm @@ -262,6 +262,7 @@ if (QDELETED(food)) return food.apply_status_effect(/datum/status_effect/slime_food, user) + ADD_TRAIT(food, TRAIT_SPAWNED_MOB, INNATE_TRAIT) stored_monkeys-- stored_monkeys = round(stored_monkeys, 0.1) //Prevents rounding errors diff --git a/code/modules/spells/spell_types/conjure/_conjure.dm b/code/modules/spells/spell_types/conjure/_conjure.dm index 5501f1055ca..cfc10f3e27d 100644 --- a/code/modules/spells/spell_types/conjure/_conjure.dm +++ b/code/modules/spells/spell_types/conjure/_conjure.dm @@ -58,6 +58,7 @@ var/atom/summoned_object = new summoned_object_type(spawn_place) summoned_object.flags_1 |= ADMIN_SPAWNED_1 + ADD_TRAIT(summoned_object, TRAIT_SPAWNED_MOB, INNATE_TRAIT) if(summon_lifespan > 0) QDEL_IN(summoned_object, summon_lifespan)