Files
Bubberstation/code/controllers/subsystem/queuelinks.dm
jimmyl 92a585cb3a new icebox ruin: outpost 31 + megafauna (technically???) (#88714)
## About The Pull Request
<details>
<summary> expand to spoil the fun of exploring something for yourself
</summary>

firstly, the new ruin: outpost 31
its layout is vaguely based off an official map of the Outpost 31 from
the Thing movie but i ran out of space halfway


![image](https://github.com/user-attachments/assets/6db1aa9f-40d3-4693-897b-01e32b3ee1d2)

the boss drops a keycard for the storage room that you cant get in
otherwise, containing its own special item, and other stuff probably
useful for crew
crusher loot: trophy that heals you on each hit

the ruin is guarded by like 3 flesh blobs, very resilient (and slow)
masses of flesh that deal 3 brute damage, not harmful in melee but WILL
attempt to grab and devour/assimilate you which is FAR more lethal



https://github.com/user-attachments/assets/542cc6d0-f4ee-4598-9677-a03170c6c1c3



Boss: The Thing (with creative liberties otherwise this thing would
instakill you if it was true to source material)
difficulty: medium apparently idk mining jesus beat it with 400ms or so
HP: 1800
It is a much higher ranking changeling than those infiltrating SS13
It has 3 phases, 600hp each. Depleting its phase health will turn it
invincible and it will heal back half in 10 seconds. In order to prevent
this, the two Molecular Accelerators must be overloaded by interacting
with them to blast the changeling with deadly scifi magic or whatever
they do, forcing it to shed its form further and go to the next phase.
Not necessary for phase 3 because it literally just dies then

it focuses mostly on meleeing you and making certain tiles impassable
for you with 1hp tendrils, all attacks are telegraphed so theres no dumb
instakills here

it alternates between aoe abilities and abilities 

melee behavior:
- if too far, charge at target (charges twice on phase 3)
- too close, shriek (unavailable in phase 1) (technically AOE but its
more like a melee ability you know??)
- otherwise just try to melee

Shriek: if the player is too close emit a confusing shriek that makes
them confused and drop items

aoe behavior (phase 2, 3 only):
1: Puts 4 tendrils in a line cardinally
2: Puts tendrils around itself
3. Puts a patch of tendrils around and under the target, 3x3 in phase 3
4. Phase 3 only - spits patches of acid into the air that hurt when
stepped on

_(crusher is hard ok)_


https://github.com/user-attachments/assets/cbb98209-d3f0-470d-b0e8-4e310c5b709c



unique megafauna loot for this boss is like 1 AI-Uplink brain
its like a BORIS module but for humans i think you can figure out what
that means
while in a human shell they cannot roll non-malf midrounds and cannot be
converted, and cannot be mindswapped
the human MUST have all robotic organs (minus tongue because its not in
the exosuit fab and that kinda sucks to get)
will undeploy if polymorphed



https://github.com/user-attachments/assets/abcc277a-995a-4fa7-b980-0549b6b7cf52



</details>

## Why It's Good For The Game

icebox is severely lacking in actual good ruins (fuck that one fountain
ruin)
i feel that the loot given by megafauna has been and still apparently is
exclusively to make the victor more powerful, which kinda sucks because
thats just powergaming???? the loot of this boss is more crewsided,
specifically aiding the AI in a VERY limited quantity (1), so its not
anything good for powergamers, good for crew if the AI is not rogue

## Changelog
🆑
add: outpost 31, the icebox ruin. Also its associated mobs, and
megafauna, and loot. Im not spoiling anything, find it yourself.
/🆑

---------

Co-authored-by: Ben10Omintrix <138636438+Ben10Omintrix@users.noreply.github.com>
2025-01-23 18:33:05 +01:00

88 lines
2.4 KiB
Plaintext

/atom/proc/MatchedLinks(id, list/partners)
SUBSYSTEM_DEF(queuelinks)
name = "Queue Links"
flags = SS_NO_FIRE
init_order = INIT_ORDER_QUEUELINKS
///assoc list of pending queues, id = /datum/queue_link
var/list/queues = list()
/datum/controller/subsystem/queuelinks/Initialize()
return SS_INIT_SUCCESS
///Creates or adds to a queue with the id supplied, if the queue is now or above the size of the queue, calls MatchedLinks and clears queue.
/// queues with a size of 0 wait never pop until something is added with an actual queue_max
/datum/controller/subsystem/queuelinks/proc/add_to_queue(atom/what, id, queue_max = 0)
if(!isatom(what))
CRASH("Attempted to add a non-atom to queue; [what]!")
if(isnull(id))
CRASH("Attempted to add to queue with no ID; [what]")
var/datum/queue_link/link = queues[id]
if(isnull(link))
link = new /datum/queue_link(id)
queues[id] = link
if(link.add(what, queue_max))
queues -= id
/**
* Pop a queue link without waiting for it to reach its max size.
* This is useful for those links that do not have a fixed size and thus may not pop.
*/
/datum/controller/subsystem/queuelinks/proc/pop_link(id)
if(isnull(id))
CRASH("Attempted to pop a queue with no ID")
var/datum/queue_link/link = queues[id]
if(isnull(queues[id]))
CRASH("Attempted to pop a non-existant queue: [id]")
link.pop()
queues -= id
/datum/queue_link
/// atoms in our queue
var/list/partners = list()
/// how much length until we pop, only incrementable, 0 means the queue will not pop until a maximum is set
var/queue_max = 0
/// id
var/id
/datum/queue_link/New(new_id)
id = new_id
return ..()
///adds an atom to the queue, if we are popping this returns TRUE
/datum/queue_link/proc/add(atom/what, max = 0)
. = FALSE
if(what in partners)
return
partners += what
RegisterSignal(what, COMSIG_QDELETING, PROC_REF(link_object_deleted))
if(queue_max != 0 && max != 0 && max != queue_max)
CRASH("Tried to change queue size to [max] from [queue_max]!")
else if(!queue_max)
queue_max = max
if(!queue_max || length(partners) < queue_max)
return
pop()
return TRUE
/datum/queue_link/proc/pop()
for(var/atom/item as anything in partners)
item.MatchedLinks(id, partners - item)
qdel(src)
/datum/queue_link/proc/link_object_deleted(datum/source) // because CI and stuff
SIGNAL_HANDLER
partners -= source
/datum/queue_link/Destroy()
. = ..()
partners = null