mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-23 05:00:55 +01:00
[MIRROR] Turns Changeling Headslugs into a Basic Mob [MDB IGNORE] (#21690)
* Turns Changeling Headslugs into a Basic Mob * fix --------- Co-authored-by: san7890 <the@san7890.com> Co-authored-by: ghost sheep <sheepwiththemask@gmail.com>
This commit is contained in:
co-authored by
san7890
ghost sheep
parent
85c31e1256
commit
c968dca9b2
@@ -255,7 +255,9 @@
|
||||
/mob/living/basic/cow/wisdom,
|
||||
/mob/living/basic/giant_spider,
|
||||
/mob/living/basic/giant_spider/hunter,
|
||||
/mob/living/basic/headslug,
|
||||
/mob/living/basic/killer_tomato,
|
||||
/mob/living/basic/lizard,
|
||||
/mob/living/basic/mouse,
|
||||
/mob/living/basic/pet/dog/breaddog,
|
||||
/mob/living/basic/pet/dog/corgi,
|
||||
@@ -269,8 +271,6 @@
|
||||
/mob/living/simple_animal/hostile/bear,
|
||||
/mob/living/simple_animal/hostile/blob/blobbernaut/independent,
|
||||
/mob/living/simple_animal/hostile/gorilla,
|
||||
/mob/living/simple_animal/hostile/headcrab,
|
||||
/mob/living/basic/lizard,
|
||||
/mob/living/simple_animal/hostile/megafauna/dragon/lesser,
|
||||
/mob/living/simple_animal/hostile/morph,
|
||||
/mob/living/simple_animal/hostile/mushroom,
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
#define EGG_INCUBATION_TIME (4 MINUTES)
|
||||
|
||||
/// The actual organ that the changeling headslug implants into a dead host.
|
||||
/obj/item/organ/internal/body_egg/changeling_egg
|
||||
name = "changeling egg"
|
||||
desc = "Twitching and disgusting."
|
||||
/// The mind of the original changeling that gave forth to the headslug mob.
|
||||
var/datum/mind/origin
|
||||
/// Tracks how long the egg has been growing.
|
||||
var/time = 0
|
||||
|
||||
/obj/item/organ/internal/body_egg/changeling_egg/egg_process(seconds_per_tick, times_fired)
|
||||
// Changeling eggs grow in dead people
|
||||
time += seconds_per_tick * 10
|
||||
if(time >= EGG_INCUBATION_TIME)
|
||||
pop()
|
||||
|
||||
/// Once the egg is fully grown, we gib the host and spawn a monkey (with the changeling's player controlling it). Very descriptive proc name.
|
||||
/obj/item/organ/internal/body_egg/changeling_egg/proc/pop()
|
||||
var/mob/living/carbon/human/spawned_monkey = new(owner)
|
||||
spawned_monkey.set_species(/datum/species/monkey)
|
||||
|
||||
for(var/obj/item/organ/insertable in src)
|
||||
insertable.Insert(spawned_monkey, 1)
|
||||
|
||||
if(origin && (origin.current ? (origin.current.stat == DEAD) : origin.get_ghost()))
|
||||
origin.transfer_to(spawned_monkey)
|
||||
spawned_monkey.key = origin.key
|
||||
var/datum/antagonist/changeling/changeling_datum = origin.has_antag_datum(/datum/antagonist/changeling)
|
||||
if(!changeling_datum)
|
||||
changeling_datum = origin.add_antag_datum(/datum/antagonist/changeling/headslug)
|
||||
if(changeling_datum.can_absorb_dna(owner))
|
||||
changeling_datum.add_new_profile(owner)
|
||||
|
||||
var/datum/action/changeling/lesserform/transform = new()
|
||||
changeling_datum.purchased_powers[transform.type] = transform
|
||||
changeling_datum.regain_powers()
|
||||
|
||||
owner.investigate_log("has been gibbed by a changeling egg burst.", INVESTIGATE_DEATHS)
|
||||
owner.gib()
|
||||
qdel(src)
|
||||
|
||||
#undef EGG_INCUBATION_TIME
|
||||
@@ -40,13 +40,10 @@
|
||||
addtimer(CALLBACK(src, PROC_REF(spawn_headcrab), stored_mind, user_turf, organs), 3 SECONDS)
|
||||
|
||||
/datum/action/changeling/headcrab/proc/spawn_headcrab(datum/mind/stored_mind, turf/spawn_location, list/organs)
|
||||
var/mob/living/simple_animal/hostile/headcrab/crab = new(spawn_location)
|
||||
var/mob/living/basic/headslug/crab = new(spawn_location)
|
||||
for(var/obj/item/organ/I in organs)
|
||||
I.forceMove(crab)
|
||||
crab.origin = stored_mind
|
||||
if(!crab.origin)
|
||||
return
|
||||
crab.origin.active = TRUE
|
||||
crab.origin.transfer_to(crab)
|
||||
|
||||
stored_mind.transfer_to(crab)
|
||||
spawn_location.transfer_observers_to(crab)
|
||||
to_chat(crab, span_warning("You burst out of the remains of your former body in a shower of gore!"))
|
||||
|
||||
@@ -56,7 +56,7 @@
|
||||
if(contents.len >= max_occupants)
|
||||
to_chat(user, span_warning("[src] are full!"))
|
||||
return
|
||||
if(istype(target, /mob/living/simple_animal/hostile/retaliate/snake) || istype(target, /mob/living/simple_animal/hostile/headcrab) || islarva(target))
|
||||
if(istype(target, /mob/living/simple_animal/hostile/retaliate/snake) || istype(target, /mob/living/basic/headslug) || islarva(target))
|
||||
target.forceMove(src)
|
||||
to_chat(user, span_notice("[target] slithers into [src]."))
|
||||
|
||||
|
||||
@@ -0,0 +1,92 @@
|
||||
/**
|
||||
* ## Headslugs
|
||||
*
|
||||
* Player-controlled slugs that arise from a changeling ability in order to live on in an extremely limited capacity until they can find a suitable corpse to inhabit.
|
||||
*/
|
||||
/mob/living/basic/headslug
|
||||
name = "headslug"
|
||||
desc = "A small, slug-like creature with a large, gaping maw. It's covered in a thick, slimy mucus."
|
||||
icon_state = "headslug"
|
||||
icon_living = "headslug"
|
||||
icon_dead = "headslug_dead"
|
||||
gender = NEUTER
|
||||
health = 50
|
||||
maxHealth = 50
|
||||
melee_damage_lower = 5
|
||||
melee_damage_upper = 5
|
||||
attack_verb_continuous = "chomps"
|
||||
attack_verb_simple = "chomp"
|
||||
attack_sound = 'sound/weapons/bite.ogg'
|
||||
attack_vis_effect = ATTACK_EFFECT_BITE
|
||||
faction = list(FACTION_CREATURE)
|
||||
obj_damage = 0
|
||||
environment_smash = ENVIRONMENT_SMASH_NONE
|
||||
speak_emote = list("squeaks")
|
||||
|
||||
ai_controller = /datum/ai_controller/basic_controller/headslug
|
||||
|
||||
/// Set to true once we've implanted our egg
|
||||
var/egg_lain = FALSE
|
||||
|
||||
/mob/living/basic/headslug/Initialize(mapload)
|
||||
. = ..()
|
||||
ADD_TRAIT(src, TRAIT_VENTCRAWLER_ALWAYS, INNATE_TRAIT)
|
||||
RegisterSignal(src, COMSIG_HOSTILE_POST_ATTACKINGTARGET, PROC_REF(check_and_implant))
|
||||
|
||||
/mob/living/basic/headslug/Destroy()
|
||||
UnregisterSignal(src, COMSIG_HOSTILE_POST_ATTACKINGTARGET)
|
||||
return ..()
|
||||
|
||||
/mob/living/basic/headslug/examine(mob/user)
|
||||
. = ..()
|
||||
if(isnull(client))
|
||||
. += span_notice("It appears to be moving around listlessly.")
|
||||
else
|
||||
. += span_warning("It's moving around intelligently!")
|
||||
|
||||
/// Signal Handler proc that runs on every attack and checks to see if this is a valid target for implantation. If so, it implants the egg and starts the countdown to death.
|
||||
/mob/living/basic/headslug/proc/check_and_implant(mob/living/basic/attacker, atom/target)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
if (egg_lain || !iscarbon(target) || ismonkey(target))
|
||||
return
|
||||
|
||||
var/mob/living/carbon/victim = target
|
||||
if(victim.stat == DEAD)
|
||||
return
|
||||
if(HAS_TRAIT(victim, TRAIT_XENO_HOST))
|
||||
target.balloon_alert(src, "already pregnant!") // Maybe the worst balloon alert in the codebase
|
||||
return
|
||||
|
||||
if(!infect(victim))
|
||||
target.balloon_alert(src, "failed to implant egg!")
|
||||
stack_trace("[key] in [src] failed to implant egg in [victim], despite all checks suggesting it should have worked!")
|
||||
return
|
||||
|
||||
egg_lain = TRUE
|
||||
to_chat(src, span_userdanger("With our egg laid, our death approaches rapidly..."))
|
||||
addtimer(CALLBACK(src, PROC_REF(death)), 10 SECONDS)
|
||||
|
||||
/// Simply infects the target corpse with our changeling eggs. This shouldn't fail, because all checks should have been done in check_and_implant()
|
||||
/// Just to be super-duper safe to the player, we do return TRUE if all goes well and read that value in check_and_implant() to be nice to the player.
|
||||
/mob/living/basic/headslug/proc/infect(mob/living/carbon/victim)
|
||||
var/obj/item/organ/internal/body_egg/changeling_egg/egg = new(victim)
|
||||
egg.Insert(victim)
|
||||
|
||||
egg.origin = mind
|
||||
|
||||
for(var/obj/item/organ/target in src)
|
||||
target.forceMove(egg)
|
||||
|
||||
visible_message(
|
||||
span_warning("[src] plants something in [victim]'s flesh!"),
|
||||
span_danger("We inject our egg into [victim]'s body!"),
|
||||
)
|
||||
|
||||
return TRUE
|
||||
|
||||
/// This is a bit neutered since these aren't intended to exist outside of player control, but it's a bit weird to just have these guys be completely stationary.
|
||||
/// No attacking or anything like that, though. Just something so they seem alive.
|
||||
/datum/ai_controller/basic_controller/headslug
|
||||
ai_movement = /datum/ai_movement/basic_avoidance
|
||||
idle_behavior = /datum/idle_behavior/idle_random_walk
|
||||
@@ -1445,6 +1445,7 @@
|
||||
/mob/living/basic/cow,
|
||||
/mob/living/basic/giant_spider,
|
||||
/mob/living/basic/giant_spider/hunter,
|
||||
/mob/living/basic/headslug,
|
||||
/mob/living/basic/killer_tomato,
|
||||
/mob/living/basic/lizard,
|
||||
/mob/living/basic/mouse,
|
||||
@@ -1460,7 +1461,6 @@
|
||||
/mob/living/simple_animal/hostile/bear,
|
||||
/mob/living/simple_animal/hostile/blob/blobbernaut/independent,
|
||||
/mob/living/simple_animal/hostile/gorilla,
|
||||
/mob/living/simple_animal/hostile/headcrab,
|
||||
/mob/living/simple_animal/hostile/megafauna/dragon/lesser,
|
||||
/mob/living/simple_animal/hostile/morph,
|
||||
/mob/living/simple_animal/hostile/mushroom,
|
||||
|
||||
@@ -1,113 +0,0 @@
|
||||
#define EGG_INCUBATION_TIME (4 MINUTES)
|
||||
|
||||
/mob/living/simple_animal/hostile/headcrab
|
||||
name = "headslug"
|
||||
desc = "Absolutely not de-beaked or harmless. Keep away from corpses."
|
||||
icon_state = "headcrab"
|
||||
icon_living = "headcrab"
|
||||
icon_dead = "headcrab_dead"
|
||||
gender = NEUTER
|
||||
health = 50
|
||||
maxHealth = 50
|
||||
melee_damage_lower = 5
|
||||
melee_damage_upper = 5
|
||||
attack_verb_continuous = "chomps"
|
||||
attack_verb_simple = "chomp"
|
||||
attack_sound = 'sound/weapons/bite.ogg'
|
||||
attack_vis_effect = ATTACK_EFFECT_BITE
|
||||
faction = list(FACTION_CREATURE)
|
||||
robust_searching = 1
|
||||
stat_attack = DEAD
|
||||
obj_damage = 0
|
||||
environment_smash = ENVIRONMENT_SMASH_NONE
|
||||
speak_emote = list("squeaks")
|
||||
/// The mind to transfer to our egg when it hatches
|
||||
var/datum/mind/origin
|
||||
/// Set to true once we've implanted our egg
|
||||
var/egg_lain = FALSE
|
||||
|
||||
/mob/living/simple_animal/hostile/headcrab/Initialize(mapload)
|
||||
. = ..()
|
||||
ADD_TRAIT(src, TRAIT_VENTCRAWLER_ALWAYS, INNATE_TRAIT)
|
||||
|
||||
/mob/living/simple_animal/hostile/headcrab/proc/Infect(mob/living/carbon/victim)
|
||||
var/obj/item/organ/internal/body_egg/changeling_egg/egg = new(victim)
|
||||
egg.Insert(victim)
|
||||
if(origin)
|
||||
egg.origin = origin
|
||||
else if(mind) // Let's make this a feature
|
||||
egg.origin = mind
|
||||
for(var/obj/item/organ/I in src)
|
||||
I.forceMove(egg)
|
||||
visible_message(span_warning("[src] plants something in [victim]'s flesh!"), \
|
||||
span_danger("We inject our egg into [victim]'s body!"))
|
||||
egg_lain = TRUE
|
||||
|
||||
/mob/living/simple_animal/hostile/headcrab/AttackingTarget()
|
||||
. = ..()
|
||||
if (!. || egg_lain || !iscarbon(target) || ismonkey(target))
|
||||
return
|
||||
var/mob/living/carbon/victim = target
|
||||
if(victim.stat != DEAD)
|
||||
return
|
||||
if(HAS_TRAIT(victim, TRAIT_XENO_HOST))
|
||||
target.balloon_alert(src, "already pregnant!") // Maybe the worst balloon alert in the codebase
|
||||
return
|
||||
Infect(target)
|
||||
to_chat(src, span_userdanger("With our egg laid, our death approaches rapidly..."))
|
||||
addtimer(CALLBACK(src, PROC_REF(death)), 10 SECONDS)
|
||||
|
||||
/obj/item/organ/internal/body_egg/changeling_egg
|
||||
name = "changeling egg"
|
||||
desc = "Twitching and disgusting."
|
||||
var/datum/mind/origin
|
||||
var/time = 0
|
||||
|
||||
/obj/item/organ/internal/body_egg/changeling_egg/egg_process(seconds_per_tick, times_fired)
|
||||
// Changeling eggs grow in dead people
|
||||
time += seconds_per_tick * 10
|
||||
if(time >= EGG_INCUBATION_TIME)
|
||||
Pop()
|
||||
Remove(owner)
|
||||
qdel(src)
|
||||
|
||||
/obj/item/organ/internal/body_egg/changeling_egg/proc/Pop()
|
||||
// SKYRAT EDIT START
|
||||
var/mob/living/carbon/human/species/monkey/spawned_monkey = new(owner)
|
||||
var/datum/dna/current_dna = spawned_monkey.dna
|
||||
for(var/key in current_dna.mutant_bodyparts)
|
||||
LAZYSET(current_dna.mutant_bodyparts, key, "None")
|
||||
for(var/key in current_dna.body_markings)
|
||||
LAZYSET(current_dna.body_markings, key, null)
|
||||
if(current_dna.features["body_size"])
|
||||
LAZYSET(current_dna.features, "body_size", 1)
|
||||
if(current_dna.features["legs"])
|
||||
LAZYREMOVE(current_dna.features, "legs")
|
||||
spawned_monkey.set_species(/datum/species/monkey)
|
||||
for(var/scar in spawned_monkey.all_scars)
|
||||
var/datum/scar/iter_scar = scar
|
||||
if(iter_scar.fake)
|
||||
qdel(iter_scar)
|
||||
spawned_monkey.regenerate_icons()
|
||||
// SKYRAT EDIT END
|
||||
|
||||
for(var/obj/item/organ/I in src)
|
||||
I.Insert(spawned_monkey, 1)
|
||||
|
||||
if(origin && (origin.current ? (origin.current.stat == DEAD) : origin.get_ghost()))
|
||||
origin.transfer_to(spawned_monkey)
|
||||
spawned_monkey.key = origin.key
|
||||
var/datum/antagonist/changeling/changeling_datum = origin.has_antag_datum(/datum/antagonist/changeling)
|
||||
if(!changeling_datum)
|
||||
changeling_datum = origin.add_antag_datum(/datum/antagonist/changeling/headslug)
|
||||
if(changeling_datum.can_absorb_dna(owner))
|
||||
changeling_datum.add_new_profile(owner)
|
||||
|
||||
var/datum/action/changeling/lesserform/transform = new()
|
||||
changeling_datum.purchased_powers[transform.type] = transform
|
||||
changeling_datum.regain_powers()
|
||||
|
||||
owner.investigate_log("has been gibbed by a changeling egg burst.", INVESTIGATE_DEATHS)
|
||||
owner.gib()
|
||||
|
||||
#undef EGG_INCUBATION_TIME
|
||||
@@ -48,10 +48,10 @@
|
||||
|
||||
/// Dead headcrab for changeling-themed ruins
|
||||
/obj/effect/mob_spawn/corpse/headcrab
|
||||
mob_type = /mob/living/simple_animal/hostile/headcrab
|
||||
mob_type = /mob/living/basic/headslug
|
||||
icon = 'icons/mob/simple/animal.dmi'
|
||||
icon_state = "headcrab_dead"
|
||||
icon_state = "headslug_dead"
|
||||
|
||||
/obj/effect/mob_spawn/corpse/headcrab/special(mob/living/simple_animal/hostile/headcrab/crab)
|
||||
/obj/effect/mob_spawn/corpse/headcrab/special(mob/living/basic/headslug/crab)
|
||||
. = ..()
|
||||
crab.egg_lain = TRUE // Prevents using mad science to become a changeling
|
||||
|
||||
@@ -156,7 +156,6 @@
|
||||
/mob/living/simple_animal/hostile/guardian/ranged,
|
||||
/mob/living/simple_animal/hostile/guardian/standard,
|
||||
/mob/living/simple_animal/hostile/guardian/support,
|
||||
/mob/living/simple_animal/hostile/headcrab,
|
||||
/mob/living/simple_animal/hostile/heretic_summon,
|
||||
/mob/living/simple_animal/hostile/heretic_summon/armsy,
|
||||
/mob/living/simple_animal/hostile/heretic_summon/armsy/prime,
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 276 KiB After Width: | Height: | Size: 276 KiB |
+2
-1
@@ -2595,6 +2595,7 @@
|
||||
#include "code\modules\antagonists\changeling\changeling.dm"
|
||||
#include "code\modules\antagonists\changeling\changeling_power.dm"
|
||||
#include "code\modules\antagonists\changeling\fallen_changeling.dm"
|
||||
#include "code\modules\antagonists\changeling\headslug_eggs.dm"
|
||||
#include "code\modules\antagonists\changeling\powers\absorb.dm"
|
||||
#include "code\modules\antagonists\changeling\powers\adrenaline.dm"
|
||||
#include "code\modules\antagonists\changeling\powers\augmented_eyesight.dm"
|
||||
@@ -4052,6 +4053,7 @@
|
||||
#include "code\modules\mob\living\basic\space_fauna\faithless.dm"
|
||||
#include "code\modules\mob\living\basic\space_fauna\garden_gnome.dm"
|
||||
#include "code\modules\mob\living\basic\space_fauna\ghost.dm"
|
||||
#include "code\modules\mob\living\basic\space_fauna\headslug.dm"
|
||||
#include "code\modules\mob\living\basic\space_fauna\killer_tomato.dm"
|
||||
#include "code\modules\mob\living\basic\space_fauna\lightgeist.dm"
|
||||
#include "code\modules\mob\living\basic\space_fauna\carp\carp.dm"
|
||||
@@ -4297,7 +4299,6 @@
|
||||
#include "code\modules\mob\living\simple_animal\hostile\blobspore.dm"
|
||||
#include "code\modules\mob\living\simple_animal\hostile\dark_wizard.dm"
|
||||
#include "code\modules\mob\living\simple_animal\hostile\eyeballs.dm"
|
||||
#include "code\modules\mob\living\simple_animal\hostile\headcrab.dm"
|
||||
#include "code\modules\mob\living\simple_animal\hostile\heretic_monsters.dm"
|
||||
#include "code\modules\mob\living\simple_animal\hostile\hivebot.dm"
|
||||
#include "code\modules\mob\living\simple_animal\hostile\hostile.dm"
|
||||
|
||||
Reference in New Issue
Block a user