Artifically spawned mobs have a vastly reduced penalty for death moodlet (#93348)

## About The Pull Request

Closes #93285

Mood event from the death of a mob spawned "artificially" is 75% weaker,
lasts 80% the duration, and don't compound

An artificial monkey's death will now result 
- -8 * 0.25 * 0.5 = floor(1) = 1 strength moodlet for the average crew
member
   - ...Lasting 30 seconds (unless refreshed)
- -8 * 0.25 * 1.5 = floor(3) = 3 strength moodlet for animal friends
   - ...Lasting 1.5 minutes (unless refreshed)
- -8 * 0.25 = floor(2) = 2 strength moodlet for compassionate crew
members
   - ...Lasting 1 minute (unless refreshed)

Artifical spawning includes
- Moneky Cube
- Xenobiology Console
- "Life" reaction
- Summoned rats
- Spawner grenades
- Cult ghosts

Lemmie know if I'm missing any obvious spawns 

## Why It's Good For The Game

While funny it was not my intention to have Xenobiology / Genetics /
Virology nuke your mood.

## Changelog

🆑 Melbert
balance: Death of artifical mobs (such as monkey cube monkeys) result in
a 75% weaker, 80% shorter moodlet that does not compound with more
deaths.
/🆑
This commit is contained in:
MrMelbert
2025-10-11 00:14:54 +02:00
committed by GitHub
parent 8979fe249f
commit 0800c75540
11 changed files with 21 additions and 6 deletions
+3
View File
@@ -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
+2 -1
View File
@@ -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,
@@ -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 ..()
+2 -1
View File
@@ -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)
@@ -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
@@ -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)
+1 -1
View File
@@ -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."))
@@ -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))
+1
View File
@@ -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]!"))
@@ -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
@@ -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)