Resprites Xeno structures. Adds Xeno Doors. Fixes and polishes a lot of issues and features of Xenos (#19978)

* Benodoor1

* TheScopeOfThisPRisOutTheWindow

* BalancesDoor+GoodSounds

* Fixes Map Issues(?) - Mapedit by Lightfire

* FixesMapIssues for good

* Nests+WallWeeds(WIP)

* Doorforcing

* EggSprite

* Weed,Carbon,Wallchecks

* Spelling+cleanercomment1

* ReviewBatchTest

Co-authored-by: Sirryan2002 <80364400+Sirryan2002@users.noreply.github.com>

* Sirryan'sReviewBatchTest

Co-authored-by: Sirryan2002 <80364400+Sirryan2002@users.noreply.github.com>

* Sirryan'sReviewFinalBatch

Co-authored-by: Sirryan2002 <80364400+Sirryan2002@users.noreply.github.com>

* MoreFixesForReview

* Initializes+UserFeedbackWarns

* ForgorWallweedName

* SeanRequestsPart1

* SeanPart2

* SirryanReviewPart1

Co-authored-by: Sirryan2002 <80364400+Sirryan2002@users.noreply.github.com>

* TheWeedening

* SirryanReviewPart2

* CleaningLayer

* SirryanReviewPart1

Co-authored-by: Ryan <80364400+Sirryan2002@users.noreply.github.com>

* SirryanReviewPart2

* SirryanReview

Co-authored-by: Ryan <80364400+Sirryan2002@users.noreply.github.com>

* RemovingOldSprites

Co-authored-by: Sirryan2002 <80364400+Sirryan2002@users.noreply.github.com>
This commit is contained in:
Eric6426-Blossom
2023-01-10 17:03:43 -05:00
committed by GitHub
co-authored by Sirryan2002
parent d08786fe8b
commit ba1fa9fb63
23 changed files with 356 additions and 97 deletions
+274 -38
View File
@@ -53,12 +53,18 @@
max_integrity = 200
var/resintype = null
/obj/structure/alien/resin/Initialize()
/obj/structure/alien/resin/Initialize(mapload)
air_update_turf(1)
..()
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)
return ..()
/obj/structure/alien/resin/Destroy()
var/turf/T = get_turf(src)
playsound(loc, 'sound/effects/alien_resin_break2.ogg', 100, TRUE)
. = ..()
T.air_update_turf(TRUE)
@@ -70,6 +76,14 @@
/obj/structure/alien/resin/CanAtmosPass()
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."
@@ -82,23 +96,140 @@
/obj/structure/alien/resin/wall/BlockSuperconductivity()
return TRUE
/obj/structure/alien/resin/membrane
name = "resin membrane"
desc = "Resin just thin enough to let light pass through."
icon = 'icons/obj/smooth_structures/alien/resin_membrane.dmi'
icon_state = "resin_membrane-0"
base_icon_state = "resin_membrane"
opacity = FALSE
max_integrity = 160
resintype = "membrane"
/*
*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 = 150
armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 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 = 1.5 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/CanPass(atom/movable/mover, turf/target)
if(istype(mover) && mover.checkpass(PASSGLASS))
return !opacity
/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)
air_update_turf(1)
return ..()
/obj/structure/alien/resin/door/Move()
var/turf/T = loc
. = ..()
move_update_air(T)
/obj/structure/alien/resin/door/Crossed(mob/living/L, oldloc)
..()
if(!state_open)
return try_to_operate(L)
/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(turf/T)
return !density
/obj/structure/alien/resin/door/proc/try_to_operate(mob/user)
if(is_operating)
return
if(!iscarbon(user))
return
var/mob/living/carbon/C = user
if(C.get_int_organ(/obj/item/organ/internal/xenos/hivenode))
if(world.time - C.last_bumped <= 60)
return
if(!C.handcuffed)
operate()
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()
is_operating = TRUE
if(!state_open)
playsound(loc, open_sound, 100, 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, 100, 1)
flick("[initial_state]closing", src)
density = !density
opacity = !opacity
state_open = !state_open
addtimer(CALLBACK(src, PROC_REF(operate_update)), 1 SECONDS)
/obj/structure/alien/resin/door/proc/operate_update()
air_update_turf(1)
update_icon(UPDATE_ICON_STATE)
is_operating = FALSE
if(state_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/CanPass(atom/movable/mover, turf/target)
if(iscarbon(mover))
var/mob/living/carbon/C = mover
if(C.get_int_organ(/obj/item/organ/internal/xenos/hivenode))
return TRUE
if(iscarbon(mover.pulledby))
var/mob/living/carbon/L = mover.pulledby
if(L.get_int_organ(/obj/item/organ/internal/xenos/hivenode))
return TRUE
return !density
/*
* Weeds
@@ -112,38 +243,91 @@
desc = "A thick resin surface covers the floor."
anchored = TRUE
density = FALSE
layer = ABOVE_OPEN_TURF_LAYER
plane = FLOOR_PLANE
icon = 'icons/obj/smooth_structures/alien/weeds1.dmi'
icon_state = "weeds1"
base_icon_state = "weeds1"
icon = 'icons/obj/smooth_structures/alien/weeds.dmi'
icon_state = "weeds"
base_icon_state = "weeds"
max_integrity = 15
layer = WIRE_TERMINAL_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)
transform = matrix(1, 0, -4, 0, 1, -4)
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
/obj/structure/alien/weeds/New(pos, node)
/obj/structure/alien/weeds/Initialize(mapload, node)
..()
linked_node = node
if(isspaceturf(loc))
qdel(src)
return
if(icon_state == "weeds")
icon_state = pick("weeds", "weeds1", "weeds2")
spawn(rand(150, 200))
if(src)
Life()
check_surroundings()
START_PROCESSING(SSobj, src)
/obj/structure/alien/weeds/Destroy()
STOP_PROCESSING(SSobj, src)
QUEUE_SMOOTH_NEIGHBORS(src)
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/Life()
/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()
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(get_turf(src))
wall_weed.compare_overlays(wall_dirs)
/obj/structure/alien/weeds/proc/spread()
var/turf/U = get_turf(src)
if(isspaceturf(U))
@@ -154,29 +338,81 @@
return
for(var/turf/T in U.GetAtmosAdjacentTurfs())
if(locate(/obj/structure/alien/weeds) in T || isspaceturf(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)
//Weed nodes
/*
* 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/list/overlay_list = list()
/obj/structure/alien/wallweed/Destroy()
playsound(loc, pick('sound/effects/alien_resin_break2.ogg','sound/effects/alien_resin_break1.ogg'), 50, FALSE)
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 = "glowing resin"
desc = "Blue bioluminescence shines from beneath the surface."
icon = 'icons/obj/smooth_structures/alien/weednode.dmi'
icon_state = "weednode"
base_icon_state = "weednode"
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/New()
/obj/structure/alien/weeds/node/Initialize()
add_overlay("weednode")
..(loc, src)
#undef NODERANGE
@@ -208,7 +444,7 @@
/*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
/obj/structure/alien/egg/grown
@@ -231,7 +467,7 @@
return attack_hand(user)
/obj/structure/alien/egg/attack_hand(mob/living/user)
if(user.get_int_organ(/obj/item/organ/internal/xenos/plasmavessel))
if(user.get_int_organ(/obj/item/organ/internal/xenos/hivenode))
switch(status)
if(BURST)
to_chat(user, "<span class='notice'>You clear the hatched egg.</span>")
+10 -21
View File
@@ -19,8 +19,8 @@
var/hardness = 1
var/sheetType = /obj/item/stack/sheet/metal
var/sheetAmount = 7
var/openSound = 'sound/effects/stonedoor_openclose.ogg'
var/closeSound = 'sound/effects/stonedoor_openclose.ogg'
var/open_sound = 'sound/effects/stonedoor_openclose.ogg'
var/close_sound = 'sound/effects/stonedoor_openclose.ogg'
var/damageSound = null
/obj/structure/mineral_door/Initialize()
@@ -82,15 +82,18 @@
/obj/structure/mineral_door/proc/operate()
is_operating = TRUE
if(!state_open)
playsound(loc, openSound, 100, 1)
playsound(loc, open_sound, 100, TRUE)
flick("[initial_state]opening",src)
else
var/turf/T = get_turf(src)
for(var/mob/living/L in T)
is_operating = FALSE
return
playsound(loc, closeSound, 100, 1)
playsound(loc, close_sound, 100, TRUE)
flick("[initial_state]closing",src)
sleep(10)
addtimer(CALLBACK(src, PROC_REF(operate_update)), 1 SECONDS)
/obj/structure/mineral_door/proc/operate_update()
density = !density
opacity = !opacity
state_open = !state_open
@@ -198,24 +201,10 @@
/obj/structure/mineral_door/wood
name = "wood door"
icon_state = "wood"
openSound = 'sound/effects/doorcreaky.ogg'
closeSound = 'sound/effects/doorcreaky.ogg'
open_sound = 'sound/effects/doorcreaky.ogg'
close_sound = 'sound/effects/doorcreaky.ogg'
sheetType = /obj/item/stack/sheet/wood
hardness = 1
resistance_flags = FLAMMABLE
max_integrity = 200
rad_insulation = RAD_VERY_LIGHT_INSULATION
/obj/structure/mineral_door/resin
name = "resin door"
icon_state = "resin"
hardness = 1.5
close_delay = 100
openSound = 'sound/effects/attackblob.ogg'
closeSound = 'sound/effects/attackblob.ogg'
damageSound = 'sound/effects/attackblob.ogg'
sheetType = null
/obj/structure/mineral_door/resin/try_to_operate(atom/user)
if(isalien(user))
return ..()
@@ -14,12 +14,12 @@
. = ..()
nest_overlay = image('icons/mob/alien.dmi', "nestoverlay", layer=MOB_LAYER - 0.2)
/obj/structure/bed/nest/user_unbuckle_mob(mob/living/user)
/obj/structure/bed/nest/user_unbuckle_mob(mob/living/buckled_mob, mob/user)
if(has_buckled_mobs())
for(var/buck in buckled_mobs) //breaking a nest releases all the buckled mobs, because the nest isn't holding them down anymore
var/mob/living/M = buck
if(user.get_int_organ(/obj/item/organ/internal/xenos/plasmavessel))
if(user.get_int_organ(/obj/item/organ/internal/xenos/hivenode))
unbuckle_mob(M)
add_fingerprint(user)
return
@@ -45,15 +45,16 @@
unbuckle_mob(M)
add_fingerprint(user)
/obj/structure/bed/nest/user_buckle_mob(mob/living/M, mob/living/user)
if (!ismob(M) || (get_dist(src, user) > 1) || (M.loc != loc) || user.incapacitated() || M.buckled)
return
if(M.get_int_organ(/obj/item/organ/internal/xenos/plasmavessel))
if(M.get_int_organ(/obj/item/organ/internal/xenos/hivenode))
to_chat(user, "<span class='noticealien'>[M]'s linkage with the hive prevents you from securing them into [src]</span>")
return
if(!user.get_int_organ(/obj/item/organ/internal/xenos/plasmavessel))
if(!user.get_int_organ(/obj/item/organ/internal/xenos/hivenode))
to_chat(user, "<span class='noticealien'>Your lack of linkage to the hive prevents you from buckling [M] into [src]</span>")
return
if(has_buckled_mobs())
@@ -87,8 +88,10 @@
/obj/structure/bed/nest/attack_alien(mob/living/carbon/alien/user)
if(user.a_intent != INTENT_HARM)
return attack_hand(user)
else
return ..()
if(!do_after(user, 4 SECONDS, target = src) || QDELETED(src))
return
playsound(loc, pick('sound/effects/alien_resin_break2.ogg','sound/effects/alien_resin_break1.ogg'), 50, FALSE)
qdel(src)
/obj/structure/bed/nest/prevents_buckled_mobs_attacking()
return TRUE