diff --git a/aurorastation.dme b/aurorastation.dme index 3662c98958d..d18fb920ebe 100644 --- a/aurorastation.dme +++ b/aurorastation.dme @@ -2390,6 +2390,7 @@ #include "code\modules\events\vent_clog.dm" #include "code\modules\events\visitor.dm" #include "code\modules\events\wallrot.dm" +#include "code\modules\events\wandering_psirens.dm" #include "code\modules\ext_scripts\python.dm" #include "code\modules\fabrication\_fabricator.dm" #include "code\modules\fabrication\_fabricator_build_order.dm" diff --git a/code/game/gamemodes/technomancer/spells/summon/summon_creature.dm b/code/game/gamemodes/technomancer/spells/summon/summon_creature.dm index 0a8cf35cb20..12d94f1f995 100644 --- a/code/game/gamemodes/technomancer/spells/summon/summon_creature.dm +++ b/code/game/gamemodes/technomancer/spells/summon/summon_creature.dm @@ -34,7 +34,10 @@ "GREIMORIAN BOMBARDIER" = /mob/living/simple_animal/hostile/giant_spider/bombardier, "GREIMORIAN NURSE" = /mob/living/simple_animal/hostile/giant_spider/nurse, "CARP" = /mob/living/simple_animal/hostile/carp, - "BEAR" = /mob/living/simple_animal/hostile/bear + "BEAR" = /mob/living/simple_animal/hostile/bear, + "PSIREN LASHER" = /mob/living/simple_animal/hostile/psiren, + "PSIREN DARTER" = /mob/living/simple_animal/hostile/psiren/ranged, + "PSIREN OMEN" = /mob/living/simple_animal/hostile/psiren/omen ) cooldown = 30 instability_cost = 10 diff --git a/code/modules/events/event_container.dm b/code/modules/events/event_container.dm index 4d98e80fe4f..10533c884e0 100644 --- a/code/modules/events/event_container.dm +++ b/code/modules/events/event_container.dm @@ -335,6 +335,9 @@ GLOBAL_LIST_INIT(severity_to_string, alist(EVENT_LEVEL_MUNDANE = "Mundane", EVEN new /datum/event_meta(EVENT_LEVEL_MODERATE, "APC Damage", /datum/event/apc_damage, 20, list(ASSIGNMENT_ENGINEER = 15, ASSIGNMENT_JANITOR = 20)), + new /datum/event_meta(EVENT_LEVEL_MODERATE, "Wandering Psirens", /datum/event/wandering_psirens, + 10, list(ASSIGNMENT_SECURITY = 15)), + ) // Severity Level, Event Name, Event Type, Base Weight, Role Weight(s), One Shot (TRUE/FALSE), Min Weight, Max Weight. Last two only used if set and non-zero. @@ -388,6 +391,9 @@ GLOBAL_LIST_INIT(severity_to_string, alist(EVENT_LEVEL_MUNDANE = "Mundane", EVEN 35, list(ASSIGNMENT_ENGINEER = 20), is_one_shot = TRUE, pop_needed = 12), + new /datum/event_meta(EVENT_LEVEL_MAJOR, "Wandering Psiren School", /datum/event/wandering_psirens, + 10, list(ASSIGNMENT_SECURITY = 15, ASSIGNMENT_MEDICAL = 5)), + ) #undef ASSIGNMENT_ANY diff --git a/code/modules/events/wandering_psirens.dm b/code/modules/events/wandering_psirens.dm new file mode 100644 index 00000000000..013ff01e35f --- /dev/null +++ b/code/modules/events/wandering_psirens.dm @@ -0,0 +1,75 @@ +/// Wandering Psirens, an event similar enough to Carp Migration that I can reuse much of the code. +/datum/event/wandering_psirens + announceWhen = 50 + endWhen = 900 + + var/list/spawned_psirens = list() + + var/list/despawn_turfs = list( + /turf/space, + /turf/simulated/floor/exoplanet/asteroid, + /turf/simulated/open, + /turf/simulated/floor/reinforced/airless // Station roof. + ) + +/datum/event/wandering_psirens/setup() + announceWhen = rand(40, 60) + endWhen = rand(600, 1200) + despawn_turfs = typecacheof(despawn_turfs) + +/datum/event/wandering_psirens/announce() + // Pings every "Psi-sensitive", will trigger feedback on people's mindshields. + for (var/mob/victim in GLOB.player_list) + if (SShallucinations.is_adpi_excluded(victim) || SShallucinations.is_adpi_blocked(victim)) + continue + + SShallucinations.send_adpi_message(victim, null, FALSE) + +/datum/event/wandering_psirens/start() + ..() + + if(severity == EVENT_LEVEL_MAJOR) + spawn_psirens(length(GLOB.landmarks_list)) + else if(severity == EVENT_LEVEL_MODERATE) + spawn_psirens(rand(4, 6)) //12 to 30 psirens + else + spawn_psirens(rand(1, 3), 1, 2) //1 to 6 psirens, alone or in pairs + +/datum/event/wandering_psirens/proc/spawn_psirens(num_groups, group_size_min = 3, group_size_max = 5) + set waitfor = FALSE + var/list/spawn_locations = list() + + for(var/obj/effect/landmark/C in GLOB.landmarks_list) + if(C.name == "carpspawn") // Reusing the carp landmarks. :) + spawn_locations.Add(C.loc) + spawn_locations = shuffle(spawn_locations) + num_groups = min(num_groups, spawn_locations.len) + + var/i = 1 + while (i <= num_groups) + var/group_size = rand(group_size_min, group_size_max) + for(var/j = 1, j <= group_size, j++) + if(prob(95)) + var/basic_psiren + if (prob(50)) + basic_psiren = new /mob/living/simple_animal/hostile/psiren(spawn_locations[i]) + else basic_psiren = new /mob/living/simple_animal/hostile/psiren/ranged(spawn_locations[i]) + spawned_psirens += WEAKREF(basic_psiren) + else + var/mob/living/simple_animal/hostile/psiren/omen/new_omen = new(spawn_locations[i]) + spawned_psirens += WEAKREF(new_omen) + CHECK_TICK + i++ + +/datum/event/wandering_psirens/end(faked) + ..() + + for (var/datum/weakref/psiren_weakref in spawned_psirens) + var/mob/living/simple_animal/hostile/psiren/psiren = psiren_weakref.resolve() + if (psiren && prob(50) && is_type_in_typecache(psiren.loc, despawn_turfs)) + spawned_psirens -= psiren_weakref + qdel(psiren_weakref) + spawned_psirens?.Cut() + +/datum/event/wandering_psirens/overmap + despawn_turfs = list(/turf/space) diff --git a/code/modules/overmap/events/event.dm b/code/modules/overmap/events/event.dm index c951befacc6..1bd94603d8c 100644 --- a/code/modules/overmap/events/event.dm +++ b/code/modules/overmap/events/event.dm @@ -328,6 +328,20 @@ can_be_destroyed = FALSE tooltip_text = "Unstable gravitic shear effects detected; wide-field artificial gravity should be powered down before transit." +/obj/effect/overmap/event/psiren + name = "psiren shoal" + events = list(/datum/event/wandering_psirens/overmap) + difficulty = EVENT_LEVEL_MODERATE + event_icon_states = list("carp") + movable_event_chance = 30 + tooltip_text = "Xenofauna: usually hostile." + +/obj/effect/overmap/event/psiren/major + name = "psiren school" + opacity = 1 + difficulty = EVENT_LEVEL_MAJOR + movable_event_chance = 15 + /obj/effect/overmap/event/MouseEntered(location, control, params) . = ..() openToolTip(usr, src, params, tooltip_text) @@ -402,3 +416,17 @@ radius = 12 hazards = /obj/effect/overmap/event/gravity_anomaly sectors = list(SECTOR_LEMURIAN_SEA, SECTOR_LEMURIAN_SEA_FAR) + +/datum/overmap_event/psiren + name = "psiren shoal" + count = 3 + radius = 1 + continuous = FALSE + hazards = /obj/effect/overmap/event/psiren + +/datum/overmap_event/psiren/major + name = "psiren school" + count = 2 + radius = 2 + opacity = 1 + hazards = /obj/effect/overmap/event/psiren/major diff --git a/html/changelogs/hellfirejag-introducing-psirens.yml b/html/changelogs/hellfirejag-introducing-psirens.yml new file mode 100644 index 00000000000..5a08ddf5b82 --- /dev/null +++ b/html/changelogs/hellfirejag-introducing-psirens.yml @@ -0,0 +1,5 @@ +author: Hellfirejag +delete-after: True +changes: + - rscadd: "Psirens can now visit the ship, both via overmap hazard, or as a random event." + - rscadd: "Technomancers can now summon the 3 basic Psiren types"