From e46675991372e17f180e202befb987abaab1c20e Mon Sep 17 00:00:00 2001
From: Helg2 <93882977+Helg2@users.noreply.github.com>
Date: Fri, 26 Jul 2024 09:38:44 +0300
Subject: [PATCH 01/10] Reorgs `xeno_structures.dm`, tunnels now use minimap to
choose exit. (#35)
* tunnel
* reorg
* Update tunnel.dm
---
code/__HELPERS/ai.dm | 19 +
code/modules/xenomorph/_xeno_structure.dm | 59 +
code/modules/xenomorph/acidwell.dm | 192 +++
code/modules/xenomorph/jellypod.dm | 67 +
code/modules/xenomorph/nest.dm | 63 +
code/modules/xenomorph/plant.dm | 255 +++
code/modules/xenomorph/silo.dm | 159 ++
code/modules/xenomorph/spawner.dm | 112 ++
code/modules/xenomorph/trap.dm | 211 +++
code/modules/xenomorph/tunnel.dm | 181 +++
code/modules/xenomorph/turret.dm | 272 ++++
code/modules/xenomorph/xeno_structures.dm | 1731 ---------------------
code/modules/xenomorph/xeno_towers.dm | 117 ++
tgmc.dme | 11 +-
14 files changed, 1717 insertions(+), 1732 deletions(-)
create mode 100644 code/modules/xenomorph/_xeno_structure.dm
create mode 100644 code/modules/xenomorph/acidwell.dm
create mode 100644 code/modules/xenomorph/jellypod.dm
create mode 100644 code/modules/xenomorph/nest.dm
create mode 100644 code/modules/xenomorph/plant.dm
create mode 100644 code/modules/xenomorph/silo.dm
create mode 100644 code/modules/xenomorph/spawner.dm
create mode 100644 code/modules/xenomorph/trap.dm
create mode 100644 code/modules/xenomorph/tunnel.dm
create mode 100644 code/modules/xenomorph/turret.dm
delete mode 100644 code/modules/xenomorph/xeno_structures.dm
create mode 100644 code/modules/xenomorph/xeno_towers.dm
diff --git a/code/__HELPERS/ai.dm b/code/__HELPERS/ai.dm
index 3b371ce8a67..f7357fe9c9a 100644
--- a/code/__HELPERS/ai.dm
+++ b/code/__HELPERS/ai.dm
@@ -103,3 +103,22 @@
continue
nearest_target = nearby_vehicle
return nearest_target
+
+/**
+ * This proc attempts to get an instance of an atom type within distance, with center as the center.
+ * Arguments
+ * * center - The center of the search
+ * * type - The type of atom we're looking for
+ * * distance - The distance we should search
+ * * list_to_search - The list to look through for the type
+ */
+/proc/cheap_get_atom(atom/center, type, distance, list/list_to_search)
+ var/turf/turf_center = get_turf(center)
+ if(!turf_center)
+ return
+ for(var/atom/near AS in list_to_search)
+ if(!istype(near, type))
+ continue
+ if(get_dist(turf_center, near) > distance)
+ continue
+ return near
diff --git a/code/modules/xenomorph/_xeno_structure.dm b/code/modules/xenomorph/_xeno_structure.dm
new file mode 100644
index 00000000000..cddad162cd9
--- /dev/null
+++ b/code/modules/xenomorph/_xeno_structure.dm
@@ -0,0 +1,59 @@
+/obj/structure/xeno
+ hit_sound = "alien_resin_break"
+ layer = RESIN_STRUCTURE_LAYER
+ resistance_flags = UNACIDABLE
+ ///Bitflags specific to xeno structures
+ var/xeno_structure_flags
+ ///Which hive(number) do we belong to?
+ var/hivenumber = XENO_HIVE_NORMAL
+
+/obj/structure/xeno/Initialize(mapload, _hivenumber)
+ . = ..()
+ if(!(xeno_structure_flags & IGNORE_WEED_REMOVAL))
+ RegisterSignal(loc, COMSIG_TURF_WEED_REMOVED, PROC_REF(weed_removed))
+ if(_hivenumber) ///because admins can spawn them
+ hivenumber = _hivenumber
+ LAZYADDASSOC(GLOB.xeno_structures_by_hive, hivenumber, src)
+ if(xeno_structure_flags & CRITICAL_STRUCTURE)
+ LAZYADDASSOC(GLOB.xeno_critical_structures_by_hive, hivenumber, src)
+
+/obj/structure/xeno/Destroy()
+ if(!locate(src) in GLOB.xeno_structures_by_hive[hivenumber]+GLOB.xeno_critical_structures_by_hive[hivenumber]) //The rest of the proc is pointless to look through if its not in the lists
+ stack_trace("[src] not found in the list of (potentially critical) xeno structures!") //We dont want to CRASH because that'd block deletion completely. Just trace it and continue.
+ return ..()
+ GLOB.xeno_structures_by_hive[hivenumber] -= src
+ if(xeno_structure_flags & CRITICAL_STRUCTURE)
+ GLOB.xeno_critical_structures_by_hive[hivenumber] -= src
+ return ..()
+
+/obj/structure/xeno/ex_act(severity)
+ take_damage(severity * 0.8, BRUTE, BOMB)
+
+/obj/structure/xeno/attack_hand(mob/living/user)
+ balloon_alert(user, "You only scrape at it")
+ return TRUE
+
+/obj/structure/xeno/flamer_fire_act(burnlevel)
+ take_damage(burnlevel / 3, BURN, FIRE)
+
+/obj/structure/xeno/fire_act()
+ take_damage(10, BURN, FIRE)
+
+/// Destroy the xeno structure when the weed it was on is destroyed
+/obj/structure/xeno/proc/weed_removed()
+ SIGNAL_HANDLER
+ var/obj/alien/weeds/found_weed = locate(/obj/alien/weeds) in loc
+ if(found_weed.obj_integrity <= 0)
+ obj_destruction(damage_flag = MELEE)
+ else
+ obj_destruction()
+
+/obj/structure/xeno/attack_alien(mob/living/carbon/xenomorph/xeno_attacker, damage_amount, damage_type, damage_flag, effects, armor_penetration, isrightclick)
+ if(!(HAS_TRAIT(xeno_attacker, TRAIT_VALHALLA_XENO) && xeno_attacker.a_intent == INTENT_HARM && (tgui_alert(xeno_attacker, "Are you sure you want to tear down [src]?", "Tear down [src]?", list("Yes","No"))) == "Yes"))
+ return ..()
+ if(!do_after(xeno_attacker, 3 SECONDS, NONE, src))
+ return
+ xeno_attacker.do_attack_animation(src, ATTACK_EFFECT_CLAW)
+ balloon_alert_to_viewers("\The [xeno_attacker] tears down \the [src]!", "We tear down \the [src].")
+ playsound(src, "alien_resin_break", 25)
+ take_damage(max_integrity) // Ensure its destroyed
diff --git a/code/modules/xenomorph/acidwell.dm b/code/modules/xenomorph/acidwell.dm
new file mode 100644
index 00000000000..3461ab16f41
--- /dev/null
+++ b/code/modules/xenomorph/acidwell.dm
@@ -0,0 +1,192 @@
+/obj/structure/xeno/acidwell
+ name = "acid well"
+ desc = "An acid well. It stores acid to put out fires."
+ icon = 'icons/Xeno/acid_pool.dmi'
+ plane = FLOOR_PLANE
+ icon_state = "well"
+ density = FALSE
+ opacity = FALSE
+ anchored = TRUE
+ max_integrity = 5
+
+ hit_sound = "alien_resin_move"
+ destroy_sound = "alien_resin_move"
+ ///How many charges of acid this well contains
+ var/charges = 1
+ ///If a xeno is charging this well
+ var/charging = FALSE
+ ///What xeno created this well
+ var/mob/living/carbon/xenomorph/creator = null
+
+/obj/structure/xeno/acidwell/Initialize(mapload, _creator)
+ . = ..()
+ creator = _creator
+ RegisterSignal(creator, COMSIG_QDELETING, PROC_REF(clear_creator))
+ update_icon()
+ var/static/list/connections = list(
+ COMSIG_ATOM_ENTERED = PROC_REF(on_cross),
+ )
+ AddElement(/datum/element/connect_loc, connections)
+
+/obj/structure/xeno/acidwell/Destroy()
+ creator = null
+ return ..()
+
+///Signal handler for creator destruction to clear reference
+/obj/structure/xeno/acidwell/proc/clear_creator()
+ SIGNAL_HANDLER
+ creator = null
+
+/obj/structure/xeno/acidwell/obj_destruction(damage_amount, damage_type, damage_flag)
+ if(!QDELETED(creator) && creator.stat == CONSCIOUS && creator.z == z)
+ var/area/A = get_area(src)
+ if(A)
+ to_chat(creator, span_xenoannounce("You sense your acid well at [A.name] has been destroyed!") )
+
+ if(damage_amount || damage_flag) //Spawn the gas only if we actually get destroyed by damage
+ var/datum/effect_system/smoke_spread/xeno/acid/A = new(get_turf(src))
+ A.set_up(clamp(CEILING(charges*0.5, 1),0,3),src) //smoke scales with charges
+ A.start()
+ return ..()
+
+/obj/structure/xeno/acidwell/examine(mob/user)
+ . = ..()
+ if(!isxeno(user) && !isobserver(user))
+ return
+ . += span_xenonotice("An acid well made by [creator]. It currently has [charges]/[XENO_ACID_WELL_MAX_CHARGES] charges.")
+
+/obj/structure/xeno/acidwell/deconstruct(disassembled = TRUE)
+ visible_message(span_danger("[src] suddenly collapses!") )
+ return ..()
+
+/obj/structure/xeno/acidwell/update_icon()
+ . = ..()
+ set_light(charges , charges / 2, LIGHT_COLOR_GREEN)
+
+/obj/structure/xeno/acidwell/update_overlays()
+ . = ..()
+ if(!charges)
+ return
+ . += mutable_appearance(icon, "[charges]", alpha = src.alpha)
+ . += emissive_appearance(icon, "[charges]", alpha = src.alpha)
+
+/obj/structure/xeno/acidwell/flamer_fire_act(burnlevel) //Removes a charge of acid, but fire is extinguished
+ acid_well_fire_interaction()
+
+/obj/structure/xeno/acidwell/fire_act() //Removes a charge of acid, but fire is extinguished
+ acid_well_fire_interaction()
+
+///Handles fire based interactions with the acid well. Depletes 1 charge if there are any to extinguish all fires in the turf while producing acid smoke.
+/obj/structure/xeno/acidwell/proc/acid_well_fire_interaction()
+ if(!charges)
+ take_damage(50, BURN, FIRE)
+ return
+
+ charges--
+ update_icon()
+ var/turf/T = get_turf(src)
+ var/datum/effect_system/smoke_spread/xeno/acid/extuingishing/acid_smoke = new(T) //spawn acid smoke when charges are actually used
+ acid_smoke.set_up(0, src) //acid smoke in the immediate vicinity
+ acid_smoke.start()
+
+ for(var/obj/flamer_fire/F in T) //Extinguish all flames in turf
+ qdel(F)
+
+/obj/structure/xeno/acidwell/attackby(obj/item/I, mob/user, params)
+ if(!isxeno(user))
+ return ..()
+ attack_alien(user)
+
+/obj/structure/xeno/acidwell/attack_alien(mob/living/carbon/xenomorph/xeno_attacker, damage_amount = xeno_attacker.xeno_caste.melee_damage, damage_type = BRUTE, damage_flag = MELEE, effects = TRUE, armor_penetration = 0, isrightclick = FALSE)
+ if(xeno_attacker.a_intent == INTENT_HARM && (CHECK_BITFIELD(xeno_attacker.xeno_caste.caste_flags, CASTE_IS_BUILDER) || xeno_attacker == creator) ) //If we're a builder caste or the creator and we're on harm intent, deconstruct it.
+ balloon_alert(xeno_attacker, "Removing...")
+ if(!do_after(xeno_attacker, XENO_ACID_WELL_FILL_TIME, IGNORE_HELD_ITEM, src, BUSY_ICON_HOSTILE))
+ balloon_alert(xeno_attacker, "Stopped removing")
+ return
+ playsound(src, "alien_resin_break", 25)
+ deconstruct(TRUE, xeno_attacker)
+ return
+
+ if(charges >= 5)
+ balloon_alert(xeno_attacker, "Already full")
+ return
+ if(charging)
+ balloon_alert(xeno_attacker, "Already being filled")
+ return
+
+ if(xeno_attacker.plasma_stored < XENO_ACID_WELL_FILL_COST) //You need to have enough plasma to attempt to fill the well
+ balloon_alert(xeno_attacker, "Need [XENO_ACID_WELL_FILL_COST - xeno_attacker.plasma_stored] more plasma")
+ return
+
+ charging = TRUE
+
+ balloon_alert(xeno_attacker, "Refilling...")
+ if(!do_after(xeno_attacker, XENO_ACID_WELL_FILL_TIME, IGNORE_HELD_ITEM, src, BUSY_ICON_BUILD))
+ charging = FALSE
+ balloon_alert(xeno_attacker, "Aborted refilling")
+ return
+
+ if(xeno_attacker.plasma_stored < XENO_ACID_WELL_FILL_COST)
+ charging = FALSE
+ balloon_alert(xeno_attacker, "Need [XENO_ACID_WELL_FILL_COST - xeno_attacker.plasma_stored] more plasma")
+ return
+
+ xeno_attacker.plasma_stored -= XENO_ACID_WELL_FILL_COST
+ charges++
+ charging = FALSE
+ update_icon()
+ balloon_alert(xeno_attacker, "Now has [charges] / [XENO_ACID_WELL_MAX_CHARGES] charges")
+ to_chat(xeno_attacker,span_xenonotice("We add acid to [src]. It is currently has [charges] / [XENO_ACID_WELL_MAX_CHARGES] charges.") )
+
+/obj/structure/xeno/acidwell/proc/on_cross(datum/source, atom/movable/A, oldloc, oldlocs)
+ SIGNAL_HANDLER
+ if(CHECK_MULTIPLE_BITFIELDS(A.allow_pass_flags, HOVERING))
+ return
+ if(iscarbon(A))
+ HasProximity(A)
+
+/obj/structure/xeno/acidwell/HasProximity(atom/movable/AM)
+ if(!charges)
+ return
+ if(!isliving(AM))
+ return
+ var/mob/living/stepper = AM
+ if(stepper.stat == DEAD)
+ return
+
+ var/charges_used = 0
+
+ for(var/obj/item/explosive/grenade/sticky/sticky_bomb in stepper.contents)
+ if(charges_used >= charges)
+ break
+ if(sticky_bomb.stuck_to == stepper)
+ sticky_bomb.clean_refs()
+ sticky_bomb.forceMove(loc) // i'm not sure if this is even needed, but just to prevent possible bugs
+ visible_message(span_danger("[src] sizzles as [sticky_bomb] melts down in the acid."))
+ qdel(sticky_bomb)
+ charges_used ++
+
+ if(stepper.on_fire && (charges_used < charges))
+ stepper.ExtinguishMob()
+ charges_used ++
+
+ if(!isxeno(stepper))
+ stepper.next_move_slowdown += charges * 2 //Acid spray has slow down so this should too; scales with charges, Min 2 slowdown, Max 10
+ stepper.apply_damage(charges * 10, BURN, BODY_ZONE_PRECISE_L_FOOT, ACID, penetration = 33)
+ stepper.apply_damage(charges * 10, BURN, BODY_ZONE_PRECISE_R_FOOT, ACID, penetration = 33)
+ stepper.visible_message(span_danger("[stepper] is immersed in [src]'s acid!") , \
+ span_danger("We are immersed in [src]'s acid!") , null, 5)
+ playsound(stepper, "sound/bullets/acid_impact1.ogg", 10 * charges)
+ new /obj/effect/temp_visual/acid_bath(get_turf(stepper))
+ charges_used = charges //humans stepping on it empties it out
+
+ if(!charges_used)
+ return
+
+ var/datum/effect_system/smoke_spread/xeno/acid/extuingishing/acid_smoke
+ acid_smoke = new(get_turf(stepper)) //spawn acid smoke when charges are actually used
+ acid_smoke.set_up(0, src) //acid smoke in the immediate vicinity
+ acid_smoke.start()
+
+ charges -= charges_used
+ update_icon()
diff --git a/code/modules/xenomorph/jellypod.dm b/code/modules/xenomorph/jellypod.dm
new file mode 100644
index 00000000000..96c34be0088
--- /dev/null
+++ b/code/modules/xenomorph/jellypod.dm
@@ -0,0 +1,67 @@
+/obj/structure/xeno/resin_jelly_pod
+ name = "Resin jelly pod"
+ desc = "A large resin pod. Inside is a thick, viscous fluid that looks like it doesnt burn easily."
+ icon = 'icons/Xeno/resinpod.dmi'
+ icon_state = "resinpod"
+ density = FALSE
+ opacity = FALSE
+ anchored = TRUE
+ max_integrity = 250
+ layer = RESIN_STRUCTURE_LAYER
+ pixel_x = -16
+ pixel_y = -16
+ xeno_structure_flags = IGNORE_WEED_REMOVAL
+
+ hit_sound = "alien_resin_move"
+ destroy_sound = "alien_resin_move"
+ ///How many actual jellies the pod has stored
+ var/chargesleft = 0
+ ///Max amount of jellies the pod can hold
+ var/maxcharges = 10
+ ///Every 5 times this number seconds we will create a jelly
+ var/recharge_rate = 10
+ ///Countdown to the next time we generate a jelly
+ var/nextjelly = 0
+
+/obj/structure/xeno/resin_jelly_pod/Initialize(mapload, _hivenumber)
+ . = ..()
+ add_overlay(image(icon, "resinpod_inside", layer + 0.01, dir))
+ START_PROCESSING(SSslowprocess, src)
+
+/obj/structure/xeno/resin_jelly_pod/Destroy()
+ STOP_PROCESSING(SSslowprocess, src)
+ return ..()
+
+/obj/structure/xeno/resin_jelly_pod/examine(mob/user, distance, infix, suffix)
+ . = ..()
+ if(isxeno(user))
+ . += "It has [chargesleft] jelly globules remaining[datum_flags & DF_ISPROCESSING ? ", and will create a new jelly in [(recharge_rate-nextjelly)*5] seconds": " and seems latent"]."
+
+/obj/structure/xeno/resin_jelly_pod/process()
+ if(nextjelly <= recharge_rate)
+ nextjelly++
+ return
+ nextjelly = 0
+ chargesleft++
+ if(chargesleft >= maxcharges)
+ return PROCESS_KILL
+
+/obj/structure/xeno/resin_jelly_pod/attack_alien(mob/living/carbon/xenomorph/xeno_attacker, damage_amount = xeno_attacker.xeno_caste.melee_damage, damage_type = BRUTE, damage_flag = MELEE, effects = TRUE, armor_penetration = 0, isrightclick = FALSE)
+ if(xeno_attacker.status_flags & INCORPOREAL)
+ return FALSE
+
+ if((xeno_attacker.a_intent == INTENT_HARM && isxenohivelord(xeno_attacker)) || xeno_attacker.hivenumber != hivenumber)
+ balloon_alert(xeno_attacker, "Destroying...")
+ if(do_after(xeno_attacker, HIVELORD_TUNNEL_DISMANTLE_TIME, IGNORE_HELD_ITEM, src, BUSY_ICON_BUILD))
+ deconstruct(FALSE)
+ return
+
+ if(!chargesleft)
+ balloon_alert(xeno_attacker, "No jelly remaining")
+ to_chat(xeno_attacker, span_xenonotice("We reach into \the [src], but only find dregs of resin. We should wait some more.") )
+ return
+ balloon_alert(xeno_attacker, "Retrieved jelly")
+ new /obj/item/resin_jelly(loc)
+ chargesleft--
+ if(!(datum_flags & DF_ISPROCESSING) && (chargesleft < maxcharges))
+ START_PROCESSING(SSslowprocess, src)
diff --git a/code/modules/xenomorph/nest.dm b/code/modules/xenomorph/nest.dm
new file mode 100644
index 00000000000..52b388d1b02
--- /dev/null
+++ b/code/modules/xenomorph/nest.dm
@@ -0,0 +1,63 @@
+/obj/structure/bed/nest
+ var/force_nest = FALSE
+
+/obj/structure/bed/nest/structure
+ name = "thick alien nest"
+ desc = "A very thick nest, oozing with a thick sticky substance."
+ force_nest = TRUE
+ var/obj/structure/xeno/thick_nest/linked_structure
+
+/obj/structure/bed/nest/structure/Initialize(mapload, hive, obj/structure/xeno/thick_nest/to_link)
+ . = ..()
+ if(to_link)
+ linked_structure = to_link
+ max_integrity = linked_structure.max_integrity
+
+/obj/structure/bed/nest/structure/Destroy()
+ . = ..()
+ if(linked_structure)
+ linked_structure.pred_nest = null
+ QDEL_NULL(linked_structure)
+
+/obj/structure/bed/nest/structure/attack_hand(mob/user)
+ if(!isxeno(user))
+ to_chat(user, span_notice("The sticky resin is too strong for you to do anything to this nest"))
+ return FALSE
+ . = ..()
+
+/obj/structure/xeno/thick_nest
+ name = "thick resin nest"
+ desc = "A very thick nest, oozing with a thick sticky substance."
+ pixel_x = -8
+ pixel_y = -8
+ max_integrity = 400
+ mouse_opacity = MOUSE_OPACITY_ICON
+ icon = 'icons/Xeno/nest.dmi'
+ icon_state = "reinforced_nest"
+ layer = 2.5
+ var/obj/structure/bed/nest/structure/pred_nest
+
+/obj/structure/xeno/thick_nest/examine(mob/user)
+ . = ..()
+ if((isxeno(user) || isobserver(user)) && hivenumber)
+ . += "Used to secure formidable hosts."
+
+/obj/structure/xeno/thick_nest/Initialize(mapload, new_hivenumber)
+ . = ..()
+ if(new_hivenumber)
+ hivenumber = new_hivenumber
+
+ var/datum/hive_status/hive_ref = GLOB.hive_datums[hivenumber]
+ if(hive_ref)
+ hive_ref.thick_nests += src
+
+ pred_nest = new /obj/structure/bed/nest/structure(loc, hive_ref, src) // Nest cannot be destroyed unless the structure itself is destroyed
+
+/obj/structure/xeno/thick_nest/Destroy()
+ . = ..()
+
+ if(hivenumber)
+ GLOB.hive_datums[hivenumber].thick_nests -= src
+
+ pred_nest?.linked_structure = null
+ QDEL_NULL(pred_nest)
diff --git a/code/modules/xenomorph/plant.dm b/code/modules/xenomorph/plant.dm
new file mode 100644
index 00000000000..48e4da15369
--- /dev/null
+++ b/code/modules/xenomorph/plant.dm
@@ -0,0 +1,255 @@
+/obj/structure/xeno/plant
+ name = "Xeno Plant"
+ max_integrity = 5
+ icon = 'icons/Xeno/plants.dmi'
+ interaction_flags = INTERACT_CHECK_INCAPACITATED
+ ///The plant's icon once it's fully grown
+ var/mature_icon_state
+ ///Is the plant ready to be used ?
+ var/mature = FALSE
+ ///How long does it take for the plant to be useable
+ var/maturation_time = 2 MINUTES
+
+/obj/structure/xeno/plant/Initialize(mapload, _hivenumber)
+ . = ..()
+ addtimer(CALLBACK(src, PROC_REF(on_mature)), maturation_time)
+ SSminimaps.add_marker(src, MINIMAP_FLAG_XENO, image('icons/UI_icons/map_blips.dmi', null, "[mature_icon_state]"))
+
+/obj/structure/xeno/plant/can_interact(mob/user)
+ . = ..()
+ if(!.)
+ return FALSE
+ if(!mature && isxeno(user))
+ balloon_alert(user, "Not fully grown")
+ return FALSE
+
+/obj/structure/xeno/plant/update_icon_state()
+ . = ..()
+ icon_state = (mature) ? mature_icon_state : initial(icon_state)
+
+///Called whenever someone uses the plant, xeno or marine
+/obj/structure/xeno/plant/proc/on_use(mob/user)
+ mature = FALSE
+ update_icon()
+ addtimer(CALLBACK(src, PROC_REF(on_mature)), maturation_time)
+ return TRUE
+
+///Called when the plant reaches maturity
+/obj/structure/xeno/plant/proc/on_mature(mob/user)
+ playsound(src, "alien_resin_build", 25)
+ mature = TRUE
+ update_icon()
+
+/obj/structure/xeno/plant/attack_hand(mob/living/user)
+ if(!can_interact(user))
+ return ..()
+ return on_use(user)
+
+/obj/structure/xeno/plant/attack_alien(mob/living/carbon/xenomorph/xeno_attacker, damage_amount = xeno_attacker.xeno_caste.melee_damage, damage_type = BRUTE, damage_flag = MELEE, effects = TRUE, armor_penetration = 0, isrightclick = FALSE)
+ if((xeno_attacker.status_flags & INCORPOREAL))
+ return FALSE
+
+ if(xeno_attacker.a_intent == INTENT_HARM && isxenodrone(xeno_attacker))
+ balloon_alert(xeno_attacker, "Uprooted the plant")
+ xeno_attacker.do_attack_animation(src)
+ deconstruct(FALSE)
+ return FALSE
+ if(can_interact(xeno_attacker))
+ return on_use(xeno_attacker)
+ return TRUE
+
+/obj/structure/xeno/plant/heal_fruit
+ name = "life fruit"
+ desc = "It would almost be appetizing wasn't it for the green colour and the shifting fluids inside..."
+ icon_state = "heal_fruit_immature"
+ mature_icon_state = "heal_fruit"
+ ///Minimum amount of health recovered
+ var/healing_amount_min = 125
+ ///Maximum amount of health recovered, depends on the xeno's max health
+ var/healing_amount_max_health_scaling = 0.5
+
+/obj/structure/xeno/plant/heal_fruit/on_use(mob/user)
+ balloon_alert(user, "Consuming...")
+ if(!do_after(user, 2 SECONDS, IGNORE_HELD_ITEM, src))
+ return FALSE
+ if(!isxeno(user))
+ var/datum/effect_system/smoke_spread/xeno/acid/plant_explosion = new(get_turf(src))
+ plant_explosion.set_up(3,src)
+ plant_explosion.start()
+ visible_message(span_danger("[src] bursts, releasing toxic gas!"))
+ qdel(src)
+ return TRUE
+
+ var/mob/living/carbon/xenomorph/X = user
+ var/heal_amount = max(healing_amount_min, healing_amount_max_health_scaling * X.xeno_caste.max_health)
+ HEAL_XENO_DAMAGE(X, heal_amount, FALSE)
+ playsound(user, "alien_drool", 25)
+ balloon_alert(X, "Health restored")
+ to_chat(X, span_xenowarning("We feel a sudden soothing chill as [src] tends to our wounds."))
+
+ return ..()
+
+/obj/structure/xeno/plant/armor_fruit
+ name = "hard fruit"
+ desc = "The contents of this fruit are protected by a tough outer shell."
+ icon_state = "armor_fruit_immature"
+ mature_icon_state = "armor_fruit"
+ ///How much total sunder should we remove
+ var/sunder_removal = 30
+
+/obj/structure/xeno/plant/armor_fruit/on_use(mob/user)
+ balloon_alert(user, "Consuming...")
+ if(!do_after(user, 2 SECONDS, IGNORE_HELD_ITEM, src))
+ return FALSE
+ if(!isxeno(user))
+ var/turf/far_away_lands = get_turf(user)
+ for(var/x in 1 to 20)
+ var/turf/next_turf = get_step(far_away_lands, REVERSE_DIR(user.dir))
+ if(!next_turf)
+ break
+ far_away_lands = next_turf
+
+ user.throw_at(far_away_lands, 20, spin = TRUE)
+ to_chat(user, span_warning("[src] bursts, releasing a strong gust of pressurised gas!"))
+ if(ishuman(user))
+ var/mob/living/carbon/human/H = user
+ H.adjust_stagger(3 SECONDS)
+ H.apply_damage(30, BRUTE, "chest", BOMB)
+ qdel(src)
+ return TRUE
+
+ balloon_alert(user, "Armor restored")
+ to_chat(user, span_xenowarning("We shed our shattered scales as new ones grow to replace them!"))
+ var/mob/living/carbon/xenomorph/X = user
+ X.adjust_sunder(-sunder_removal)
+ playsound(user, "alien_drool", 25)
+ return ..()
+
+/obj/structure/xeno/plant/plasma_fruit
+ name = "power fruit"
+ desc = "A cyan fruit, beating like a creature's heart"
+ icon_state = "plasma_fruit_immature"
+ mature_icon_state = "plasma_fruit"
+ ///How much bonus plasma should we restore during the duration, 1 being 100% from base regen
+ var/bonus_regen = 1
+ ///How long should the buff last
+ var/duration = 1 MINUTES
+
+/obj/structure/xeno/plant/plasma_fruit/can_interact(mob/user)
+ . = ..()
+ if(!.)
+ return FALSE
+ if(!isxeno(user))
+ return
+ var/mob/living/carbon/xenomorph/X = user
+ if(X.has_status_effect(STATUS_EFFECT_PLASMA_SURGE))
+ balloon_alert(X, "Already increased plasma regen")
+ return FALSE
+
+/obj/structure/xeno/plant/plasma_fruit/on_use(mob/user)
+ balloon_alert(user, "Consuming...")
+ if(!do_after(user, 2 SECONDS, IGNORE_HELD_ITEM, src))
+ return FALSE
+ if(!isxeno(user))
+ visible_message(span_warning("[src] releases a sticky substance before spontaneously bursting into flames!"))
+ flame_radius(3, get_turf(src), colour = "green")
+ qdel(src)
+ return TRUE
+
+ var/mob/living/carbon/xenomorph/X = user
+ if(!(X.xeno_caste.can_flags & CASTE_CAN_BE_GIVEN_PLASMA))
+ to_chat(X, span_xenowarning("But our body rejects the fruit, we do not share the same plasma type!"))
+ return FALSE
+ X.apply_status_effect(/datum/status_effect/plasma_surge, X.xeno_caste.plasma_max, bonus_regen, duration)
+ balloon_alert(X, "Plasma restored")
+ to_chat(X, span_xenowarning("[src] Restores our plasma reserves, our organism is on overdrive!"))
+ playsound(user, "alien_drool", 25)
+ return ..()
+
+/obj/structure/xeno/plant/stealth_plant
+ name = "night shade"
+ desc = "A beautiful flower, what purpose it could serve to the alien hive is beyond you however..."
+ icon_state = "stealth_plant_immature"
+ mature_icon_state = "stealth_plant"
+ maturation_time = 4 MINUTES
+ ///The radius of the passive structure camouflage, requires line of sight
+ var/camouflage_range = 7
+ ///The range of the active stealth ability, does not require line of sight
+ var/active_camouflage_pulse_range = 10
+ ///How long should veil last
+ var/active_camouflage_duration = 20 SECONDS
+ ///How long until the plant can be activated again
+ var/cooldown = 2 MINUTES
+ ///Is the active ability veil on cooldown ?
+ var/on_cooldown = FALSE
+ ///The list of passively camouflaged structures
+ var/list/obj/structure/xeno/camouflaged_structures = list()
+ ////The list of actively camouflaged xenos by veil
+ var/list/mob/living/carbon/xenomorph/camouflaged_xenos = list()
+
+/obj/structure/xeno/plant/stealth_plant/on_mature(mob/user)
+ . = ..()
+ START_PROCESSING(SSslowprocess, src)
+
+/obj/structure/xeno/plant/stealth_plant/Destroy()
+ for(var/obj/structure/xeno/xeno_struct AS in camouflaged_structures)
+ xeno_struct.alpha = initial(xeno_struct.alpha)
+ unveil()
+ STOP_PROCESSING(SSslowprocess, src)
+ return ..()
+
+/obj/structure/xeno/plant/stealth_plant/process()
+ for(var/turf/tile AS in RANGE_TURFS(camouflage_range, loc))
+ for(var/obj/structure/xeno/xeno_struct in tile)
+ if(istype(xeno_struct, /obj/structure/xeno/plant) || !line_of_sight(src, xeno_struct)) //We don't hide plants
+ continue
+ camouflaged_structures.Add(xeno_struct)
+ xeno_struct.alpha = STEALTH_PLANT_PASSIVE_CAMOUFLAGE_ALPHA
+
+/obj/structure/xeno/plant/stealth_plant/can_interact(mob/user)
+ . = ..()
+ if(!.)
+ return FALSE
+ if(ishuman(user))
+ balloon_alert(user, "Nothing happens")
+ to_chat(user, span_notice("You caress [src]'s petals, nothing happens."))
+ return FALSE
+ if(on_cooldown)
+ balloon_alert(user, "Not ready yet")
+ to_chat(user, span_xenowarning("[src] soft light shimmers, we should give it more time to recover!"))
+ return FALSE
+
+/obj/structure/xeno/plant/stealth_plant/on_use(mob/user)
+ balloon_alert(user, "Shaking...")
+ if(!do_after(user, 2 SECONDS, IGNORE_HELD_ITEM, src))
+ return FALSE
+ visible_message(span_danger("[src] releases a burst of glowing pollen!"))
+ veil()
+ return TRUE
+
+///Hides all nearby xenos
+/obj/structure/xeno/plant/stealth_plant/proc/veil()
+ for(var/turf/tile in RANGE_TURFS(camouflage_range, loc))
+ for(var/mob/living/carbon/xenomorph/X in tile)
+ if(X.stat == DEAD || isxenohunter(X) || X.alpha != 255) //We don't mess with xenos capable of going stealth by themselves
+ continue
+ X.alpha = HUNTER_STEALTH_RUN_ALPHA
+ new /obj/effect/temp_visual/alien_fruit_eaten(get_turf(X))
+ balloon_alert(X, "We now blend in")
+ to_chat(X, span_xenowarning("The pollen from [src] reacts with our scales, we are blending with our surroundings!"))
+ camouflaged_xenos.Add(X)
+ on_cooldown = TRUE
+ addtimer(CALLBACK(src, PROC_REF(unveil)), active_camouflage_duration)
+ addtimer(CALLBACK(src, PROC_REF(ready)), cooldown)
+
+///Called when veil() can be used once again
+/obj/structure/xeno/plant/stealth_plant/proc/ready()
+ visible_message(span_danger("[src] petals shift in hue, it is ready to release more pollen."))
+ on_cooldown = FALSE
+
+///Reveals all xenos hidden by veil()
+/obj/structure/xeno/plant/stealth_plant/proc/unveil()
+ for(var/mob/living/carbon/xenomorph/X AS in camouflaged_xenos)
+ X.alpha = initial(X.alpha)
+ balloon_alert(X, "Effect wears off")
+ to_chat(X, span_xenowarning("The effect of [src] wears off!"))
diff --git a/code/modules/xenomorph/silo.dm b/code/modules/xenomorph/silo.dm
new file mode 100644
index 00000000000..ef3e9ac28ff
--- /dev/null
+++ b/code/modules/xenomorph/silo.dm
@@ -0,0 +1,159 @@
+/obj/structure/xeno/silo
+ name = "Resin silo"
+ icon = 'icons/Xeno/resin_silo.dmi'
+ icon_state = "weed_silo"
+ desc = "A slimy, oozy resin bed filled with foul-looking egg-like ...things."
+ bound_width = 96
+ bound_height = 96
+ max_integrity = 1000
+ resistance_flags = UNACIDABLE | DROPSHIP_IMMUNE | PLASMACUTTER_IMMUNE
+ xeno_structure_flags = IGNORE_WEED_REMOVAL|CRITICAL_STRUCTURE
+ plane = FLOOR_PLANE
+ ///How many larva points one silo produce in one minute
+ var/larva_spawn_rate = 0.5
+ var/turf/center_turf
+ var/number_silo
+ ///For minimap icon change if silo takes damage or nearby hostile
+ var/warning
+ COOLDOWN_DECLARE(silo_damage_alert_cooldown)
+ COOLDOWN_DECLARE(silo_proxy_alert_cooldown)
+
+/obj/structure/xeno/silo/Initialize(mapload, _hivenumber)
+ . = ..()
+ center_turf = get_step(src, NORTHEAST)
+ if(!istype(center_turf))
+ center_turf = loc
+
+ if(SSticker.mode?.flags_round_type & MODE_SILO_RESPAWN)
+ for(var/turfs in RANGE_TURFS(XENO_SILO_DETECTION_RANGE, src))
+ RegisterSignal(turfs, COMSIG_ATOM_ENTERED, PROC_REF(resin_silo_proxy_alert))
+
+ if(SSticker.mode?.flags_round_type & MODE_SILOS_SPAWN_MINIONS)
+ SSspawning.registerspawner(src, INFINITY, GLOB.xeno_ai_spawnable, 0, 0, null)
+ SSspawning.spawnerdata[src].required_increment = 2 * max(45 SECONDS, 3 MINUTES - SSmonitor.maximum_connected_players_count * SPAWN_RATE_PER_PLAYER)/SSspawning.wait
+ SSspawning.spawnerdata[src].max_allowed_mobs = max(1, MAX_SPAWNABLE_MOB_PER_PLAYER * SSmonitor.maximum_connected_players_count * 0.5)
+ update_minimap_icon()
+
+ return INITIALIZE_HINT_LATELOAD
+
+/obj/structure/xeno/silo/LateInitialize()
+ . = ..()
+ var/siloprefix = GLOB.hive_datums[hivenumber].name
+ number_silo = length(GLOB.xeno_resin_silos_by_hive[hivenumber]) + 1
+ name = "[siloprefix == "Normal" ? "" : "[siloprefix] "][name] [number_silo]"
+ LAZYADDASSOC(GLOB.xeno_resin_silos_by_hive, hivenumber, src)
+
+ if(!locate(/obj/alien/weeds) in center_turf)
+ new /obj/alien/weeds/node(center_turf)
+ if(GLOB.hive_datums[hivenumber])
+ RegisterSignals(GLOB.hive_datums[hivenumber], list(COMSIG_HIVE_XENO_MOTHER_PRE_CHECK, COMSIG_HIVE_XENO_MOTHER_CHECK), PROC_REF(is_burrowed_larva_host))
+ if(length(GLOB.xeno_resin_silos_by_hive[hivenumber]) == 1)
+ GLOB.hive_datums[hivenumber].give_larva_to_next_in_queue()
+ var/turf/tunnel_turf = get_step(center_turf, NORTH)
+ if(tunnel_turf.can_dig_xeno_tunnel())
+ var/obj/structure/xeno/tunnel/newt = new(tunnel_turf, hivenumber)
+ newt.tunnel_desc = "[AREACOORD_NO_Z(newt)]"
+ newt.name += " [name]"
+ if(GLOB.hive_datums[hivenumber])
+ SSticker.mode.update_silo_death_timer(GLOB.hive_datums[hivenumber])
+
+/obj/structure/xeno/silo/obj_destruction(damage_amount, damage_type, damage_flag)
+ if(GLOB.hive_datums[hivenumber])
+ INVOKE_NEXT_TICK(SSticker.mode, TYPE_PROC_REF(/datum/game_mode, update_silo_death_timer), GLOB.hive_datums[hivenumber]) // checks all silos next tick after this one is gone
+ UnregisterSignal(GLOB.hive_datums[hivenumber], list(COMSIG_HIVE_XENO_MOTHER_PRE_CHECK, COMSIG_HIVE_XENO_MOTHER_CHECK))
+ GLOB.hive_datums[hivenumber].xeno_message("A resin silo has been destroyed at [AREACOORD_NO_Z(src)]!", "xenoannounce", 5, FALSE,src.loc, 'sound/voice/alien_help2.ogg',FALSE , null, /atom/movable/screen/arrow/silo_damaged_arrow)
+ notify_ghosts("\ A resin silo has been destroyed at [AREACOORD_NO_Z(src)]!", source = get_turf(src), action = NOTIFY_JUMP)
+ playsound(loc,'sound/effects/alien_egg_burst.ogg', 75)
+ return ..()
+
+/obj/structure/xeno/silo/Destroy()
+ GLOB.xeno_resin_silos_by_hive[hivenumber] -= src
+
+ for(var/i in contents)
+ var/atom/movable/AM = i
+ AM.forceMove(get_step(center_turf, pick(CARDINAL_ALL_DIRS)))
+ center_turf = null
+
+ STOP_PROCESSING(SSslowprocess, src)
+ return ..()
+
+/obj/structure/xeno/silo/examine(mob/user)
+ . = ..()
+ var/current_integrity = (obj_integrity / max_integrity) * 100
+ switch(current_integrity)
+ if(0 to 20)
+ . += span_warning("It's barely holding, there's leaking oozes all around, and most eggs are broken. Yet it is not inert.")
+ if(20 to 40)
+ . += span_warning("It looks severely damaged, its movements slow.")
+ if(40 to 60)
+ . += span_warning("It's quite beat up, but it seems alive.")
+ if(60 to 80)
+ . += span_warning("It's slightly damaged, but still seems healthy.")
+ if(80 to 100)
+ . += span_info("It appears in good shape, pulsating healthily.")
+
+/obj/structure/xeno/silo/take_damage(damage_amount, damage_type, damage_flag, sound_effect, attack_dir, armour_penetration)
+ . = ..()
+
+ //We took damage, so it's time to start regenerating if we're not already processing
+ if(!CHECK_BITFIELD(datum_flags, DF_ISPROCESSING))
+ START_PROCESSING(SSslowprocess, src)
+
+ resin_silo_damage_alert()
+
+/obj/structure/xeno/silo/proc/resin_silo_damage_alert()
+ if(!COOLDOWN_CHECK(src, silo_damage_alert_cooldown))
+ return
+ warning = TRUE
+ update_minimap_icon()
+ GLOB.hive_datums[hivenumber].xeno_message("Our [name] at [AREACOORD_NO_Z(src)] is under attack! It has [obj_integrity]/[max_integrity] Health remaining.", "xenoannounce", 5, FALSE, src, 'sound/voice/alien_help1.ogg',FALSE, null, /atom/movable/screen/arrow/silo_damaged_arrow)
+ COOLDOWN_START(src, silo_damage_alert_cooldown, XENO_SILO_HEALTH_ALERT_COOLDOWN) //set the cooldown.
+ addtimer(CALLBACK(src, PROC_REF(clear_warning)), XENO_SILO_HEALTH_ALERT_COOLDOWN) //clear warning
+
+///Alerts the Hive when hostiles get too close to their resin silo
+/obj/structure/xeno/silo/proc/resin_silo_proxy_alert(datum/source, atom/movable/hostile, direction)
+ SIGNAL_HANDLER
+
+ if(!COOLDOWN_CHECK(src, silo_proxy_alert_cooldown)) //Proxy alert triggered too recently; abort
+ return
+
+ if(!isliving(hostile))
+ return
+
+ var/mob/living/living_triggerer = hostile
+ if(living_triggerer.stat == DEAD) //We don't care about the dead
+ return
+
+ if(isxeno(hostile))
+ var/mob/living/carbon/xenomorph/X = hostile
+ if(X.hive == GLOB.hive_datums[hivenumber]) //Trigger proxy alert only for hostile xenos
+ return
+
+ warning = TRUE
+ update_minimap_icon()
+ GLOB.hive_datums[hivenumber].xeno_message("Our [name] has detected a nearby hostile [hostile] at [get_area(hostile)] (X: [hostile.x], Y: [hostile.y]).", "xenoannounce", 5, FALSE, hostile, 'sound/voice/alien_help1.ogg', FALSE, null, /atom/movable/screen/arrow/leader_tracker_arrow)
+ COOLDOWN_START(src, silo_proxy_alert_cooldown, XENO_SILO_DETECTION_COOLDOWN) //set the cooldown.
+ addtimer(CALLBACK(src, PROC_REF(clear_warning)), XENO_SILO_DETECTION_COOLDOWN) //clear warning
+
+///Clears the warning for minimap if its warning for hostiles
+/obj/structure/xeno/silo/proc/clear_warning()
+ warning = FALSE
+ update_minimap_icon()
+
+/obj/structure/xeno/silo/process()
+ //Regenerate if we're at less than max integrity
+ if(obj_integrity < max_integrity)
+ obj_integrity = min(obj_integrity + 25, max_integrity) //Regen 5 HP per sec
+
+/obj/structure/xeno/silo/proc/is_burrowed_larva_host(datum/source, list/mothers, list/silos)
+ SIGNAL_HANDLER
+ if(GLOB.hive_datums[hivenumber])
+ silos += src
+
+///Change minimap icon if silo is under attack or not
+/obj/structure/xeno/silo/proc/update_minimap_icon()
+ SSminimaps.remove_marker(src)
+ SSminimaps.add_marker(src, MINIMAP_FLAG_XENO, image('icons/UI_icons/map_blips.dmi', null, "silo[warning ? "_warn" : "_passive"]", VERY_HIGH_FLOAT_LAYER)) // RU TGMC edit - map blips
+
+/obj/structure/xeno/silo/crash
+ resistance_flags = UNACIDABLE | DROPSHIP_IMMUNE | PLASMACUTTER_IMMUNE | INDESTRUCTIBLE
diff --git a/code/modules/xenomorph/spawner.dm b/code/modules/xenomorph/spawner.dm
new file mode 100644
index 00000000000..441780081b0
--- /dev/null
+++ b/code/modules/xenomorph/spawner.dm
@@ -0,0 +1,112 @@
+/obj/structure/xeno/spawner
+ icon = 'icons/Xeno/2x2building.dmi.dmi'
+ bound_width = 64
+ bound_height = 64
+ plane = FLOOR_PLANE
+ name = "spawner"
+ desc = "A slimy, oozy resin bed filled with foul-looking egg-like ...things."
+ icon_state = "spawner"
+ max_integrity = 500
+ resistance_flags = UNACIDABLE | DROPSHIP_IMMUNE
+ xeno_structure_flags = IGNORE_WEED_REMOVAL | CRITICAL_STRUCTURE
+ ///For minimap icon change if silo takes damage or nearby hostile
+ var/warning
+ COOLDOWN_DECLARE(spawner_damage_alert_cooldown)
+ COOLDOWN_DECLARE(spawner_proxy_alert_cooldown)
+ var/linked_minions = list()
+
+/obj/structure/xeno/spawner/Initialize(mapload, _hivenumber)
+ . = ..()
+ LAZYADDASSOC(GLOB.xeno_spawners_by_hive, hivenumber, src)
+ SSspawning.registerspawner(src, INFINITY, GLOB.xeno_ai_spawnable, 0, 0, CALLBACK(src, PROC_REF(on_spawn)))
+ SSspawning.spawnerdata[src].required_increment = max(45 SECONDS, 3 MINUTES - SSmonitor.maximum_connected_players_count * SPAWN_RATE_PER_PLAYER)/SSspawning.wait
+ SSspawning.spawnerdata[src].max_allowed_mobs = max(2, MAX_SPAWNABLE_MOB_PER_PLAYER * SSmonitor.maximum_connected_players_count)
+ set_light(2, 2, LIGHT_COLOR_GREEN)
+ for(var/turfs in RANGE_TURFS(XENO_SILO_DETECTION_RANGE, src))
+ RegisterSignal(turfs, COMSIG_ATOM_ENTERED, PROC_REF(spawner_proxy_alert))
+ update_minimap_icon()
+
+/obj/structure/xeno/spawner/examine(mob/user)
+ . = ..()
+ var/current_integrity = (obj_integrity / max_integrity) * 100
+ switch(current_integrity)
+ if(0 to 20)
+ . += span_warning("It's barely holding, there's leaking oozes all around, and most eggs are broken. Yet it is not inert.")
+ if(20 to 40)
+ . += span_warning("It looks severely damaged, its movements slow.")
+ if(40 to 60)
+ . += span_warning("It's quite beat up, but it seems alive.")
+ if(60 to 80)
+ . += span_warning("It's slightly damaged, but still seems healthy.")
+ if(80 to 100)
+ . += span_info("It appears in good shape, pulsating healthily.")
+
+
+/obj/structure/xeno/spawner/take_damage(damage_amount, damage_type, damage_flag, sound_effect, attack_dir, armour_penetration)
+ . = ..()
+ spawner_damage_alert()
+
+///Alert if spawner is receiving damage
+/obj/structure/xeno/spawner/proc/spawner_damage_alert()
+ if(!COOLDOWN_CHECK(src, spawner_damage_alert_cooldown))
+ warning = FALSE
+ return
+ warning = TRUE
+ update_minimap_icon()
+ GLOB.hive_datums[hivenumber].xeno_message("Our [name] at [AREACOORD_NO_Z(src)] is under attack! It has [obj_integrity]/[max_integrity] Health remaining.", "xenoannounce", 5, FALSE, src, 'sound/voice/alien_help1.ogg',FALSE, null, /atom/movable/screen/arrow/silo_damaged_arrow)
+ COOLDOWN_START(src, spawner_damage_alert_cooldown, XENO_SILO_HEALTH_ALERT_COOLDOWN) //set the cooldown.
+ addtimer(CALLBACK(src, PROC_REF(clear_warning)), XENO_SILO_DETECTION_COOLDOWN) //clear warning
+
+///Alerts the Hive when hostiles get too close to their spawner
+/obj/structure/xeno/spawner/proc/spawner_proxy_alert(datum/source, atom/movable/hostile, direction)
+ SIGNAL_HANDLER
+
+ if(!COOLDOWN_CHECK(src, spawner_proxy_alert_cooldown)) //Proxy alert triggered too recently; abort
+ warning = FALSE
+ return
+
+ if(!isliving(hostile))
+ return
+
+ var/mob/living/living_triggerer = hostile
+ if(living_triggerer.stat == DEAD) //We don't care about the dead
+ return
+
+ if(isxeno(hostile))
+ var/mob/living/carbon/xenomorph/X = hostile
+ if(X.hivenumber == hivenumber) //Trigger proxy alert only for hostile xenos
+ return
+
+ warning = TRUE
+ update_minimap_icon()
+ GLOB.hive_datums[hivenumber].xeno_message("Our [name] has detected a nearby hostile [hostile] at [get_area(hostile)] (X: [hostile.x], Y: [hostile.y]).", "xenoannounce", 5, FALSE, hostile, 'sound/voice/alien_help1.ogg', FALSE, null, /atom/movable/screen/arrow/leader_tracker_arrow)
+ COOLDOWN_START(src, spawner_proxy_alert_cooldown, XENO_SILO_DETECTION_COOLDOWN) //set the cooldown.
+ addtimer(CALLBACK(src, PROC_REF(clear_warning)), XENO_SILO_DETECTION_COOLDOWN) //clear warning
+
+///Clears the warning for minimap if its warning for hostiles
+/obj/structure/xeno/spawner/proc/clear_warning()
+ warning = FALSE
+ update_minimap_icon()
+
+/obj/structure/xeno/spawner/Destroy()
+ GLOB.xeno_spawners_by_hive[hivenumber] -= src
+ return ..()
+
+///Change minimap icon if spawner is under attack or not
+/obj/structure/xeno/spawner/proc/update_minimap_icon()
+ SSminimaps.remove_marker(src)
+ SSminimaps.add_marker(src, MINIMAP_FLAG_XENO, image('icons/UI_icons/map_blips.dmi', null, "spawner[warning ? "_warn" : "_passive"]", , ABOVE_FLOAT_LAYER)) // RU TGMC edit - map blips
+
+/obj/structure/xeno/spawner/proc/on_spawn(list/squad)
+ if(!isxeno(squad[length(squad)]))
+ CRASH("Xeno spawner somehow tried to spawn a non xeno (tried to spawn [squad[length(squad)]])")
+ var/mob/living/carbon/xenomorph/X = squad[length(squad)]
+ X.transfer_to_hive(hivenumber)
+ linked_minions = squad
+ if(hivenumber == XENO_HIVE_FALLEN) //snowflake so valhalla isnt filled with minions after you're done
+ RegisterSignal(src, COMSIG_QDELETING, PROC_REF(kill_linked_minions))
+
+/obj/structure/xeno/spawner/proc/kill_linked_minions()
+ for(var/mob/living/carbon/xenomorph/linked in linked_minions)
+ linked.death(TRUE)
+ UnregisterSignal(src, COMSIG_QDELETING)
diff --git a/code/modules/xenomorph/trap.dm b/code/modules/xenomorph/trap.dm
new file mode 100644
index 00000000000..f6180ad44ae
--- /dev/null
+++ b/code/modules/xenomorph/trap.dm
@@ -0,0 +1,211 @@
+/obj/structure/xeno/trap
+ desc = "It looks like a hiding hole."
+ name = "resin hole"
+ icon = 'icons/Xeno/Effects.dmi'
+ icon_state = "trap"
+ density = FALSE
+ opacity = FALSE
+ anchored = TRUE
+ max_integrity = 5
+ layer = RESIN_STRUCTURE_LAYER
+ destroy_sound = "alien_resin_break"
+ ///defines for trap type to trigger on activation
+ var/trap_type
+ ///The hugger inside our trap
+ var/obj/item/clothing/mask/facehugger/hugger = null
+ ///smoke effect to create when the trap is triggered
+ var/datum/effect_system/smoke_spread/smoke
+ ///connection list for huggers
+ var/static/list/listen_connections = list(
+ COMSIG_ATOM_ENTERED = PROC_REF(trigger_trap),
+ )
+
+/obj/structure/xeno/trap/Initialize(mapload, _hivenumber)
+ . = ..()
+ AddElement(/datum/element/connect_loc, listen_connections)
+
+/obj/structure/xeno/trap/ex_act(severity)
+ take_damage(severity, BRUTE, BOMB)
+
+/obj/structure/xeno/trap/update_icon_state()
+ . = ..()
+ switch(trap_type)
+ if(TRAP_HUGGER)
+ icon_state = "traphugger"
+ if(TRAP_SMOKE_NEURO)
+ icon_state = "trapneurogas"
+ if(TRAP_SMOKE_ACID)
+ icon_state = "trapacidgas"
+ if(TRAP_ACID_WEAK)
+ icon_state = "trapacidweak"
+ if(TRAP_ACID_NORMAL)
+ icon_state = "trapacid"
+ if(TRAP_ACID_STRONG)
+ icon_state = "trapacidstrong"
+ else
+ icon_state = "trap"
+
+/obj/structure/xeno/trap/obj_destruction(damage_amount, damage_type, damage_flag)
+ if((damage_amount || damage_flag) && hugger && loc)
+ trigger_trap()
+ return ..()
+
+/obj/structure/xeno/trap/proc/set_trap_type(new_trap_type)
+ if(new_trap_type == trap_type)
+ return
+ trap_type = new_trap_type
+ update_icon()
+
+/obj/structure/xeno/trap/examine(mob/user)
+ . = ..()
+ if(!isxeno(user))
+ return
+ . += "A hole for a little one to hide in ambush for or for spewing acid."
+ switch(trap_type)
+ if(TRAP_HUGGER)
+ . += "There's a little one inside."
+ if(TRAP_SMOKE_NEURO)
+ . += "There's pressurized neurotoxin inside."
+ if(TRAP_SMOKE_ACID)
+ . += "There's pressurized acid gas inside."
+ if(TRAP_ACID_WEAK)
+ . += "There's pressurized weak acid inside."
+ if(TRAP_ACID_NORMAL)
+ . += "There's pressurized normal acid inside."
+ if(TRAP_ACID_STRONG)
+ . += "There's strong pressurized acid inside."
+ else
+ . += "It's empty."
+
+/obj/structure/xeno/trap/flamer_fire_act(burnlevel)
+ hugger?.kill_hugger()
+ trigger_trap()
+ set_trap_type(null)
+
+/obj/structure/xeno/trap/fire_act()
+ hugger?.kill_hugger()
+ trigger_trap()
+ set_trap_type(null)
+
+///Triggers the hugger trap
+/obj/structure/xeno/trap/proc/trigger_trap(datum/source, atom/movable/AM, oldloc, oldlocs)
+ SIGNAL_HANDLER
+ if(!trap_type)
+ return
+ if(AM && (hivenumber == AM.get_xeno_hivenumber()))
+ return
+ playsound(src, "alien_resin_break", 25)
+ if(iscarbon(AM))
+ var/mob/living/carbon/crosser = AM
+ crosser.visible_message(span_warning("[crosser] trips on [src]!"), span_danger("You trip on [src]!"))
+ crosser.ParalyzeNoChain(4 SECONDS)
+ switch(trap_type)
+ if(TRAP_HUGGER)
+ if(!AM)
+ drop_hugger()
+ return
+ if(!iscarbon(AM))
+ return
+ var/mob/living/carbon/crosser = AM
+ if(!crosser.can_be_facehugged(hugger))
+ return
+ drop_hugger()
+ if(TRAP_SMOKE_NEURO, TRAP_SMOKE_ACID)
+ smoke.start()
+ if(TRAP_ACID_WEAK)
+ for(var/turf/acided AS in RANGE_TURFS(1, src))
+ new /obj/effect/xenomorph/spray/weak(acided, 8 SECONDS, XENO_WEAK_ACID_PUDDLE_DAMAGE)
+ if(TRAP_ACID_NORMAL)
+ for(var/turf/acided AS in RANGE_TURFS(1, src))
+ new /obj/effect/xenomorph/spray(acided, 10 SECONDS, XENO_DEFAULT_ACID_PUDDLE_DAMAGE)
+ if(TRAP_ACID_STRONG)
+ for(var/turf/acided AS in RANGE_TURFS(1, src))
+ new /obj/effect/xenomorph/spray/strong(acided, 12 SECONDS, XENO_HIGH_ACID_PUDDLE_DAMAGE)
+ xeno_message("A [trap_type] trap at [AREACOORD_NO_Z(src)] has been triggered!", "xenoannounce", 5, hivenumber, FALSE, get_turf(src), 'sound/voice/alien_talk2.ogg', FALSE, null, /atom/movable/screen/arrow/attack_order_arrow, COLOR_ORANGE, TRUE)
+ set_trap_type(null)
+
+/// Move the hugger out of the trap
+/obj/structure/xeno/trap/proc/drop_hugger()
+ hugger.forceMove(loc)
+ hugger.go_active(TRUE, TRUE) //Removes stasis
+ visible_message(span_warning("[hugger] gets out of [src]!") )
+ hugger = null
+ set_trap_type(null)
+
+/obj/structure/xeno/trap/attack_alien(mob/living/carbon/xenomorph/xeno_attacker, damage_amount = xeno_attacker.xeno_caste.melee_damage, damage_type = BRUTE, damage_flag = MELEE, effects = TRUE, armor_penetration = 0, isrightclick = FALSE)
+ if(xeno_attacker.status_flags & INCORPOREAL)
+ return FALSE
+
+ if(xeno_attacker.a_intent == INTENT_HARM)
+ return ..()
+ if(trap_type == TRAP_HUGGER)
+ if(!(xeno_attacker.xeno_caste.can_flags & CASTE_CAN_HOLD_FACEHUGGERS))
+ return
+ if(!hugger)
+ balloon_alert(xeno_attacker, "It is empty")
+ return
+ xeno_attacker.put_in_active_hand(hugger)
+ hugger.go_active(TRUE)
+ hugger = null
+ set_trap_type(null)
+ balloon_alert(xeno_attacker, "Removed facehugger")
+ return
+ var/datum/action/ability/activable/xeno/corrosive_acid/acid_action = locate(/datum/action/ability/activable/xeno/corrosive_acid) in xeno_attacker.actions
+ if(istype(xeno_attacker.ammo, /datum/ammo/xeno/boiler_gas))
+ var/datum/ammo/xeno/boiler_gas/boiler_glob = xeno_attacker.ammo
+ if(!boiler_glob.enhance_trap(src, xeno_attacker))
+ return
+ else if(acid_action)
+ if(!do_after(xeno_attacker, 2 SECONDS, NONE, src))
+ return
+ switch(acid_action.acid_type)
+ if(/obj/effect/xenomorph/acid/weak)
+ set_trap_type(TRAP_ACID_WEAK)
+ if(/obj/effect/xenomorph/acid)
+ set_trap_type(TRAP_ACID_NORMAL)
+ if(/obj/effect/xenomorph/acid/strong)
+ set_trap_type(TRAP_ACID_STRONG)
+ else
+ return // nothing happened!
+ playsound(xeno_attacker.loc, 'sound/effects/refill.ogg', 25, 1)
+ balloon_alert(xeno_attacker, "Filled with [trap_type]")
+
+/obj/structure/xeno/trap/attackby(obj/item/I, mob/user, params)
+ . = ..()
+
+ if(!istype(I, /obj/item/clothing/mask/facehugger) || !isxeno(user))
+ return
+ var/obj/item/clothing/mask/facehugger/FH = I
+ if(trap_type)
+ balloon_alert(user, "Already occupied")
+ return
+
+ if(FH.stat == DEAD)
+ balloon_alert(user, "Cannot insert facehugger")
+ return
+
+ user.transferItemToLoc(FH, src)
+ FH.go_idle(TRUE)
+ hugger = FH
+ set_trap_type(TRAP_HUGGER)
+ balloon_alert(user, "Inserted facehugger")
+
+//Sentient facehugger can get in the trap
+/obj/structure/xeno/trap/attack_facehugger(mob/living/carbon/xenomorph/facehugger/F, isrightclick = FALSE)
+ . = ..()
+ if(tgui_alert(F, "Do you want to get into the trap?", "Get inside the trap", list("Yes", "No")) != "Yes")
+ return
+
+ if(trap_type)
+ F.balloon_alert(F, "The trap is occupied")
+ return
+
+ var/obj/item/clothing/mask/facehugger/FH = new(src)
+ FH.go_idle(TRUE)
+ hugger = FH
+ set_trap_type(TRAP_HUGGER)
+
+ F.visible_message(span_xenowarning("[F] slides back into [src]."),span_xenonotice("You slides back into [src]."))
+ F.ghostize()
+ F.death(deathmessage = "get inside the trap", silent = TRUE)
+ qdel(F)
diff --git a/code/modules/xenomorph/tunnel.dm b/code/modules/xenomorph/tunnel.dm
new file mode 100644
index 00000000000..0eeaee13180
--- /dev/null
+++ b/code/modules/xenomorph/tunnel.dm
@@ -0,0 +1,181 @@
+/obj/structure/xeno/tunnel
+ name = "tunnel"
+ desc = "A tunnel entrance. Looks like it was dug by some kind of clawed beast."
+ icon = 'icons/Xeno/Effects.dmi'
+ icon_state = "hole"
+
+ density = FALSE
+ opacity = FALSE
+ anchored = TRUE
+ resistance_flags = UNACIDABLE|BANISH_IMMUNE
+ layer = RESIN_STRUCTURE_LAYER
+
+ max_integrity = 140
+
+ xeno_structure_flags = IGNORE_WEED_REMOVAL
+ ///Description added by the hivelord.
+ var/tunnel_desc = ""
+ ///What hivelord created that tunnel. Can be null
+ var/mob/living/carbon/xenomorph/hivelord/creator = null
+
+/obj/structure/xeno/tunnel/Initialize(mapload, _hivenumber)
+ . = ..()
+ LAZYADDASSOC(GLOB.xeno_tunnels_by_hive, hivenumber, src)
+ SSminimaps.add_marker(src, MINIMAP_FLAG_XENO, image('icons/UI_icons/map_blips.dmi', null, "xenotunnel", HIGH_FLOAT_LAYER)) // RU TGMC edit - map blips
+
+/obj/structure/xeno/tunnel/Destroy()
+ var/turf/drop_loc = get_turf(src)
+ for(var/atom/movable/thing AS in contents) //Empty the tunnel of contents
+ thing.forceMove(drop_loc)
+
+ if(!QDELETED(creator))
+ to_chat(creator, span_xenoannounce("You sense your [name] at [tunnel_desc] has been destroyed!") ) //Alert creator
+
+ xeno_message("Hive tunnel [name] at [tunnel_desc] has been destroyed!", "xenoannounce", 5, hivenumber) //Also alert hive because tunnels matter.
+
+ LAZYREMOVE(GLOB.xeno_tunnels_by_hive[hivenumber], src)
+ if(creator)
+ creator.tunnels -= src
+ creator = null
+
+ for(var/datum/atom_hud/xeno_tactical/xeno_tac_hud in GLOB.huds) //HUD clean up
+ xeno_tac_hud.remove_from_hud(src)
+ SSminimaps.remove_marker(src)
+
+ return ..()
+
+///Signal handler for creator destruction to clear reference
+/obj/structure/xeno/tunnel/proc/clear_creator()
+ SIGNAL_HANDLER
+ creator = null
+
+/obj/structure/xeno/tunnel/examine(mob/user)
+ . = ..()
+ if(!isxeno(user) && !isobserver(user))
+ return
+ if(tunnel_desc)
+ . += span_info("The Hivelord scent reads: \'[tunnel_desc]\'")
+
+/obj/structure/xeno/tunnel/deconstruct(disassembled = TRUE)
+ visible_message(span_danger("[src] suddenly collapses!") )
+ return ..()
+
+/obj/structure/xeno/tunnel/attackby(obj/item/I, mob/user, params)
+ if(!isxeno(user))
+ return ..()
+ attack_alien(user)
+
+/obj/structure/xeno/tunnel/attack_alien(mob/living/carbon/xenomorph/xeno_attacker, damage_amount = xeno_attacker.xeno_caste.melee_damage, damage_type = BRUTE, damage_flag = MELEE, effects = TRUE, armor_penetration = 0, isrightclick = FALSE)
+ if(!istype(xeno_attacker) || xeno_attacker.stat || xeno_attacker.lying_angle || xeno_attacker.status_flags & INCORPOREAL)
+ return
+
+ if(xeno_attacker.a_intent == INTENT_HARM && xeno_attacker == creator)
+ balloon_alert(xeno_attacker, "Filling in tunnel...")
+ if(do_after(xeno_attacker, HIVELORD_TUNNEL_DISMANTLE_TIME, IGNORE_HELD_ITEM, src, BUSY_ICON_BUILD))
+ deconstruct(FALSE)
+ return
+
+ if(xeno_attacker.anchored)
+ balloon_alert(xeno_attacker, "Cannot enter while immobile")
+ return FALSE
+
+ if(length(GLOB.xeno_tunnels_by_hive[hivenumber]) < 2)
+ balloon_alert(xeno_attacker, "No exit tunnel")
+ return FALSE
+
+ pick_a_tunnel(xeno_attacker)
+
+/obj/structure/xeno/tunnel/attack_larva(mob/living/carbon/xenomorph/larva/L) //So larvas can actually use tunnels
+ attack_alien(L)
+
+/obj/structure/xeno/tunnel/attack_ghost(mob/dead/observer/user)
+ . = ..()
+
+ var/list/obj/destinations = GLOB.xeno_tunnels_by_hive[hivenumber]
+ var/obj/structure/xeno/tunnel/targettunnel
+ if(LAZYLEN(destinations) > 2)
+ var/list/tunnel_assoc = list()
+ for(var/obj/D in destinations)
+ tunnel_assoc["X:[D.x], Y:[D.y] - \[[get_area(D)]\]"] = D
+ destinations = list()
+ for(var/d in tunnel_assoc)
+ destinations += d
+ var/input = tgui_input_list(user ,"Choose a tunnel to teleport to:" ,"Ghost Tunnel teleport" ,destinations ,null, 0)
+ if(!input)
+ return
+ targettunnel = tunnel_assoc[input]
+ if(!input)
+ return
+ else
+ //There are only 2 tunnels. Pick the other one.
+ for(var/P in destinations)
+ if(P != src)
+ targettunnel = P
+ if(!targettunnel || QDELETED(targettunnel) || !targettunnel.loc)
+ return
+ user.forceMove(get_turf(targettunnel))
+
+///Here we pick a tunnel to go to, then travel to that tunnel and peep out, confirming whether or not we want to emerge or go to another tunnel.
+/obj/structure/xeno/tunnel/proc/pick_a_tunnel(mob/living/carbon/xenomorph/M)
+ to_chat(M, span_notice("Select a tunnel to go to."))
+
+ var/atom/movable/screen/minimap/map = SSminimaps.fetch_minimap_object(z, MINIMAP_FLAG_XENO)
+ M.client.screen += map
+ var/list/polled_coords = map.get_coords_from_click(M)
+ M.client.screen -= map
+ if(!polled_coords)
+ return
+ var/turf/clicked_turf = locate(polled_coords[1], polled_coords[2], z)
+
+ ///We find the tunnel, looking within 10 tiles of where the user clicked, excluding src
+ var/obj/structure/xeno/tunnel/targettunnel = cheap_get_atom(clicked_turf, /obj/structure/xeno/tunnel, 10, GLOB.xeno_tunnels_by_hive[hivenumber] - src)
+ if(QDELETED(src)) //Make sure we still exist in the event the player keeps the interface open
+ return
+ if(!M.Adjacent(src) && M.loc != src) //Make sure we're close enough to our tunnel; either adjacent to or in one
+ return
+ if(QDELETED(targettunnel)) //Make sure our target destination still exists in the event the player keeps the interface open
+ if(M.loc == src) //If we're in the tunnel and cancelling out, spit us out.
+ M.forceMove(loc)
+ return
+ if(targettunnel == src)
+ balloon_alert(M, "We're already here")
+ if(M.loc == src) //If we're in the tunnel and cancelling out, spit us out.
+ M.forceMove(loc)
+ return
+ if(targettunnel.z != z)
+ balloon_alert(M, "Tunnel not connected")
+ if(M.loc == src) //If we're in the tunnel and cancelling out, spit us out.
+ M.forceMove(loc)
+ return
+ var/distance = get_dist(get_turf(src), get_turf(targettunnel))
+ var/tunnel_time = clamp(distance, HIVELORD_TUNNEL_MIN_TRAVEL_TIME, HIVELORD_TUNNEL_SMALL_MAX_TRAVEL_TIME)
+
+ if(M.mob_size == MOB_SIZE_BIG) //Big xenos take longer
+ tunnel_time = clamp(distance * 1.5, HIVELORD_TUNNEL_MIN_TRAVEL_TIME, HIVELORD_TUNNEL_LARGE_MAX_TRAVEL_TIME)
+ M.visible_message(span_xenonotice("[M] begins heaving their huge bulk down into \the [src].") , \
+ span_xenonotice("We begin heaving our monstrous bulk into \the [src] to [targettunnel.tunnel_desc].") )
+ else
+ M.visible_message(span_xenonotice("\The [M] begins crawling down into \the [src].") , \
+ span_xenonotice("We begin crawling down into \the [src] to [targettunnel.tunnel_desc].") )
+
+ if(isxenolarva(M)) //Larva can zip through near-instantly, they are wormlike after all
+ tunnel_time = 5
+
+ if(!do_after(M, tunnel_time, IGNORE_HELD_ITEM, src, BUSY_ICON_GENERIC))
+ balloon_alert(M, "Crawling interrupted")
+ return
+ if(!targettunnel || !isturf(targettunnel.loc)) //Make sure the end tunnel is still there
+ balloon_alert(M, "Tunnel ended unexpectedly")
+ return
+ M.forceMove(targettunnel)
+ var/double_check = tgui_alert(M, "Emerge here?", "Tunnel: [targettunnel]", list("Yes","Pick another tunnel"), 0)
+ if(M.loc != targettunnel) //double check that we're still in the tunnel in the event it gets destroyed while we still have the interface open
+ return
+ if(double_check == "Pick another tunnel")
+ return targettunnel.pick_a_tunnel(M)
+ M.forceMove(targettunnel.loc)
+ M.visible_message(span_xenonotice("\The [M] pops out of \the [src].") , \
+ span_xenonotice("We pop out through the other side!") )
+
+/obj/structure/xeno/tunnel/attack_facehugger(mob/living/carbon/xenomorph/facehugger/F, isrightclick = FALSE)
+ attack_alien(F)
diff --git a/code/modules/xenomorph/turret.dm b/code/modules/xenomorph/turret.dm
new file mode 100644
index 00000000000..11a6905b9a4
--- /dev/null
+++ b/code/modules/xenomorph/turret.dm
@@ -0,0 +1,272 @@
+/obj/structure/xeno/xeno_turret
+ icon = 'icons/Xeno/acidturret.dmi'
+ icon_state = XENO_TURRET_ACID_ICONSTATE
+ name = "acid turret"
+ desc = "A menacing looking construct of resin, it seems to be alive. It fires acid against intruders."
+ bound_width = 32
+ bound_height = 32
+ obj_integrity = 600
+ max_integrity = 1500
+ layer = ABOVE_MOB_LAYER
+ density = TRUE
+ resistance_flags = UNACIDABLE | DROPSHIP_IMMUNE |PORTAL_IMMUNE
+ xeno_structure_flags = IGNORE_WEED_REMOVAL|HAS_OVERLAY
+ allow_pass_flags = PASS_AIR|PASS_THROW
+ ///What kind of spit it uses
+ var/datum/ammo/ammo = /datum/ammo/xeno/acid/heavy/turret
+ ///Range of the turret
+ var/range = 7
+ ///Target of the turret
+ var/atom/hostile
+ ///Last target of the turret
+ var/atom/last_hostile
+ ///Potential list of targets found by scan
+ var/list/atom/potential_hostiles
+ ///Fire rate of the target in ticks
+ var/firerate = 5
+ ///The last time the sentry did a scan
+ var/last_scan_time
+ ///light color that gets set in initialize
+ var/light_initial_color = LIGHT_COLOR_GREEN
+ ///For minimap icon change if sentry is firing
+ var/firing
+
+///Change minimap icon if its firing or not firing
+/obj/structure/xeno/xeno_turret/proc/update_minimap_icon()
+ SSminimaps.remove_marker(src)
+ SSminimaps.add_marker(src, MINIMAP_FLAG_XENO, image('icons/UI_icons/map_blips.dmi', null, "xeno_turret[firing ? "_firing" : "_passive"]")) // RU TGMC edit - map blips
+
+/obj/structure/xeno/xeno_turret/Initialize(mapload, _hivenumber)
+ . = ..()
+ ammo = GLOB.ammo_list[ammo]
+ potential_hostiles = list()
+ LAZYADDASSOC(GLOB.xeno_resin_turrets_by_hive, hivenumber, src)
+ START_PROCESSING(SSobj, src)
+ AddComponent(/datum/component/automatedfire/xeno_turret_autofire, firerate)
+ RegisterSignal(src, COMSIG_AUTOMATIC_SHOOTER_SHOOT, PROC_REF(shoot))
+ RegisterSignal(SSdcs, COMSIG_GLOB_DROPSHIP_HIJACKED, PROC_REF(destroy_on_hijack))
+ if(light_initial_color)
+ set_light(2, 2, light_initial_color)
+ update_minimap_icon()
+ update_icon()
+
+///Signal handler to delete the turret when the alamo is hijacked
+/obj/structure/xeno/xeno_turret/proc/destroy_on_hijack()
+ SIGNAL_HANDLER
+ qdel(src)
+
+/obj/structure/xeno/xeno_turret/obj_destruction(damage_amount, damage_type, damage_flag)
+ if(damage_amount) //Spawn effects only if we actually get destroyed by damage
+ on_destruction()
+ return ..()
+
+/obj/structure/xeno/xeno_turret/proc/on_destruction()
+ var/datum/effect_system/smoke_spread/xeno/smoke = new /datum/effect_system/smoke_spread/xeno/acid(src)
+ smoke.set_up(1, get_turf(src))
+ smoke.start()
+
+/obj/structure/xeno/xeno_turret/Destroy()
+ GLOB.xeno_resin_turrets_by_hive[hivenumber] -= src
+ set_hostile(null)
+ set_last_hostile(null)
+ STOP_PROCESSING(SSobj, src)
+ playsound(loc,'sound/effects/xeno_turret_death.ogg', 70)
+ return ..()
+
+/obj/structure/xeno/xeno_turret/ex_act(severity)
+ take_damage(severity * 5, BRUTE, BOMB)
+
+/obj/structure/xeno/xeno_turret/flamer_fire_act(burnlevel)
+ take_damage(burnlevel * 2, BURN, FIRE)
+ ENABLE_BITFIELD(resistance_flags, ON_FIRE)
+
+/obj/structure/xeno/xeno_turret/fire_act()
+ take_damage(60, BURN, FIRE)
+ ENABLE_BITFIELD(resistance_flags, ON_FIRE)
+
+/obj/structure/xeno/xeno_turret/update_overlays()
+ . = ..()
+ if(!(xeno_structure_flags & HAS_OVERLAY))
+ return
+ if(obj_integrity <= max_integrity / 2)
+ . += image('icons/Xeno/acidturret.dmi', src, "+turret_damage")
+ if(CHECK_BITFIELD(resistance_flags, ON_FIRE))
+ . += image('icons/Xeno/acidturret.dmi', src, "+turret_on_fire")
+
+/obj/structure/xeno/xeno_turret/process()
+ //Turrets regen some HP, every 2 sec
+ if(obj_integrity < max_integrity)
+ obj_integrity = min(obj_integrity + TURRET_HEALTH_REGEN, max_integrity)
+ update_icon()
+ DISABLE_BITFIELD(resistance_flags, ON_FIRE)
+ if(world.time > last_scan_time + TURRET_SCAN_FREQUENCY)
+ scan()
+ last_scan_time = world.time
+ if(!length(potential_hostiles))
+ return
+ set_hostile(get_target())
+ if (!hostile)
+ if(last_hostile)
+ set_last_hostile(null)
+ return
+ if(!TIMER_COOLDOWN_CHECK(src, COOLDOWN_XENO_TURRETS_ALERT))
+ GLOB.hive_datums[hivenumber].xeno_message("Our [name] is attacking a nearby hostile [hostile] at [get_area(hostile)] (X: [hostile.x], Y: [hostile.y]).", "xenoannounce", 5, FALSE, hostile, 'sound/voice/alien_help1.ogg', FALSE, null, /atom/movable/screen/arrow/turret_attacking_arrow)
+ TIMER_COOLDOWN_START(src, COOLDOWN_XENO_TURRETS_ALERT, 20 SECONDS)
+ if(hostile != last_hostile)
+ set_last_hostile(hostile)
+ SEND_SIGNAL(src, COMSIG_AUTOMATIC_SHOOTER_START_SHOOTING_AT)
+
+/obj/structure/xeno/xeno_turret/attackby(obj/item/I, mob/living/user, params)
+ if(I.flags_item & NOBLUDGEON || !isliving(user))
+ return attack_hand(user)
+
+ user.changeNext_move(I.attack_speed)
+ user.do_attack_animation(src, used_item = I)
+
+ var/damage = I.force
+ var/multiplier = 1
+ if(I.damtype == BURN) //Burn damage deals extra vs resin structures (mostly welders).
+ multiplier += 1
+
+ if(istype(I, /obj/item/tool/pickaxe/plasmacutter) && !user.do_actions)
+ var/obj/item/tool/pickaxe/plasmacutter/P = I
+ if(P.start_cut(user, name, src, PLASMACUTTER_BASE_COST * PLASMACUTTER_VLOW_MOD))
+ multiplier += PLASMACUTTER_RESIN_MULTIPLIER
+ P.cut_apart(user, name, src, PLASMACUTTER_BASE_COST * PLASMACUTTER_VLOW_MOD)
+
+ damage *= max(0, multiplier)
+ take_damage(damage, BRUTE, MELEE)
+ playsound(src, "alien_resin_break", 25)
+
+///Signal handler for hard del of hostile
+/obj/structure/xeno/xeno_turret/proc/unset_hostile()
+ SIGNAL_HANDLER
+ hostile = null
+
+///Signal handler for hard del of last_hostile
+/obj/structure/xeno/xeno_turret/proc/unset_last_hostile()
+ SIGNAL_HANDLER
+ last_hostile = null
+
+///Setter for hostile with hard del in mind
+/obj/structure/xeno/xeno_turret/proc/set_hostile(_hostile)
+ if(hostile != _hostile)
+ hostile = _hostile
+ RegisterSignal(hostile, COMSIG_QDELETING, PROC_REF(unset_hostile))
+
+///Setter for last_hostile with hard del in mind
+/obj/structure/xeno/xeno_turret/proc/set_last_hostile(_last_hostile)
+ if(last_hostile)
+ UnregisterSignal(last_hostile, COMSIG_QDELETING)
+ last_hostile = _last_hostile
+
+///Look for the closest human in range and in light of sight. If no human is in range, will look for xenos of other hives
+/obj/structure/xeno/xeno_turret/proc/get_target()
+ var/distance = range + 0.5 //we add 0.5 so if a potential target is at range, it is accepted by the system
+ var/buffer_distance
+ var/list/turf/path = list()
+ for (var/atom/nearby_hostile AS in potential_hostiles)
+ if(isliving(nearby_hostile))
+ var/mob/living/nearby_living_hostile = nearby_hostile
+ if(nearby_living_hostile.stat == DEAD)
+ continue
+ if(HAS_TRAIT(nearby_hostile, TRAIT_TURRET_HIDDEN))
+ continue
+ buffer_distance = get_dist(nearby_hostile, src)
+ if (distance <= buffer_distance) //If we already found a target that's closer
+ continue
+ path = getline(src, nearby_hostile)
+ path -= get_turf(src)
+ if(!length(path)) //Can't shoot if it's on the same turf
+ continue
+ var/blocked = FALSE
+ for(var/turf/T AS in path)
+ if(IS_OPAQUE_TURF(T) || T.density && !(T.allow_pass_flags & PASS_PROJECTILE))
+ blocked = TRUE
+ break //LoF Broken; stop checking; we can't proceed further.
+
+ for(var/obj/machinery/MA in T)
+ if(MA.opacity || MA.density && !(MA.allow_pass_flags & PASS_PROJECTILE))
+ blocked = TRUE
+ break //LoF Broken; stop checking; we can't proceed further.
+
+ for(var/obj/structure/S in T)
+ if(S.opacity || S.density && !(S.allow_pass_flags & PASS_PROJECTILE))
+ blocked = TRUE
+ break //LoF Broken; stop checking; we can't proceed further.
+ if(!blocked)
+ distance = buffer_distance
+ . = nearby_hostile
+
+///Return TRUE if a possible target is near
+/obj/structure/xeno/xeno_turret/proc/scan()
+ potential_hostiles.Cut()
+ for (var/mob/living/carbon/human/nearby_human AS in cheap_get_humans_near(src, TURRET_SCAN_RANGE))
+ if(nearby_human.stat == DEAD)
+ continue
+ if(nearby_human.get_xeno_hivenumber() == hivenumber)
+ continue
+ potential_hostiles += nearby_human
+ for (var/mob/living/carbon/xenomorph/nearby_xeno AS in cheap_get_xenos_near(src, range))
+ if(GLOB.hive_datums[hivenumber] == nearby_xeno.hive)
+ continue
+ if(nearby_xeno.stat == DEAD)
+ continue
+ potential_hostiles += nearby_xeno
+ for(var/obj/vehicle/unmanned/vehicle AS in GLOB.unmanned_vehicles)
+ if(vehicle.z == z && get_dist(vehicle, src) <= range)
+ potential_hostiles += vehicle
+ for(var/obj/vehicle/sealed/mecha/mech AS in GLOB.mechas_list)
+ if(mech.z == z && get_dist(mech, src) <= range)
+ potential_hostiles += mech
+
+///Signal handler to make the turret shoot at its target
+/obj/structure/xeno/xeno_turret/proc/shoot()
+ SIGNAL_HANDLER
+ if(!hostile)
+ SEND_SIGNAL(src, COMSIG_AUTOMATIC_SHOOTER_STOP_SHOOTING_AT)
+ firing = FALSE
+ update_minimap_icon()
+ return
+ face_atom(hostile)
+ var/obj/projectile/newshot = new(loc)
+ newshot.generate_bullet(ammo)
+ newshot.def_zone = pick(GLOB.base_miss_chance)
+ newshot.fire_at(hostile, src, null, ammo.max_range, ammo.shell_speed)
+ if(istype(ammo, /datum/ammo/xeno/hugger))
+ var/datum/ammo/xeno/hugger/hugger_ammo = ammo
+ newshot.color = initial(hugger_ammo.hugger_type.color)
+ hugger_ammo.hivenumber = hivenumber
+ firing = TRUE
+ update_minimap_icon()
+
+/obj/structure/xeno/xeno_turret/sticky
+ name = "Sticky resin turret"
+ icon = 'icons/Xeno/acidturret.dmi'
+ icon_state = XENO_TURRET_STICKY_ICONSTATE
+ desc = "A menacing looking construct of resin, it seems to be alive. It fires resin against intruders."
+ light_initial_color = LIGHT_COLOR_PURPLE
+ ammo = /datum/ammo/xeno/sticky/turret
+ firerate = 5
+
+/obj/structure/xeno/xeno_turret/sticky/on_destruction()
+ for(var/i = 1 to 20) // maybe a bit laggy
+ var/obj/projectile/new_proj = new(src)
+ new_proj.generate_bullet(ammo)
+ new_proj.fire_at(null, src, range = rand(1, 4), angle = rand(1, 360), recursivity = TRUE)
+
+/obj/structure/xeno/xeno_turret/hugger_turret
+ name = "hugger turret"
+ icon_state = "hugger_turret"
+ desc = "A menacing looking construct of resin, it seems to be alive. It fires huggers against intruders."
+ obj_integrity = 400
+ max_integrity = 400
+ light_initial_color = LIGHT_COLOR_BROWN
+ ammo = /datum/ammo/xeno/hugger
+ firerate = 5 SECONDS
+
+/obj/structure/xeno/xeno_turret/hugger_turret/on_destruction()
+ for(var/i = 1 to 5)
+ var/obj/projectile/new_proj = new(src)
+ new_proj.generate_bullet(ammo)
+ new_proj.fire_at(null, src, range = rand(1, 3), angle = rand(1, 360), recursivity = TRUE)
diff --git a/code/modules/xenomorph/xeno_structures.dm b/code/modules/xenomorph/xeno_structures.dm
deleted file mode 100644
index 51991c3b656..00000000000
--- a/code/modules/xenomorph/xeno_structures.dm
+++ /dev/null
@@ -1,1731 +0,0 @@
-/obj/structure/xeno
- hit_sound = "alien_resin_break"
- layer = RESIN_STRUCTURE_LAYER
- resistance_flags = UNACIDABLE
- ///Bitflags specific to xeno structures
- var/xeno_structure_flags
- ///Which hive(number) do we belong to?
- var/hivenumber = XENO_HIVE_NORMAL
-
-/obj/structure/xeno/Initialize(mapload, _hivenumber)
- . = ..()
- if(!(xeno_structure_flags & IGNORE_WEED_REMOVAL))
- RegisterSignal(loc, COMSIG_TURF_WEED_REMOVED, PROC_REF(weed_removed))
- if(_hivenumber) ///because admins can spawn them
- hivenumber = _hivenumber
- LAZYADDASSOC(GLOB.xeno_structures_by_hive, hivenumber, src)
- if(xeno_structure_flags & CRITICAL_STRUCTURE)
- LAZYADDASSOC(GLOB.xeno_critical_structures_by_hive, hivenumber, src)
-
-/obj/structure/xeno/Destroy()
- if(!locate(src) in GLOB.xeno_structures_by_hive[hivenumber]+GLOB.xeno_critical_structures_by_hive[hivenumber]) //The rest of the proc is pointless to look through if its not in the lists
- stack_trace("[src] not found in the list of (potentially critical) xeno structures!") //We dont want to CRASH because that'd block deletion completely. Just trace it and continue.
- return ..()
- GLOB.xeno_structures_by_hive[hivenumber] -= src
- if(xeno_structure_flags & CRITICAL_STRUCTURE)
- GLOB.xeno_critical_structures_by_hive[hivenumber] -= src
- return ..()
-
-/obj/structure/xeno/ex_act(severity)
- take_damage(severity * 0.8, BRUTE, BOMB)
-
-/obj/structure/xeno/attack_hand(mob/living/user)
- balloon_alert(user, "You only scrape at it")
- return TRUE
-
-/obj/structure/xeno/flamer_fire_act(burnlevel)
- take_damage(burnlevel / 3, BURN, FIRE)
-
-/obj/structure/xeno/fire_act()
- take_damage(10, BURN, FIRE)
-
-/// Destroy the xeno structure when the weed it was on is destroyed
-/obj/structure/xeno/proc/weed_removed()
- SIGNAL_HANDLER
- var/obj/alien/weeds/found_weed = locate(/obj/alien/weeds) in loc
- if(found_weed.obj_integrity <= 0)
- obj_destruction(damage_flag = MELEE)
- else
- obj_destruction()
-
-/obj/structure/xeno/attack_alien(mob/living/carbon/xenomorph/xeno_attacker, damage_amount, damage_type, damage_flag, effects, armor_penetration, isrightclick)
- if(!(HAS_TRAIT(xeno_attacker, TRAIT_VALHALLA_XENO) && xeno_attacker.a_intent == INTENT_HARM && (tgui_alert(xeno_attacker, "Are you sure you want to tear down [src]?", "Tear down [src]?", list("Yes","No"))) == "Yes"))
- return ..()
- if(!do_after(xeno_attacker, 3 SECONDS, NONE, src))
- return
- xeno_attacker.do_attack_animation(src, ATTACK_EFFECT_CLAW)
- balloon_alert_to_viewers("\The [xeno_attacker] tears down \the [src]!", "We tear down \the [src].")
- playsound(src, "alien_resin_break", 25)
- take_damage(max_integrity) // Ensure its destroyed
-
-//Carrier trap
-/obj/structure/xeno/trap
- desc = "It looks like a hiding hole."
- name = "resin hole"
- icon = 'icons/Xeno/Effects.dmi'
- icon_state = "trap"
- density = FALSE
- opacity = FALSE
- anchored = TRUE
- max_integrity = 5
- layer = RESIN_STRUCTURE_LAYER
- destroy_sound = "alien_resin_break"
- ///defines for trap type to trigger on activation
- var/trap_type
- ///The hugger inside our trap
- var/obj/item/clothing/mask/facehugger/hugger = null
- ///smoke effect to create when the trap is triggered
- var/datum/effect_system/smoke_spread/smoke
- ///connection list for huggers
- var/static/list/listen_connections = list(
- COMSIG_ATOM_ENTERED = PROC_REF(trigger_trap),
- )
-
-/obj/structure/xeno/trap/Initialize(mapload, _hivenumber)
- . = ..()
- RegisterSignal(src, COMSIG_MOVABLE_SHUTTLE_CRUSH, PROC_REF(shuttle_crush))
- AddElement(/datum/element/connect_loc, listen_connections)
-
-/obj/structure/xeno/trap/ex_act(severity)
- take_damage(severity, BRUTE, BOMB)
-
-/obj/structure/xeno/trap/update_icon_state()
- . = ..()
- switch(trap_type)
- if(TRAP_HUGGER)
- icon_state = "traphugger"
- if(TRAP_SMOKE_NEURO)
- icon_state = "trapneurogas"
- if(TRAP_SMOKE_ACID)
- icon_state = "trapacidgas"
- if(TRAP_ACID_WEAK)
- icon_state = "trapacidweak"
- if(TRAP_ACID_NORMAL)
- icon_state = "trapacid"
- if(TRAP_ACID_STRONG)
- icon_state = "trapacidstrong"
- else
- icon_state = "trap"
-
-/obj/structure/xeno/trap/obj_destruction(damage_amount, damage_type, damage_flag)
- if((damage_amount || damage_flag) && hugger && loc)
- trigger_trap()
- return ..()
-
-/obj/structure/xeno/trap/proc/set_trap_type(new_trap_type)
- if(new_trap_type == trap_type)
- return
- trap_type = new_trap_type
- update_icon()
-
-///Ensures that no huggies will be released when the trap is crushed by a shuttle; no more trapping shuttles with huggies
-/obj/structure/xeno/trap/proc/shuttle_crush()
- SIGNAL_HANDLER
- qdel(src)
-
-/obj/structure/xeno/trap/examine(mob/user)
- . = ..()
- if(!isxeno(user))
- return
- . += "A hole for a little one to hide in ambush for or for spewing acid."
- switch(trap_type)
- if(TRAP_HUGGER)
- . += "There's a little one inside."
- if(TRAP_SMOKE_NEURO)
- . += "There's pressurized neurotoxin inside."
- if(TRAP_SMOKE_ACID)
- . += "There's pressurized acid gas inside."
- if(TRAP_ACID_WEAK)
- . += "There's pressurized weak acid inside."
- if(TRAP_ACID_NORMAL)
- . += "There's pressurized normal acid inside."
- if(TRAP_ACID_STRONG)
- . += "There's strong pressurized acid inside."
- else
- . += "It's empty."
-
-/obj/structure/xeno/trap/flamer_fire_act(burnlevel)
- hugger?.kill_hugger()
- trigger_trap()
- set_trap_type(null)
-
-/obj/structure/xeno/trap/fire_act()
- hugger?.kill_hugger()
- trigger_trap()
- set_trap_type(null)
-
-///Triggers the hugger trap
-/obj/structure/xeno/trap/proc/trigger_trap(datum/source, atom/movable/AM, oldloc, oldlocs)
- SIGNAL_HANDLER
- if(!trap_type)
- return
- if(AM && (hivenumber == AM.get_xeno_hivenumber()))
- return
- playsound(src, "alien_resin_break", 25)
- if(iscarbon(AM))
- var/mob/living/carbon/crosser = AM
- crosser.visible_message(span_warning("[crosser] trips on [src]!"), span_danger("You trip on [src]!"))
- crosser.ParalyzeNoChain(4 SECONDS)
- switch(trap_type)
- if(TRAP_HUGGER)
- if(!AM)
- drop_hugger()
- return
- if(!iscarbon(AM))
- return
- var/mob/living/carbon/crosser = AM
- if(!crosser.can_be_facehugged(hugger))
- return
- drop_hugger()
- if(TRAP_SMOKE_NEURO, TRAP_SMOKE_ACID)
- smoke.start()
- if(TRAP_ACID_WEAK)
- for(var/turf/acided AS in RANGE_TURFS(1, src))
- new /obj/effect/xenomorph/spray/weak(acided, 8 SECONDS, XENO_WEAK_ACID_PUDDLE_DAMAGE)
- if(TRAP_ACID_NORMAL)
- for(var/turf/acided AS in RANGE_TURFS(1, src))
- new /obj/effect/xenomorph/spray(acided, 10 SECONDS, XENO_DEFAULT_ACID_PUDDLE_DAMAGE)
- if(TRAP_ACID_STRONG)
- for(var/turf/acided AS in RANGE_TURFS(1, src))
- new /obj/effect/xenomorph/spray/strong(acided, 12 SECONDS, XENO_HIGH_ACID_PUDDLE_DAMAGE)
- xeno_message("A [trap_type] trap at [AREACOORD_NO_Z(src)] has been triggered!", "xenoannounce", 5, hivenumber, FALSE, get_turf(src), 'sound/voice/alien_talk2.ogg', FALSE, null, /atom/movable/screen/arrow/attack_order_arrow, COLOR_ORANGE, TRUE)
- set_trap_type(null)
-
-/// Move the hugger out of the trap
-/obj/structure/xeno/trap/proc/drop_hugger()
- hugger.forceMove(loc)
- hugger.go_active(TRUE, TRUE) //Removes stasis
- visible_message(span_warning("[hugger] gets out of [src]!") )
- hugger = null
- set_trap_type(null)
-
-/obj/structure/xeno/trap/attack_alien(mob/living/carbon/xenomorph/xeno_attacker, damage_amount = xeno_attacker.xeno_caste.melee_damage, damage_type = BRUTE, damage_flag = MELEE, effects = TRUE, armor_penetration = 0, isrightclick = FALSE)
- if(xeno_attacker.status_flags & INCORPOREAL)
- return FALSE
-
- if(xeno_attacker.a_intent == INTENT_HARM)
- return ..()
- if(trap_type == TRAP_HUGGER)
- if(!(xeno_attacker.xeno_caste.can_flags & CASTE_CAN_HOLD_FACEHUGGERS))
- return
- if(!hugger)
- balloon_alert(xeno_attacker, "It is empty")
- return
- xeno_attacker.put_in_active_hand(hugger)
- hugger.go_active(TRUE)
- hugger = null
- set_trap_type(null)
- balloon_alert(xeno_attacker, "Removed facehugger")
- return
- var/datum/action/ability/activable/xeno/corrosive_acid/acid_action = locate(/datum/action/ability/activable/xeno/corrosive_acid) in xeno_attacker.actions
- if(istype(xeno_attacker.ammo, /datum/ammo/xeno/boiler_gas))
- var/datum/ammo/xeno/boiler_gas/boiler_glob = xeno_attacker.ammo
- if(!boiler_glob.enhance_trap(src, xeno_attacker))
- return
- else if(acid_action)
- if(!do_after(xeno_attacker, 2 SECONDS, NONE, src))
- return
- switch(acid_action.acid_type)
- if(/obj/effect/xenomorph/acid/weak)
- set_trap_type(TRAP_ACID_WEAK)
- if(/obj/effect/xenomorph/acid)
- set_trap_type(TRAP_ACID_NORMAL)
- if(/obj/effect/xenomorph/acid/strong)
- set_trap_type(TRAP_ACID_STRONG)
- else
- return // nothing happened!
- playsound(xeno_attacker.loc, 'sound/effects/refill.ogg', 25, 1)
- balloon_alert(xeno_attacker, "Filled with [trap_type]")
-
-/obj/structure/xeno/trap/attackby(obj/item/I, mob/user, params)
- . = ..()
-
- if(!istype(I, /obj/item/clothing/mask/facehugger) || !isxeno(user))
- return
- var/obj/item/clothing/mask/facehugger/FH = I
- if(trap_type)
- balloon_alert(user, "Already occupied")
- return
-
- if(FH.stat == DEAD)
- balloon_alert(user, "Cannot insert facehugger")
- return
-
- user.transferItemToLoc(FH, src)
- FH.go_idle(TRUE)
- hugger = FH
- set_trap_type(TRAP_HUGGER)
- balloon_alert(user, "Inserted facehugger")
-
-//Sentient facehugger can get in the trap
-/obj/structure/xeno/trap/attack_facehugger(mob/living/carbon/xenomorph/facehugger/F, isrightclick = FALSE)
- . = ..()
- if(tgui_alert(F, "Do you want to get into the trap?", "Get inside the trap", list("Yes", "No")) != "Yes")
- return
-
- if(trap_type)
- F.balloon_alert(F, "The trap is occupied")
- return
-
- var/obj/item/clothing/mask/facehugger/FH = new(src)
- FH.go_idle(TRUE)
- hugger = FH
- set_trap_type(TRAP_HUGGER)
-
- F.visible_message(span_xenowarning("[F] slides back into [src]."),span_xenonotice("You slides back into [src]."))
- F.ghostize()
- F.death(deathmessage = "get inside the trap", silent = TRUE)
- qdel(F)
-
-/*
-TUNNEL
-*/
-/obj/structure/xeno/tunnel
- name = "tunnel"
- desc = "A tunnel entrance. Looks like it was dug by some kind of clawed beast."
- icon = 'icons/Xeno/Effects.dmi'
- icon_state = "hole"
-
- density = FALSE
- opacity = FALSE
- anchored = TRUE
- resistance_flags = UNACIDABLE|BANISH_IMMUNE
- layer = RESIN_STRUCTURE_LAYER
-
- max_integrity = 140
-
- hud_possible = list(XENO_TACTICAL_HUD)
- xeno_structure_flags = IGNORE_WEED_REMOVAL
- ///Description added by the hivelord.
- var/tunnel_desc = ""
- ///What hivelord created that tunnel. Can be null
- var/mob/living/carbon/xenomorph/hivelord/creator = null
-
-/obj/structure/xeno/tunnel/Initialize(mapload, _hivenumber)
- . = ..()
- LAZYADDASSOC(GLOB.xeno_tunnels_by_hive, hivenumber, src)
- prepare_huds()
- for(var/datum/atom_hud/xeno_tactical/xeno_tac_hud in GLOB.huds) //Add to the xeno tachud
- xeno_tac_hud.add_to_hud(src)
- hud_set_xeno_tunnel()
- SSminimaps.add_marker(src, MINIMAP_FLAG_XENO, image('icons/UI_icons/map_blips.dmi', null, "xenotunnel", HIGH_FLOAT_LAYER)) // RU TGMC edit - map blips
-
-/obj/structure/xeno/tunnel/Destroy()
- var/turf/drop_loc = get_turf(src)
- for(var/atom/movable/thing AS in contents) //Empty the tunnel of contents
- thing.forceMove(drop_loc)
-
- if(!QDELETED(creator))
- to_chat(creator, span_xenoannounce("You sense your [name] at [tunnel_desc] has been destroyed!") ) //Alert creator
-
- xeno_message("Hive tunnel [name] at [tunnel_desc] has been destroyed!", "xenoannounce", 5, hivenumber) //Also alert hive because tunnels matter.
-
- LAZYREMOVE(GLOB.xeno_tunnels_by_hive[hivenumber], src)
- if(creator)
- creator.tunnels -= src
- creator = null
-
- for(var/datum/atom_hud/xeno_tactical/xeno_tac_hud in GLOB.huds) //HUD clean up
- xeno_tac_hud.remove_from_hud(src)
- SSminimaps.remove_marker(src)
-
- return ..()
-
-///Signal handler for creator destruction to clear reference
-/obj/structure/xeno/tunnel/proc/clear_creator()
- SIGNAL_HANDLER
- creator = null
-
-/obj/structure/xeno/tunnel/examine(mob/user)
- . = ..()
- if(!isxeno(user) && !isobserver(user))
- return
- if(tunnel_desc)
- . += span_info("The Hivelord scent reads: \'[tunnel_desc]\'")
-
-/obj/structure/xeno/tunnel/deconstruct(disassembled = TRUE)
- visible_message(span_danger("[src] suddenly collapses!") )
- return ..()
-
-/obj/structure/xeno/tunnel/attackby(obj/item/I, mob/user, params)
- if(!isxeno(user))
- return ..()
- attack_alien(user)
-
-/obj/structure/xeno/tunnel/attack_alien(mob/living/carbon/xenomorph/xeno_attacker, damage_amount = xeno_attacker.xeno_caste.melee_damage, damage_type = BRUTE, damage_flag = MELEE, effects = TRUE, armor_penetration = 0, isrightclick = FALSE)
- if(!istype(xeno_attacker) || xeno_attacker.stat || xeno_attacker.lying_angle || xeno_attacker.status_flags & INCORPOREAL)
- return
-
- if(xeno_attacker.a_intent == INTENT_HARM && xeno_attacker == creator)
- balloon_alert(xeno_attacker, "Filling in tunnel...")
- if(do_after(xeno_attacker, HIVELORD_TUNNEL_DISMANTLE_TIME, IGNORE_HELD_ITEM, src, BUSY_ICON_BUILD))
- deconstruct(FALSE)
- return
-
- if(xeno_attacker.anchored)
- balloon_alert(xeno_attacker, "Cannot enter while immobile")
- return FALSE
-
- if(length(GLOB.xeno_tunnels_by_hive[hivenumber]) < 2)
- balloon_alert(xeno_attacker, "No exit tunnel")
- return FALSE
-
- pick_a_tunnel(xeno_attacker)
-
-/obj/structure/xeno/tunnel/attack_larva(mob/living/carbon/xenomorph/larva/L) //So larvas can actually use tunnels
- attack_alien(L)
-
-/obj/structure/xeno/tunnel/attack_ghost(mob/dead/observer/user)
- . = ..()
-
- var/list/obj/destinations = GLOB.xeno_tunnels_by_hive[hivenumber]
- var/obj/structure/xeno/tunnel/targettunnel
- if(LAZYLEN(destinations) > 2)
- var/list/tunnel_assoc = list()
- for(var/obj/D in destinations)
- tunnel_assoc["X:[D.x], Y:[D.y] - \[[get_area(D)]\]"] = D
- destinations = list()
- for(var/d in tunnel_assoc)
- destinations += d
- var/input = tgui_input_list(user ,"Choose a tunnel to teleport to:" ,"Ghost Tunnel teleport" ,destinations ,null, 0)
- if(!input)
- return
- targettunnel = tunnel_assoc[input]
- if(!input)
- return
- else
- //There are only 2 tunnels. Pick the other one.
- for(var/P in destinations)
- if(P != src)
- targettunnel = P
- if(!targettunnel || QDELETED(targettunnel) || !targettunnel.loc)
- return
- user.forceMove(get_turf(targettunnel))
-
-///Here we pick a tunnel to go to, then travel to that tunnel and peep out, confirming whether or not we want to emerge or go to another tunnel.
-/obj/structure/xeno/tunnel/proc/pick_a_tunnel(mob/living/carbon/xenomorph/M)
- var/obj/structure/xeno/tunnel/targettunnel = tgui_input_list(M, "Choose a tunnel to crawl to", "Tunnel", GLOB.xeno_tunnels_by_hive[hivenumber])
- if(QDELETED(src)) //Make sure we still exist in the event the player keeps the interface open
- return
- if(!M.Adjacent(src) && M.loc != src) //Make sure we're close enough to our tunnel; either adjacent to or in one
- return
- if(QDELETED(targettunnel)) //Make sure our target destination still exists in the event the player keeps the interface open
- balloon_alert(M, "Tunnel no longer exists")
- if(M.loc == src) //If we're in the tunnel and cancelling out, spit us out.
- M.forceMove(loc)
- return
- if(targettunnel == src)
- balloon_alert(M, "We're already here")
- if(M.loc == src) //If we're in the tunnel and cancelling out, spit us out.
- M.forceMove(loc)
- return
- if(targettunnel.z != z)
- balloon_alert(M, "Tunnel not connected")
- if(M.loc == src) //If we're in the tunnel and cancelling out, spit us out.
- M.forceMove(loc)
- return
- var/distance = get_dist(get_turf(src), get_turf(targettunnel))
- var/tunnel_time = clamp(distance, HIVELORD_TUNNEL_MIN_TRAVEL_TIME, HIVELORD_TUNNEL_SMALL_MAX_TRAVEL_TIME)
-
- if(M.mob_size == MOB_SIZE_BIG) //Big xenos take longer
- tunnel_time = clamp(distance * 1.5, HIVELORD_TUNNEL_MIN_TRAVEL_TIME, HIVELORD_TUNNEL_LARGE_MAX_TRAVEL_TIME)
- M.visible_message(span_xenonotice("[M] begins heaving their huge bulk down into \the [src].") , \
- span_xenonotice("We begin heaving our monstrous bulk into \the [src] to [targettunnel.tunnel_desc].") )
- else
- M.visible_message(span_xenonotice("\The [M] begins crawling down into \the [src].") , \
- span_xenonotice("We begin crawling down into \the [src] to [targettunnel.tunnel_desc].") )
-
- if(isxenolarva(M)) //Larva can zip through near-instantly, they are wormlike after all
- tunnel_time = 5
-
- if(!do_after(M, tunnel_time, IGNORE_HELD_ITEM, src, BUSY_ICON_GENERIC))
- balloon_alert(M, "Crawling interrupted")
- return
- if(!targettunnel || !isturf(targettunnel.loc)) //Make sure the end tunnel is still there
- balloon_alert(M, "Tunnel ended unexpectedly")
- return
- M.forceMove(targettunnel)
- var/double_check = tgui_alert(M, "Emerge here?", "Tunnel: [targettunnel]", list("Yes","Pick another tunnel"), 0)
- if(M.loc != targettunnel) //double check that we're still in the tunnel in the event it gets destroyed while we still have the interface open
- return
- if(double_check == "Pick another tunnel")
- return targettunnel.pick_a_tunnel(M)
- M.forceMove(targettunnel.loc)
- M.visible_message(span_xenonotice("\The [M] pops out of \the [src].") , \
- span_xenonotice("We pop out through the other side!") )
-
-///Makes sure the tunnel is visible to other xenos even through obscuration.
-/obj/structure/xeno/tunnel/proc/hud_set_xeno_tunnel()
- var/image/holder = hud_list[XENO_TACTICAL_HUD]
- if(!holder)
- return
- holder.icon = 'icons/mob/hud.dmi'
- holder.icon_state = "hudtraitor"
- hud_list[XENO_TACTICAL_HUD] = holder
-
-/obj/structure/xeno/tunnel/attack_facehugger(mob/living/carbon/xenomorph/facehugger/F, isrightclick = FALSE)
- attack_alien(F)
-
-//Resin Water Well
-/obj/structure/xeno/acidwell
- name = "acid well"
- desc = "An acid well. It stores acid to put out fires."
- icon = 'icons/Xeno/acid_pool.dmi'
- plane = FLOOR_PLANE
- icon_state = "well"
- density = FALSE
- opacity = FALSE
- anchored = TRUE
- max_integrity = 5
-
- hit_sound = "alien_resin_move"
- destroy_sound = "alien_resin_move"
- ///How many charges of acid this well contains
- var/charges = 1
- ///If a xeno is charging this well
- var/charging = FALSE
- ///What xeno created this well
- var/mob/living/carbon/xenomorph/creator = null
-
-/obj/structure/xeno/acidwell/Initialize(mapload, _creator)
- . = ..()
- creator = _creator
- RegisterSignal(creator, COMSIG_QDELETING, PROC_REF(clear_creator))
- update_icon()
- var/static/list/connections = list(
- COMSIG_ATOM_ENTERED = PROC_REF(on_cross),
- )
- AddElement(/datum/element/connect_loc, connections)
-
-/obj/structure/xeno/acidwell/Destroy()
- creator = null
- return ..()
-
-///Signal handler for creator destruction to clear reference
-/obj/structure/xeno/acidwell/proc/clear_creator()
- SIGNAL_HANDLER
- creator = null
-
-///Ensures that no acid gas will be released when the well is crushed by a shuttle
-/obj/structure/xeno/acidwell/proc/shuttle_crush()
- SIGNAL_HANDLER
- qdel(src)
-
-
-/obj/structure/xeno/acidwell/obj_destruction(damage_amount, damage_type, damage_flag)
- if(!QDELETED(creator) && creator.stat == CONSCIOUS && creator.z == z)
- var/area/A = get_area(src)
- if(A)
- to_chat(creator, span_xenoannounce("You sense your acid well at [A.name] has been destroyed!") )
-
- if(damage_amount || damage_flag) //Spawn the gas only if we actually get destroyed by damage
- var/datum/effect_system/smoke_spread/xeno/acid/A = new(get_turf(src))
- A.set_up(clamp(CEILING(charges*0.5, 1),0,3),src) //smoke scales with charges
- A.start()
- return ..()
-
-/obj/structure/xeno/acidwell/examine(mob/user)
- . = ..()
- if(!isxeno(user) && !isobserver(user))
- return
- . += span_xenonotice("An acid well made by [creator]. It currently has [charges]/[XENO_ACID_WELL_MAX_CHARGES] charges.")
-
-/obj/structure/xeno/acidwell/deconstruct(disassembled = TRUE)
- visible_message(span_danger("[src] suddenly collapses!") )
- return ..()
-
-/obj/structure/xeno/acidwell/update_icon()
- . = ..()
- set_light(charges , charges / 2, LIGHT_COLOR_GREEN)
-
-/obj/structure/xeno/acidwell/update_overlays()
- . = ..()
- if(!charges)
- return
- . += mutable_appearance(icon, "[charges]", alpha = src.alpha)
- . += emissive_appearance(icon, "[charges]", alpha = src.alpha)
-
-/obj/structure/xeno/acidwell/flamer_fire_act(burnlevel) //Removes a charge of acid, but fire is extinguished
- acid_well_fire_interaction()
-
-/obj/structure/xeno/acidwell/fire_act() //Removes a charge of acid, but fire is extinguished
- acid_well_fire_interaction()
-
-///Handles fire based interactions with the acid well. Depletes 1 charge if there are any to extinguish all fires in the turf while producing acid smoke.
-/obj/structure/xeno/acidwell/proc/acid_well_fire_interaction()
- if(!charges)
- take_damage(50, BURN, FIRE)
- return
-
- charges--
- update_icon()
- var/turf/T = get_turf(src)
- var/datum/effect_system/smoke_spread/xeno/acid/extuingishing/acid_smoke = new(T) //spawn acid smoke when charges are actually used
- acid_smoke.set_up(0, src) //acid smoke in the immediate vicinity
- acid_smoke.start()
-
- for(var/obj/flamer_fire/F in T) //Extinguish all flames in turf
- qdel(F)
-
-/obj/structure/xeno/acidwell/attackby(obj/item/I, mob/user, params)
- if(!isxeno(user))
- return ..()
- attack_alien(user)
-
-/obj/structure/xeno/acidwell/attack_alien(mob/living/carbon/xenomorph/xeno_attacker, damage_amount = xeno_attacker.xeno_caste.melee_damage, damage_type = BRUTE, damage_flag = MELEE, effects = TRUE, armor_penetration = 0, isrightclick = FALSE)
- if(xeno_attacker.a_intent == INTENT_HARM && (CHECK_BITFIELD(xeno_attacker.xeno_caste.caste_flags, CASTE_IS_BUILDER) || xeno_attacker == creator) ) //If we're a builder caste or the creator and we're on harm intent, deconstruct it.
- balloon_alert(xeno_attacker, "Removing...")
- if(!do_after(xeno_attacker, XENO_ACID_WELL_FILL_TIME, IGNORE_HELD_ITEM, src, BUSY_ICON_HOSTILE))
- balloon_alert(xeno_attacker, "Stopped removing")
- return
- playsound(src, "alien_resin_break", 25)
- deconstruct(TRUE, xeno_attacker)
- return
-
- if(charges >= 5)
- balloon_alert(xeno_attacker, "Already full")
- return
- if(charging)
- balloon_alert(xeno_attacker, "Already being filled")
- return
-
- if(xeno_attacker.plasma_stored < XENO_ACID_WELL_FILL_COST) //You need to have enough plasma to attempt to fill the well
- balloon_alert(xeno_attacker, "Need [XENO_ACID_WELL_FILL_COST - xeno_attacker.plasma_stored] more plasma")
- return
-
- charging = TRUE
-
- balloon_alert(xeno_attacker, "Refilling...")
- if(!do_after(xeno_attacker, XENO_ACID_WELL_FILL_TIME, IGNORE_HELD_ITEM, src, BUSY_ICON_BUILD))
- charging = FALSE
- balloon_alert(xeno_attacker, "Aborted refilling")
- return
-
- if(xeno_attacker.plasma_stored < XENO_ACID_WELL_FILL_COST)
- charging = FALSE
- balloon_alert(xeno_attacker, "Need [XENO_ACID_WELL_FILL_COST - xeno_attacker.plasma_stored] more plasma")
- return
-
- xeno_attacker.plasma_stored -= XENO_ACID_WELL_FILL_COST
- charges++
- charging = FALSE
- update_icon()
- balloon_alert(xeno_attacker, "Now has [charges] / [XENO_ACID_WELL_MAX_CHARGES] charges")
- to_chat(xeno_attacker,span_xenonotice("We add acid to [src]. It is currently has [charges] / [XENO_ACID_WELL_MAX_CHARGES] charges.") )
-
-/obj/structure/xeno/acidwell/proc/on_cross(datum/source, atom/movable/A, oldloc, oldlocs)
- SIGNAL_HANDLER
- if(CHECK_MULTIPLE_BITFIELDS(A.allow_pass_flags, HOVERING))
- return
- if(iscarbon(A))
- HasProximity(A)
-
-/obj/structure/xeno/acidwell/HasProximity(atom/movable/AM)
- if(!charges)
- return
- if(!isliving(AM))
- return
- var/mob/living/stepper = AM
- if(stepper.stat == DEAD)
- return
-
- var/charges_used = 0
-
- for(var/obj/item/explosive/grenade/sticky/sticky_bomb in stepper.contents)
- if(charges_used >= charges)
- break
- if(sticky_bomb.stuck_to == stepper)
- sticky_bomb.clean_refs()
- sticky_bomb.forceMove(loc) // i'm not sure if this is even needed, but just to prevent possible bugs
- visible_message(span_danger("[src] sizzles as [sticky_bomb] melts down in the acid."))
- qdel(sticky_bomb)
- charges_used ++
-
- if(stepper.on_fire && (charges_used < charges))
- stepper.ExtinguishMob()
- charges_used ++
-
- if(!isxeno(stepper))
- stepper.next_move_slowdown += charges * 2 //Acid spray has slow down so this should too; scales with charges, Min 2 slowdown, Max 10
- stepper.apply_damage(charges * 10, BURN, BODY_ZONE_PRECISE_L_FOOT, ACID, penetration = 33)
- stepper.apply_damage(charges * 10, BURN, BODY_ZONE_PRECISE_R_FOOT, ACID, penetration = 33)
- stepper.visible_message(span_danger("[stepper] is immersed in [src]'s acid!") , \
- span_danger("We are immersed in [src]'s acid!") , null, 5)
- playsound(stepper, "sound/bullets/acid_impact1.ogg", 10 * charges)
- new /obj/effect/temp_visual/acid_bath(get_turf(stepper))
- charges_used = charges //humans stepping on it empties it out
-
- if(!charges_used)
- return
-
- var/datum/effect_system/smoke_spread/xeno/acid/extuingishing/acid_smoke
- acid_smoke = new(get_turf(stepper)) //spawn acid smoke when charges are actually used
- acid_smoke.set_up(0, src) //acid smoke in the immediate vicinity
- acid_smoke.start()
-
- charges -= charges_used
- update_icon()
-
-/obj/structure/xeno/resin_jelly_pod
- name = "Resin jelly pod"
- desc = "A large resin pod. Inside is a thick, viscous fluid that looks like it doesnt burn easily."
- icon = 'icons/Xeno/resinpod.dmi'
- icon_state = "resinpod"
- density = FALSE
- opacity = FALSE
- anchored = TRUE
- max_integrity = 250
- layer = RESIN_STRUCTURE_LAYER
- pixel_x = -16
- pixel_y = -16
- xeno_structure_flags = IGNORE_WEED_REMOVAL
-
- hit_sound = "alien_resin_move"
- destroy_sound = "alien_resin_move"
- ///How many actual jellies the pod has stored
- var/chargesleft = 0
- ///Max amount of jellies the pod can hold
- var/maxcharges = 10
- ///Every 5 times this number seconds we will create a jelly
- var/recharge_rate = 10
- ///Countdown to the next time we generate a jelly
- var/nextjelly = 0
-
-/obj/structure/xeno/resin_jelly_pod/Initialize(mapload, _hivenumber)
- . = ..()
- add_overlay(image(icon, "resinpod_inside", layer + 0.01, dir))
- START_PROCESSING(SSslowprocess, src)
-
-/obj/structure/xeno/resin_jelly_pod/Destroy()
- STOP_PROCESSING(SSslowprocess, src)
- return ..()
-
-/obj/structure/xeno/resin_jelly_pod/examine(mob/user, distance, infix, suffix)
- . = ..()
- if(isxeno(user))
- . += "It has [chargesleft] jelly globules remaining[datum_flags & DF_ISPROCESSING ? ", and will create a new jelly in [(recharge_rate-nextjelly)*5] seconds": " and seems latent"]."
-
-/obj/structure/xeno/resin_jelly_pod/process()
- if(nextjelly <= recharge_rate)
- nextjelly++
- return
- nextjelly = 0
- chargesleft++
- if(chargesleft >= maxcharges)
- return PROCESS_KILL
-
-/obj/structure/xeno/resin_jelly_pod/attack_alien(mob/living/carbon/xenomorph/xeno_attacker, damage_amount = xeno_attacker.xeno_caste.melee_damage, damage_type = BRUTE, damage_flag = MELEE, effects = TRUE, armor_penetration = 0, isrightclick = FALSE)
- if(xeno_attacker.status_flags & INCORPOREAL)
- return FALSE
-
- if((xeno_attacker.a_intent == INTENT_HARM && isxenohivelord(xeno_attacker)) || xeno_attacker.hivenumber != hivenumber)
- balloon_alert(xeno_attacker, "Destroying...")
- if(do_after(xeno_attacker, HIVELORD_TUNNEL_DISMANTLE_TIME, IGNORE_HELD_ITEM, src, BUSY_ICON_BUILD))
- deconstruct(FALSE)
- return
-
- if(!chargesleft)
- balloon_alert(xeno_attacker, "No jelly remaining")
- to_chat(xeno_attacker, span_xenonotice("We reach into \the [src], but only find dregs of resin. We should wait some more.") )
- return
- balloon_alert(xeno_attacker, "Retrieved jelly")
- new /obj/item/resin_jelly(loc)
- chargesleft--
- if(!(datum_flags & DF_ISPROCESSING) && (chargesleft < maxcharges))
- START_PROCESSING(SSslowprocess, src)
-
-/obj/structure/xeno/silo
- name = "Resin silo"
- icon = 'icons/Xeno/resin_silo.dmi'
- icon_state = "weed_silo"
- desc = "A slimy, oozy resin bed filled with foul-looking egg-like ...things."
- bound_width = 96
- bound_height = 96
- max_integrity = 1000
- resistance_flags = UNACIDABLE | DROPSHIP_IMMUNE | PLASMACUTTER_IMMUNE
- xeno_structure_flags = IGNORE_WEED_REMOVAL|CRITICAL_STRUCTURE
- plane = FLOOR_PLANE
- ///How many larva points one silo produce in one minute
- var/larva_spawn_rate = 0.5
- var/turf/center_turf
- var/number_silo
- ///For minimap icon change if silo takes damage or nearby hostile
- var/warning
- COOLDOWN_DECLARE(silo_damage_alert_cooldown)
- COOLDOWN_DECLARE(silo_proxy_alert_cooldown)
-
-/obj/structure/xeno/silo/Initialize(mapload, _hivenumber)
- . = ..()
- center_turf = get_step(src, NORTHEAST)
- if(!istype(center_turf))
- center_turf = loc
-
- if(SSticker.mode?.flags_round_type & MODE_SILO_RESPAWN)
- for(var/turfs in RANGE_TURFS(XENO_SILO_DETECTION_RANGE, src))
- RegisterSignal(turfs, COMSIG_ATOM_ENTERED, PROC_REF(resin_silo_proxy_alert))
-
- if(SSticker.mode?.flags_round_type & MODE_SILOS_SPAWN_MINIONS)
- SSspawning.registerspawner(src, INFINITY, GLOB.xeno_ai_spawnable, 0, 0, null)
- SSspawning.spawnerdata[src].required_increment = 2 * max(45 SECONDS, 3 MINUTES - SSmonitor.maximum_connected_players_count * SPAWN_RATE_PER_PLAYER)/SSspawning.wait
- SSspawning.spawnerdata[src].max_allowed_mobs = max(1, MAX_SPAWNABLE_MOB_PER_PLAYER * SSmonitor.maximum_connected_players_count * 0.5)
- update_minimap_icon()
-
- return INITIALIZE_HINT_LATELOAD
-
-
-/obj/structure/xeno/silo/LateInitialize()
- . = ..()
- var/siloprefix = GLOB.hive_datums[hivenumber].name
- number_silo = length(GLOB.xeno_resin_silos_by_hive[hivenumber]) + 1
- name = "[siloprefix == "Normal" ? "" : "[siloprefix] "][name] [number_silo]"
- LAZYADDASSOC(GLOB.xeno_resin_silos_by_hive, hivenumber, src)
-
- if(!locate(/obj/alien/weeds) in center_turf)
- new /obj/alien/weeds/node(center_turf)
- if(GLOB.hive_datums[hivenumber])
- RegisterSignals(GLOB.hive_datums[hivenumber], list(COMSIG_HIVE_XENO_MOTHER_PRE_CHECK, COMSIG_HIVE_XENO_MOTHER_CHECK), PROC_REF(is_burrowed_larva_host))
- if(length(GLOB.xeno_resin_silos_by_hive[hivenumber]) == 1)
- GLOB.hive_datums[hivenumber].give_larva_to_next_in_queue()
- var/turf/tunnel_turf = get_step(center_turf, NORTH)
- if(tunnel_turf.can_dig_xeno_tunnel())
- var/obj/structure/xeno/tunnel/newt = new(tunnel_turf, hivenumber)
- newt.tunnel_desc = "[AREACOORD_NO_Z(newt)]"
- newt.name += " [name]"
- if(GLOB.hive_datums[hivenumber])
- SSticker.mode.update_silo_death_timer(GLOB.hive_datums[hivenumber])
-
-/obj/structure/xeno/silo/obj_destruction(damage_amount, damage_type, damage_flag)
- if(GLOB.hive_datums[hivenumber])
- INVOKE_NEXT_TICK(SSticker.mode, TYPE_PROC_REF(/datum/game_mode, update_silo_death_timer), GLOB.hive_datums[hivenumber]) // checks all silos next tick after this one is gone
- UnregisterSignal(GLOB.hive_datums[hivenumber], list(COMSIG_HIVE_XENO_MOTHER_PRE_CHECK, COMSIG_HIVE_XENO_MOTHER_CHECK))
- GLOB.hive_datums[hivenumber].xeno_message("A resin silo has been destroyed at [AREACOORD_NO_Z(src)]!", "xenoannounce", 5, FALSE,src.loc, 'sound/voice/alien_help2.ogg',FALSE , null, /atom/movable/screen/arrow/silo_damaged_arrow)
- notify_ghosts("\ A resin silo has been destroyed at [AREACOORD_NO_Z(src)]!", source = get_turf(src), action = NOTIFY_JUMP)
- playsound(loc,'sound/effects/alien_egg_burst.ogg', 75)
- return ..()
-
-/obj/structure/xeno/silo/Destroy()
- GLOB.xeno_resin_silos_by_hive[hivenumber] -= src
-
- for(var/i in contents)
- var/atom/movable/AM = i
- AM.forceMove(get_step(center_turf, pick(CARDINAL_ALL_DIRS)))
- center_turf = null
-
- STOP_PROCESSING(SSslowprocess, src)
- return ..()
-
-/obj/structure/xeno/silo/examine(mob/user)
- . = ..()
- var/current_integrity = (obj_integrity / max_integrity) * 100
- switch(current_integrity)
- if(0 to 20)
- . += span_warning("It's barely holding, there's leaking oozes all around, and most eggs are broken. Yet it is not inert.")
- if(20 to 40)
- . += span_warning("It looks severely damaged, its movements slow.")
- if(40 to 60)
- . += span_warning("It's quite beat up, but it seems alive.")
- if(60 to 80)
- . += span_warning("It's slightly damaged, but still seems healthy.")
- if(80 to 100)
- . += span_info("It appears in good shape, pulsating healthily.")
-
-
-/obj/structure/xeno/silo/take_damage(damage_amount, damage_type, damage_flag, sound_effect, attack_dir, armour_penetration)
- . = ..()
-
- //We took damage, so it's time to start regenerating if we're not already processing
- if(!CHECK_BITFIELD(datum_flags, DF_ISPROCESSING))
- START_PROCESSING(SSslowprocess, src)
-
- resin_silo_damage_alert()
-
-/obj/structure/xeno/silo/proc/resin_silo_damage_alert()
- if(!COOLDOWN_CHECK(src, silo_damage_alert_cooldown))
- return
- warning = TRUE
- update_minimap_icon()
- GLOB.hive_datums[hivenumber].xeno_message("Our [name] at [AREACOORD_NO_Z(src)] is under attack! It has [obj_integrity]/[max_integrity] Health remaining.", "xenoannounce", 5, FALSE, src, 'sound/voice/alien_help1.ogg',FALSE, null, /atom/movable/screen/arrow/silo_damaged_arrow)
- COOLDOWN_START(src, silo_damage_alert_cooldown, XENO_SILO_HEALTH_ALERT_COOLDOWN) //set the cooldown.
- addtimer(CALLBACK(src, PROC_REF(clear_warning)), XENO_SILO_HEALTH_ALERT_COOLDOWN) //clear warning
-
-///Alerts the Hive when hostiles get too close to their resin silo
-/obj/structure/xeno/silo/proc/resin_silo_proxy_alert(datum/source, atom/movable/hostile, direction)
- SIGNAL_HANDLER
-
- if(!COOLDOWN_CHECK(src, silo_proxy_alert_cooldown)) //Proxy alert triggered too recently; abort
- return
-
- if(!isliving(hostile))
- return
-
- var/mob/living/living_triggerer = hostile
- if(living_triggerer.stat == DEAD) //We don't care about the dead
- return
-
- if(isxeno(hostile))
- var/mob/living/carbon/xenomorph/X = hostile
- if(X.hive == GLOB.hive_datums[hivenumber]) //Trigger proxy alert only for hostile xenos
- return
-
- warning = TRUE
- update_minimap_icon()
- GLOB.hive_datums[hivenumber].xeno_message("Our [name] has detected a nearby hostile [hostile] at [get_area(hostile)] (X: [hostile.x], Y: [hostile.y]).", "xenoannounce", 5, FALSE, hostile, 'sound/voice/alien_help1.ogg', FALSE, null, /atom/movable/screen/arrow/leader_tracker_arrow)
- COOLDOWN_START(src, silo_proxy_alert_cooldown, XENO_SILO_DETECTION_COOLDOWN) //set the cooldown.
- addtimer(CALLBACK(src, PROC_REF(clear_warning)), XENO_SILO_DETECTION_COOLDOWN) //clear warning
-
-///Clears the warning for minimap if its warning for hostiles
-/obj/structure/xeno/silo/proc/clear_warning()
- warning = FALSE
- update_minimap_icon()
-
-/obj/structure/xeno/silo/process()
- //Regenerate if we're at less than max integrity
- if(obj_integrity < max_integrity)
- obj_integrity = min(obj_integrity + 25, max_integrity) //Regen 5 HP per sec
-
-/obj/structure/xeno/silo/proc/is_burrowed_larva_host(datum/source, list/mothers, list/silos)
- SIGNAL_HANDLER
- if(GLOB.hive_datums[hivenumber])
- silos += src
-
-///Change minimap icon if silo is under attack or not
-/obj/structure/xeno/silo/proc/update_minimap_icon()
- SSminimaps.remove_marker(src)
- SSminimaps.add_marker(src, MINIMAP_FLAG_XENO, image('icons/UI_icons/map_blips.dmi', null, "silo[warning ? "_warn" : "_passive"]", VERY_HIGH_FLOAT_LAYER)) // RU TGMC edit - map blips
-
-/obj/structure/xeno/silo/crash
- resistance_flags = UNACIDABLE | DROPSHIP_IMMUNE | PLASMACUTTER_IMMUNE | INDESTRUCTIBLE
-
-/obj/structure/xeno/xeno_turret
- icon = 'icons/Xeno/acidturret.dmi'
- icon_state = XENO_TURRET_ACID_ICONSTATE
- name = "acid turret"
- desc = "A menacing looking construct of resin, it seems to be alive. It fires acid against intruders."
- bound_width = 32
- bound_height = 32
- obj_integrity = 600
- max_integrity = 1500
- layer = ABOVE_MOB_LAYER
- density = TRUE
- resistance_flags = UNACIDABLE | DROPSHIP_IMMUNE |PORTAL_IMMUNE
- xeno_structure_flags = IGNORE_WEED_REMOVAL|HAS_OVERLAY
- allow_pass_flags = PASS_AIR|PASS_THROW
- ///What kind of spit it uses
- var/datum/ammo/ammo = /datum/ammo/xeno/acid/heavy/turret
- ///Range of the turret
- var/range = 7
- ///Target of the turret
- var/atom/hostile
- ///Last target of the turret
- var/atom/last_hostile
- ///Potential list of targets found by scan
- var/list/atom/potential_hostiles
- ///Fire rate of the target in ticks
- var/firerate = 5
- ///The last time the sentry did a scan
- var/last_scan_time
- ///light color that gets set in initialize
- var/light_initial_color = LIGHT_COLOR_GREEN
- ///For minimap icon change if sentry is firing
- var/firing
-
-///Change minimap icon if its firing or not firing
-/obj/structure/xeno/xeno_turret/proc/update_minimap_icon()
- SSminimaps.remove_marker(src)
- SSminimaps.add_marker(src, MINIMAP_FLAG_XENO, image('icons/UI_icons/map_blips.dmi', null, "xeno_turret[firing ? "_firing" : "_passive"]")) // RU TGMC edit - map blips
-
-/obj/structure/xeno/xeno_turret/Initialize(mapload, _hivenumber)
- . = ..()
- ammo = GLOB.ammo_list[ammo]
- potential_hostiles = list()
- LAZYADDASSOC(GLOB.xeno_resin_turrets_by_hive, hivenumber, src)
- START_PROCESSING(SSobj, src)
- AddComponent(/datum/component/automatedfire/xeno_turret_autofire, firerate)
- RegisterSignal(src, COMSIG_AUTOMATIC_SHOOTER_SHOOT, PROC_REF(shoot))
- RegisterSignal(SSdcs, COMSIG_GLOB_DROPSHIP_HIJACKED, PROC_REF(destroy_on_hijack))
- if(light_initial_color)
- set_light(2, 2, light_initial_color)
- update_minimap_icon()
- update_icon()
-
-///Signal handler to delete the turret when the alamo is hijacked
-/obj/structure/xeno/xeno_turret/proc/destroy_on_hijack()
- SIGNAL_HANDLER
- qdel(src)
-
-/obj/structure/xeno/xeno_turret/obj_destruction(damage_amount, damage_type, damage_flag)
- if(damage_amount) //Spawn effects only if we actually get destroyed by damage
- on_destruction()
- return ..()
-
-/obj/structure/xeno/xeno_turret/proc/on_destruction()
- var/datum/effect_system/smoke_spread/xeno/smoke = new /datum/effect_system/smoke_spread/xeno/acid(src)
- smoke.set_up(1, get_turf(src))
- smoke.start()
-
-/obj/structure/xeno/xeno_turret/Destroy()
- GLOB.xeno_resin_turrets_by_hive[hivenumber] -= src
- set_hostile(null)
- set_last_hostile(null)
- STOP_PROCESSING(SSobj, src)
- playsound(loc,'sound/effects/xeno_turret_death.ogg', 70)
- return ..()
-
-/obj/structure/xeno/xeno_turret/ex_act(severity)
- switch(severity)
- if(EXPLODE_DEVASTATE)
- take_damage(1500, BRUTE, BOMB)
- if(EXPLODE_HEAVY)
- take_damage(750, BRUTE, BOMB)
- if(EXPLODE_LIGHT)
- take_damage(300, BRUTE, BOMB)
-
-/obj/structure/xeno/xeno_turret/flamer_fire_act(burnlevel)
- take_damage(burnlevel * 2, BURN, FIRE)
- ENABLE_BITFIELD(resistance_flags, ON_FIRE)
-
-/obj/structure/xeno/xeno_turret/fire_act()
- take_damage(60, BURN, FIRE)
- ENABLE_BITFIELD(resistance_flags, ON_FIRE)
-
-/obj/structure/xeno/xeno_turret/update_overlays()
- . = ..()
- if(!(xeno_structure_flags & HAS_OVERLAY))
- return
- if(obj_integrity <= max_integrity / 2)
- . += image('icons/Xeno/acidturret.dmi', src, "+turret_damage")
- if(CHECK_BITFIELD(resistance_flags, ON_FIRE))
- . += image('icons/Xeno/acidturret.dmi', src, "+turret_on_fire")
-
-/obj/structure/xeno/xeno_turret/process()
- //Turrets regen some HP, every 2 sec
- if(obj_integrity < max_integrity)
- obj_integrity = min(obj_integrity + TURRET_HEALTH_REGEN, max_integrity)
- update_icon()
- DISABLE_BITFIELD(resistance_flags, ON_FIRE)
- if(world.time > last_scan_time + TURRET_SCAN_FREQUENCY)
- scan()
- last_scan_time = world.time
- if(!length(potential_hostiles))
- return
- set_hostile(get_target())
- if (!hostile)
- if(last_hostile)
- set_last_hostile(null)
- return
- if(!TIMER_COOLDOWN_CHECK(src, COOLDOWN_XENO_TURRETS_ALERT))
- GLOB.hive_datums[hivenumber].xeno_message("Our [name] is attacking a nearby hostile [hostile] at [get_area(hostile)] (X: [hostile.x], Y: [hostile.y]).", "xenoannounce", 5, FALSE, hostile, 'sound/voice/alien_help1.ogg', FALSE, null, /atom/movable/screen/arrow/turret_attacking_arrow)
- TIMER_COOLDOWN_START(src, COOLDOWN_XENO_TURRETS_ALERT, 20 SECONDS)
- if(hostile != last_hostile)
- set_last_hostile(hostile)
- SEND_SIGNAL(src, COMSIG_AUTOMATIC_SHOOTER_START_SHOOTING_AT)
-
-/obj/structure/xeno/xeno_turret/attackby(obj/item/I, mob/living/user, params)
- if(I.flags_item & NOBLUDGEON || !isliving(user))
- return attack_hand(user)
-
- user.changeNext_move(I.attack_speed)
- user.do_attack_animation(src, used_item = I)
-
- var/damage = I.force
- var/multiplier = 1
- if(I.damtype == BURN) //Burn damage deals extra vs resin structures (mostly welders).
- multiplier += 1
-
- if(istype(I, /obj/item/tool/pickaxe/plasmacutter) && !user.do_actions)
- var/obj/item/tool/pickaxe/plasmacutter/P = I
- if(P.start_cut(user, name, src, PLASMACUTTER_BASE_COST * PLASMACUTTER_VLOW_MOD))
- multiplier += PLASMACUTTER_RESIN_MULTIPLIER
- P.cut_apart(user, name, src, PLASMACUTTER_BASE_COST * PLASMACUTTER_VLOW_MOD)
-
- damage *= max(0, multiplier)
- take_damage(damage, BRUTE, MELEE)
- playsound(src, "alien_resin_break", 25)
-
-///Signal handler for hard del of hostile
-/obj/structure/xeno/xeno_turret/proc/unset_hostile()
- SIGNAL_HANDLER
- hostile = null
-
-///Signal handler for hard del of last_hostile
-/obj/structure/xeno/xeno_turret/proc/unset_last_hostile()
- SIGNAL_HANDLER
- last_hostile = null
-
-///Setter for hostile with hard del in mind
-/obj/structure/xeno/xeno_turret/proc/set_hostile(_hostile)
- if(hostile != _hostile)
- hostile = _hostile
- RegisterSignal(hostile, COMSIG_QDELETING, PROC_REF(unset_hostile))
-
-///Setter for last_hostile with hard del in mind
-/obj/structure/xeno/xeno_turret/proc/set_last_hostile(_last_hostile)
- if(last_hostile)
- UnregisterSignal(last_hostile, COMSIG_QDELETING)
- last_hostile = _last_hostile
-
-///Look for the closest human in range and in light of sight. If no human is in range, will look for xenos of other hives
-/obj/structure/xeno/xeno_turret/proc/get_target()
- var/distance = range + 0.5 //we add 0.5 so if a potential target is at range, it is accepted by the system
- var/buffer_distance
- var/list/turf/path = list()
- for (var/atom/nearby_hostile AS in potential_hostiles)
- if(isliving(nearby_hostile))
- var/mob/living/nearby_living_hostile = nearby_hostile
- if(nearby_living_hostile.stat == DEAD)
- continue
- if(HAS_TRAIT(nearby_hostile, TRAIT_TURRET_HIDDEN))
- continue
- buffer_distance = get_dist(nearby_hostile, src)
- if (distance <= buffer_distance) //If we already found a target that's closer
- continue
- path = getline(src, nearby_hostile)
- path -= get_turf(src)
- if(!length(path)) //Can't shoot if it's on the same turf
- continue
- var/blocked = FALSE
- for(var/turf/T AS in path)
- if(IS_OPAQUE_TURF(T) || T.density && !(T.allow_pass_flags & PASS_PROJECTILE))
- blocked = TRUE
- break //LoF Broken; stop checking; we can't proceed further.
-
- for(var/obj/machinery/MA in T)
- if(MA.opacity || MA.density && !(MA.allow_pass_flags & PASS_PROJECTILE))
- blocked = TRUE
- break //LoF Broken; stop checking; we can't proceed further.
-
- for(var/obj/structure/S in T)
- if(S.opacity || S.density && !(S.allow_pass_flags & PASS_PROJECTILE))
- blocked = TRUE
- break //LoF Broken; stop checking; we can't proceed further.
- if(!blocked)
- distance = buffer_distance
- . = nearby_hostile
-
-///Return TRUE if a possible target is near
-/obj/structure/xeno/xeno_turret/proc/scan()
- potential_hostiles.Cut()
- for (var/mob/living/carbon/human/nearby_human AS in cheap_get_humans_near(src, TURRET_SCAN_RANGE))
- if(nearby_human.stat == DEAD)
- continue
- if(nearby_human.get_xeno_hivenumber() == hivenumber)
- continue
- potential_hostiles += nearby_human
- for (var/mob/living/carbon/xenomorph/nearby_xeno AS in cheap_get_xenos_near(src, range))
- if(GLOB.hive_datums[hivenumber] == nearby_xeno.hive)
- continue
- if(nearby_xeno.stat == DEAD)
- continue
- potential_hostiles += nearby_xeno
- for(var/obj/vehicle/unmanned/vehicle AS in GLOB.unmanned_vehicles)
- if(vehicle.z == z && get_dist(vehicle, src) <= range)
- potential_hostiles += vehicle
- for(var/obj/vehicle/sealed/mecha/mech AS in GLOB.mechas_list)
- if(mech.z == z && get_dist(mech, src) <= range)
- potential_hostiles += mech
-
-///Signal handler to make the turret shoot at its target
-/obj/structure/xeno/xeno_turret/proc/shoot()
- SIGNAL_HANDLER
- if(!hostile)
- SEND_SIGNAL(src, COMSIG_AUTOMATIC_SHOOTER_STOP_SHOOTING_AT)
- firing = FALSE
- update_minimap_icon()
- return
- face_atom(hostile)
- var/obj/projectile/newshot = new(loc)
- newshot.generate_bullet(ammo)
- newshot.def_zone = pick(GLOB.base_miss_chance)
- newshot.fire_at(hostile, src, null, ammo.max_range, ammo.shell_speed)
- if(istype(ammo, /datum/ammo/xeno/hugger))
- var/datum/ammo/xeno/hugger/hugger_ammo = ammo
- newshot.color = initial(hugger_ammo.hugger_type.color)
- hugger_ammo.hivenumber = hivenumber
- firing = TRUE
- update_minimap_icon()
-
-/obj/structure/xeno/xeno_turret/sticky
- name = "Sticky resin turret"
- icon = 'icons/Xeno/acidturret.dmi'
- icon_state = XENO_TURRET_STICKY_ICONSTATE
- desc = "A menacing looking construct of resin, it seems to be alive. It fires resin against intruders."
- light_initial_color = LIGHT_COLOR_PURPLE
- ammo = /datum/ammo/xeno/sticky/turret
- firerate = 5
-
-/obj/structure/xeno/xeno_turret/sticky/on_destruction()
- for(var/i = 1 to 20) // maybe a bit laggy
- var/obj/projectile/new_proj = new(src)
- new_proj.generate_bullet(ammo)
- new_proj.fire_at(null, src, range = rand(1, 4), angle = rand(1, 360), recursivity = TRUE)
-
-/obj/structure/xeno/xeno_turret/hugger_turret
- name = "hugger turret"
- icon_state = "hugger_turret"
- desc = "A menacing looking construct of resin, it seems to be alive. It fires huggers against intruders."
- obj_integrity = 400
- max_integrity = 400
- light_initial_color = LIGHT_COLOR_BROWN
- ammo = /datum/ammo/xeno/hugger
- firerate = 5 SECONDS
-
-/obj/structure/xeno/xeno_turret/hugger_turret/on_destruction()
- for(var/i = 1 to 5)
- var/obj/projectile/new_proj = new(src)
- new_proj.generate_bullet(ammo)
- new_proj.fire_at(null, src, range = rand(1, 3), angle = rand(1, 360), recursivity = TRUE)
-
-/obj/structure/xeno/evotower
- name = "evolution tower"
- desc = "A sickly outcrop from the ground. It seems to ooze a strange chemical that shimmers and warps the ground around it."
- icon = 'icons/Xeno/2x2building.dmi'
- icon_state = "evotower"
- bound_width = 64
- bound_height = 64
- obj_integrity = 600
- max_integrity = 600
- xeno_structure_flags = CRITICAL_STRUCTURE
- ///boost amt to be added per tower per cycle
- var/boost_amount = 0.2
-
-/obj/structure/xeno/evotower/Initialize(mapload, _hivenumber)
- . = ..()
- GLOB.hive_datums[hivenumber].evotowers += src
- set_light(2, 2, LIGHT_COLOR_GREEN)
- SSminimaps.add_marker(src, MINIMAP_FLAG_XENO, image('icons/UI_icons/map_blips.dmi', null, "tower"))
-
-/obj/structure/xeno/evotower/Destroy()
- GLOB.hive_datums[hivenumber].evotowers -= src
- return ..()
-
-/obj/structure/xeno/evotower/ex_act(severity)
- take_damage(severity * 2.5, BRUTE, BOMB)
-
-/obj/structure/xeno/psychictower
- name = "Psychic Relay"
- desc = "A sickly outcrop from the ground. It seems to allow for more advanced growth of the Xenomorphs."
- icon = 'icons/Xeno/2x2building.dmi'
- icon_state = "maturitytower"
- bound_width = 64
- bound_height = 64
- obj_integrity = 400
- max_integrity = 400
- xeno_structure_flags = CRITICAL_STRUCTURE
-
-/obj/structure/xeno/psychictower/Initialize(mapload, _hivenumber)
- . = ..()
- GLOB.hive_datums[hivenumber].psychictowers += src
- set_light(2, 2, LIGHT_COLOR_GREEN)
- SSminimaps.add_marker(src, MINIMAP_FLAG_XENO, image('icons/UI_icons/map_blips.dmi', null, "tower"))
-
-/obj/structure/xeno/psychictower/Destroy()
- GLOB.hive_datums[hivenumber].psychictowers -= src
- return ..()
-
-/obj/structure/xeno/psychictower/ex_act(severity)
- take_damage(severity * 2.5, BRUTE, BOMB)
-
-/obj/structure/xeno/pherotower
- name = "Pheromone tower"
- desc = "A resin formation that looks like a small pillar. A faint, weird smell can be perceived from it."
- icon = 'icons/Xeno/1x1building.dmi'
- icon_state = "recoverytower"
- bound_width = 32
- bound_height = 32
- obj_integrity = 400
- max_integrity = 400
- xeno_structure_flags = CRITICAL_STRUCTURE
- ///The type of pheromone currently being emitted.
- var/datum/aura_bearer/current_aura
- ///Strength of pheromones given by this tower.
- var/aura_strength = 5
- ///Radius (in tiles) of the pheromones given by this tower.
- var/aura_radius = 32
-
-/obj/structure/xeno/pherotower/Initialize(mapload, _hivenumber)
- . = ..()
- SSminimaps.add_marker(src, MINIMAP_FLAG_XENO, image('icons/UI_icons/map_blips.dmi', null, "phero", ABOVE_FLOAT_LAYER)) // RU TGMC edit - map blips
- GLOB.hive_datums[hivenumber].pherotowers += src
-
-//Pheromone towers start off with recovery.
- current_aura = SSaura.add_emitter(src, AURA_XENO_RECOVERY, aura_radius, aura_strength, -1, FACTION_XENO, hivenumber)
- playsound(src, "alien_drool", 25)
- update_icon()
-
-/obj/structure/xeno/pherotower/ex_act(severity)
- take_damage(severity * 2.5, BRUTE, BOMB)
-
-/obj/structure/xeno/pherotower/Destroy()
- GLOB.hive_datums[hivenumber].pherotowers -= src
- return ..()
-
-// Clicking on the tower brings up a radial menu that allows you to select the type of pheromone that this tower will emit.
-/obj/structure/xeno/pherotower/attack_alien(mob/living/carbon/xenomorph/xeno_attacker, damage_amount = xeno_attacker.xeno_caste.melee_damage, damage_type = BRUTE, damage_flag = MELEE, effects = TRUE, armor_penetration = 0, isrightclick = FALSE)
- var/phero_choice = show_radial_menu(xeno_attacker, src, GLOB.pheromone_images_list, radius = 35, require_near = TRUE)
-
- if(!phero_choice)
- return
-
- QDEL_NULL(current_aura)
- current_aura = SSaura.add_emitter(src, phero_choice, aura_radius, aura_strength, -1, FACTION_XENO, hivenumber)
- balloon_alert(xeno_attacker, "[phero_choice]")
- playsound(src, "alien_drool", 25)
- update_icon()
-
-/obj/structure/xeno/pherotower/update_icon_state()
- . = ..()
- switch(current_aura.aura_types[1])
- if(AURA_XENO_RECOVERY)
- icon_state = "recoverytower"
- set_light(2, 2, LIGHT_COLOR_BLUE)
- if(AURA_XENO_WARDING)
- icon_state = "wardingtower"
- set_light(2, 2, LIGHT_COLOR_GREEN)
- if(AURA_XENO_FRENZY)
- icon_state = "frenzytower"
- set_light(2, 2, LIGHT_COLOR_RED)
-
-/obj/structure/xeno/pherotower/crash
- name = "Recovery tower"
- resistance_flags = RESIST_ALL
- xeno_structure_flags = IGNORE_WEED_REMOVAL | CRITICAL_STRUCTURE
-
-/obj/structure/xeno/pherotower/crash/attack_alien(isrightclick = FALSE)
- return
-
-/obj/structure/xeno/spawner
- icon = 'icons/Xeno/2x2building.dmi.dmi'
- bound_width = 64
- bound_height = 64
- plane = FLOOR_PLANE
- name = "spawner"
- desc = "A slimy, oozy resin bed filled with foul-looking egg-like ...things."
- icon_state = "spawner"
- max_integrity = 500
- resistance_flags = UNACIDABLE | DROPSHIP_IMMUNE
- xeno_structure_flags = IGNORE_WEED_REMOVAL | CRITICAL_STRUCTURE
- ///For minimap icon change if silo takes damage or nearby hostile
- var/warning
- COOLDOWN_DECLARE(spawner_damage_alert_cooldown)
- COOLDOWN_DECLARE(spawner_proxy_alert_cooldown)
- var/linked_minions = list()
-
-/obj/structure/xeno/spawner/Initialize(mapload, _hivenumber)
- . = ..()
- LAZYADDASSOC(GLOB.xeno_spawners_by_hive, hivenumber, src)
- SSspawning.registerspawner(src, INFINITY, GLOB.xeno_ai_spawnable, 0, 0, CALLBACK(src, PROC_REF(on_spawn)))
- SSspawning.spawnerdata[src].required_increment = max(45 SECONDS, 3 MINUTES - SSmonitor.maximum_connected_players_count * SPAWN_RATE_PER_PLAYER)/SSspawning.wait
- SSspawning.spawnerdata[src].max_allowed_mobs = max(2, MAX_SPAWNABLE_MOB_PER_PLAYER * SSmonitor.maximum_connected_players_count)
- set_light(2, 2, LIGHT_COLOR_GREEN)
- for(var/turfs in RANGE_TURFS(XENO_SILO_DETECTION_RANGE, src))
- RegisterSignal(turfs, COMSIG_ATOM_ENTERED, PROC_REF(spawner_proxy_alert))
- update_minimap_icon()
-
-/obj/structure/xeno/spawner/examine(mob/user)
- . = ..()
- var/current_integrity = (obj_integrity / max_integrity) * 100
- switch(current_integrity)
- if(0 to 20)
- . += span_warning("It's barely holding, there's leaking oozes all around, and most eggs are broken. Yet it is not inert.")
- if(20 to 40)
- . += span_warning("It looks severely damaged, its movements slow.")
- if(40 to 60)
- . += span_warning("It's quite beat up, but it seems alive.")
- if(60 to 80)
- . += span_warning("It's slightly damaged, but still seems healthy.")
- if(80 to 100)
- . += span_info("It appears in good shape, pulsating healthily.")
-
-
-/obj/structure/xeno/spawner/take_damage(damage_amount, damage_type, damage_flag, sound_effect, attack_dir, armour_penetration)
- . = ..()
- spawner_damage_alert()
-
-///Alert if spawner is receiving damage
-/obj/structure/xeno/spawner/proc/spawner_damage_alert()
- if(!COOLDOWN_CHECK(src, spawner_damage_alert_cooldown))
- warning = FALSE
- return
- warning = TRUE
- update_minimap_icon()
- GLOB.hive_datums[hivenumber].xeno_message("Our [name] at [AREACOORD_NO_Z(src)] is under attack! It has [obj_integrity]/[max_integrity] Health remaining.", "xenoannounce", 5, FALSE, src, 'sound/voice/alien_help1.ogg',FALSE, null, /atom/movable/screen/arrow/silo_damaged_arrow)
- COOLDOWN_START(src, spawner_damage_alert_cooldown, XENO_SILO_HEALTH_ALERT_COOLDOWN) //set the cooldown.
- addtimer(CALLBACK(src, PROC_REF(clear_warning)), XENO_SILO_DETECTION_COOLDOWN) //clear warning
-
-///Alerts the Hive when hostiles get too close to their spawner
-/obj/structure/xeno/spawner/proc/spawner_proxy_alert(datum/source, atom/movable/hostile, direction)
- SIGNAL_HANDLER
-
- if(!COOLDOWN_CHECK(src, spawner_proxy_alert_cooldown)) //Proxy alert triggered too recently; abort
- warning = FALSE
- return
-
- if(!isliving(hostile))
- return
-
- var/mob/living/living_triggerer = hostile
- if(living_triggerer.stat == DEAD) //We don't care about the dead
- return
-
- if(isxeno(hostile))
- var/mob/living/carbon/xenomorph/X = hostile
- if(X.hivenumber == hivenumber) //Trigger proxy alert only for hostile xenos
- return
-
- warning = TRUE
- update_minimap_icon()
- GLOB.hive_datums[hivenumber].xeno_message("Our [name] has detected a nearby hostile [hostile] at [get_area(hostile)] (X: [hostile.x], Y: [hostile.y]).", "xenoannounce", 5, FALSE, hostile, 'sound/voice/alien_help1.ogg', FALSE, null, /atom/movable/screen/arrow/leader_tracker_arrow)
- COOLDOWN_START(src, spawner_proxy_alert_cooldown, XENO_SILO_DETECTION_COOLDOWN) //set the cooldown.
- addtimer(CALLBACK(src, PROC_REF(clear_warning)), XENO_SILO_DETECTION_COOLDOWN) //clear warning
-
-///Clears the warning for minimap if its warning for hostiles
-/obj/structure/xeno/spawner/proc/clear_warning()
- warning = FALSE
- update_minimap_icon()
-
-/obj/structure/xeno/spawner/Destroy()
- GLOB.xeno_spawners_by_hive[hivenumber] -= src
- return ..()
-
-///Change minimap icon if spawner is under attack or not
-/obj/structure/xeno/spawner/proc/update_minimap_icon()
- SSminimaps.remove_marker(src)
- SSminimaps.add_marker(src, MINIMAP_FLAG_XENO, image('icons/UI_icons/map_blips.dmi', null, "spawner[warning ? "_warn" : "_passive"]", , ABOVE_FLOAT_LAYER)) // RU TGMC edit - map blips
-
-/obj/structure/xeno/spawner/proc/on_spawn(list/squad)
- if(!isxeno(squad[length(squad)]))
- CRASH("Xeno spawner somehow tried to spawn a non xeno (tried to spawn [squad[length(squad)]])")
- var/mob/living/carbon/xenomorph/X = squad[length(squad)]
- X.transfer_to_hive(hivenumber)
- linked_minions = squad
- if(hivenumber == XENO_HIVE_FALLEN) //snowflake so valhalla isnt filled with minions after you're done
- RegisterSignal(src, COMSIG_QDELETING, PROC_REF(kill_linked_minions))
-
-/obj/structure/xeno/spawner/proc/kill_linked_minions()
- for(var/mob/living/carbon/xenomorph/linked in linked_minions)
- linked.death(TRUE)
- UnregisterSignal(src, COMSIG_QDELETING)
-
-///Those structures need time to grow and are supposed to be extremely weak healh-wise
-/obj/structure/xeno/plant
- name = "Xeno Plant"
- max_integrity = 5
- icon = 'icons/Xeno/plants.dmi'
- interaction_flags = INTERACT_CHECK_INCAPACITATED
- ///The plant's icon once it's fully grown
- var/mature_icon_state
- ///Is the plant ready to be used ?
- var/mature = FALSE
- ///How long does it take for the plant to be useable
- var/maturation_time = 2 MINUTES
-
-/obj/structure/xeno/plant/Initialize(mapload, _hivenumber)
- . = ..()
- addtimer(CALLBACK(src, PROC_REF(on_mature)), maturation_time)
- SSminimaps.add_marker(src, MINIMAP_FLAG_XENO, image('icons/UI_icons/map_blips.dmi', null, "[mature_icon_state]"))
-
-/obj/structure/xeno/plant/can_interact(mob/user)
- . = ..()
- if(!.)
- return FALSE
- if(!mature && isxeno(user))
- balloon_alert(user, "Not fully grown")
- return FALSE
-
-/obj/structure/xeno/plant/update_icon_state()
- . = ..()
- icon_state = (mature) ? mature_icon_state : initial(icon_state)
-
-///Called whenever someone uses the plant, xeno or marine
-/obj/structure/xeno/plant/proc/on_use(mob/user)
- mature = FALSE
- update_icon()
- addtimer(CALLBACK(src, PROC_REF(on_mature)), maturation_time)
- return TRUE
-
-///Called when the plant reaches maturity
-/obj/structure/xeno/plant/proc/on_mature(mob/user)
- playsound(src, "alien_resin_build", 25)
- mature = TRUE
- update_icon()
-
-/obj/structure/xeno/plant/attack_hand(mob/living/user)
- if(!can_interact(user))
- return ..()
- return on_use(user)
-
-/obj/structure/xeno/plant/attack_alien(mob/living/carbon/xenomorph/xeno_attacker, damage_amount = xeno_attacker.xeno_caste.melee_damage, damage_type = BRUTE, damage_flag = MELEE, effects = TRUE, armor_penetration = 0, isrightclick = FALSE)
- if((xeno_attacker.status_flags & INCORPOREAL))
- return FALSE
-
- if(xeno_attacker.a_intent == INTENT_HARM && isxenodrone(xeno_attacker))
- balloon_alert(xeno_attacker, "Uprooted the plant")
- xeno_attacker.do_attack_animation(src)
- deconstruct(FALSE)
- return FALSE
- if(can_interact(xeno_attacker))
- return on_use(xeno_attacker)
- return TRUE
-
-/obj/structure/xeno/plant/heal_fruit
- name = "life fruit"
- desc = "It would almost be appetizing wasn't it for the green colour and the shifting fluids inside..."
- icon_state = "heal_fruit_immature"
- mature_icon_state = "heal_fruit"
- ///Minimum amount of health recovered
- var/healing_amount_min = 125
- ///Maximum amount of health recovered, depends on the xeno's max health
- var/healing_amount_max_health_scaling = 0.5
-
-/obj/structure/xeno/plant/heal_fruit/on_use(mob/user)
- balloon_alert(user, "Consuming...")
- if(!do_after(user, 2 SECONDS, IGNORE_HELD_ITEM, src))
- return FALSE
- if(!isxeno(user))
- var/datum/effect_system/smoke_spread/xeno/acid/plant_explosion = new(get_turf(src))
- plant_explosion.set_up(3,src)
- plant_explosion.start()
- visible_message(span_danger("[src] bursts, releasing toxic gas!"))
- qdel(src)
- return TRUE
-
- var/mob/living/carbon/xenomorph/X = user
- var/heal_amount = max(healing_amount_min, healing_amount_max_health_scaling * X.xeno_caste.max_health)
- HEAL_XENO_DAMAGE(X, heal_amount, FALSE)
- playsound(user, "alien_drool", 25)
- balloon_alert(X, "Health restored")
- to_chat(X, span_xenowarning("We feel a sudden soothing chill as [src] tends to our wounds."))
-
- return ..()
-
-/obj/structure/xeno/plant/armor_fruit
- name = "hard fruit"
- desc = "The contents of this fruit are protected by a tough outer shell."
- icon_state = "armor_fruit_immature"
- mature_icon_state = "armor_fruit"
- ///How much total sunder should we remove
- var/sunder_removal = 30
-
-/obj/structure/xeno/plant/armor_fruit/on_use(mob/user)
- balloon_alert(user, "Consuming...")
- if(!do_after(user, 2 SECONDS, IGNORE_HELD_ITEM, src))
- return FALSE
- if(!isxeno(user))
- var/turf/far_away_lands = get_turf(user)
- for(var/x in 1 to 20)
- var/turf/next_turf = get_step(far_away_lands, REVERSE_DIR(user.dir))
- if(!next_turf)
- break
- far_away_lands = next_turf
-
- user.throw_at(far_away_lands, 20, spin = TRUE)
- to_chat(user, span_warning("[src] bursts, releasing a strong gust of pressurised gas!"))
- if(ishuman(user))
- var/mob/living/carbon/human/H = user
- H.adjust_stagger(3 SECONDS)
- H.apply_damage(30, BRUTE, "chest", BOMB)
- qdel(src)
- return TRUE
-
- balloon_alert(user, "Armor restored")
- to_chat(user, span_xenowarning("We shed our shattered scales as new ones grow to replace them!"))
- var/mob/living/carbon/xenomorph/X = user
- X.adjust_sunder(-sunder_removal)
- playsound(user, "alien_drool", 25)
- return ..()
-
-/obj/structure/xeno/plant/plasma_fruit
- name = "power fruit"
- desc = "A cyan fruit, beating like a creature's heart"
- icon_state = "plasma_fruit_immature"
- mature_icon_state = "plasma_fruit"
- ///How much bonus plasma should we restore during the duration, 1 being 100% from base regen
- var/bonus_regen = 1
- ///How long should the buff last
- var/duration = 1 MINUTES
-
-/obj/structure/xeno/plant/plasma_fruit/can_interact(mob/user)
- . = ..()
- if(!.)
- return FALSE
- if(!isxeno(user))
- return
- var/mob/living/carbon/xenomorph/X = user
- if(X.has_status_effect(STATUS_EFFECT_PLASMA_SURGE))
- balloon_alert(X, "Already increased plasma regen")
- return FALSE
-
-/obj/structure/xeno/plant/plasma_fruit/on_use(mob/user)
- balloon_alert(user, "Consuming...")
- if(!do_after(user, 2 SECONDS, IGNORE_HELD_ITEM, src))
- return FALSE
- if(!isxeno(user))
- visible_message(span_warning("[src] releases a sticky substance before spontaneously bursting into flames!"))
- flame_radius(3, get_turf(src), colour = "green")
- qdel(src)
- return TRUE
-
- var/mob/living/carbon/xenomorph/X = user
- if(!(X.xeno_caste.can_flags & CASTE_CAN_BE_GIVEN_PLASMA))
- to_chat(X, span_xenowarning("But our body rejects the fruit, we do not share the same plasma type!"))
- return FALSE
- X.apply_status_effect(/datum/status_effect/plasma_surge, X.xeno_caste.plasma_max, bonus_regen, duration)
- balloon_alert(X, "Plasma restored")
- to_chat(X, span_xenowarning("[src] Restores our plasma reserves, our organism is on overdrive!"))
- playsound(user, "alien_drool", 25)
- return ..()
-
-/obj/structure/xeno/plant/stealth_plant
- name = "night shade"
- desc = "A beautiful flower, what purpose it could serve to the alien hive is beyond you however..."
- icon_state = "stealth_plant_immature"
- mature_icon_state = "stealth_plant"
- maturation_time = 4 MINUTES
- ///The radius of the passive structure camouflage, requires line of sight
- var/camouflage_range = 7
- ///The range of the active stealth ability, does not require line of sight
- var/active_camouflage_pulse_range = 10
- ///How long should veil last
- var/active_camouflage_duration = 20 SECONDS
- ///How long until the plant can be activated again
- var/cooldown = 2 MINUTES
- ///Is the active ability veil on cooldown ?
- var/on_cooldown = FALSE
- ///The list of passively camouflaged structures
- var/list/obj/structure/xeno/camouflaged_structures = list()
- ////The list of actively camouflaged xenos by veil
- var/list/mob/living/carbon/xenomorph/camouflaged_xenos = list()
-
-/obj/structure/xeno/plant/stealth_plant/on_mature(mob/user)
- . = ..()
- START_PROCESSING(SSslowprocess, src)
-
-/obj/structure/xeno/plant/stealth_plant/Destroy()
- for(var/obj/structure/xeno/xeno_struct AS in camouflaged_structures)
- xeno_struct.alpha = initial(xeno_struct.alpha)
- unveil()
- STOP_PROCESSING(SSslowprocess, src)
- return ..()
-
-/obj/structure/xeno/plant/stealth_plant/process()
- for(var/turf/tile AS in RANGE_TURFS(camouflage_range, loc))
- for(var/obj/structure/xeno/xeno_struct in tile)
- if(istype(xeno_struct, /obj/structure/xeno/plant) || !line_of_sight(src, xeno_struct)) //We don't hide plants
- continue
- camouflaged_structures.Add(xeno_struct)
- xeno_struct.alpha = STEALTH_PLANT_PASSIVE_CAMOUFLAGE_ALPHA
-
-/obj/structure/xeno/plant/stealth_plant/can_interact(mob/user)
- . = ..()
- if(!.)
- return FALSE
- if(ishuman(user))
- balloon_alert(user, "Nothing happens")
- to_chat(user, span_notice("You caress [src]'s petals, nothing happens."))
- return FALSE
- if(on_cooldown)
- balloon_alert(user, "Not ready yet")
- to_chat(user, span_xenowarning("[src] soft light shimmers, we should give it more time to recover!"))
- return FALSE
-
-/obj/structure/xeno/plant/stealth_plant/on_use(mob/user)
- balloon_alert(user, "Shaking...")
- if(!do_after(user, 2 SECONDS, IGNORE_HELD_ITEM, src))
- return FALSE
- visible_message(span_danger("[src] releases a burst of glowing pollen!"))
- veil()
- return TRUE
-
-///Hides all nearby xenos
-/obj/structure/xeno/plant/stealth_plant/proc/veil()
- for(var/turf/tile in RANGE_TURFS(camouflage_range, loc))
- for(var/mob/living/carbon/xenomorph/X in tile)
- if(X.stat == DEAD || isxenohunter(X) || X.alpha != 255) //We don't mess with xenos capable of going stealth by themselves
- continue
- X.alpha = HUNTER_STEALTH_RUN_ALPHA
- new /obj/effect/temp_visual/alien_fruit_eaten(get_turf(X))
- balloon_alert(X, "We now blend in")
- to_chat(X, span_xenowarning("The pollen from [src] reacts with our scales, we are blending with our surroundings!"))
- camouflaged_xenos.Add(X)
- on_cooldown = TRUE
- addtimer(CALLBACK(src, PROC_REF(unveil)), active_camouflage_duration)
- addtimer(CALLBACK(src, PROC_REF(ready)), cooldown)
-
-///Called when veil() can be used once again
-/obj/structure/xeno/plant/stealth_plant/proc/ready()
- visible_message(span_danger("[src] petals shift in hue, it is ready to release more pollen."))
- on_cooldown = FALSE
-
-///Reveals all xenos hidden by veil()
-/obj/structure/xeno/plant/stealth_plant/proc/unveil()
- for(var/mob/living/carbon/xenomorph/X AS in camouflaged_xenos)
- X.alpha = initial(X.alpha)
- balloon_alert(X, "Effect wears off")
- to_chat(X, span_xenowarning("The effect of [src] wears off!"))
-
-/obj/structure/xeno/thick_nest
- name = "thick resin nest"
- desc = "A very thick nest, oozing with a thick sticky substance."
- pixel_x = -8
- pixel_y = -8
- max_integrity = 400
- mouse_opacity = MOUSE_OPACITY_ICON
-
- icon = 'icons/Xeno/nest.dmi'
- icon_state = "reinforced_nest"
- layer = 2.5
-
- var/obj/structure/bed/nest/structure/pred_nest
-
-/obj/structure/xeno/thick_nest/examine(mob/user)
- . = ..()
- if((isxeno(user) || isobserver(user)) && hivenumber)
- . += "Used to secure formidable hosts."
-
-/obj/structure/xeno/thick_nest/Initialize(mapload, new_hivenumber)
- . = ..()
- if(new_hivenumber)
- hivenumber = new_hivenumber
-
- var/datum/hive_status/hive_ref = GLOB.hive_datums[hivenumber]
- if(hive_ref)
- hive_ref.thick_nests += src
-
- pred_nest = new /obj/structure/bed/nest/structure(loc, hive_ref, src) // Nest cannot be destroyed unless the structure itself is destroyed
-
-
-/obj/structure/xeno/thick_nest/Destroy()
- . = ..()
-
- if(hivenumber)
- GLOB.hive_datums[hivenumber].thick_nests -= src
-
- pred_nest?.linked_structure = null
- QDEL_NULL(pred_nest)
-
-/obj/structure/bed/nest
- var/force_nest = FALSE
-
-/obj/structure/bed/nest/structure
- name = "thick alien nest"
- desc = "A very thick nest, oozing with a thick sticky substance."
- force_nest = TRUE
- var/obj/structure/xeno/thick_nest/linked_structure
-
-/obj/structure/bed/nest/structure/Initialize(mapload, hive, obj/structure/xeno/thick_nest/to_link)
- . = ..()
- if(to_link)
- linked_structure = to_link
- max_integrity = linked_structure.max_integrity
-
-/obj/structure/bed/nest/structure/Destroy()
- . = ..()
- if(linked_structure)
- linked_structure.pred_nest = null
- QDEL_NULL(linked_structure)
-
-/obj/structure/bed/nest/structure/attack_hand(mob/user)
- if(!isxeno(user))
- to_chat(user, span_notice("The sticky resin is too strong for you to do anything to this nest"))
- return FALSE
- . = ..()
diff --git a/code/modules/xenomorph/xeno_towers.dm b/code/modules/xenomorph/xeno_towers.dm
new file mode 100644
index 00000000000..79bddc688df
--- /dev/null
+++ b/code/modules/xenomorph/xeno_towers.dm
@@ -0,0 +1,117 @@
+/obj/structure/xeno/evotower
+ name = "evolution tower"
+ desc = "A sickly outcrop from the ground. It seems to ooze a strange chemical that shimmers and warps the ground around it."
+ icon = 'icons/Xeno/2x2building.dmi'
+ icon_state = "evotower"
+ bound_width = 64
+ bound_height = 64
+ obj_integrity = 600
+ max_integrity = 600
+ xeno_structure_flags = CRITICAL_STRUCTURE
+ ///boost amt to be added per tower per cycle
+ var/boost_amount = 0.2
+
+/obj/structure/xeno/evotower/Initialize(mapload, _hivenumber)
+ . = ..()
+ GLOB.hive_datums[hivenumber].evotowers += src
+ set_light(2, 2, LIGHT_COLOR_GREEN)
+ SSminimaps.add_marker(src, MINIMAP_FLAG_XENO, image('icons/UI_icons/map_blips.dmi', null, "tower"))
+
+/obj/structure/xeno/evotower/Destroy()
+ GLOB.hive_datums[hivenumber].evotowers -= src
+ return ..()
+
+/obj/structure/xeno/evotower/ex_act(severity)
+ take_damage(severity * 2.5, BRUTE, BOMB)
+
+/obj/structure/xeno/psychictower
+ name = "Psychic Relay"
+ desc = "A sickly outcrop from the ground. It seems to allow for more advanced growth of the Xenomorphs."
+ icon = 'icons/Xeno/2x2building.dmi'
+ icon_state = "maturitytower"
+ bound_width = 64
+ bound_height = 64
+ obj_integrity = 400
+ max_integrity = 400
+ xeno_structure_flags = CRITICAL_STRUCTURE
+
+/obj/structure/xeno/psychictower/Initialize(mapload, _hivenumber)
+ . = ..()
+ GLOB.hive_datums[hivenumber].psychictowers += src
+ set_light(2, 2, LIGHT_COLOR_GREEN)
+ SSminimaps.add_marker(src, MINIMAP_FLAG_XENO, image('icons/UI_icons/map_blips.dmi', null, "tower"))
+
+/obj/structure/xeno/psychictower/Destroy()
+ GLOB.hive_datums[hivenumber].psychictowers -= src
+ return ..()
+
+/obj/structure/xeno/psychictower/ex_act(severity)
+ take_damage(severity * 2.5, BRUTE, BOMB)
+
+/obj/structure/xeno/pherotower
+ name = "Pheromone tower"
+ desc = "A resin formation that looks like a small pillar. A faint, weird smell can be perceived from it."
+ icon = 'icons/Xeno/1x1building.dmi'
+ icon_state = "recoverytower"
+ bound_width = 32
+ bound_height = 32
+ obj_integrity = 400
+ max_integrity = 400
+ xeno_structure_flags = CRITICAL_STRUCTURE
+ ///The type of pheromone currently being emitted.
+ var/datum/aura_bearer/current_aura
+ ///Strength of pheromones given by this tower.
+ var/aura_strength = 5
+ ///Radius (in tiles) of the pheromones given by this tower.
+ var/aura_radius = 32
+
+/obj/structure/xeno/pherotower/Initialize(mapload, _hivenumber)
+ . = ..()
+ SSminimaps.add_marker(src, MINIMAP_FLAG_XENO, image('icons/UI_icons/map_blips.dmi', null, "phero", ABOVE_FLOAT_LAYER)) // RU TGMC edit - map blips
+ GLOB.hive_datums[hivenumber].pherotowers += src
+
+//Pheromone towers start off with recovery.
+ current_aura = SSaura.add_emitter(src, AURA_XENO_RECOVERY, aura_radius, aura_strength, -1, FACTION_XENO, hivenumber)
+ playsound(src, "alien_drool", 25)
+ update_icon()
+
+/obj/structure/xeno/pherotower/ex_act(severity)
+ take_damage(severity * 2.5, BRUTE, BOMB)
+
+/obj/structure/xeno/pherotower/Destroy()
+ GLOB.hive_datums[hivenumber].pherotowers -= src
+ return ..()
+
+// Clicking on the tower brings up a radial menu that allows you to select the type of pheromone that this tower will emit.
+/obj/structure/xeno/pherotower/attack_alien(mob/living/carbon/xenomorph/xeno_attacker, damage_amount = xeno_attacker.xeno_caste.melee_damage, damage_type = BRUTE, damage_flag = MELEE, effects = TRUE, armor_penetration = 0, isrightclick = FALSE)
+ var/phero_choice = show_radial_menu(xeno_attacker, src, GLOB.pheromone_images_list, radius = 35, require_near = TRUE)
+
+ if(!phero_choice)
+ return
+
+ QDEL_NULL(current_aura)
+ current_aura = SSaura.add_emitter(src, phero_choice, aura_radius, aura_strength, -1, FACTION_XENO, hivenumber)
+ balloon_alert(xeno_attacker, "[phero_choice]")
+ playsound(src, "alien_drool", 25)
+ update_icon()
+
+/obj/structure/xeno/pherotower/update_icon_state()
+ . = ..()
+ switch(current_aura.aura_types[1])
+ if(AURA_XENO_RECOVERY)
+ icon_state = "recoverytower"
+ set_light(2, 2, LIGHT_COLOR_BLUE)
+ if(AURA_XENO_WARDING)
+ icon_state = "wardingtower"
+ set_light(2, 2, LIGHT_COLOR_GREEN)
+ if(AURA_XENO_FRENZY)
+ icon_state = "frenzytower"
+ set_light(2, 2, LIGHT_COLOR_RED)
+
+/obj/structure/xeno/pherotower/crash
+ name = "Recovery tower"
+ resistance_flags = RESIST_ALL
+ xeno_structure_flags = IGNORE_WEED_REMOVAL | CRITICAL_STRUCTURE
+
+/obj/structure/xeno/pherotower/crash/attack_alien(isrightclick = FALSE)
+ return
diff --git a/tgmc.dme b/tgmc.dme
index 000182fbbc5..d27df1bceab 100644
--- a/tgmc.dme
+++ b/tgmc.dme
@@ -2084,7 +2084,16 @@
#include "code\modules\vehicles\unmanned\unmanned_turrets.dm"
#include "code\modules\vehicles\unmanned\unmanned_vehicle.dm"
#include "code\modules\vehicles\unmanned\unmanned_vehicle_remote.dm"
-#include "code\modules\xenomorph\xeno_structures.dm"
+#include "code\modules\xenomorph\_xeno_structure.dm"
+#include "code\modules\xenomorph\acidwell.dm"
+#include "code\modules\xenomorph\jellypod.dm"
+#include "code\modules\xenomorph\nest.dm"
+#include "code\modules\xenomorph\plant.dm"
+#include "code\modules\xenomorph\silo.dm"
+#include "code\modules\xenomorph\trap.dm"
+#include "code\modules\xenomorph\tunnel.dm"
+#include "code\modules\xenomorph\turret.dm"
+#include "code\modules\xenomorph\xeno_towers.dm"
#include "code\ze_genesis_call\genesis_call.dm"
#include "interface\interface.dm"
#include "interface\menu.dm"
From 0936eba463cfe0071c6f1572f61e1c68fc836661 Mon Sep 17 00:00:00 2001
From: "github-actions[bot]"
<41898282+github-actions[bot]@users.noreply.github.com>
Date: Fri, 26 Jul 2024 06:39:00 +0000
Subject: [PATCH 02/10] Automatic changelog for PR #35 [ci skip]
---
html/changelogs/AutoChangeLog-pr-35.yml | 4 ++++
1 file changed, 4 insertions(+)
create mode 100644 html/changelogs/AutoChangeLog-pr-35.yml
diff --git a/html/changelogs/AutoChangeLog-pr-35.yml b/html/changelogs/AutoChangeLog-pr-35.yml
new file mode 100644
index 00000000000..5d98e85f8e2
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-35.yml
@@ -0,0 +1,4 @@
+author: "Helg2"
+delete-after: True
+changes:
+ - rscadd: "Туннели теперь используют миникарту для выбора места выхода."
\ No newline at end of file
From a821932d989209a8e51c5ac79d8b224c0e7017ad Mon Sep 17 00:00:00 2001
From: Helg2 <93882977+Helg2@users.noreply.github.com>
Date: Fri, 26 Jul 2024 09:40:01 +0300
Subject: [PATCH 03/10] Deletes mech duplicate files. (#37)
* cleaning
* Update mecha_wreckage.dm
---
_maps/map_files/BigRed_v2/BigRed_v2.dmm | 4 +-
.../jungle_outpost/jungle_outpost.dmm | 2 +-
.../map_files/Ice_Colony_v2/Ice_Colony_v2.dmm | 2 +-
_maps/map_files/LV624/LV624.dmm | 2 +-
.../Lawanka_Outpost/LawankaOutpost.dmm | 8 +-
_maps/map_files/slumbridge/slumbridge.dmm | 20 +-
.../modularmaps/big_red/bigredofficevar1.dmm | 2 +-
.../big_red/bigredsecornervar6.dmm | 2 +-
_maps/modularmaps/lv624/newcavevar2.dmm | 2 +-
code/game/mecha/mech_bay.dm | 15 --
code/game/mecha/mecha_parts.dm | 193 ------------------
code/game/mecha/mecha_wreckage.dm | 68 ------
code/modules/vehicles/mecha/mech_bay.dm | 1 -
code/modules/vehicles/mecha/mecha_parts.dm | 70 +++----
code/modules/vehicles/mecha/mecha_wreckage.dm | 15 +-
tgmc.dme | 3 -
16 files changed, 66 insertions(+), 343 deletions(-)
delete mode 100644 code/game/mecha/mech_bay.dm
delete mode 100644 code/game/mecha/mecha_parts.dm
delete mode 100644 code/game/mecha/mecha_wreckage.dm
diff --git a/_maps/map_files/BigRed_v2/BigRed_v2.dmm b/_maps/map_files/BigRed_v2/BigRed_v2.dmm
index e871b0ea946..97bec5fc0f9 100644
--- a/_maps/map_files/BigRed_v2/BigRed_v2.dmm
+++ b/_maps/map_files/BigRed_v2/BigRed_v2.dmm
@@ -11576,7 +11576,7 @@
/turf/open/floor/freezer,
/area/bigredv2/caves/lambda_lab)
"kuf" = (
-/obj/mecha_wreckage/ripley,
+/obj/structure/mecha_wreckage/ripley,
/obj/effect/decal/cleanable/dirt,
/turf/open/floor,
/area/bigredv2/outside/cargo)
@@ -14405,7 +14405,7 @@
/turf/open/floor,
/area/bigredv2/outside/engineering)
"rlw" = (
-/obj/mecha_wreckage/seraph,
+/obj/structure/mecha_wreckage/seraph,
/turf/open/floor/tile/dark,
/area/bigredv2/outside/nanotrasen_lab/inside/garbledradio)
"rlA" = (
diff --git a/_maps/map_files/Campaign maps/jungle_outpost/jungle_outpost.dmm b/_maps/map_files/Campaign maps/jungle_outpost/jungle_outpost.dmm
index 5801f153312..5613659a4d0 100644
--- a/_maps/map_files/Campaign maps/jungle_outpost/jungle_outpost.dmm
+++ b/_maps/map_files/Campaign maps/jungle_outpost/jungle_outpost.dmm
@@ -8809,7 +8809,7 @@
/turf/open/floor/plating/ground/concrete,
/area/campaign/jungle_outpost/outpost/req/depot)
"Mc" = (
-/obj/mecha_wreckage/durand,
+/obj/structure/mecha_wreckage/durand,
/turf/open/floor/tile/purple/whitepurple{
dir = 1
},
diff --git a/_maps/map_files/Ice_Colony_v2/Ice_Colony_v2.dmm b/_maps/map_files/Ice_Colony_v2/Ice_Colony_v2.dmm
index 75f42e19bdb..97711c78dfc 100644
--- a/_maps/map_files/Ice_Colony_v2/Ice_Colony_v2.dmm
+++ b/_maps/map_files/Ice_Colony_v2/Ice_Colony_v2.dmm
@@ -32238,7 +32238,7 @@
},
/area/ice_colony/underground/medical/lobby/garbledradio)
"woG" = (
-/obj/mecha_wreckage/ripley,
+/obj/structure/mecha_wreckage/ripley,
/turf/open/floor/plating/ground/snow/layer0,
/area/ice_colony/exterior/surface/valley/south)
"woW" = (
diff --git a/_maps/map_files/LV624/LV624.dmm b/_maps/map_files/LV624/LV624.dmm
index c1525df8876..e9dc0feca5f 100644
--- a/_maps/map_files/LV624/LV624.dmm
+++ b/_maps/map_files/LV624/LV624.dmm
@@ -8878,7 +8878,7 @@
},
/area/lv624/lazarus/hydroponics/aux)
"iud" = (
-/obj/mecha_wreckage/ripley/lv624,
+/obj/structure/mecha_wreckage/ripley/lv624,
/turf/open/floor/plating/ground/dirt,
/area/lv624/ground/sand4)
"iuM" = (
diff --git a/_maps/map_files/Lawanka_Outpost/LawankaOutpost.dmm b/_maps/map_files/Lawanka_Outpost/LawankaOutpost.dmm
index 6103aed710f..2c9bab5c93e 100644
--- a/_maps/map_files/Lawanka_Outpost/LawankaOutpost.dmm
+++ b/_maps/map_files/Lawanka_Outpost/LawankaOutpost.dmm
@@ -14953,7 +14953,7 @@
},
/area/shuttle/drop1/lz1)
"mMn" = (
-/obj/mecha_wreckage/ripley,
+/obj/structure/mecha_wreckage/ripley,
/turf/open/floor/mech_bay_recharge_floor,
/area/lawankaoutpost/colony/cargo)
"mMH" = (
@@ -25824,7 +25824,7 @@
/turf/open/floor/tile/red/whitered,
/area/lawankaoutpost/colony/medbay)
"vJJ" = (
-/obj/mecha_wreckage/ripley,
+/obj/structure/mecha_wreckage/ripley,
/turf/open/floor/mech_bay_recharge_floor,
/area/lawankaoutpost/colony/mining)
"vJM" = (
@@ -26621,7 +26621,7 @@
},
/area/shuttle/drop1/lz1)
"wns" = (
-/obj/mecha_wreckage/phazon,
+/obj/structure/mecha_wreckage/phazon,
/turf/open/floor/mech_bay_recharge_floor,
/area/lawankaoutpost/colony/robotics)
"wnM" = (
@@ -28029,7 +28029,7 @@
/turf/open/ground/grass/weedable,
/area/lawankaoutpost/outside/south)
"xxH" = (
-/obj/mecha_wreckage/seraph,
+/obj/structure/mecha_wreckage/seraph,
/turf/open/floor/tile/dark/yellow2{
dir = 1
},
diff --git a/_maps/map_files/slumbridge/slumbridge.dmm b/_maps/map_files/slumbridge/slumbridge.dmm
index 76618408d74..15694d432f9 100644
--- a/_maps/map_files/slumbridge/slumbridge.dmm
+++ b/_maps/map_files/slumbridge/slumbridge.dmm
@@ -638,7 +638,7 @@
},
/area/slumbridge/inside/sombase/west)
"aCj" = (
-/obj/mecha_wreckage/ripley/firefighter,
+/obj/structure/mecha_wreckage/ripley/firefighter,
/turf/open/floor/plating/ground/concrete,
/area/slumbridge/outside/southwest)
"aCG" = (
@@ -3645,7 +3645,7 @@
/turf/open/floor/plating,
/area/slumbridge/inside/colony/pharmacy)
"cIm" = (
-/obj/mecha_wreckage/ripley/lv624,
+/obj/structure/mecha_wreckage/ripley/lv624,
/turf/open/floor/plating/ground/concrete/edge,
/area/slumbridge/outside/southwest)
"cIK" = (
@@ -5080,7 +5080,7 @@
/turf/open/ground/grass/weedable,
/area/slumbridge/outside/southeast)
"dQp" = (
-/obj/mecha_wreckage/ripley/lv624,
+/obj/structure/mecha_wreckage/ripley/lv624,
/turf/open/floor/plating/ground/concrete,
/area/slumbridge/outside/southwest)
"dQz" = (
@@ -5358,7 +5358,7 @@
/turf/open/floor/tile/green,
/area/slumbridge/inside/houses/recreational)
"dYX" = (
-/obj/mecha_wreckage/seraph,
+/obj/structure/mecha_wreckage/seraph,
/turf/open/floor/plating/platebotc,
/area/slumbridge/inside/engi/south)
"dZj" = (
@@ -5623,7 +5623,7 @@
/turf/open/floor/plating/ground/mars/random/cave,
/area/slumbridge/caves/mining)
"emS" = (
-/obj/mecha_wreckage/durand,
+/obj/structure/mecha_wreckage/durand,
/turf/open/floor/plating/platebotc,
/area/slumbridge/inside/engi/south)
"enk" = (
@@ -6400,7 +6400,7 @@
},
/area/slumbridge/inside/zeta/south)
"eVa" = (
-/obj/mecha_wreckage/mauler,
+/obj/structure/mecha_wreckage/mauler,
/turf/open/floor/plating/platebotc,
/area/slumbridge/inside/engi/south)
"eVd" = (
@@ -21882,7 +21882,7 @@
},
/area/slumbridge/inside/prison/outerringsouth)
"qkn" = (
-/obj/mecha_wreckage/ripley/lv624,
+/obj/structure/mecha_wreckage/ripley/lv624,
/turf/open/floor/plating/ground/concrete/edge{
dir = 4
},
@@ -26508,7 +26508,7 @@
/turf/open/floor/plating,
/area/slumbridge/inside/pmcdome)
"tBA" = (
-/obj/mecha_wreckage/gygax,
+/obj/structure/mecha_wreckage/gygax,
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/plating/platebotc,
/area/slumbridge/inside/engi/south)
@@ -31334,7 +31334,7 @@
/turf/open/floor/tile/showroom,
/area/slumbridge/inside/engi/west)
"xbI" = (
-/obj/mecha_wreckage/marauder,
+/obj/structure/mecha_wreckage/marauder,
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/plating/platebotc,
/area/slumbridge/inside/engi/south)
@@ -32293,7 +32293,7 @@
/turf/open/floor/plating,
/area/slumbridge/inside/colony/kitchen)
"xQE" = (
-/obj/mecha_wreckage/ripley,
+/obj/structure/mecha_wreckage/ripley,
/turf/open/floor/tile/dark,
/area/slumbridge/inside/colony/construction)
"xQF" = (
diff --git a/_maps/modularmaps/big_red/bigredofficevar1.dmm b/_maps/modularmaps/big_red/bigredofficevar1.dmm
index bf715e87322..31051a36a87 100644
--- a/_maps/modularmaps/big_red/bigredofficevar1.dmm
+++ b/_maps/modularmaps/big_red/bigredofficevar1.dmm
@@ -495,7 +495,7 @@
/turf/open/floor,
/area/bigredv2/outside/office_complex)
"vR" = (
-/obj/mecha_wreckage/ripley/firefighter,
+/obj/structure/mecha_wreckage/ripley/firefighter,
/turf/open/floor/mech_bay_recharge_floor,
/area/bigredv2/outside/office_complex)
"vU" = (
diff --git a/_maps/modularmaps/big_red/bigredsecornervar6.dmm b/_maps/modularmaps/big_red/bigredsecornervar6.dmm
index e8804fc2a3c..797f79cfe98 100644
--- a/_maps/modularmaps/big_red/bigredsecornervar6.dmm
+++ b/_maps/modularmaps/big_red/bigredsecornervar6.dmm
@@ -388,7 +388,7 @@
/area/bigredv2/caves/secomplex)
"wO" = (
/obj/effect/decal/cleanable/cobweb,
-/obj/mecha_wreckage/ripley/lv624,
+/obj/structure/mecha_wreckage/ripley/lv624,
/turf/open/floor/tile/dark,
/area/bigredv2/caves/secomplex)
"xa" = (
diff --git a/_maps/modularmaps/lv624/newcavevar2.dmm b/_maps/modularmaps/lv624/newcavevar2.dmm
index 73fdda5c6e4..e26c863b251 100644
--- a/_maps/modularmaps/lv624/newcavevar2.dmm
+++ b/_maps/modularmaps/lv624/newcavevar2.dmm
@@ -18,7 +18,7 @@
/area/lv624/ground/caves/central2)
"cu" = (
/obj/item/mecha_parts/part/durand_head,
-/obj/mecha_wreckage/durand,
+/obj/structure/mecha_wreckage/durand,
/turf/open/floor/plating/ground/dirt,
/area/lv624/ground/caves/central2)
"cQ" = (
diff --git a/code/game/mecha/mech_bay.dm b/code/game/mecha/mech_bay.dm
deleted file mode 100644
index 13f35958931..00000000000
--- a/code/game/mecha/mech_bay.dm
+++ /dev/null
@@ -1,15 +0,0 @@
-
-
-/obj/machinery/mech_bay_recharge_port
- name = "Mech Bay Power Port"
- density = TRUE
- anchored = TRUE
- icon = 'icons/mecha/mech_bay.dmi'
- icon_state = "recharge_port"
-
-/obj/machinery/computer/mech_bay_power_console
- name = "Mech Bay Power Control Console"
- density = TRUE
- anchored = TRUE
- icon = 'icons/obj/machines/computer.dmi'
- icon_state = "recharge_comp"
diff --git a/code/game/mecha/mecha_parts.dm b/code/game/mecha/mecha_parts.dm
deleted file mode 100644
index c5758bdb004..00000000000
--- a/code/game/mecha/mecha_parts.dm
+++ /dev/null
@@ -1,193 +0,0 @@
-/////////////////////////
-////// Mecha Parts //////
-/////////////////////////
-
-/obj/item/mecha_parts
- name = "mecha part"
- icon = 'icons/mecha/mech_construct.dmi'
- icon_state = "blank"
- w_class = WEIGHT_CLASS_HUGE
-
-
-/obj/item/mecha_parts/chassis
- name="Mecha Chassis"
- icon_state = "backbone"
-
-
-/////////// Ripley
-
-/obj/item/mecha_parts/chassis/ripley
- name = "Ripley Chassis"
-
-
-/obj/item/mecha_parts/part/ripley_torso
- name="Ripley Torso"
- desc="A torso part of Ripley APLU. Contains power unit, processing core and life support systems."
- icon_state = "ripley_harness"
-
-/obj/item/mecha_parts/part/ripley_left_arm
- name="Ripley Left Arm"
- desc="A Ripley APLU left arm. Data and power sockets are compatible with most exosuit tools."
- icon_state = "ripley_l_arm"
-
-/obj/item/mecha_parts/part/ripley_right_arm
- name="Ripley Right Arm"
- desc="A Ripley APLU right arm. Data and power sockets are compatible with most exosuit tools."
- icon_state = "ripley_r_arm"
-
-/obj/item/mecha_parts/part/ripley_left_leg
- name="Ripley Left Leg"
- desc="A Ripley APLU left leg. Contains somewhat complex servodrives and balance maintaining systems."
- icon_state = "ripley_l_leg"
-
-/obj/item/mecha_parts/part/ripley_right_leg
- name="Ripley Right Leg"
- desc="A Ripley APLU right leg. Contains somewhat complex servodrives and balance maintaining systems."
- icon_state = "ripley_r_leg"
-
-///////// Gygax
-
-/obj/item/mecha_parts/chassis/gygax
- name = "Gygax Chassis"
-
-/obj/item/mecha_parts/part/gygax_torso
- name="Gygax Torso"
- desc="A torso part of Gygax. Contains power unit, processing core and life support systems. Has an additional equipment slot."
- icon_state = "gygax_harness"
-
-/obj/item/mecha_parts/part/gygax_head
- name="Gygax Head"
- desc="A Gygax head. Houses advanced surveilance and targeting sensors."
- icon_state = "gygax_head"
-
-/obj/item/mecha_parts/part/gygax_left_arm
- name="Gygax Left Arm"
- desc="A Gygax left arm. Data and power sockets are compatible with most exosuit tools and weapons."
- icon_state = "gygax_l_arm"
-
-/obj/item/mecha_parts/part/gygax_right_arm
- name="Gygax Right Arm"
- desc="A Gygax right arm. Data and power sockets are compatible with most exosuit tools and weapons."
- icon_state = "gygax_r_arm"
-
-/obj/item/mecha_parts/part/gygax_left_leg
- name="Gygax Left Leg"
- icon_state = "gygax_l_leg"
-
-/obj/item/mecha_parts/part/gygax_right_leg
- name="Gygax Right Leg"
- icon_state = "gygax_r_leg"
-
-/obj/item/mecha_parts/part/gygax_armour
- name="Gygax Armour Plates"
- icon_state = "gygax_armour"
-
-
-//////////// Durand
-
-/obj/item/mecha_parts/chassis/durand
- name = "Durand Chassis"
-
-
-/obj/item/mecha_parts/part/durand_torso
- name="Durand Torso"
- icon_state = "durand_harness"
-
-/obj/item/mecha_parts/part/durand_head
- name="Durand Head"
- icon_state = "durand_head"
-
-/obj/item/mecha_parts/part/durand_left_arm
- name="Durand Left Arm"
- icon_state = "durand_l_arm"
-
-/obj/item/mecha_parts/part/durand_right_arm
- name="Durand Right Arm"
- icon_state = "durand_r_arm"
-
-/obj/item/mecha_parts/part/durand_left_leg
- name="Durand Left Leg"
- icon_state = "durand_l_leg"
-
-/obj/item/mecha_parts/part/durand_right_leg
- name="Durand Right Leg"
- icon_state = "durand_r_leg"
-
-/obj/item/mecha_parts/part/durand_armour
- name="Durand Armour Plates"
- icon_state = "durand_armour"
-
-
-
-////////// Firefighter
-
-/obj/item/mecha_parts/chassis/firefighter
- name = "Firefighter Chassis"
-
-
-////////// Phazon
-
-/obj/item/mecha_parts/chassis/phazon
- name = "Phazon Chassis"
-
-/obj/item/mecha_parts/part/phazon_torso
- name="Phazon Torso"
- icon_state = "phazon_harness"
-
-/obj/item/mecha_parts/part/phazon_head
- name="Phazon Head"
- icon_state = "phazon_head"
-
-/obj/item/mecha_parts/part/phazon_left_arm
- name="Phazon Left Arm"
- icon_state = "phazon_l_arm"
-
-/obj/item/mecha_parts/part/phazon_right_arm
- name="Phazon Right Arm"
- icon_state = "phazon_r_arm"
-
-/obj/item/mecha_parts/part/phazon_left_leg
- name="Phazon Left Leg"
- icon_state = "phazon_l_leg"
-
-/obj/item/mecha_parts/part/phazon_right_leg
- name="Phazon Right Leg"
- icon_state = "phazon_r_leg"
-
-///////// Odysseus
-
-
-/obj/item/mecha_parts/chassis/odysseus
- name = "Odysseus Chassis"
-
-/obj/item/mecha_parts/part/odysseus_head
- name="Odysseus Head"
- icon_state = "odysseus_head"
-
-/obj/item/mecha_parts/part/odysseus_torso
- name="Odysseus Torso"
- desc="A torso part of Odysseus. Contains power unit, processing core and life support systems."
- icon_state = "odysseus_torso"
-
-/obj/item/mecha_parts/part/odysseus_left_arm
- name="Odysseus Left Arm"
- desc="An Odysseus left arm. Data and power sockets are compatible with most exosuit tools."
- icon_state = "odysseus_l_arm"
-
-/obj/item/mecha_parts/part/odysseus_right_arm
- name="Odysseus Right Arm"
- desc="An Odysseus right arm. Data and power sockets are compatible with most exosuit tools."
- icon_state = "odysseus_r_arm"
-
-/obj/item/mecha_parts/part/odysseus_left_leg
- name="Odysseus Left Leg"
- desc="An Odysseus left leg. Contains somewhat complex servodrives and balance maintaining systems."
- icon_state = "odysseus_l_leg"
-
-/obj/item/mecha_parts/part/odysseus_right_leg
- name="Odysseus Right Leg"
- desc="A Odysseus right leg. Contains somewhat complex servodrives and balance maintaining systems."
- icon_state = "odysseus_r_leg"
-
-
-
diff --git a/code/game/mecha/mecha_wreckage.dm b/code/game/mecha/mecha_wreckage.dm
deleted file mode 100644
index 09d35c6119f..00000000000
--- a/code/game/mecha/mecha_wreckage.dm
+++ /dev/null
@@ -1,68 +0,0 @@
-///////////////////////////////////
-//////// Mecha wreckage ////////
-///////////////////////////////////
-
-
-/obj/mecha_wreckage
- name = "Exosuit wreckage"
- desc = "Remains of some unfortunate mecha. There is nothing left to Salvage."
- icon = 'icons/mecha/mecha.dmi'
- hit_sound = 'sound/effects/metal_crash.ogg'
- density = TRUE
- anchored = FALSE
- opacity = FALSE
- resistance_flags = XENO_DAMAGEABLE
-
-
-/obj/mecha_wreckage/gygax
- name = "Gygax wreckage"
- icon_state = "gygax-broken"
-
-/obj/mecha_wreckage/gygax/dark
- name = "Dark Gygax wreckage"
- icon_state = "darkgygax-broken"
-
-/obj/mecha_wreckage/marauder
- name = "Marauder wreckage"
- icon_state = "marauder-broken"
-
-/obj/mecha_wreckage/mauler
- name = "Mauler Wreckage"
- icon_state = "mauler-broken"
- desc = "The syndicate won't be very happy about this..."
-
-/obj/mecha_wreckage/seraph
- name = "Seraph wreckage"
- icon_state = "seraph-broken"
-
-/obj/mecha_wreckage/ripley
- name = "Ripley wreckage"
- icon_state = "ripley-broken"
-
-/obj/mecha_wreckage/ripley/lv624
- name = "MkIV Powerloader Wreckage"
- anchored = TRUE
-
-/obj/mecha_wreckage/ripley/firefighter
- name = "Firefighter wreckage"
- icon_state = "firefighter-broken"
-
-/obj/mecha_wreckage/ripley/deathripley
- name = "Death-Ripley wreckage"
- icon_state = "deathripley-broken"
-
-/obj/mecha_wreckage/durand
- name = "Durand wreckage"
- icon_state = "durand-broken"
-
-/obj/mecha_wreckage/phazon
- name = "Phazon wreckage"
- icon_state = "phazon-broken"
-
-
-/obj/mecha_wreckage/odysseus
- name = "Odysseus wreckage"
-
-/obj/mecha_wreckage/hoverpod
- name = "Hover pod wreckage"
- icon_state = "engineering_pod-broken"
diff --git a/code/modules/vehicles/mecha/mech_bay.dm b/code/modules/vehicles/mecha/mech_bay.dm
index de5f7577e82..02171a40982 100644
--- a/code/modules/vehicles/mecha/mech_bay.dm
+++ b/code/modules/vehicles/mecha/mech_bay.dm
@@ -60,7 +60,6 @@
recharging_mech_ref = null
recharge_console.update_icon()
-
/obj/machinery/mech_bay_recharge_port/attackby(obj/item/I, mob/user, params)
if(default_change_direction_wrench(user, I))
recharging_turf = get_step(loc, dir)
diff --git a/code/modules/vehicles/mecha/mecha_parts.dm b/code/modules/vehicles/mecha/mecha_parts.dm
index 147a69d6a65..cda318519dd 100644
--- a/code/modules/vehicles/mecha/mecha_parts.dm
+++ b/code/modules/vehicles/mecha/mecha_parts.dm
@@ -1,7 +1,3 @@
-/////////////////////////
-////// Mecha Parts //////
-/////////////////////////
-
/obj/item/mecha_parts
name = "mecha part"
icon = 'icons/mecha/mech_construct.dmi'
@@ -52,6 +48,11 @@
desc = "A Ripley APLU right leg. Contains somewhat complex servodrives and balance maintaining systems."
icon_state = "ripley_r_leg"
+////////// Firefighter
+
+/obj/item/mecha_parts/chassis/firefighter
+ name = "\improper Firefighter Chassis"
+
///////// Odysseus
/obj/item/mecha_parts/chassis/odysseus
@@ -64,7 +65,7 @@
/obj/item/mecha_parts/part/odysseus_torso
name = "\improper Odysseus torso"
- desc="A torso part of Odysseus. Contains power unit, processing core and life support systems along with an attachment port for a mounted sleeper."
+ desc = "A torso part of Odysseus. Contains power unit, processing core and life support systems along with an attachment port for a mounted sleeper."
icon_state = "odysseus_torso"
/obj/item/mecha_parts/part/odysseus_left_arm
@@ -128,7 +129,6 @@
desc = "A set of armor plates designed for the Gygax. Designed to effectively deflect damage with a lightweight construction."
icon_state = "gygax_armor"
-
//////////// Durand
/obj/item/mecha_parts/chassis/durand
@@ -230,45 +230,44 @@
desc = "A H.O.N.K right leg. The foot appears just large enough to fully accommodate a clown shoe."
icon_state = "honker_r_leg"
-
////////// Phazon
/obj/item/mecha_parts/chassis/phazon
name = "\improper Phazon chassis"
/obj/item/mecha_parts/part/phazon_torso
- name="\improper Phazon torso"
- desc="A Phazon torso part. The socket for the bluespace core that powers the exosuit's unique phase drives is located in the middle."
+ name = "\improper Phazon torso"
+ desc = "A Phazon torso part. The socket for the bluespace core that powers the exosuit's unique phase drives is located in the middle."
icon_state = "phazon_harness"
/obj/item/mecha_parts/part/phazon_head
- name="\improper Phazon head"
- desc="A Phazon head. Its sensors are carefully calibrated to provide vision and data even when the exosuit is phasing."
+ name = "\improper Phazon head"
+ desc = "A Phazon head. Its sensors are carefully calibrated to provide vision and data even when the exosuit is phasing."
icon_state = "phazon_head"
/obj/item/mecha_parts/part/phazon_left_arm
- name="\improper Phazon left arm"
- desc="A Phazon left arm. Several microtool arrays are located under the armor plating, which can be adjusted to the situation at hand."
+ name = "\improper Phazon left arm"
+ desc = "A Phazon left arm. Several microtool arrays are located under the armor plating, which can be adjusted to the situation at hand."
icon_state = "phazon_l_arm"
/obj/item/mecha_parts/part/phazon_right_arm
- name="\improper Phazon right arm"
- desc="A Phazon right arm. Several microtool arrays are located under the armor plating, which can be adjusted to the situation at hand."
+ name = "\improper Phazon right arm"
+ desc = "A Phazon right arm. Several microtool arrays are located under the armor plating, which can be adjusted to the situation at hand."
icon_state = "phazon_r_arm"
/obj/item/mecha_parts/part/phazon_left_leg
- name="\improper Phazon left leg"
- desc="A Phazon left leg. It contains the unique phase drives that allow the exosuit to phase through solid matter when engaged."
+ name = "\improper Phazon left leg"
+ desc = "A Phazon left leg. It contains the unique phase drives that allow the exosuit to phase through solid matter when engaged."
icon_state = "phazon_l_leg"
/obj/item/mecha_parts/part/phazon_right_leg
- name="\improper Phazon right leg"
- desc="A Phazon right leg. It contains the unique phase drives that allow the exosuit to phase through solid matter when engaged."
+ name = "\improper Phazon right leg"
+ desc = "A Phazon right leg. It contains the unique phase drives that allow the exosuit to phase through solid matter when engaged."
icon_state = "phazon_r_leg"
/obj/item/mecha_parts/part/phazon_armor
- name="Phazon armor"
- desc="Phazon armor plates. They are layered with plasma to protect the pilot from the stress of phasing and have unusual properties."
+ name = "Phazon armor"
+ desc = "Phazon armor plates. They are layered with plasma to protect the pilot from the stress of phasing and have unusual properties."
icon_state = "phazon_armor"
// Savannah-Ivanov
@@ -277,38 +276,38 @@
name = "\improper Savannah-Ivanov chassis"
/obj/item/mecha_parts/part/savannah_ivanov_torso
- name="\improper Savannah-Ivanov torso"
- desc="A Savannah-Ivanov torso part. It's missing a huge chunk of space..."
+ name = "\improper Savannah-Ivanov torso"
+ desc = "A Savannah-Ivanov torso part. It's missing a huge chunk of space..."
icon_state = "savannah_ivanov_harness"
/obj/item/mecha_parts/part/savannah_ivanov_head
- name="\improper Savannah-Ivanov head"
- desc="A Savannah-Ivanov head. It's sensors have been adjusted to support graceful landings."
+ name = "\improper Savannah-Ivanov head"
+ desc = "A Savannah-Ivanov head. It's sensors have been adjusted to support graceful landings."
icon_state = "savannah_ivanov_head"
/obj/item/mecha_parts/part/savannah_ivanov_left_arm
- name="\improper Savannah-Ivanov left arm"
- desc="A Savannah-Ivanov left arm. Hidden rocket fabrication included in the wrists."
+ name = "\improper Savannah-Ivanov left arm"
+ desc = "A Savannah-Ivanov left arm. Hidden rocket fabrication included in the wrists."
icon_state = "savannah_ivanov_l_arm"
/obj/item/mecha_parts/part/savannah_ivanov_right_arm
- name="\improper Savannah-Ivanov right arm"
- desc="A Savannah-Ivanov left arm. Hidden rocket fabrication included in the wrists."
+ name = "\improper Savannah-Ivanov right arm"
+ desc = "A Savannah-Ivanov left arm. Hidden rocket fabrication included in the wrists."
icon_state = "savannah_ivanov_r_arm"
/obj/item/mecha_parts/part/savannah_ivanov_left_leg
- name="\improper Savannah-Ivanov left leg"
- desc="A Savannah-Ivanov left leg. In production they were designed to carry more than two passengers, so the leaping functionality was added as to not waste potential."
+ name = "\improper Savannah-Ivanov left leg"
+ desc = "A Savannah-Ivanov left leg. In production they were designed to carry more than two passengers, so the leaping functionality was added as to not waste potential."
icon_state = "savannah_ivanov_l_leg"
/obj/item/mecha_parts/part/savannah_ivanov_right_leg
- name="\improper Savannah-Ivanov right leg"
- desc="A Savannah-Ivanov left leg. In production they were designed to carry more than two passengers, so the leaping functionality was added as to not waste potential."
+ name = "\improper Savannah-Ivanov right leg"
+ desc = "A Savannah-Ivanov left leg. In production they were designed to carry more than two passengers, so the leaping functionality was added as to not waste potential."
icon_state = "savannah_ivanov_r_leg"
/obj/item/mecha_parts/part/savannah_ivanov_armor
- name="Savannah-Ivanov armor"
- desc="Savannah-Ivanov armor plates. They are uniquely shaped and reinforced to deal with the stresses of two pilots, grandiose leaps, and missiles."
+ name = "Savannah-Ivanov armor"
+ desc = "Savannah-Ivanov armor plates. They are uniquely shaped and reinforced to deal with the stresses of two pilots, grandiose leaps, and missiles."
icon_state = "savannah_ivanov_armor"
///////// Circuitboards
@@ -331,7 +330,6 @@
name = "Ripley Central Control module (Exosuit Board)"
icon_state = "mainboard"
-
/obj/item/circuitboard/mecha/gygax/peripherals
name = "Gygax Peripherals Control module (Exosuit Board)"
icon_state = "mcontroller"
diff --git a/code/modules/vehicles/mecha/mecha_wreckage.dm b/code/modules/vehicles/mecha/mecha_wreckage.dm
index 3f5c3ddd6b4..0895922dece 100644
--- a/code/modules/vehicles/mecha/mecha_wreckage.dm
+++ b/code/modules/vehicles/mecha/mecha_wreckage.dm
@@ -1,15 +1,12 @@
-///////////////////////////////////
-//////// Mecha wreckage ////////
-///////////////////////////////////
-
-
/obj/structure/mecha_wreckage
name = "exosuit wreckage"
desc = "Remains of some unfortunate mecha. Completely irreparable, but perhaps something can be salvaged."
icon = 'icons/mecha/mecha.dmi'
+ hit_sound = 'sound/effects/metal_crash.ogg'
density = TRUE
anchored = FALSE
opacity = FALSE
+ resistance_flags = XENO_DAMAGEABLE
///list of welder-salvaged items that it can output
var/list/welder_salvage = list(/obj/item/stack/sheet/plasteel)
/// times we can salvage this mech
@@ -136,6 +133,14 @@
name = "\improper Ripley MK-II wreckage"
icon_state = "ripleymkii-broken"
+/obj/structure/mecha_wreckage/ripley/lv624
+ name = "MkIV Powerloader Wreckage"
+ anchored = TRUE
+
+/obj/structure/mecha_wreckage/ripley/firefighter
+ name = "Firefighter wreckage"
+ icon_state = "firefighter-broken"
+
/obj/structure/mecha_wreckage/clarke
name = "\improper Clarke wreckage"
icon_state = "clarke-broken"
diff --git a/tgmc.dme b/tgmc.dme
index d27df1bceab..a344780b902 100644
--- a/tgmc.dme
+++ b/tgmc.dme
@@ -642,9 +642,6 @@
#include "code\game\atoms\_atom.dm"
#include "code\game\atoms\atom_appearance.dm"
#include "code\game\atoms\atom_movable.dm"
-#include "code\game\mecha\mech_bay.dm"
-#include "code\game\mecha\mecha_parts.dm"
-#include "code\game\mecha\mecha_wreckage.dm"
#include "code\game\objects\empulse.dm"
#include "code\game\objects\explosion.dm"
#include "code\game\objects\explosion_recursive.dm"
From 2ca22856c8ab95296ccce06c6528d7f91cff7944 Mon Sep 17 00:00:00 2001
From: Helg2 <93882977+Helg2@users.noreply.github.com>
Date: Fri, 26 Jul 2024 09:40:51 +0300
Subject: [PATCH 04/10] Refactors and resprites robotic cradle. (#39)
* 15143
* 15427
* 15473
* Update robotic_cradle.dm
* fix
---
code/game/objects/machinery/robotic_cradle.dm | 372 ++++++++----------
icons/obj/machines/robotic_cradle.dmi | Bin 0 -> 775 bytes
tgmc.dme | 2 +-
3 files changed, 167 insertions(+), 207 deletions(-)
create mode 100644 icons/obj/machines/robotic_cradle.dmi
diff --git a/code/game/objects/machinery/robotic_cradle.dm b/code/game/objects/machinery/robotic_cradle.dm
index 8aa08fa9b80..523efb63df9 100644
--- a/code/game/objects/machinery/robotic_cradle.dm
+++ b/code/game/objects/machinery/robotic_cradle.dm
@@ -1,63 +1,56 @@
#define CRADLE_NOTICE_SUCCESS 1
#define CRADLE_NOTICE_DEATH 2
-#define CRADLE_NOTICE_NO_RECORD 3
-#define CRADLE_NOTICE_NO_POWER 4
-#define CRADLE_NOTICE_XENO_FUCKERY 5
-#define CRADLE_NOTICE_IDIOT_EJECT 6
-#define CRADLE_NOTICE_FORCE_EJECT 7
+#define CRADLE_NOTICE_NO_POWER 3
+#define CRADLE_NOTICE_XENO_FUCKERY 4
+#define CRADLE_NOTICE_EARLY_EJECT 5
//Cradle
/obj/machinery/robotic_cradle
name = "robotic cradle"
desc = "A highly experimental robotic maintenence machine using a bath of industrial nanomachines to quickly restore any robotic machine inserted."
- icon = 'icons/obj/objects.dmi'
- icon_state = "borgcharger0"
+ icon = 'icons/obj/machines/robotic_cradle.dmi'
+ icon_state = "robotic_cradle"
density = TRUE
max_integrity = 350
soft_armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 100, BOMB = 0, BIO = 100, FIRE = 30, ACID = 30)
- //This var is used to see if the machine is currently repairing or not.
- var/repairing = FALSE
- //This var is the reference used for the patient
- var/mob/living/carbon/human/occupant
-
//It uses power
use_power = ACTIVE_POWER_USE
idle_power_usage = 15
active_power_usage = 10000 // It rebuilds you from nothing...
-
- //This var is in reference to the radio the cradle uses to speak to the craw.
+ ///This var is used to see if the machine is currently repairing or not.
+ var/repairing = FALSE
+ ///This var is the reference used for the patient
+ var/mob/living/carbon/human/occupant
+ ///This var is in reference to the radio the cradle uses to speak to the crew
var/obj/item/radio/headset/mainship/doc/radio
+ ///This var is so we can call deltimer() it if we need to abort the operation early
+ var/operation_timer
/obj/machinery/robotic_cradle/Initialize(mapload)
. = ..()
radio = new(src)
/obj/machinery/robotic_cradle/Destroy()
- do_eject(forceeject = TRUE)
+ if(occupant)
+ visible_message("\The [src] malfunctions as it is destroyed mid-repair, ejecting [occupant] with unfinished repair wounds and showering them in debris.")
+ occupant.take_limb_damage(rand(30, 50),rand(30, 50))
+ remove_occupant()
if(radio)
QDEL_NULL(radio)
return ..()
/obj/machinery/robotic_cradle/update_icon_state()
- . = ..()
- if(machine_stat & NOPOWER)
- icon_state = "borgcharger0"
- return
- if(repairing)
- icon_state = "borgcharger1"
- return
- if(occupant)
- icon_state = "borgcharger1"
- return
- icon_state = "borgcharger0"
+ if(occupant && !(machine_stat & NOPOWER))
+ icon_state = "robotic_cradle_active"
+ return ..()
+ icon_state = "robotic_cradle"
/obj/machinery/robotic_cradle/power_change()
. = ..()
if(is_operational() || !occupant)
return
visible_message("[src] engages the safety override, ejecting the occupant.")
- repairing = FALSE
- go_out(CRADLE_NOTICE_NO_POWER)
+ perform_eject(CRADLE_NOTICE_NO_POWER)
/obj/machinery/robotic_cradle/process()
if(!occupant)
@@ -65,45 +58,22 @@
if(occupant.stat == DEAD)
say("Patient has expired.")
- repairing = FALSE
- go_out(CRADLE_NOTICE_DEATH)
+ perform_eject(CRADLE_NOTICE_DEATH)
return
if(!repairing)
return
-//This proc handles the actual repair once the timer is up, ejection of the healed robot and radio message of ejection.
-/obj/machinery/robotic_cradle/proc/repair_op()
- if(QDELETED(occupant) || occupant.stat == DEAD)
- if(!ishuman(occupant))
- stack_trace("Non-human occupant made its way into the autodoc: [occupant] | [occupant?.type].")
- visible_message("[src] buzzes.")
- go_out(CRADLE_NOTICE_DEATH) //kick them out too.
- return
-
- occupant.revive()
- visible_message("\The [src] clicks and opens up having finished the requested operations.")
- repairing = FALSE
- go_out(CRADLE_NOTICE_SUCCESS)
-
/obj/machinery/robotic_cradle/attack_alien(mob/living/carbon/xenomorph/xeno_attacker, damage_amount, damage_type, damage_flag, effects, armor_penetration, isrightclick)
if(!occupant)
to_chat(xeno_attacker, span_xenowarning("There is nothing of interest in there."))
return
if(xeno_attacker.status_flags & INCORPOREAL || xeno_attacker.do_actions)
return
- visible_message(span_warning("[xeno_attacker] begins to pry the [src]'s cover!"), 3)
- playsound(src,'sound/effects/metal_creaking.ogg', 25, 1)
- if(!do_after(xeno_attacker, 2 SECONDS))
- return
- playsound(loc, 'sound/effects/metal_creaking.ogg', 25, 1)
- go_out()
+ start_emergency_eject(xeno_attacker)
-//This proc acts as a heads up to the doctors/engineers about the patient exiting the cradle for whatever reason. Does not warn if the patient itself exits the cradle. it also wipes the memory of who the patient was and readies the cradle for a new patient.
-/obj/machinery/robotic_cradle/proc/go_out(notice_code = FALSE)
- if(!occupant)
- return
- occupant.forceMove(drop_location())
+///This proc acts as a heads up to the doctors/engineers about the patient exiting the cradle for whatever reason. Takes CRADLE_NOTICE defines as arguments
+/obj/machinery/robotic_cradle/proc/notify_about_eject(notice_code = FALSE)
var/reason = "Reason for discharge: Procedural completion."
switch(notice_code)
if(CRADLE_NOTICE_SUCCESS)
@@ -111,167 +81,168 @@
if(CRADLE_NOTICE_DEATH)
playsound(src, 'sound/machines/warning-buzzer.ogg', 50, FALSE)
reason = "Reason for discharge: Patient has expired."
- if(CRADLE_NOTICE_NO_RECORD)
- playsound(src, 'sound/machines/warning-buzzer.ogg', 50, FALSE)
- reason = "Reason for discharge: Medical records not detected. Alerting security advised."
if(CRADLE_NOTICE_NO_POWER)
playsound(src, 'sound/machines/warning-buzzer.ogg', 50, FALSE)
reason = "Reason for discharge: Power failure."
if(CRADLE_NOTICE_XENO_FUCKERY)
playsound(src, 'sound/machines/warning-buzzer.ogg', 50, FALSE)
reason = "Reason for discharge: Unauthorized manual release. Alerting security advised."
- if(CRADLE_NOTICE_IDIOT_EJECT)
- playsound(src, 'sound/machines/warning-buzzer.ogg', 50, FALSE)
- reason = "Reason for discharge: Unauthorized manual release during repair. Alerting security advised."
- if(CRADLE_NOTICE_FORCE_EJECT)
- playsound(src, 'sound/machines/warning-buzzer.ogg', 50, FALSE)
- reason = "Reason for discharge: Destruction of linked CRADLE Engineering System. Alerting security advised."
+ if(CRADLE_NOTICE_EARLY_EJECT)
+ playsound(src,'sound/machines/buzz-two.ogg', 50,FALSE)
+ reason = "Reason for discharge: Operation manually terminated by end user."
+ if(!radio)//The radio shouldn't ever be deleted, but this is a sanity check just in case
+ return
radio.talk_into(src, "Patient: [occupant] has been released from [src] at: [get_area(src)]. [reason]", RADIO_CHANNEL_MEDICAL)
+
+///Forces the occupant out of the cradle, leaves it empty for someone else to enter.
+/obj/machinery/robotic_cradle/proc/remove_occupant()
+ if(!occupant)
+ return
+ occupant.forceMove(drop_location())
occupant = null
update_icon()
stop_processing()
-//This proc is what a robot calls when they try to enter a cradle on their own.
-/obj/machinery/robotic_cradle/proc/move_inside_wrapper(mob/living/dropped, mob/dragger)
- if(dragger.incapacitated() || !ishuman(dragger) || !isrobot(dropped))
- return
-
+///Finishes ejecting the patient after the cradle is done. Takes CRADLE_NOTICE defines as arguments, used in notify_about_eject()
+/obj/machinery/robotic_cradle/proc/perform_eject(notice_code = FALSE)
+ repairing = FALSE
+ if(operation_timer)
+ deltimer(operation_timer)
+ notify_about_eject(notice_code)
+ remove_occupant()
+
+///Handles any mob placing themselves or someone else into the cradle. target_mob is the mob being placed in, operating_mob is the person placing the mob in. Returns true if the mob got placed inside, false otherwise
+/obj/machinery/robotic_cradle/proc/place_mob_inside(mob/living/target_mob, mob/operating_mob)
+ if(operating_mob.incapacitated()||!ishuman(operating_mob)||!ishuman(target_mob))
+ return FALSE
if(occupant)
- to_chat(dragger, span_notice("[src] is already occupied!"))
- return
-
+ to_chat(operating_mob, span_notice("[src] is already occupied!"))
+ return FALSE
+ var/mob/living/carbon/human/patient = target_mob
+ if(!(patient.species.species_flags & ROBOTIC_LIMBS))
+ visible_message(span_warning("[src] buzzes. Subject is biological, cannot repair."))
+ playsound(src, 'sound/machines/buzz-two.ogg', 50, FALSE)
+ return FALSE
+ if(patient.abiotic())
+ visible_message(span_warning("[src] buzzes. Subject cannot wear abiotic items."))
+ playsound(src, 'sound/machines/buzz-two.ogg', 50, FALSE)
+ return FALSE
if(machine_stat & (NOPOWER|BROKEN))
- to_chat(dragger, span_notice("[src] is non-functional!"))
+ to_chat(operating_mob, span_notice("[src] is non-functional!"))
+ return FALSE
+
+ if(operating_mob == patient)
+ patient.visible_message(span_notice("[patient] starts climbing into \the [src]."),
+ span_notice("You start climbing into \the [src]."))
+ else
+ operating_mob.visible_message(span_notice("[operating_mob] starts placing [patient] \the [src]."),
+ span_notice("You start placing [patient] into \the [src]."))
+
+ if(!do_after(operating_mob, 1 SECONDS, IGNORE_HELD_ITEM, src, BUSY_ICON_GENERIC))
+ return FALSE
+ if(occupant) //In case someone tried climbing in earlier than us, while the cradle was empty
+ to_chat(operating_mob, span_notice("[src] is already occupied!"))
+ return FALSE
+ patient.stop_pulling()
+ patient.forceMove(src)
+ occupant = patient
+ return TRUE
+///Starts the repair operation of the cradle
+/obj/machinery/robotic_cradle/proc/start_repair_operation()
+ if(!occupant)
return
- if(dragger.skills.getRating(SKILL_ENGINEER) < SKILL_ENGINEER_ENGI)
- dropped.visible_message(span_notice("[dropped] fumbles around figuring out how to get into \the [src]."),
- span_notice("You fumble around figuring out how to get into \the [src]."))
- var/fumbling_time = max(0 , SKILL_TASK_TOUGH - ( SKILL_TASK_EASY * dragger.skills.getRating(SKILL_ENGINEER) ))// 8 secs non-trained, 5 amateur
- if(!do_after(dropped, fumbling_time, NONE, src, BUSY_ICON_UNSKILLED))
- return
-
- dropped.visible_message(span_notice("[dropped] starts climbing into \the [src]."),
- span_notice("You start climbing into \the [src]."))
- if(!do_after(dropped, 1 SECONDS, IGNORE_HELD_ITEM, src, BUSY_ICON_GENERIC))
+ if(powered())
+ use_power(active_power_usage)
+ playsound(loc, 'sound/machines/ping.ogg', 25, 1)
+ else
+ perform_eject(CRADLE_NOTICE_NO_POWER)
return
- if(occupant)
- to_chat(dragger, span_notice("[src] is already occupied!"))
- return
- dropped.stop_pulling()
- dropped.forceMove(src)
- occupant = dropped
- icon_state = "pod_0"
- var/implants = list(/obj/item/implant/neurostim)
- var/mob/living/carbon/human/H = occupant
- var/doc_dat
- med_scan(H, doc_dat, implants, TRUE)
- start_processing()
- say("Automatic mode engaged, initialising procedure.")
- addtimer(CALLBACK(src, PROC_REF(auto_start)), 20 SECONDS)
-
-///Callback to start auto mode on someone entering
-/obj/machinery/robotic_cradle/proc/auto_start()
- if(repairing)
+ start_processing()
+ update_icon()
+ repairing = TRUE
+ say("Automatic mode engaged, initialising repair procedure.")
+ operation_timer = addtimer(CALLBACK(src, PROC_REF(handle_repair_operation)), 20 SECONDS,TIMER_STOPPABLE)
+
+///Callback to start repair on someone entering the cradle
+/obj/machinery/robotic_cradle/proc/handle_repair_operation()
+ if(!occupant) //sanity check, in case we get teleported outside the cradle midrepair without calling perform_eject()
+ if(operation_timer)
+ deltimer(operation_timer)
+ repairing = FALSE
+ visible_message(span_warning("[src] buzzes. Occupant missing, procedures canceled."))
+ playsound(src, 'sound/machines/buzz-two.ogg', 50, FALSE)
return
+ say("Repair procedure complete.")
+ perform_repair()
+
+///This proc handles the actual repair once the timer is up and ejects the healed robot.
+/obj/machinery/robotic_cradle/proc/perform_repair()
if(!occupant)
- say("Occupant missing, procedures canceled.")
return
- say("Beginning repair procedure.")
- repair_op()
+ if(QDELETED(occupant) || occupant.stat == DEAD)
+ if(!ishuman(occupant))
+ stack_trace("Non-human occupant made its way into the autodoc: [occupant] | [occupant?.type].")
+ visible_message(span_warning("[src] buzzes."))
+ perform_eject(CRADLE_NOTICE_DEATH)
+ return
+ occupant.revive()
+ visible_message("\The [src] clicks and opens up having finished the requested operations.")
+ perform_eject(CRADLE_NOTICE_SUCCESS)
-/obj/machinery/robotic_cradle/MouseDrop_T(mob/M, mob/user)
+/obj/machinery/robotic_cradle/MouseDrop_T(mob/dropping, mob/user)
. = ..()
- move_inside_wrapper(M, user)
+ if(place_mob_inside(dropping, user))
+ start_repair_operation()
/obj/machinery/robotic_cradle/verb/move_inside()
set name = "Enter Cradle"
set category = "Object"
set src in oview(1)
- move_inside_wrapper(usr, usr)
+ if(place_mob_inside(usr, usr))
+ start_repair_operation()
-//This proc is called when someone has a robot grabbed either by hand or in a stasis bag. It is also lets docs/engineers use health analyzers on the cradle if they really want to.
/obj/machinery/robotic_cradle/attackby(obj/item/I, mob/user, params)
. = ..()
-
- if(!ishuman(user))
- return //no
+ if(.)
+ return
if(istype(I, /obj/item/healthanalyzer) && occupant) //Allows us to use the analyzer on the occupant without taking him out.
var/obj/item/healthanalyzer/J = I
J.attack(occupant, user)
return
- if(!istype(I, /obj/item/grab))
+/obj/machinery/robotic_cradle/attack_hand(mob/living/user)
+ . = ..()
+ if(user.do_actions) //stops them from spamming if they're attempting to eject someone or otherwise busy
return
-
- if(machine_stat & (NOPOWER|BROKEN))
- to_chat(user, span_notice("[src] is non-functional!"))
+ if(!occupant)
return
+ start_emergency_eject(user)
- if(occupant)
- to_chat(user, span_notice("[src] is already occupied!"))
+/obj/machinery/robotic_cradle/grab_interact(obj/item/grab/grab, mob/user, base_damage = BASE_OBJ_SLAM_DAMAGE, is_sharp = FALSE)
+ . = ..()
+ if(.)
return
+ var/mob/grabbed_mob
- var/obj/item/grab/G = I
+ if(ismob(grab.grabbed_thing))
+ grabbed_mob = grab.grabbed_thing
- var/mob/M
- if(ismob(G.grabbed_thing))
- M = G.grabbed_thing
- else if(istype(G.grabbed_thing, /obj/structure/closet/bodybag/cryobag))
- var/obj/structure/closet/bodybag/cryobag/C = G.grabbed_thing
- if(!C.bodybag_occupant)
+ else if(istype(grab.grabbed_thing,/obj/structure/closet/bodybag/cryobag))
+ var/obj/structure/closet/bodybag/cryobag/cryobag = grab.grabbed_thing
+ if(!cryobag.bodybag_occupant)
to_chat(user, span_warning("The stasis bag is empty!"))
return
- M = C.bodybag_occupant
- C.open()
- user.start_pulling(M)
+ grabbed_mob = cryobag.bodybag_occupant
+ cryobag.open()
+ user.start_pulling(grabbed_mob)
- if(!M)
- return
-
- if(!ishuman(M)) // No monkee or beano
- to_chat(user, span_notice("[src] is compatible with humanoid anatomies only!"))
- return
-
- if(M.abiotic())
- to_chat(user, span_warning("Subject cannot have abiotic items on."))
- return
-
- if(ishumanbasic(M))
- to_chat(user, span_warning("Subject is biological, cannot repair."))
- return
-
- if(user.skills.getRating(SKILL_ENGINEER) < SKILL_ENGINEER_ENGI)
- user.visible_message(span_notice("[user] fumbles around figuring out how to put [M] into [src]."),
- span_notice("You fumble around figuring out how to put [M] into [src]."))
- var/fumbling_time = max(0 , SKILL_TASK_TOUGH - ( SKILL_TASK_EASY * user.skills.getRating(SKILL_ENGINEER) ))// 8 secs non-trained, 5 amateur
- if(!do_after(user, fumbling_time, NONE, M, BUSY_ICON_UNSKILLED) || QDELETED(src))
- return
-
- visible_message("[user] starts putting [M] into [src].", 3)
-
- if(!do_after(user, 10, IGNORE_HELD_ITEM, M, BUSY_ICON_GENERIC) || QDELETED(src))
- return
-
- if(occupant)
- to_chat(user, span_notice("[src] is already occupied!"))
- return
-
- if(!M || !G)
- return
-
- M.forceMove(src)
- occupant = M
- icon_state = "pod_1"
- var/implants = list(/obj/item/implant/neurostim)
- var/mob/living/carbon/human/H = occupant
- med_scan(H, null, implants, TRUE)
- start_processing()
- say("Automatic mode engaged, initialising procedure.")
- addtimer(CALLBACK(src, PROC_REF(auto_start)), 20 SECONDS)
+ if(place_mob_inside(grabbed_mob,user))
+ start_repair_operation()
+ return TRUE
/obj/machinery/robotic_cradle/verb/eject()
set name = "Eject cradle"
@@ -279,45 +250,34 @@
set src in oview(1)
if(usr.incapacitated())
return
- do_eject()
+ start_emergency_eject(usr)
-//This proc ejects whomever is inside the cradle, by force if needed depending if the cradle is destroyed or not.
-/obj/machinery/robotic_cradle/proc/do_eject(forceeject)
+///This proc ejects whomever is inside the cradle while it is presumably operating. mob_ejecting is the mob triggering the eject
+/obj/machinery/robotic_cradle/proc/start_emergency_eject(mob/mob_ejecting)
if(!occupant)
return
- if(forceeject)
- if(!repairing)
- visible_message("\The [src] is destroyed, ejecting [occupant] and showering them in debris.")
- occupant.take_limb_damage(rand(10,20),rand(10,20))
- else
- visible_message("\The [src] malfunctions as it is destroyed mid-repair, ejecting [occupant] with unfinished repair wounds and showering them in debris.")
- occupant.take_limb_damage(rand(30,50),rand(30,50))
- go_out(CRADLE_NOTICE_FORCE_EJECT)
- return
- if(isxeno(usr) && !repairing) // let xenos eject people hiding inside; a xeno ejecting someone during repair does so like someone untrained
- go_out(CRADLE_NOTICE_XENO_FUCKERY)
+ if(!repairing)//this shouldn't be possible unless you get var edited inside without triggering start_repair_operation(), in that case just get them out
+ remove_occupant()
return
- if(!ishuman(usr))
+ if(!mob_ejecting)
+ perform_eject(CRADLE_NOTICE_EARLY_EJECT)
return
- if(usr == occupant)
- if(repairing)
- to_chat(usr, span_warning("There's no way you're getting out while this thing is operating on you!"))
- return
- else
- visible_message("[usr] engages the internal release mechanism, and climbs out of \the [src].")
- if(usr.skills.getRating(SKILL_ENGINEER) < SKILL_ENGINEER_ENGI)
- usr.visible_message(span_notice("[usr] fumbles around figuring out how to use [src]."),
- span_notice("You fumble around figuring out how to use [src]."))
- var/fumbling_time = max(0 , SKILL_TASK_TOUGH - ( SKILL_TASK_EASY * usr.skills.getRating(SKILL_ENGINEER) ))// 8 secs non-trained, 5 amateur
- if(!do_after(usr, fumbling_time, NONE, src, BUSY_ICON_UNSKILLED) || !occupant)
+ if(isxeno(mob_ejecting))
+ mob_ejecting.visible_message(span_notice("[mob_ejecting] pries the cover of [src]"),
+ span_notice("You begin to pry at the cover of [src]."))
+ playsound(mob_ejecting,'sound/effects/metal_creaking.ogg', 25, 1)
+ if(!do_after(mob_ejecting, 2 SECONDS, NONE, src, BUSY_ICON_DANGER) || !occupant)
return
- if(repairing)
- repairing = 0
- if(usr.skills.getRating(SKILL_ENGINEER) < SKILL_ENGINEER_ENGI) //Untrained people will fail to terminate the repair properly.
- visible_message("\The [src] malfunctions as [usr] aborts the rapair in progress.")
- occupant.take_limb_damage(rand(30,50),rand(30,50))
- log_game("[key_name(usr)] ejected [key_name(occupant)] from the cradle during repair causing damage.")
- message_admins("[ADMIN_TPMONTY(usr)] ejected [ADMIN_TPMONTY(occupant)] from the cradle during repair causing damage.")
- go_out(CRADLE_NOTICE_IDIOT_EJECT)
- return
- go_out()
+ perform_eject(CRADLE_NOTICE_XENO_FUCKERY)
+ return
+ if(!ishuman(mob_ejecting))
+ return
+ if(mob_ejecting == occupant)
+ to_chat(usr, span_warning("There's no way you're getting out while this thing is operating on you!"))
+ return
+ perform_eject(CRADLE_NOTICE_EARLY_EJECT)
+
+#undef CRADLE_NOTICE_SUCCESS
+#undef CRADLE_NOTICE_DEATH
+#undef CRADLE_NOTICE_NO_POWER
+#undef CRADLE_NOTICE_EARLY_EJECT
diff --git a/icons/obj/machines/robotic_cradle.dmi b/icons/obj/machines/robotic_cradle.dmi
new file mode 100644
index 0000000000000000000000000000000000000000..47b9d94934762fb7f51c77d31c48fa196d5fe005
GIT binary patch
literal 775
zcmV+i1Ni)jP)y>HWkX0*BO@)(JxDq_Ix?*)+js-Nh%-t|
zRKUQ%elqo<00001bW%=J06^y0W&i*HiF#C6bVOxyV{&P5bZKvH004NLQ&wiFFDZeB$
zIX<~4F(oHeiHkEOv#1y-VaUaqR+N~V3Sr|=9-o+8l39jB7tqF()SSdhkg$P{A(yg(
ztDg(ljR2vsGFltA)GPo10pv+UK~z|UotE2zgCGn<5e>9!_hSG5V>eif31B9>^9CoK
zhKQYpaA;~28reL?IK^qM;stN{d5HU-DwyZ!=X=3CEmgee3@ly>h$vR^qBSu2UXbXV
z5HC6di-))@lu0PlvP3`M3wXDR7oCB{13wf>=~k5zA9!l`{iEvM@N!EiC!tL0t`xqe
zdsSK`-)~854bE>k_$v7-JJ@fDW$@zH1~Xrb@@R9GQ#uO}5ApFB4RNA|H$$wP3qA)&
z;Jz#WdL2Ox@#OD|fVU;@hFJMg(ER3g2G=}L`2k}r8hGuH;?Hx4PsIcK@v?bLWrs9>
zR%u>Jh6cgS0}bWpMd<&5Etvn%0Oh~Oz|4P#ft~*z12g}j0m^@mftmkEF#n-}ng6hV
zl>g8G12P^a~S`FE
Date: Fri, 26 Jul 2024 06:41:11 +0000
Subject: [PATCH 05/10] Automatic changelog for PR #39 [ci skip]
---
html/changelogs/AutoChangeLog-pr-39.yml | 8 ++++++++
1 file changed, 8 insertions(+)
create mode 100644 html/changelogs/AutoChangeLog-pr-39.yml
diff --git a/html/changelogs/AutoChangeLog-pr-39.yml b/html/changelogs/AutoChangeLog-pr-39.yml
new file mode 100644
index 00000000000..ffaac51cf8d
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-39.yml
@@ -0,0 +1,8 @@
+author: "Helg2"
+delete-after: True
+changes:
+ - refactor: "Ремонтная коробка для роботов была переделена по части кода."
+ - qol: "Теперь жертв коробки для роботов можно вытащить из неё одним кликом."
+ - balance: "У ремонтной коробки роботов удалены требования навыков."
+ - bugfix: "Синты теперь могут засунуть себя в ремонтную коробку для роботов."
+ - imageadd: "Ремонтная коробка для роботов теперь выглядит как зарядка для мод-сьютов с ТГ."
\ No newline at end of file
From 540a6ae2ffc52dec069f927404f406df8acc8f2c Mon Sep 17 00:00:00 2001
From: Helg2 <93882977+Helg2@users.noreply.github.com>
Date: Fri, 26 Jul 2024 09:41:49 +0300
Subject: [PATCH 06/10] Ports 14878, 15112, 15167 (#42)
* 15167
* 14878
* 15112
---
code/__DEFINES/conflict.dm | 13 -------
code/__DEFINES/mobs.dm | 34 +++++++------------
code/game/data_huds.dm | 1 -
.../mob/living/carbon/carbon_defines.dm | 4 +--
.../mob/living/carbon/human/update_icons.dm | 6 ----
.../mob/living/carbon/xenomorph/life.dm | 19 +++++------
.../living/carbon/xenomorph/update_icons.dm | 27 +++++++--------
.../living/carbon/xenomorph/xeno_defines.dm | 1 -
.../mob/living/carbon/xenomorph/xenomorph.dm | 2 +-
.../mob/living/carbon/xenomorph/xenoprocs.dm | 21 +++++++++---
.../modules/mob/living/living_health_procs.dm | 2 +-
.../modules/predator/yautja/weapons/ranged.dm | 25 ++------------
code/modules/projectiles/guns/specialist.dm | 13 ++-----
13 files changed, 58 insertions(+), 110 deletions(-)
diff --git a/code/__DEFINES/conflict.dm b/code/__DEFINES/conflict.dm
index e14f37260a9..c8fe6df2574 100644
--- a/code/__DEFINES/conflict.dm
+++ b/code/__DEFINES/conflict.dm
@@ -208,19 +208,6 @@
#define MAX_PARALYSE_AMOUNT_FOR_PARALYSE_RESISTANT 2 SECONDS
-//Xeno Overlays Indexes//////////
-#define X_PRED_LASER_LAYER 10
-#define X_LASER_LAYER 9
-#define X_WOUND_LAYER 8
-#define X_HEAD_LAYER 7
-#define X_SUIT_LAYER 6
-#define X_L_HAND_LAYER 5
-#define X_R_HAND_LAYER 4
-#define X_TARGETED_LAYER 3
-#define X_FIRE_LAYER 1
-#define X_TOTAL_LAYERS 10
-/////////////////////////////////
-
// No neighbors
#define NEIGHBORS_NONE 0
// Cardinal neighborhood
diff --git a/code/__DEFINES/mobs.dm b/code/__DEFINES/mobs.dm
index f1fcf9ce960..f057d3b856b 100644
--- a/code/__DEFINES/mobs.dm
+++ b/code/__DEFINES/mobs.dm
@@ -407,13 +407,14 @@ GLOBAL_LIST_INIT(xenoupgradetiers, list(XENO_UPGRADE_BASETYPE, XENO_UPGRADE_INVA
#define HUMAN_MAX_PALENESS 30 //this is added to human skin tone to get value of pale_max variable
-// Human Overlay Indexes
-/* RU TGMC EDIT
-#define LASER_LAYER 29 //For sniper targeting laser
-#define MOTH_WINGS_LAYER 28
-#define MUTATIONS_LAYER 27
-#define DAMAGE_LAYER 26
-RU TGMC EDIT */
+// Overlay Indexes
+#define PRED_LASER_LAYER 32
+#define LASER_LAYER 31
+#define WOUND_LAYER 30
+#define MOTH_WINGS_LAYER 29
+#define MUTATIONS_LAYER 28
+#define DAMAGE_LAYER 27
+#define FLAY_LAYER 26
#define UNIFORM_LAYER 25
#define TAIL_LAYER 24 //bs12 specific. this hack is probably gonna come back to haunt me
#define ID_LAYER 23
@@ -439,9 +440,9 @@ RU TGMC EDIT */
#define OVERHEALTH_SHIELD_LAYER 3
#define TARGETED_LAYER 2 //for target sprites when held at gun point, and holo cards.
#define FIRE_LAYER 1 //If you're on fire
-/* RU TGMC EDIT
-#define TOTAL_LAYERS 29
-RU TGMC EDIT */
+
+#define TOTAL_LAYERS 32
+
#define MOTH_WINGS_BEHIND_LAYER 1
#define TOTAL_UNDERLAYS 1
@@ -486,7 +487,6 @@ RU TGMC EDIT */
#define XENO_SLOWDOWN_REGEN 0.4
#define XENO_DEADHUMAN_DRAG_SLOWDOWN 2
-//#define XENO_EXPLOSION_GIB_THRESHOLD 0.95 //if your effective bomb armour is less than 5, devestating explosions will gib xenos //RUTGMC REMOVAL - Explosions
#define KING_SUMMON_TIMER_DURATION 5 MINUTES
@@ -595,7 +595,7 @@ RU TGMC EDIT */
#define RAVAGER_ENDURE_DURATION 10 SECONDS
#define RAVAGER_ENDURE_DURATION_WARNING 0.7
-#define RAVAGER_ENDURE_HP_LIMIT -125 //RUTGMC EDIT
+#define RAVAGER_ENDURE_HP_LIMIT -125
#define RAVAGER_RAGE_DURATION 10 SECONDS
#define RAVAGER_RAGE_WARNING 0.7
@@ -813,8 +813,6 @@ GLOBAL_LIST_INIT(human_body_parts, list(BODY_ZONE_HEAD,
#define GRAB_PIXEL_SHIFT_NECK 16
#define HUMAN_CARRY_SLOWDOWN 0.35
-//#define HUMAN_EXPLOSION_GIB_THRESHOLD 0.1 //RUTGMC DELETION, explosions
-
// =============================
// Hallucinations - health hud screws for carbon mobs
@@ -888,14 +886,6 @@ GLOBAL_LIST_INIT(human_body_parts, list(BODY_ZONE_HEAD,
///Default damage for slamming a mob against another mob
#define BASE_MOB_SLAM_DAMAGE 8
-#define MOTH_WINGS_LAYER 28
-#define MUTATIONS_LAYER 27
-#define DAMAGE_LAYER 26
-#define FLAY_LAYER 25
-#define PRED_LASER_LAYER 1.9
-#define LASER_LAYER 1.8
-#define TOTAL_LAYERS 30
-
// Yautja defines
//Gear select defines
diff --git a/code/game/data_huds.dm b/code/game/data_huds.dm
index 893b1c008fc..2a224b6e78e 100644
--- a/code/game/data_huds.dm
+++ b/code/game/data_huds.dm
@@ -114,7 +114,6 @@
return
/mob/living/carbon/xenomorph/med_hud_set_status()
- hud_set_plasma()
hud_set_pheromone()
/mob/living/carbon/human/med_hud_set_status()
diff --git a/code/modules/mob/living/carbon/carbon_defines.dm b/code/modules/mob/living/carbon/carbon_defines.dm
index afb36e4cdf3..813f00e0791 100644
--- a/code/modules/mob/living/carbon/carbon_defines.dm
+++ b/code/modules/mob/living/carbon/carbon_defines.dm
@@ -15,9 +15,7 @@
var/fire_alert = FALSE
var/pressure_alert = FALSE
-//RUTGMC EDIT
var/butchery_progress = 0
-//RUTGMC EDIT
var/list/internal_organs = list()
///Overall drunkenness - check handle_status_effects() in life.dm for effects
@@ -48,6 +46,8 @@
var/list/datum/action/ability/mob_abilities = list()
///Currently selected ability
var/datum/action/ability/activable/selected_ability
+ ///carbon overlay layers
+ var/list/overlays_standing[TOTAL_LAYERS]
/mob/living/carbon/proc/transfer_identity(mob/living/carbon/destination)
if(!istype(destination))
diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm
index 32dc267677e..afea0de50f4 100644
--- a/code/modules/mob/living/carbon/human/update_icons.dm
+++ b/code/modules/mob/living/carbon/human/update_icons.dm
@@ -61,14 +61,10 @@ There are several things that need to be remembered:
#define ITEM_STATE_IF_SET(I) I.item_state ? I.item_state : I.icon_state
-
/mob/living/carbon/human
- var/list/overlays_standing[TOTAL_LAYERS]
var/list/underlays_standing[TOTAL_UNDERLAYS]
var/previous_damage_appearance // store what the body last looked like, so we only have to update it if something changed
-
-
/mob/living/carbon/human/apply_overlay(cache_index)
var/list/to_add = list()
SEND_SIGNAL(src, COMSIG_HUMAN_APPLY_OVERLAY, cache_index, to_add)
@@ -677,7 +673,6 @@ GLOBAL_LIST_EMPTY(damage_icon_parts)
/mob/living/carbon/human/update_burst()
remove_overlay(BURST_LAYER)
var/mutable_appearance/standing
-//RUTGMC EDIT ADDITION BEGIN - Preds
if(chestburst == 1)
if(isyautja(src))
standing = mutable_appearance('icons/Xeno/Effects.dmi', "predburst_stand", -BURST_LAYER)
@@ -688,7 +683,6 @@ GLOBAL_LIST_EMPTY(damage_icon_parts)
standing = mutable_appearance('icons/Xeno/Effects.dmi', "predbursted_stand", -BURST_LAYER)
else
standing = mutable_appearance('icons/Xeno/Effects.dmi', "bursted_stand", -BURST_LAYER)
-//RUTGMC EDIT ADDITION END
overlays_standing[BURST_LAYER] = standing
apply_overlay(BURST_LAYER)
diff --git a/code/modules/mob/living/carbon/xenomorph/life.dm b/code/modules/mob/living/carbon/xenomorph/life.dm
index 90baa08b845..ce5b0b59670 100644
--- a/code/modules/mob/living/carbon/xenomorph/life.dm
+++ b/code/modules/mob/living/carbon/xenomorph/life.dm
@@ -119,25 +119,23 @@
/mob/living/carbon/xenomorph/proc/handle_living_plasma_updates()
var/turf/T = loc
- if(!T || !istype(T))
+ if(!istype(T)) //This means plasma doesn't update while you're in things like a vent, but since you don't have weeds in a vent or can actually take advantage of pheros, this is fine
return
- if(plasma_stored >= xeno_caste.plasma_max * xeno_caste.plasma_regen_limit)
+
+ if(!current_aura && (plasma_stored >= xeno_caste.plasma_max * xeno_caste.plasma_regen_limit)) //no loss or gain
return
if(current_aura)
if(plasma_stored < pheromone_cost)
- use_plasma(plasma_stored)
+ use_plasma(plasma_stored, FALSE)
QDEL_NULL(current_aura)
src.balloon_alert(src, "Stop emitting, no plasma")
else
- use_plasma(pheromone_cost)
-
- if(HAS_TRAIT(src, TRAIT_NOPLASMAREGEN))
- hud_set_plasma()
- return
+ use_plasma(pheromone_cost, FALSE)
- if(!loc_weeds_type && !(xeno_caste.caste_flags & CASTE_INNATE_PLASMA_REGEN))
- hud_set_plasma() // since we used some plasma via the aura
+ if(HAS_TRAIT(src, TRAIT_NOPLASMAREGEN) || !loc_weeds_type && !(xeno_caste.caste_flags & CASTE_INNATE_PLASMA_REGEN))
+ if(current_aura) //we only need to update if we actually used plasma from pheros
+ hud_set_plasma()
return
var/plasma_gain = xeno_caste.plasma_gain
@@ -152,7 +150,6 @@
SEND_SIGNAL(src, COMSIG_XENOMORPH_PLASMA_REGEN, plasma_mod)
gain_plasma(plasma_mod[1])
- hud_set_plasma() //update plasma amount on the plasma mob_hud
/mob/living/carbon/xenomorph/can_receive_aura(aura_type, atom/source, datum/aura_bearer/bearer)
. = ..()
diff --git a/code/modules/mob/living/carbon/xenomorph/update_icons.dm b/code/modules/mob/living/carbon/xenomorph/update_icons.dm
index 70508be1803..fd46532bbde 100644
--- a/code/modules/mob/living/carbon/xenomorph/update_icons.dm
+++ b/code/modules/mob/living/carbon/xenomorph/update_icons.dm
@@ -40,7 +40,6 @@
update_fire() //the fire overlay depends on the xeno's stance, so we must update it.
update_wounds()
- hud_set_plasma()
med_hud_set_health()
hud_set_sunder()
hud_set_firestacks()
@@ -53,35 +52,35 @@
update_icons()
/mob/living/carbon/xenomorph/update_inv_r_hand()
- remove_overlay(X_R_HAND_LAYER)
+ remove_overlay(R_HAND_LAYER)
if(r_hand)
if(client && hud_used && hud_used.hud_version != HUD_STYLE_NOHUD)
r_hand.screen_loc = ui_rhand
client.screen += r_hand
- overlays_standing[X_R_HAND_LAYER] = r_hand.make_worn_icon(inhands = TRUE, slot_name = slot_r_hand_str, default_icon = 'icons/mob/items_righthand_1.dmi', default_layer = X_R_HAND_LAYER)
- apply_overlay(X_R_HAND_LAYER)
+ overlays_standing[R_HAND_LAYER] = r_hand.make_worn_icon(inhands = TRUE, slot_name = slot_r_hand_str, default_icon = 'icons/mob/items_righthand_1.dmi', default_layer = R_HAND_LAYER)
+ apply_overlay(R_HAND_LAYER)
/mob/living/carbon/xenomorph/update_inv_l_hand()
- remove_overlay(X_L_HAND_LAYER)
+ remove_overlay(L_HAND_LAYER)
if(l_hand)
if(client && hud_used && hud_used.hud_version != HUD_STYLE_NOHUD)
l_hand.screen_loc = ui_lhand
client.screen += l_hand
- overlays_standing[X_L_HAND_LAYER] = l_hand.make_worn_icon(inhands = TRUE, slot_name = slot_l_hand_str, default_icon = 'icons/mob/items_lefthand_1.dmi', default_layer = X_L_HAND_LAYER)
- apply_overlay(X_L_HAND_LAYER)
+ overlays_standing[L_HAND_LAYER] = l_hand.make_worn_icon(inhands = TRUE, slot_name = slot_l_hand_str, default_icon = 'icons/mob/items_lefthand_1.dmi', default_layer = L_HAND_LAYER)
+ apply_overlay(L_HAND_LAYER)
/mob/living/carbon/xenomorph/proc/create_shriekwave(color)
var/image/shriekwave = image("icon"='icons/Xeno/64x64_Xeno_overlays.dmi', "icon_state" = "shriek_waves") //Ehh, suit layer's not being used.
if(color)
shriekwave.color = color
- overlays_standing[X_SUIT_LAYER] = shriekwave
- apply_temp_overlay(X_SUIT_LAYER, 3 SECONDS)
+ overlays_standing[SUIT_LAYER] = shriekwave
+ apply_temp_overlay(SUIT_LAYER, 3 SECONDS)
/mob/living/carbon/xenomorph/proc/create_stomp()
- overlays_standing[X_SUIT_LAYER] = image("icon"='icons/Xeno/64x64_Xeno_overlays.dmi', "icon_state" = "stomp") //Ehh, suit layer's not being used.
- apply_temp_overlay(X_SUIT_LAYER, 1.2 SECONDS)
+ overlays_standing[SUIT_LAYER] = image("icon"='icons/Xeno/64x64_Xeno_overlays.dmi', "icon_state" = "stomp") //Ehh, suit layer's not being used.
+ apply_temp_overlay(SUIT_LAYER, 1.2 SECONDS)
/mob/living/carbon/xenomorph/update_fire()
if(!fire_overlay)
@@ -97,7 +96,7 @@
if(QDELETED(src))
return
- remove_overlay(X_WOUND_LAYER)
+ remove_overlay(WOUND_LAYER)
remove_filter("wounded_filter")
var/health_thresholds
@@ -136,8 +135,8 @@
if(xeno_caste.caste_flags & CASTE_HAS_WOUND_MASK)
var/image/wounded_mask = image(icon, null, "alpha_[overlay_to_show]")
wounded_mask.render_target = "*[REF(src)]"
- overlays_standing[X_WOUND_LAYER] = wounded_mask
- apply_overlay(X_WOUND_LAYER)
+ overlays_standing[WOUND_LAYER] = wounded_mask
+ apply_overlay(WOUND_LAYER)
add_filter("wounded_filter", 1, alpha_mask_filter(0, 0, null, "*[REF(src)]", MASK_INVERSE))
wound_overlay.vis_flags &= ~VIS_HIDE // Show the overlay
diff --git a/code/modules/mob/living/carbon/xenomorph/xeno_defines.dm b/code/modules/mob/living/carbon/xenomorph/xeno_defines.dm
index 827fe656bac..82f3f555a49 100644
--- a/code/modules/mob/living/carbon/xenomorph/xeno_defines.dm
+++ b/code/modules/mob/living/carbon/xenomorph/xeno_defines.dm
@@ -283,7 +283,6 @@ RU TGMC EDIT */
///State tracking of hive status toggles
var/status_toggle_flags = HIVE_STATUS_DEFAULTS
- var/list/overlays_standing[X_TOTAL_LAYERS]
var/atom/movable/vis_obj/xeno_wounds/wound_overlay
var/atom/movable/vis_obj/xeno_wounds/fire_overlay/fire_overlay
var/datum/xeno_caste/xeno_caste
diff --git a/code/modules/mob/living/carbon/xenomorph/xenomorph.dm b/code/modules/mob/living/carbon/xenomorph/xenomorph.dm
index 40cdb6ce118..fa3e776d6d4 100644
--- a/code/modules/mob/living/carbon/xenomorph/xenomorph.dm
+++ b/code/modules/mob/living/carbon/xenomorph/xenomorph.dm
@@ -109,7 +109,7 @@
maxHealth = xeno_caste.max_health * GLOB.xeno_stat_multiplicator_buff
if(restore_health_and_plasma)
// xenos that manage plasma through special means shouldn't gain it for free on aging
- plasma_stored = max(plasma_stored, xeno_caste.plasma_max * xeno_caste.plasma_regen_limit)
+ set_plasma(max(plasma_stored, xeno_caste.plasma_max * xeno_caste.plasma_regen_limit))
health = maxHealth
setXenoCasteSpeed(xeno_caste.speed)
diff --git a/code/modules/mob/living/carbon/xenomorph/xenoprocs.dm b/code/modules/mob/living/carbon/xenomorph/xenoprocs.dm
index f84dc8aa2df..31e79e28f98 100644
--- a/code/modules/mob/living/carbon/xenomorph/xenoprocs.dm
+++ b/code/modules/mob/living/carbon/xenomorph/xenoprocs.dm
@@ -135,6 +135,8 @@
. += "Sunder: [100-sunder]% armor left"
+ . += "Regeneration power: [max(regen_power * 100, 0)]%"
+
//Very weak <= 1.0, weak <= 2.0, no modifier 2-3, strong <= 3.5, very strong <= 4.5
var/msg_holder = ""
if(frenzy_aura)
@@ -191,16 +193,25 @@
return FALSE
return TRUE
-/mob/living/carbon/xenomorph/proc/use_plasma(value)
+/mob/living/carbon/xenomorph/proc/set_plasma(value, update_plasma = TRUE)
+ plasma_stored = clamp(value, 0, xeno_caste.plasma_max)
+ if(!update_plasma)
+ return
+ hud_set_plasma()
+
+/mob/living/carbon/xenomorph/proc/use_plasma(value, update_plasma = TRUE)
plasma_stored = max(plasma_stored - value, 0)
update_action_button_icons()
+ if(!update_plasma)
+ return
+ hud_set_plasma()
-/mob/living/carbon/xenomorph/proc/gain_plasma(value)
+/mob/living/carbon/xenomorph/proc/gain_plasma(value, update_plasma = TRUE)
plasma_stored = min(plasma_stored + value, xeno_caste.plasma_max)
update_action_button_icons()
-
-
-
+ if(!update_plasma)
+ return
+ hud_set_plasma()
//Strip all inherent xeno verbs from your caste. Used in evolution.
/mob/living/carbon/xenomorph/proc/remove_inherent_verbs()
diff --git a/code/modules/mob/living/living_health_procs.dm b/code/modules/mob/living/living_health_procs.dm
index 65895f2de02..afef8182f18 100644
--- a/code/modules/mob/living/living_health_procs.dm
+++ b/code/modules/mob/living/living_health_procs.dm
@@ -360,7 +360,7 @@
/mob/living/carbon/xenomorph/revive(admin_revive = FALSE)
- plasma_stored = xeno_caste.plasma_max
+ set_plasma(xeno_caste.plasma_max)
sunder = 0
if(stat == DEAD)
hive?.on_xeno_revive(src)
diff --git a/code/modules/predator/yautja/weapons/ranged.dm b/code/modules/predator/yautja/weapons/ranged.dm
index abc86002c59..ed2d0304506 100644
--- a/code/modules/predator/yautja/weapons/ranged.dm
+++ b/code/modules/predator/yautja/weapons/ranged.dm
@@ -461,20 +461,15 @@
/atom/proc/can_apply_pred_laser()
return FALSE
-/mob/living/carbon/human/can_apply_pred_laser()
+/mob/living/carbon/can_apply_pred_laser()
if(!overlays_standing[PRED_LASER_LAYER])
return TRUE
return FALSE
-/mob/living/carbon/xenomorph/can_apply_pred_laser()
- if(!overlays_standing[X_PRED_LASER_LAYER])
- return TRUE
- return FALSE
-
/atom/proc/apply_pred_laser()
return FALSE
-/mob/living/carbon/human/apply_pred_laser()
+/mob/living/carbon/apply_pred_laser()
overlays_standing[PRED_LASER_LAYER] = image("icon" = 'icons/mob/hunter/pred_gear.dmi', "icon_state" = "locking-y", "layer" = -PRED_LASER_LAYER)
apply_overlay(PRED_LASER_LAYER)
spawn(2 SECONDS)
@@ -484,27 +479,13 @@
apply_overlay(PRED_LASER_LAYER)
return TRUE
-/mob/living/carbon/xenomorph/apply_pred_laser()
- overlays_standing[X_PRED_LASER_LAYER] = image("icon" = 'icons/mob/hunter/pred_gear.dmi', "icon_state" = "locking-y", "layer" = -X_PRED_LASER_LAYER)
- apply_overlay(X_PRED_LASER_LAYER)
- spawn(2 SECONDS)
- if(overlays_standing[X_PRED_LASER_LAYER])
- remove_overlay(X_PRED_LASER_LAYER)
- overlays_standing[X_PRED_LASER_LAYER] = image("icon" = 'icons/mob/hunter/pred_gear.dmi', "icon_state" = "locked-y", "layer" = -X_PRED_LASER_LAYER)
- apply_overlay(X_PRED_LASER_LAYER)
- return TRUE
-
/atom/proc/remove_pred_laser()
return FALSE
-/mob/living/carbon/human/remove_pred_laser()
+/mob/living/carbon/remove_pred_laser()
remove_overlay(PRED_LASER_LAYER)
return TRUE
-/mob/living/carbon/xenomorph/remove_pred_laser()
- remove_overlay(X_PRED_LASER_LAYER)
- return TRUE
-
/obj/item/weapon/gun/energy/yautja/plasma_caster/process()
var/mob/living/user = loc
if(!istype(user))
diff --git a/code/modules/projectiles/guns/specialist.dm b/code/modules/projectiles/guns/specialist.dm
index b3a268791ab..650b5752b5f 100644
--- a/code/modules/projectiles/guns/specialist.dm
+++ b/code/modules/projectiles/guns/specialist.dm
@@ -102,27 +102,18 @@ Note that this means that snipers will have a slowdown of 3, due to the scope
/atom/proc/apply_laser()
return FALSE
-/mob/living/carbon/human/apply_laser()
+/mob/living/carbon/apply_laser()
overlays_standing[LASER_LAYER] = image("icon" = 'icons/obj/items/projectiles.dmi',"icon_state" = "sniper_laser", "layer" =-LASER_LAYER)
apply_overlay(LASER_LAYER)
return TRUE
-/mob/living/carbon/xenomorph/apply_laser()
- overlays_standing[X_LASER_LAYER] = image("icon" = 'icons/obj/items/projectiles.dmi',"icon_state" = "sniper_laser", "layer" =-X_LASER_LAYER)
- apply_overlay(X_LASER_LAYER)
- return TRUE
-
/mob/living/carbon/proc/remove_laser()
return FALSE
-/mob/living/carbon/human/remove_laser()
+/mob/living/carbon/remove_laser()
remove_overlay(LASER_LAYER)
return TRUE
-/mob/living/carbon/xenomorph/remove_laser()
- remove_overlay(X_LASER_LAYER)
- return TRUE
-
/obj/item/weapon/gun/rifle/sniper/antimaterial/unique_action(mob/user)
if(!targetmarker_primed && !targetmarker_on)
return laser_on(user)
From afdf84a21275954fdc5629454eeb02ae704a9c9b Mon Sep 17 00:00:00 2001
From: "github-actions[bot]"
<41898282+github-actions[bot]@users.noreply.github.com>
Date: Fri, 26 Jul 2024 06:42:05 +0000
Subject: [PATCH 07/10] Automatic changelog for PR #42 [ci skip]
---
html/changelogs/AutoChangeLog-pr-42.yml | 7 +++++++
1 file changed, 7 insertions(+)
create mode 100644 html/changelogs/AutoChangeLog-pr-42.yml
diff --git a/html/changelogs/AutoChangeLog-pr-42.yml b/html/changelogs/AutoChangeLog-pr-42.yml
new file mode 100644
index 00000000000..fde5247274e
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-42.yml
@@ -0,0 +1,7 @@
+author: "Helg2"
+delete-after: True
+changes:
+ - qol: "Сила регенерации ксеносов теперь отображается в панели статуса.."
+ - bugfix: "Активные феромоны теперь тратят по 5 плазмы в тик как и положено."
+ - code_imp: "Оптимизирован код апдейта плазмы."
+ - code_imp: "Слои оверлеев ксеносов и хуманов объединены в один."
\ No newline at end of file
From 1a086d6d81b1cc35cf8bab0e5bba2e4acd103eeb Mon Sep 17 00:00:00 2001
From: Helg2 <93882977+Helg2@users.noreply.github.com>
Date: Fri, 26 Jul 2024 11:06:33 +0300
Subject: [PATCH 08/10] Reorgs sound folder a bit. (#38)
* voice folder
* b18
* predator
* human male
* human female
* predalien
* alien
* larva
* queen
* oops
* effect folder
* behemoth
* alien
* explosions
* behemoth2
* alien footsteps
* Revert "alien footsteps"
This reverts commit 73b313d707df830947ab08280dfe2c4044337ba3.
* Reapply "alien footsteps"
This reverts commit ee800cfa261041ebed2005bc073c0af147f00d3f.
* hmmm
* Update sound.dm
* conflicts
---
code/__DEFINES/footsteps.dm | 168 +++++++++---------
code/datums/cinematic.dm | 16 +-
code/datums/components/suit_autodoc.dm | 2 +-
code/datums/elements/limb_support.dm | 2 +-
code/datums/status_effects/xeno_buffs.dm | 2 +-
code/game/objects/explosion_recursive.dm | 2 +-
code/game/objects/items/cocoon.dm | 2 +-
code/game/objects/items/loot_box.dm | 2 +-
code/game/objects/items/radio/headset.dm | 2 +-
.../campaign_structures/destroy_objectives.dm | 2 +-
code/game/sound.dm | 102 +++++------
code/game/turfs/closed.dm | 2 +-
.../atmospherics/machinery/atmosmachinery.dm | 2 +-
code/modules/flufftext/Hallucination.dm | 2 +-
.../mob/living/carbon/human/emote-yautja.dm | 40 ++---
code/modules/mob/living/carbon/human/emote.dm | 34 ++--
.../mob/living/carbon/human/species.dm | 2 +-
.../modules/mob/living/carbon/human/yautja.dm | 4 +-
.../mob/living/carbon/xenomorph/abilities.dm | 8 +-
.../castes/behemoth/abilities_behemoth.dm | 40 ++---
.../castes/carrier/abilities_carrier.dm | 6 +-
.../castes/chimera/abilities_chimera.dm | 8 +-
.../castes/crusher/abilities_crusher.dm | 4 +-
.../castes/defender/abilities_defender.dm | 6 +-
.../castes/defiler/abilities_defiler.dm | 14 +-
.../castes/facehugger/abilities_facehugger.dm | 2 +-
.../castes/hivelord/abilities_hivelord.dm | 2 +-
.../xenomorph/castes/hivemind/hivemind.dm | 2 +-
.../castes/hunter/abilities_hunter.dm | 12 +-
.../xenomorph/castes/king/abilities_king.dm | 4 +-
.../carbon/xenomorph/castes/king/king.dm | 4 +-
.../castes/panther/abilities_panther.dm | 12 +-
.../castes/praetorian/abilities_praetorian.dm | 2 +-
.../castes/predalien/abilities_predalien.dm | 8 +-
.../xenomorph/castes/queen/abilities_queen.dm | 8 +-
.../carbon/xenomorph/castes/queen/queen.dm | 4 +-
.../castes/ravager/abilities_ravager.dm | 18 +-
.../castes/runner/abilities_runner.dm | 12 +-
.../castes/sentinel/abilities_sentinel.dm | 12 +-
.../castes/spitter/abilities_spitter.dm | 4 +-
.../castes/warlock/abilities_warlock.dm | 2 +-
.../castes/warrior/abilities_warrior.dm | 4 +-
.../castes/wraith/abilities_wraith.dm | 6 +-
.../living/carbon/xenomorph/damage_procs.dm | 2 +-
.../mob/living/carbon/xenomorph/death.dm | 2 +-
.../mob/living/carbon/xenomorph/egg.dm | 10 +-
.../mob/living/carbon/xenomorph/embryo.dm | 4 +-
.../mob/living/carbon/xenomorph/emote.dm | 50 +++---
.../living/carbon/xenomorph/facehuggers.dm | 4 +-
.../mob/living/carbon/xenomorph/hive_datum.dm | 2 +-
.../mob/living/carbon/xenomorph/xenoprocs.dm | 2 +-
.../mob/living/silicon/ai/ai_notifications.dm | 4 +-
.../mob/living/simple_animal/hostile/alien.dm | 2 +-
code/modules/predator/yautja/bracers.dm | 2 +-
.../vehicles/mecha/combat/savannah_ivanov.dm | 2 +-
code/modules/xenomorph/silo.dm | 8 +-
code/modules/xenomorph/spawner.dm | 4 +-
code/modules/xenomorph/trap.dm | 2 +-
code/modules/xenomorph/turret.dm | 4 +-
.../behemoth/earth_pillar_destroyed.ogg | Bin
.../behemoth/earth_pillar_eating.ogg | Bin
.../behemoth/earth_pillar_hit_1.ogg | Bin
.../behemoth/earth_pillar_hit_2.ogg | Bin
.../behemoth/earth_pillar_hit_3.ogg | Bin
.../behemoth/earth_pillar_hit_4.ogg | Bin
.../behemoth/earth_pillar_hit_5.ogg | Bin
.../behemoth/earth_pillar_hit_6.ogg | Bin
.../behemoth/earth_pillar_rising.ogg | Bin
.../behemoth/landslide_enhanced_charge.ogg | Bin
.../behemoth/landslide_hit_mob.ogg | Bin
.../{ => alien}/behemoth/landslide_roar.ogg | Bin
.../behemoth/primal_wrath_roar.ogg | Bin
.../behemoth/roll.ogg} | Bin
.../behemoth/rumble.ogg} | Bin
.../behemoth/seismic_fracture_explosion.ogg | Bin
.../behemoth/stomp.ogg} | Bin
.../egg_burst.ogg} | Bin
.../egg_move.ogg} | Bin
.../evolveready.ogg} | Bin
.../{xeno_newlarva.ogg => alien/newlarva.ogg} | Bin
.../recycler.ogg} | Bin
.../resin_break1.ogg} | Bin
.../resin_break2.ogg} | Bin
.../resin_build1.ogg} | Bin
.../resin_build2.ogg} | Bin
.../resin_build3.ogg} | Bin
.../resin_move1.ogg} | Bin
.../resin_move2.ogg} | Bin
.../tail_swipe1.ogg} | Bin
.../tail_swipe2.ogg} | Bin
.../tail_swipe3.ogg} | Bin
.../turret_death.ogg} | Bin
.../ventcrawl1.ogg} | Bin
.../ventcrawl2.ogg} | Bin
.../ventpass1.ogg} | Bin
.../ventpass2.ogg} | Bin
.../creak1.ogg} | Bin
.../creak2.ogg} | Bin
.../{explosionfar.ogg => explosion/far0.ogg} | Bin
.../far1.ogg} | Bin
.../far2.ogg} | Bin
.../far3.ogg} | Bin
.../far4.ogg} | Bin
.../far5.ogg} | Bin
.../incendiary1.ogg} | Bin
.../incendiary2.ogg} | Bin
.../incendiary3.ogg} | Bin
.../large1.ogg} | Bin
.../large2.ogg} | Bin
.../large3.ogg} | Bin
.../large4.ogg} | Bin
.../large5.ogg} | Bin
.../large6.ogg} | Bin
.../medium1.ogg} | Bin
.../medium2.ogg} | Bin
.../medium3.ogg} | Bin
.../medium4.ogg} | Bin
.../medium5.ogg} | Bin
.../medium6.ogg} | Bin
.../micro1.ogg} | Bin
.../micro2.ogg} | Bin
.../micro3.ogg} | Bin
.../small1.ogg} | Bin
.../small2.ogg} | Bin
.../small3.ogg} | Bin
.../small4.ogg} | Bin
.../small_far0.ogg} | Bin
.../small_far1.ogg} | Bin
.../small_far2.ogg} | Bin
.../small_far3.ogg} | Bin
.../small_far4.ogg} | Bin
.../alien/charge1.ogg} | Bin
.../alien/charge2.ogg} | Bin
.../alien/charge3.ogg} | Bin
.../alien/large1.ogg} | Bin
.../alien/large2.ogg} | Bin
.../alien/large3.ogg} | Bin
.../alien/medium1.ogg} | Bin
.../alien/medium2.ogg} | Bin
.../alien/medium3.ogg} | Bin
.../alien/resin_move1.ogg} | Bin
.../alien/resin_move2.ogg} | Bin
.../footstep/alien_footstep_large1.ogg | Bin 7555 -> 0 bytes
.../footstep/alien_footstep_large2.ogg | Bin 7379 -> 0 bytes
.../footstep/alien_footstep_large3.ogg | Bin 7054 -> 0 bytes
.../footstep/alien_footstep_medium1.ogg | Bin 25788 -> 0 bytes
.../footstep/alien_footstep_medium2.ogg | Bin 29640 -> 0 bytes
.../footstep/alien_footstep_medium3.ogg | Bin 31168 -> 0 bytes
.../{4_xeno_roars.ogg => alien/4_roars.ogg} | Bin
.../chestburst.ogg} | Bin
.../chestburst2.ogg} | Bin
.../{alien_death.ogg => alien/death.ogg} | Bin
.../{alien_death2.ogg => alien/death2.ogg} | Bin
.../distantroar_3.ogg} | Bin
.../{alien_drool1.ogg => alien/drool1.ogg} | Bin
.../{alien_drool2.ogg => alien/drool2.ogg} | Bin
.../facehugger_dies.ogg} | Bin
.../{alien_growl1.ogg => alien/growl1.ogg} | Bin
.../{alien_growl2.ogg => alien/growl2.ogg} | Bin
.../{alien_growl3.ogg => alien/growl3.ogg} | Bin
.../{alien_growl4.ogg => alien/growl4.ogg} | Bin
.../{alien_help1.ogg => alien/help1.ogg} | Bin
.../{alien_help2.ogg => alien/help2.ogg} | Bin
.../{alien_hiss1.ogg => alien/hiss1.ogg} | Bin
.../{alien_hiss2.ogg => alien/hiss2.ogg} | Bin
.../{alien_hiss3.ogg => alien/hiss3.ogg} | Bin
sound/voice/{hiss1.ogg => alien/hiss4.ogg} | Bin
sound/voice/{hiss2.ogg => alien/hiss5.ogg} | Bin
sound/voice/{hiss3.ogg => alien/hiss6.ogg} | Bin
sound/voice/{hiss4.ogg => alien/hiss7.ogg} | Bin
sound/voice/{hiss5.ogg => alien/hiss8.ogg} | Bin
sound/voice/{hiss6.ogg => alien/hiss9.ogg} | Bin
.../king_died.ogg} | Bin
.../{ed209_20sec.ogg => alien/king_roar.ogg} | Bin
.../larva/roar1.ogg} | Bin
.../larva/roar2.ogg} | Bin
.../larva/roar3.ogg} | Bin
.../larva/roar4.ogg} | Bin
.../larva/talk1.ogg} | Bin
.../larva/talk2.ogg} | Bin
.../larva/talk3.ogg} | Bin
.../larva/talk4.ogg} | Bin
.../{alien_pounce.ogg => alien/pounce.ogg} | Bin
.../{alien_pounce2.ogg => alien/pounce2.ogg} | Bin
.../predalien/click.ogg} | Bin
.../predalien/click1.ogg} | Bin
.../predalien/click2.ogg} | Bin
.../predalien/click3.ogg} | Bin
.../predalien/death.ogg} | Bin
.../predalien/growl.ogg} | Bin
.../predalien/hiss.ogg} | Bin
.../predalien/pounce.ogg} | Bin
.../predalien/roar.ogg} | Bin
.../queen/breath1.ogg} | Bin
.../queen/breath2.ogg} | Bin
.../queen/command.ogg} | Bin
.../queen/command2.ogg} | Bin
.../queen/command3.ogg} | Bin
.../queen/died.ogg} | Bin
.../queen/screech.ogg} | Bin
.../queen/screech_frenzy.ogg} | Bin
.../queen/screech_heal.ogg} | Bin
.../queen/screech_plasma.ogg} | Bin
.../{alien_roar1.ogg => alien/roar1.ogg} | Bin
.../{alien_roar10.ogg => alien/roar10.ogg} | Bin
.../{alien_roar11.ogg => alien/roar11.ogg} | Bin
.../{alien_roar12.ogg => alien/roar12.ogg} | Bin
.../{alien_roar2.ogg => alien/roar2.ogg} | Bin
.../{alien_roar3.ogg => alien/roar3.ogg} | Bin
.../{alien_roar4.ogg => alien/roar4.ogg} | Bin
.../{alien_roar5.ogg => alien/roar5.ogg} | Bin
.../{alien_roar6.ogg => alien/roar6.ogg} | Bin
.../{alien_roar7.ogg => alien/roar7.ogg} | Bin
.../{alien_roar8.ogg => alien/roar8.ogg} | Bin
.../{alien_roar9.ogg => alien/roar9.ogg} | Bin
.../roar_warlock.ogg} | Bin
.../spitacid.ogg} | Bin
.../spitacid2.ogg} | Bin
.../voice/{alien_talk.ogg => alien/talk.ogg} | Bin
.../{alien_talk2.ogg => alien/talk2.ogg} | Bin
.../{alien_talk3.ogg => alien/talk3.ogg} | Bin
sound/voice/{ => alien}/xenos_roaring.ogg | Bin
.../yell_alt.ogg} | Bin
sound/voice/alien_cena.ogg | Bin 58020 -> 0 bytes
sound/voice/alien_queen_xmas.ogg | Bin 34180 -> 0 bytes
.../{b18_activate.ogg => b18/activate.ogg} | Bin
.../{b18_antitoxin.ogg => b18/antitoxin.ogg} | Bin
.../antitoxin2.ogg} | Bin
sound/voice/{b18_brute.ogg => b18/brute.ogg} | Bin
.../{b18_fracture.ogg => b18/fracture.ogg} | Bin
sound/voice/{ => b18}/ib_detected.ogg | Bin
.../pain_suppress.ogg} | Bin
sound/voice/bcreep.ogg | Bin 4370 -> 0 bytes
sound/voice/bcriminal.ogg | Bin 4416 -> 0 bytes
sound/voice/bfreeze.ogg | Bin 4317 -> 0 bytes
sound/voice/bgod.ogg | Bin 7389 -> 0 bytes
sound/voice/biamthelaw.ogg | Bin 5897 -> 0 bytes
sound/voice/binsult.ogg | Bin 24561 -> 0 bytes
sound/voice/bjustice.ogg | Bin 4286 -> 0 bytes
sound/voice/bradio.ogg | Bin 5430 -> 0 bytes
sound/voice/bsecureday.ogg | Bin 4610 -> 0 bytes
.../female/cough1.ogg} | Bin
.../female/cough2.ogg} | Bin
.../female/cry_1.ogg} | Bin
.../female/facehugged1.ogg} | Bin
.../female/facehugged2.ogg} | Bin
.../female/gasp1.ogg} | Bin
.../female/gasp2.ogg} | Bin
.../female/giggle_1.ogg} | Bin
.../female/gored_1.ogg} | Bin
.../female/gored_2.ogg} | Bin
.../female/grenadethrow_1.ogg} | Bin
.../female/grenadethrow_2.ogg} | Bin
.../female/grenadethrow_3.ogg} | Bin
.../female/laugh_1.ogg} | Bin
.../female/medic.ogg} | Bin
.../female/moan_1.ogg} | Bin
.../female/pain_1.ogg} | Bin
.../female/pain_2.ogg} | Bin
.../female/pain_3.ogg} | Bin
.../female/preburst1.ogg} | Bin
.../female/preburst2.ogg} | Bin
.../female/preburst3.ogg} | Bin
.../female/scream_1.ogg} | Bin
.../female/scream_2.ogg} | Bin
.../female/scream_3.ogg} | Bin
.../female/scream_4.ogg} | Bin
.../female/scream_5.ogg} | Bin
.../female/sigh_1.ogg} | Bin
.../female/warcry_1.ogg} | Bin
.../female/warcry_10.ogg} | Bin
.../female/warcry_11.ogg} | Bin
.../female/warcry_12.ogg} | Bin
.../female/warcry_13.ogg} | Bin
.../female/warcry_14.ogg} | Bin
.../female/warcry_15.ogg} | Bin
.../female/warcry_16.ogg} | Bin
.../female/warcry_17.ogg} | Bin
.../female/warcry_18.ogg} | Bin
.../female/warcry_19.ogg} | Bin
.../female/warcry_2.ogg} | Bin
.../female/warcry_3.ogg} | Bin
.../female/warcry_4.ogg} | Bin
.../female/warcry_5.ogg} | Bin
.../female/warcry_6.ogg} | Bin
.../female/warcry_7.ogg} | Bin
.../female/warcry_8.ogg} | Bin
.../female/warcry_9.ogg} | Bin
.../female/yawn_1.ogg} | Bin
.../male/cough1.ogg} | Bin
.../male/cough2.ogg} | Bin
.../male/cry_1.ogg} | Bin
.../male/facehugged1.ogg} | Bin
.../male/facehugged2.ogg} | Bin
.../male/facehugged3.ogg} | Bin
.../male/gasp1.ogg} | Bin
.../male/gasp2.ogg} | Bin
.../male/gasp3.ogg} | Bin
.../male/giggle_1.ogg} | Bin
.../male/gored3.ogg} | Bin
.../male/gored_1.ogg} | Bin
.../male/gored_2.ogg} | Bin
.../male/grenadethrow_1.ogg} | Bin
.../male/grenadethrow_2.ogg} | Bin
.../male/grenadethrow_3.ogg} | Bin
.../male/laugh_1.ogg} | Bin
.../male/laugh_2.ogg} | Bin
.../male/medic.ogg} | Bin
.../male/medic2.ogg} | Bin
.../male/moan_1.ogg} | Bin
.../male/pain_1.ogg} | Bin
.../male/pain_10.ogg} | Bin
.../male/pain_11.ogg} | Bin
.../male/pain_2.ogg} | Bin
.../male/pain_3.ogg} | Bin
.../male/pain_4.ogg} | Bin
.../male/pain_5.ogg} | Bin
.../male/pain_6.ogg} | Bin
.../male/pain_7.ogg} | Bin
.../male/pain_8.ogg} | Bin
.../male/pain_9.ogg} | Bin
.../male/preburst1.ogg} | Bin
.../male/preburst10.ogg} | Bin
.../male/preburst2.ogg} | Bin
.../male/preburst3.ogg} | Bin
.../male/preburst4.ogg} | Bin
.../male/preburst5.ogg} | Bin
.../male/preburst6.ogg} | Bin
.../male/preburst7.ogg} | Bin
.../male/preburst8.ogg} | Bin
.../male/preburst9.ogg} | Bin
.../male/scream_1.ogg} | Bin
.../male/scream_2.ogg} | Bin
.../male/scream_3.ogg} | Bin
.../male/scream_4.ogg} | Bin
.../male/scream_5.ogg} | Bin
.../male/scream_6.ogg} | Bin
.../male/scream_7.ogg} | Bin
.../male/sigh_1.ogg} | Bin
.../male/warcry_1.ogg} | Bin
.../male/warcry_10.ogg} | Bin
.../male/warcry_11.ogg} | Bin
.../male/warcry_12.ogg} | Bin
.../male/warcry_13.ogg} | Bin
.../male/warcry_14.ogg} | Bin
.../male/warcry_15.ogg} | Bin
.../male/warcry_16.ogg} | Bin
.../male/warcry_17.ogg} | Bin
.../male/warcry_18.ogg} | Bin
.../male/warcry_19.ogg} | Bin
.../male/warcry_2.ogg} | Bin
.../male/warcry_20.ogg} | Bin
.../male/warcry_21.ogg} | Bin
.../male/warcry_22.ogg} | Bin
.../male/warcry_23.ogg} | Bin
.../male/warcry_24.ogg} | Bin
.../male/warcry_25.ogg} | Bin
.../male/warcry_26.ogg} | Bin
.../male/warcry_27.ogg} | Bin
.../male/warcry_28.ogg} | Bin
.../male/warcry_29.ogg} | Bin
.../male/warcry_3.ogg} | Bin
.../male/warcry_4.ogg} | Bin
.../male/warcry_5.ogg} | Bin
.../male/warcry_6.ogg} | Bin
.../male/warcry_7.ogg} | Bin
.../male/warcry_8.ogg} | Bin
.../male/warcry_9.ogg} | Bin
.../male/yawn_1.ogg} | Bin
.../whistle1.ogg} | Bin
sound/voice/liveagain.ogg | Bin 28143 -> 0 bytes
.../anytime.ogg} | Bin
.../{pred_click1.ogg => predator/click1.ogg} | Bin
.../{pred_click2.ogg => predator/click2.ogg} | Bin
.../{pred_click3.ogg => predator/click3.ogg} | Bin
.../{pred_click4.ogg => predator/click4.ogg} | Bin
.../{pred_click5.ogg => predator/click5.ogg} | Bin
.../come_on_out.ogg} | Bin
.../deathlaugh.ogg} | Bin
.../facehugged.ogg} | Bin
.../{pred_helpme.ogg => predator/helpme.ogg} | Bin
.../itsatrap.ogg} | Bin
.../{pred_laugh1.ogg => predator/laugh1.ogg} | Bin
.../{pred_laugh2.ogg => predator/laugh2.ogg} | Bin
.../{pred_laugh3.ogg => predator/laugh3.ogg} | Bin
.../{pred_laugh4.ogg => predator/laugh4.ogg} | Bin
.../over_there.ogg} | Bin
.../overhere.ogg} | Bin
.../{pred_pain1.ogg => predator/pain1.ogg} | Bin
.../{pred_pain2.ogg => predator/pain2.ogg} | Bin
.../{pred_pain3.ogg => predator/pain3.ogg} | Bin
.../{pred_pain4.ogg => predator/pain4.ogg} | Bin
.../{pred_pain5.ogg => predator/pain5.ogg} | Bin
.../pain_rare1.ogg} | Bin
.../{pred_roar1.ogg => predator/roar1.ogg} | Bin
.../{pred_roar2.ogg => predator/roar2.ogg} | Bin
.../{pred_roar3.ogg => predator/roar3.ogg} | Bin
.../{pred_roar4.ogg => predator/roar4.ogg} | Bin
.../{pred_roar5.ogg => predator/roar5.ogg} | Bin
.../turnaround.ogg} | Bin
.../ugly_freak.ogg} | Bin
.../{pred_warcry.ogg => predator/warcry.ogg} | Bin
402 files changed, 348 insertions(+), 348 deletions(-)
rename sound/effects/{ => alien}/behemoth/earth_pillar_destroyed.ogg (100%)
rename sound/effects/{ => alien}/behemoth/earth_pillar_eating.ogg (100%)
rename sound/effects/{ => alien}/behemoth/earth_pillar_hit_1.ogg (100%)
rename sound/effects/{ => alien}/behemoth/earth_pillar_hit_2.ogg (100%)
rename sound/effects/{ => alien}/behemoth/earth_pillar_hit_3.ogg (100%)
rename sound/effects/{ => alien}/behemoth/earth_pillar_hit_4.ogg (100%)
rename sound/effects/{ => alien}/behemoth/earth_pillar_hit_5.ogg (100%)
rename sound/effects/{ => alien}/behemoth/earth_pillar_hit_6.ogg (100%)
rename sound/effects/{ => alien}/behemoth/earth_pillar_rising.ogg (100%)
rename sound/effects/{ => alien}/behemoth/landslide_enhanced_charge.ogg (100%)
rename sound/effects/{ => alien}/behemoth/landslide_hit_mob.ogg (100%)
rename sound/effects/{ => alien}/behemoth/landslide_roar.ogg (100%)
rename sound/effects/{ => alien}/behemoth/primal_wrath_roar.ogg (100%)
rename sound/effects/{behemoth/behemoth_roll.ogg => alien/behemoth/roll.ogg} (100%)
rename sound/effects/{behemoth/behemoth_rumble.ogg => alien/behemoth/rumble.ogg} (100%)
rename sound/effects/{ => alien}/behemoth/seismic_fracture_explosion.ogg (100%)
rename sound/effects/{behemoth/behemoth_stomp.ogg => alien/behemoth/stomp.ogg} (100%)
rename sound/effects/{alien_egg_burst.ogg => alien/egg_burst.ogg} (100%)
rename sound/effects/{alien_egg_move.ogg => alien/egg_move.ogg} (100%)
rename sound/effects/{xeno_evolveready.ogg => alien/evolveready.ogg} (100%)
rename sound/effects/{xeno_newlarva.ogg => alien/newlarva.ogg} (100%)
rename sound/effects/{alien_recycler.ogg => alien/recycler.ogg} (100%)
rename sound/effects/{alien_resin_break1.ogg => alien/resin_break1.ogg} (100%)
rename sound/effects/{alien_resin_break2.ogg => alien/resin_break2.ogg} (100%)
rename sound/effects/{alien_resin_build1.ogg => alien/resin_build1.ogg} (100%)
rename sound/effects/{alien_resin_build2.ogg => alien/resin_build2.ogg} (100%)
rename sound/effects/{alien_resin_build3.ogg => alien/resin_build3.ogg} (100%)
rename sound/effects/{footstep/alien_resin_move1.ogg => alien/resin_move1.ogg} (100%)
rename sound/effects/{footstep/alien_resin_move2.ogg => alien/resin_move2.ogg} (100%)
rename sound/effects/{alien_tail_swipe1.ogg => alien/tail_swipe1.ogg} (100%)
rename sound/effects/{alien_tail_swipe2.ogg => alien/tail_swipe2.ogg} (100%)
rename sound/effects/{alien_tail_swipe3.ogg => alien/tail_swipe3.ogg} (100%)
rename sound/effects/{xeno_turret_death.ogg => alien/turret_death.ogg} (100%)
rename sound/effects/{alien_ventcrawl1.ogg => alien/ventcrawl1.ogg} (100%)
rename sound/effects/{alien_ventcrawl2.ogg => alien/ventcrawl2.ogg} (100%)
rename sound/effects/{alien_ventpass1.ogg => alien/ventpass1.ogg} (100%)
rename sound/effects/{alien_ventpass2.ogg => alien/ventpass2.ogg} (100%)
rename sound/effects/{explosioncreak1.ogg => explosion/creak1.ogg} (100%)
rename sound/effects/{explosioncreak2.ogg => explosion/creak2.ogg} (100%)
rename sound/effects/{explosionfar.ogg => explosion/far0.ogg} (100%)
rename sound/effects/{explosion_far1.ogg => explosion/far1.ogg} (100%)
rename sound/effects/{explosion_far2.ogg => explosion/far2.ogg} (100%)
rename sound/effects/{explosion_far3.ogg => explosion/far3.ogg} (100%)
rename sound/effects/{explosion_far4.ogg => explosion/far4.ogg} (100%)
rename sound/effects/{explosion_far5.ogg => explosion/far5.ogg} (100%)
rename sound/effects/{incendiary_explosion_1.ogg => explosion/incendiary1.ogg} (100%)
rename sound/effects/{incendiary_explosion_2.ogg => explosion/incendiary2.ogg} (100%)
rename sound/effects/{incendiary_explosion_3.ogg => explosion/incendiary3.ogg} (100%)
rename sound/effects/{explosion_large1.ogg => explosion/large1.ogg} (100%)
rename sound/effects/{explosion_large2.ogg => explosion/large2.ogg} (100%)
rename sound/effects/{explosion_large3.ogg => explosion/large3.ogg} (100%)
rename sound/effects/{explosion_large4.ogg => explosion/large4.ogg} (100%)
rename sound/effects/{explosion_large5.ogg => explosion/large5.ogg} (100%)
rename sound/effects/{explosion_large6.ogg => explosion/large6.ogg} (100%)
rename sound/effects/{explosion_med1.ogg => explosion/medium1.ogg} (100%)
rename sound/effects/{explosion_med2.ogg => explosion/medium2.ogg} (100%)
rename sound/effects/{explosion_med3.ogg => explosion/medium3.ogg} (100%)
rename sound/effects/{explosion_med4.ogg => explosion/medium4.ogg} (100%)
rename sound/effects/{explosion_med5.ogg => explosion/medium5.ogg} (100%)
rename sound/effects/{explosion_med6.ogg => explosion/medium6.ogg} (100%)
rename sound/effects/{explosion_micro1.ogg => explosion/micro1.ogg} (100%)
rename sound/effects/{explosion_micro2.ogg => explosion/micro2.ogg} (100%)
rename sound/effects/{explosion_micro3.ogg => explosion/micro3.ogg} (100%)
rename sound/effects/{explosion_small1.ogg => explosion/small1.ogg} (100%)
rename sound/effects/{explosion_small2.ogg => explosion/small2.ogg} (100%)
rename sound/effects/{explosion_small3.ogg => explosion/small3.ogg} (100%)
rename sound/effects/{explosion_small4.ogg => explosion/small4.ogg} (100%)
rename sound/effects/{explosionsmallfar.ogg => explosion/small_far0.ogg} (100%)
rename sound/effects/{explosion_smallfar1.ogg => explosion/small_far1.ogg} (100%)
rename sound/effects/{explosion_smallfar2.ogg => explosion/small_far2.ogg} (100%)
rename sound/effects/{explosion_smallfar3.ogg => explosion/small_far3.ogg} (100%)
rename sound/effects/{explosion_smallfar4.ogg => explosion/small_far4.ogg} (100%)
rename sound/effects/{alien_footstep_charge1.ogg => footstep/alien/charge1.ogg} (100%)
rename sound/effects/{alien_footstep_charge2.ogg => footstep/alien/charge2.ogg} (100%)
rename sound/effects/{alien_footstep_charge3.ogg => footstep/alien/charge3.ogg} (100%)
rename sound/effects/{alien_footstep_large1.ogg => footstep/alien/large1.ogg} (100%)
rename sound/effects/{alien_footstep_large2.ogg => footstep/alien/large2.ogg} (100%)
rename sound/effects/{alien_footstep_large3.ogg => footstep/alien/large3.ogg} (100%)
rename sound/effects/{alien_footstep_medium1.ogg => footstep/alien/medium1.ogg} (100%)
rename sound/effects/{alien_footstep_medium2.ogg => footstep/alien/medium2.ogg} (100%)
rename sound/effects/{alien_footstep_medium3.ogg => footstep/alien/medium3.ogg} (100%)
rename sound/effects/{alien_resin_move1.ogg => footstep/alien/resin_move1.ogg} (100%)
rename sound/effects/{alien_resin_move2.ogg => footstep/alien/resin_move2.ogg} (100%)
delete mode 100644 sound/effects/footstep/alien_footstep_large1.ogg
delete mode 100644 sound/effects/footstep/alien_footstep_large2.ogg
delete mode 100644 sound/effects/footstep/alien_footstep_large3.ogg
delete mode 100644 sound/effects/footstep/alien_footstep_medium1.ogg
delete mode 100644 sound/effects/footstep/alien_footstep_medium2.ogg
delete mode 100644 sound/effects/footstep/alien_footstep_medium3.ogg
rename sound/voice/{4_xeno_roars.ogg => alien/4_roars.ogg} (100%)
rename sound/voice/{alien_chestburst.ogg => alien/chestburst.ogg} (100%)
rename sound/voice/{alien_chestburst2.ogg => alien/chestburst2.ogg} (100%)
rename sound/voice/{alien_death.ogg => alien/death.ogg} (100%)
rename sound/voice/{alien_death2.ogg => alien/death2.ogg} (100%)
rename sound/voice/{alien_distantroar_3.ogg => alien/distantroar_3.ogg} (100%)
rename sound/voice/{alien_drool1.ogg => alien/drool1.ogg} (100%)
rename sound/voice/{alien_drool2.ogg => alien/drool2.ogg} (100%)
rename sound/voice/{alien_facehugger_dies.ogg => alien/facehugger_dies.ogg} (100%)
rename sound/voice/{alien_growl1.ogg => alien/growl1.ogg} (100%)
rename sound/voice/{alien_growl2.ogg => alien/growl2.ogg} (100%)
rename sound/voice/{alien_growl3.ogg => alien/growl3.ogg} (100%)
rename sound/voice/{alien_growl4.ogg => alien/growl4.ogg} (100%)
rename sound/voice/{alien_help1.ogg => alien/help1.ogg} (100%)
rename sound/voice/{alien_help2.ogg => alien/help2.ogg} (100%)
rename sound/voice/{alien_hiss1.ogg => alien/hiss1.ogg} (100%)
rename sound/voice/{alien_hiss2.ogg => alien/hiss2.ogg} (100%)
rename sound/voice/{alien_hiss3.ogg => alien/hiss3.ogg} (100%)
rename sound/voice/{hiss1.ogg => alien/hiss4.ogg} (100%)
rename sound/voice/{hiss2.ogg => alien/hiss5.ogg} (100%)
rename sound/voice/{hiss3.ogg => alien/hiss6.ogg} (100%)
rename sound/voice/{hiss4.ogg => alien/hiss7.ogg} (100%)
rename sound/voice/{hiss5.ogg => alien/hiss8.ogg} (100%)
rename sound/voice/{hiss6.ogg => alien/hiss9.ogg} (100%)
rename sound/voice/{alien_king_died.ogg => alien/king_died.ogg} (100%)
rename sound/voice/{ed209_20sec.ogg => alien/king_roar.ogg} (100%)
rename sound/voice/{alien_roar_larva1.ogg => alien/larva/roar1.ogg} (100%)
rename sound/voice/{alien_roar_larva2.ogg => alien/larva/roar2.ogg} (100%)
rename sound/voice/{alien_roar_larva3.ogg => alien/larva/roar3.ogg} (100%)
rename sound/voice/{alien_roar_larva4.ogg => alien/larva/roar4.ogg} (100%)
rename sound/voice/{larva_talk1.ogg => alien/larva/talk1.ogg} (100%)
rename sound/voice/{larva_talk2.ogg => alien/larva/talk2.ogg} (100%)
rename sound/voice/{larva_talk3.ogg => alien/larva/talk3.ogg} (100%)
rename sound/voice/{larva_talk4.ogg => alien/larva/talk4.ogg} (100%)
rename sound/voice/{alien_pounce.ogg => alien/pounce.ogg} (100%)
rename sound/voice/{alien_pounce2.ogg => alien/pounce2.ogg} (100%)
rename sound/voice/{predalien_click.ogg => alien/predalien/click.ogg} (100%)
rename sound/voice/{predalien_click1.ogg => alien/predalien/click1.ogg} (100%)
rename sound/voice/{predalien_click2.ogg => alien/predalien/click2.ogg} (100%)
rename sound/voice/{predalien_click3.ogg => alien/predalien/click3.ogg} (100%)
rename sound/voice/{predalien_death.ogg => alien/predalien/death.ogg} (100%)
rename sound/voice/{predalien_growl.ogg => alien/predalien/growl.ogg} (100%)
rename sound/voice/{predalien_hiss.ogg => alien/predalien/hiss.ogg} (100%)
rename sound/voice/{predalien_pounce.ogg => alien/predalien/pounce.ogg} (100%)
rename sound/voice/{predalien_roar.ogg => alien/predalien/roar.ogg} (100%)
rename sound/voice/{alien_queen_breath1.ogg => alien/queen/breath1.ogg} (100%)
rename sound/voice/{alien_queen_breath2.ogg => alien/queen/breath2.ogg} (100%)
rename sound/voice/{alien_queen_command.ogg => alien/queen/command.ogg} (100%)
rename sound/voice/{alien_queen_command2.ogg => alien/queen/command2.ogg} (100%)
rename sound/voice/{alien_queen_command3.ogg => alien/queen/command3.ogg} (100%)
rename sound/voice/{alien_queen_died.ogg => alien/queen/died.ogg} (100%)
rename sound/voice/{alien_queen_screech.ogg => alien/queen/screech.ogg} (100%)
rename sound/voice/{alien_frenzy_screech.ogg => alien/queen/screech_frenzy.ogg} (100%)
rename sound/voice/{alien_heal_screech.ogg => alien/queen/screech_heal.ogg} (100%)
rename sound/voice/{alien_plasma_screech.ogg => alien/queen/screech_plasma.ogg} (100%)
rename sound/voice/{alien_roar1.ogg => alien/roar1.ogg} (100%)
rename sound/voice/{alien_roar10.ogg => alien/roar10.ogg} (100%)
rename sound/voice/{alien_roar11.ogg => alien/roar11.ogg} (100%)
rename sound/voice/{alien_roar12.ogg => alien/roar12.ogg} (100%)
rename sound/voice/{alien_roar2.ogg => alien/roar2.ogg} (100%)
rename sound/voice/{alien_roar3.ogg => alien/roar3.ogg} (100%)
rename sound/voice/{alien_roar4.ogg => alien/roar4.ogg} (100%)
rename sound/voice/{alien_roar5.ogg => alien/roar5.ogg} (100%)
rename sound/voice/{alien_roar6.ogg => alien/roar6.ogg} (100%)
rename sound/voice/{alien_roar7.ogg => alien/roar7.ogg} (100%)
rename sound/voice/{alien_roar8.ogg => alien/roar8.ogg} (100%)
rename sound/voice/{alien_roar9.ogg => alien/roar9.ogg} (100%)
rename sound/voice/{alien_roar_warlock.ogg => alien/roar_warlock.ogg} (100%)
rename sound/voice/{alien_spitacid.ogg => alien/spitacid.ogg} (100%)
rename sound/voice/{alien_spitacid2.ogg => alien/spitacid2.ogg} (100%)
rename sound/voice/{alien_talk.ogg => alien/talk.ogg} (100%)
rename sound/voice/{alien_talk2.ogg => alien/talk2.ogg} (100%)
rename sound/voice/{alien_talk3.ogg => alien/talk3.ogg} (100%)
rename sound/voice/{ => alien}/xenos_roaring.ogg (100%)
rename sound/voice/{alien_yell_alt.ogg => alien/yell_alt.ogg} (100%)
delete mode 100644 sound/voice/alien_cena.ogg
delete mode 100644 sound/voice/alien_queen_xmas.ogg
rename sound/voice/{b18_activate.ogg => b18/activate.ogg} (100%)
rename sound/voice/{b18_antitoxin.ogg => b18/antitoxin.ogg} (100%)
rename sound/voice/{b18_antitoxin2.ogg => b18/antitoxin2.ogg} (100%)
rename sound/voice/{b18_brute.ogg => b18/brute.ogg} (100%)
rename sound/voice/{b18_fracture.ogg => b18/fracture.ogg} (100%)
rename sound/voice/{ => b18}/ib_detected.ogg (100%)
rename sound/voice/{b18_pain_suppress.ogg => b18/pain_suppress.ogg} (100%)
delete mode 100644 sound/voice/bcreep.ogg
delete mode 100644 sound/voice/bcriminal.ogg
delete mode 100644 sound/voice/bfreeze.ogg
delete mode 100644 sound/voice/bgod.ogg
delete mode 100644 sound/voice/biamthelaw.ogg
delete mode 100644 sound/voice/binsult.ogg
delete mode 100644 sound/voice/bjustice.ogg
delete mode 100644 sound/voice/bradio.ogg
delete mode 100644 sound/voice/bsecureday.ogg
rename sound/voice/{human_female_cough1.ogg => human/female/cough1.ogg} (100%)
rename sound/voice/{human_female_cough2.ogg => human/female/cough2.ogg} (100%)
rename sound/voice/{human_female_cry_1.ogg => human/female/cry_1.ogg} (100%)
rename sound/voice/{human_female_facehugged1.ogg => human/female/facehugged1.ogg} (100%)
rename sound/voice/{human_female_facehugged2.ogg => human/female/facehugged2.ogg} (100%)
rename sound/voice/{human_female_gasp1.ogg => human/female/gasp1.ogg} (100%)
rename sound/voice/{human_female_gasp2.ogg => human/female/gasp2.ogg} (100%)
rename sound/voice/{human_female_giggle_1.ogg => human/female/giggle_1.ogg} (100%)
rename sound/voice/{human_female_gored_1.ogg => human/female/gored_1.ogg} (100%)
rename sound/voice/{human_female_gored_2.ogg => human/female/gored_2.ogg} (100%)
rename sound/voice/{human_female_grenadethrow_1.ogg => human/female/grenadethrow_1.ogg} (100%)
rename sound/voice/{human_female_grenadethrow_2.ogg => human/female/grenadethrow_2.ogg} (100%)
rename sound/voice/{human_female_grenadethrow_3.ogg => human/female/grenadethrow_3.ogg} (100%)
rename sound/voice/{human_female_laugh_1.ogg => human/female/laugh_1.ogg} (100%)
rename sound/voice/{human_female_medic.ogg => human/female/medic.ogg} (100%)
rename sound/voice/{human_female_moan_1.ogg => human/female/moan_1.ogg} (100%)
rename sound/voice/{human_female_pain_1.ogg => human/female/pain_1.ogg} (100%)
rename sound/voice/{human_female_pain_2.ogg => human/female/pain_2.ogg} (100%)
rename sound/voice/{human_female_pain_3.ogg => human/female/pain_3.ogg} (100%)
rename sound/voice/{human_female_preburst1.ogg => human/female/preburst1.ogg} (100%)
rename sound/voice/{human_female_preburst2.ogg => human/female/preburst2.ogg} (100%)
rename sound/voice/{human_female_preburst3.ogg => human/female/preburst3.ogg} (100%)
rename sound/voice/{human_female_scream_1.ogg => human/female/scream_1.ogg} (100%)
rename sound/voice/{human_female_scream_2.ogg => human/female/scream_2.ogg} (100%)
rename sound/voice/{human_female_scream_3.ogg => human/female/scream_3.ogg} (100%)
rename sound/voice/{human_female_scream_4.ogg => human/female/scream_4.ogg} (100%)
rename sound/voice/{human_female_scream_5.ogg => human/female/scream_5.ogg} (100%)
rename sound/voice/{human_female_sigh_1.ogg => human/female/sigh_1.ogg} (100%)
rename sound/voice/{human_female_warcry_1.ogg => human/female/warcry_1.ogg} (100%)
rename sound/voice/{human_female_warcry_10.ogg => human/female/warcry_10.ogg} (100%)
rename sound/voice/{human_female_warcry_11.ogg => human/female/warcry_11.ogg} (100%)
rename sound/voice/{human_female_warcry_12.ogg => human/female/warcry_12.ogg} (100%)
rename sound/voice/{human_female_warcry_13.ogg => human/female/warcry_13.ogg} (100%)
rename sound/voice/{human_female_warcry_14.ogg => human/female/warcry_14.ogg} (100%)
rename sound/voice/{human_female_warcry_15.ogg => human/female/warcry_15.ogg} (100%)
rename sound/voice/{human_female_warcry_16.ogg => human/female/warcry_16.ogg} (100%)
rename sound/voice/{human_female_warcry_17.ogg => human/female/warcry_17.ogg} (100%)
rename sound/voice/{human_female_warcry_18.ogg => human/female/warcry_18.ogg} (100%)
rename sound/voice/{human_female_warcry_19.ogg => human/female/warcry_19.ogg} (100%)
rename sound/voice/{human_female_warcry_2.ogg => human/female/warcry_2.ogg} (100%)
rename sound/voice/{human_female_warcry_3.ogg => human/female/warcry_3.ogg} (100%)
rename sound/voice/{human_female_warcry_4.ogg => human/female/warcry_4.ogg} (100%)
rename sound/voice/{human_female_warcry_5.ogg => human/female/warcry_5.ogg} (100%)
rename sound/voice/{human_female_warcry_6.ogg => human/female/warcry_6.ogg} (100%)
rename sound/voice/{human_female_warcry_7.ogg => human/female/warcry_7.ogg} (100%)
rename sound/voice/{human_female_warcry_8.ogg => human/female/warcry_8.ogg} (100%)
rename sound/voice/{human_female_warcry_9.ogg => human/female/warcry_9.ogg} (100%)
rename sound/voice/{human_female_yawn_1.ogg => human/female/yawn_1.ogg} (100%)
rename sound/voice/{human_male_cough1.ogg => human/male/cough1.ogg} (100%)
rename sound/voice/{human_male_cough2.ogg => human/male/cough2.ogg} (100%)
rename sound/voice/{human_male_cry_1.ogg => human/male/cry_1.ogg} (100%)
rename sound/voice/{human_male_facehugged1.ogg => human/male/facehugged1.ogg} (100%)
rename sound/voice/{human_male_facehugged2.ogg => human/male/facehugged2.ogg} (100%)
rename sound/voice/{human_male_facehugged3.ogg => human/male/facehugged3.ogg} (100%)
rename sound/voice/{human_male_gasp1.ogg => human/male/gasp1.ogg} (100%)
rename sound/voice/{human_male_gasp2.ogg => human/male/gasp2.ogg} (100%)
rename sound/voice/{human_male_gasp3.ogg => human/male/gasp3.ogg} (100%)
rename sound/voice/{human_male_giggle_1.ogg => human/male/giggle_1.ogg} (100%)
rename sound/voice/{human_male_gored3.ogg => human/male/gored3.ogg} (100%)
rename sound/voice/{human_male_gored_1.ogg => human/male/gored_1.ogg} (100%)
rename sound/voice/{human_male_gored_2.ogg => human/male/gored_2.ogg} (100%)
rename sound/voice/{human_male_grenadethrow_1.ogg => human/male/grenadethrow_1.ogg} (100%)
rename sound/voice/{human_male_grenadethrow_2.ogg => human/male/grenadethrow_2.ogg} (100%)
rename sound/voice/{human_male_grenadethrow_3.ogg => human/male/grenadethrow_3.ogg} (100%)
rename sound/voice/{human_male_laugh_1.ogg => human/male/laugh_1.ogg} (100%)
rename sound/voice/{human_male_laugh_2.ogg => human/male/laugh_2.ogg} (100%)
rename sound/voice/{human_male_medic.ogg => human/male/medic.ogg} (100%)
rename sound/voice/{human_male_medic2.ogg => human/male/medic2.ogg} (100%)
rename sound/voice/{human_male_moan_1.ogg => human/male/moan_1.ogg} (100%)
rename sound/voice/{human_male_pain_1.ogg => human/male/pain_1.ogg} (100%)
rename sound/voice/{human_male_pain_10.ogg => human/male/pain_10.ogg} (100%)
rename sound/voice/{human_male_pain_11.ogg => human/male/pain_11.ogg} (100%)
rename sound/voice/{human_male_pain_2.ogg => human/male/pain_2.ogg} (100%)
rename sound/voice/{human_male_pain_3.ogg => human/male/pain_3.ogg} (100%)
rename sound/voice/{human_male_pain_4.ogg => human/male/pain_4.ogg} (100%)
rename sound/voice/{human_male_pain_5.ogg => human/male/pain_5.ogg} (100%)
rename sound/voice/{human_male_pain_6.ogg => human/male/pain_6.ogg} (100%)
rename sound/voice/{human_male_pain_7.ogg => human/male/pain_7.ogg} (100%)
rename sound/voice/{human_male_pain_8.ogg => human/male/pain_8.ogg} (100%)
rename sound/voice/{human_male_pain_9.ogg => human/male/pain_9.ogg} (100%)
rename sound/voice/{human_male_preburst1.ogg => human/male/preburst1.ogg} (100%)
rename sound/voice/{human_male_preburst10.ogg => human/male/preburst10.ogg} (100%)
rename sound/voice/{human_male_preburst2.ogg => human/male/preburst2.ogg} (100%)
rename sound/voice/{human_male_preburst3.ogg => human/male/preburst3.ogg} (100%)
rename sound/voice/{human_male_preburst4.ogg => human/male/preburst4.ogg} (100%)
rename sound/voice/{human_male_preburst5.ogg => human/male/preburst5.ogg} (100%)
rename sound/voice/{human_male_preburst6.ogg => human/male/preburst6.ogg} (100%)
rename sound/voice/{human_male_preburst7.ogg => human/male/preburst7.ogg} (100%)
rename sound/voice/{human_male_preburst8.ogg => human/male/preburst8.ogg} (100%)
rename sound/voice/{human_male_preburst9.ogg => human/male/preburst9.ogg} (100%)
rename sound/voice/{human_male_scream_1.ogg => human/male/scream_1.ogg} (100%)
rename sound/voice/{human_male_scream_2.ogg => human/male/scream_2.ogg} (100%)
rename sound/voice/{human_male_scream_3.ogg => human/male/scream_3.ogg} (100%)
rename sound/voice/{human_male_scream_4.ogg => human/male/scream_4.ogg} (100%)
rename sound/voice/{human_male_scream_5.ogg => human/male/scream_5.ogg} (100%)
rename sound/voice/{human_male_scream_6.ogg => human/male/scream_6.ogg} (100%)
rename sound/voice/{human_male_scream_7.ogg => human/male/scream_7.ogg} (100%)
rename sound/voice/{human_male_sigh_1.ogg => human/male/sigh_1.ogg} (100%)
rename sound/voice/{human_male_warcry_1.ogg => human/male/warcry_1.ogg} (100%)
rename sound/voice/{human_male_warcry_10.ogg => human/male/warcry_10.ogg} (100%)
rename sound/voice/{human_male_warcry_11.ogg => human/male/warcry_11.ogg} (100%)
rename sound/voice/{human_male_warcry_12.ogg => human/male/warcry_12.ogg} (100%)
rename sound/voice/{human_male_warcry_13.ogg => human/male/warcry_13.ogg} (100%)
rename sound/voice/{human_male_warcry_14.ogg => human/male/warcry_14.ogg} (100%)
rename sound/voice/{human_male_warcry_15.ogg => human/male/warcry_15.ogg} (100%)
rename sound/voice/{human_male_warcry_16.ogg => human/male/warcry_16.ogg} (100%)
rename sound/voice/{human_male_warcry_17.ogg => human/male/warcry_17.ogg} (100%)
rename sound/voice/{human_male_warcry_18.ogg => human/male/warcry_18.ogg} (100%)
rename sound/voice/{human_male_warcry_19.ogg => human/male/warcry_19.ogg} (100%)
rename sound/voice/{human_male_warcry_2.ogg => human/male/warcry_2.ogg} (100%)
rename sound/voice/{human_male_warcry_20.ogg => human/male/warcry_20.ogg} (100%)
rename sound/voice/{human_male_warcry_21.ogg => human/male/warcry_21.ogg} (100%)
rename sound/voice/{human_male_warcry_22.ogg => human/male/warcry_22.ogg} (100%)
rename sound/voice/{human_male_warcry_23.ogg => human/male/warcry_23.ogg} (100%)
rename sound/voice/{human_male_warcry_24.ogg => human/male/warcry_24.ogg} (100%)
rename sound/voice/{human_male_warcry_25.ogg => human/male/warcry_25.ogg} (100%)
rename sound/voice/{human_male_warcry_26.ogg => human/male/warcry_26.ogg} (100%)
rename sound/voice/{human_male_warcry_27.ogg => human/male/warcry_27.ogg} (100%)
rename sound/voice/{human_male_warcry_28.ogg => human/male/warcry_28.ogg} (100%)
rename sound/voice/{human_male_warcry_29.ogg => human/male/warcry_29.ogg} (100%)
rename sound/voice/{human_male_warcry_3.ogg => human/male/warcry_3.ogg} (100%)
rename sound/voice/{human_male_warcry_4.ogg => human/male/warcry_4.ogg} (100%)
rename sound/voice/{human_male_warcry_5.ogg => human/male/warcry_5.ogg} (100%)
rename sound/voice/{human_male_warcry_6.ogg => human/male/warcry_6.ogg} (100%)
rename sound/voice/{human_male_warcry_7.ogg => human/male/warcry_7.ogg} (100%)
rename sound/voice/{human_male_warcry_8.ogg => human/male/warcry_8.ogg} (100%)
rename sound/voice/{human_male_warcry_9.ogg => human/male/warcry_9.ogg} (100%)
rename sound/voice/{human_male_yawn_1.ogg => human/male/yawn_1.ogg} (100%)
rename sound/voice/{sound_voice_human_whistle1.ogg => human/whistle1.ogg} (100%)
delete mode 100644 sound/voice/liveagain.ogg
rename sound/voice/{pred_anytime.ogg => predator/anytime.ogg} (100%)
rename sound/voice/{pred_click1.ogg => predator/click1.ogg} (100%)
rename sound/voice/{pred_click2.ogg => predator/click2.ogg} (100%)
rename sound/voice/{pred_click3.ogg => predator/click3.ogg} (100%)
rename sound/voice/{pred_click4.ogg => predator/click4.ogg} (100%)
rename sound/voice/{pred_click5.ogg => predator/click5.ogg} (100%)
rename sound/voice/{pred_come_on_out.ogg => predator/come_on_out.ogg} (100%)
rename sound/voice/{pred_deathlaugh.ogg => predator/deathlaugh.ogg} (100%)
rename sound/voice/{pred_facehugged.ogg => predator/facehugged.ogg} (100%)
rename sound/voice/{pred_helpme.ogg => predator/helpme.ogg} (100%)
rename sound/voice/{pred_itsatrap.ogg => predator/itsatrap.ogg} (100%)
rename sound/voice/{pred_laugh1.ogg => predator/laugh1.ogg} (100%)
rename sound/voice/{pred_laugh2.ogg => predator/laugh2.ogg} (100%)
rename sound/voice/{pred_laugh3.ogg => predator/laugh3.ogg} (100%)
rename sound/voice/{pred_laugh4.ogg => predator/laugh4.ogg} (100%)
rename sound/voice/{pred_over_there.ogg => predator/over_there.ogg} (100%)
rename sound/voice/{pred_overhere.ogg => predator/overhere.ogg} (100%)
rename sound/voice/{pred_pain1.ogg => predator/pain1.ogg} (100%)
rename sound/voice/{pred_pain2.ogg => predator/pain2.ogg} (100%)
rename sound/voice/{pred_pain3.ogg => predator/pain3.ogg} (100%)
rename sound/voice/{pred_pain4.ogg => predator/pain4.ogg} (100%)
rename sound/voice/{pred_pain5.ogg => predator/pain5.ogg} (100%)
rename sound/voice/{pred_pain_rare1.ogg => predator/pain_rare1.ogg} (100%)
rename sound/voice/{pred_roar1.ogg => predator/roar1.ogg} (100%)
rename sound/voice/{pred_roar2.ogg => predator/roar2.ogg} (100%)
rename sound/voice/{pred_roar3.ogg => predator/roar3.ogg} (100%)
rename sound/voice/{pred_roar4.ogg => predator/roar4.ogg} (100%)
rename sound/voice/{pred_roar5.ogg => predator/roar5.ogg} (100%)
rename sound/voice/{pred_turnaround.ogg => predator/turnaround.ogg} (100%)
rename sound/voice/{pred_ugly_freak.ogg => predator/ugly_freak.ogg} (100%)
rename sound/voice/{pred_warcry.ogg => predator/warcry.ogg} (100%)
diff --git a/code/__DEFINES/footsteps.dm b/code/__DEFINES/footsteps.dm
index 31d7b858e89..1d32f06317b 100644
--- a/code/__DEFINES/footsteps.dm
+++ b/code/__DEFINES/footsteps.dm
@@ -67,8 +67,8 @@ GLOBAL_LIST_INIT(shoefootstep, list(
'sound/effects/footstep/water3.ogg',
'sound/effects/footstep/water4.ogg'), 100, 1),
FOOTSTEP_RESIN = list(list(
- 'sound/effects/footstep/alien_resin_move1.ogg',
- 'sound/effects/footstep/alien_resin_move2.ogg',), 50, 2),
+ 'sound/effects/footstep/alien/resin_move1.ogg',
+ 'sound/effects/footstep/alien/resin_move2.ogg',), 50, 2),
FOOTSTEP_CATWALK = list(list(
'sound/effects/footstep/catwalk1.ogg',
'sound/effects/footstep/catwalk2.ogg',
@@ -156,8 +156,8 @@ GLOBAL_LIST_INIT(barefootstep, list(
'sound/effects/footstep/water3.ogg',
'sound/effects/footstep/water4.ogg'), 100, 1),
FOOTSTEP_RESIN = list(list(
- 'sound/effects/footstep/alien_resin_move1.ogg',
- 'sound/effects/footstep/alien_resin_move2.ogg',), 70, 2),
+ 'sound/effects/footstep/alien/resin_move1.ogg',
+ 'sound/effects/footstep/alien/resin_move2.ogg',), 70, 2),
FOOTSTEP_CATWALK = list(list(
'sound/effects/footstep/catwalk1.ogg',
'sound/effects/footstep/catwalk2.ogg',
@@ -246,8 +246,8 @@ GLOBAL_LIST_INIT(xenomediumstep, list(
'sound/effects/footstep/water3.ogg',
'sound/effects/footstep/water4.ogg'), 50, 1),
FOOTSTEP_RESIN = list(list(
- 'sound/effects/footstep/alien_resin_move1.ogg',
- 'sound/effects/footstep/alien_resin_move2.ogg',), 15, -4),
+ 'sound/effects/footstep/alien/resin_move1.ogg',
+ 'sound/effects/footstep/alien/resin_move2.ogg',), 15, -4),
FOOTSTEP_CATWALK = list(list(
'sound/effects/footstep/catwalk1.ogg',
'sound/effects/footstep/catwalk2.ogg',
@@ -360,120 +360,120 @@ GLOBAL_LIST_INIT(xenoheavystep, list(
//claw footsteps lists
GLOBAL_LIST_INIT(xenostompy, list(
FOOTSTEP_WOOD = list(list(
- 'sound/effects/footstep/alien_footstep_large1.ogg',
- 'sound/effects/footstep/alien_footstep_large2.ogg',
- 'sound/effects/footstep/alien_footstep_large3.ogg'), 60, 1),
+ 'sound/effects/footstep/alien/large1.ogg',
+ 'sound/effects/footstep/alien/large2.ogg',
+ 'sound/effects/footstep/alien/large3.ogg'), 60, 1),
FOOTSTEP_PLATING = list(list(
- 'sound/effects/footstep/alien_footstep_large1.ogg',
- 'sound/effects/footstep/alien_footstep_large2.ogg',
- 'sound/effects/footstep/alien_footstep_large3.ogg'), 70, 1),
+ 'sound/effects/footstep/alien/large1.ogg',
+ 'sound/effects/footstep/alien/large2.ogg',
+ 'sound/effects/footstep/alien/large3.ogg'), 70, 1),
FOOTSTEP_FLOOR = list(list(
- 'sound/effects/footstep/alien_footstep_large1.ogg',
- 'sound/effects/footstep/alien_footstep_large2.ogg',
- 'sound/effects/footstep/alien_footstep_large3.ogg'), 70, 1),
+ 'sound/effects/footstep/alien/large1.ogg',
+ 'sound/effects/footstep/alien/large2.ogg',
+ 'sound/effects/footstep/alien/large3.ogg'), 70, 1),
FOOTSTEP_HARD = list(list(
- 'sound/effects/footstep/alien_footstep_large1.ogg',
- 'sound/effects/footstep/alien_footstep_large2.ogg',
- 'sound/effects/footstep/alien_footstep_large3.ogg'), 70, 1),
+ 'sound/effects/footstep/alien/large1.ogg',
+ 'sound/effects/footstep/alien/large2.ogg',
+ 'sound/effects/footstep/alien/large3.ogg'), 70, 1),
FOOTSTEP_CARPET = list(list(
- 'sound/effects/footstep/alien_footstep_large1.ogg',
- 'sound/effects/footstep/alien_footstep_large2.ogg',
- 'sound/effects/footstep/alien_footstep_large3.ogg'), 55, -1),
+ 'sound/effects/footstep/alien/large1.ogg',
+ 'sound/effects/footstep/alien/large2.ogg',
+ 'sound/effects/footstep/alien/large3.ogg'), 55, -1),
FOOTSTEP_SAND = list(list(
- 'sound/effects/footstep/alien_footstep_large1.ogg',
- 'sound/effects/footstep/alien_footstep_large2.ogg',
- 'sound/effects/footstep/alien_footstep_large3.ogg'), 55, 1),
+ 'sound/effects/footstep/alien/large1.ogg',
+ 'sound/effects/footstep/alien/large2.ogg',
+ 'sound/effects/footstep/alien/large3.ogg'), 55, 1),
FOOTSTEP_GRASS = list(list(
- 'sound/effects/footstep/alien_footstep_large1.ogg',
- 'sound/effects/footstep/alien_footstep_large2.ogg',
- 'sound/effects/footstep/alien_footstep_large3.ogg'), 65, 1),
+ 'sound/effects/footstep/alien/large1.ogg',
+ 'sound/effects/footstep/alien/large2.ogg',
+ 'sound/effects/footstep/alien/large3.ogg'), 65, 1),
FOOTSTEP_WATER = list(list(
'sound/effects/footstep/water1.ogg',
'sound/effects/footstep/water2.ogg',
'sound/effects/footstep/water3.ogg',
'sound/effects/footstep/water4.ogg'), 50, 1),
FOOTSTEP_CATWALK = list(list(
- 'sound/effects/footstep/alien_footstep_large1.ogg',
- 'sound/effects/footstep/alien_footstep_large2.ogg',
- 'sound/effects/footstep/alien_footstep_large3.ogg'), 70, 1),
+ 'sound/effects/footstep/alien/large1.ogg',
+ 'sound/effects/footstep/alien/large2.ogg',
+ 'sound/effects/footstep/alien/large3.ogg'), 70, 1),
FOOTSTEP_SNOW = list(list(
- 'sound/effects/footstep/alien_footstep_large1.ogg',
- 'sound/effects/footstep/alien_footstep_large2.ogg',
- 'sound/effects/footstep/alien_footstep_large3.ogg'), 70, 1),
+ 'sound/effects/footstep/alien/large1.ogg',
+ 'sound/effects/footstep/alien/large2.ogg',
+ 'sound/effects/footstep/alien/large3.ogg'), 70, 1),
FOOTSTEP_ICE = list(list(
- 'sound/effects/footstep/alien_footstep_large1.ogg',
- 'sound/effects/footstep/alien_footstep_large2.ogg',
- 'sound/effects/footstep/alien_footstep_large3.ogg'), 50, 1),
+ 'sound/effects/footstep/alien/large1.ogg',
+ 'sound/effects/footstep/alien/large2.ogg',
+ 'sound/effects/footstep/alien/large3.ogg'), 50, 1),
FOOTSTEP_CONCRETE = list(list(
- 'sound/effects/footstep/alien_footstep_large1.ogg',
- 'sound/effects/footstep/alien_footstep_large2.ogg',
- 'sound/effects/footstep/alien_footstep_large3.ogg'), 70, 1),
+ 'sound/effects/footstep/alien/large1.ogg',
+ 'sound/effects/footstep/alien/large2.ogg',
+ 'sound/effects/footstep/alien/large3.ogg'), 70, 1),
FOOTSTEP_GRAVEL = list(list(
- 'sound/effects/footstep/alien_footstep_large1.ogg',
- 'sound/effects/footstep/alien_footstep_large2.ogg',
- 'sound/effects/footstep/alien_footstep_large3.ogg'), 55, 1),
+ 'sound/effects/footstep/alien/large1.ogg',
+ 'sound/effects/footstep/alien/large2.ogg',
+ 'sound/effects/footstep/alien/large3.ogg'), 55, 1),
FOOTSTEP_RESIN = list(list(
- 'sound/effects/footstep/alien_footstep_large1.ogg',
- 'sound/effects/footstep/alien_footstep_large2.ogg',
- 'sound/effects/footstep/alien_footstep_large3.ogg'), 40, -1),
+ 'sound/effects/footstep/alien/large1.ogg',
+ 'sound/effects/footstep/alien/large2.ogg',
+ 'sound/effects/footstep/alien/large3.ogg'), 40, -1),
))
GLOBAL_LIST_INIT(predalienstompy, list(
FOOTSTEP_WOOD = list(list(
- 'sound/effects/footstep/alien_footstep_medium1.ogg',
- 'sound/effects/footstep/alien_footstep_medium2.ogg',
- 'sound/effects/footstep/alien_footstep_medium3.ogg'), 60, 1),
+ 'sound/effects/footstep/alien/medium1.ogg',
+ 'sound/effects/footstep/alien/medium2.ogg',
+ 'sound/effects/footstep/alien/medium3.ogg'), 60, 1),
FOOTSTEP_PLATING = list(list(
- 'sound/effects/footstep/alien_footstep_medium1.ogg',
- 'sound/effects/footstep/alien_footstep_medium2.ogg',
- 'sound/effects/footstep/alien_footstep_medium3.ogg'), 70, 1),
+ 'sound/effects/footstep/alien/medium1.ogg',
+ 'sound/effects/footstep/alien/medium2.ogg',
+ 'sound/effects/footstep/alien/medium3.ogg'), 70, 1),
FOOTSTEP_FLOOR = list(list(
- 'sound/effects/footstep/alien_footstep_medium1.ogg',
- 'sound/effects/footstep/alien_footstep_medium2.ogg',
- 'sound/effects/footstep/alien_footstep_medium3.ogg'), 70, 1),
+ 'sound/effects/footstep/alien/medium1.ogg',
+ 'sound/effects/footstep/alien/medium2.ogg',
+ 'sound/effects/footstep/alien/medium3.ogg'), 70, 1),
FOOTSTEP_HARD = list(list(
- 'sound/effects/footstep/alien_footstep_medium1.ogg',
- 'sound/effects/footstep/alien_footstep_medium2.ogg',
- 'sound/effects/footstep/alien_footstep_medium3.ogg'), 70, 1),
+ 'sound/effects/footstep/alien/medium1.ogg',
+ 'sound/effects/footstep/alien/medium2.ogg',
+ 'sound/effects/footstep/alien/medium3.ogg'), 70, 1),
FOOTSTEP_CARPET = list(list(
- 'sound/effects/footstep/alien_footstep_medium1.ogg',
- 'sound/effects/footstep/alien_footstep_medium2.ogg',
- 'sound/effects/footstep/alien_footstep_medium3.ogg'), 55, -1),
+ 'sound/effects/footstep/alien/medium1.ogg',
+ 'sound/effects/footstep/alien/medium2.ogg',
+ 'sound/effects/footstep/alien/medium3.ogg'), 55, -1),
FOOTSTEP_SAND = list(list(
- 'sound/effects/footstep/alien_footstep_medium1.ogg',
- 'sound/effects/footstep/alien_footstep_medium2.ogg',
- 'sound/effects/footstep/alien_footstep_medium3.ogg'), 55, 1),
+ 'sound/effects/footstep/alien/medium1.ogg',
+ 'sound/effects/footstep/alien/medium2.ogg',
+ 'sound/effects/footstep/alien/medium3.ogg'), 55, 1),
FOOTSTEP_GRASS = list(list(
- 'sound/effects/footstep/alien_footstep_medium1.ogg',
- 'sound/effects/footstep/alien_footstep_medium2.ogg',
- 'sound/effects/footstep/alien_footstep_medium3.ogg'), 65, 1),
+ 'sound/effects/footstep/alien/medium1.ogg',
+ 'sound/effects/footstep/alien/medium2.ogg',
+ 'sound/effects/footstep/alien/medium3.ogg'), 65, 1),
FOOTSTEP_WATER = list(list(
'sound/effects/footstep/water1.ogg',
'sound/effects/footstep/water2.ogg',
'sound/effects/footstep/water3.ogg',
'sound/effects/footstep/water4.ogg'), 50, 1),
FOOTSTEP_CATWALK = list(list(
- 'sound/effects/footstep/alien_footstep_medium1.ogg',
- 'sound/effects/footstep/alien_footstep_medium2.ogg',
- 'sound/effects/footstep/alien_footstep_medium3.ogg'), 70, 1),
+ 'sound/effects/footstep/alien/medium1.ogg',
+ 'sound/effects/footstep/alien/medium2.ogg',
+ 'sound/effects/footstep/alien/medium3.ogg'), 70, 1),
FOOTSTEP_SNOW = list(list(
- 'sound/effects/footstep/alien_footstep_medium1.ogg',
- 'sound/effects/footstep/alien_footstep_medium2.ogg',
- 'sound/effects/footstep/alien_footstep_medium3.ogg'), 70, 1),
+ 'sound/effects/footstep/alien/medium1.ogg',
+ 'sound/effects/footstep/alien/medium2.ogg',
+ 'sound/effects/footstep/alien/medium3.ogg'), 70, 1),
FOOTSTEP_ICE = list(list(
- 'sound/effects/footstep/alien_footstep_medium1.ogg',
- 'sound/effects/footstep/alien_footstep_medium2.ogg',
- 'sound/effects/footstep/alien_footstep_medium3.ogg'), 50, 1),
+ 'sound/effects/footstep/alien/medium1.ogg',
+ 'sound/effects/footstep/alien/medium2.ogg',
+ 'sound/effects/footstep/alien/medium3.ogg'), 50, 1),
FOOTSTEP_CONCRETE = list(list(
- 'sound/effects/footstep/alien_footstep_medium1.ogg',
- 'sound/effects/footstep/alien_footstep_medium2.ogg',
- 'sound/effects/footstep/alien_footstep_medium3.ogg'), 70, 1),
+ 'sound/effects/footstep/alien/medium1.ogg',
+ 'sound/effects/footstep/alien/medium2.ogg',
+ 'sound/effects/footstep/alien/medium3.ogg'), 70, 1),
FOOTSTEP_GRAVEL = list(list(
- 'sound/effects/footstep/alien_footstep_medium1.ogg',
- 'sound/effects/footstep/alien_footstep_medium2.ogg',
- 'sound/effects/footstep/alien_footstep_medium3.ogg'), 55, 1),
+ 'sound/effects/footstep/alien/medium1.ogg',
+ 'sound/effects/footstep/alien/medium2.ogg',
+ 'sound/effects/footstep/alien/medium3.ogg'), 55, 1),
FOOTSTEP_RESIN = list(list(
- 'sound/effects/footstep/alien_footstep_medium1.ogg',
- 'sound/effects/footstep/alien_footstep_medium2.ogg',
- 'sound/effects/footstep/alien_footstep_medium3.ogg'), 40, -1),
+ 'sound/effects/footstep/alien/medium1.ogg',
+ 'sound/effects/footstep/alien/medium2.ogg',
+ 'sound/effects/footstep/alien/medium3.ogg'), 40, -1),
))
diff --git a/code/datums/cinematic.dm b/code/datums/cinematic.dm
index 3f77abe704d..004f93345bf 100644
--- a/code/datums/cinematic.dm
+++ b/code/datums/cinematic.dm
@@ -128,7 +128,7 @@ GLOBAL_LIST_EMPTY(cinematics)
flick("intro_nuke", screen)
sleep(runtime)
flick("station_explode_fade_red", screen)
- cinematic_sound(sound('sound/effects/explosionfar.ogg', channel = CHANNEL_CINEMATIC))
+ cinematic_sound(sound('sound/effects/explosion/far0.ogg', channel = CHANNEL_CINEMATIC))
special()
screen.icon_state = "summary_nukewin"
@@ -141,7 +141,7 @@ GLOBAL_LIST_EMPTY(cinematics)
/datum/cinematic/nuke_miss/content()
flick("intro_nuke", screen)
sleep(runtime)
- cinematic_sound(sound('sound/effects/explosionfar.ogg', channel = CHANNEL_CINEMATIC))
+ cinematic_sound(sound('sound/effects/explosion/far0.ogg', channel = CHANNEL_CINEMATIC))
special()
flick("station_intact_fade_red", screen)
screen.icon_state = "summary_nukefail"
@@ -156,7 +156,7 @@ GLOBAL_LIST_EMPTY(cinematics)
flick("intro_nuke", screen)
sleep(runtime)
flick("station_explode_fade_red", screen)
- cinematic_sound(sound('sound/effects/explosionfar.ogg', channel = CHANNEL_CINEMATIC))
+ cinematic_sound(sound('sound/effects/explosion/far0.ogg', channel = CHANNEL_CINEMATIC))
special()
screen.icon_state = "summary_selfdes"
@@ -169,7 +169,7 @@ GLOBAL_LIST_EMPTY(cinematics)
/datum/cinematic/nuke_selfdestruct_miss/content()
flick("intro_nuke", screen)
sleep(runtime)
- cinematic_sound(sound('sound/effects/explosionfar.ogg', channel = CHANNEL_CINEMATIC))
+ cinematic_sound(sound('sound/effects/explosion/far0.ogg', channel = CHANNEL_CINEMATIC))
special()
screen.icon_state = "station_intact"
@@ -183,7 +183,7 @@ GLOBAL_LIST_EMPTY(cinematics)
flick("intro_malf", screen)
sleep(runtime)
flick("station_explode_fade_red", screen)
- cinematic_sound(sound('sound/effects/explosionfar.ogg', channel = CHANNEL_CINEMATIC))
+ cinematic_sound(sound('sound/effects/explosion/far0.ogg', channel = CHANNEL_CINEMATIC))
special()
screen.icon_state = "summary_malf"
@@ -197,7 +197,7 @@ GLOBAL_LIST_EMPTY(cinematics)
flick("intro_nuke", screen)
sleep(runtime)
flick("station_explode_fade_red", screen)
- cinematic_sound(sound('sound/effects/explosionfar.ogg', channel = CHANNEL_CINEMATIC))
+ cinematic_sound(sound('sound/effects/explosion/far0.ogg', channel = CHANNEL_CINEMATIC))
special()
screen.icon_state = "summary_totala"
@@ -235,7 +235,7 @@ GLOBAL_LIST_EMPTY(cinematics)
/datum/cinematic/nuke_far/content()
- cinematic_sound(sound('sound/effects/explosionfar.ogg', channel = CHANNEL_CINEMATIC))
+ cinematic_sound(sound('sound/effects/explosion/far0.ogg', channel = CHANNEL_CINEMATIC))
special()
@@ -251,6 +251,6 @@ GLOBAL_LIST_EMPTY(cinematics)
flick("intro_nuke", screen) // 3.5 seconds
sleep(5.5 SECONDS)
flick("planet_nuke", screen) // About 1.5 seconds length
- cinematic_sound(sound('sound/effects/explosionfar.ogg', channel = CHANNEL_CINEMATIC))
+ cinematic_sound(sound('sound/effects/explosion/far0.ogg', channel = CHANNEL_CINEMATIC))
special()
screen.icon_state = "planet_end"
diff --git a/code/datums/components/suit_autodoc.dm b/code/datums/components/suit_autodoc.dm
index cac077d3328..737fcc6aeba 100644
--- a/code/datums/components/suit_autodoc.dm
+++ b/code/datums/components/suit_autodoc.dm
@@ -199,7 +199,7 @@
START_PROCESSING(SSobj, src)
if(!silent)
wearer.balloon_alert(wearer, "The automedical suite activates")
- playsound(parent,'sound/voice/b18_activate.ogg', 15, 0, 1)
+ playsound(parent,'sound/voice/b18/activate.ogg', 15, 0, 1)
/**
diff --git a/code/datums/elements/limb_support.dm b/code/datums/elements/limb_support.dm
index 057d25772f7..5d5feb41bdc 100644
--- a/code/datums/elements/limb_support.dm
+++ b/code/datums/elements/limb_support.dm
@@ -50,6 +50,6 @@
if(!dropped && ((limb.limb_status & LIMB_BROKEN) && !(limb.limb_status & LIMB_STABILIZED)))
limb.limb_status |= LIMB_STABILIZED
- playsound(worn_suit, 'sound/voice/b18_fracture.ogg', 15, 0, 1)
+ playsound(worn_suit, 'sound/voice/b18/fracture.ogg', 15, 0, 1)
to_chat(injured_mob, span_notice("You feel [worn_suit] constrict about your [limb.display_name], stabilizing it."))
playsound(worn_suit, 'sound/machines/hydraulics_1.ogg', 15, 0, 1)
diff --git a/code/datums/status_effects/xeno_buffs.dm b/code/datums/status_effects/xeno_buffs.dm
index 45ee88b8ce2..f6deb2ea740 100644
--- a/code/datums/status_effects/xeno_buffs.dm
+++ b/code/datums/status_effects/xeno_buffs.dm
@@ -751,7 +751,7 @@
new /obj/effect/temp_visual/healing(get_turf(owner))
owner.balloon_alert(owner, "Regeneration is no longer accelerated")
- owner.playsound_local(owner, 'sound/voice/hiss5.ogg', 25)
+ owner.playsound_local(owner, 'sound/voice/alien/hiss8.ogg', 25)
return ..()
diff --git a/code/game/objects/explosion_recursive.dm b/code/game/objects/explosion_recursive.dm
index 15fbc4e3ccc..20fd7a2dbaa 100644
--- a/code/game/objects/explosion_recursive.dm
+++ b/code/game/objects/explosion_recursive.dm
@@ -55,7 +55,7 @@ explosion resistance exactly as much as their health
msg_admin_ff("Explosion with Power: [power], Falloff: [falloff] in area [epicenter.loc.name] ([epicenter.x],[epicenter.y],[epicenter.z]).", src.loc.x, src.loc.y, src.loc.z [ADMIN_JMP(epicenter)])
- playsound(epicenter, 'sound/effects/explosionfar.ogg', 100, 1, round(power ^ 2, 1))
+ playsound(epicenter, 'sound/effects/explosion/far0.ogg', 100, 1, round(power ^ 2, 1))
var/sound/explosion_sound = sound(get_sfx("explosion_large"))
switch(power)
if(0 to EXPLODE_LIGHT)
diff --git a/code/game/objects/items/cocoon.dm b/code/game/objects/items/cocoon.dm
index 22d0030e892..3456de75fd4 100644
--- a/code/game/objects/items/cocoon.dm
+++ b/code/game/objects/items/cocoon.dm
@@ -5,7 +5,7 @@
icon_state = "xeno_cocoon"
density = FALSE
layer = BELOW_OBJ_LAYER
- hit_sound = 'sound/effects/alien_resin_break2.ogg'
+ hit_sound = 'sound/effects/alien/resin_break2.ogg'
max_integrity = 400
anchored = TRUE
obj_flags = CAN_BE_HIT
diff --git a/code/game/objects/items/loot_box.dm b/code/game/objects/items/loot_box.dm
index 2d2d5238a91..945d1b31605 100644
--- a/code/game/objects/items/loot_box.dm
+++ b/code/game/objects/items/loot_box.dm
@@ -173,7 +173,7 @@
if(picked)
picked.mind.transfer_to(new_xeno, TRUE)
to_chat(new_xeno, span_xenoannounce("The Queen Mother has hurled us through Bluespace, we live for the hive!"))
- new_xeno << sound('sound/effects/xeno_newlarva.ogg')
+ new_xeno << sound('sound/effects/alien/newlarva.ogg')
return INITIALIZE_HINT_QDEL
//The actual drop sets
diff --git a/code/game/objects/items/radio/headset.dm b/code/game/objects/items/radio/headset.dm
index dd36d3b7f99..7e15c50ed3f 100644
--- a/code/game/objects/items/radio/headset.dm
+++ b/code/game/objects/items/radio/headset.dm
@@ -209,7 +209,7 @@ GLOBAL_LIST_INIT(channel_tokens, list(
///Explodes the headset if you put on an enemy's headset
/obj/item/radio/headset/mainship/proc/safety_protocol(mob/living/carbon/human/user)
balloon_alert_to_viewers("Explodes")
- playsound(user, 'sound/effects/explosion_micro1.ogg', 50, 1)
+ playsound(user, 'sound/effects/explosion/micro1.ogg', 50, 1)
user.ex_act(EXPLODE_LIGHT)
qdel(src)
diff --git a/code/game/objects/structures/campaign_structures/destroy_objectives.dm b/code/game/objects/structures/campaign_structures/destroy_objectives.dm
index c4c8e855d4b..1a3d91e0dcf 100644
--- a/code/game/objects/structures/campaign_structures/destroy_objectives.dm
+++ b/code/game/objects/structures/campaign_structures/destroy_objectives.dm
@@ -216,7 +216,7 @@
layer = ABOVE_MOB_LAYER
/obj/structure/campaign_objective/destruction_objective/nt_pod/Destroy()
- playsound(loc, 'sound/voice/predalien_death.ogg', 75, 0)
+ playsound(loc, 'sound/voice/alien/predalien/death.ogg', 75, 0)
return ..()
//teleporter core
diff --git a/code/game/sound.dm b/code/game/sound.dm
index 3c908ca82a0..310dd41601c 100644
--- a/code/game/sound.dm
+++ b/code/game/sound.dm
@@ -178,17 +178,17 @@ A good representation is: 'byond applies a volume reduction to the sound every X
if("shatter")
S = pick('sound/effects/glassbr1.ogg','sound/effects/glassbr2.ogg','sound/effects/glassbr3.ogg')
if("explosion_large")
- S = pick('sound/effects/explosion_large1.ogg','sound/effects/explosion_large2.ogg','sound/effects/explosion_large3.ogg','sound/effects/explosion_large4.ogg','sound/effects/explosion_large5.ogg','sound/effects/explosion_large6.ogg')
+ S = pick('sound/effects/explosion/large1.ogg','sound/effects/explosion/large2.ogg','sound/effects/explosion/large3.ogg','sound/effects/explosion/large4.ogg','sound/effects/explosion/large5.ogg','sound/effects/explosion/large6.ogg')
if("explosion_micro")
- S = pick('sound/effects/explosion_micro1.ogg','sound/effects/explosion_micro2.ogg','sound/effects/explosion_micro3.ogg')
+ S = pick('sound/effects/explosion/micro1.ogg','sound/effects/explosion/micro2.ogg','sound/effects/explosion/micro3.ogg')
if("explosion_small")
- S = pick('sound/effects/explosion_small1.ogg','sound/effects/explosion_small2.ogg','sound/effects/explosion_small3.ogg','sound/effects/explosion_small4.ogg')
+ S = pick('sound/effects/explosion/small1.ogg','sound/effects/explosion/small2.ogg','sound/effects/explosion/small3.ogg','sound/effects/explosion/small4.ogg')
if("explosion_med")
- S = pick('sound/effects/explosion_med1.ogg','sound/effects/explosion_med2.ogg','sound/effects/explosion_med3.ogg','sound/effects/explosion_med4.ogg','sound/effects/explosion_med5.ogg','sound/effects/explosion_med6.ogg')
+ S = pick('sound/effects/explosion/medium1.ogg','sound/effects/explosion/medium2.ogg','sound/effects/explosion/medium3.ogg','sound/effects/explosion/medium4.ogg','sound/effects/explosion/medium5.ogg','sound/effects/explosion/medium6.ogg')
if("explosion_small_distant")
- S = pick('sound/effects/explosion_smallfar1.ogg','sound/effects/explosion_smallfar2.ogg','sound/effects/explosion_smallfar3.ogg','sound/effects/explosion_smallfar4.ogg')
+ S = pick('sound/effects/explosion/small_far1.ogg','sound/effects/explosion/small_far2.ogg','sound/effects/explosion/small_far3.ogg','sound/effects/explosion/small_far4.ogg')
if("explosion_large_distant")
- S = pick('sound/effects/explosion_far1.ogg','sound/effects/explosion_far2.ogg','sound/effects/explosion_far3.ogg','sound/effects/explosion_far4.ogg','sound/effects/explosion_far5.ogg')
+ S = pick('sound/effects/explosion/far1.ogg','sound/effects/explosion/far2.ogg','sound/effects/explosion/far3.ogg','sound/effects/explosion/far4.ogg','sound/effects/explosion/far5.ogg')
if("explosion_creak")
S = pick('sound/effects/creak1.ogg','sound/effects/creak2.ogg')
if("sparks")
@@ -214,7 +214,7 @@ A good representation is: 'byond applies a volume reduction to the sound every X
if("vending")
S = pick('sound/machines/vending_cans.ogg', 'sound/machines/vending_drop.ogg')
if("incendiary_explosion")
- S = pick('sound/effects/incendiary_explosion_1.ogg', 'sound/effects/incendiary_explosion_2.ogg', 'sound/effects/incendiary_explosion_3.ogg')
+ S = pick('sound/effects/explosion/incendiary1.ogg', 'sound/effects/explosion/incendiary2.ogg', 'sound/effects/explosion/incendiary3.ogg')
if("molotov")
S = pick('sound/effects/molotov_detonate_1.ogg', 'sound/effects/molotov_detonate_2.ogg', 'sound/effects/molotov_detonate_3.ogg')
if("flashbang")
@@ -279,83 +279,83 @@ A good representation is: 'byond applies a volume reduction to the sound every X
if("alien_tail_attack")
S = 'sound/weapons/alien_tail_attack.ogg'
if("alien_footstep_large")
- S = pick('sound/effects/alien_footstep_large1.ogg','sound/effects/alien_footstep_large2.ogg','sound/effects/alien_footstep_large3.ogg')
+ S = pick('sound/effects/footstep/alien/large1.ogg','sound/effects/footstep/alien/large2.ogg','sound/effects/footstep/alien/large3.ogg')
if("alien_charge")
- S = pick('sound/effects/alien_footstep_charge1.ogg','sound/effects/alien_footstep_charge2.ogg','sound/effects/alien_footstep_charge3.ogg')
+ S = pick('sound/effects/footstep/alien/charge1.ogg','sound/effects/footstep/alien/charge2.ogg','sound/effects/footstep/alien/charge3.ogg')
if("alien_resin_build")
- S = pick('sound/effects/alien_resin_build1.ogg','sound/effects/alien_resin_build2.ogg','sound/effects/alien_resin_build3.ogg')
+ S = pick('sound/effects/alien/resin_build1.ogg','sound/effects/alien/resin_build2.ogg','sound/effects/alien/resin_build3.ogg')
if("alien_resin_break")
- S = pick('sound/effects/alien_resin_break1.ogg','sound/effects/alien_resin_break2.ogg')
- if("alien_resin_move")
- S = pick('sound/effects/alien_resin_move1.ogg','sound/effects/alien_resin_move2.ogg')
+ S = pick('sound/effects/alien/resin_break1.ogg','sound/effects/alien/resin_break2.ogg')
+ if("alien_resin_move") // be aware, this isn't a footstep, footsteps are located elsewhere
+ S = pick('sound/effects/alien/resin_move1.ogg', 'sound/effects/alien/resin_move2.ogg')
if("alien_talk")
- S = pick('sound/voice/alien_talk.ogg','sound/voice/alien_talk2.ogg','sound/voice/alien_talk3.ogg')
+ S = pick('sound/voice/alien/talk.ogg','sound/voice/alien/talk2.ogg','sound/voice/alien/talk3.ogg')
if("larva_talk")
- S = pick('sound/voice/larva_talk1.ogg','sound/voice/larva_talk2.ogg','sound/voice/larva_talk3.ogg', 'sound/voice/larva_talk4.ogg')
+ S = pick('sound/voice/alien/larva/talk1.ogg','sound/voice/alien/larva/talk2.ogg','sound/voice/alien/larva/talk3.ogg', 'sound/voice/alien/larva/talk4.ogg')
if("predalien_talk")
- S = pick('sound/voice/predalien_click1.ogg','sound/voice/predalien_click2.ogg','sound/voice/predalien_click3.ogg')
+ S = pick('sound/voice/alien/predalien/click1.ogg','sound/voice/alien/predalien/click2.ogg','sound/voice/alien/predalien/click3.ogg')
if("alien_growl")
- S = pick('sound/voice/alien_growl1.ogg','sound/voice/alien_growl2.ogg','sound/voice/alien_growl3.ogg','sound/voice/alien_growl4.ogg')
+ S = pick('sound/voice/alien/growl1.ogg','sound/voice/alien/growl2.ogg','sound/voice/alien/growl3.ogg','sound/voice/alien/growl4.ogg')
if("alien_hiss")
- S = pick('sound/voice/alien_hiss1.ogg','sound/voice/alien_hiss2.ogg','sound/voice/alien_hiss3.ogg')
+ S = pick('sound/voice/alien/hiss1.ogg','sound/voice/alien/hiss2.ogg','sound/voice/alien/hiss3.ogg')
if("alien_tail_swipe")
- S = pick('sound/effects/alien_tail_swipe1.ogg','sound/effects/alien_tail_swipe2.ogg','sound/effects/alien_tail_swipe3.ogg')
+ S = pick('sound/effects/alien/tail_swipe1.ogg','sound/effects/alien/tail_swipe2.ogg','sound/effects/alien/tail_swipe3.ogg')
if("alien_help")
- S = pick('sound/voice/alien_help1.ogg','sound/voice/alien_help2.ogg')
+ S = pick('sound/voice/alien/help1.ogg','sound/voice/alien/help2.ogg')
if("alien_drool")
- S = pick('sound/voice/alien_drool1.ogg','sound/voice/alien_drool2.ogg')
+ S = pick('sound/voice/alien/drool1.ogg','sound/voice/alien/drool2.ogg')
if("alien_roar")
- S = pick('sound/voice/alien_roar1.ogg','sound/voice/alien_roar2.ogg','sound/voice/alien_roar3.ogg','sound/voice/alien_roar4.ogg','sound/voice/alien_roar5.ogg','sound/voice/alien_roar6.ogg','sound/voice/alien_roar7.ogg','sound/voice/alien_roar8.ogg','sound/voice/alien_roar9.ogg','sound/voice/alien_roar10.ogg','sound/voice/alien_roar11.ogg','sound/voice/alien_roar12.ogg')
+ S = pick('sound/voice/alien/roar1.ogg','sound/voice/alien/roar2.ogg','sound/voice/alien/roar3.ogg','sound/voice/alien/roar4.ogg','sound/voice/alien/roar5.ogg','sound/voice/alien/roar6.ogg','sound/voice/alien/roar7.ogg','sound/voice/alien/roar8.ogg','sound/voice/alien/roar9.ogg','sound/voice/alien/roar10.ogg','sound/voice/alien/roar11.ogg','sound/voice/alien/roar12.ogg')
if("alien_roar_larva")
- S = pick('sound/voice/alien_roar_larva1.ogg','sound/voice/alien_roar_larva2.ogg','sound/voice/alien_roar_larva3.ogg','sound/voice/alien_roar_larva4.ogg')
+ S = pick('sound/voice/alien/larva/roar1.ogg','sound/voice/alien/larva/roar2.ogg','sound/voice/alien/larva/roar3.ogg','sound/voice/alien/larva/roar4.ogg')
if("queen")
- S = pick('sound/voice/alien_queen_command.ogg','sound/voice/alien_queen_command2.ogg','sound/voice/alien_queen_command3.ogg')
+ S = pick('sound/voice/alien/queen/command.ogg','sound/voice/alien/queen/command2.ogg','sound/voice/alien/queen/command3.ogg')
if("alien_ventpass")
- S = pick('sound/effects/alien_ventpass1.ogg', 'sound/effects/alien_ventpass2.ogg')
+ S = pick('sound/effects/alien/ventpass1.ogg', 'sound/effects/alien/ventpass2.ogg')
if("behemoth_step_sounds")
- S = pick('sound/effects/alien_footstep_large1.ogg', 'sound/effects/alien_footstep_large2.ogg', 'sound/effects/alien_footstep_large3.ogg')
+ S = pick('sound/effects/footstep/alien/large1.ogg', 'sound/effects/footstep/alien/large2.ogg', 'sound/effects/footstep/alien/large3.ogg')
if("behemoth_rolling")
- S = 'sound/effects/behemoth/behemoth_roll.ogg'
+ S = 'sound/effects/alien/behemoth/roll.ogg'
if("behemoth_earth_pillar_hit")
- S = pick('sound/effects/behemoth/earth_pillar_hit_1.ogg', 'sound/effects/behemoth/earth_pillar_hit_2.ogg', 'sound/effects/behemoth/earth_pillar_hit_3.ogg', 'sound/effects/behemoth/earth_pillar_hit_4.ogg', 'sound/effects/behemoth/earth_pillar_hit_5.ogg', 'sound/effects/behemoth/earth_pillar_hit_6.ogg')
+ S = pick('sound/effects/alien/behemoth/earth_pillar_hit_1.ogg', 'sound/effects/alien/behemoth/earth_pillar_hit_2.ogg', 'sound/effects/alien/behemoth/earth_pillar_hit_3.ogg', 'sound/effects/alien/behemoth/earth_pillar_hit_4.ogg', 'sound/effects/alien/behemoth/earth_pillar_hit_5.ogg', 'sound/effects/alien/behemoth/earth_pillar_hit_6.ogg')
// Human
if("male_scream")
- S = pick('sound/voice/human_male_scream_1.ogg','sound/voice/human_male_scream_2.ogg','sound/voice/human_male_scream_3.ogg','sound/voice/human_male_scream_4.ogg','sound/voice/human_male_scream_5.ogg','sound/voice/human_male_scream_6.ogg', 'sound/voice/human_male_scream_7.ogg')
+ S = pick('sound/voice/human/male/scream_1.ogg','sound/voice/human/male/scream_2.ogg','sound/voice/human/male/scream_3.ogg','sound/voice/human/male/scream_4.ogg','sound/voice/human/male/scream_5.ogg','sound/voice/human/male/scream_6.ogg', 'sound/voice/human/male/scream_7.ogg')
if("male_pain")
- S = pick('sound/voice/human_male_pain_1.ogg','sound/voice/human_male_pain_2.ogg','sound/voice/human_male_pain_3.ogg','sound/voice/human_male_pain_4.ogg','sound/voice/human_male_pain_5.ogg','sound/voice/human_male_pain_6.ogg','sound/voice/human_male_pain_7.ogg','sound/voice/human_male_pain_8.ogg', 'sound/voice/human_male_pain_9.ogg', 'sound/voice/human_male_pain_10.ogg', 'sound/voice/human_male_pain_11.ogg')
+ S = pick('sound/voice/human/male/pain_1.ogg','sound/voice/human/male/pain_2.ogg','sound/voice/human/male/pain_3.ogg','sound/voice/human/male/pain_4.ogg','sound/voice/human/male/pain_5.ogg','sound/voice/human/male/pain_6.ogg','sound/voice/human/male/pain_7.ogg','sound/voice/human/male/pain_8.ogg', 'sound/voice/human/male/pain_9.ogg', 'sound/voice/human/male/pain_10.ogg', 'sound/voice/human/male/pain_11.ogg')
if("male_gored")
- S = pick('sound/voice/human_male_gored_1.ogg','sound/voice/human_male_gored_2.ogg', 'sound/voice/human_male_gored3.ogg')
+ S = pick('sound/voice/human/male/gored_1.ogg','sound/voice/human/male/gored_2.ogg', 'sound/voice/human/male/gored3.ogg')
if("male_fragout")
- S = pick('sound/voice/human_male_grenadethrow_1.ogg', 'sound/voice/human_male_grenadethrow_2.ogg', 'sound/voice/human_male_grenadethrow_3.ogg')
+ S = pick('sound/voice/human/male/grenadethrow_1.ogg', 'sound/voice/human/male/grenadethrow_2.ogg', 'sound/voice/human/male/grenadethrow_3.ogg')
if("male_warcry")
- S = pick('sound/voice/human_male_warcry_1.ogg','sound/voice/human_male_warcry_2.ogg','sound/voice/human_male_warcry_3.ogg','sound/voice/human_male_warcry_4.ogg','sound/voice/human_male_warcry_5.ogg','sound/voice/human_male_warcry_6.ogg','sound/voice/human_male_warcry_7.ogg','sound/voice/human_male_warcry_8.ogg','sound/voice/human_male_warcry_9.ogg','sound/voice/human_male_warcry_10.ogg','sound/voice/human_male_warcry_11.ogg','sound/voice/human_male_warcry_12.ogg','sound/voice/human_male_warcry_13.ogg','sound/voice/human_male_warcry_14.ogg','sound/voice/human_male_warcry_15.ogg','sound/voice/human_male_warcry_16.ogg','sound/voice/human_male_warcry_17.ogg','sound/voice/human_male_warcry_18.ogg','sound/voice/human_male_warcry_19.ogg','sound/voice/human_male_warcry_20.ogg','sound/voice/human_male_warcry_21.ogg','sound/voice/human_male_warcry_22.ogg','sound/voice/human_male_warcry_23.ogg','sound/voice/human_male_warcry_24.ogg','sound/voice/human_male_warcry_25.ogg','sound/voice/human_male_warcry_26.ogg','sound/voice/human_male_warcry_27.ogg','sound/voice/human_male_warcry_28.ogg','sound/voice/human_male_warcry_29.ogg')
+ S = pick('sound/voice/human/male/warcry_1.ogg','sound/voice/human/male/warcry_2.ogg','sound/voice/human/male/warcry_3.ogg','sound/voice/human/male/warcry_4.ogg','sound/voice/human/male/warcry_5.ogg','sound/voice/human/male/warcry_6.ogg','sound/voice/human/male/warcry_7.ogg','sound/voice/human/male/warcry_8.ogg','sound/voice/human/male/warcry_9.ogg','sound/voice/human/male/warcry_10.ogg','sound/voice/human/male/warcry_11.ogg','sound/voice/human/male/warcry_12.ogg','sound/voice/human/male/warcry_13.ogg','sound/voice/human/male/warcry_14.ogg','sound/voice/human/male/warcry_15.ogg','sound/voice/human/male/warcry_16.ogg','sound/voice/human/male/warcry_17.ogg','sound/voice/human/male/warcry_18.ogg','sound/voice/human/male/warcry_19.ogg','sound/voice/human/male/warcry_20.ogg','sound/voice/human/male/warcry_21.ogg','sound/voice/human/male/warcry_22.ogg','sound/voice/human/male/warcry_23.ogg','sound/voice/human/male/warcry_24.ogg','sound/voice/human/male/warcry_25.ogg','sound/voice/human/male/warcry_26.ogg','sound/voice/human/male/warcry_27.ogg','sound/voice/human/male/warcry_28.ogg','sound/voice/human/male/warcry_29.ogg')
if("female_scream")
- S = pick('sound/voice/human_female_scream_1.ogg','sound/voice/human_female_scream_2.ogg','sound/voice/human_female_scream_3.ogg','sound/voice/human_female_scream_4.ogg','sound/voice/human_female_scream_5.ogg')
+ S = pick('sound/voice/human/female/scream_1.ogg','sound/voice/human/female/scream_2.ogg','sound/voice/human/female/scream_3.ogg','sound/voice/human/female/scream_4.ogg','sound/voice/human/female/scream_5.ogg')
if("female_pain")
- S = pick('sound/voice/human_female_pain_1.ogg','sound/voice/human_female_pain_2.ogg','sound/voice/human_female_pain_3.ogg')
+ S = pick('sound/voice/human/female/pain_1.ogg','sound/voice/human/female/pain_2.ogg','sound/voice/human/female/pain_3.ogg')
if("female_gored")
- S = pick('sound/voice/human_female_gored_1.ogg','sound/voice/human_female_gored_2.ogg')
+ S = pick('sound/voice/human/female/gored_1.ogg','sound/voice/human/female/gored_2.ogg')
if("female_fragout")
- S = pick("sound/voice/human_female_grenadethrow_1.ogg", 'sound/voice/human_female_grenadethrow_2.ogg', 'sound/voice/human_female_grenadethrow_3.ogg')
+ S = pick("sound/voice/human/female/grenadethrow_1.ogg", 'sound/voice/human/female/grenadethrow_2.ogg', 'sound/voice/human/female/grenadethrow_3.ogg')
if("female_warcry")
- S = pick('sound/voice/human_female_warcry_1.ogg','sound/voice/human_female_warcry_2.ogg','sound/voice/human_female_warcry_3.ogg','sound/voice/human_female_warcry_4.ogg','sound/voice/human_female_warcry_5.ogg','sound/voice/human_female_warcry_6.ogg','sound/voice/human_female_warcry_7.ogg','sound/voice/human_female_warcry_8.ogg','sound/voice/human_female_warcry_9.ogg','sound/voice/human_female_warcry_10.ogg','sound/voice/human_female_warcry_11.ogg','sound/voice/human_female_warcry_12.ogg','sound/voice/human_female_warcry_13.ogg','sound/voice/human_female_warcry_14.ogg','sound/voice/human_female_warcry_15.ogg','sound/voice/human_female_warcry_16.ogg','sound/voice/human_female_warcry_17.ogg','sound/voice/human_female_warcry_18.ogg','sound/voice/human_female_warcry_19.ogg')
+ S = pick('sound/voice/human/female/warcry_1.ogg','sound/voice/human/female/warcry_2.ogg','sound/voice/human/female/warcry_3.ogg','sound/voice/human/female/warcry_4.ogg','sound/voice/human/female/warcry_5.ogg','sound/voice/human/female/warcry_6.ogg','sound/voice/human/female/warcry_7.ogg','sound/voice/human/female/warcry_8.ogg','sound/voice/human/female/warcry_9.ogg','sound/voice/human/female/warcry_10.ogg','sound/voice/human/female/warcry_11.ogg','sound/voice/human/female/warcry_12.ogg','sound/voice/human/female/warcry_13.ogg','sound/voice/human/female/warcry_14.ogg','sound/voice/human/female/warcry_15.ogg','sound/voice/human/female/warcry_16.ogg','sound/voice/human/female/warcry_17.ogg','sound/voice/human/female/warcry_18.ogg','sound/voice/human/female/warcry_19.ogg')
if("male_hugged")
- S = pick("sound/voice/human_male_facehugged1.ogg", 'sound/voice/human_male_facehugged2.ogg', 'sound/voice/human_male_facehugged3.ogg')
+ S = pick("sound/voice/human/male/facehugged1.ogg", 'sound/voice/human/male/facehugged2.ogg', 'sound/voice/human/male/facehugged3.ogg')
if("female_hugged")
- S = pick("sound/voice/human_female_facehugged1.ogg", 'sound/voice/human_female_facehugged2.ogg')
+ S = pick("sound/voice/human/female/facehugged1.ogg", 'sound/voice/human/female/facehugged2.ogg')
if("male_gasp")
- S = pick("sound/voice/human_male_gasp1.ogg", 'sound/voice/human_male_gasp2.ogg', 'sound/voice/human_male_gasp3.ogg')
+ S = pick("sound/voice/human/male/gasp1.ogg", 'sound/voice/human/male/gasp2.ogg', 'sound/voice/human/male/gasp3.ogg')
if("female_gasp")
- S = pick("sound/voice/human_female_gasp1.ogg", 'sound/voice/human_female_gasp2.ogg')
+ S = pick("sound/voice/human/female/gasp1.ogg", 'sound/voice/human/female/gasp2.ogg')
if("male_cough")
- S = pick("sound/voice/human_male_cough1.ogg", 'sound/voice/human_male_cough2.ogg')
+ S = pick("sound/voice/human/male/cough1.ogg", 'sound/voice/human/male/cough2.ogg')
if("female_cough")
- S = pick("sound/voice/human_female_cough1.ogg", 'sound/voice/human_female_cough2.ogg')
+ S = pick("sound/voice/human/female/cough1.ogg", 'sound/voice/human/female/cough2.ogg')
if("male_preburst")
- S = pick("sound/voice/human_male_preburst1.ogg", 'sound/voice/human_male_preburst2.ogg', 'sound/voice/human_male_preburst3.ogg', 'sound/voice/human_male_preburst4.ogg', 'sound/voice/human_male_preburst5.ogg', 'sound/voice/human_male_preburst6.ogg', 'sound/voice/human_male_preburst7.ogg', 'sound/voice/human_male_preburst8.ogg', 'sound/voice/human_male_preburst9.ogg', 'sound/voice/human_male_preburst10.ogg')
+ S = pick("sound/voice/human/male/preburst1.ogg", 'sound/voice/human/male/preburst2.ogg', 'sound/voice/human/male/preburst3.ogg', 'sound/voice/human/male/preburst4.ogg', 'sound/voice/human/male/preburst5.ogg', 'sound/voice/human/male/preburst6.ogg', 'sound/voice/human/male/preburst7.ogg', 'sound/voice/human/male/preburst8.ogg', 'sound/voice/human/male/preburst9.ogg', 'sound/voice/human/male/preburst10.ogg')
if("female_preburst")
- S = pick("sound/voice/human_female_preburst1.ogg", 'sound/voice/human_female_preburst2.ogg', 'sound/voice/human_female_preburst3.ogg')
+ S = pick("sound/voice/human/female/preburst1.ogg", 'sound/voice/human/female/preburst2.ogg', 'sound/voice/human/female/preburst3.ogg')
if("jump")
S = pick('sound/effects/bounce_1.ogg','sound/effects/bounce_2.ogg','sound/effects/bounce_3.ogg','sound/effects/bounce_4.ogg')
@@ -369,15 +369,15 @@ A good representation is: 'byond applies a volume reduction to the sound every X
//yautja race
if("pred_scream")
- S = pick('sound/voice/pred_roar1.ogg','sound/voice/pred_roar2.ogg','sound/voice/pred_roar3.ogg','sound/voice/pred_roar4.ogg','sound/voice/pred_roar5.ogg')
+ S = pick('sound/voice/predator/roar1.ogg','sound/voice/predator/roar2.ogg','sound/voice/predator/roar3.ogg','sound/voice/predator/roar4.ogg','sound/voice/predator/roar5.ogg')
if("pred_pain")
- S = pick('sound/voice/pred_pain1.ogg','sound/voice/pred_pain2.ogg','sound/voice/pred_pain3.ogg','sound/voice/pred_pain4.ogg','sound/voice/pred_pain5.ogg')
+ S = pick('sound/voice/predator/pain1.ogg','sound/voice/predator/pain2.ogg','sound/voice/predator/pain3.ogg','sound/voice/predator/pain4.ogg','sound/voice/predator/pain5.ogg')
if("pred_hugged")
- S = pick('sound/voice/pred_facehugged.ogg')
+ S = pick('sound/voice/predator/facehugged.ogg')
if("pred_preburst")
- S = pick('sound/voice/pred_pain_rare1.ogg')
+ S = pick('sound/voice/predator/pain_rare1.ogg')
if("pred_warcry")
- S = pick('sound/voice/pred_warcry.ogg')
+ S = pick('sound/voice/predator/warcry.ogg')
//pred items
if("clan_sword_hit")
diff --git a/code/game/turfs/closed.dm b/code/game/turfs/closed.dm
index eb27ddf1d05..58c293c9007 100644
--- a/code/game/turfs/closed.dm
+++ b/code/game/turfs/closed.dm
@@ -58,7 +58,7 @@
. = ..()
if(isxenobehemoth(xeno_user))
xeno_user.do_attack_animation(src)
- playsound(src, 'sound/effects/behemoth/earth_pillar_eating.ogg', 10, TRUE)
+ playsound(src, 'sound/effects/alien/behemoth/earth_pillar_eating.ogg', 10, TRUE)
xeno_user.visible_message(span_xenowarning("\The [xeno_user] eats away at the [src.name]!"), \
span_xenonotice(pick(
"We eat away at the stone. It tastes good, as expected of our primary diet.",
diff --git a/code/modules/atmospherics/machinery/atmosmachinery.dm b/code/modules/atmospherics/machinery/atmosmachinery.dm
index 829f17ac96c..8a4a1c2081f 100644
--- a/code/modules/atmospherics/machinery/atmosmachinery.dm
+++ b/code/modules/atmospherics/machinery/atmosmachinery.dm
@@ -307,7 +307,7 @@
if(TIMER_COOLDOWN_CHECK(user, COOLDOWN_VENTSOUND) || silent_crawl)
return
TIMER_COOLDOWN_START(user, COOLDOWN_VENTSOUND, 3 SECONDS)
- playsound(src, pick('sound/effects/alien_ventcrawl1.ogg','sound/effects/alien_ventcrawl2.ogg'), 50, TRUE, -3)
+ playsound(src, pick('sound/effects/alien/ventcrawl1.ogg','sound/effects/alien/ventcrawl2.ogg'), 50, TRUE, -3)
diff --git a/code/modules/flufftext/Hallucination.dm b/code/modules/flufftext/Hallucination.dm
index 4f9a8438e90..61f186a7e5f 100644
--- a/code/modules/flufftext/Hallucination.dm
+++ b/code/modules/flufftext/Hallucination.dm
@@ -282,7 +282,7 @@ GLOBAL_LIST_INIT(hallucination_list, list(
if("apc sparks")
target.playsound_local(source, get_sfx("sparks"), 35, TRUE)
if("hugged")
- target.playsound_local(source, 'sound/effects/alien_egg_move.ogg', 35, TRUE)
+ target.playsound_local(source, 'sound/effects/alien/egg_move.ogg', 35, TRUE)
sleep(1 SECONDS)
target.playsound_local(source, get_sfx("[pick("male", "female")]_hugged"), 35, TRUE)
if("weed placed")
diff --git a/code/modules/mob/living/carbon/human/emote-yautja.dm b/code/modules/mob/living/carbon/human/emote-yautja.dm
index d19cadf19fd..fe38dbbfa23 100644
--- a/code/modules/mob/living/carbon/human/emote-yautja.dm
+++ b/code/modules/mob/living/carbon/human/emote-yautja.dm
@@ -3,7 +3,7 @@
/datum/emote/living/carbon/human/species/yautja/anytime
key = "anytime"
- sound = 'sound/voice/pred_anytime.ogg'
+ sound = 'sound/voice/predator/anytime.ogg'
key_third_person = "anytime"
message = "any time"
emote_type = EMOTE_AUDIBLE
@@ -16,13 +16,13 @@
/datum/emote/living/carbon/human/species/yautja/click/get_sound(mob/living/user)
if(rand(0,100) < 50)
- return 'sound/voice/pred_click1.ogg'
+ return 'sound/voice/predator/click1.ogg'
else
- return 'sound/voice/pred_click2.ogg'
+ return 'sound/voice/predator/click2.ogg'
/datum/emote/living/carbon/human/species/yautja/helpme
key = "helpme"
- sound = 'sound/voice/pred_helpme.ogg'
+ sound = 'sound/voice/predator/helpme.ogg'
key_third_person = "helpme"
message = "help me!"
emote_type = EMOTE_AUDIBLE
@@ -36,42 +36,42 @@
/datum/emote/living/carbon/human/species/yautja/itsatrap
key = "itsatrap"
- sound = 'sound/voice/pred_itsatrap.ogg'
+ sound = 'sound/voice/predator/itsatrap.ogg'
key_third_person = "itsatrap"
message = "it's a trap!"
emote_type = EMOTE_AUDIBLE
/datum/emote/living/carbon/human/species/yautja/laugh1
key = "laugh1"
- sound = 'sound/voice/pred_laugh1.ogg'
+ sound = 'sound/voice/predator/laugh1.ogg'
key_third_person = "laugh1"
message = "laughs"
emote_type = EMOTE_AUDIBLE
/datum/emote/living/carbon/human/species/yautja/laugh2
key = "laugh2"
- sound = 'sound/voice/pred_laugh2.ogg'
+ sound = 'sound/voice/predator/laugh2.ogg'
key_third_person = "laugh2"
message = "laughs"
emote_type = EMOTE_AUDIBLE
/datum/emote/living/carbon/human/species/yautja/laugh3
key = "laugh3"
- sound = 'sound/voice/pred_laugh3.ogg'
+ sound = 'sound/voice/predator/laugh3.ogg'
key_third_person = "laugh3"
message = "laughs"
emote_type = EMOTE_AUDIBLE
/datum/emote/living/carbon/human/species/yautja/laugh4
key = "laugh4"
- sound = 'sound/voice/pred_laugh4.ogg'
+ sound = 'sound/voice/predator/laugh4.ogg'
key_third_person = "laugh4"
message = "laughs"
emote_type = EMOTE_AUDIBLE
/datum/emote/living/carbon/human/species/yautja/overhere
key = "overhere"
- sound = 'sound/voice/pred_overhere.ogg'
+ sound = 'sound/voice/predator/overhere.ogg'
key_third_person = "overhere"
message = "over here!"
emote_type = EMOTE_AUDIBLE
@@ -83,12 +83,12 @@
emote_type = EMOTE_AUDIBLE
/datum/emote/living/carbon/human/species/yautja/predroar/get_sound(mob/living/user)
- return pick('sound/voice/pred_roar1.ogg', 'sound/voice/pred_roar2.ogg')
+ return pick('sound/voice/predator/roar1.ogg', 'sound/voice/predator/roar2.ogg')
/datum/emote/living/carbon/human/species/yautja/predroar2
key = "predroar2"
key_third_person = "predroars2"
- sound = 'sound/voice/pred_roar3.ogg'
+ sound = 'sound/voice/predator/roar3.ogg'
message = "roars!"
emote_type = EMOTE_AUDIBLE
@@ -100,7 +100,7 @@
emote_type = EMOTE_AUDIBLE
/datum/emote/living/carbon/human/species/yautja/loudroar/get_sound(mob/living/user)
- return pick('sound/voice/pred_roar4.ogg', 'sound/voice/pred_roar5.ogg')
+ return pick('sound/voice/predator/roar4.ogg', 'sound/voice/predator/roar5.ogg')
/datum/emote/living/carbon/human/species/yautja/loudroar/run_emote(mob/user, params, type_override, intentional)
. = ..()
@@ -118,7 +118,7 @@
key = "turnaround"
key_third_person = "turnaround"
message = "turn around!"
- sound = 'sound/voice/pred_turnaround.ogg'
+ sound = 'sound/voice/predator/turnaround.ogg'
emote_type = EMOTE_AUDIBLE
/datum/emote/living/carbon/human/species/yautja/click2
@@ -128,7 +128,7 @@
emote_type = EMOTE_AUDIBLE
/datum/emote/living/carbon/human/species/yautja/click2/get_sound(mob/living/user)
- return pick('sound/voice/pred_click3.ogg', 'sound/voice/pred_click4.ogg')
+ return pick('sound/voice/predator/click3.ogg', 'sound/voice/predator/click4.ogg')
/datum/emote/living/carbon/human/species/yautja/aliengrowl
key = "aliengrowl"
@@ -137,7 +137,7 @@
emote_type = EMOTE_AUDIBLE
/datum/emote/living/carbon/human/species/yautja/aliengrowl/get_sound(mob/living/user)
- return pick('sound/voice/alien_growl1.ogg', 'sound/voice/alien_growl2.ogg')
+ return pick('sound/voice/alien/growl1.ogg', 'sound/voice/alien/growl2.ogg')
/datum/emote/living/carbon/human/species/yautja/alienhelp
key = "alienhelp"
@@ -146,25 +146,25 @@
emote_type = EMOTE_AUDIBLE
/datum/emote/living/carbon/human/species/yautja/alienhelp/get_sound(mob/living/user)
- return pick('sound/voice/alien_help1.ogg', 'sound/voice/alien_help2.ogg')
+ return pick('sound/voice/alien/help1.ogg', 'sound/voice/alien/help2.ogg')
/datum/emote/living/carbon/human/species/yautja/comeonout
key = "comeonout"
key_third_person = "comeonout"
message = "come on out!"
- sound = 'sound/voice/pred_come_on_out.ogg'
+ sound = 'sound/voice/predator/come_on_out.ogg'
emote_type = EMOTE_AUDIBLE
/datum/emote/living/carbon/human/species/yautja/overthere
key = "overthere"
key_third_person = "overthere"
message = "over there!"
- sound = 'sound/voice/pred_over_there.ogg'
+ sound = 'sound/voice/predator/over_there.ogg'
emote_type = EMOTE_AUDIBLE
/datum/emote/living/carbon/human/species/yautja/uglyfreak
key = "uglyfreak"
key_third_person = "uglyfreak"
message = "ugly freak!"
- sound = 'sound/voice/pred_ugly_freak.ogg'
+ sound = 'sound/voice/predator/ugly_freak.ogg'
emote_type = EMOTE_AUDIBLE
diff --git a/code/modules/mob/living/carbon/human/emote.dm b/code/modules/mob/living/carbon/human/emote.dm
index d6731448d08..a20ec4301f1 100644
--- a/code/modules/mob/living/carbon/human/emote.dm
+++ b/code/modules/mob/living/carbon/human/emote.dm
@@ -373,12 +373,12 @@
/datum/emote/living/carbon/human/laugh/get_sound(mob/living/user)
//RUTGMC EDIT
if(isyautja(user))
- return pick('sound/voice/pred_laugh1.ogg', 'sound/voice/pred_laugh2.ogg', 'sound/voice/pred_laugh3.ogg', 'sound/voice/pred_laugh4.ogg')
+ return pick('sound/voice/predator/laugh1.ogg', 'sound/voice/predator/laugh2.ogg', 'sound/voice/predator/laugh3.ogg', 'sound/voice/predator/laugh4.ogg')
//RUTGMC EDIT
else if(user.gender == FEMALE)
- return 'sound/voice/human_female_laugh_1.ogg'
+ return 'sound/voice/human/female/laugh_1.ogg'
else
- return pick('sound/voice/human_male_laugh_1.ogg', 'sound/voice/human_male_laugh_2.ogg')
+ return pick('sound/voice/human/male/laugh_1.ogg', 'sound/voice/human/male/laugh_2.ogg')
/datum/emote/living/carbon/human/warcry
key = "warcry"
@@ -491,11 +491,11 @@
/datum/emote/living/carbon/human/medic/get_sound(mob/living/carbon/human/user)
if(user.gender == MALE)
if(prob(95))
- return 'sound/voice/human_male_medic.ogg'
+ return 'sound/voice/human/male/medic.ogg'
else
- return 'sound/voice/human_male_medic2.ogg'
+ return 'sound/voice/human/male/medic2.ogg'
else
- return 'sound/voice/human_female_medic.ogg'
+ return 'sound/voice/human/female/medic.ogg'
/datum/emote/living/carbon/human/medic/run_emote(mob/user, params, type_override, intentional = FALSE, prefix)
@@ -590,9 +590,9 @@
if(isrobot(user))
return
if(user.gender == FEMALE)
- return 'sound/voice/human_female_sigh_1.ogg'
+ return 'sound/voice/human/female/sigh_1.ogg'
else
- return 'sound/voice/human_male_sigh_1.ogg'
+ return 'sound/voice/human/male/sigh_1.ogg'
/datum/emote/living/carbon/human/giggle/get_sound(mob/living/user)
@@ -602,36 +602,36 @@
else
return 'sound/voice/robotic/male_giggle.ogg'
if(user.gender == FEMALE)
- return 'sound/voice/human_female_giggle_1.ogg'
+ return 'sound/voice/human/female/giggle_1.ogg'
else
- return 'sound/voice/human_male_giggle_1.ogg'
+ return 'sound/voice/human/male/giggle_1.ogg'
/datum/emote/living/carbon/human/yawn/get_sound(mob/living/user)
if(isrobot(user))
return
if(user.gender == FEMALE)
- return 'sound/voice/human_female_yawn_1.ogg'
+ return 'sound/voice/human/female/yawn_1.ogg'
else
- return 'sound/voice/human_male_yawn_1.ogg'
+ return 'sound/voice/human/male/yawn_1.ogg'
/datum/emote/living/carbon/human/moan/get_sound(mob/living/user)
if(isrobot(user))
return
if(user.gender == FEMALE)
- return 'sound/voice/human_female_moan_1.ogg'
+ return 'sound/voice/human/female/moan_1.ogg'
else
- return 'sound/voice/human_male_moan_1.ogg'
+ return 'sound/voice/human/male/moan_1.ogg'
/datum/emote/living/carbon/human/cry/get_sound(mob/living/user)
if(isrobot(user))
return
if(user.gender == FEMALE)
- return 'sound/voice/human_female_cry_1.ogg'
+ return 'sound/voice/human/female/cry_1.ogg'
else
- return 'sound/voice/human_male_cry_1.ogg'
+ return 'sound/voice/human/male/cry_1.ogg'
/datum/emote/living/carbon/human/laugh/get_sound(mob/living/user)
if(isrobot(user))
@@ -661,7 +661,7 @@
/datum/emote/living/carbon/human/whistle/get_sound(mob/living/user)
if(isrobot(user))
return
- return 'sound/voice/sound_voice_human_whistle1.ogg'
+ return 'sound/voice/human/whistle1.ogg'
/datum/emote/living/carbon/human/crack
key = "crack"
diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm
index 088d6eb9f0a..7ab04b5c0d9 100644
--- a/code/modules/mob/living/carbon/human/species.dm
+++ b/code/modules/mob/living/carbon/human/species.dm
@@ -744,7 +744,7 @@
preferences = list("moth_wings" = "Wings")
screams = list("neuter" = 'sound/voice/moth_scream.ogg')
- paincries = list("neuter" = 'sound/voice/human_male_pain_3.ogg')
+ paincries = list("neuter" = 'sound/voice/human/male/pain_3.ogg')
goredcries = list("neuter" = 'sound/voice/moth_scream.ogg')
burstscreams = list("neuter" = 'sound/voice/moth_scream.ogg')
warcries = list("neuter" = 'sound/voice/moth_scream.ogg')
diff --git a/code/modules/mob/living/carbon/human/yautja.dm b/code/modules/mob/living/carbon/human/yautja.dm
index afbf2b67103..0b5f8433b24 100644
--- a/code/modules/mob/living/carbon/human/yautja.dm
+++ b/code/modules/mob/living/carbon/human/yautja.dm
@@ -33,7 +33,7 @@
max_stamina = 250
blood_color = "#20d450"
flesh_color = "#907E4A"
- speech_sounds = list('sound/voice/pred_click1.ogg', 'sound/voice/pred_click2.ogg')
+ speech_sounds = list('sound/voice/predator/click1.ogg', 'sound/voice/predator/click2.ogg')
speech_chance = 100
death_message = "clicks in agony and falls still, motionless and completely lifeless..."
@@ -254,7 +254,7 @@ var/global/image/hud_icon_hunter_thralled
/mob/living/carbon/human/species/yautja/send_speech(message_raw, message_range = 6, obj/source = src, bubble_type = bubble_icon, list/spans, datum/language/message_language=null, message_mode, tts_message, list/tts_filter)
. = ..()
- playsound(loc, pick('sound/voice/pred_click1.ogg', 'sound/voice/pred_click2.ogg'), 25, 1)
+ playsound(loc, pick('sound/voice/predator/click1.ogg', 'sound/voice/predator/click2.ogg'), 25, 1)
/mob/living/carbon/human/species/yautja/get_idcard(hand_first = TRUE)
. = ..()
diff --git a/code/modules/mob/living/carbon/xenomorph/abilities.dm b/code/modules/mob/living/carbon/xenomorph/abilities.dm
index 8eafcf3a1ae..b9331768eaf 100644
--- a/code/modules/mob/living/carbon/xenomorph/abilities.dm
+++ b/code/modules/mob/living/carbon/xenomorph/abilities.dm
@@ -704,7 +704,7 @@
/datum/action/ability/activable/xeno/spray_acid/on_cooldown_finish()
- playsound(owner.loc, 'sound/voice/alien_drool1.ogg', 50, 1)
+ playsound(owner.loc, 'sound/voice/alien/drool1.ogg', 50, 1)
to_chat(owner, span_xenodanger("We feel our acid glands refill. We can spray acid again."))
return ..()
@@ -817,7 +817,7 @@
/datum/action/ability/activable/xeno/xeno_spit/proc/fire()
var/mob/living/carbon/xenomorph/X = owner
var/turf/current_turf = get_turf(owner)
- var/sound_to_play = pick(1, 2) == 1 ? 'sound/voice/alien_spitacid.ogg' : 'sound/voice/alien_spitacid2.ogg'
+ var/sound_to_play = pick(1, 2) == 1 ? 'sound/voice/alien/spitacid.ogg' : 'sound/voice/alien/spitacid2.ogg'
playsound(X.loc, sound_to_play, 25, 1)
var/obj/projectile/newspit = new /obj/projectile(current_turf)
@@ -939,7 +939,7 @@
return FALSE
/datum/action/ability/activable/xeno/neurotox_sting/on_cooldown_finish()
- playsound(owner.loc, 'sound/voice/alien_drool1.ogg', 50, 1)
+ playsound(owner.loc, 'sound/voice/alien/drool1.ogg', 50, 1)
to_chat(owner, span_xenodanger("We feel our toxic glands refill. We can use our [initial(name)] again."))
return ..()
@@ -1076,7 +1076,7 @@
/datum/action/ability/xeno_action/rally_hive/action_activate()
var/mob/living/carbon/xenomorph/X = owner
- xeno_message("Our leader [X] is rallying the hive to [AREACOORD_NO_Z(X.loc)]!", "xenoannounce", 6, X.hivenumber, FALSE, X, 'sound/voice/alien_distantroar_3.ogg',TRUE,null,/atom/movable/screen/arrow/leader_tracker_arrow)
+ xeno_message("Our leader [X] is rallying the hive to [AREACOORD_NO_Z(X.loc)]!", "xenoannounce", 6, X.hivenumber, FALSE, X, 'sound/voice/alien/distantroar_3.ogg',TRUE,null,/atom/movable/screen/arrow/leader_tracker_arrow)
notify_ghosts("\ [X] is rallying the hive to [AREACOORD_NO_Z(X.loc)]!", source = X, action = NOTIFY_JUMP)
succeed_activate()
diff --git a/code/modules/mob/living/carbon/xenomorph/castes/behemoth/abilities_behemoth.dm b/code/modules/mob/living/carbon/xenomorph/castes/behemoth/abilities_behemoth.dm
index 7a3a788ccee..2b1aa2a346e 100644
--- a/code/modules/mob/living/carbon/xenomorph/castes/behemoth/abilities_behemoth.dm
+++ b/code/modules/mob/living/carbon/xenomorph/castes/behemoth/abilities_behemoth.dm
@@ -307,7 +307,7 @@
xeno_owner.set_canmove(FALSE)
xeno_owner.behemoth_charging = TRUE
ADD_TRAIT(xeno_owner, TRAIT_SILENT_FOOTSTEPS, XENO_TRAIT)
- playsound(xeno_owner, 'sound/effects/behemoth/landslide_roar.ogg', 40, TRUE)
+ playsound(xeno_owner, 'sound/effects/alien/behemoth/landslide_roar.ogg', 40, TRUE)
var/which_step = pick(0, 1)
new /obj/effect/temp_visual/behemoth/landslide/dust(owner_turf, direction, which_step)
do_warning(xeno_owner, get_affected_turfs(owner_turf, direction, LANDSLIDE_RANGE), LANDSLIDE_WIND_UP + 0.5 SECONDS)
@@ -316,7 +316,7 @@
if(primal_wrath_action?.ability_active)
var/animation_time = LANDSLIDE_RANGE * LANDSLIDE_ENHANCED_STEP_DELAY
addtimer(CALLBACK(src, PROC_REF(enhanced_do_charge), direction, charge_damage, LANDSLIDE_ENHANCED_STEP_DELAY, LANDSLIDE_RANGE), LANDSLIDE_ENHANCED_WIND_UP)
- addtimer(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(playsound), xeno_owner, 'sound/effects/behemoth/landslide_enhanced_charge.ogg', 30, TRUE), LANDSLIDE_ENHANCED_WIND_UP)
+ addtimer(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(playsound), xeno_owner, 'sound/effects/alien/behemoth/landslide_enhanced_charge.ogg', 30, TRUE), LANDSLIDE_ENHANCED_WIND_UP)
animate(xeno_owner, time = LANDSLIDE_ENHANCED_WIND_UP, flags = ANIMATION_END_NOW)
animate(pixel_y = xeno_owner.pixel_y + (LANDSLIDE_RANGE / 2), time = animation_time / 2, easing = CIRCULAR_EASING|EASE_OUT)
animate(pixel_y = initial(xeno_owner.pixel_y), time = animation_time / 2, easing = CIRCULAR_EASING|EASE_IN)
@@ -401,7 +401,7 @@
continue
hit_object(affected_object)
if(LinkBlocked(owner_turf, direct_turf))
- playsound(direct_turf, 'sound/effects/behemoth/behemoth_stomp.ogg', 40, TRUE)
+ playsound(direct_turf, 'sound/effects/alien/behemoth/stomp.ogg', 40, TRUE)
xeno_owner.do_attack_animation(direct_turf)
addtimer(CALLBACK(src, PROC_REF(end_charge)), LANDSLIDE_ENDING_COLLISION_DELAY)
return
@@ -433,7 +433,7 @@
var/mob/living/carbon/xenomorph/xeno_owner = owner
if(steps_to_take <= 0 || xeno_owner.wrath_stored < ability_cost)
if(LinkBlocked(owner_turf, direct_turf))
- playsound(direct_turf, 'sound/effects/behemoth/behemoth_stomp.ogg', 40, TRUE)
+ playsound(direct_turf, 'sound/effects/alien/behemoth/stomp.ogg', 40, TRUE)
xeno_owner.do_attack_animation(direct_turf)
new /obj/effect/temp_visual/behemoth/crack/landslide(get_turf(owner), direction, pick(1, 2))
end_charge()
@@ -500,7 +500,7 @@
if(!living_target.lying_angle)
living_target.Knockdown(LANDSLIDE_KNOCKDOWN_DURATION)
new /obj/effect/temp_visual/behemoth/landslide/hit(get_turf(living_target))
- playsound(living_target, 'sound/effects/behemoth/landslide_hit_mob.ogg', 30, TRUE)
+ playsound(living_target, 'sound/effects/alien/behemoth/landslide_hit_mob.ogg', 30, TRUE)
living_target.emote("scream")
shake_camera(living_target, 1, 0.8)
living_target.apply_damage(damage, BRUTE, blocked = MELEE)
@@ -644,7 +644,7 @@
var/datum/action/ability/xeno_action/ready_charge/behemoth_roll/behemoth_roll_action = xeno_owner.actions_by_path[/datum/action/ability/xeno_action/ready_charge/behemoth_roll]
if(behemoth_roll_action?.charge_ability_on)
behemoth_roll_action.charge_off()
- playsound(target_turf, 'sound/effects/behemoth/behemoth_stomp.ogg', 30, TRUE)
+ playsound(target_turf, 'sound/effects/alien/behemoth/stomp.ogg', 30, TRUE)
new /obj/effect/temp_visual/behemoth/stomp/west(owner_turf, owner.dir)
new /obj/effect/temp_visual/behemoth/crack(owner_turf, owner.dir)
var/wind_up_duration = EARTH_RISER_WIND_UP
@@ -683,7 +683,7 @@
while(length(active_pillars) > maximum_pillars)
var/obj/structure/earth_pillar/oldest_pillar = popleft(active_pillars)
new /obj/effect/temp_visual/behemoth/earth_pillar/broken(oldest_pillar.loc)
- playsound(oldest_pillar.loc, 'sound/effects/behemoth/earth_pillar_destroyed.ogg', 30, TRUE)
+ playsound(oldest_pillar.loc, 'sound/effects/alien/behemoth/earth_pillar_destroyed.ogg', 30, TRUE)
qdel(oldest_pillar)
update_button_icon()
@@ -792,7 +792,7 @@ RU TGMC EDIT */
var/owner_turf = get_turf(xeno_owner)
new /obj/effect/temp_visual/behemoth/stomp/east(owner_turf, owner.dir)
new /obj/effect/temp_visual/behemoth/crack(owner_turf, owner.dir)
- playsound(target_turf, 'sound/effects/behemoth/behemoth_stomp.ogg', 30, TRUE)
+ playsound(target_turf, 'sound/effects/alien/behemoth/stomp.ogg', 30, TRUE)
var/datum/action/ability/xeno_action/primal_wrath/primal_wrath_action = xeno_owner.actions_by_path[/datum/action/ability/xeno_action/primal_wrath]
do_ability(target_turf, SEISMIC_FRACTURE_WIND_UP, primal_wrath_action?.ability_active? TRUE : FALSE)
@@ -822,7 +822,7 @@ RU TGMC EDIT */
if(!enhanced)
return
new /obj/effect/temp_visual/shockwave/enhanced(get_turf(owner), SEISMIC_FRACTURE_ATTACK_RADIUS, owner.dir)
- playsound(owner, 'sound/effects/behemoth/landslide_roar.ogg', 40, TRUE)
+ playsound(owner, 'sound/effects/alien/behemoth/landslide_roar.ogg', 40, TRUE)
var/list/turf/extra_turfs_to_warn = filled_turfs(target_turf, SEISMIC_FRACTURE_ATTACK_RADIUS_ENHANCED, bypass_window = TRUE, projectile = TRUE)
for(var/turf/extra_turf_to_warn AS in extra_turfs_to_warn)
if(isclosedturf(extra_turf_to_warn))
@@ -850,7 +850,7 @@ RU TGMC EDIT */
if(isclosedturf(target_turf))
continue
new /obj/effect/temp_visual/behemoth/crack(target_turf)
- playsound(target_turf, 'sound/effects/behemoth/seismic_fracture_explosion.ogg', 15)
+ playsound(target_turf, 'sound/effects/alien/behemoth/seismic_fracture_explosion.ogg', 15)
var/attack_vfx = enhanced? /obj/effect/temp_visual/behemoth/seismic_fracture/enhanced : /obj/effect/temp_visual/behemoth/seismic_fracture
new attack_vfx(target_turf, enhanced? FALSE : null)
for(var/atom/movable/affected_atom AS in target_turf)
@@ -894,7 +894,7 @@ RU TGMC EDIT */
affected_living.layer = initial(affected_living.layer)
var/landing_damage = (xeno_owner.xeno_caste.melee_damage * xeno_owner.xeno_melee_damage_modifier) / 2
affected_living.apply_damage(landing_damage, BRUTE, blocked = MELEE)
- //playsound(affected_living.loc, 'sound/effects/behemoth/seismic_fracture_landing.ogg', 10, TRUE)
+ //playsound(affected_living.loc, 'sound/effects/alien/behemoth/seismic_fracture_landing.ogg', 10, TRUE)
new /obj/effect/temp_visual/behemoth/stomp(affected_living.loc)
/**
@@ -1044,7 +1044,7 @@ RU TGMC EDIT */
xeno_owner.face_atom(target)
xeno_owner.set_canmove(FALSE)
var/owner_turf = get_turf(xeno_owner)
- playsound(owner_turf, 'sound/effects/behemoth/primal_wrath_roar.ogg', 75, TRUE)
+ playsound(owner_turf, 'sound/effects/alien/behemoth/primal_wrath_roar.ogg', 75, TRUE)
do_ability(owner_turf)
addtimer(CALLBACK(src, PROC_REF(end_ability)), PRIMAL_WRATH_ACTIVATION_DURATION)
succeed_activate()
@@ -1261,7 +1261,7 @@ RU TGMC EDIT */
density = TRUE
max_integrity = 200
soft_armor = list(MELEE = 25, BULLET = 50, LASER = 50, ENERGY = 50, BOMB = 0, BIO = 100, FIRE = 100, ACID = 0)
- destroy_sound = 'sound/effects/behemoth/earth_pillar_destroyed.ogg'
+ destroy_sound = 'sound/effects/alien/behemoth/earth_pillar_destroyed.ogg'
coverage = 128
/// The xeno owner of this object.
var/mob/living/carbon/xenomorph/xeno_owner
@@ -1282,7 +1282,7 @@ RU TGMC EDIT */
animate(src, pixel_x = random_x, pixel_y = 500, time = 0)
animate(pixel_x = 0, pixel_y = 0, time = 0.5 SECONDS)
return
- playsound(src, 'sound/effects/behemoth/earth_pillar_rising.ogg', 40, TRUE)
+ playsound(src, 'sound/effects/alien/behemoth/earth_pillar_rising.ogg', 40, TRUE)
particle_holder = new(src, /particles/earth_pillar)
particle_holder.pixel_y = -4
animate(particle_holder, pixel_y = 4, time = 1.0 SECONDS)
@@ -1292,7 +1292,7 @@ RU TGMC EDIT */
RegisterSignals(src, list(COMSIG_ATOM_BULLET_ACT, COMSIG_ATOM_ATTACK_HAND, COMSIG_ATOM_ATTACK_HAND_ALTERNATE, COMSIG_ATOM_ATTACKBY), PROC_REF(call_update_icon_state))
/obj/structure/earth_pillar/Destroy()
- playsound(loc, 'sound/effects/behemoth/earth_pillar_destroyed.ogg', 40, TRUE)
+ playsound(loc, 'sound/effects/alien/behemoth/earth_pillar_destroyed.ogg', 40, TRUE)
new /obj/effect/temp_visual/behemoth/earth_pillar/broken(loc)
var/datum/action/ability/activable/xeno/earth_riser/earth_riser_action = xeno_owner?.actions_by_path[/datum/action/ability/activable/xeno/earth_riser]
if(earth_riser_action && (src in earth_riser_action.active_pillars))
@@ -1346,7 +1346,7 @@ RU TGMC EDIT */
if(isxenobehemoth(xeno_user))
xeno_user.do_attack_animation(src)
do_jitter_animation(jitter_loops = 1)
- playsound(src, 'sound/effects/behemoth/earth_pillar_eating.ogg', 30, TRUE)
+ playsound(src, 'sound/effects/alien/behemoth/earth_pillar_eating.ogg', 30, TRUE)
xeno_user.visible_message(span_xenowarning("\The [xeno_user] eats away at the [src.name]!"), \
span_xenonotice(pick(
"We eat away at the stone. It tastes good, as expected of our primary diet.",
@@ -1446,11 +1446,11 @@ RU TGMC EDIT */
/// VFX + SFX for when the rock doesn't hit anything.
/datum/ammo/xeno/earth_pillar/proc/rock_broke(turf/hit_turf, obj/projectile/proj)
new /obj/effect/temp_visual/behemoth/earth_pillar/broken(hit_turf)
- playsound(hit_turf, 'sound/effects/behemoth/earth_pillar_destroyed.ogg', 30, TRUE)
+ playsound(hit_turf, 'sound/effects/alien/behemoth/earth_pillar_destroyed.ogg', 30, TRUE)
/// Does some stuff if the rock DOES hit something.
/datum/ammo/xeno/earth_pillar/proc/on_hit_anything(turf/hit_turf, obj/projectile/proj)
- playsound(hit_turf, 'sound/effects/behemoth/earth_pillar_destroyed.ogg', 40, TRUE)
+ playsound(hit_turf, 'sound/effects/alien/behemoth/earth_pillar_destroyed.ogg', 40, TRUE)
new /obj/effect/temp_visual/behemoth/earth_pillar/destroyed(hit_turf)
var/list/turf/affected_turfs = filled_turfs(hit_turf, EARTH_PILLAR_SPREAD_RADIUS, include_edge = FALSE, bypass_window = TRUE, projectile = TRUE)
behemoth_area_attack(proj.firer, affected_turfs, damage_multiplier = EARTH_PILLAR_SPREAD_DAMAGE_MULTIPLIER)
@@ -1488,7 +1488,7 @@ RU TGMC EDIT */
if(isclosedturf(affected_turf))
continue
new /obj/effect/temp_visual/behemoth/crack(affected_turf)
- playsound(affected_turf, 'sound/effects/behemoth/seismic_fracture_explosion.ogg', 15)
+ playsound(affected_turf, 'sound/effects/alien/behemoth/seismic_fracture_explosion.ogg', 15)
var/attack_vfx = enhanced? /obj/effect/temp_visual/behemoth/seismic_fracture/enhanced : /obj/effect/temp_visual/behemoth/seismic_fracture
new attack_vfx(affected_turf, enhanced? FALSE : null)
for(var/atom/movable/affected_atom AS in affected_turf)
@@ -1537,7 +1537,7 @@ RU TGMC EDIT */
var/warning_type = primal_wrath_action?.ability_active? /obj/effect/temp_visual/behemoth/warning/enhanced : /obj/effect/temp_visual/behemoth/warning
for(var/turf/target_turf AS in target_turfs)
new warning_type(target_turf, duration)
- playsound(target_turf, 'sound/effects/behemoth/behemoth_rumble.ogg', 15, TRUE)
+ playsound(target_turf, 'sound/effects/alien/behemoth/rumble.ogg', 15, TRUE)
for(var/mob/living/target_living in target_turf)
if(xeno_owner.issamexenohive(target_living) || target_living.stat == DEAD || CHECK_BITFIELD(target_living.status_flags, INCORPOREAL|GODMODE))
continue
diff --git a/code/modules/mob/living/carbon/xenomorph/castes/carrier/abilities_carrier.dm b/code/modules/mob/living/carbon/xenomorph/castes/carrier/abilities_carrier.dm
index 1f5609a01c7..97b685426bd 100644
--- a/code/modules/mob/living/carbon/xenomorph/castes/carrier/abilities_carrier.dm
+++ b/code/modules/mob/living/carbon/xenomorph/castes/carrier/abilities_carrier.dm
@@ -99,7 +99,7 @@ GLOBAL_LIST_INIT(hugger_images_list, list(
F.kill_hugger()
huggers++
if(message)
- playsound(src, 'sound/voice/alien_drool2.ogg', 50, 0, 1)
+ playsound(src, 'sound/voice/alien/drool2.ogg', 50, 0, 1)
to_chat(src, span_notice("We salvage this young one's biomass to produce another. Now sheltering: [huggers] / [xeno_caste.huggers_max]."))
else if(message)
to_chat(src, span_warning("We can't carry any more facehuggers!"))
@@ -161,7 +161,7 @@ GLOBAL_LIST_INIT(hugger_images_list, list(
/datum/action/ability/xeno_action/spawn_hugger/on_cooldown_finish()
to_chat(owner, span_xenodanger("We can now spawn another young one."))
- owner.playsound_local(owner, 'sound/effects/xeno_newlarva.ogg', 25, 0, 1)
+ owner.playsound_local(owner, 'sound/effects/alien/newlarva.ogg', 25, 0, 1)
return ..()
/datum/action/ability/xeno_action/spawn_hugger/can_use_action(silent = FALSE, override_flags)
@@ -179,7 +179,7 @@ GLOBAL_LIST_INIT(hugger_images_list, list(
caster.huggers++
to_chat(caster, span_xenowarning("We spawn a young one via the miracle of asexual internal reproduction, adding it to our stores. Now sheltering: [caster.huggers] / [caster.xeno_caste.huggers_max]."))
- playsound(caster, 'sound/voice/alien_drool2.ogg', 50, 0, 1)
+ playsound(caster, 'sound/voice/alien/drool2.ogg', 50, 0, 1)
succeed_activate()
add_cooldown()
if(owner.client)
diff --git a/code/modules/mob/living/carbon/xenomorph/castes/chimera/abilities_chimera.dm b/code/modules/mob/living/carbon/xenomorph/castes/chimera/abilities_chimera.dm
index 5441f19947d..0646419751e 100644
--- a/code/modules/mob/living/carbon/xenomorph/castes/chimera/abilities_chimera.dm
+++ b/code/modules/mob/living/carbon/xenomorph/castes/chimera/abilities_chimera.dm
@@ -141,7 +141,7 @@
/datum/action/ability/activable/xeno/blink/on_cooldown_finish()
to_chat(owner, span_xenodanger("We are able to blink again."))
- owner.playsound_local(owner, 'sound/effects/xeno_newlarva.ogg', 25, 0, 1)
+ owner.playsound_local(owner, 'sound/effects/alien/newlarva.ogg', 25, 0, 1)
return ..()
///Return TRUE if we have a block, return FALSE otherwise
@@ -191,7 +191,7 @@
/datum/action/ability/xeno_action/phantom/on_cooldown_finish()
to_chat(owner, span_xenodanger("We gather enough strength to create a new phantom."))
- owner.playsound_local(owner, 'sound/effects/xeno_newlarva.ogg', 25, 0, 1)
+ owner.playsound_local(owner, 'sound/effects/alien/newlarva.ogg', 25, 0, 1)
return ..()
/datum/action/ability/xeno_action/phantom/action_activate()
@@ -268,7 +268,7 @@
/datum/action/ability/activable/xeno/pounce/abduction/on_cooldown_finish()
to_chat(owner, span_xenodanger("We gather enough strength to abduct another one."))
- owner.playsound_local(owner, 'sound/effects/xeno_newlarva.ogg', 25, 0, 1)
+ owner.playsound_local(owner, 'sound/effects/alien/newlarva.ogg', 25, 0, 1)
return ..()
/datum/action/ability/activable/xeno/pounce/abduction/use_ability(atom/A)
@@ -343,7 +343,7 @@
/datum/action/ability/activable/xeno/body_swap/on_cooldown_finish()
to_chat(owner, span_xenodanger("We gather enough strength to perform body swap again."))
- owner.playsound_local(owner, 'sound/effects/xeno_newlarva.ogg', 25, 0, 1)
+ owner.playsound_local(owner, 'sound/effects/alien/newlarva.ogg', 25, 0, 1)
return ..()
/datum/action/ability/activable/xeno/body_swap/use_ability(atom/A)
diff --git a/code/modules/mob/living/carbon/xenomorph/castes/crusher/abilities_crusher.dm b/code/modules/mob/living/carbon/xenomorph/castes/crusher/abilities_crusher.dm
index e100992c86f..2dea79212b5 100644
--- a/code/modules/mob/living/carbon/xenomorph/castes/crusher/abilities_crusher.dm
+++ b/code/modules/mob/living/carbon/xenomorph/castes/crusher/abilities_crusher.dm
@@ -80,7 +80,7 @@
/datum/action/ability/activable/xeno/cresttoss/on_cooldown_finish()
var/mob/living/carbon/xenomorph/X = owner
to_chat(X, span_xenowarning("We can now crest toss again."))
- playsound(X, 'sound/effects/xeno_newlarva.ogg', 50, 0, 1)
+ playsound(X, 'sound/effects/alien/newlarva.ogg', 50, 0, 1)
return ..()
/datum/action/ability/activable/xeno/cresttoss/can_use_ability(atom/A, silent = FALSE, override_flags)
@@ -198,7 +198,7 @@
/datum/action/ability/activable/xeno/advance/on_cooldown_finish()
to_chat(owner, span_xenowarning("We can now rapidly charge forward again."))
- playsound(owner, 'sound/effects/xeno_newlarva.ogg', 50, 0, 1)
+ playsound(owner, 'sound/effects/alien/newlarva.ogg', 50, 0, 1)
return ..()
/datum/action/ability/activable/xeno/advance/can_use_ability(atom/A, silent = FALSE, override_flags)
diff --git a/code/modules/mob/living/carbon/xenomorph/castes/defender/abilities_defender.dm b/code/modules/mob/living/carbon/xenomorph/castes/defender/abilities_defender.dm
index a6e2b090c25..81833f6b757 100644
--- a/code/modules/mob/living/carbon/xenomorph/castes/defender/abilities_defender.dm
+++ b/code/modules/mob/living/carbon/xenomorph/castes/defender/abilities_defender.dm
@@ -31,7 +31,7 @@
X.add_filter("defender_tail_sweep", 2, gauss_blur_filter(1)) //Add cool SFX
X.spin(4, 1)
X.enable_throw_parry(0.6 SECONDS)
- playsound(X,pick('sound/effects/alien_tail_swipe1.ogg','sound/effects/alien_tail_swipe2.ogg','sound/effects/alien_tail_swipe3.ogg'), 25, 1) //Sound effects
+ playsound(X,pick('sound/effects/alien/tail_swipe1.ogg','sound/effects/alien/tail_swipe2.ogg','sound/effects/alien/tail_swipe3.ogg'), 25, 1) //Sound effects
var/sweep_range = 1
var/list/L = orange(sweep_range, X) // Not actually the fruit
@@ -70,7 +70,7 @@
/datum/action/ability/xeno_action/tail_sweep/on_cooldown_finish()
var/mob/living/carbon/xenomorph/X = owner
to_chat(X, span_notice("We gather enough strength to tail sweep again."))
- owner.playsound_local(owner, 'sound/effects/xeno_newlarva.ogg', 25, 0, 1)
+ owner.playsound_local(owner, 'sound/effects/alien/newlarva.ogg', 25, 0, 1)
return ..()
/datum/action/ability/xeno_action/tail_sweep/ai_should_start_consider()
@@ -416,7 +416,7 @@
var/mob/living/carbon/xenomorph/X = owner
X.spin(4, 1)
X.enable_throw_parry(0.6 SECONDS)
- playsound(X, pick('sound/effects/alien_tail_swipe1.ogg','sound/effects/alien_tail_swipe2.ogg','sound/effects/alien_tail_swipe3.ogg'), 25, 1) //Sound effects
+ playsound(X, pick('sound/effects/alien/tail_swipe1.ogg','sound/effects/alien/tail_swipe2.ogg','sound/effects/alien/tail_swipe3.ogg'), 25, 1) //Sound effects
for(var/mob/living/carbon/human/slapped in orange(1, X))
if(slapped.stat == DEAD)
diff --git a/code/modules/mob/living/carbon/xenomorph/castes/defiler/abilities_defiler.dm b/code/modules/mob/living/carbon/xenomorph/castes/defiler/abilities_defiler.dm
index a586d21b313..d953ae64b10 100644
--- a/code/modules/mob/living/carbon/xenomorph/castes/defiler/abilities_defiler.dm
+++ b/code/modules/mob/living/carbon/xenomorph/castes/defiler/abilities_defiler.dm
@@ -73,7 +73,7 @@
)
/datum/action/ability/activable/xeno/defile/on_cooldown_finish()
- playsound(owner.loc, 'sound/voice/alien_drool1.ogg', 50, 1)
+ playsound(owner.loc, 'sound/voice/alien/drool1.ogg', 50, 1)
to_chat(owner, span_xenodanger("You feel your toxin accelerant glands refill. You can use Defile again."))
return ..()
@@ -110,7 +110,7 @@
X.face_atom(living_target)
X.do_attack_animation(living_target)
playsound(living_target, 'sound/effects/spray3.ogg', 15, TRUE)
- playsound(living_target, pick('sound/voice/alien_drool1.ogg', 'sound/voice/alien_drool2.ogg'), 15, 1)
+ playsound(living_target, pick('sound/voice/alien/drool1.ogg', 'sound/voice/alien/drool2.ogg'), 15, 1)
to_chat(X, span_xenodanger("Our stinger successfully discharges accelerant into our victim."))
to_chat(living_target, span_danger("You feel horrible pain as something sharp forcibly pierces your thorax."))
living_target.apply_damage(50, STAMINA)
@@ -176,7 +176,7 @@
var/obj/effect/abstract/particle_holder/particle_holder
/datum/action/ability/xeno_action/emit_neurogas/on_cooldown_finish()
- playsound(owner.loc, 'sound/effects/xeno_newlarva.ogg', 50, 0)
+ playsound(owner.loc, 'sound/effects/alien/newlarva.ogg', 50, 0)
to_chat(owner, span_xenodanger("We feel our dorsal vents bristle with heated gas. We can emit Noxious Gas again."))
return ..()
@@ -301,7 +301,7 @@
)
/datum/action/ability/activable/xeno/inject_egg_neurogas/on_cooldown_finish()
- playsound(owner.loc, 'sound/effects/xeno_newlarva.ogg', 50, 0)
+ playsound(owner.loc, 'sound/effects/alien/newlarva.ogg', 50, 0)
to_chat(owner, span_xenodanger("We feel our stinger fill with toxins. We can inject an egg with gas again."))
return ..()
@@ -456,7 +456,7 @@
reagent_slash_reagent = X.selected_reagent
X.balloon_alert(X, "Reagent slash active") //Let the user know
- X.playsound_local(X, 'sound/voice/alien_drool2.ogg', 25)
+ X.playsound_local(X, 'sound/voice/alien/drool2.ogg', 25)
toggle_particles(TRUE)
succeed_activate()
@@ -473,7 +473,7 @@
toggle_particles(FALSE)
X.balloon_alert(X, "Reagent slash over") //Let the user know
- X.playsound_local(X, 'sound/voice/hiss5.ogg', 25)
+ X.playsound_local(X, 'sound/voice/alien/hiss8.ogg', 25)
///Called when we slash while reagent slash is active
@@ -513,7 +513,7 @@
/datum/action/ability/xeno_action/reagent_slash/on_cooldown_finish()
to_chat(owner, span_xenodanger("We are able to infuse our spines with toxins again."))
- owner.playsound_local(owner, 'sound/effects/xeno_newlarva.ogg', 25, 0, 1)
+ owner.playsound_local(owner, 'sound/effects/alien/newlarva.ogg', 25, 0, 1)
return ..()
// Toggles particles on or off, depending on the defined var.
diff --git a/code/modules/mob/living/carbon/xenomorph/castes/facehugger/abilities_facehugger.dm b/code/modules/mob/living/carbon/xenomorph/castes/facehugger/abilities_facehugger.dm
index 1bed20235ac..710de6df33d 100644
--- a/code/modules/mob/living/carbon/xenomorph/castes/facehugger/abilities_facehugger.dm
+++ b/code/modules/mob/living/carbon/xenomorph/castes/facehugger/abilities_facehugger.dm
@@ -47,7 +47,7 @@
var/mob/living/carbon/xenomorph/facehugger/caster = owner
caster.visible_message(span_danger("[caster] leaps on [living_target]!"), span_xenodanger("We leap on [living_target]!"), null, 5)
- playsound(caster.loc, 'sound/voice/alien_roar_larva3.ogg', 25, TRUE) //TODO: I NEED ACTUAL HUGGERS SOUND DAMMED
+ playsound(caster.loc, 'sound/voice/alien/larva/roar3.ogg', 25, TRUE) //TODO: I NEED ACTUAL HUGGERS SOUND DAMMED
if(ishuman(living_target) && (angle_to_dir(Get_Angle(caster.throw_source, living_target)) in reverse_nearby_direction(living_target.dir)))
var/mob/living/carbon/human/human_target = living_target
diff --git a/code/modules/mob/living/carbon/xenomorph/castes/hivelord/abilities_hivelord.dm b/code/modules/mob/living/carbon/xenomorph/castes/hivelord/abilities_hivelord.dm
index 7ce164dfeb2..43242153c28 100644
--- a/code/modules/mob/living/carbon/xenomorph/castes/hivelord/abilities_hivelord.dm
+++ b/code/modules/mob/living/carbon/xenomorph/castes/hivelord/abilities_hivelord.dm
@@ -53,7 +53,7 @@
recycled_xeno.gib()
- playsound(hivelord, 'sound/effects/alien_recycler.ogg', 40)
+ playsound(hivelord, 'sound/effects/alien/recycler.ogg', 40)
hivelord.visible_message(span_xenowarning("\The [hivelord] brushes xenomorphs' bits off its claws."), \
span_danger("We brush xenomorphs' bits off of our claws."), null, 20)
return succeed_activate() //dew it
diff --git a/code/modules/mob/living/carbon/xenomorph/castes/hivemind/hivemind.dm b/code/modules/mob/living/carbon/xenomorph/castes/hivemind/hivemind.dm
index c71a6865c7b..bcc61d546f9 100644
--- a/code/modules/mob/living/carbon/xenomorph/castes/hivemind/hivemind.dm
+++ b/code/modules/mob/living/carbon/xenomorph/castes/hivemind/hivemind.dm
@@ -404,7 +404,7 @@
return
to_chat(get_parent(), span_xenoannounce("Our [src.name] has detected a nearby hostile [hostile] at [get_area(hostile)] (X: [hostile.x], Y: [hostile.y])."))
- SEND_SOUND(get_parent(), 'sound/voice/alien_help1.ogg')
+ SEND_SOUND(get_parent(), 'sound/voice/alien/help1.ogg')
COOLDOWN_START(src, hivemind_proxy_alert_cooldown, XENO_HIVEMIND_DETECTION_COOLDOWN) //set the cooldown.
/// Getter for the parent of this hive core
diff --git a/code/modules/mob/living/carbon/xenomorph/castes/hunter/abilities_hunter.dm b/code/modules/mob/living/carbon/xenomorph/castes/hunter/abilities_hunter.dm
index ce9c339e5af..b42f00153fe 100644
--- a/code/modules/mob/living/carbon/xenomorph/castes/hunter/abilities_hunter.dm
+++ b/code/modules/mob/living/carbon/xenomorph/castes/hunter/abilities_hunter.dm
@@ -34,7 +34,7 @@
/datum/action/ability/xeno_action/stealth/on_cooldown_finish()
owner.balloon_alert(owner, "Stealth ready.")
- playsound(owner, "sound/effects/xeno_newlarva.ogg", 25, 0, 1)
+ playsound(owner, "sound/effects/alien/newlarva.ogg", 25, 0, 1)
return ..()
/datum/action/ability/xeno_action/stealth/action_activate()
@@ -113,7 +113,7 @@
return
can_sneak_attack = TRUE
owner.balloon_alert(owner, "Sneak Attack ready.")
- playsound(owner, "sound/effects/xeno_newlarva.ogg", 25, 0, 1)
+ playsound(owner, "sound/effects/alien/newlarva.ogg", 25, 0, 1)
/datum/action/ability/xeno_action/stealth/process()
if(!stealth)
@@ -306,7 +306,7 @@
/datum/action/ability/activable/xeno/pounce/on_cooldown_finish()
owner.balloon_alert(owner, "Pounce ready")
- owner.playsound_local(owner, 'sound/effects/xeno_newlarva.ogg', 25, 0, 1)
+ owner.playsound_local(owner, 'sound/effects/alien/newlarva.ogg', 25, 0, 1)
return ..()
/datum/action/ability/activable/xeno/pounce/can_use_ability(atom/A, silent = FALSE, override_flags)
@@ -364,7 +364,7 @@
///Triggers the effect of a successful pounce on the target.
/datum/action/ability/activable/xeno/pounce/proc/trigger_pounce_effect(mob/living/living_target)
- playsound(get_turf(living_target), 'sound/voice/alien_pounce.ogg', 25, TRUE)
+ playsound(get_turf(living_target), 'sound/voice/alien/pounce.ogg', 25, TRUE)
var/mob/living/carbon/xenomorph/xeno_owner = owner
xeno_owner.set_throwing(FALSE)
xeno_owner.Immobilize(XENO_POUNCE_STANDBY_DURATION)
@@ -459,7 +459,7 @@
/datum/action/ability/activable/xeno/hunter_mark/on_cooldown_finish()
to_chat(owner, span_xenowarning("We are able to impose our psychic mark again."))
- owner.playsound_local(owner, 'sound/effects/xeno_newlarva.ogg', 25, 0, 1)
+ owner.playsound_local(owner, 'sound/effects/alien/newlarva.ogg', 25, 0, 1)
return ..()
@@ -713,7 +713,7 @@
/datum/action/ability/activable/xeno/silence/on_cooldown_finish()
to_chat(owner, span_xenowarning("We refocus our psionic energies, allowing us to impose silence again.") )
- owner.playsound_local(owner, 'sound/effects/xeno_newlarva.ogg', 25, 0, 1)
+ owner.playsound_local(owner, 'sound/effects/alien/newlarva.ogg', 25, 0, 1)
cooldown_duration = initial(cooldown_duration) //Reset the cooldown timer to its initial state in the event of a whiffed Silence.
return ..()
diff --git a/code/modules/mob/living/carbon/xenomorph/castes/king/abilities_king.dm b/code/modules/mob/living/carbon/xenomorph/castes/king/abilities_king.dm
index 3961e9b8321..0b9f61c541c 100644
--- a/code/modules/mob/living/carbon/xenomorph/castes/king/abilities_king.dm
+++ b/code/modules/mob/living/carbon/xenomorph/castes/king/abilities_king.dm
@@ -204,7 +204,7 @@
return
owner.dir = get_cardinal_dir(owner, target)
- playsound(owner, 'sound/voice/ed209_20sec.ogg', 70, sound_range = 20)
+ playsound(owner, 'sound/voice/alien/king_roar.ogg', 70, sound_range = 20)
var/mob/living/carbon/xenomorph/king/king_owner = owner
if(istype(king_owner))
king_owner.icon_state = "King Screeching"
@@ -218,7 +218,7 @@
return fail_activate()
finish_charging()
- playsound(owner, 'sound/voice/xenos_roaring.ogg', 90, sound_range = 30)
+ playsound(owner, 'sound/voice/alien/xenos_roaring.ogg', 90, sound_range = 30)
for(var/mob/living/carbon/human/human_victim AS in GLOB.humans_by_zlevel["[owner.z]"])
if(get_dist(human_victim, owner) > 9)
continue
diff --git a/code/modules/mob/living/carbon/xenomorph/castes/king/king.dm b/code/modules/mob/living/carbon/xenomorph/castes/king/king.dm
index 811fc690c55..6b3ce27b5ce 100644
--- a/code/modules/mob/living/carbon/xenomorph/castes/king/king.dm
+++ b/code/modules/mob/living/carbon/xenomorph/castes/king/king.dm
@@ -24,7 +24,7 @@
/mob/living/carbon/xenomorph/king/Initialize(mapload)
. = ..()
- playsound(loc, 'sound/voice/xenos_roaring.ogg', 75, 0)
+ playsound(loc, 'sound/voice/alien/xenos_roaring.ogg', 75, 0)
/mob/living/carbon/xenomorph/king/generate_name()
var/playtime_mins = client?.get_exp(xeno_caste.caste_name)
@@ -48,4 +48,4 @@
mind.name = name
/mob/living/carbon/xenomorph/king/death_cry()
- playsound(loc, 'sound/voice/alien_king_died.ogg', 75, 0)
+ playsound(loc, 'sound/voice/alien/king_died.ogg', 75, 0)
diff --git a/code/modules/mob/living/carbon/xenomorph/castes/panther/abilities_panther.dm b/code/modules/mob/living/carbon/xenomorph/castes/panther/abilities_panther.dm
index 49461bc044f..d2cd95efa17 100644
--- a/code/modules/mob/living/carbon/xenomorph/castes/panther/abilities_panther.dm
+++ b/code/modules/mob/living/carbon/xenomorph/castes/panther/abilities_panther.dm
@@ -38,7 +38,7 @@
xenomorph_owner.add_filter("defender_tail_sweep", 2, gauss_blur_filter(1)) //Add cool SFX
xenomorph_owner.spin(4, 1)
xenomorph_owner.enable_throw_parry(0.6 SECONDS)
- playsound(xenomorph_owner,pick('sound/effects/alien_tail_swipe1.ogg','sound/effects/alien_tail_swipe2.ogg','sound/effects/alien_tail_swipe3.ogg'), 25, 1) //Sound effects
+ playsound(xenomorph_owner,pick('sound/effects/alien/tail_swipe1.ogg','sound/effects/alien/tail_swipe2.ogg','sound/effects/alien/tail_swipe3.ogg'), 25, 1) //Sound effects
var/sweep_range = 1
var/list/L = orange(sweep_range, xenomorph_owner) // Not actually the fruit
@@ -69,7 +69,7 @@
/datum/action/ability/xeno_action/tearingtail/on_cooldown_finish()
var/mob/living/carbon/xenomorph/xenomorph_owner = owner
to_chat(xenomorph_owner, span_notice("We gather enough strength to tear the skin again."))
- owner.playsound_local(owner, 'sound/effects/xeno_newlarva.ogg', 25, 0, 1)
+ owner.playsound_local(owner, 'sound/effects/alien/newlarva.ogg', 25, 0, 1)
return ..()
///////////////////////////////////
@@ -93,7 +93,7 @@
/datum/action/ability/activable/xeno/adrenalinejump/on_cooldown_finish()
to_chat(owner, span_xenodanger("We ready ourselves to jump again."))
- owner.playsound_local(owner, 'sound/effects/xeno_newlarva.ogg', 25, 0, 1)
+ owner.playsound_local(owner, 'sound/effects/alien/newlarva.ogg', 25, 0, 1)
return ..()
/datum/action/ability/activable/xeno/adrenalinejump/can_use_ability(atom/A, silent = FALSE, override_flags)
@@ -391,13 +391,13 @@
evade_active = FALSE //Evasion is no longer active
owner.balloon_alert(owner, "Evasion ended")
- owner.playsound_local(owner, 'sound/voice/hiss5.ogg', 50)
+ owner.playsound_local(owner, 'sound/voice/alien/hiss8.ogg', 50)
#define PANTHER_EVASION_RUN_DELAY 0.5 SECONDS // If the time since the Runner last moved is equal to or greater than this, its Evasion ends.
/datum/action/ability/xeno_action/evasive_maneuvers/on_cooldown_finish()
to_chat(owner, span_xenodanger("We are able to take evasive action again."))
- owner.playsound_local(owner, 'sound/effects/xeno_newlarva.ogg', 25, 0, 1)
+ owner.playsound_local(owner, 'sound/effects/alien/newlarva.ogg', 25, 0, 1)
return ..()
@@ -455,7 +455,7 @@
xenomorph_owner.do_jitter_animation(4000)
var/turf/our_turf = get_turf(xenomorph_owner) //location of after image SFX
- playsound(our_turf, pick('sound/effects/throw.ogg','sound/effects/alien_tail_swipe1.ogg', 'sound/effects/alien_tail_swipe2.ogg'), 25, 1) //sound effects
+ playsound(our_turf, pick('sound/effects/throw.ogg','sound/effects/alien/tail_swipe1.ogg', 'sound/effects/alien/tail_swipe2.ogg'), 25, 1) //sound effects
var/obj/effect/temp_visual/xenomorph/afterimage/our_afterimage
for(var/i = 0 to 2) //number of after images
our_afterimage = new /obj/effect/temp_visual/xenomorph/afterimage(our_turf, owner) //Create the after image.
diff --git a/code/modules/mob/living/carbon/xenomorph/castes/praetorian/abilities_praetorian.dm b/code/modules/mob/living/carbon/xenomorph/castes/praetorian/abilities_praetorian.dm
index 70e47599d0b..f2eb176f0a7 100644
--- a/code/modules/mob/living/carbon/xenomorph/castes/praetorian/abilities_praetorian.dm
+++ b/code/modules/mob/living/carbon/xenomorph/castes/praetorian/abilities_praetorian.dm
@@ -37,7 +37,7 @@
/datum/action/ability/activable/xeno/scatter_spit/on_cooldown_finish()
to_chat(owner, span_xenodanger("Our auxiliary sacks fill to bursting; we can use scatter spit again."))
- owner.playsound_local(owner, 'sound/voice/alien_drool1.ogg', 25, 0, 1)
+ owner.playsound_local(owner, 'sound/voice/alien/drool1.ogg', 25, 0, 1)
return ..()
// ***************************************
diff --git a/code/modules/mob/living/carbon/xenomorph/castes/predalien/abilities_predalien.dm b/code/modules/mob/living/carbon/xenomorph/castes/predalien/abilities_predalien.dm
index 25bfe60f699..de0646270f2 100644
--- a/code/modules/mob/living/carbon/xenomorph/castes/predalien/abilities_predalien.dm
+++ b/code/modules/mob/living/carbon/xenomorph/castes/predalien/abilities_predalien.dm
@@ -19,7 +19,7 @@
///Triggers the effect of a successful pounce on the target.
/datum/action/ability/activable/xeno/pounce/predalien/trigger_pounce_effect(mob/living/living_target)
- playsound(get_turf(living_target), 'sound/voice/predalien_pounce.ogg', 25, TRUE)
+ playsound(get_turf(living_target), 'sound/voice/alien/predalien/pounce.ogg', 25, TRUE)
var/mob/living/carbon/xenomorph/xeno_owner = owner
xeno_owner.set_throwing(FALSE)
xeno_owner.Immobilize(XENO_POUNCE_STANDBY_DURATION)
@@ -40,7 +40,7 @@
cooldown_duration = 25 SECONDS
ability_cost = 50
- var/predalien_roar = list("sound/voice/predalien_roar.ogg")
+ var/predalien_roar = list("sound/voice/alien/predalien/roar.ogg")
var/bonus_damage_scale = 2.5
var/bonus_speed_scale = 0.05
@@ -90,7 +90,7 @@
ability_cost = 80
var/freeze_duration = 1.5 SECONDS
- var/smash_sounds = list('sound/effects/alien_footstep_charge1.ogg', 'sound/effects/alien_footstep_charge2.ogg', 'sound/effects/alien_footstep_charge3.ogg')
+ var/smash_sounds = list('sound/effects/footstep/alien/charge1.ogg', 'sound/effects/footstep/alien/charge2.ogg', 'sound/effects/footstep/alien/charge3.ogg')
/datum/action/ability/activable/xeno/smash/can_use_ability(atom/target, silent = FALSE, override_flags)
. = ..()
@@ -196,7 +196,7 @@
xeno.setDir(turn(xeno.dir, 90))
xeno.do_attack_animation(carbon, ATTACK_EFFECT_BITE)
- playsound(xeno, 'sound/voice/predalien_growl.ogg', 75, 0)
+ playsound(xeno, 'sound/voice/alien/predalien/growl.ogg', 75, 0)
xeno.anchored = FALSE
xeno.SetImmobilized(0)
diff --git a/code/modules/mob/living/carbon/xenomorph/castes/queen/abilities_queen.dm b/code/modules/mob/living/carbon/xenomorph/castes/queen/abilities_queen.dm
index 03580ce55a5..eafdf370085 100644
--- a/code/modules/mob/living/carbon/xenomorph/castes/queen/abilities_queen.dm
+++ b/code/modules/mob/living/carbon/xenomorph/castes/queen/abilities_queen.dm
@@ -37,7 +37,7 @@
var/queens_word = "HIVE MESSAGE:
" + input
var/sound/queen_sound = sound(get_sfx("queen"), channel = CHANNEL_ANNOUNCEMENTS)
- var/sound/king_sound = sound('sound/voice/xenos_roaring.ogg', channel = CHANNEL_ANNOUNCEMENTS)
+ var/sound/king_sound = sound('sound/voice/alien/xenos_roaring.ogg', channel = CHANNEL_ANNOUNCEMENTS)
for(var/mob/living/carbon/xenomorph/X AS in Q.hive.get_all_xenos())
switch(Q.caste_base_type)
if(/mob/living/carbon/xenomorph/queen)
@@ -92,7 +92,7 @@
succeed_activate()
add_cooldown()
- playsound(X.loc, 'sound/voice/alien_queen_screech.ogg', 75, 0)
+ playsound(X.loc, 'sound/voice/alien/queen/screech.ogg', 75, 0)
X.visible_message(span_xenohighdanger("\The [X] emits an ear-splitting guttural roar!"))
GLOB.round_statistics.queen_screech++
SSblackbox.record_feedback("tally", "round_statistics", 1, "queen_screech")
@@ -155,7 +155,7 @@
continue
affected_xeno.apply_status_effect(/datum/status_effect/plasma_surge, affected_xeno.xeno_caste.plasma_max / 3, bonus_regen, duration)
- playsound(X.loc, 'sound/voice/alien_plasma_screech.ogg', 75, 0)
+ playsound(X.loc, 'sound/voice/alien/queen/screech_plasma.ogg', 75, 0)
X.visible_message(span_xenohighdanger("\The [X] emits an ear-splitting guttural roar!"))
succeed_activate()
@@ -188,7 +188,7 @@
for(var/mob/living/carbon/xenomorph/affected_xeno in cheap_get_xenos_near(X, screech_range))
affected_xeno.apply_status_effect(/datum/status_effect/frenzy_screech, buff_duration, buff_damage_modifier)
- playsound(X.loc, 'sound/voice/alien_frenzy_screech.ogg', 75, 0)
+ playsound(X.loc, 'sound/voice/alien/queen/screech_frenzy.ogg', 75, 0)
X.visible_message(span_xenohighdanger("\The [X] emits an ear-splitting guttural roar!"))
succeed_activate()
diff --git a/code/modules/mob/living/carbon/xenomorph/castes/queen/queen.dm b/code/modules/mob/living/carbon/xenomorph/castes/queen/queen.dm
index 32ab7a3b7b2..b6b6feb4211 100644
--- a/code/modules/mob/living/carbon/xenomorph/castes/queen/queen.dm
+++ b/code/modules/mob/living/carbon/xenomorph/castes/queen/queen.dm
@@ -31,7 +31,7 @@
RegisterSignal(src, COMSIG_HIVE_BECOME_RULER, PROC_REF(on_becoming_ruler))
. = ..()
hive.RegisterSignal(src, COMSIG_HIVE_XENO_DEATH, TYPE_PROC_REF(/datum/hive_status, on_queen_death))
- playsound(loc, 'sound/voice/alien_queen_command.ogg', 75, 0)
+ playsound(loc, 'sound/voice/alien/queen/command.ogg', 75, 0)
// ***************************************
// *********** Mob overrides
@@ -98,7 +98,7 @@
// *********** Death
// ***************************************
/mob/living/carbon/xenomorph/queen/death_cry()
- playsound(loc, 'sound/voice/alien_queen_died.ogg', 75, 0)
+ playsound(loc, 'sound/voice/alien/queen/died.ogg', 75, 0)
/mob/living/carbon/xenomorph/queen/xeno_death_alert()
return
diff --git a/code/modules/mob/living/carbon/xenomorph/castes/ravager/abilities_ravager.dm b/code/modules/mob/living/carbon/xenomorph/castes/ravager/abilities_ravager.dm
index aac732b46d4..5672ebd1b6e 100644
--- a/code/modules/mob/living/carbon/xenomorph/castes/ravager/abilities_ravager.dm
+++ b/code/modules/mob/living/carbon/xenomorph/castes/ravager/abilities_ravager.dm
@@ -34,7 +34,7 @@
/datum/action/ability/activable/xeno/charge/on_cooldown_finish()
to_chat(owner, span_xenodanger("Our exoskeleton quivers as we get ready to use [name] again."))
- playsound(owner, "sound/effects/xeno_newlarva.ogg", 50, 0, 1)
+ playsound(owner, "sound/effects/alien/newlarva.ogg", 50, 0, 1)
return ..()
/datum/action/ability/activable/xeno/charge/ai_should_start_consider()
@@ -105,7 +105,7 @@
/datum/action/ability/activable/xeno/ravage/on_cooldown_finish()
to_chat(owner, span_xenodanger("We gather enough strength to Ravage again."))
- playsound(owner, "sound/effects/xeno_newlarva.ogg", 50, 0, 1)
+ playsound(owner, "sound/effects/alien/newlarva.ogg", 50, 0, 1)
return ..()
/datum/action/ability/activable/xeno/ravage/use_ability(atom/A)
@@ -209,7 +209,7 @@
/datum/action/ability/xeno_action/endure/on_cooldown_finish()
to_chat(owner, span_xenodanger("We feel able to imbue ourselves with plasma to Endure once again!"))
- owner.playsound_local(owner, 'sound/effects/xeno_newlarva.ogg', 25, 0, 1)
+ owner.playsound_local(owner, 'sound/effects/alien/newlarva.ogg', 25, 0, 1)
return ..()
/datum/action/ability/xeno_action/endure/action_activate()
@@ -246,7 +246,7 @@
if(QDELETED(owner))
return
to_chat(owner,span_highdanger("We feel the plasma draining from our veins... [initial(name)] will last for only [timeleft(endure_duration) * 0.1] more seconds!"))
- owner.playsound_local(owner, 'sound/voice/hiss4.ogg', 50, 0, 1)
+ owner.playsound_local(owner, 'sound/voice/alien/hiss8.ogg', 50, 0, 1)
///Turns off the Endure buff
/datum/action/ability/xeno_action/endure/proc/endure_deactivate()
@@ -276,7 +276,7 @@
endure_warning_duration = initial(endure_warning_duration)
to_chat(owner,span_highdanger("The last of the plasma drains from our body... We can no longer endure beyond our normal limits!"))
- owner.playsound_local(owner, 'sound/voice/hiss4.ogg', 50, 0, 1)
+ owner.playsound_local(owner, 'sound/voice/alien/hiss8.ogg', 50, 0, 1)
///Warns us when our health is critically low and tells us exactly how much more punishment we can take
/datum/action/ability/xeno_action/endure/proc/damage_taken(mob/living/carbon/xenomorph/X, damage_taken)
@@ -326,7 +326,7 @@
/datum/action/ability/xeno_action/rage/on_cooldown_finish()
to_chat(owner, span_xenodanger("We are able to enter our rage once again."))
- owner.playsound_local(owner, 'sound/effects/xeno_newlarva.ogg', 25, 0, 1)
+ owner.playsound_local(owner, 'sound/effects/alien/newlarva.ogg', 25, 0, 1)
return ..()
/datum/action/ability/xeno_action/rage/can_use_action(atom/A, silent = FALSE, override_flags)
@@ -359,7 +359,7 @@
//Roar SFX; volume scales with rage
- playsound(X.loc, 'sound/voice/alien_roar2.ogg', clamp(100 * rage_power, 25, 80), 0)
+ playsound(X.loc, 'sound/voice/alien/roar2.ogg', clamp(100 * rage_power, 25, 80), 0)
var/bonus_duration
if(rage_power >= RAVAGER_RAGE_SUPER_RAGE_THRESHOLD) //If we're super pissed it's time to get crazy
@@ -428,7 +428,7 @@ RU TGMC EDIT */
if(QDELETED(owner))
return
to_chat(owner,span_highdanger("Our rage begins to subside... [initial(name)] will only last for only [(RAVAGER_RAGE_DURATION + bonus_duration) * (1-RAVAGER_RAGE_WARNING) * 0.1] more seconds!"))
- owner.playsound_local(owner, 'sound/voice/hiss4.ogg', 50, 0, 1)
+ owner.playsound_local(owner, 'sound/voice/alien/hiss8.ogg', 50, 0, 1)
///Warns the user when his rage is about to end.
/datum/action/ability/xeno_action/rage/proc/drain_slash(datum/source, mob/living/target, damage, list/damage_mod, list/armor_mod)
@@ -482,7 +482,7 @@ RU TGMC EDIT */
//rage_sunder = 0 //RU TGMC EDIT
rage_power = 0
rage_plasma = 0
- X.playsound_local(X, 'sound/voice/hiss5.ogg', 50) //Audio cue
+ X.playsound_local(X, 'sound/voice/alien/hiss8.ogg', 50) //Audio cue
// ***************************************
diff --git a/code/modules/mob/living/carbon/xenomorph/castes/runner/abilities_runner.dm b/code/modules/mob/living/carbon/xenomorph/castes/runner/abilities_runner.dm
index 5c899221807..d5c71092b96 100644
--- a/code/modules/mob/living/carbon/xenomorph/castes/runner/abilities_runner.dm
+++ b/code/modules/mob/living/carbon/xenomorph/castes/runner/abilities_runner.dm
@@ -61,7 +61,7 @@
if(COOLDOWN_CHECK(src, savage_cooldown))
button.cut_overlay(visual_references[VREF_MUTABLE_SAVAGE_COOLDOWN])
owner.balloon_alert(owner, "Savage ready")
- owner.playsound_local(owner, 'sound/effects/xeno_newlarva.ogg', 25, 0, 1)
+ owner.playsound_local(owner, 'sound/effects/alien/newlarva.ogg', 25, 0, 1)
STOP_PROCESSING(SSprocessing, src)
return
button.cut_overlay(visual_references[VREF_MUTABLE_SAVAGE_COOLDOWN])
@@ -101,7 +101,7 @@
/datum/action/ability/xeno_action/evasion/on_cooldown_finish()
. = ..()
owner.balloon_alert(owner, "Evasion ready")
- owner.playsound_local(owner, 'sound/effects/xeno_newlarva.ogg', 25, 0, 1)
+ owner.playsound_local(owner, 'sound/effects/alien/newlarva.ogg', 25, 0, 1)
/datum/action/ability/xeno_action/evasion/can_use_action(silent = FALSE, override_flags)
. = ..()
@@ -195,7 +195,7 @@
evasion_stacks = 0
evasion_duration = 0
owner.balloon_alert(owner, "Evasion ended")
- owner.playsound_local(owner, 'sound/voice/hiss5.ogg', 50)
+ owner.playsound_local(owner, 'sound/voice/alien/hiss8.ogg', 50)
var/mob/living/carbon/xenomorph/runner/runner_owner = owner
runner_owner.hud_set_evasion(evasion_duration)
@@ -245,7 +245,7 @@
if(auto_evasion && xeno_owner.plasma_stored >= ability_cost)
action_activate()
var/turf/current_turf = get_turf(xeno_owner) //location of after image SFX
- playsound(current_turf, pick('sound/effects/throw.ogg','sound/effects/alien_tail_swipe1.ogg', 'sound/effects/alien_tail_swipe2.ogg'), 25, 1) //sound effects
+ playsound(current_turf, pick('sound/effects/throw.ogg','sound/effects/alien/tail_swipe1.ogg', 'sound/effects/alien/tail_swipe2.ogg'), 25, 1) //sound effects
var/obj/effect/temp_visual/xenomorph/afterimage/after_image
for(var/i=0 to 2) //number of after images
after_image = new /obj/effect/temp_visual/xenomorph/afterimage(current_turf, owner) //Create the after image.
@@ -329,7 +329,7 @@
if(!stolen_item)
victim.balloon_alert(owner, "Snatch failed, no item")
return fail_activate()
- playsound(owner, 'sound/voice/alien_pounce2.ogg', 30)
+ playsound(owner, 'sound/voice/alien/pounce2.ogg', 30)
victim.dropItemToGround(stolen_item, TRUE)
stolen_item.forceMove(owner)
stolen_appearance = mutable_appearance(stolen_item.icon, stolen_item.icon_state)
@@ -382,6 +382,6 @@
stolen_item.forceMove(get_turf(owner))
stolen_item = null
owner.overlays -= stolen_appearance
- playsound(owner, 'sound/voice/alien_pounce2.ogg', 30, frequency = -1)
+ playsound(owner, 'sound/voice/alien/pounce2.ogg', 30, frequency = -1)
UnregisterSignal(owner, COMSIG_ATOM_DIR_CHANGE)
diff --git a/code/modules/mob/living/carbon/xenomorph/castes/sentinel/abilities_sentinel.dm b/code/modules/mob/living/carbon/xenomorph/castes/sentinel/abilities_sentinel.dm
index 929fe567b5e..74f50fe83f4 100644
--- a/code/modules/mob/living/carbon/xenomorph/castes/sentinel/abilities_sentinel.dm
+++ b/code/modules/mob/living/carbon/xenomorph/castes/sentinel/abilities_sentinel.dm
@@ -60,7 +60,7 @@
ability_duration = addtimer(CALLBACK(src, PROC_REF(toxic_slash_deactivate), xeno_owner), SENTINEL_TOXIC_SLASH_DURATION, TIMER_STOPPABLE) //Initiate the timer and set the timer ID for reference
RegisterSignal(xeno_owner, COMSIG_XENOMORPH_ATTACK_LIVING, PROC_REF(toxic_slash))
xeno_owner.balloon_alert(xeno_owner, "Toxic Slash active")
- xeno_owner.playsound_local(xeno_owner, 'sound/voice/alien_drool2.ogg', 25)
+ xeno_owner.playsound_local(xeno_owner, 'sound/voice/alien/drool2.ogg', 25)
action_icon_state = "neuroclaws_on"
particle_holder = new(owner, /particles/toxic_slash)
particle_holder.pixel_x = 9
@@ -93,11 +93,11 @@
ability_duration = null
QDEL_NULL(particle_holder)
xeno_owner.balloon_alert(xeno_owner, "Toxic Slash over") //Let the user know
- xeno_owner.playsound_local(xeno_owner, 'sound/voice/hiss5.ogg', 25)
+ xeno_owner.playsound_local(xeno_owner, 'sound/voice/alien/hiss8.ogg', 25)
action_icon_state = "neuroclaws_off"
/datum/action/ability/xeno_action/toxic_slash/on_cooldown_finish()
- owner.playsound_local(owner, 'sound/effects/xeno_newlarva.ogg', 25, 0, 1)
+ owner.playsound_local(owner, 'sound/effects/alien/newlarva.ogg', 25, 0, 1)
owner.balloon_alert(owner, "Toxic Slash ready")
return ..()
@@ -168,7 +168,7 @@
HEAL_XENO_DAMAGE(xeno_owner, drain_potency, FALSE)
xeno_owner.gain_plasma(drain_potency * 3.5)
xeno_owner.do_attack_animation(xeno_target, ATTACK_EFFECT_DRAIN_STING)
- playsound(owner.loc, 'sound/effects/alien_tail_swipe1.ogg', 30)
+ playsound(owner.loc, 'sound/effects/alien/tail_swipe1.ogg', 30)
xeno_owner.visible_message(message = span_xenowarning("\A [xeno_owner] stings [xeno_target]!"), self_message = span_xenowarning("We sting [xeno_target]!"))
debuff.stacks -= round(debuff.stacks * 0.7)
succeed_activate()
@@ -177,7 +177,7 @@
SSblackbox.record_feedback("tally", "round_statistics", 1, "sentinel_drain_stings")
/datum/action/ability/activable/xeno/drain_sting/on_cooldown_finish()
- playsound(owner.loc, 'sound/voice/alien_drool1.ogg', 50, 1)
+ playsound(owner.loc, 'sound/voice/alien/drool1.ogg', 50, 1)
owner.balloon_alert(owner, "Drain Sting ready")
return ..()
@@ -220,7 +220,7 @@
smoke_duration = 4
dangerous = TRUE
smoketype = /datum/effect_system/smoke_spread/xeno/toxic
- arm_sound = 'sound/voice/alien_yell_alt.ogg'
+ arm_sound = 'sound/voice/alien/yell_alt.ogg'
smokeradius = 3
/obj/item/explosive/grenade/smokebomb/xeno/update_overlays()
diff --git a/code/modules/mob/living/carbon/xenomorph/castes/spitter/abilities_spitter.dm b/code/modules/mob/living/carbon/xenomorph/castes/spitter/abilities_spitter.dm
index 22cdd0196ad..f74cdbcb04c 100644
--- a/code/modules/mob/living/carbon/xenomorph/castes/spitter/abilities_spitter.dm
+++ b/code/modules/mob/living/carbon/xenomorph/castes/spitter/abilities_spitter.dm
@@ -94,7 +94,7 @@
/datum/action/ability/activable/xeno/spray_acid/line/on_cooldown_finish() //Give acid spray a proper cooldown notification
to_chat(owner, span_xenodanger("Our dermal pouches bloat with fresh acid; we can use acid spray again."))
- owner.playsound_local(owner, 'sound/voice/alien_drool2.ogg', 25, 0, 1)
+ owner.playsound_local(owner, 'sound/voice/alien/drool2.ogg', 25, 0, 1)
return ..()
// ***************************************
@@ -135,5 +135,5 @@
/datum/action/ability/activable/xeno/scatter_spit/on_cooldown_finish()
to_chat(owner, span_xenodanger("Our auxiliary sacks fill to bursting; we can use scatter spit again."))
- owner.playsound_local(owner, 'sound/voice/alien_drool1.ogg', 25, 0, 1)
+ owner.playsound_local(owner, 'sound/voice/alien/drool1.ogg', 25, 0, 1)
return ..()
diff --git a/code/modules/mob/living/carbon/xenomorph/castes/warlock/abilities_warlock.dm b/code/modules/mob/living/carbon/xenomorph/castes/warlock/abilities_warlock.dm
index 4e94675eea2..7ce5071e9b4 100644
--- a/code/modules/mob/living/carbon/xenomorph/castes/warlock/abilities_warlock.dm
+++ b/code/modules/mob/living/carbon/xenomorph/castes/warlock/abilities_warlock.dm
@@ -172,7 +172,7 @@
affected.throw_at(throwlocation, 4, 1, owner, TRUE)
playsound(owner,'sound/effects/bamf.ogg', 75, TRUE)
- playsound(owner, 'sound/voice/alien_roar_warlock.ogg', 25)
+ playsound(owner, 'sound/voice/alien/roar_warlock.ogg', 25)
GLOB.round_statistics.psy_shield_blasts++
SSblackbox.record_feedback("tally", "round_statistics", 1, "psy_shield_blasts")
diff --git a/code/modules/mob/living/carbon/xenomorph/castes/warrior/abilities_warrior.dm b/code/modules/mob/living/carbon/xenomorph/castes/warrior/abilities_warrior.dm
index e033747fb01..06775cfa9eb 100644
--- a/code/modules/mob/living/carbon/xenomorph/castes/warrior/abilities_warrior.dm
+++ b/code/modules/mob/living/carbon/xenomorph/castes/warrior/abilities_warrior.dm
@@ -59,7 +59,7 @@
/// Happens when Empower fades.
/datum/action/ability/xeno_action/empower/proc/empower_fade()
- owner.playsound_local(owner, 'sound/voice/hiss4.ogg', 25, 0, 1)
+ owner.playsound_local(owner, 'sound/voice/alien/hiss8.ogg', 25, 0, 1)
clear_empower()
@@ -772,5 +772,5 @@ RU TGMC EDIT*/
/datum/action/ability/activable/xeno/warrior/punch/jab/on_cooldown_finish()
var/mob/living/carbon/xenomorph/xeno_owner = owner
xeno_owner.balloon_alert(xeno_owner, "Jab ready")
- owner.playsound_local(owner, 'sound/effects/xeno_newlarva.ogg', 25, 0, 1)
+ owner.playsound_local(owner, 'sound/effects/alien/newlarva.ogg', 25, 0, 1)
return ..()
diff --git a/code/modules/mob/living/carbon/xenomorph/castes/wraith/abilities_wraith.dm b/code/modules/mob/living/carbon/xenomorph/castes/wraith/abilities_wraith.dm
index b086e6e5fb6..a85be7c090c 100644
--- a/code/modules/mob/living/carbon/xenomorph/castes/wraith/abilities_wraith.dm
+++ b/code/modules/mob/living/carbon/xenomorph/castes/wraith/abilities_wraith.dm
@@ -147,7 +147,7 @@ GLOBAL_LIST_INIT(wraith_banish_very_short_duration_list, typecacheof(list(
/datum/action/ability/activable/xeno/blink/on_cooldown_finish()
to_chat(owner, span_xenodanger("We are able to blink again."))
- owner.playsound_local(owner, 'sound/effects/xeno_newlarva.ogg', 25, 0, 1)
+ owner.playsound_local(owner, 'sound/effects/alien/newlarva.ogg', 25, 0, 1)
return ..()
// ***************************************
@@ -287,7 +287,7 @@ GLOBAL_LIST_INIT(wraith_banish_very_short_duration_list, typecacheof(list(
return
to_chat(owner,span_highdanger("Our banishment target [banishment_target.name] is about to return to reality at [AREACOORD_NO_Z(portal)]!"))
- owner.playsound_local(owner, 'sound/voice/hiss4.ogg', 50, 0, 1)
+ owner.playsound_local(owner, 'sound/voice/alien/hiss8.ogg', 50, 0, 1)
///Ends the effect of the Banish ability
/datum/action/ability/activable/xeno/banish/proc/banish_deactivate()
@@ -338,7 +338,7 @@ GLOBAL_LIST_INIT(wraith_banish_very_short_duration_list, typecacheof(list(
/datum/action/ability/activable/xeno/banish/on_cooldown_finish()
to_chat(owner, span_xenodanger("We are able to banish again."))
- owner.playsound_local(owner, 'sound/effects/xeno_newlarva.ogg', 25, 0, 1)
+ owner.playsound_local(owner, 'sound/effects/alien/newlarva.ogg', 25, 0, 1)
return ..()
// ***************************************
diff --git a/code/modules/mob/living/carbon/xenomorph/damage_procs.dm b/code/modules/mob/living/carbon/xenomorph/damage_procs.dm
index 5c3457aa490..e67512fc590 100644
--- a/code/modules/mob/living/carbon/xenomorph/damage_procs.dm
+++ b/code/modules/mob/living/carbon/xenomorph/damage_procs.dm
@@ -111,7 +111,7 @@
if(X.client.prefs.mute_xeno_health_alert_messages) //Build the filter list; people who opted not to receive health alert messages
filter_list += X //Add the xeno to the filter list
- xeno_message("Our sister [name] is badly hurt with ([health]/[maxHealth]) health remaining at [AREACOORD_NO_Z(src)]!", "xenoannounce", 5, hivenumber, FALSE, src, 'sound/voice/alien_help1.ogg', TRUE, filter_list, /atom/movable/screen/arrow/silo_damaged_arrow)
+ xeno_message("Our sister [name] is badly hurt with ([health]/[maxHealth]) health remaining at [AREACOORD_NO_Z(src)]!", "xenoannounce", 5, hivenumber, FALSE, src, 'sound/voice/alien/help1.ogg', TRUE, filter_list, /atom/movable/screen/arrow/silo_damaged_arrow)
COOLDOWN_START(src, xeno_health_alert_cooldown, XENO_HEALTH_ALERT_COOLDOWN) //set the cooldown.
return damage
diff --git a/code/modules/mob/living/carbon/xenomorph/death.dm b/code/modules/mob/living/carbon/xenomorph/death.dm
index c5a7573d96a..272e1eb20aa 100644
--- a/code/modules/mob/living/carbon/xenomorph/death.dm
+++ b/code/modules/mob/living/carbon/xenomorph/death.dm
@@ -1,6 +1,6 @@
/mob/living/carbon/xenomorph/proc/death_cry()
- playsound(loc, prob(50) ? 'sound/voice/alien_death.ogg' : 'sound/voice/alien_death2.ogg', 25, 1)
+ playsound(loc, prob(50) ? 'sound/voice/alien/death.ogg' : 'sound/voice/alien/death2.ogg', 25, 1)
/mob/living/carbon/xenomorph/death(gibbing, deathmessage = "lets out a waning guttural screech, green blood bubbling from its maw.", silent)
diff --git a/code/modules/mob/living/carbon/xenomorph/egg.dm b/code/modules/mob/living/carbon/xenomorph/egg.dm
index f67ceb114ab..5caa4d308b7 100644
--- a/code/modules/mob/living/carbon/xenomorph/egg.dm
+++ b/code/modules/mob/living/carbon/xenomorph/egg.dm
@@ -116,7 +116,7 @@
advance_maturity(stage_ready_to_burst + 1)
for(var/turf/turf_to_watch AS in filled_turfs(src, trigger_size, "circle", FALSE))
UnregisterSignal(turf_to_watch, COMSIG_ATOM_ENTERED)
- playsound(loc, "sound/effects/alien_egg_move.ogg", 25)
+ playsound(loc, "sound/effects/alien/egg_move.ogg", 25)
flick("egg opening", src)
var/mob/living/carbon/xenomorph/facehugger/new_hugger = new(loc)
@@ -162,10 +162,10 @@
return
if(via_damage)
hugger_type = null
- playsound(loc, "sound/effects/alien_egg_burst.ogg", 30)
+ playsound(loc, "sound/effects/alien/egg_burst.ogg", 30)
flick("egg exploding", src)
return
- playsound(src.loc, "sound/effects/alien_egg_move.ogg", 25)
+ playsound(src.loc, "sound/effects/alien/egg_move.ogg", 25)
flick("egg opening", src)
addtimer(CALLBACK(src, PROC_REF(spawn_hugger), loc), 1 SECONDS)
@@ -277,11 +277,11 @@
return
var/spread = EGG_GAS_DEFAULT_SPREAD
if(via_damage) // More violent destruction, more gas.
- playsound(loc, "sound/effects/alien_egg_burst.ogg", 30)
+ playsound(loc, "sound/effects/alien/egg_burst.ogg", 30)
flick("egg gas exploding", src)
spread = EGG_GAS_KILL_SPREAD
else
- playsound(src.loc, "sound/effects/alien_egg_move.ogg", 25)
+ playsound(src.loc, "sound/effects/alien/egg_move.ogg", 25)
flick("egg gas opening", src)
spread += gas_size_bonus
diff --git a/code/modules/mob/living/carbon/xenomorph/embryo.dm b/code/modules/mob/living/carbon/xenomorph/embryo.dm
index 58aedefb467..a3dae7170e5 100644
--- a/code/modules/mob/living/carbon/xenomorph/embryo.dm
+++ b/code/modules/mob/living/carbon/xenomorph/embryo.dm
@@ -162,7 +162,7 @@
if(picked)
picked.mind.transfer_to(new_xeno, TRUE)
to_chat(new_xeno, span_xenoannounce("We are a xenomorph larva inside a host! Move to burst out of it!"))
- new_xeno << sound('sound/effects/xeno_newlarva.ogg')
+ new_xeno << sound('sound/effects/alien/newlarva.ogg')
stage = 6
@@ -209,7 +209,7 @@
forceMove(veh.exit_location(src))
else
forceMove(get_turf(victim)) //moved to the turf directly so we don't get stuck inside a cryopod or another mob container.
- playsound(src, pick('sound/voice/alien_chestburst.ogg','sound/voice/alien_chestburst2.ogg'), 25)
+ playsound(src, pick('sound/voice/alien/chestburst.ogg','sound/voice/alien/chestburst2.ogg'), 25)
GLOB.round_statistics.total_larva_burst++
SSblackbox.record_feedback("tally", "round_statistics", 1, "total_larva_burst")
var/obj/item/alien_embryo/AE = locate() in victim
diff --git a/code/modules/mob/living/carbon/xenomorph/emote.dm b/code/modules/mob/living/carbon/xenomorph/emote.dm
index cc524fc7fda..33927f20f1d 100644
--- a/code/modules/mob/living/carbon/xenomorph/emote.dm
+++ b/code/modules/mob/living/carbon/xenomorph/emote.dm
@@ -15,23 +15,23 @@
key_third_person = "growls"
message = "growls!"
emote_type = EMOTE_AUDIBLE
- predalien_sound = 'sound/voice/predalien_growl.ogg'
- sound = 'sound/voice/alien_growl1.ogg'
+ predalien_sound = 'sound/voice/alien/predalien/growl.ogg'
+ sound = 'sound/voice/alien/growl1.ogg'
/datum/emote/living/carbon/xenomorph/growl/one
key = "growl1"
- sound = 'sound/voice/alien_growl1.ogg'
+ sound = 'sound/voice/alien/growl1.ogg'
/datum/emote/living/carbon/xenomorph/growl/two
key = "growl2"
- sound = 'sound/voice/alien_growl2.ogg'
+ sound = 'sound/voice/alien/growl2.ogg'
/datum/emote/living/carbon/xenomorph/growl/three
key = "growl3"
- sound = 'sound/voice/alien_growl3.ogg'
+ sound = 'sound/voice/alien/growl3.ogg'
/datum/emote/living/carbon/xenomorph/hiss
@@ -39,23 +39,23 @@
key_third_person = "hisses"
message = "hisses!"
emote_type = EMOTE_AUDIBLE
- predalien_sound = 'sound/voice/predalien_hiss.ogg'
- sound = 'sound/voice/alien_hiss1.ogg'
+ predalien_sound = 'sound/voice/alien/predalien/hiss.ogg'
+ sound = 'sound/voice/alien/hiss1.ogg'
/datum/emote/living/carbon/xenomorph/hiss/one
key = "hiss1"
- sound = 'sound/voice/alien_hiss1.ogg'
+ sound = 'sound/voice/alien/hiss1.ogg'
/datum/emote/living/carbon/xenomorph/hiss/two
key = "hiss2"
- sound = 'sound/voice/alien_hiss2.ogg'
+ sound = 'sound/voice/alien/hiss2.ogg'
/datum/emote/living/carbon/xenomorph/hiss/three
key = "hiss3"
- sound = 'sound/voice/alien_hiss3.ogg'
+ sound = 'sound/voice/alien/hiss3.ogg'
/datum/emote/living/carbon/xenomorph/needhelp
@@ -63,17 +63,17 @@
key_third_person = "needshelp"
message = "needs help!"
emote_type = EMOTE_AUDIBLE
- sound = 'sound/voice/alien_help1.ogg'
+ sound = 'sound/voice/alien/help1.ogg'
/datum/emote/living/carbon/xenomorph/needhelp/one
key = "needhelp1"
- sound = 'sound/voice/alien_help1.ogg'
+ sound = 'sound/voice/alien/help1.ogg'
/datum/emote/living/carbon/xenomorph/needhelp/two
key = "needhelp2"
- sound = 'sound/voice/alien_help2.ogg'
+ sound = 'sound/voice/alien/help2.ogg'
/datum/emote/living/carbon/xenomorph/roar
@@ -81,38 +81,38 @@
key_third_person = "roars"
message = "roars!"
emote_type = EMOTE_AUDIBLE
- predalien_sound = 'sound/voice/predalien_roar.ogg'
- sound = 'sound/voice/alien_roar1.ogg'
+ predalien_sound = 'sound/voice/alien/predalien/roar.ogg'
+ sound = 'sound/voice/alien/roar1.ogg'
/datum/emote/living/carbon/xenomorph/roar/one
key = "roar1"
- sound = 'sound/voice/alien_roar1.ogg'
+ sound = 'sound/voice/alien/roar1.ogg'
/datum/emote/living/carbon/xenomorph/roar/two
key = "roar2"
- sound = 'sound/voice/alien_roar2.ogg'
+ sound = 'sound/voice/alien/roar2.ogg'
/datum/emote/living/carbon/xenomorph/roar/three
key = "roar3"
- sound = 'sound/voice/alien_roar3.ogg'
+ sound = 'sound/voice/alien/roar3.ogg'
/datum/emote/living/carbon/xenomorph/roar/four
key = "roar4"
- sound = 'sound/voice/alien_roar4.ogg'
+ sound = 'sound/voice/alien/roar4.ogg'
/datum/emote/living/carbon/xenomorph/roar/five
key = "roar5"
- sound = 'sound/voice/alien_roar5.ogg'
+ sound = 'sound/voice/alien/roar5.ogg'
/datum/emote/living/carbon/xenomorph/roar/six
key = "roar6"
- sound = 'sound/voice/alien_roar6.ogg'
+ sound = 'sound/voice/alien/roar6.ogg'
/datum/emote/living/carbon/xenomorph/tail
@@ -120,22 +120,22 @@
key_third_person = "tailsweeps"
message = "swipes its tail."
emote_type = EMOTE_AUDIBLE
- sound = 'sound/effects/alien_tail_swipe1.ogg'
+ sound = 'sound/effects/alien/tail_swipe1.ogg'
/datum/emote/living/carbon/xenomorph/tail/one
key = "tail1"
- sound = 'sound/effects/alien_tail_swipe1.ogg'
+ sound = 'sound/effects/alien/tail_swipe1.ogg'
/datum/emote/living/carbon/xenomorph/tail/two
key = "tail2"
- sound = 'sound/effects/alien_tail_swipe2.ogg'
+ sound = 'sound/effects/alien/tail_swipe2.ogg'
/datum/emote/living/carbon/xenomorph/tail/three
key = "tail3"
- sound = 'sound/effects/alien_tail_swipe3.ogg'
+ sound = 'sound/effects/alien/tail_swipe3.ogg'
/datum/emote/living/carbon/xenomorph/run_emote(mob/user, params, type_override, intentional = FALSE, prefix)
diff --git a/code/modules/mob/living/carbon/xenomorph/facehuggers.dm b/code/modules/mob/living/carbon/xenomorph/facehuggers.dm
index b39fb232626..23529590f74 100644
--- a/code/modules/mob/living/carbon/xenomorph/facehuggers.dm
+++ b/code/modules/mob/living/carbon/xenomorph/facehuggers.dm
@@ -594,7 +594,7 @@
kill_hugger()
else
reset_attach_status(as_planned)
- playsound(loc, 'sound/voice/alien_facehugger_dies.ogg', 25, 1)
+ playsound(loc, 'sound/voice/alien/facehugger_dies.ogg', 25, 1)
activetimer = addtimer(CALLBACK(src, PROC_REF(go_active)), activate_time, TIMER_STOPPABLE|TIMER_UNIQUE)
update_icon()
@@ -621,7 +621,7 @@
remove_danger_overlay() //Remove the danger overlay
update_icon()
- playsound(loc, 'sound/voice/alien_facehugger_dies.ogg', 25, 1)
+ playsound(loc, 'sound/voice/alien/facehugger_dies.ogg', 25, 1)
layer = BELOW_MOB_LAYER //so dead hugger appears below live hugger if stacked on same tile.
diff --git a/code/modules/mob/living/carbon/xenomorph/hive_datum.dm b/code/modules/mob/living/carbon/xenomorph/hive_datum.dm
index b127aa0c497..3360e6c0120 100644
--- a/code/modules/mob/living/carbon/xenomorph/hive_datum.dm
+++ b/code/modules/mob/living/carbon/xenomorph/hive_datum.dm
@@ -1266,7 +1266,7 @@ to_chat will check for valid clients itself already so no need to double check f
message_admins("[key_name(xeno_candidate)] has joined as [ADMIN_TPMONTY(new_xeno)].")
xeno_candidate.mob.mind.transfer_to(new_xeno, TRUE)
- new_xeno.playsound_local(new_xeno, 'sound/effects/xeno_newlarva.ogg')
+ new_xeno.playsound_local(new_xeno, 'sound/effects/alien/newlarva.ogg')
to_chat(new_xeno, span_xenoannounce("We are a xenomorph larva awakened from slumber!"))
if(!larva_already_reserved)
xeno_job.occupy_job_positions(1)
diff --git a/code/modules/mob/living/carbon/xenomorph/xenoprocs.dm b/code/modules/mob/living/carbon/xenomorph/xenoprocs.dm
index 31e79e28f98..f7e53ce3d59 100644
--- a/code/modules/mob/living/carbon/xenomorph/xenoprocs.dm
+++ b/code/modules/mob/living/carbon/xenomorph/xenoprocs.dm
@@ -261,7 +261,7 @@
if(evolution_stored == xeno_caste.evolution_threshold)
to_chat(src, span_xenodanger("Our carapace crackles and our tendons strengthen. We are ready to evolve!"))
- SEND_SOUND(src, sound('sound/effects/xeno_evolveready.ogg'))
+ SEND_SOUND(src, sound('sound/effects/alien/evolveready.ogg'))
//This deals with "throwing" xenos -- ravagers, hunters, and runners in particular. Everyone else defaults to normal
diff --git a/code/modules/mob/living/silicon/ai/ai_notifications.dm b/code/modules/mob/living/silicon/ai/ai_notifications.dm
index 59bfb1049bd..7c3b481b6c2 100644
--- a/code/modules/mob/living/silicon/ai/ai_notifications.dm
+++ b/code/modules/mob/living/silicon/ai/ai_notifications.dm
@@ -45,14 +45,14 @@
SIGNAL_HANDLER
var/area/A = get_area(lockedship)
to_chat(src, span_notice("Electronic corruption detected at [A]! Controls overridden!"))
- playsound_local(src, 'sound/voice/4_xeno_roars.ogg', 15)
+ playsound_local(src, 'sound/voice/alien/4_roars.ogg', 15)
notify_ai(src, " Electronic corruption detected at [A]! Controls overridden! " , source = lockedship, action = NOTIFY_AI_ALERT, notify_volume = 15)
///Receive notifications about the tad control equipment being destroyed
/mob/living/silicon/ai/proc/receive_tad_warning(datum/source, obj/machinery/computer/camera_advanced/shuttle_docker/minidropship/ruinedtad)
SIGNAL_HANDLER
to_chat(src, span_notice("Telemetry from our mini dropship reports that the controls have become nonfunctional!"))
- notify_ai(src, " Telemetry from our mini dropship reports that the controls have become nonfunctional! ", ai_sound = 'sound/voice/4_xeno_roars.ogg', source = ruinedtad, action = NOTIFY_AI_ALERT, notify_volume = 15)
+ notify_ai(src, " Telemetry from our mini dropship reports that the controls have become nonfunctional! ", ai_sound = 'sound/voice/alien/4_roars.ogg', source = ruinedtad, action = NOTIFY_AI_ALERT, notify_volume = 15)
///Receive notifications about disks being generated
/mob/living/silicon/ai/proc/show_disk_complete(datum/source, obj/machinery/computer/nuke_disk_generator/generatingcomputer)
diff --git a/code/modules/mob/living/simple_animal/hostile/alien.dm b/code/modules/mob/living/simple_animal/hostile/alien.dm
index 75a9bb9dccc..6fc64779728 100644
--- a/code/modules/mob/living/simple_animal/hostile/alien.dm
+++ b/code/modules/mob/living/simple_animal/hostile/alien.dm
@@ -45,5 +45,5 @@
if(stat == DEAD)
return ..()
if(!gibbing && !silent)
- playsound(src, 'sound/voice/alien_death.ogg', 50, TRUE)
+ playsound(src, 'sound/voice/alien/death.ogg', 50, TRUE)
return ..()
diff --git a/code/modules/predator/yautja/bracers.dm b/code/modules/predator/yautja/bracers.dm
index c8219aa155c..deae7ceb1f1 100644
--- a/code/modules/predator/yautja/bracers.dm
+++ b/code/modules/predator/yautja/bracers.dm
@@ -616,7 +616,7 @@
exploding = TRUE
var/turf/T = get_turf(src)
if(explosion_type == SD_TYPE_BIG && victim.stat == CONSCIOUS && (is_ground_level(T.z) || SSticker.mode.flags_round_type & MODE_SHIPSIDE_SD))
- playsound(src, 'sound/voice/pred_deathlaugh.ogg', 100, 0, 17)
+ playsound(src, 'sound/voice/predator/deathlaugh.ogg', 100, 0, 17)
playsound(src, 'sound/effects/pred_countdown.ogg', 100, 0, 17)
message_admins(font_size_xl("CLICK TO CANCEL THIS PRED SD"))
diff --git a/code/modules/vehicles/mecha/combat/savannah_ivanov.dm b/code/modules/vehicles/mecha/combat/savannah_ivanov.dm
index 1df73bcf698..ed8c6e0de7f 100644
--- a/code/modules/vehicles/mecha/combat/savannah_ivanov.dm
+++ b/code/modules/vehicles/mecha/combat/savannah_ivanov.dm
@@ -155,7 +155,7 @@
*/
/datum/action/vehicle/sealed/mecha/skyfall/proc/land()
chassis.visible_message(span_danger("[chassis] lands from above!"))
- playsound(chassis, 'sound/effects/explosion_large1.ogg', 50, 1)
+ playsound(chassis, 'sound/effects/explosion/large1.ogg', 50, 1)
chassis.resistance_flags &= ~INDESTRUCTIBLE
chassis.mecha_flags &= ~(QUIET_STEPS|QUIET_TURNS|CANNOT_INTERACT)
chassis.phasing = initial(chassis.phasing)
diff --git a/code/modules/xenomorph/silo.dm b/code/modules/xenomorph/silo.dm
index ef3e9ac28ff..1bc6a028beb 100644
--- a/code/modules/xenomorph/silo.dm
+++ b/code/modules/xenomorph/silo.dm
@@ -61,9 +61,9 @@
if(GLOB.hive_datums[hivenumber])
INVOKE_NEXT_TICK(SSticker.mode, TYPE_PROC_REF(/datum/game_mode, update_silo_death_timer), GLOB.hive_datums[hivenumber]) // checks all silos next tick after this one is gone
UnregisterSignal(GLOB.hive_datums[hivenumber], list(COMSIG_HIVE_XENO_MOTHER_PRE_CHECK, COMSIG_HIVE_XENO_MOTHER_CHECK))
- GLOB.hive_datums[hivenumber].xeno_message("A resin silo has been destroyed at [AREACOORD_NO_Z(src)]!", "xenoannounce", 5, FALSE,src.loc, 'sound/voice/alien_help2.ogg',FALSE , null, /atom/movable/screen/arrow/silo_damaged_arrow)
+ GLOB.hive_datums[hivenumber].xeno_message("A resin silo has been destroyed at [AREACOORD_NO_Z(src)]!", "xenoannounce", 5, FALSE,src.loc, 'sound/voice/alien/help2.ogg',FALSE , null, /atom/movable/screen/arrow/silo_damaged_arrow)
notify_ghosts("\ A resin silo has been destroyed at [AREACOORD_NO_Z(src)]!", source = get_turf(src), action = NOTIFY_JUMP)
- playsound(loc,'sound/effects/alien_egg_burst.ogg', 75)
+ playsound(loc,'sound/effects/alien/egg_burst.ogg', 75)
return ..()
/obj/structure/xeno/silo/Destroy()
@@ -106,7 +106,7 @@
return
warning = TRUE
update_minimap_icon()
- GLOB.hive_datums[hivenumber].xeno_message("Our [name] at [AREACOORD_NO_Z(src)] is under attack! It has [obj_integrity]/[max_integrity] Health remaining.", "xenoannounce", 5, FALSE, src, 'sound/voice/alien_help1.ogg',FALSE, null, /atom/movable/screen/arrow/silo_damaged_arrow)
+ GLOB.hive_datums[hivenumber].xeno_message("Our [name] at [AREACOORD_NO_Z(src)] is under attack! It has [obj_integrity]/[max_integrity] Health remaining.", "xenoannounce", 5, FALSE, src, 'sound/voice/alien/help1.ogg',FALSE, null, /atom/movable/screen/arrow/silo_damaged_arrow)
COOLDOWN_START(src, silo_damage_alert_cooldown, XENO_SILO_HEALTH_ALERT_COOLDOWN) //set the cooldown.
addtimer(CALLBACK(src, PROC_REF(clear_warning)), XENO_SILO_HEALTH_ALERT_COOLDOWN) //clear warning
@@ -131,7 +131,7 @@
warning = TRUE
update_minimap_icon()
- GLOB.hive_datums[hivenumber].xeno_message("Our [name] has detected a nearby hostile [hostile] at [get_area(hostile)] (X: [hostile.x], Y: [hostile.y]).", "xenoannounce", 5, FALSE, hostile, 'sound/voice/alien_help1.ogg', FALSE, null, /atom/movable/screen/arrow/leader_tracker_arrow)
+ GLOB.hive_datums[hivenumber].xeno_message("Our [name] has detected a nearby hostile [hostile] at [get_area(hostile)] (X: [hostile.x], Y: [hostile.y]).", "xenoannounce", 5, FALSE, hostile, 'sound/voice/alien/help1.ogg', FALSE, null, /atom/movable/screen/arrow/leader_tracker_arrow)
COOLDOWN_START(src, silo_proxy_alert_cooldown, XENO_SILO_DETECTION_COOLDOWN) //set the cooldown.
addtimer(CALLBACK(src, PROC_REF(clear_warning)), XENO_SILO_DETECTION_COOLDOWN) //clear warning
diff --git a/code/modules/xenomorph/spawner.dm b/code/modules/xenomorph/spawner.dm
index 441780081b0..28747bb1f22 100644
--- a/code/modules/xenomorph/spawner.dm
+++ b/code/modules/xenomorph/spawner.dm
@@ -53,7 +53,7 @@
return
warning = TRUE
update_minimap_icon()
- GLOB.hive_datums[hivenumber].xeno_message("Our [name] at [AREACOORD_NO_Z(src)] is under attack! It has [obj_integrity]/[max_integrity] Health remaining.", "xenoannounce", 5, FALSE, src, 'sound/voice/alien_help1.ogg',FALSE, null, /atom/movable/screen/arrow/silo_damaged_arrow)
+ GLOB.hive_datums[hivenumber].xeno_message("Our [name] at [AREACOORD_NO_Z(src)] is under attack! It has [obj_integrity]/[max_integrity] Health remaining.", "xenoannounce", 5, FALSE, src, 'sound/voice/alien/help1.ogg',FALSE, null, /atom/movable/screen/arrow/silo_damaged_arrow)
COOLDOWN_START(src, spawner_damage_alert_cooldown, XENO_SILO_HEALTH_ALERT_COOLDOWN) //set the cooldown.
addtimer(CALLBACK(src, PROC_REF(clear_warning)), XENO_SILO_DETECTION_COOLDOWN) //clear warning
@@ -79,7 +79,7 @@
warning = TRUE
update_minimap_icon()
- GLOB.hive_datums[hivenumber].xeno_message("Our [name] has detected a nearby hostile [hostile] at [get_area(hostile)] (X: [hostile.x], Y: [hostile.y]).", "xenoannounce", 5, FALSE, hostile, 'sound/voice/alien_help1.ogg', FALSE, null, /atom/movable/screen/arrow/leader_tracker_arrow)
+ GLOB.hive_datums[hivenumber].xeno_message("Our [name] has detected a nearby hostile [hostile] at [get_area(hostile)] (X: [hostile.x], Y: [hostile.y]).", "xenoannounce", 5, FALSE, hostile, 'sound/voice/alien/help1.ogg', FALSE, null, /atom/movable/screen/arrow/leader_tracker_arrow)
COOLDOWN_START(src, spawner_proxy_alert_cooldown, XENO_SILO_DETECTION_COOLDOWN) //set the cooldown.
addtimer(CALLBACK(src, PROC_REF(clear_warning)), XENO_SILO_DETECTION_COOLDOWN) //clear warning
diff --git a/code/modules/xenomorph/trap.dm b/code/modules/xenomorph/trap.dm
index f6180ad44ae..a8cfea59a82 100644
--- a/code/modules/xenomorph/trap.dm
+++ b/code/modules/xenomorph/trap.dm
@@ -121,7 +121,7 @@
if(TRAP_ACID_STRONG)
for(var/turf/acided AS in RANGE_TURFS(1, src))
new /obj/effect/xenomorph/spray/strong(acided, 12 SECONDS, XENO_HIGH_ACID_PUDDLE_DAMAGE)
- xeno_message("A [trap_type] trap at [AREACOORD_NO_Z(src)] has been triggered!", "xenoannounce", 5, hivenumber, FALSE, get_turf(src), 'sound/voice/alien_talk2.ogg', FALSE, null, /atom/movable/screen/arrow/attack_order_arrow, COLOR_ORANGE, TRUE)
+ xeno_message("A [trap_type] trap at [AREACOORD_NO_Z(src)] has been triggered!", "xenoannounce", 5, hivenumber, FALSE, get_turf(src), 'sound/voice/alien/talk2.ogg', FALSE, null, /atom/movable/screen/arrow/attack_order_arrow, COLOR_ORANGE, TRUE)
set_trap_type(null)
/// Move the hugger out of the trap
diff --git a/code/modules/xenomorph/turret.dm b/code/modules/xenomorph/turret.dm
index 11a6905b9a4..82b2c92ab07 100644
--- a/code/modules/xenomorph/turret.dm
+++ b/code/modules/xenomorph/turret.dm
@@ -70,7 +70,7 @@
set_hostile(null)
set_last_hostile(null)
STOP_PROCESSING(SSobj, src)
- playsound(loc,'sound/effects/xeno_turret_death.ogg', 70)
+ playsound(loc,'sound/effects/alien/turret_death.ogg', 70)
return ..()
/obj/structure/xeno/xeno_turret/ex_act(severity)
@@ -110,7 +110,7 @@
set_last_hostile(null)
return
if(!TIMER_COOLDOWN_CHECK(src, COOLDOWN_XENO_TURRETS_ALERT))
- GLOB.hive_datums[hivenumber].xeno_message("Our [name] is attacking a nearby hostile [hostile] at [get_area(hostile)] (X: [hostile.x], Y: [hostile.y]).", "xenoannounce", 5, FALSE, hostile, 'sound/voice/alien_help1.ogg', FALSE, null, /atom/movable/screen/arrow/turret_attacking_arrow)
+ GLOB.hive_datums[hivenumber].xeno_message("Our [name] is attacking a nearby hostile [hostile] at [get_area(hostile)] (X: [hostile.x], Y: [hostile.y]).", "xenoannounce", 5, FALSE, hostile, 'sound/voice/alien/help1.ogg', FALSE, null, /atom/movable/screen/arrow/turret_attacking_arrow)
TIMER_COOLDOWN_START(src, COOLDOWN_XENO_TURRETS_ALERT, 20 SECONDS)
if(hostile != last_hostile)
set_last_hostile(hostile)
diff --git a/sound/effects/behemoth/earth_pillar_destroyed.ogg b/sound/effects/alien/behemoth/earth_pillar_destroyed.ogg
similarity index 100%
rename from sound/effects/behemoth/earth_pillar_destroyed.ogg
rename to sound/effects/alien/behemoth/earth_pillar_destroyed.ogg
diff --git a/sound/effects/behemoth/earth_pillar_eating.ogg b/sound/effects/alien/behemoth/earth_pillar_eating.ogg
similarity index 100%
rename from sound/effects/behemoth/earth_pillar_eating.ogg
rename to sound/effects/alien/behemoth/earth_pillar_eating.ogg
diff --git a/sound/effects/behemoth/earth_pillar_hit_1.ogg b/sound/effects/alien/behemoth/earth_pillar_hit_1.ogg
similarity index 100%
rename from sound/effects/behemoth/earth_pillar_hit_1.ogg
rename to sound/effects/alien/behemoth/earth_pillar_hit_1.ogg
diff --git a/sound/effects/behemoth/earth_pillar_hit_2.ogg b/sound/effects/alien/behemoth/earth_pillar_hit_2.ogg
similarity index 100%
rename from sound/effects/behemoth/earth_pillar_hit_2.ogg
rename to sound/effects/alien/behemoth/earth_pillar_hit_2.ogg
diff --git a/sound/effects/behemoth/earth_pillar_hit_3.ogg b/sound/effects/alien/behemoth/earth_pillar_hit_3.ogg
similarity index 100%
rename from sound/effects/behemoth/earth_pillar_hit_3.ogg
rename to sound/effects/alien/behemoth/earth_pillar_hit_3.ogg
diff --git a/sound/effects/behemoth/earth_pillar_hit_4.ogg b/sound/effects/alien/behemoth/earth_pillar_hit_4.ogg
similarity index 100%
rename from sound/effects/behemoth/earth_pillar_hit_4.ogg
rename to sound/effects/alien/behemoth/earth_pillar_hit_4.ogg
diff --git a/sound/effects/behemoth/earth_pillar_hit_5.ogg b/sound/effects/alien/behemoth/earth_pillar_hit_5.ogg
similarity index 100%
rename from sound/effects/behemoth/earth_pillar_hit_5.ogg
rename to sound/effects/alien/behemoth/earth_pillar_hit_5.ogg
diff --git a/sound/effects/behemoth/earth_pillar_hit_6.ogg b/sound/effects/alien/behemoth/earth_pillar_hit_6.ogg
similarity index 100%
rename from sound/effects/behemoth/earth_pillar_hit_6.ogg
rename to sound/effects/alien/behemoth/earth_pillar_hit_6.ogg
diff --git a/sound/effects/behemoth/earth_pillar_rising.ogg b/sound/effects/alien/behemoth/earth_pillar_rising.ogg
similarity index 100%
rename from sound/effects/behemoth/earth_pillar_rising.ogg
rename to sound/effects/alien/behemoth/earth_pillar_rising.ogg
diff --git a/sound/effects/behemoth/landslide_enhanced_charge.ogg b/sound/effects/alien/behemoth/landslide_enhanced_charge.ogg
similarity index 100%
rename from sound/effects/behemoth/landslide_enhanced_charge.ogg
rename to sound/effects/alien/behemoth/landslide_enhanced_charge.ogg
diff --git a/sound/effects/behemoth/landslide_hit_mob.ogg b/sound/effects/alien/behemoth/landslide_hit_mob.ogg
similarity index 100%
rename from sound/effects/behemoth/landslide_hit_mob.ogg
rename to sound/effects/alien/behemoth/landslide_hit_mob.ogg
diff --git a/sound/effects/behemoth/landslide_roar.ogg b/sound/effects/alien/behemoth/landslide_roar.ogg
similarity index 100%
rename from sound/effects/behemoth/landslide_roar.ogg
rename to sound/effects/alien/behemoth/landslide_roar.ogg
diff --git a/sound/effects/behemoth/primal_wrath_roar.ogg b/sound/effects/alien/behemoth/primal_wrath_roar.ogg
similarity index 100%
rename from sound/effects/behemoth/primal_wrath_roar.ogg
rename to sound/effects/alien/behemoth/primal_wrath_roar.ogg
diff --git a/sound/effects/behemoth/behemoth_roll.ogg b/sound/effects/alien/behemoth/roll.ogg
similarity index 100%
rename from sound/effects/behemoth/behemoth_roll.ogg
rename to sound/effects/alien/behemoth/roll.ogg
diff --git a/sound/effects/behemoth/behemoth_rumble.ogg b/sound/effects/alien/behemoth/rumble.ogg
similarity index 100%
rename from sound/effects/behemoth/behemoth_rumble.ogg
rename to sound/effects/alien/behemoth/rumble.ogg
diff --git a/sound/effects/behemoth/seismic_fracture_explosion.ogg b/sound/effects/alien/behemoth/seismic_fracture_explosion.ogg
similarity index 100%
rename from sound/effects/behemoth/seismic_fracture_explosion.ogg
rename to sound/effects/alien/behemoth/seismic_fracture_explosion.ogg
diff --git a/sound/effects/behemoth/behemoth_stomp.ogg b/sound/effects/alien/behemoth/stomp.ogg
similarity index 100%
rename from sound/effects/behemoth/behemoth_stomp.ogg
rename to sound/effects/alien/behemoth/stomp.ogg
diff --git a/sound/effects/alien_egg_burst.ogg b/sound/effects/alien/egg_burst.ogg
similarity index 100%
rename from sound/effects/alien_egg_burst.ogg
rename to sound/effects/alien/egg_burst.ogg
diff --git a/sound/effects/alien_egg_move.ogg b/sound/effects/alien/egg_move.ogg
similarity index 100%
rename from sound/effects/alien_egg_move.ogg
rename to sound/effects/alien/egg_move.ogg
diff --git a/sound/effects/xeno_evolveready.ogg b/sound/effects/alien/evolveready.ogg
similarity index 100%
rename from sound/effects/xeno_evolveready.ogg
rename to sound/effects/alien/evolveready.ogg
diff --git a/sound/effects/xeno_newlarva.ogg b/sound/effects/alien/newlarva.ogg
similarity index 100%
rename from sound/effects/xeno_newlarva.ogg
rename to sound/effects/alien/newlarva.ogg
diff --git a/sound/effects/alien_recycler.ogg b/sound/effects/alien/recycler.ogg
similarity index 100%
rename from sound/effects/alien_recycler.ogg
rename to sound/effects/alien/recycler.ogg
diff --git a/sound/effects/alien_resin_break1.ogg b/sound/effects/alien/resin_break1.ogg
similarity index 100%
rename from sound/effects/alien_resin_break1.ogg
rename to sound/effects/alien/resin_break1.ogg
diff --git a/sound/effects/alien_resin_break2.ogg b/sound/effects/alien/resin_break2.ogg
similarity index 100%
rename from sound/effects/alien_resin_break2.ogg
rename to sound/effects/alien/resin_break2.ogg
diff --git a/sound/effects/alien_resin_build1.ogg b/sound/effects/alien/resin_build1.ogg
similarity index 100%
rename from sound/effects/alien_resin_build1.ogg
rename to sound/effects/alien/resin_build1.ogg
diff --git a/sound/effects/alien_resin_build2.ogg b/sound/effects/alien/resin_build2.ogg
similarity index 100%
rename from sound/effects/alien_resin_build2.ogg
rename to sound/effects/alien/resin_build2.ogg
diff --git a/sound/effects/alien_resin_build3.ogg b/sound/effects/alien/resin_build3.ogg
similarity index 100%
rename from sound/effects/alien_resin_build3.ogg
rename to sound/effects/alien/resin_build3.ogg
diff --git a/sound/effects/footstep/alien_resin_move1.ogg b/sound/effects/alien/resin_move1.ogg
similarity index 100%
rename from sound/effects/footstep/alien_resin_move1.ogg
rename to sound/effects/alien/resin_move1.ogg
diff --git a/sound/effects/footstep/alien_resin_move2.ogg b/sound/effects/alien/resin_move2.ogg
similarity index 100%
rename from sound/effects/footstep/alien_resin_move2.ogg
rename to sound/effects/alien/resin_move2.ogg
diff --git a/sound/effects/alien_tail_swipe1.ogg b/sound/effects/alien/tail_swipe1.ogg
similarity index 100%
rename from sound/effects/alien_tail_swipe1.ogg
rename to sound/effects/alien/tail_swipe1.ogg
diff --git a/sound/effects/alien_tail_swipe2.ogg b/sound/effects/alien/tail_swipe2.ogg
similarity index 100%
rename from sound/effects/alien_tail_swipe2.ogg
rename to sound/effects/alien/tail_swipe2.ogg
diff --git a/sound/effects/alien_tail_swipe3.ogg b/sound/effects/alien/tail_swipe3.ogg
similarity index 100%
rename from sound/effects/alien_tail_swipe3.ogg
rename to sound/effects/alien/tail_swipe3.ogg
diff --git a/sound/effects/xeno_turret_death.ogg b/sound/effects/alien/turret_death.ogg
similarity index 100%
rename from sound/effects/xeno_turret_death.ogg
rename to sound/effects/alien/turret_death.ogg
diff --git a/sound/effects/alien_ventcrawl1.ogg b/sound/effects/alien/ventcrawl1.ogg
similarity index 100%
rename from sound/effects/alien_ventcrawl1.ogg
rename to sound/effects/alien/ventcrawl1.ogg
diff --git a/sound/effects/alien_ventcrawl2.ogg b/sound/effects/alien/ventcrawl2.ogg
similarity index 100%
rename from sound/effects/alien_ventcrawl2.ogg
rename to sound/effects/alien/ventcrawl2.ogg
diff --git a/sound/effects/alien_ventpass1.ogg b/sound/effects/alien/ventpass1.ogg
similarity index 100%
rename from sound/effects/alien_ventpass1.ogg
rename to sound/effects/alien/ventpass1.ogg
diff --git a/sound/effects/alien_ventpass2.ogg b/sound/effects/alien/ventpass2.ogg
similarity index 100%
rename from sound/effects/alien_ventpass2.ogg
rename to sound/effects/alien/ventpass2.ogg
diff --git a/sound/effects/explosioncreak1.ogg b/sound/effects/explosion/creak1.ogg
similarity index 100%
rename from sound/effects/explosioncreak1.ogg
rename to sound/effects/explosion/creak1.ogg
diff --git a/sound/effects/explosioncreak2.ogg b/sound/effects/explosion/creak2.ogg
similarity index 100%
rename from sound/effects/explosioncreak2.ogg
rename to sound/effects/explosion/creak2.ogg
diff --git a/sound/effects/explosionfar.ogg b/sound/effects/explosion/far0.ogg
similarity index 100%
rename from sound/effects/explosionfar.ogg
rename to sound/effects/explosion/far0.ogg
diff --git a/sound/effects/explosion_far1.ogg b/sound/effects/explosion/far1.ogg
similarity index 100%
rename from sound/effects/explosion_far1.ogg
rename to sound/effects/explosion/far1.ogg
diff --git a/sound/effects/explosion_far2.ogg b/sound/effects/explosion/far2.ogg
similarity index 100%
rename from sound/effects/explosion_far2.ogg
rename to sound/effects/explosion/far2.ogg
diff --git a/sound/effects/explosion_far3.ogg b/sound/effects/explosion/far3.ogg
similarity index 100%
rename from sound/effects/explosion_far3.ogg
rename to sound/effects/explosion/far3.ogg
diff --git a/sound/effects/explosion_far4.ogg b/sound/effects/explosion/far4.ogg
similarity index 100%
rename from sound/effects/explosion_far4.ogg
rename to sound/effects/explosion/far4.ogg
diff --git a/sound/effects/explosion_far5.ogg b/sound/effects/explosion/far5.ogg
similarity index 100%
rename from sound/effects/explosion_far5.ogg
rename to sound/effects/explosion/far5.ogg
diff --git a/sound/effects/incendiary_explosion_1.ogg b/sound/effects/explosion/incendiary1.ogg
similarity index 100%
rename from sound/effects/incendiary_explosion_1.ogg
rename to sound/effects/explosion/incendiary1.ogg
diff --git a/sound/effects/incendiary_explosion_2.ogg b/sound/effects/explosion/incendiary2.ogg
similarity index 100%
rename from sound/effects/incendiary_explosion_2.ogg
rename to sound/effects/explosion/incendiary2.ogg
diff --git a/sound/effects/incendiary_explosion_3.ogg b/sound/effects/explosion/incendiary3.ogg
similarity index 100%
rename from sound/effects/incendiary_explosion_3.ogg
rename to sound/effects/explosion/incendiary3.ogg
diff --git a/sound/effects/explosion_large1.ogg b/sound/effects/explosion/large1.ogg
similarity index 100%
rename from sound/effects/explosion_large1.ogg
rename to sound/effects/explosion/large1.ogg
diff --git a/sound/effects/explosion_large2.ogg b/sound/effects/explosion/large2.ogg
similarity index 100%
rename from sound/effects/explosion_large2.ogg
rename to sound/effects/explosion/large2.ogg
diff --git a/sound/effects/explosion_large3.ogg b/sound/effects/explosion/large3.ogg
similarity index 100%
rename from sound/effects/explosion_large3.ogg
rename to sound/effects/explosion/large3.ogg
diff --git a/sound/effects/explosion_large4.ogg b/sound/effects/explosion/large4.ogg
similarity index 100%
rename from sound/effects/explosion_large4.ogg
rename to sound/effects/explosion/large4.ogg
diff --git a/sound/effects/explosion_large5.ogg b/sound/effects/explosion/large5.ogg
similarity index 100%
rename from sound/effects/explosion_large5.ogg
rename to sound/effects/explosion/large5.ogg
diff --git a/sound/effects/explosion_large6.ogg b/sound/effects/explosion/large6.ogg
similarity index 100%
rename from sound/effects/explosion_large6.ogg
rename to sound/effects/explosion/large6.ogg
diff --git a/sound/effects/explosion_med1.ogg b/sound/effects/explosion/medium1.ogg
similarity index 100%
rename from sound/effects/explosion_med1.ogg
rename to sound/effects/explosion/medium1.ogg
diff --git a/sound/effects/explosion_med2.ogg b/sound/effects/explosion/medium2.ogg
similarity index 100%
rename from sound/effects/explosion_med2.ogg
rename to sound/effects/explosion/medium2.ogg
diff --git a/sound/effects/explosion_med3.ogg b/sound/effects/explosion/medium3.ogg
similarity index 100%
rename from sound/effects/explosion_med3.ogg
rename to sound/effects/explosion/medium3.ogg
diff --git a/sound/effects/explosion_med4.ogg b/sound/effects/explosion/medium4.ogg
similarity index 100%
rename from sound/effects/explosion_med4.ogg
rename to sound/effects/explosion/medium4.ogg
diff --git a/sound/effects/explosion_med5.ogg b/sound/effects/explosion/medium5.ogg
similarity index 100%
rename from sound/effects/explosion_med5.ogg
rename to sound/effects/explosion/medium5.ogg
diff --git a/sound/effects/explosion_med6.ogg b/sound/effects/explosion/medium6.ogg
similarity index 100%
rename from sound/effects/explosion_med6.ogg
rename to sound/effects/explosion/medium6.ogg
diff --git a/sound/effects/explosion_micro1.ogg b/sound/effects/explosion/micro1.ogg
similarity index 100%
rename from sound/effects/explosion_micro1.ogg
rename to sound/effects/explosion/micro1.ogg
diff --git a/sound/effects/explosion_micro2.ogg b/sound/effects/explosion/micro2.ogg
similarity index 100%
rename from sound/effects/explosion_micro2.ogg
rename to sound/effects/explosion/micro2.ogg
diff --git a/sound/effects/explosion_micro3.ogg b/sound/effects/explosion/micro3.ogg
similarity index 100%
rename from sound/effects/explosion_micro3.ogg
rename to sound/effects/explosion/micro3.ogg
diff --git a/sound/effects/explosion_small1.ogg b/sound/effects/explosion/small1.ogg
similarity index 100%
rename from sound/effects/explosion_small1.ogg
rename to sound/effects/explosion/small1.ogg
diff --git a/sound/effects/explosion_small2.ogg b/sound/effects/explosion/small2.ogg
similarity index 100%
rename from sound/effects/explosion_small2.ogg
rename to sound/effects/explosion/small2.ogg
diff --git a/sound/effects/explosion_small3.ogg b/sound/effects/explosion/small3.ogg
similarity index 100%
rename from sound/effects/explosion_small3.ogg
rename to sound/effects/explosion/small3.ogg
diff --git a/sound/effects/explosion_small4.ogg b/sound/effects/explosion/small4.ogg
similarity index 100%
rename from sound/effects/explosion_small4.ogg
rename to sound/effects/explosion/small4.ogg
diff --git a/sound/effects/explosionsmallfar.ogg b/sound/effects/explosion/small_far0.ogg
similarity index 100%
rename from sound/effects/explosionsmallfar.ogg
rename to sound/effects/explosion/small_far0.ogg
diff --git a/sound/effects/explosion_smallfar1.ogg b/sound/effects/explosion/small_far1.ogg
similarity index 100%
rename from sound/effects/explosion_smallfar1.ogg
rename to sound/effects/explosion/small_far1.ogg
diff --git a/sound/effects/explosion_smallfar2.ogg b/sound/effects/explosion/small_far2.ogg
similarity index 100%
rename from sound/effects/explosion_smallfar2.ogg
rename to sound/effects/explosion/small_far2.ogg
diff --git a/sound/effects/explosion_smallfar3.ogg b/sound/effects/explosion/small_far3.ogg
similarity index 100%
rename from sound/effects/explosion_smallfar3.ogg
rename to sound/effects/explosion/small_far3.ogg
diff --git a/sound/effects/explosion_smallfar4.ogg b/sound/effects/explosion/small_far4.ogg
similarity index 100%
rename from sound/effects/explosion_smallfar4.ogg
rename to sound/effects/explosion/small_far4.ogg
diff --git a/sound/effects/alien_footstep_charge1.ogg b/sound/effects/footstep/alien/charge1.ogg
similarity index 100%
rename from sound/effects/alien_footstep_charge1.ogg
rename to sound/effects/footstep/alien/charge1.ogg
diff --git a/sound/effects/alien_footstep_charge2.ogg b/sound/effects/footstep/alien/charge2.ogg
similarity index 100%
rename from sound/effects/alien_footstep_charge2.ogg
rename to sound/effects/footstep/alien/charge2.ogg
diff --git a/sound/effects/alien_footstep_charge3.ogg b/sound/effects/footstep/alien/charge3.ogg
similarity index 100%
rename from sound/effects/alien_footstep_charge3.ogg
rename to sound/effects/footstep/alien/charge3.ogg
diff --git a/sound/effects/alien_footstep_large1.ogg b/sound/effects/footstep/alien/large1.ogg
similarity index 100%
rename from sound/effects/alien_footstep_large1.ogg
rename to sound/effects/footstep/alien/large1.ogg
diff --git a/sound/effects/alien_footstep_large2.ogg b/sound/effects/footstep/alien/large2.ogg
similarity index 100%
rename from sound/effects/alien_footstep_large2.ogg
rename to sound/effects/footstep/alien/large2.ogg
diff --git a/sound/effects/alien_footstep_large3.ogg b/sound/effects/footstep/alien/large3.ogg
similarity index 100%
rename from sound/effects/alien_footstep_large3.ogg
rename to sound/effects/footstep/alien/large3.ogg
diff --git a/sound/effects/alien_footstep_medium1.ogg b/sound/effects/footstep/alien/medium1.ogg
similarity index 100%
rename from sound/effects/alien_footstep_medium1.ogg
rename to sound/effects/footstep/alien/medium1.ogg
diff --git a/sound/effects/alien_footstep_medium2.ogg b/sound/effects/footstep/alien/medium2.ogg
similarity index 100%
rename from sound/effects/alien_footstep_medium2.ogg
rename to sound/effects/footstep/alien/medium2.ogg
diff --git a/sound/effects/alien_footstep_medium3.ogg b/sound/effects/footstep/alien/medium3.ogg
similarity index 100%
rename from sound/effects/alien_footstep_medium3.ogg
rename to sound/effects/footstep/alien/medium3.ogg
diff --git a/sound/effects/alien_resin_move1.ogg b/sound/effects/footstep/alien/resin_move1.ogg
similarity index 100%
rename from sound/effects/alien_resin_move1.ogg
rename to sound/effects/footstep/alien/resin_move1.ogg
diff --git a/sound/effects/alien_resin_move2.ogg b/sound/effects/footstep/alien/resin_move2.ogg
similarity index 100%
rename from sound/effects/alien_resin_move2.ogg
rename to sound/effects/footstep/alien/resin_move2.ogg
diff --git a/sound/effects/footstep/alien_footstep_large1.ogg b/sound/effects/footstep/alien_footstep_large1.ogg
deleted file mode 100644
index 5292006352003af40443998978986361f6a9f0e7..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 7555
zcmcgRc|4Tezh^8NiYB3Q<#RvxbN{;MbDlHb=X{s*-Ol-*hy6i8&OikGdqeul
zjtfD1=WG;A8Fn}_#-Gj*PQX;%gg*d?r~m$~gzXn{{;LT&VbGfaqO3!v^4EWAt)joh
zNJH3teuobk?AmUyb2~vtM;w~i3O#`lw8((K7*hyIgOEG*AtV7EM)&{CC-*Os03ZJ&
zrj9X@XqU*yFop^=9~narqDT0}M#lKW1Re^EfkXwGhSU7@X@=%{E>X^*>mi~5zt})i
zT^$`mZ5>^0U7|cR6-y5f{7)RZL<6GUPMG-b1yxBFZZKd50Fs2z5a-ddj5_31G8IdU
zNnQB%Eu=n`GK|F;qc($fB+aHVAf42CvM<{e2pKpicgGkz?P)fn4C&qzJ%fgzDRfXz
zv?LaSvWU~nm@L9?tV|4ENOw}sCO!HJ5`s7=2&xc5;e-ZejDQG1Z_%eIG1m=*SY(h)
z%vzz8Hle&(q2x@1hJoL7tHi5ArcnGU6hW9)U|bhUfnHI+=g|5A@*o?4;u2i?Bu)mQ
zR3`;G06>^U%h_Cz+gpq3eu9yPOCNwD0|Rh~&Nhu>o6hyfIz%s0J6eh>DAl-HNAIfB
z>aLq@+P=ze3xK1OTx*n^#429^0B~PidYNI?8xJP;K#@dB+BFf71b`Ssx6YFN+2MoWcblMgIu_Tt!LIqL3o%C8a<@ZLruv5?EAnlPB=0SlUzPYvyp3
zV+*EBly4M9^FkFFy#82F211nCw#vAYrCSak(t
zV+%S3L4s(Y0ncGkZ1Ls!{^|I36r+dGj!s^uJ5!wFVARQBIv90f%Cab-c)pzTzS=1T
z8jnB3W>lNwX_kPRuABDX3u29k&RZ5D(SZa9<`1!EI~v0-95
znOb%^CfzrL-G0E*Ufy-kHGKG6xX-unmxF;XzXd)U3_O?@_<|pPaOmK{;kf_WS4~e6
z14&tLAg@E+Hj85`wHlmk7(jreGQ;%Owop8>um_lG^t_-Wc~_1URGd{_C4mA1c@1hw
zrK@4X9LOuD7hMqsyQ(U^yt1k)q@bMszju)mm8$?q0X
z;e@h^(Q0Sv?}cpax9t7u<+L--***N9AV4I-*3K}2dMD%x2*@$9>({scKX##GMF5n1
zh@5P)L#?|tz72EJTZ1E)Gmu!3@4wGzu9CC{FVT3KtimnsAJ^q(Q`RM3$tQIn-0HEgmhp&b)IQJrS99LQ>1jvKXylaf!)xWI5A
zt7CI0)U}m?OmZl;915uj3VO6sAYH_O698ujws?*lg-p1TZ$ZYlvuL*XDRztlu{}Q)
zp)rk&l_7IjF@i>&3Sfgf<(npsC#*X1=OnsIZvr{URyRb
zL%4VbA&5fNs%-V3rW0E885!EcebnpF8qOKSc4{)S_M12Ls!&uq4-%!bv%Sce+?Y3X
zbUSa+o3WiV^gJV2dwL*by+&IRLvVlOc`|}G#SZyk+B%XrPeeXreB=#Hcs{o3U?=xA
zelJhdu^t>t?%~5PG7v^Hs<9tC6IdbJc~f50S<@kgOC)9a-+qiQ^^Kj9nnq~4@K=FjiTGmNs*;$U~kHj
z>6NUfR2-L|N6p0Z6)f3N&pg8N!RKz048kLV+D0Cj@DFx4k5+DrU>f)KfPZPTOksBq1z=vK5!)FM1MTlb>
zI?*V?HHhlmrVh)oM%H_!Ez2!jJ*M%;lKq_S!=!L)IWbYlITs7Em(?5CV^HW0J#otp%Q8#D8C$98x=&M+>ceJ3u*y=R=6b
zHkR{w{x>$18GIKZ!oxEXIy8-;B!eu+w&qhaYN52mVe3~HM?xI+3bgelH$5Ox99bH)
z8qzbXl23&YxUhQO|q4ITVsC^bm7c!mRstQ{yYx2@zmlF7VQ1+rZwUtui(xG1P})tEc`
zM<=ZwCaW8mOjuJwu*OfL_1kc*!eFq@>EcL!%Vr?Rk}50;nXHmRfkZ(Y
zRz$dgH|t{+Bp`*Xek(*{>j_k(3b_Ibrm}3vDHO+5+M8L}=9W0y*sqir-nffJK36%E
z724f6I8L`WZ9qW^8AA#g*C3>%4@iPH&_NDqkk1e(rXq#4d>tiISlZK}au3-iL_nnm
zLO{vLgvxyif;=PC56_K-5G5>%(KH&;4_^qWi|4YSiYz5OtHR_)*}j;HzU*9JrVOR{
zI+DPS&hzUb!nFrSblOlXmVXAcD<~O_);;F7__ktW9G;I1`&gL5qGk{!awr)F)8omI
zD+`hZrh{(6Bb4ob4Vq&>8z%lf418#@zVKMm`qaOSfD4@`P~;*RJ;douN+tpFU^<}<
zx}=!5B54AmgbEEppi{Di2n1<{4IPVcl~^Gn1z|K@3>gcDj1X4r|H%kLsEVxC^8fz<
zQWc8Je;w38N5cbH%dh)wif&ASluhzlVK7rf0gy7sas8oKV4;fzzAy)h)P-aU`5m-h
z$&%0kLWZvnTUZnl6fP)m{|rX|KwU&UH%ExD6xiW~35e$k1N;x&KhVD}H~))6M8K`h
zD1ep?WBXy>U5nDcwVDsm#jaS6kwu2%S=p3|{L(BE9?zkWr8dw6cJEP8DS}R?E+U-E
zVUaXc;soXr*wk!_q)Kj<(F~5|NYTKuo)U4~6ge^(pPNmxt&C++aM)ZSaV~{yi_Jxl
zr3yJNWT{Gy3k6;nn@v*3a+uI-4h!PtvdCm?EQO?j=R!NTl7%4K;<*k`&Ev?Ca4M;g
zxmYd}+H<)sBuPjE3a$i_0@=)@-~pIeJ*nYFofUQP&GxrG0y(8RSpeNc%viBQ^ec9%
zaDvrEb!mJXn$OXCh;U|}{Uk@rB;u?sWC(9q$W3H;NwU9*TCPQxqf=wU08zYEfp%=6
zb`x|hfQtaJ6fuBApt0Tdz`N!hc`35a1&WWIKWl8=myIdU*K;1cyb%CLBwGWD6S{90LHO
zYG!Gv&yZKxgj7`8jM}2S6|DlP@Vl9rnXLk7Xf!ih{S*@e`&Xxc@Ka29!CZRp(5mU;
zxIc_e^AF$e5*|ViJQM_dF9ih!1_lTC1^5U0`B8m*-0kcf_L*7lQP$d(b9Qa9*CIML
zrgM7m`)JCAXYJdIYJ5*o>I7wRyDuMi`0JA4()i;`-m|XecI}Snod7ip?hw8AKda27Pi;^ejPUI)b3605#IOyP|J#5F)>Noq<5Yf
zow1{Ovtn?FVBvg-Mc@13J-=>_IlDW4`J=mjCHjs1m#(u%CXauJzOoariyeC@5+3P4
zpE(4vtvop4n_IB+Q!8^v%zx=LHT5a&&-(hV^s7wVlJzvp>j`GRqFiEsRX<|pv6cUM
zWux;t4US4uStQKM)KvG7ogHtdGZZ9tV7u5y(|D50$3AEQkYEpBV@5C+n}OgJ(Oe_t~8P+N-a%kqRj!$kL)CZdy&UCZ^WeXm8iytKjF(|I~Px>FTit9b!X!QFNGXc!pbH%J0kPuY!JO_|6m
zuoDNJ&=jPJ@qUkGBpttEbG35
zKQKT3{m{{odc2@(ywy6e=5E}bd`0Bv^N13kx8aAXCqWTglL)}bC|#_o9zVJ~_Ve!7
zpmPJk)|!1JJ^7A~+vu5uHDStn8miJ>Og-0%SiNU626@VMM~xWc+#-`^%C8
z@=Li5^KauYmEms&noBWu&zwfYla+jdk`mpQEsbI^IwEP=U
z`9{GrkJlZ%{YB#JZQMJA*xVq~*BtD8{w&}vxFI$?)G{P?Q<_MK%bGuaLyf;ngHSkK
zJiJmTIcZig^O*oDYvPv+D(>vq{1_9Kma!=J%=pB0vRB_T*I)T#L
za`T|Pv@X)(hj6}~X`s95C97Vj9=msT;F{=`%w7Ae{!WktF4K1x8Um3`wYcQ6nsk4I
zghSt5Ome&5Zx^|Hv)o-!@^JFip4sjUMiF})xo-rec3IX}ET`E8(MY-#)UG
zzfwxpWD>(#?ytm&0hZvfa!UHgcn040v{BvdzSyQGUW{X(^%_gU&WgNSbE%TlGgzH?
za2;PKjD5aIOrUWqQ!jNaFJdS1NP+mPLF&hfXw%HC9kp
zFip+7h(8B4OL3?YjSd4Y1I@=9%pL1q=VP2A#dho&`7uL@XzILV^ftRTsAK45^pe1l
zQHLKDWZIxagQmI+uO7^JT4-=lqHJ8iv)Hk?sr#<>rDtO`_4B2%;KZf1R8at5IJ)
zIB->0d$uK5`tQXzc8aO{ngfn$--y?1ea+H;f5AfWtxH_n_ItU0-l>YM3Q9@^HH&nG
zqj@==DN(U2)Y0z5#@&3&p%UCybzQA}L^7vR@uBrucDkI~;UkJINyZnz?%R7gZa@h+
zXS3ue229w*(d9h_n%6yTGM`gzV_+wD1?0DSZgUjdI(g)~XMe!)ZAWWA@5~+TJe+sA
zsAOGXY>%^4A$4s7aWs3)*x2d68)D&ev!51v`>Z$hUY(X#jB7J*;Ktf-Pyov8&1HO8
zIyqsu=>V+w0NMX&)2-!RbCayug2}}puLlp@lQK&_-ES^aj;#GOrjmZ{heN!3B#cSF
zBKFsz!pU%rE1MjHpR~R_n&SOQ?b60Vu{@mm=Y@y6uU|PYW6i1UYDD7(+`
zo7FQytfJ;sT$OJ&rRSf|Emu^iw#=dUD676Eigxo$yTn-!4`$T1|+P|`-z*S2R5Hc;Isq4_ltM3%|s1&jfcc$;1KGe8z|Eo|hL^(Ss
z$fA9&fkSIGi*{}fv;VfJ&C@SM9BYZ0>B*R+Kjs)D_m`%*%pJa$rVw2WD;nGAf(O#2
ziPK>Y0H>=)7sN~QPv5NcyjQ7BHyplr
zpjC6B$~42;(#)#%kyvDY!!{K*$v$#yN44c+P1j~^1NRhBDz=+0nyCd&tZZ(+0+TyC
z@i$5iIL7(cEk+Jr7&bSo^}8-POL|KB!bB8#=E9eIUQ1p+B!PK8@z_vvdzSx6?5)~)
zW3wHa%PY7*?c)a)JOlc-4a@18Z#ebHL*Mg#QeVNuANJ);`LIuMJA1f=BH-_;**XG9
zC;9JRu>&q7Sw??SM%ipOPSb1BRcm+d5`3;?>CDchkyz_3`F$ag6(%QUuUEa?K05yA
z&?cuR4f}kaMSIVA-<#^(HuYqm<^Zm8X{Mz|@T{kww@GbasK8=H%dt}(z?83UzB35Y
zEn|mI+=LZ}?5%s@{H}ZEk!zHTI@9!$p4}Ynz=)3PNN`B%j|2B@uTNuh41<$-=XA1P
z#oHLHm7Ubs|IoiPu3*Kx?e50AjA7+vOz)&P%Laq+flC?d4M}q4=W3pmita98IPC@K
zrW-3_CX&;vsMGJR{^7F@C;2EdS#pRZs%wXMA=hJRk6oPHx8t2f#AnSbfhOR5Ue%X0#;uiwFW>PtD#j{4zJ
z2s3rueYE_I5?AWNgCt9r%c-Q!KZ0^~%8a&3sNTz4e3V^daOQcT%!#JiYvSlW$pzyA
zF~F?HT%G!L@_voB)&$%x&2Re+haIw`+Ex;=@OwiI4<;y<=fk~U`b{@Vk4PPh4Q581
zZC~$2+L>k0ZTsX#-Vw2(ukH?V;vO%6&a`WK$kQ616V(Ib*>j~+Kzw)l=F*L3;MHI1
zLQ@F4oV>4wL`FxMFoe!&nHbu7QmalnJ1A{zVQWJ)TJ;d
zefdimMZ~C{
zQkimlZ7A|Eo=w?j(0;xbyL5s0j(%w?jcex$AV=MQ4f1PljGkzz4_CJfJEix)maVx_
z%4BYTb>aFXo!ZQ%LEZ9u73svd-LZ0gTEz#|+bE@?_Iq`2OD5=@t{0pk;bU$+Psa{Z
zTMMUfC$5b&Z(1nU%-Y`lbXh07Xp3Z#D^+xJKKo_iGqEv9|9Y^Q&O
z_q3)3FX~@wKIB#IayfBq@N{ASS^WUD_T5s(=jipvt7h~fBttz5zC_TQH_Nh
zuBsK3zr*@#=bRRafA-+=?3C^v6uIj=q^+&na$9~N;<{inD$8Ni>u%ny!k#S?_!os?
zKde5DeCkn0t7}%YrQob!-c4hBmq4(_tHKweVd|ZSeSSUvFlZ}YtKS#3a^h)KR%%;a
zrv6>rp-9)%V`Bm0XX^21WcJh_&vPpcuQ!aW)S4ezxK?AA_Ca6tWUdd2(PzD}Mboug
zqg{Nt&is|xtO-!=8uPmhOA;}@ErG$D#s4*Ze4U(?Yo>;A4+#5-bAGVp99wGc(ov-w
zX@3cB+D#X_R`ctAV%iQpv~c+rEu)%nMXX_AhT(#dDUhwVx@U8{zVTS4Vd}JrGx$50
z8oCRZB@7>359E^V_C@Y!ewpxojoQgrRlemeUH{&bq!$vphtD+R+6xSC5*SCXdsWA3
zk{a5^R6_8+y#ux4qOr4OaR)s|Tz+m8blHt9CG4lcb%x>(*E^M2z?ALA7}LO4{_tVh
znkf`xd1=zqqSyQQVp)G>#cfu@NpBsehUgGBWvSonhnm^r#gMzVhwjvFXZdS7=S5HJ
zrFXhvCp@f0sTR4lM?wOd_y(_r$`i_nyBWuy#7X(VcH^7+$EAU<&mLIP4XoWB?;Q&o
zlrtUn?n+_Xce(m)a6V8H@ti@=Ols*J;q4Ol66MDD;AXw$hMG0ax_U42#q5j10kd_v
z6XZ(ln5PY^0sF-E*ZCakh}2s%cXV!%1nYBHwDMfBsE0V%{q6?|`a6#CpGi5EX6xfm
z9GcvBwxd?xo92>i7ZnfSTgMIgH&h<5<(pc~|-3juJPmJ8?2rhYe*%4{mKhCU+*@$wh`s
z+?kbUd$afvm)eh>7B`)6oZloK1!nJ$#>y!4JUcqP(6(e_>2qa!nud@LH?7rb6N8>|&a
z1sjD6;J|z2$EiKQaHLVjP#wYi6-v`k#r6OI
diff --git a/sound/effects/footstep/alien_footstep_large2.ogg b/sound/effects/footstep/alien_footstep_large2.ogg
deleted file mode 100644
index c5ff7040a26a0a5c2180eae0ae231101e4b48657..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 7379
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
F{{Voagtq_y
diff --git a/sound/effects/footstep/alien_footstep_large3.ogg b/sound/effects/footstep/alien_footstep_large3.ogg
deleted file mode 100644
index d5a6d280dbb103c67905eb4f38d660c26250a429..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 7054
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
)FTTic~iF{wtIr71}KDJH&P{&v%DllJc2Uf#Ri
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
I6@T0P7d{RB)c^nh
diff --git a/sound/effects/footstep/alien_footstep_medium1.ogg b/sound/effects/footstep/alien_footstep_medium1.ogg
deleted file mode 100644
index dd68658f8aef908a61e7e295c9af89c2e29c575f..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 25788
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