diff --git a/code/__DEFINES/is_helpers.dm b/code/__DEFINES/is_helpers.dm
index 8df9e3ae6c7..6a51b057434 100644
--- a/code/__DEFINES/is_helpers.dm
+++ b/code/__DEFINES/is_helpers.dm
@@ -125,6 +125,10 @@ GLOBAL_LIST_INIT(turfs_without_ground, typecacheof(list(
#define ishostile(A) (istype(A, /mob/living/simple_animal/hostile))
+#define israt(A) (istype(A, /mob/living/simple_animal/hostile/rat))
+
+#define isregalrat(A) (istype(A, /mob/living/simple_animal/hostile/regalrat))
+
#define isswarmer(A) (istype(A, /mob/living/simple_animal/hostile/swarmer))
#define isguardian(A) (istype(A, /mob/living/simple_animal/hostile/guardian))
diff --git a/code/controllers/subsystem/minor_mapping.dm b/code/controllers/subsystem/minor_mapping.dm
index 30e06472fe3..eca7502c0ca 100644
--- a/code/controllers/subsystem/minor_mapping.dm
+++ b/code/controllers/subsystem/minor_mapping.dm
@@ -1,3 +1,5 @@
+#define PROB_MOUSE_SPAWN 98
+
SUBSYSTEM_DEF(minor_mapping)
name = "Minor Mapping"
init_order = INIT_ORDER_MINOR_MAPPING
@@ -11,15 +13,18 @@ SUBSYSTEM_DEF(minor_mapping)
/datum/controller/subsystem/minor_mapping/proc/trigger_migration(num_mice=10)
var/list/exposed_wires = find_exposed_wires()
- var/mob/living/simple_animal/mouse/M
+ var/mob/living/simple_animal/M
var/turf/proposed_turf
while((num_mice > 0) && exposed_wires.len)
proposed_turf = pick_n_take(exposed_wires)
- if(!M)
- M = new(proposed_turf)
+ if(prob(PROB_MOUSE_SPAWN))
+ if(!M)
+ M = new(proposed_turf)
+ else
+ M.forceMove(proposed_turf)
else
- M.forceMove(proposed_turf)
+ M = new /mob/living/simple_animal/hostile/regalrat/controlled(proposed_turf)
if(M.environment_air_is_safe())
num_mice -= 1
M = null
@@ -57,3 +62,5 @@ SUBSYSTEM_DEF(minor_mapping)
suitable += t
return shuffle(suitable)
+
+#undef PROB_MOUSE_SPAWN
diff --git a/code/modules/assembly/mousetrap.dm b/code/modules/assembly/mousetrap.dm
index a4febbaecaa..c05dbded620 100644
--- a/code/modules/assembly/mousetrap.dm
+++ b/code/modules/assembly/mousetrap.dm
@@ -62,6 +62,13 @@
var/mob/living/simple_animal/mouse/M = target
visible_message("SPLAT!")
M.splat()
+ else if(israt(target))
+ var/mob/living/simple_animal/hostile/rat/ratt = target
+ visible_message("Clink!")
+ ratt.apply_damage(5) //Not lethal, but just enought to make a mark.
+ ratt.Stun(1 SECONDS)
+ else if(isregalrat(target))
+ visible_message("Skreeeee!") //He's simply too large to be affected by a tiny mouse trap.
playsound(src, 'sound/effects/snap.ogg', 50, TRUE)
armed = FALSE
update_icon()
diff --git a/code/modules/mob/living/simple_animal/friendly/mouse.dm b/code/modules/mob/living/simple_animal/friendly/mouse.dm
index b2213d575df..476a911f09b 100644
--- a/code/modules/mob/living/simple_animal/friendly/mouse.dm
+++ b/code/modules/mob/living/simple_animal/friendly/mouse.dm
@@ -136,7 +136,7 @@
*Spawns a new regal rat, says some good jazz, and if sentient, transfers the relivant mind.
*/
/mob/living/simple_animal/mouse/proc/evolve()
- var/mob/living/simple_animal/hostile/regalrat = new /mob/living/simple_animal/hostile/regalrat(loc)
+ var/mob/living/simple_animal/hostile/regalrat/regalrat = new /mob/living/simple_animal/hostile/regalrat/controlled(loc)
visible_message("[src] devours the cheese! He morphs into something... greater!")
regalrat.say("RISE, MY SUBJECTS! SCREEEEEEE!")
if(mind)
diff --git a/code/modules/mob/living/simple_animal/hostile/regalrat.dm b/code/modules/mob/living/simple_animal/hostile/regalrat.dm
index a5f62f453b1..c250b8700a3 100644
--- a/code/modules/mob/living/simple_animal/hostile/regalrat.dm
+++ b/code/modules/mob/living/simple_animal/hostile/regalrat.dm
@@ -1,5 +1,9 @@
+#define MINOR_HEAL 10
+#define MEDIUM_HEAL 35
+#define MAJOR_HEAL 70
+
/mob/living/simple_animal/hostile/regalrat
- name = "regal rat"
+ name = "feral regal rat"
desc = "An evolved rat, created through some strange science. It leads nearby rats with deadly efficiency to protect its kingdom. Not technically a king."
icon_state = "regalrat"
icon_living = "regalrat"
@@ -26,9 +30,10 @@
ventcrawler = VENTCRAWLER_ALWAYS
unique_name = TRUE
faction = list("rat")
+ ///The spell that the rat uses to scrounge up junk.
var/datum/action/cooldown/coffer
+ ///The Spell that the rat uses to recruit/convert more rats.
var/datum/action/cooldown/riot
- ///Number assigned to rats and mice, checked when determining infighting.
/mob/living/simple_animal/hostile/regalrat/Initialize()
. = ..()
@@ -36,7 +41,7 @@
riot = new /datum/action/cooldown/riot
coffer.Grant(src)
riot.Grant(src)
- INVOKE_ASYNC(src, .proc/get_player)
+ AddElement(/datum/element/waddling)
/mob/living/simple_animal/hostile/regalrat/proc/get_player()
var/list/mob/dead/observer/candidates = pollGhostCandidates("Do you want to play as the Royal Rat, cheesey be his crown?", ROLE_SENTIENCE, null, FALSE, 100, POLL_IGNORE_SENTIENCE_POTION)
@@ -44,6 +49,7 @@
var/mob/dead/observer/C = pick(candidates)
key = C.key
notify_ghosts("All rise for the rat king, ascendant to the throne in \the [get_area(src)].", source = src, action = NOTIFY_ORBIT, flashwindow = FALSE, header = "Sentient Rat Created")
+ to_chat(src, "You are an independent, invasive force on the station! Horde coins, trash, cheese, and the like from the safety of darkness!")
/mob/living/simple_animal/hostile/regalrat/handle_automated_action()
if(prob(20))
@@ -78,13 +84,32 @@
/mob/living/simple_animal/hostile/regalrat/AttackingTarget()
. = ..()
+ if(health >= maxHealth)
+ to_chat(src, "You feel fine, no need to eat anything!")
+ return
if(istype(target, /obj/item/reagent_containers/food/snacks/cheesewedge))
- if (health >= maxHealth)
- to_chat(src, "You feel fine, no need to eat anything!")
- return
- to_chat(src, "You eat \the [src], restoring some health.")
- heal_bodypart_damage(10)
+ to_chat(src, "You eat [src], restoring some health.")
+ heal_bodypart_damage(MINOR_HEAL)
qdel(target)
+ return
+ if(istype(target, /obj/item/reagent_containers/food/snacks/store/cheesewheel))
+ to_chat(src, "You eat [src], restoring some health.")
+ heal_bodypart_damage(MEDIUM_HEAL)
+ qdel(target)
+ return
+ if(istype(target, /obj/item/reagent_containers/food/snacks/royalcheese))
+ to_chat(src, "You eat [src], revitalizing your royal resolve completely.")
+ heal_bodypart_damage(MAJOR_HEAL)
+ qdel(target)
+ return
+
+/mob/living/simple_animal/hostile/regalrat/controlled
+ name = "regal rat"
+
+/mob/living/simple_animal/hostile/regalrat/controlled/Initialize()
+ . = ..()
+ INVOKE_ASYNC(src, .proc/get_player)
+
/**
*This action creates trash, money, dirt, and cheese.
@@ -202,6 +227,12 @@
return ..()
/mob/living/simple_animal/hostile/rat/death(gibbed)
+ if(!ckey)
+ ..(TRUE)
+ if(!gibbed)
+ var/obj/item/reagent_containers/food/snacks/deadmouse/mouse = new(loc)
+ mouse.icon_state = icon_dead
+ mouse.name = name
SSmobs.cheeserats -= src // remove rats on death
return ..()
@@ -270,5 +301,9 @@
to_chat(src, "You feel fine, no need to eat anything!")
return
to_chat(src, "You eat \the [src], restoring some health.")
- heal_bodypart_damage(5)
+ heal_bodypart_damage(MINOR_HEAL)
qdel(target)
+
+#undef MINOR_HEAL
+#undef MEDIUM_HEAL
+#undef MAJOR_HEAL