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>
This commit is contained in:
jimmyl
2025-01-23 18:33:05 +01:00
committed by GitHub
co-authored by Ben10Omintrix
parent 85473b849c
commit 92a585cb3a
33 changed files with 5513 additions and 20 deletions
@@ -231,3 +231,23 @@
var/mob/living/basic/legion_brood/minion = new (LivingUser.loc)
minion.assign_creator(LivingUser)
next_use_time = world.time + 4 SECONDS
//The Thing
/obj/item/crusher_trophy/flesh_glob
name = "glob of shifting flesh"
desc = "A glob of shifting flesh. Sealed shut permanently. Suitable as a trophy for a kinetic crusher."
icon_state = "glob"
denied_type = /obj/item/crusher_trophy/flesh_glob
bonus_value = 20
/// the order in which we heal damage
var/static/list/damage_heal_order = list(BRUTE, BURN, OXY, TOX)
/obj/item/crusher_trophy/flesh_glob/effect_desc()
return "melee hits heal you for <b>[bonus_value * 0.2]</b>, and for <b>[bonus_value * 0.5]</b> on mark detonation"
/obj/item/crusher_trophy/flesh_glob/on_melee_hit(mob/living/target, mob/living/user)
user.heal_ordered_damage(bonus_value * 0.2, damage_heal_order)
/obj/item/crusher_trophy/flesh_glob/on_mark_detonation(mob/living/target, mob/living/user)
. = ..()
user.heal_ordered_damage(bonus_value * 0.5, damage_heal_order)
@@ -1115,3 +1115,170 @@
playsound(target, 'sound/effects/magic/lightningbolt.ogg', 100, TRUE)
target.visible_message(span_danger("A thunderbolt strikes [target]!"))
explosion(target, light_impact_range = (boosted ? 1 : 0), flame_range = (boosted ? 2 : 1), silent = TRUE)
/datum/action/innate/brain_undeployment
name = "Disconnect from shell"
desc = "Stop controlling your shell and resume normal core operations."
button_icon = 'icons/mob/actions/actions_AI.dmi'
button_icon_state = "ai_core"
/datum/action/innate/brain_undeployment/Trigger(trigger_flags)
if(!..())
return FALSE
var/obj/item/organ/brain/cybernetic/ai/shell_to_disconnect = owner.get_organ_by_type(/obj/item/organ/brain/cybernetic/ai)
shell_to_disconnect.undeploy()
return TRUE
/obj/item/organ/brain/cybernetic/ai
name = "AI-uplink brain"
desc = "Can be inserted into a body with NO ORGANIC INTERNAL ORGANS (robotic organs only) to allow AIs to control it. Comes with its own health sensors beacon. MUST be a humanoid or bad things happen to the consciousness."
can_smoothen_out = FALSE
/// if connected, our AI
var/mob/living/silicon/ai/mainframe
/// action for undeployment
var/datum/action/innate/brain_undeployment/undeployment_action = new
/obj/item/organ/brain/cybernetic/ai/Initialize(mapload)
. = ..()
AddElement(/datum/element/noticable_organ, "%PRONOUN_Their eyes move with machine precision, their expression completely blank.")
/obj/item/organ/brain/cybernetic/ai/Destroy()
. = ..()
undeploy()
mainframe = null
QDEL_NULL(undeployment_action)
/obj/item/organ/brain/cybernetic/ai/on_mob_insert(mob/living/carbon/brain_owner, special, movement_flags)
. = ..()
brain_owner.add_traits(list(HUMAN_SENSORS_VISIBLE_WITHOUT_SUIT, TRAIT_NO_MINDSWAP), ORGAN_TRAIT)
update_med_hud_status(brain_owner)
RegisterSignal(brain_owner, COMSIG_LIVING_HEALTH_UPDATE, PROC_REF(update_med_hud_status))
RegisterSignal(brain_owner, COMSIG_CLICK, PROC_REF(owner_clicked))
RegisterSignal(brain_owner, COMSIG_MOB_GET_STATUS_TAB_ITEMS, PROC_REF(get_status_tab_item))
RegisterSignal(brain_owner, COMSIG_MOB_MIND_BEFORE_MIDROUND_ROLL, PROC_REF(cancel_rolls))
RegisterSignals(brain_owner, list(COMSIG_QDELETING, COMSIG_LIVING_PRE_WABBAJACKED), PROC_REF(undeploy))
RegisterSignal(brain_owner, COMSIG_CARBON_GAIN_ORGAN, PROC_REF(on_organ_gain))
/obj/item/organ/brain/cybernetic/ai/on_mob_remove(mob/living/carbon/organ_owner, special, movement_flags)
undeploy()
. = ..()
organ_owner.remove_traits(list(HUMAN_SENSORS_VISIBLE_WITHOUT_SUIT, TRAIT_NO_MINDSWAP), ORGAN_TRAIT)
UnregisterSignal(organ_owner, list(COMSIG_LIVING_HEALTH_UPDATE, COMSIG_CLICK, COMSIG_MOB_GET_STATUS_TAB_ITEMS, COMSIG_MOB_MIND_BEFORE_MIDROUND_ROLL, COMSIG_QDELETING, COMSIG_LIVING_PRE_WABBAJACKED))
/obj/item/organ/brain/cybernetic/ai/proc/cancel_rolls(mob/living/source, datum/mind/mind, datum/antagonist/antagonist)
SIGNAL_HANDLER
if(ispath(antagonist, /datum/antagonist/malf_ai))
return
return CANCEL_ROLL
/obj/item/organ/brain/cybernetic/ai/proc/get_status_tab_item(mob/living/source, list/items)
SIGNAL_HANDLER
if(!mainframe)
return
items += mainframe.get_status_tab_items()
/obj/item/organ/brain/cybernetic/ai/proc/update_med_hud_status(mob/living/mob_parent)
SIGNAL_HANDLER
var/image/holder = mob_parent.hud_list?[STATUS_HUD]
if(isnull(holder))
return
var/icon/size_check = icon(mob_parent.icon, mob_parent.icon_state, mob_parent.dir)
holder.pixel_y = size_check.Height() - ICON_SIZE_Y
if(mob_parent.stat == DEAD || HAS_TRAIT(mob_parent, TRAIT_FAKEDEATH) || isnull(mainframe))
holder.icon_state = "huddead2"
holder.pixel_x = -8 // new icon states? nuh uh
else
holder.icon_state = "hudtrackingai"
holder.pixel_x = -16
// no thoughts only wifi
/obj/item/organ/brain/cybernetic/ai/can_gain_trauma(datum/brain_trauma/trauma, resilience, natural_gain = FALSE)
return FALSE
/obj/item/organ/brain/cybernetic/ai/proc/owner_clicked(datum/source, atom/location, control, params, mob/user)
SIGNAL_HANDLER
if(!isAI(user))
return
var/list/lines = list()
lines += span_bold("[owner]")
lines += "Target is currently [!HAS_TRAIT(owner, TRAIT_INCAPACITATED) ? "functional" : "incapacitated"]"
lines += "Estimated organic/inorganic integrity: [owner.health]"
if(is_sufficiently_augmented())
lines += "<a href='byond://?src=[REF(src)];ai_take_control=[REF(user)]'>[span_boldnotice("Take control?")]</a><br>"
else
lines += span_warning("Organic organs detected. Robotic organs only, cannot take over.")
to_chat(user, boxed_message(jointext(lines, "\n")), type = MESSAGE_TYPE_INFO)
/obj/item/organ/brain/cybernetic/ai/Topic(href, href_list)
..()
if(!href_list["ai_take_control"] || !is_sufficiently_augmented())
return
var/mob/living/silicon/ai/AI = locate(href_list["ai_take_control"]) in GLOB.silicon_mobs
if(isnull(AI))
return
if(AI.controlled_equipment)
to_chat(AI, span_warning("You are already loaded into an onboard computer!"))
return
if(!GLOB.cameranet.checkCameraVis(owner))
to_chat(AI, span_warning("Target is no longer near active cameras."))
return
if(!isturf(AI.loc))
to_chat(AI, span_warning("You aren't in your core!"))
return
RegisterSignal(owner, COMSIG_LIVING_DEATH, PROC_REF(undeploy))
AI.deployed_shell = owner
deploy_init(AI)
ADD_TRAIT(AI.mind, TRAIT_UNCONVERTABLE, ORGAN_TRAIT)
AI.mind.transfer_to(owner)
/obj/item/organ/brain/cybernetic/ai/proc/deploy_init(mob/living/silicon/ai/AI)
//todo camera maybe
mainframe = AI
RegisterSignal(AI, COMSIG_QDELETING, PROC_REF(ai_deleted))
undeployment_action.Grant(owner)
update_med_hud_status(owner)
to_chat(owner, span_boldbig("You are still considered a silicon/cyborg/AI. Follow your laws."))
/obj/item/organ/brain/cybernetic/ai/proc/undeploy(datum/source)
SIGNAL_HANDLER
if(!owner?.mind || !mainframe)
return
UnregisterSignal(src, list(COMSIG_LIVING_DEATH, COMSIG_QDELETING))
mainframe.redeploy_action.Remove(mainframe)
mainframe.redeploy_action.last_used_shell = null
owner.mind.transfer_to(mainframe)
mainframe.deployed_shell = null
undeployment_action.Remove(owner)
if(mainframe.laws)
mainframe.laws.show_laws(mainframe)
if(mainframe.eyeobj)
mainframe.eyeobj.setLoc(loc)
REMOVE_TRAIT(mainframe.mind, TRAIT_UNCONVERTABLE, ORGAN_TRAIT)
mainframe = null
update_med_hud_status(owner)
/obj/item/organ/brain/cybernetic/ai/proc/is_sufficiently_augmented()
var/mob/living/carbon/carb_owner = owner
. = TRUE
if(!istype(carb_owner))
return
for(var/obj/item/organ/organ as anything in carb_owner.organs)
if(organ.organ_flags & ORGAN_EXTERNAL)
continue
if(!IS_ROBOTIC_ORGAN(organ) && !istype(organ, /obj/item/organ/tongue)) //tongues are not in the exosuit fab and nobody is going to bother to find them so
return FALSE
/obj/item/organ/brain/cybernetic/ai/proc/on_organ_gain(datum/source, obj/item/organ/new_organ, special)
SIGNAL_HANDLER
if(!is_sufficiently_augmented())
to_chat(owner, span_danger("Connection failure. Organics detected."))
undeploy()
/obj/item/organ/brain/cybernetic/ai/proc/ai_deleted(datum/source)
SIGNAL_HANDLER
to_chat(owner, span_danger("Your core has been rendered inoperable..."))
undeploy()