mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-01-12 02:22:11 +00:00
* refactor: Movement cross/uncross implementation.
* wrong var name
* fix unit tests dropping PDAs into nowhere
* Add documentation.
* remove unused constants
* say which procs are off limits
* fix simpleanimal z change runtime
* helps not to leave merge conflicts
* kill me
* fix typecast
* fix projectile/table collision
* treadmills don't cause MC to crash anymore
* connect_loc is appropriate here
* fix windoors and teleporters
* fix bonfires and clarify docs
* fix proximity sensors
Tested with sensors in crates, sensors in modsuits
Tested new proximity component with firing projectiles at singularity
Tested new proximity component with portable flashes
Tested new proximity component with facehuggers
* lint
* fix: polarized access helper false positives
* Revert "fix: polarized access helper false positives"
This reverts commit 9814f98cf6.
* hopefully the right change for mindflayer steam
* Changes following cameras
* fix glass table collision
* appears to fix doorspam
* fix ore bags not picking up ore
* fix signatures of /Exited
* remove debug log
* remove duplicate signal registrar
* fix emptying bags into locations
* I don't trust these nested Move calls
* use connect_loc for upgraded resonator fields
* use moveToNullspace
* fix spiderweb crossing
* fix pass checking for windows from a tile off
* fix bluespace closet/transparency issues
* fix mechs not interacting with doors and probably other things
* fix debug
* fix telepete
* add some docs
* stop trying to shoehorn prox monitor into cards
* I should make sure things build
* kill override signal warning
* undef signal
* not many prox monitors survive going off like this
* small fixes to storage
* make moving wormholes respect signals
* use correct signals for pulse demon
* fix pulse heart too
* fix smoke signals
* may have fucked singulo projectile swerve
* fix singulo projectile arcing
* remove duplicate define
* just look at it
* hopefully last cleanups of incorrect signal usage
* fix squeaking
* may god have mercy on my soul
* Apply suggestions from code review
Co-authored-by: Luc <89928798+lewcc@users.noreply.github.com>
Signed-off-by: warriorstar-orion <orion@snowfrost.garden>
* lewc review
* Apply suggestions from code review
Co-authored-by: Burzah <116982774+Burzah@users.noreply.github.com>
Signed-off-by: warriorstar-orion <orion@snowfrost.garden>
* burza review
* fix bad args for grenade assemblies
* Update code/__DEFINES/is_helpers.dm
Co-authored-by: Luc <89928798+lewcc@users.noreply.github.com>
Signed-off-by: warriorstar-orion <orion@snowfrost.garden>
---------
Signed-off-by: warriorstar-orion <orion@snowfrost.garden>
Co-authored-by: DGamerL <daan.lyklema@gmail.com>
Co-authored-by: Luc <89928798+lewcc@users.noreply.github.com>
Co-authored-by: Burzah <116982774+Burzah@users.noreply.github.com>
575 lines
16 KiB
Plaintext
575 lines
16 KiB
Plaintext
/* Alien structures!
|
|
* Contains:
|
|
* structure/alien
|
|
* Resin
|
|
* Weeds
|
|
* Eggs
|
|
*/
|
|
|
|
#define WEED_NORTH_EDGING "north"
|
|
#define WEED_SOUTH_EDGING "south"
|
|
#define WEED_EAST_EDGING "east"
|
|
#define WEED_WEST_EDGING "west"
|
|
|
|
/obj/structure/alien
|
|
icon = 'icons/mob/alien.dmi'
|
|
max_integrity = 100
|
|
|
|
/obj/structure/alien/run_obj_armor(damage_amount, damage_type, damage_flag = 0, attack_dir)
|
|
if(damage_flag == MELEE)
|
|
switch(damage_type)
|
|
if(BRUTE)
|
|
damage_amount *= 0.25
|
|
if(BURN)
|
|
damage_amount *= 2
|
|
. = ..()
|
|
|
|
/obj/structure/alien/play_attack_sound(damage_amount, damage_type = BRUTE, damage_flag = 0)
|
|
switch(damage_type)
|
|
if(BRUTE)
|
|
if(damage_amount)
|
|
playsound(loc, 'sound/effects/attackblob.ogg', 100, TRUE)
|
|
else
|
|
playsound(src, 'sound/weapons/tap.ogg', 50, TRUE)
|
|
if(BURN)
|
|
if(damage_amount)
|
|
playsound(loc, 'sound/items/welder.ogg', 100, TRUE)
|
|
|
|
/*
|
|
* Resin
|
|
*/
|
|
/obj/structure/alien/resin
|
|
name = "resin"
|
|
desc = "Looks like some kind of thick resin."
|
|
icon = 'icons/obj/smooth_structures/alien/resin_wall.dmi'
|
|
icon_state = "resin_wall-0"
|
|
base_icon_state = "resin_wall"
|
|
density = TRUE
|
|
opacity = TRUE
|
|
anchored = TRUE
|
|
smoothing_flags = SMOOTH_BITMASK
|
|
smoothing_groups = list(SMOOTH_GROUP_ALIEN_RESIN)
|
|
canSmoothWith = list(SMOOTH_GROUP_ALIEN_RESIN)
|
|
max_integrity = 200
|
|
var/resintype = null
|
|
var/is_alien = TRUE
|
|
|
|
/obj/structure/alien/resin/Initialize(mapload)
|
|
recalculate_atmos_connectivity()
|
|
if(!is_alien)
|
|
return ..()
|
|
for(var/obj/structure/alien/weeds/node/W in get_turf(src))
|
|
qdel(W)
|
|
if(locate(/obj/structure/alien/weeds) in get_turf(src))
|
|
return ..()
|
|
new /obj/structure/alien/weeds(loc, src)
|
|
return ..()
|
|
|
|
/obj/structure/alien/resin/Destroy()
|
|
var/turf/T = get_turf(src)
|
|
playsound(loc, 'sound/effects/alien_resin_break2.ogg', 100, TRUE)
|
|
. = ..()
|
|
T.recalculate_atmos_connectivity()
|
|
|
|
/obj/structure/alien/resin/Move()
|
|
var/turf/T = loc
|
|
..()
|
|
move_update_air(T)
|
|
|
|
/obj/structure/alien/resin/CanAtmosPass(direction)
|
|
return !density
|
|
|
|
/obj/structure/alien/resin/attack_alien(mob/living/carbon/alien/humanoid/user)
|
|
if(user.a_intent != INTENT_HARM)
|
|
return
|
|
to_chat(user, "<span class='noticealien'>We begin tearing down this resin structure.</span>")
|
|
if(!do_after(user, 40, target = src) || QDELETED(src))
|
|
return
|
|
qdel(src)
|
|
|
|
/obj/structure/alien/resin/wall
|
|
name = "resin wall"
|
|
desc = "Thick resin solidified into a wall."
|
|
icon = 'icons/obj/smooth_structures/alien/resin_wall.dmi'
|
|
icon_state = "resin_wall-0"
|
|
base_icon_state = "resin_wall"
|
|
smoothing_groups = list(SMOOTH_GROUP_ALIEN_RESIN, SMOOTH_GROUP_ALIEN_WALLS)
|
|
canSmoothWith = list(SMOOTH_GROUP_ALIEN_WALLS)
|
|
|
|
/obj/structure/alien/resin/wall/get_superconductivity(direction)
|
|
return FALSE
|
|
|
|
/*
|
|
*Resin-Door - Borrows its code from Mineral-Door, not a subtype due to needing many overrides if so
|
|
*/
|
|
/obj/structure/alien/resin/door
|
|
name = "resin door"
|
|
density = TRUE
|
|
anchored = TRUE
|
|
opacity = TRUE
|
|
|
|
icon = 'icons/obj/smooth_structures/alien/resin_door.dmi'
|
|
icon_state = "resin"
|
|
base_icon_state = "resin"
|
|
max_integrity = 60
|
|
armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, RAD = 0, FIRE = 50, ACID = 50)
|
|
damage_deflection = 0
|
|
flags_2 = RAD_PROTECT_CONTENTS_2 | RAD_NO_CONTAMINATE_2
|
|
rad_insulation = RAD_MEDIUM_INSULATION
|
|
var/initial_state
|
|
var/state_open = FALSE
|
|
var/is_operating = FALSE
|
|
var/close_delay = 3 SECONDS
|
|
smoothing_flags = null
|
|
var/open_sound = 'sound/machines/alien_airlock.ogg'
|
|
var/close_sound = 'sound/machines/alien_airlock.ogg'
|
|
|
|
smoothing_groups = list(SMOOTH_GROUP_ALIEN_RESIN, SMOOTH_GROUP_ALIEN_WALLS)
|
|
canSmoothWith = list(SMOOTH_GROUP_ALIEN_WALLS)
|
|
|
|
/obj/structure/alien/resin/door/Initialize(mapload)
|
|
. = ..()
|
|
initial_state = icon_state
|
|
QUEUE_SMOOTH_NEIGHBORS(src)
|
|
|
|
/obj/structure/alien/resin/door/Destroy()
|
|
density = FALSE
|
|
QUEUE_SMOOTH_NEIGHBORS(src)
|
|
recalculate_atmos_connectivity()
|
|
return ..()
|
|
|
|
/obj/structure/alien/resin/door/Move()
|
|
var/turf/T = loc
|
|
. = ..()
|
|
move_update_air(T)
|
|
|
|
/obj/structure/alien/resin/door/attack_ai(mob/user)
|
|
return
|
|
|
|
/obj/structure/alien/resin/door/attack_hand(mob/user)
|
|
return try_to_operate(user)
|
|
|
|
/obj/structure/alien/resin/door/attack_ghost(mob/user)
|
|
if(user.can_advanced_admin_interact())
|
|
operate()
|
|
|
|
/obj/structure/alien/resin/door/CanAtmosPass(direction)
|
|
return !density
|
|
|
|
/obj/structure/alien/resin/door/proc/try_to_operate(mob/user, bumped_open = FALSE)
|
|
if(is_operating)
|
|
return
|
|
if(!iscarbon(user))
|
|
return
|
|
var/mob/living/carbon/C = user
|
|
if(C.get_int_organ(/obj/item/organ/internal/alien/hivenode))
|
|
if(!C.handcuffed)
|
|
operate(bumped_open)
|
|
return
|
|
to_chat(user, "<span class='noticealien'>Your lack of connection to the hive prevents the resin door from opening</span>")
|
|
/*
|
|
* This 2nd try_to_operate() is needed so that CALLBACK can close the door without having to either call operate() and get bugged when clicked much or
|
|
* call try_to_operate(atom/user) and not be able to use it due to not having a mob using it
|
|
*/
|
|
/obj/structure/alien/resin/door/proc/mobless_try_to_operate()
|
|
if(is_operating)
|
|
if(state_open)
|
|
addtimer(CALLBACK(src, PROC_REF(mobless_try_to_operate)), close_delay)
|
|
return
|
|
operate()
|
|
|
|
/obj/structure/alien/resin/door/proc/operate(bumped_open = FALSE)
|
|
is_operating = TRUE
|
|
if(!state_open)
|
|
playsound(loc, open_sound, 50, TRUE)
|
|
flick("[initial_state]opening", src)
|
|
else
|
|
for(var/mob/living/L in get_turf(src))
|
|
is_operating = FALSE
|
|
if(state_open)
|
|
addtimer(CALLBACK(src, PROC_REF(mobless_try_to_operate)), close_delay)
|
|
return
|
|
playsound(loc, close_sound, 50, 1)
|
|
flick("[initial_state]closing", src)
|
|
density = !density
|
|
opacity = !opacity
|
|
state_open = !state_open
|
|
addtimer(CALLBACK(src, PROC_REF(operate_update), bumped_open), 1 SECONDS)
|
|
|
|
/obj/structure/alien/resin/door/proc/operate_update(bumped_open)
|
|
recalculate_atmos_connectivity()
|
|
update_icon(UPDATE_ICON_STATE)
|
|
is_operating = FALSE
|
|
|
|
if(state_open && bumped_open)
|
|
addtimer(CALLBACK(src, PROC_REF(mobless_try_to_operate)), close_delay)
|
|
|
|
/obj/structure/alien/resin/door/update_icon_state()
|
|
icon_state = state_open ? "[initial_state]open" : initial_state
|
|
|
|
/obj/structure/alien/resin/door/attack_alien(mob/living/carbon/alien/humanoid/user)
|
|
if(user.a_intent != INTENT_HARM)
|
|
try_to_operate(user)
|
|
return
|
|
to_chat(user, "<span class='noticealien'>We begin tearing down this resin structure.</span>")
|
|
if(!do_after(user, 40, target = src) || QDELETED(src))
|
|
return
|
|
qdel(src)
|
|
|
|
/obj/structure/alien/resin/door/Bumped(atom/user)
|
|
..()
|
|
if(!state_open)
|
|
return try_to_operate(user, TRUE)
|
|
|
|
/*
|
|
* Weeds
|
|
*/
|
|
|
|
#define NODERANGE 3
|
|
|
|
/obj/structure/alien/weeds
|
|
gender = PLURAL
|
|
name = "resin floor"
|
|
desc = "A thick resin surface covers the floor."
|
|
anchored = TRUE
|
|
density = FALSE
|
|
plane = FLOOR_PLANE
|
|
icon = 'icons/obj/smooth_structures/alien/weeds.dmi'
|
|
icon_state = "weeds"
|
|
base_icon_state = "weeds"
|
|
max_integrity = 15
|
|
layer = ABOVE_ICYOVERLAY_LAYER
|
|
smoothing_flags = SMOOTH_BITMASK
|
|
smoothing_groups = list(SMOOTH_GROUP_ALIEN_RESIN, SMOOTH_GROUP_ALIEN_WEEDS)
|
|
canSmoothWith = list(SMOOTH_GROUP_ALIEN_WEEDS, SMOOTH_GROUP_WALLS)
|
|
creates_cover = TRUE
|
|
var/obj/structure/alien/weeds/node/linked_node = null
|
|
var/obj/structure/alien/wallweed/wall_weed // This var is used to handle wall-weed interactions for when they need to be deleted
|
|
var/static/list/weedImageCache
|
|
var/check_counter // This var is how many process() procs it takes for a weed to spread
|
|
/// This var is used for making automatic weed removals silent instead of making them produce the breaking sound
|
|
var/silent_removal = FALSE
|
|
|
|
/obj/structure/alien/weeds/Initialize(mapload, node)
|
|
. = ..()
|
|
linked_node = node
|
|
if(isspaceturf(loc))
|
|
qdel(src)
|
|
return
|
|
check_surroundings()
|
|
START_PROCESSING(SSobj, src)
|
|
RegisterSignal(linked_node, COMSIG_PARENT_QDELETING, PROC_REF(clear_linked_node))
|
|
|
|
/obj/structure/alien/weeds/Destroy()
|
|
STOP_PROCESSING(SSobj, src)
|
|
QUEUE_SMOOTH_NEIGHBORS(src)
|
|
if(!silent_removal)
|
|
playsound(loc, pick('sound/effects/alien_resin_break2.ogg','sound/effects/alien_resin_break1.ogg'), 50, FALSE)
|
|
linked_node = null
|
|
clear_wall_weed()
|
|
return ..()
|
|
|
|
/obj/structure/alien/weeds/proc/clear_linked_node()
|
|
SIGNAL_HANDLER
|
|
UnregisterSignal(linked_node, COMSIG_PARENT_QDELETING)
|
|
linked_node = null
|
|
|
|
/obj/structure/alien/weeds/attack_alien(mob/living/carbon/alien/humanoid/user)
|
|
if(user.a_intent != INTENT_HARM)
|
|
return
|
|
return ..()
|
|
|
|
/obj/structure/alien/weeds/process()
|
|
check_counter++
|
|
if(check_counter >= 5)
|
|
spread()
|
|
check_counter = 0
|
|
|
|
/obj/structure/alien/weeds/proc/clear_wall_weed()
|
|
if(wall_weed && !QDELETED(wall_weed))
|
|
wall_weed.weed = null
|
|
wall_weed.silent_removal = TRUE
|
|
QDEL_NULL(wall_weed)
|
|
|
|
/obj/structure/alien/weeds/proc/check_surroundings()
|
|
var/turf/T = get_turf(src)
|
|
var/list/nearby_dense_turfs = T.AdjacentTurfs(cardinal_only = FALSE, dense_only = TRUE)
|
|
if(!length(nearby_dense_turfs)) // There is no dense turfs around it
|
|
clear_wall_weed()
|
|
return
|
|
|
|
var/list/wall_dirs = list()
|
|
for(var/turf/W in nearby_dense_turfs)
|
|
if(iswallturf(W))
|
|
wall_dirs.Add(get_dir(W, T))
|
|
if(!length(wall_dirs)) // There is no walls around it
|
|
clear_wall_weed()
|
|
return
|
|
|
|
var/list/nearby_open_turfs = T.AdjacentTurfs(open_only = TRUE, cardinal_only = TRUE)
|
|
|
|
for(var/turf/W in nearby_open_turfs) // This handles removal of corner-weeds when they are to be replaced with a full side-weed instead
|
|
if(locate(/obj/structure/alien/weeds, W))
|
|
var/dirs = get_dir(W, T)
|
|
switch(dirs)
|
|
if(NORTH)
|
|
wall_dirs.Remove(NORTHEAST, NORTHWEST)
|
|
if(SOUTH)
|
|
wall_dirs.Remove(SOUTHEAST, SOUTHWEST)
|
|
if(EAST)
|
|
wall_dirs.Remove(NORTHEAST, SOUTHEAST)
|
|
if(WEST)
|
|
wall_dirs.Remove(NORTHWEST, SOUTHWEST)
|
|
|
|
if(!length(wall_dirs)) // No weeds will be applied, better off deleting it
|
|
clear_wall_weed()
|
|
return
|
|
|
|
if(!wall_weed || QDELETED(wall_weed))
|
|
wall_weed = new /obj/structure/alien/wallweed(T, src)
|
|
|
|
wall_weed.compare_overlays(wall_dirs)
|
|
|
|
/obj/structure/alien/weeds/proc/spread()
|
|
var/turf/U = get_turf(src)
|
|
|
|
if(isspaceturf(U))
|
|
qdel(src)
|
|
return
|
|
|
|
if(!linked_node)
|
|
if(prob(20))
|
|
silent_removal = TRUE
|
|
qdel(src)
|
|
return
|
|
|
|
if((istype(linked_node, /obj/structure/alien/resin/door)) || (istype(linked_node, /obj/structure/alien/resin/wall)))
|
|
return
|
|
|
|
if(get_dist(linked_node, src) > linked_node.node_range) /*!linked_node || */
|
|
return
|
|
|
|
for(var/turf/T in U.GetAtmosAdjacentTurfs())
|
|
if((locate(/obj/structure/alien/weeds) in T) || isspaceturf(T) || islava(T) || ischasm(T))
|
|
continue
|
|
new /obj/structure/alien/weeds(T, linked_node)
|
|
check_surroundings()
|
|
|
|
/obj/structure/alien/weeds/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)
|
|
..()
|
|
if(exposed_temperature > 300)
|
|
take_damage(5, BURN, 0, 0)
|
|
|
|
/*
|
|
* Wall Weeds
|
|
*/
|
|
|
|
/obj/structure/alien/wallweed
|
|
name = "resin overgrowth"
|
|
desc = "A thick resin surface covers the wall."
|
|
icon = 'icons/obj/smooth_structures/alien/weeds.dmi'
|
|
icon_state = null
|
|
anchored = TRUE
|
|
layer = ABOVE_WINDOW_LAYER
|
|
plane = GAME_PLANE
|
|
|
|
max_integrity = 15
|
|
var/obj/structure/alien/weeds/weed
|
|
var/list/overlay_list = list()
|
|
/// This var is used for making automatic weed removals silent instead of making them produce the breaking sound
|
|
var/silent_removal = FALSE
|
|
|
|
/obj/structure/alien/wallweed/Initialize(mapload, weed_owner)
|
|
. = ..()
|
|
weed = weed_owner
|
|
|
|
/obj/structure/alien/wallweed/Destroy()
|
|
if(!silent_removal)
|
|
playsound(loc, pick('sound/effects/alien_resin_break2.ogg','sound/effects/alien_resin_break1.ogg'), 50, FALSE)
|
|
if(weed)
|
|
weed.wall_weed = null
|
|
return ..()
|
|
|
|
/obj/structure/alien/wallweed/proc/compare_overlays(list/wall_dirs)
|
|
if(overlay_list != wall_dirs)
|
|
overlay_list = wall_dirs
|
|
update_icon(UPDATE_OVERLAYS)
|
|
|
|
/obj/structure/alien/wallweed/update_overlays()
|
|
. = ..()
|
|
if(!length(overlay_list))
|
|
return
|
|
for(var/dirs in overlay_list)
|
|
var/image/I = image(icon, icon_state = "wallweed-[dirs]")
|
|
switch(dirs)
|
|
if(NORTH, NORTHEAST, NORTHWEST)
|
|
I.pixel_y = -32
|
|
if(SOUTH, SOUTHEAST, SOUTHWEST)
|
|
I.pixel_y = 32
|
|
switch(dirs)
|
|
if(EAST, NORTHEAST, SOUTHEAST)
|
|
I.pixel_x = -32
|
|
if(WEST, NORTHWEST, SOUTHWEST)
|
|
I.pixel_x = 32
|
|
I.layer = BELOW_MOB_LAYER
|
|
. += I
|
|
|
|
/obj/structure/alien/wallweed/attack_alien(mob/living/carbon/alien/humanoid/user)
|
|
if(user.a_intent != INTENT_HARM)
|
|
return
|
|
return ..()
|
|
|
|
/*
|
|
* Weed nodes
|
|
*/
|
|
|
|
/obj/structure/alien/weeds/node
|
|
name = "resin node"
|
|
desc = "A large bulbous node pumping resin into the surface bellow it."
|
|
icon = 'icons/obj/smooth_structures/alien/weeds.dmi'
|
|
icon_state = "weeds"
|
|
base_icon_state = "weeds"
|
|
light_range = 1
|
|
var/node_range = NODERANGE
|
|
|
|
|
|
/obj/structure/alien/weeds/node/Initialize(mapload)
|
|
add_overlay("weednode")
|
|
return ..(loc, src)
|
|
|
|
#undef NODERANGE
|
|
|
|
|
|
/*
|
|
* Egg
|
|
*/
|
|
|
|
///Used in the /status var
|
|
#define BURST 0
|
|
#define BURSTING 1
|
|
#define GROWING 2
|
|
#define GROWN 3
|
|
///time it takes to grow a hugger
|
|
#define MIN_GROWTH_TIME 2 MINUTES
|
|
#define MAX_GROWTH_TIME 3 MINUTES
|
|
|
|
/obj/structure/alien/egg
|
|
name = "egg"
|
|
desc = "A large mottled egg."
|
|
icon_state = "egg_growing"
|
|
density = FALSE
|
|
anchored = TRUE
|
|
max_integrity = 100
|
|
integrity_failure = 5
|
|
layer = MOB_LAYER
|
|
flags_2 = CRITICAL_ATOM_2
|
|
/*can be GROWING, GROWN or BURST; all mutually exclusive. GROWING has the egg in the grown state, and it will take 180-300 seconds for it to advance to the hatched state
|
|
*In the GROWN state, an alien egg can be destroyed or attacked by a xenomorph to force it to be burst, going near an egg in this state will also cause it to burst if you can be infected by a face hugger
|
|
*In the BURST/BURSTING state, the alien egg can be removed by being attacked by a alien or any other weapon
|
|
**/
|
|
var/status = GROWING
|
|
var/datum/proximity_monitor/proximity_monitor
|
|
|
|
/obj/structure/alien/egg/grown
|
|
status = GROWN
|
|
icon_state = "egg"
|
|
|
|
/obj/structure/alien/egg/burst
|
|
status = BURST
|
|
icon_state = "egg_hatched"
|
|
|
|
/obj/structure/alien/egg/Initialize(mapload)
|
|
. = ..()
|
|
new /obj/item/clothing/mask/facehugger(src)
|
|
if(status == BURST)
|
|
obj_integrity = integrity_failure
|
|
else if(status != GROWN)
|
|
addtimer(CALLBACK(src, PROC_REF(grow)), rand(MIN_GROWTH_TIME, MAX_GROWTH_TIME))
|
|
if(status == GROWN)
|
|
proximity_monitor = new(src)
|
|
|
|
/obj/structure/alien/egg/attack_alien(mob/living/carbon/alien/user)
|
|
return attack_hand(user)
|
|
|
|
/obj/structure/alien/egg/attack_hand(mob/living/user)
|
|
if(user.get_int_organ(/obj/item/organ/internal/alien/plasmavessel))
|
|
switch(status)
|
|
if(BURST)
|
|
to_chat(user, "<span class='notice'>You clear the hatched egg.</span>")
|
|
playsound(loc, 'sound/effects/attackblob.ogg', 100, 1)
|
|
qdel(src)
|
|
return
|
|
if(GROWING)
|
|
to_chat(user, "<span class='notice'>The child is not developed yet.</span>")
|
|
return
|
|
if(GROWN)
|
|
to_chat(user, "<span class='notice'>You retrieve the child.</span>")
|
|
burst(FALSE)
|
|
return
|
|
else
|
|
to_chat(user, "<span class='notice'>It feels slimy.</span>")
|
|
user.changeNext_move(CLICK_CD_MELEE)
|
|
|
|
|
|
/obj/structure/alien/egg/proc/getFacehugger()
|
|
return locate(/obj/item/clothing/mask/facehugger) in contents
|
|
|
|
/obj/structure/alien/egg/proc/grow()
|
|
icon_state = "egg"
|
|
status = GROWN
|
|
proximity_monitor = new(src)
|
|
|
|
///Need to carry the kill from Burst() to Hatch(), this section handles the alien opening the egg
|
|
/obj/structure/alien/egg/proc/burst(kill)
|
|
if(status == GROWN || status == GROWING)
|
|
icon_state = "egg_hatched"
|
|
flick("egg_opening", src)
|
|
status = BURSTING
|
|
QDEL_NULL(proximity_monitor)
|
|
addtimer(CALLBACK(src, PROC_REF(hatch)), 1.5 SECONDS)
|
|
|
|
///We now check HOW the hugger is hatching, kill carried from Burst() and obj_break()
|
|
/obj/structure/alien/egg/proc/hatch(kill)
|
|
status = BURST
|
|
var/obj/item/clothing/mask/facehugger/child = getFacehugger()
|
|
child.forceMove(get_turf(src))
|
|
if(kill)
|
|
child.Die()
|
|
for(var/mob/M in range(1, src))
|
|
if(CanHug(M))
|
|
child.Attach(M)
|
|
break
|
|
|
|
/obj/structure/alien/egg/obj_break(damage_flag)
|
|
if(!(flags & NODECONSTRUCT))
|
|
if(status != BURST)
|
|
burst(kill = TRUE)
|
|
|
|
/obj/structure/alien/egg/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)
|
|
..()
|
|
if(exposed_temperature > 500)
|
|
take_damage(5, BURN, 0, 0)
|
|
|
|
/obj/structure/alien/egg/HasProximity(atom/movable/AM)
|
|
if(status == GROWN)
|
|
if(!CanHug(AM))
|
|
return
|
|
|
|
var/mob/living/carbon/C = AM
|
|
if(C.stat == CONSCIOUS && C.get_int_organ(/obj/item/organ/internal/body_egg/alien_embryo))
|
|
return
|
|
|
|
burst(FALSE)
|
|
|
|
#undef BURST
|
|
#undef BURSTING
|
|
#undef GROWING
|
|
#undef GROWN
|
|
#undef MIN_GROWTH_TIME
|
|
#undef MAX_GROWTH_TIME
|
|
|
|
#undef WEED_NORTH_EDGING
|
|
#undef WEED_SOUTH_EDGING
|
|
#undef WEED_EAST_EDGING
|
|
#undef WEED_WEST_EDGING
|