[EE] Adds a new medium midround event: Irradiated mouse (#31947)

* added irradiated mouse

* mouse pulling buff

* adds upgrade spells

* cooldown on upgrades

* icons and cats

* radioactive sludge, health decrease, upgrades counter

* objectives and sound

* spells to new file + check if alive in life

* afterimage

* description fix, contaminate, comments

* lintma?

* removed empty lines, , -> :, new -> new()

---------

Signed-off-by: Christer2222 <25958019+Christer2222@users.noreply.github.com>
This commit is contained in:
Christer2222
2026-05-13 22:09:02 +00:00
committed by GitHub
parent 93e6c06c1a
commit 2f2ebafb31
12 changed files with 295 additions and 10 deletions
+1
View File
@@ -67,6 +67,7 @@
#define SPECIAL_ROLE_HERETIC "Heretic"
#define SPECIAL_ROLE_EVENTMISC "Event Role"
#define SPECIAL_ROLE_NINJA "Space Ninja"
#define SPECIAL_ROLE_IRRADIATED_MOUSE "Irradiated Mouse"
// Constants used by code which checks the status of nuclear blasts during a
// round, regardless of original game mode, e.g. setting the ending cinematic.
+3
View File
@@ -46,6 +46,7 @@
#define ROLE_GHOST "ghost role"
#define ROLE_ELITE "lavaland elite"
#define ROLE_NINJA "ninja"
#define ROLE_IRRADIATED_MOUSE "irradiated mouse"
#define ROLE_UPLIFTED_PRIMITIVE "uplifted primitive"
// Misc jobban categories
@@ -74,6 +75,8 @@ GLOBAL_LIST_INIT(special_roles_antags, list(
ROLE_MIND_FLAYER,
ROLE_HERETIC,
ROLE_NINJA,
ROLE_IRRADIATED_MOUSE,
ROLE_UPLIFTED_PRIMITIVE,
// UNUSED/BROKEN ANTAGS
// ROLE_HOG_GOD = /datum/game_mode/hand_of_god,
@@ -0,0 +1,188 @@
/datum/event/spawn_irradiated_mouse
name = "Irradiated Mouse Spawn"
noAutoEnd = TRUE
nominal_severity = EVENT_LEVEL_MODERATE
role_weights = list(ASSIGNMENT_CREW = 1, ASSIGNMENT_MEDICAL = 5)
role_requirements = list(ASSIGNMENT_CREW = 10, ASSIGNMENT_MEDICAL = 1)
/datum/event/spawn_irradiated_mouse/start()
INVOKE_ASYNC(src, PROC_REF(spawn_mouse))
/datum/event/spawn_irradiated_mouse/proc/spawn_mouse()
// poll for ghosts
var/list/mob/dead/observer/candidates = SSghost_spawns.poll_candidates("Do you want to play as an irradiated mouse?", ROLE_IRRADIATED_MOUSE, TRUE, source = /mob/living/basic/mouse/irradiated_mouse)
if(!length(candidates))
kill()
return
var/mob/candidate = pick(candidates)
var/obj/vents = get_valid_vent_spawns(TRUE, TRUE, 0) // find an unwelded vent with nobody nearby
if(!length(vents))
message_admins("Warning: No suitable vents detected for spawning an irradiated mouse.")
return
// pick a vent and spawn a mouse inside of it
var/obj/vent = pick(vents)
var/mob/living/basic/mouse/irradiated_mouse/spawned_mouse = new /mob/living/basic/mouse/irradiated_mouse(vent.loc)
spawned_mouse.forceMove(vent)
spawned_mouse.add_ventcrawl(vent)
// put the ghost inside the mouse
spawned_mouse.ckey = candidate.ckey
dust_if_respawnable(spawned_mouse)
// objectives
spawned_mouse.mind = new
spawned_mouse.mind.bind_to(spawned_mouse)
spawned_mouse.mind.set_original_mob(spawned_mouse)
spawned_mouse.mind.wipe_memory()
spawned_mouse.mind.assigned_role = SPECIAL_ROLE_IRRADIATED_MOUSE
spawned_mouse.mind.special_role = SPECIAL_ROLE_IRRADIATED_MOUSE
SSticker.mode.traitors |= spawned_mouse.mind
// start sound + intro message
SEND_SOUND(spawned_mouse, sound('sound/items/geiger/ext1.ogg'))
spawned_mouse.mind.add_mind_objective(/datum/objective/irradiated_mouse_objective)
spawned_mouse.give_intro_text()
/datum/objective/irradiated_mouse_objective
explanation_text = "Enjoy the remainder of your life the best you can! Whether by gorging on cheese, pestering the crew or exploring the station."
completed = TRUE
needs_target = FALSE
/mob/living/basic/mouse/irradiated_mouse
desc = "It's a small, disease-ridden rodent... Thats glowing?"
maxHealth = 150
health = 150
butcher_results = list(/obj/item/food/meat = 1, /obj/item/stack/sheet/mineral/uranium = 1)
gold_core_spawnable = NO_SPAWN
minimum_survivable_temperature = 0
initial_traits = list(TRAIT_SHOCKIMMUNE, TRAIT_AI_PAUSED, TRAIT_RADIMMUNE) // shock immune so you can chew on those yummy wires
mouse_color = "green"
icon_state = "mouse_green"
a_intent = INTENT_HARM
var/available_upgrades = 0
var/upgrade_cooldown_in_seconds = 120
var/radiation_upgrades = 0
var/speed_upgrades = 0
var/damage_upgrades = 0
var/level_cap = 3
var/alpha_rad = 0
var/beta_rad = 0
var/gamma_rad = 0
var/alpha_rad_per_level = 500
var/beta_rad_per_level = 500
var/gamma_rad_per_level = 0
var/radiation_cooldown = 0.1
var/produce_radioactive_sludge = FALSE
var/speed_per_level = -0.5
var/speed_capstone_alpha = 50
var/has_exited_vents = FALSE
var/seconds_time_till_death = 60 * 15
var/datum/spell/irradiated_mouse_spell/upgrade_radiation/upgrade_radiation_spell
var/datum/spell/irradiated_mouse_spell/upgrade_speed/upgrade_speed_spell
var/datum/spell/irradiated_mouse_spell/upgrade_damage/upgrade_damage_spell
/mob/living/basic/mouse/irradiated_mouse/Initialize(mapload)
. = ..()
add_language("Galactic Common")
set_default_language(GLOB.all_languages["Galactic Common"])
upgrade_radiation_spell = new()
upgrade_speed_spell = new()
upgrade_damage_spell = new()
AddSpell(upgrade_radiation_spell)
AddSpell(upgrade_speed_spell)
AddSpell(upgrade_damage_spell)
/mob/living/basic/mouse/irradiated_mouse/update_desc()
. = ..()
desc = initial(desc) // we dont want the standard description auto added by mice
/mob/living/basic/mouse/irradiated_mouse/proc/give_intro_text()
var/list/messages = list()
messages.Add(SPAN_USERDANGER("<center>You are an Irradiated Mouse!</center>"))
messages.Add("<center>[SPAN_NOTICE("Due to your proximity to radioactive material laying around you've started rapidly mutating! Unfortunately this comes at the cost of your life: [SPAN_BOLDNOTICE("once you exit the vents you will have 15 minutes to live.")]")]</center>")
messages.Add(mind.prepare_announce_objectives(FALSE))
messages.Add("<center>[SPAN_MOTD("For more information, check the wiki page: ([GLOB.configuration.url.wiki_url]/index.php/Irradiated_Mouse) ")]</center>")
to_chat(src, chat_box_red(messages.Join("<br>")))
/mob/living/basic/mouse/irradiated_mouse/remove_ventcrawl()
. = ..()
if(!has_exited_vents)
upgrade_radiation()
upgrade_speed()
upgrade_damage()
has_exited_vents = TRUE
/mob/living/basic/mouse/irradiated_mouse/Life(seconds, times_fired)
. = ..()
if(stat != CONSCIOUS)
return
if(!has_exited_vents)
return
// telegraph the radiation by giving tiles harmless alpha radiation
for(var/turf/turf in range(1, src))
contaminate_target(turf, src, alpha_rad, ALPHA_RAD)
// reduce health by a constant so the mouse eventually dies
adjustBruteLoss(maxHealth * seconds / seconds_time_till_death)
// subtract time after you've left a vent
upgrade_cooldown_in_seconds -= seconds
if(upgrade_cooldown_in_seconds <= 0)
upgrade_cooldown_in_seconds += initial(upgrade_cooldown_in_seconds)
available_upgrades++
to_chat(src, SPAN_NOTICE("You have [available_upgrades] upgrades available."))
if(!produce_radioactive_sludge)
return
var/chance = 50 - (health/maxHealth * 50) // more likely as health drops, fastest you can get this is after 6 minutes, giving a 20% spawn chance per 2 seconds
if(prob(chance))
new /obj/effect/decal/cleanable/radioactive_sludge(get_turf(src))
/mob/living/basic/mouse/irradiated_mouse/proc/upgrade_radiation()
radiation_upgrades++
alpha_rad = alpha_rad_per_level * radiation_upgrades
beta_rad = beta_rad_per_level * radiation_upgrades
gamma_rad = gamma_rad_per_level * radiation_upgrades
// update your radiation component
DeleteComponentsType(/datum/component/inherent_radioactivity)
AddComponent(/datum/component/inherent_radioactivity, alpha_rad, beta_rad, gamma_rad, radiation_cooldown)
/mob/living/basic/mouse/irradiated_mouse/proc/upgrade_speed()
speed_upgrades++
speed = initial(speed) + speed_per_level * speed_upgrades // this will tend towards a negative value (due to speed_per_level being negative) which is faster
if(speed_upgrades > level_cap)
alpha = speed_capstone_alpha
RegisterSignal(src, COMSIG_MOVABLE_MOVED, PROC_REF(on_movement)) // handles afterimages
/mob/living/basic/mouse/irradiated_mouse/proc/upgrade_damage()
damage_upgrades++
melee_damage_lower = damage_upgrades * 5
melee_damage_upper = melee_damage_lower + 5
if(damage_upgrades > level_cap)
environment_smash = ENVIRONMENT_SMASH_WALLS // what allows wall smashing
/mob/living/basic/mouse/irradiated_mouse/proc/on_movement(mob/living/mob, atom/old_loc)
if(stat != CONSCIOUS)
return
new /obj/effect/temp_visual/decoy/irradiated_mouse_afterimage(old_loc, mob)
/obj/effect/temp_visual/decoy/irradiated_mouse_afterimage
duration = 0.75 SECONDS
/obj/effect/temp_visual/decoy/irradiated_mouse_afterimage/Initialize(mapload, atom/mimiced_atom)
. = ..()
animate(src, alpha = 0, time = duration, easing = EASE_OUT) // gradually fading out after image
@@ -0,0 +1,69 @@
/datum/spell/irradiated_mouse_spell/
action_background_icon_state = "bg_irradiated_mouse"
clothes_req = FALSE
base_cooldown = 5 SECONDS
/datum/spell/irradiated_mouse_spell/create_new_targeting()
return new /datum/spell_targeting/self
/datum/spell/irradiated_mouse_spell/proc/has_upgrades(mob/living/basic/mouse/irradiated_mouse/user)
if(!user.available_upgrades)
to_chat(user, SPAN_WARN("You dont have any available upgrades"))
return FALSE
return TRUE
/datum/spell/irradiated_mouse_spell/upgrade_radiation
name = "Upgrade Radiation"
desc = "Upgrade the amount of radiation you emit. You will start producing radioactive sludge at level 3."
action_icon_state = "irradiated_mouse_radiation"
/datum/spell/irradiated_mouse_spell/upgrade_radiation/cast(list/targets, mob/living/basic/mouse/irradiated_mouse/user)
. = ..()
if(!has_upgrades(user))
return
to_chat(user, SPAN_NOTICE("You upgrade your the amount of radiation you give off."))
user.available_upgrades--
user.upgrade_radiation()
if(user.radiation_upgrades > user.level_cap)
user.RemoveSpell(user.upgrade_radiation_spell)
user.produce_radioactive_sludge = TRUE
to_chat(user, SPAN_NOTICE("You feel like shedding some weight."))
/datum/spell/irradiated_mouse_spell/upgrade_speed
name = "Upgrade Speed"
desc = "Upgrade your speed. You will become semi-transparent at level 3."
action_icon_state = "irradiated_mouse_speed"
/datum/spell/irradiated_mouse_spell/upgrade_speed/cast(list/targets, mob/living/basic/mouse/irradiated_mouse/user)
. = ..()
if(!has_upgrades(user))
return
to_chat(user, SPAN_NOTICE("You upgrade your speed."))
user.available_upgrades--
user.upgrade_speed()
if(user.speed_upgrades > user.level_cap)
user.RemoveSpell(user.upgrade_speed_spell)
to_chat(user, SPAN_NOTICE("You feel like the wind."))
/datum/spell/irradiated_mouse_spell/upgrade_damage
name = "Upgrade Damage"
desc = "Upgrade your damage. You will become able to damage walls and windows at level 3."
action_icon_state = "irradiated_mouse_damage"
/datum/spell/irradiated_mouse_spell/upgrade_damage/cast(list/targets, mob/living/basic/mouse/irradiated_mouse/user)
. = ..()
if(!has_upgrades(user))
return
to_chat(user, SPAN_NOTICE("You upgrade your damage."))
user.available_upgrades--
user.upgrade_damage()
if(user.damage_upgrades > user.level_cap)
user.RemoveSpell(user.upgrade_damage_spell)
to_chat(user, SPAN_NOTICE("You feel much stronger."))
@@ -0,0 +1,10 @@
/obj/effect/decal/cleanable/radioactive_sludge
gender = PLURAL
name = "Radioactive Sludge"
desc = "You should probably clean this up."
icon_state = "greenglow"
/obj/effect/decal/cleanable/radioactive_sludge/Initialize(mapload)
. = ..()
AddComponent(/datum/component/inherent_radioactivity, 800, 800, 0, 1.5)
@@ -4,6 +4,7 @@ GLOBAL_LIST_INIT(special_role_times, list(
ROLE_GOLEM = 0,
ROLE_PAI = 0,
ROLE_GUARDIAN = 0,
ROLE_IRRADIATED_MOUSE = 7,
ROLE_TRAITOR = 7,
ROLE_CHANGELING = 14,
ROLE_WIZARD = 14,
+1
View File
@@ -201,6 +201,7 @@ GLOBAL_LIST_EMPTY(event_last_fired)
new /datum/event_meta(EVENT_LEVEL_MODERATE, /datum/event/market_crash, 20),
new /datum/event_meta(EVENT_LEVEL_MODERATE, /datum/event/cargo_pods, 50),
new /datum/event_meta(EVENT_LEVEL_MODERATE, /datum/event/spawn_floor_cluwne, 3),
new /datum/event_meta(EVENT_LEVEL_MODERATE, /datum/event/spawn_irradiated_mouse, 20),
)
/datum/event_container/major
@@ -125,10 +125,10 @@
cable.deconstruct()
/mob/living/basic/mouse/start_pulling(atom/movable/AM, state, force = pull_force, show_message = FALSE)// Prevents mouse from pulling things
if(istype(AM, /obj/item/food/sliced/cheesewedge))
if(istype(AM, /obj/item/food/sliced/cheesewedge) || istype(AM, /mob/living/basic/mouse))
return ..() // Get dem
if(show_message)
to_chat(src, SPAN_WARNING("You are too small to pull anything except cheese."))
to_chat(src, SPAN_WARNING("You are too small to pull anything except cheese and other mice."))
return
/mob/living/basic/mouse/proc/on_atom_entered(datum/source, atom/movable/entered)
@@ -140,14 +140,23 @@
//MICE!
if(eats_mice && isturf(loc) && !incapacitated())
for(var/mob/living/basic/mouse/M in view(1, src))
if(!M.stat && Adjacent(M))
custom_emote(EMOTE_VISIBLE, "splats \the [M]!")
M.death()
M.splat()
movement_target = null
walk(src, 0)
stop_automated_movement = FALSE
break
if(M.stat == DEAD || !Adjacent(M))
continue
if(istype(M, /mob/living/basic/mouse/irradiated_mouse))
if(prob(50))
death()
return
else
name = "Schrödinger's [name]"
custom_emote(EMOTE_VISIBLE, "splats \the [M]!")
M.death()
M.splat()
movement_target = null
walk(src, 0)
stop_automated_movement = FALSE
break
for(var/obj/item/toy/cattoy/T in view(1, src))
if(T.cooldown < (world.time - 400))
custom_emote(EMOTE_VISIBLE, "bats \the [T] around with its paw!")
Binary file not shown.

Before

Width:  |  Height:  |  Size: 142 KiB

After

Width:  |  Height:  |  Size: 148 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 276 KiB

After

Width:  |  Height:  |  Size: 293 KiB

+3
View File
@@ -977,6 +977,8 @@
#include "code\game\gamemodes\miniantags\guardian\types\protector.dm"
#include "code\game\gamemodes\miniantags\guardian\types\ranged.dm"
#include "code\game\gamemodes\miniantags\guardian\types\standard_guardian.dm"
#include "code\game\gamemodes\miniantags\irradiated_mouse\irradiated_mouse.dm"
#include "code\game\gamemodes\miniantags\irradiated_mouse\irradiated_mouse_spells.dm"
#include "code\game\gamemodes\miniantags\morph\morph.dm"
#include "code\game\gamemodes\miniantags\morph\morph_event.dm"
#include "code\game\gamemodes\miniantags\morph\spells\ambush.dm"
@@ -1216,6 +1218,7 @@
#include "code\game\objects\effects\decals\Cleanable\fuel.dm"
#include "code\game\objects\effects\decals\Cleanable\humans.dm"
#include "code\game\objects\effects\decals\Cleanable\misc_cleanables.dm"
#include "code\game\objects\effects\decals\Cleanable\radioactive_sludge.dm"
#include "code\game\objects\effects\decals\Cleanable\robots.dm"
#include "code\game\objects\effects\decals\Cleanable\tar.dm"
#include "code\game\objects\effects\decals\Cleanable\tracks.dm"