diff --git a/_maps/map_files/RandomRuins/SpaceRuins/derelict1.dmm b/_maps/map_files/RandomRuins/SpaceRuins/derelict1.dmm index 3d983d2a5be..5d159c28d40 100644 --- a/_maps/map_files/RandomRuins/SpaceRuins/derelict1.dmm +++ b/_maps/map_files/RandomRuins/SpaceRuins/derelict1.dmm @@ -11,7 +11,7 @@ /area/ruin/space/unpowered) "d" = ( /obj/structure/alien/weeds, -/obj/structure/alien/resin/membrane, +/obj/structure/alien/resin/wall, /turf/simulated/floor/plating/airless, /area/ruin/space/unpowered) "e" = ( @@ -47,10 +47,6 @@ /obj/structure/alien/resin/wall, /turf/simulated/floor/plating/airless, /area/ruin/space/unpowered) -"l" = ( -/obj/structure/alien/resin/membrane, -/turf/simulated/floor/plating/airless, -/area/ruin/space/unpowered) "m" = ( /obj/structure/alien/weeds, /obj/structure/table, @@ -819,7 +815,7 @@ f c f f -l +k b b a @@ -862,7 +858,7 @@ f f f f -l +k q b a @@ -1229,8 +1225,8 @@ a a b b -l -l +k +k p p a diff --git a/code/__DEFINES/icon_smoothing.dm b/code/__DEFINES/icon_smoothing.dm index bcc1c8fa8af..023d7b63d32 100644 --- a/code/__DEFINES/icon_smoothing.dm +++ b/code/__DEFINES/icon_smoothing.dm @@ -117,7 +117,7 @@ DEFINE_BITFIELD(smoothing_flags, list( #define SMOOTH_GROUP_REINFORCED_TABLES S_OBJ(56) ///obj/structure/table/reinforced, /obj/structure/table/glass/reinforced #define SMOOTH_GROUP_ALIEN_RESIN S_OBJ(60) ///obj/structure/alien/resin -#define SMOOTH_GROUP_ALIEN_WALLS S_OBJ(61) ///obj/structure/alien/resin/wall, /obj/structure/alien/resin/membrane +#define SMOOTH_GROUP_ALIEN_WALLS S_OBJ(61) ///obj/structure/alien/resin/wall, #define SMOOTH_GROUP_ALIEN_WEEDS S_OBJ(62) ///obj/structure/alien/weeds #define SMOOTH_GROUP_SECURITY_BARRICADE S_OBJ(63) ///obj/structure/barricade/security diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm index 523d0d0d6c7..eed6f6627ba 100644 --- a/code/game/machinery/doors/airlock.dm +++ b/code/game/machinery/doors/airlock.dm @@ -1384,6 +1384,12 @@ GLOBAL_LIST_EMPTY(airlock_emissive_underlays) shock(user, 100) //Mmm, fried xeno! return if(!density) //Already open + if(!arePowerSystemsOn()) + close(TRUE) + return + if(HAS_TRAIT_FROM(user, TRAIT_FORCE_DOORS, VAMPIRE_TRAIT)) + close(TRUE) + return return if(locked || welded) //Extremely generic, as aliens only understand the basics of how airlocks work. to_chat(user, "[src] refuses to budge!") @@ -1391,14 +1397,22 @@ GLOBAL_LIST_EMPTY(airlock_emissive_underlays) if(prying_so_hard) return prying_so_hard = TRUE - user.visible_message("[user] begins prying open [src].",\ - "You begin digging your claws into [src] with all your might!",\ - "You hear groaning metal...") - var/time_to_open = 5 + var/time_to_open = 0 if(arePowerSystemsOn()) + if(HAS_TRAIT_FROM(user, TRAIT_FORCE_DOORS, VAMPIRE_TRAIT)) + open(TRUE) + visible_message("[user] forces the door!") + playsound(loc, "sparks", 100, TRUE, SHORT_RANGE_SOUND_EXTRARANGE) + prying_so_hard = FALSE + return + user.visible_message("[user] begins prying open [src].",\ + "You begin digging your claws into [src] with all your might!",\ + "You hear groaning metal...") time_to_open = 50 //Powered airlocks take longer to open, and are loud. playsound(src, 'sound/machines/airlock_alien_prying.ogg', 100, TRUE) - + else + visible_message("[user] forces the door!") + playsound(loc, "sparks", 100, TRUE, SHORT_RANGE_SOUND_EXTRARANGE) if(do_after(user, time_to_open, TRUE, src)) if(density && !open(2)) //The airlock is still closed, but something prevented it opening. (Another player noticed and bolted/welded the airlock in time!) diff --git a/code/game/objects/structures/aliens.dm b/code/game/objects/structures/aliens.dm index 56071ee5650..1235b7d9add 100644 --- a/code/game/objects/structures/aliens.dm +++ b/code/game/objects/structures/aliens.dm @@ -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, "We begin tearing down this resin structure.") + 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, "Your lack of connection to the hive prevents the resin door from opening") +/* + * 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, "We begin tearing down this resin structure.") + 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, "You clear the hatched egg.") diff --git a/code/game/objects/structures/mineral_doors.dm b/code/game/objects/structures/mineral_doors.dm index d664e0f3495..90a0e4e21c0 100644 --- a/code/game/objects/structures/mineral_doors.dm +++ b/code/game/objects/structures/mineral_doors.dm @@ -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 ..() diff --git a/code/game/objects/structures/stool_bed_chair_nest/alien_nests.dm b/code/game/objects/structures/stool_bed_chair_nest/alien_nests.dm index 80a3ab3b3d9..cc4ac4e012f 100644 --- a/code/game/objects/structures/stool_bed_chair_nest/alien_nests.dm +++ b/code/game/objects/structures/stool_bed_chair_nest/alien_nests.dm @@ -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, "[M]'s linkage with the hive prevents you from securing them into [src]") 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, "Your lack of linkage to the hive prevents you from buckling [M] into [src]") 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 diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm index c55913c0205..485e843e399 100644 --- a/code/game/turfs/turf.dm +++ b/code/game/turfs/turf.dm @@ -279,11 +279,16 @@ //update firedoor adjacency var/list/turfs_to_check = get_adjacent_open_turfs(src) | src - for(var/I in turfs_to_check) - var/turf/T = I + for(var/turf/T in turfs_to_check) for(var/obj/machinery/door/firedoor/FD in T) FD.CalculateAffectingAreas() + // Check for weeds and either update, create or delete wall weeds + turfs_to_check = AdjacentTurfs(open_only = TRUE, cardinal_only = FALSE) + for(var/turf/T in turfs_to_check) + for(var/obj/structure/alien/weeds/W in T) + W.check_surroundings() + if(!keep_cabling && !can_have_cabling()) for(var/obj/structure/cable/C in contents) qdel(C) diff --git a/code/modules/mob/living/carbon/alien/humanoid/alien_powers.dm b/code/modules/mob/living/carbon/alien/humanoid/alien_powers.dm index a62dc4be832..1593bab6d4d 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/alien_powers.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/alien_powers.dm @@ -28,9 +28,14 @@ Doesn't work on other aliens/AI.*/ return if(powerc(50,1)) + for(var/obj/structure/alien/resin in get_turf(src)) + to_chat(src, "There is already a resin construction here.") + return adjustPlasma(-50) for(var/mob/O in viewers(src, null)) O.show_message(text("[src] has planted some alien weeds!"), 1) + for(var/obj/structure/alien/weeds/W in get_turf(src)) + qdel(W) new /obj/structure/alien/weeds/node(loc) return @@ -114,29 +119,39 @@ Doesn't work on other aliens/AI.*/ return /mob/living/carbon/alien/humanoid/proc/resin() // -- TLE - set name = "Secrete Resin (55)" + set name = "Secrete Resin" set desc = "Secrete tough malleable resin." set category = "Alien" + var/list/resin_buildings = list("Resin Wall (55)" = image(icon = 'icons/obj/smooth_structures/alien/resin_wall.dmi', icon_state = "resin_wall-0"), + "Resin Nest (55)" = image(icon = 'icons/mob/alien.dmi', icon_state = "nest"), + "Resin Door (80)" = image(icon = 'icons/obj/smooth_structures/alien/resin_door.dmi', icon_state = "resin")) + var/choice = show_radial_menu(src, src, resin_buildings, src, radius = 40) if(powerc(55, TRUE)) - var/choice = input("Choose what you wish to shape.","Resin building") as null|anything in list("resin wall","resin membrane","resin nest") //would do it through typesof but then the player choice would have the type path and we don't want the internal workings to be exposed ICly - Urist - - if(!choice || !powerc(55, TRUE)) - return - var/obj/structure/alien/resin/T = locate() in get_turf(src) - if(T) + var/built = FALSE + if(locate(/obj/structure/alien/resin) in get_turf(src)) to_chat(src, "There is already a resin construction here.") return adjustPlasma(-55) - for(var/mob/O in viewers(src, null)) - O.show_message(text("[src] vomits up a thick purple substance and shapes it!"), 1) + switch(choice) - if("resin wall") + if("Resin Wall (55)") new /obj/structure/alien/resin/wall(loc) - if("resin membrane") - new /obj/structure/alien/resin/membrane(loc) - if("resin nest") + built = TRUE + if("Resin Nest (55)") new /obj/structure/bed/nest(loc) + built = TRUE + if("Resin Door (80)") + if(powerc(25, TRUE)) + var/obj/structure/alien/resin/door/door = new(loc) + door.dir = dir + adjustPlasma(-25) + built = TRUE + else + to_chat(src, "Not enough plasma stored.") + adjustPlasma(55) + if(built) + visible_message("[src] vomits up a thick purple substance and shapes it!") return /mob/living/carbon/alien/humanoid/verb/regurgitate() diff --git a/code/modules/mob/living/carbon/alien/humanoid/queen.dm b/code/modules/mob/living/carbon/alien/humanoid/queen.dm index 6b53be110cc..093d279908d 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/queen.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/queen.dm @@ -15,14 +15,15 @@ alien_slash_damage = 30 //Queens do higher slashing damage to people alien_movement_delay = 1 //This represents a movement delay of 1, or roughly 80% the movement speed of a normal carbon mob - /mob/living/carbon/alien/humanoid/queen/Initialize(mapload) . = ..() //there should only be one queen for(var/mob/living/carbon/alien/humanoid/queen/Q in GLOB.alive_mob_list) if(Q == src) + ADD_TRAIT(Q, TRAIT_FORCE_DOORS, VAMPIRE_TRAIT) continue if(Q.stat == DEAD) + ADD_TRAIT(Q, TRAIT_FORCE_DOORS, VAMPIRE_TRAIT) continue if(Q.client) name = "alien princess ([rand(1, 999)])" //if this is too cutesy feel free to change it/remove it. diff --git a/icons/mob/alien.dmi b/icons/mob/alien.dmi index 74154047ccc..15631f719db 100644 Binary files a/icons/mob/alien.dmi and b/icons/mob/alien.dmi differ diff --git a/icons/obj/doors/mineral_doors.dmi b/icons/obj/doors/mineral_doors.dmi index 56d5a32bc59..eb5b7100809 100644 Binary files a/icons/obj/doors/mineral_doors.dmi and b/icons/obj/doors/mineral_doors.dmi differ diff --git a/icons/obj/smooth_structures/alien/nest.dmi b/icons/obj/smooth_structures/alien/nest.dmi deleted file mode 100644 index 6de377886f9..00000000000 Binary files a/icons/obj/smooth_structures/alien/nest.dmi and /dev/null differ diff --git a/icons/obj/smooth_structures/alien/resin_door.dmi b/icons/obj/smooth_structures/alien/resin_door.dmi new file mode 100644 index 00000000000..3d54a2ceb07 Binary files /dev/null and b/icons/obj/smooth_structures/alien/resin_door.dmi differ diff --git a/icons/obj/smooth_structures/alien/resin_membrane.dmi b/icons/obj/smooth_structures/alien/resin_membrane.dmi deleted file mode 100644 index 1ea306eaa66..00000000000 Binary files a/icons/obj/smooth_structures/alien/resin_membrane.dmi and /dev/null differ diff --git a/icons/obj/smooth_structures/alien/resin_wall.dmi b/icons/obj/smooth_structures/alien/resin_wall.dmi index 7d837172b8c..9ceb50e935d 100644 Binary files a/icons/obj/smooth_structures/alien/resin_wall.dmi and b/icons/obj/smooth_structures/alien/resin_wall.dmi differ diff --git a/icons/obj/smooth_structures/alien/weednode.dmi b/icons/obj/smooth_structures/alien/weednode.dmi deleted file mode 100644 index 888fce62ad1..00000000000 Binary files a/icons/obj/smooth_structures/alien/weednode.dmi and /dev/null differ diff --git a/icons/obj/smooth_structures/alien/weeds.dmi b/icons/obj/smooth_structures/alien/weeds.dmi new file mode 100644 index 00000000000..17131956916 Binary files /dev/null and b/icons/obj/smooth_structures/alien/weeds.dmi differ diff --git a/icons/obj/smooth_structures/alien/weeds1.dmi b/icons/obj/smooth_structures/alien/weeds1.dmi deleted file mode 100644 index e9022e89414..00000000000 Binary files a/icons/obj/smooth_structures/alien/weeds1.dmi and /dev/null differ diff --git a/icons/obj/smooth_structures/alien/weeds2.dmi b/icons/obj/smooth_structures/alien/weeds2.dmi deleted file mode 100644 index 13207496e1c..00000000000 Binary files a/icons/obj/smooth_structures/alien/weeds2.dmi and /dev/null differ diff --git a/icons/obj/smooth_structures/alien/weeds3.dmi b/icons/obj/smooth_structures/alien/weeds3.dmi deleted file mode 100644 index 2ed86420b4d..00000000000 Binary files a/icons/obj/smooth_structures/alien/weeds3.dmi and /dev/null differ diff --git a/sound/effects/alien_resin_break1.ogg b/sound/effects/alien_resin_break1.ogg new file mode 100644 index 00000000000..bf2cd2053a7 Binary files /dev/null and b/sound/effects/alien_resin_break1.ogg differ diff --git a/sound/effects/alien_resin_break2.ogg b/sound/effects/alien_resin_break2.ogg new file mode 100644 index 00000000000..57e13bfc943 Binary files /dev/null and b/sound/effects/alien_resin_break2.ogg differ diff --git a/sound/machines/alien_airlock.ogg b/sound/machines/alien_airlock.ogg new file mode 100644 index 00000000000..078af38d077 Binary files /dev/null and b/sound/machines/alien_airlock.ogg differ