diff --git a/_maps/RandomRuins/SpaceRuins/goatresearch.dmm b/_maps/RandomRuins/SpaceRuins/goatresearch.dmm index e2e8b0ec5000..3fc736744193 100644 --- a/_maps/RandomRuins/SpaceRuins/goatresearch.dmm +++ b/_maps/RandomRuins/SpaceRuins/goatresearch.dmm @@ -505,6 +505,10 @@ /mob/living/simple_animal/hostile/retaliate/goat/ras, /turf/open/floor/grass, /area/ruin/powered) +"bV" = ( +/mob/living/simple_animal/hostile/retaliate/goat/radioactive, +/turf/open/floor/grass, +/area/ruin/powered) "bW" = ( /obj/structure/chair/wood/normal{ dir = 1; @@ -616,10 +620,6 @@ /obj/machinery/light, /turf/open/floor/grass, /area/ruin/powered) -"od" = ( -/mob/living/simple_animal/hostile/retaliate/goat/orange, -/turf/open/floor/grass, -/area/ruin/powered) "sr" = ( /turf/closed/wall/mineral/titanium/nodiagonal, /area/ruin/powered) @@ -4536,7 +4536,7 @@ bZ aN bH ae -od +bV cm ab aa diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm index cf878b8e09b4..fedd97ad3a54 100644 --- a/code/__HELPERS/unsorted.dm +++ b/code/__HELPERS/unsorted.dm @@ -1391,6 +1391,7 @@ GLOBAL_DATUM_INIT(dview_mob, /mob/dview, new) var/list/blocked = list(/mob/living/simple_animal/hostile/retaliate/goat/huge, /mob/living/simple_animal/hostile/retaliate/goat/clown, /mob/living/simple_animal/hostile/retaliate/goat/stack, + /mob/living/simple_animal/hostile/retaliate/goat/radioactive, /mob/living/simple_animal/hostile/retaliate/goat/blue, /mob/living/simple_animal/hostile/retaliate/goat/brown, /mob/living/simple_animal/hostile/retaliate/goat/chocolate, @@ -1416,6 +1417,7 @@ GLOBAL_DATUM_INIT(dview_mob, /mob/dview, new) var/list/blocked = list(/mob/living/simple_animal/hostile/retaliate/goat/huge, /mob/living/simple_animal/hostile/retaliate/goat/clown, /mob/living/simple_animal/hostile/retaliate/goat/stack, + /mob/living/simple_animal/hostile/retaliate/goat/radioactive, /mob/living/simple_animal/hostile/retaliate/goat/ras, /mob/living/simple_animal/hostile/retaliate/goat/christmas, /mob/living/simple_animal/hostile/retaliate/goat/confetti, diff --git a/code/game/objects/effects/anomalies.dm b/code/game/objects/effects/anomalies.dm index 2e6cd7a44dad..abc4f04eafcd 100644 --- a/code/game/objects/effects/anomalies.dm +++ b/code/game/objects/effects/anomalies.dm @@ -368,5 +368,52 @@ SSexplosions.lowturf += T ///////////////////////// +/obj/effect/anomaly/radiation + name = "radiation anomaly" + icon = 'icons/obj/projectiles.dmi' + icon_state = "radiation_anomaly" + density = TRUE + var/spawn_goat = FALSE //For goat spawning + +/obj/effect/anomaly/radiation/admin //bussing + spawn_goat = TRUE + +/obj/effect/anomaly/radiation/anomalyEffect() + ..() + for(var/i = 1 to 15) + fire_nuclear_particle() + radiation_pulse(src, 500, 5) + +/obj/effect/anomaly/radiation/proc/makegoat() + var/turf/open/T = get_turf(src) + var/mob/living/simple_animal/hostile/retaliate/goat/radioactive/S = new(T) + + var/list/mob/dead/observer/candidates = pollCandidatesForMob("Do you want to play as a radioactive goat?", ROLE_SENTIENCE, null, null, 100, S, POLL_IGNORE_PYROSLIME) + if(LAZYLEN(candidates)) + var/mob/dead/observer/chosen = pick(candidates) + S.key = chosen.key + var/datum/action/cooldown/spell/conjure/radiation_anomaly/spell + spell.Grant(S) + log_game("[key_name(S.key)] was made into a radioactive goat by radiation anomaly at [AREACOORD(T)].") + +/obj/effect/anomaly/radiation/detonate() + INVOKE_ASYNC(src, PROC_REF(rad_Spin)) + +/obj/effect/anomaly/radiation/proc/rad_Spin() + radiation_pulse(src, 5000, 7) + var/turf/T = get_turf(src) + for(var/i=1 to 100) + var/angle = i * 10 + T.fire_nuclear_particle(angle) + sleep(0.7) + +/obj/effect/anomaly/radiation/process(delta_time) + anomalyEffect(delta_time) + if(death_time < world.time) + if(loc) + if(spawn_goat) + INVOKE_ASYNC(src, PROC_REF(makegoat)) + detonate() + addtimer(CALLBACK(GLOBAL_PROC, PROC_REF(qdel), src), 150) #undef ANOMALY_MOVECHANCE diff --git a/code/game/objects/structures/crates_lockers/crates.dm b/code/game/objects/structures/crates_lockers/crates.dm index 651062e841f3..c816a772f666 100644 --- a/code/game/objects/structures/crates_lockers/crates.dm +++ b/code/game/objects/structures/crates_lockers/crates.dm @@ -339,7 +339,7 @@ if(16) new /mob/living/simple_animal/hostile/retaliate/goat/pixel(loc) if(17) - new /mob/living/simple_animal/hostile/retaliate/goat/rainbow(loc) + new /mob/living/simple_animal/hostile/retaliate/goat/radioactive(loc) if(18) new /mob/living/simple_animal/hostile/retaliate/goat/rainbow(loc) if(19) diff --git a/code/modules/assembly/signaler.dm b/code/modules/assembly/signaler.dm index cab02fe48b7c..999bc9ac0c40 100644 --- a/code/modules/assembly/signaler.dm +++ b/code/modules/assembly/signaler.dm @@ -217,6 +217,12 @@ /obj/item/assembly/signaler/anomaly/attack_self() return +/obj/item/assembly/signaler/anomaly/radiation + name = "\improper radiation anomaly core" + desc = "The neutralized core of a radiation anomaly. It keeps pulsing an ominous green. It'd probably be valuable for research." + icon_state = "anomaly core" + anomaly_type = /obj/effect/anomaly/radiation + /obj/item/assembly/signaler/cyborg /obj/item/assembly/signaler/cyborg/attackby(obj/item/W, mob/user, params) diff --git a/code/modules/events/anomaly_radiation.dm b/code/modules/events/anomaly_radiation.dm new file mode 100644 index 000000000000..aa105573cf5e --- /dev/null +++ b/code/modules/events/anomaly_radiation.dm @@ -0,0 +1,17 @@ +/datum/round_event_control/anomaly/anomaly_radiation + name = "Anomaly: Radiation" + typepath = /datum/round_event/anomaly/anomaly_radiation + + max_occurrences = 7 + weight = 20 + +/datum/round_event/anomaly/anomaly_radiation + startWhen = 3 + announceWhen = 10 + anomaly_path = /obj/effect/anomaly/radiation + +/datum/round_event/anomaly/anomaly_radiation/announce(fake) + if(prob(90)) + priority_announce("Radioactive anomaly detected on long range scanners. Expected location: [impact_area.name].", "Anomaly Alert") + else + print_command_report("Radioactive anomaly detected on long range scanners. Expected location: [impact_area.name].", "Radioactive anomaly") diff --git a/code/modules/power/supermatter/supermatter.dm b/code/modules/power/supermatter/supermatter.dm index c6c709b1e72e..f1fa4ea210cc 100644 --- a/code/modules/power/supermatter/supermatter.dm +++ b/code/modules/power/supermatter/supermatter.dm @@ -83,6 +83,7 @@ #define GRAVITATIONAL_ANOMALY "gravitational_anomaly" #define FLUX_ANOMALY "flux_anomaly" #define PYRO_ANOMALY "pyro_anomaly" +#define RADIATION_ANOMALY "radiation_anomaly" //If integrity percent remaining is less than these values, the monitor sets off the relevant alarm. #define SUPERMATTER_DELAM_PERCENT 5 @@ -665,6 +666,8 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal) supermatter_anomaly_gen(src, GRAVITATIONAL_ANOMALY, rand(5, 10)) if(power > SEVERE_POWER_PENALTY_THRESHOLD && prob(2) || prob(0.3) && power > POWER_PENALTY_THRESHOLD) supermatter_anomaly_gen(src, PYRO_ANOMALY, rand(5, 10)) + if(power > SEVERE_POWER_PENALTY_THRESHOLD && prob(3) || prob(0.5)) + supermatter_anomaly_gen(src, RADIATION_ANOMALY, rand(5, 10)) if(damage > warning_point) // while the core is still damaged and it's still worth noting its status if(damage_archived < warning_point) //If damage_archive is under the warning point, this is the very first cycle that we've reached said point. @@ -1153,6 +1156,8 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal) new /obj/effect/anomaly/grav(L, 250) if(PYRO_ANOMALY) new /obj/effect/anomaly/pyro(L, 400) + if(RADIATION_ANOMALY) + new /obj/effect/anomaly/radiation(L, 400) /obj/machinery/proc/supermatter_zap(atom/zapstart, range = 3, power) . = zapstart.dir @@ -1274,3 +1279,4 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal) #undef SUPERMATTER_EXPLOSION_LAMBDA #undef FLUX_ANOMALY #undef PYRO_ANOMALY +#undef RADIATION_ANOMALY diff --git a/code/modules/spells/spell_types/conjure/rad_goat.dm b/code/modules/spells/spell_types/conjure/rad_goat.dm new file mode 100644 index 000000000000..f68f191ce8f5 --- /dev/null +++ b/code/modules/spells/spell_types/conjure/rad_goat.dm @@ -0,0 +1,24 @@ +/datum/action/cooldown/spell/conjure/radiation_anomaly + name = "Spawn Radiation Anomaly" + desc = "Spawn a radiation anomaly, summon your brothers!" + button_icon = 'icons/obj/projectiles.dmi' + button_icon_state = "radiation_anomaly" + sound = 'sound/weapons/resonator_fire.ogg' + + school = SCHOOL_CONJURATION + cooldown_time = 10 SECONDS + + invocation_type = INVOCATION_SHOUT + invocation = "UNGA" + spell_requirements = NONE + + summon_type = list(/obj/effect/anomaly/radiation) + summon_radius = 0 + +/datum/action/cooldown/spell/conjure/radiation_anomaly/post_summon(atom/summoned_object, atom/cast_on) + if(!istype(summoned_object, /obj/effect/anomaly/radiation)) + return + var/obj/effect/anomaly/radiation/anomaly = summoned_object + anomaly.spawn_goat = TRUE + owner.visible_message(span_notice("You see the radiation anomaly emerges from the [owner]."), span_notice("The radiation anomaly emerges from your body.")) + notify_ghosts("The Radioactive Goat has spawned a radiation anomaly!", source = anomaly, action = NOTIFY_ORBIT, flashwindow = FALSE, header = "Radiation Anomaly Spawned!") diff --git a/yogstation.dme b/yogstation.dme index ec1a62b2d547..c77271e003ae 100644 --- a/yogstation.dme +++ b/yogstation.dme @@ -2218,6 +2218,7 @@ #include "code\modules\events\anomaly_flux.dm" #include "code\modules\events\anomaly_grav.dm" #include "code\modules\events\anomaly_pyro.dm" +#include "code\modules\events\anomaly_radiation.dm" #include "code\modules\events\anomaly_vortex.dm" #include "code\modules\events\aurora_caelus.dm" #include "code\modules\events\blob.dm" @@ -3497,6 +3498,7 @@ #include "code\modules\spells\spell_types\conjure\invisible_wall.dm" #include "code\modules\spells\spell_types\conjure\link_worlds.dm" #include "code\modules\spells\spell_types\conjure\presents.dm" +#include "code\modules\spells\spell_types\conjure\rad_goat.dm" #include "code\modules\spells\spell_types\conjure\soulstone.dm" #include "code\modules\spells\spell_types\conjure\the_traps.dm" #include "code\modules\spells\spell_types\conjure_item\_conjure_item.dm" diff --git a/yogstation/code/modules/mob/living/simple_animal/friendly/goats.dm b/yogstation/code/modules/mob/living/simple_animal/friendly/goats.dm index ca2d12a0bd49..3550f54cf552 100644 --- a/yogstation/code/modules/mob/living/simple_animal/friendly/goats.dm +++ b/yogstation/code/modules/mob/living/simple_animal/friendly/goats.dm @@ -157,6 +157,71 @@ icon_dead = "pixelgoat_dead" gold_core_spawnable = NO_SPAWN +/mob/living/simple_animal/hostile/retaliate/goat/radioactive + name = "Radioactive Goat" + desc = "I would not get near this goat if I were you." + icon = 'yogstation/icons/mob/goats/radioactive_goat.dmi' + icon_state = "radioactivegoat" + icon_living = "radioactivegoat" + icon_dead = "radioactivegoat_dead" + gold_core_spawnable = NO_SPAWN + light_power = 5 + light_range = 4 + melee_damage_lower = 20 + melee_damage_upper = 30 + speed = -0.5 + robust_searching = 1 + turns_per_move = 5 + dodging = 1 + stat_attack = UNCONSCIOUS + health = 200 + maxHealth = 200 + var/datum/action/innate/rad_goat/rad_switch + var/datum/action/cooldown/spell/conjure/radiation_anomaly/radiation_anomaly + var/rad_emit = TRUE + +/mob/living/simple_animal/hostile/retaliate/goat/radioactive/bullet_act(obj/item/projectile/P) + if(istype(P, /obj/item/projectile/energy/nuclear_particle)) + P.damage = 0 //No damaging goat + return ..() + +/mob/living/simple_animal/hostile/retaliate/goat/radioactive/on_hit(obj/item/projectile/P) + . = ..() + if(istype(P, /obj/item/projectile/energy/nuclear_particle)) + // abosrbs nuclear particle to heal + adjustBruteLoss(-1) + adjustFireLoss(-1) + +/mob/living/simple_animal/hostile/retaliate/goat/radioactive/Life() + if(stat == CONSCIOUS) + adjustBruteLoss(-0.5) + adjustFireLoss(-0.5) //gets healed over time + if(rad_emit) + light_color = LIGHT_COLOR_GREEN + radiation_pulse(src, 600) + else + light_color = initial(light_color) + +/mob/living/simple_animal/hostile/retaliate/goat/radioactive/Initialize(mapload) + . = ..() + ADD_TRAIT(src, TRAIT_RADIMMUNE, GENETIC_MUTATION) + rad_switch = new + rad_switch.Grant(src) + radiation_anomaly = new + radiation_anomaly.Grant(src) + +/datum/action/innate/rad_goat //This is for rad goat only. + name = "Rad emission switch" + desc = "If you want to enable/disable radiation emission." + background_icon_state = "bg_default" + button_icon = 'icons/obj/wizard.dmi' + button_icon_state = "greentext" + +/datum/action/innate/rad_goat/Activate() + var/mob/living/simple_animal/hostile/retaliate/goat/radioactive/S = owner + S.rad_emit = !S.rad_emit + to_chat(S, span_notice("You [S.rad_emit? "enable" : "disable"] radiation emission.")) + /mob/living/simple_animal/hostile/retaliate/goat/rainbow name = "Rainbow Goat" desc = "WHAT DOES IT MEANNNNNNN!"