Polymorph belt plays nicely with mob evolution (#94723)

## About The Pull Request

Fixes #82319
Fixes #94129

If your mob type changes while you are transformed via the polymorph
belt, it will transfer the polymorph status to the new mob.
This means that turning into a Bileworm after Bileworms have evolved
will no longer ghost you, and instead you will just keep playing as a
vileworm.
Additionally it means if you copy a chick, spiderling, juvenile lobster,
and walk around as one of those for long enough to grow up, it will
seamlessly move you over.
Or if you turn into a mouse and a nearby regal rat uses their riot
ability it will transform you into a rat, etc.

If you change back into a human and then change back into your mob you
will return to the original state though.

I decided to put this on a new subtype of the status effect rather than
the base type because I think it's more of a programming issue if this
happens for an ability with a fixed transform type (and we wouldn't want
to mutate the possible shapes list in that case), so in those cases we
should keep the existing behaviour of just untransforming you.

Additionally, I made the evolutionary leap component always wait a
minimum of three seconds instead of being instant before transforming a
mob. This means that other things have time to register signals and
react to the transformation, so you should never be deleted by bileworm
evolution any more.

## Why It's Good For The Game

This fixes a few long-standing bugs and seems more fun than
untransforming you.

## Changelog

🆑
fix: If you use the polymorph belt to turn into a mob which transforms
into another mob, it won't ghost you or kick you out upon
transformation.
/🆑
This commit is contained in:
Jacquerel
2026-01-07 21:00:41 -07:00
committed by GitHub
parent aa3209be7a
commit 190904b5bb
3 changed files with 30 additions and 8 deletions
+4 -5
View File
@@ -23,9 +23,9 @@
RegisterSignal(SSticker, COMSIG_TICKER_ROUND_STARTING, PROC_REF(comp_on_round_start))
return
//if the round has already taken long enough, just leap right away.
//if the round has already taken long enough, evolve in three seconds.
if((world.time - SSticker.round_start_time) > evolve_mark)
leap(silent = TRUE)
addtimer(CALLBACK(src, PROC_REF(leap)), 3 SECONDS, TIMER_DELETE_ME)
return
setup_timer()
@@ -49,12 +49,11 @@
var/mark = evolve_mark - sum
timer_id = addtimer(CALLBACK(src, PROC_REF(leap), FALSE), mark, TIMER_STOPPABLE)
/datum/component/evolutionary_leap/proc/leap(silent)
/datum/component/evolutionary_leap/proc/leap()
var/mob/living/old_mob = parent
if (old_mob.stat == DEAD)
return
var/mob/living/new_mob = evolve_path
var/new_mob_name = initial(new_mob.name)
if(!silent)
old_mob.visible_message(span_warning("[old_mob] evolves into \a [new_mob_name]!"))
old_mob.visible_message(span_warning("[old_mob] evolves into \a [new_mob_name]!"))
old_mob.change_mob_type(evolve_path, old_mob.loc, new_name = new_mob_name, delete_old_mob = TRUE)