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/__DEFINES/__game.dm b/code/__DEFINES/__game.dm
index ad4fa14628f..234493baed2 100644
--- a/code/__DEFINES/__game.dm
+++ b/code/__DEFINES/__game.dm
@@ -38,7 +38,6 @@
#define INVISIBILITY_ABSTRACT 101 //only used for abstract objects (e.g. spacevine_controller), things that are not really there.
-
//Object specific defines
#define CANDLE_LUM 3 //For how bright candles are
@@ -47,24 +46,11 @@
#define SEC_LEVEL_RED 2
#define SEC_LEVEL_DELTA 3
-
-//=================================================
-#define HOSTILE_STANCE_IDLE 1
-#define HOSTILE_STANCE_ALERT 2
-#define HOSTILE_STANCE_ATTACK 3
-#define HOSTILE_STANCE_ATTACKING 4
-#define HOSTILE_STANCE_TIRED 5
-//=================================================
-
-
//=================================================
//Game mode related defines.
#define TRANSITIONEDGE 3 //Distance from edge to move to another z-level
-//Flags for zone sleeping
-#define ZONE_ACTIVE 1
-#define ZONE_SLEEPING 0
#define GET_RANDOM_FREQ rand(32000, 55000) //Frequency stuff only works with 45kbps oggs.
//ceiling types
@@ -77,7 +63,6 @@
#define CEILING_DEEP_UNDERGROUND 6
#define CEILING_DEEP_UNDERGROUND_METAL 6
-
// Default font settings
#define FONT_SIZE "5pt"
#define FONT_COLOR "#09f"
@@ -89,7 +74,6 @@
#define GAME_YEAR (text2num(time2text(world.realtime, "YYYY")) + 395)
-
#define MAX_MESSAGE_LEN 1024
#define MAX_PAPER_MESSAGE_LEN 3072
#define MAX_BOOK_MESSAGE_LEN 9216
@@ -97,13 +81,6 @@
#define MAX_BROADCAST_LEN 512
#define MAX_NAME_HYPO 3
-
-//for whether AI eyes see static, and whether it is mouse-opaque or not
-#define USE_STATIC_NONE 0
-#define USE_STATIC_TRANSPARENT 1
-#define USE_STATIC_OPAQUE 2
-
-
#define CINEMATIC_DEFAULT 1
#define CINEMATIC_SELFDESTRUCT 2
#define CINEMATIC_SELFDESTRUCT_MISS 3
diff --git a/code/__DEFINES/_radio.dm b/code/__DEFINES/_radio.dm
index 07a1a131fca..0f0c5ff1503 100644
--- a/code/__DEFINES/_radio.dm
+++ b/code/__DEFINES/_radio.dm
@@ -60,13 +60,13 @@
#define RADIO_CHANNEL_ECHO "Echo"
#define RADIO_CHANNEL_DS1 "Alamo"
#define RADIO_CHANNEL_DS2 "Normandy"
-#define RADIO_CHANNEL_YAUTJA "Yautja" //RU TGMC ADDITION
+#define RADIO_CHANNEL_YAUTJA "Yautja"
#define MIN_FREE_FREQ 1201 // -------------------------------------------------
// Frequencies are always odd numbers and range from 1201 to 1599.
//Preds
-#define YAUT_FREQ 1233 //RU TGMC ADDITION
+#define YAUT_FREQ 1233
//SOM squads
#define FREQ_COMMAND_SOM 1235
@@ -119,14 +119,11 @@
#define FREQ_CIV_GENERAL 1469
-
#define MAX_FREQ 1489 // ------------------------------------------------------
-
#define MAX_FREE_FREQ 1599 // -------------------------------------------------
-
// Transmission types.
#define TRANSMISSION_WIRE 0 // some sort of wired connection, not used
#define TRANSMISSION_RADIO 1 // electromagnetic radiation (default)
diff --git a/code/__DEFINES/actions.dm b/code/__DEFINES/actions.dm
index f7649a678ee..67157524c32 100644
--- a/code/__DEFINES/actions.dm
+++ b/code/__DEFINES/actions.dm
@@ -13,15 +13,12 @@
#define ABILITY_IGNORE_DEAD_TARGET (1 << 13) // bypass checks of a dead target
#define ABILITY_IGNORE_SELECTED_ABILITY (1 << 14) // bypass the check of the selected ability
#define ABILITY_DO_AFTER_ATTACK (1 << 15) //Let the xeno attack the object and perform the ability.
-#define ABILITY_USE_BURROWED (1 << 16) // ignore being burrowed
-#define ABILITY_USE_ROOTED (1 << 17) // ignore being currently rooted
#define ABILITY_TURF_TARGET (1 << 0) // ability targets turfs
#define ABILITY_MOB_TARGET (1 << 1) // ability targets mobs
#define ABILITY_KEYBIND_USE_ABILITY (1 << 0) // immediately activate even if selectable
-
#define ABILITY_CRASH (1<<0)
#define ABILITY_NUCLEARWAR (1<<1)
#define ABILITY_ALL_GAMEMODE (ABILITY_CRASH|ABILITY_NUCLEARWAR)
diff --git a/code/__DEFINES/area.dm b/code/__DEFINES/area.dm
index 69f79abf673..7bfd6ce6308 100644
--- a/code/__DEFINES/area.dm
+++ b/code/__DEFINES/area.dm
@@ -14,7 +14,7 @@
#define NO_DROPPOD (1<<2)
///Make this area immune to cas/ob laser. Explosions can still go through if the ob is called in a nearby area
#define OB_CAS_IMMUNE (1<<3)
-///Prevent wraith from portaling there, and hivemind to weed there when shutters are closed
+///Prevent hivemind to weed there when shutters are closed
#define MARINE_BASE (1<<4)
///radio works even underground
#define ALWAYS_RADIO (1<<5)
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/cooldowns.dm b/code/__DEFINES/cooldowns.dm
index 6633b1f43b7..561517ce170 100644
--- a/code/__DEFINES/cooldowns.dm
+++ b/code/__DEFINES/cooldowns.dm
@@ -45,7 +45,6 @@
#define COOLDOWN_GAS_BREATH "cooldown_gas_breath"
#define COOLDOWN_SIGNALLER_SEND "cooldown_signaller_send"
#define COOLDOWN_BIKE_FUEL_MESSAGE "cooldown_bikee_fuel_message"
-#define COOLDOWN_WRAITH_PORTAL_TELEPORTED "cooldown_wraith_portal_teleported"
#define COOLDOWN_ITEM_TRICK "cooldown_item_trick"
#define COOLDOWN_RAVAGER_FLAMER_ACT "cooldown_ravager_flamer_act"
#define COOLDOWN_DROPPOD_TARGETTING "cooldown_droppod_targetting"
diff --git a/code/__DEFINES/dcs/signals.dm b/code/__DEFINES/dcs/signals.dm
index 3d596d510ed..f479b311e6d 100644
--- a/code/__DEFINES/dcs/signals.dm
+++ b/code/__DEFINES/dcs/signals.dm
@@ -229,7 +229,7 @@
///from base of atom/get_mechanics_info(): (/mob)
#define COMSIG_ATOM_GET_MECHANICS_INFO "atom_mechanics_info"
#define COMPONENT_MECHANICS_CHANGE (1<<0)
-
+
///from base of [/atom/proc/update_appearance]: (updates)
#define COMSIG_ATOM_UPDATE_APPEARANCE "atom_update_appearance"
/// If returned from [COMSIG_ATOM_UPDATE_APPEARANCE] it prevents the atom from updating its name.
@@ -678,9 +678,6 @@
#define COMSIG_XENO_PROJECTILE_HIT "xeno_projectile_hit" ///from [/mob/living/carbon/xenomorph/projectile_hit] called when a projectile hits a xeno but before confirmation of a hit (can miss due to inaccuracy/evasion)
#define COMPONENT_PROJECTILE_DODGE (1<<0)
-#define COMSIG_XENOMORPH_WRAITH_RECALL "xenomorph_wraith_recall"
- #define COMPONENT_BANISH_TARGETS_EXIST (1<<0)
-
#define COMSIG_XENO_PSYCHIC_LINK_REMOVED "xeno_psychic_link_removed"
#define COMSIG_XENOMORPH_LEAP_BUMP "xenomorph_leap_bump" //from /mob/living/carbon/xenomorph/bump
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/__DEFINES/is_helpers.dm b/code/__DEFINES/is_helpers.dm
index d63ab0aef12..326ef6b9c79 100644
--- a/code/__DEFINES/is_helpers.dm
+++ b/code/__DEFINES/is_helpers.dm
@@ -111,8 +111,6 @@
#define isxenodefiler(A) (istype(A, /mob/living/carbon/xenomorph/defiler))
#define isxenobull(A) (istype(A, /mob/living/carbon/xenomorph/bull))
#define isxenohivemind(A) (istype(A, /mob/living/carbon/xenomorph/hivemind))
-#define isxenowraith(A) (istype(A, /mob/living/carbon/xenomorph/wraith))
-//#define isxenowidow(A) (istype(A, /mob/living/carbon/xenomorph/widow)) //RUTGMC DELETION, WIDOW DELETION
#define isxenowarlock(A) (istype(A, /mob/living/carbon/xenomorph/warlock))
#define isxenoking(A) (istype(A, /mob/living/carbon/xenomorph/king))
#define isxenobehemoth(A) (istype(A, /mob/living/carbon/xenomorph/behemoth))
diff --git a/code/__DEFINES/mobs.dm b/code/__DEFINES/mobs.dm
index f1fcf9ce960..9a99a003a79 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
@@ -714,36 +714,17 @@ RU TGMC EDIT */
#define SENTINEL_INTOXICATED_RESIST_REDUCTION 8 //Amount of stacks removed every time the Intoxicated debuff is Resisted against.
#define SENTINEL_INTOXICATED_SANGUINAL_INCREASE 3 //Amount of debuff stacks applied for every tick of Sanguinal.
-//Wraith defines
-
-#define WRAITH_BLINK_DRAG_NONFRIENDLY_MULTIPLIER 20 //The amount we multiply the cooldown by when we teleport while dragging a non-friendly target
-#define WRAITH_BLINK_DRAG_FRIENDLY_MULTIPLIER 4 //The amount we multiply the cooldown by when we teleport while dragging a friendly target
-#define WRAITH_BLINK_RANGE 3
-
-#define WRAITH_BANISH_BASE_DURATION 10 SECONDS
-#define WRAITH_BANISH_NONFRIENDLY_LIVING_MULTIPLIER 0.5
-#define WRAITH_BANISH_VERY_SHORT_MULTIPLIER 0.3
-
-#define WRAITH_TELEPORT_DEBUFF_STAGGER_STACKS 2 SECONDS //Stagger and slow stacks applied to adjacent living hostiles before/after a teleport
-#define WRAITH_TELEPORT_DEBUFF_SLOWDOWN_STACKS 3 //Stagger and slow stacks applied to adjacent living hostiles before/after a teleport
-
//Larva defines
#define LARVA_VENT_CRAWL_TIME 1 SECONDS //Larva can crawl into vents fast
-/* RUTGMC DELETION, WIDOW DELETION
-//Widow Defines
-#define WIDOW_SPEED_BONUS 1 // How much faster widow moves while she has wall_speedup element
-#define WIDOW_WEB_HOOK_RANGE 10 // how far the web hook can reach
-#define WIDOW_WEB_HOOK_MIN_RANGE 3 // the minimum range that the hook must travel to use the ability
-#define WIDOW_WEB_HOOK_SPEED 3 // how fast widow yeets herself when using web hook
-
-//Spiderling defines
-#define TIME_TO_DISSOLVE 5 SECONDS
-#define SPIDERLING_RAGE_RANGE 10 // how close a nearby human has to be in order to be targeted
-*/
//Praetorian defines
#define PRAE_CHARGEDISTANCE 6
+// Chimera defines
+//Stagger and slowdown stacks applied to adjacent living hostiles before/after a teleport
+#define CHIMERA_TELEPORT_DEBUFF_STAGGER_STACKS 2 SECONDS
+#define CHIMERA_TELEPORT_DEBUFF_SLOWDOWN_STACKS 3
+
//misc
#define STANDARD_SLOWDOWN_REGEN 0.3
@@ -813,8 +794,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
@@ -837,14 +816,6 @@ GLOBAL_LIST_INIT(human_body_parts, list(BODY_ZONE_HEAD,
#define IGNORE_LOC_CHANGE (IGNORE_USER_LOC_CHANGE|IGNORE_TARGET_LOC_CHANGE)
-/* RUTGMC DELETION
-#define TIER_ONE_THRESHOLD 420
-
-#define TIER_TWO_THRESHOLD 840
-
-#define TIER_THREE_THRESHOLD 1750
-*/
-
// Pheromones and buff orders
#define AURA_XENO_RECOVERY "Recovery"
@@ -888,14 +859,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/__DEFINES/obj_flags.dm b/code/__DEFINES/obj_flags.dm
index fe8f881952c..324034253df 100644
--- a/code/__DEFINES/obj_flags.dm
+++ b/code/__DEFINES/obj_flags.dm
@@ -12,10 +12,8 @@
#define XENO_DAMAGEABLE (1<<3) //xenos can damage this by slashing and spitting
#define DROPSHIP_IMMUNE (1<<4) //dropship cannot land on it
#define CRUSHER_IMMUNE (1<<5) //is immune to crusher's charge destruction
-#define BANISH_IMMUNE (1<<6) //is immune it wraith's banish ability
-#define PLASMACUTTER_IMMUNE (1<<7) //is immune to being cut by a plasmacutter
-#define PROJECTILE_IMMUNE (1<<8) //Cannot be hit by projectiles
-#define PORTAL_IMMUNE (1<<9) //Cannot be teleported by wraith's portals
+#define PLASMACUTTER_IMMUNE (1<<6) //is immune to being cut by a plasmacutter
+#define PROJECTILE_IMMUNE (1<<7) //Cannot be hit by projectiles
#define RESIST_ALL (UNACIDABLE|INDESTRUCTIBLE|PLASMACUTTER_IMMUNE)
diff --git a/code/__DEFINES/traits.dm b/code/__DEFINES/traits.dm
index ef98bccb3b4..fab56ea4f19 100644
--- a/code/__DEFINES/traits.dm
+++ b/code/__DEFINES/traits.dm
@@ -101,7 +101,6 @@
#define OPTABLE_TRAIT "optable"
#define TIMESHIFT_TRAIT "timeshift"
#define BRAIN_TRAIT "brain"
-//#define WIDOW_ABILITY_TRAIT "widow_ability_trait" //RUTGMC DELETION, WIDOW DELETION
#define PSYCHIC_BLAST_ABILITY_TRAIT "psychic_blast_ability_trait"
#define PSYCHIC_CRUSH_ABILITY_TRAIT "psychic_crush_ability_trait"
#define VORTEX_ABILITY_TRAIT "vortex_ability_trait"
@@ -183,7 +182,6 @@
#define TRAIT_LEGLESS "legless" //Has lost all the appendages needed to stay standing up.
#define TRAIT_NOPLASMAREGEN "noplasmaregen"//xeno plasma wont recharge
#define TRAIT_UNDEFIBBABLE "undefibbable"//human can't be revived
-// #define TRAIT_HOLLOW "hollowedout" //examine trait for puppeteer
#define TRAIT_IMMEDIATE_DEFIB "immediate_defib"//immediately revives when defibbed, rather than just healing
#define TRAIT_HEALING_INFUSION "healing_infusion"//greatly improves natural healing for xenos
#define TRAIT_PSY_DRAINED "psy_drained"//mob was drained of life force by a xenos
diff --git a/code/__DEFINES/xeno.dm b/code/__DEFINES/xeno.dm
index 90c3b297c7c..43f5af92c85 100644
--- a/code/__DEFINES/xeno.dm
+++ b/code/__DEFINES/xeno.dm
@@ -55,12 +55,7 @@
#define WEAK_ACID_STRENGTH 0.016
#define REGULAR_ACID_STRENGTH 0.04
#define STRONG_ACID_STRENGTH 0.1
-/* RU TGMC EDIT
-#define PUPPET_RECALL "recall puppet"
-#define PUPPET_SEEK_CLOSEST "seeking closest and attack order" //not xeno-usable
-#define PUPPET_ATTACK "seek and attack order"
-#define PUPPET_SCOUT "scouting order"
-RU TGMC EDIT*/
+
//List of weed types
GLOBAL_LIST_INIT(weed_type_list, typecacheof(list(
/obj/alien/weeds/node,
@@ -134,24 +129,6 @@ GLOBAL_LIST_INIT(resin_images_list, list(
ALIEN_NEST = image('icons/Xeno/actions.dmi', icon_state = ALIEN_NEST)
))
-/* RU TGMC EDIT PUPPETEER REMOVAL
-//List of puppeteer order images
-GLOBAL_LIST_INIT(puppeteer_order_images_list, list(
- PUPPET_ATTACK = image('icons/Xeno/actions.dmi', icon_state = "enrage"),
- PUPPET_SCOUT = image('icons/mob/actions.dmi', icon_state = "66"),
- PUPPET_RECALL = image('icons/mob/actions.dmi', icon_state = "rally")
- ))
-RU TGMC EDIT PUPPETEER REMOVAL*/
-//RUTGMC EDIT BEGIN - Moved to modular_RUtgmc\code\__DEFINES\xeno.dm
-/*
-//List of puppeteer pheromone images
-GLOBAL_LIST_INIT(puppeteer_phero_images_list, list(
- AURA_XENO_BLESSFURY = image('icons/mob/actions.dmi', icon_state = "Fury"),
- AURA_XENO_BLESSWARDING = image('icons/mob/actions.dmi', icon_state = "Warding"),
- AURA_XENO_BLESSFRENZY = image('icons/mob/actions.dmi', icon_state = "Frenzy"),
- ))
-*/ //RUTGMC EDIT END
-
GLOBAL_LIST_INIT(panther_toxin_type_list, list(
/datum/reagent/toxin/xeno_hemodile,
/datum/reagent/toxin/xeno_transvitox,
@@ -215,6 +192,4 @@ GLOBAL_LIST_INIT(xeno_ai_spawnable, list(
/// Failed to other blockers such as egg, power plant , coocon , traps
#define ERROR_CONSTRUCT 8
-#define PUPPET_WITHER_RANGE 15
-
#define PRIMAL_WRATH_GAIN_MULTIPLIER 0.5
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/_globalvars/bitfields.dm b/code/_globalvars/bitfields.dm
index 83513a29487..b7f5d52513d 100644
--- a/code/_globalvars/bitfields.dm
+++ b/code/_globalvars/bitfields.dm
@@ -551,10 +551,8 @@ GLOBAL_LIST_INIT(bitfields, list(
"XENO_DAMAGEABLE" = XENO_DAMAGEABLE,
"DROPSHIP_IMMUNE" = DROPSHIP_IMMUNE,
"CRUSHER_IMMUNE" = CRUSHER_IMMUNE,
- "BANISH_IMMUNE" = BANISH_IMMUNE,
"PLASMACUTTER_IMMUNE" = PLASMACUTTER_IMMUNE,
"PROJECTILE_IMMUNE" = PROJECTILE_IMMUNE,
- "PORTAL_IMMUNE" = PORTAL_IMMUNE
),
"restrained_flags" = list(
"RESTRAINED_XENO_NEST" = RESTRAINED_XENO_NEST,
@@ -601,8 +599,6 @@ GLOBAL_LIST_INIT(bitfields, list(
"ABILITY_IGNORE_DEAD_TARGET" = ABILITY_IGNORE_DEAD_TARGET,
"ABILITY_IGNORE_SELECTED_ABILITY" = ABILITY_IGNORE_SELECTED_ABILITY,
"ABILITY_DO_AFTER_ATTACK" = ABILITY_DO_AFTER_ATTACK,
- "ABILITY_USE_BURROWED" = ABILITY_USE_BURROWED,
- "ABILITY_USE_ROOTED" = ABILITY_USE_ROOTED
),
"pipe_flags" = list(
"PIPING_ALL_LAYER" = PIPING_ALL_LAYER,
diff --git a/code/datums/actions/ability_actions.dm b/code/datums/actions/ability_actions.dm
index fb5e2129d37..202cbc67f0f 100644
--- a/code/datums/actions/ability_actions.dm
+++ b/code/datums/actions/ability_actions.dm
@@ -90,11 +90,6 @@
carbon_owner.balloon_alert(carbon_owner, "Cannot, busy")
return FALSE
- if(!(flags_to_check & ABILITY_USE_BURROWED) && HAS_TRAIT(carbon_owner, TRAIT_BURROWED))
- if(!silent)
- carbon_owner.balloon_alert(carbon_owner, "Cannot while burrowed")
- return FALSE
-
if(!(flags_to_check & ABILITY_USE_CLOSEDTURF) && isclosedturf(get_turf(carbon_owner)))
if(!silent)
//Not converted to balloon alert as xeno.dm's balloon alert is simultaneously called and will overlap.
diff --git a/code/datums/actions/xeno_action.dm b/code/datums/actions/xeno_action.dm
index 0b1aa86c113..775a5249af5 100644
--- a/code/datums/actions/xeno_action.dm
+++ b/code/datums/actions/xeno_action.dm
@@ -37,11 +37,6 @@
X.balloon_alert(X, "Cannot while in crest defense")
return FALSE
- if(!(flags_to_check & ABILITY_USE_ROOTED) && HAS_TRAIT_FROM(X, TRAIT_IMMOBILE, BOILER_ROOTED_TRAIT))
- if(!silent)
- X.balloon_alert(X, "Cannot while rooted")
- return FALSE
-
if(!(flags_to_check & ABILITY_IGNORE_PLASMA) && X.plasma_stored < ability_cost)
if(!silent)
X.balloon_alert(X, "Need [ability_cost - X.plasma_stored] more plasma")
@@ -83,11 +78,6 @@
X.balloon_alert(X, "Cannot while in crest defense")
return FALSE
- if(!(flags_to_check & ABILITY_USE_ROOTED) && HAS_TRAIT_FROM(X, TRAIT_IMMOBILE, BOILER_ROOTED_TRAIT))
- if(!silent)
- X.balloon_alert(X, "Cannot while rooted")
- return FALSE
-
if(!(flags_to_check & ABILITY_IGNORE_PLASMA) && X.plasma_stored < ability_cost)
if(!silent)
X.balloon_alert(X, "Need [ability_cost - X.plasma_stored] more plasma")
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/riding/riding_mob.dm b/code/datums/components/riding/riding_mob.dm
index c6b718be36c..ad2710fa57e 100644
--- a/code/datums/components/riding/riding_mob.dm
+++ b/code/datums/components/riding/riding_mob.dm
@@ -276,78 +276,3 @@
. = riding_offsets["[mob_type]"]
else if(riding_offsets["[RIDING_OFFSET_ALL]"])
. = riding_offsets["[RIDING_OFFSET_ALL]"]
-
-/* RUTGMC DELETION, WIDOW DELETION
-// ***************************************
-// *********** Widow
-// ***************************************
-/datum/component/riding/creature/widow
- can_be_driven = FALSE
-
-/datum/component/riding/creature/widow/handle_specials()
- . = ..()
- var/mob/living/widow = parent
- if(widow.stat == UNCONSCIOUS) //For spiderling guard
- set_riding_offsets(1, list(TEXT_NORTH = list(0, 0), TEXT_SOUTH = list(0, 0), TEXT_EAST = list(0, 0), TEXT_WEST = list(0, 0)))
- set_riding_offsets(2, list(TEXT_NORTH = list(16, 16), TEXT_SOUTH = list(16, 16), TEXT_EAST = list(16, 16), TEXT_WEST = list(16, 16)))
- set_riding_offsets(3, list(TEXT_NORTH = list(-16, 16), TEXT_SOUTH = list(-16, 16), TEXT_EAST = list(-16, 16), TEXT_WEST = list(-16, 16)))
- set_riding_offsets(4, list(TEXT_NORTH = list(16, 32), TEXT_SOUTH = list(16, -16), TEXT_EAST = list(16, -16), TEXT_WEST = list(16, -16)))
- set_riding_offsets(5, list(TEXT_NORTH = list(0, -16), TEXT_SOUTH = list(-16, -16), TEXT_EAST = list(-16, -16), TEXT_WEST = list(-16, -16)))
- set_vehicle_dir_layer(SOUTH, ABOVE_ALL_MOB_LAYER)
- set_vehicle_dir_layer(NORTH, ABOVE_ALL_MOB_LAYER)
- set_vehicle_dir_layer(EAST, ABOVE_ALL_MOB_LAYER)
- set_vehicle_dir_layer(WEST, ABOVE_ALL_MOB_LAYER)
- return
- set_riding_offsets(1, list(TEXT_NORTH = list(-16, 9), TEXT_SOUTH = list(-16, 17), TEXT_EAST = list(-21, 7), TEXT_WEST = list(-6, 7)))
- set_riding_offsets(2, list(TEXT_NORTH = list(16, 16), TEXT_SOUTH = list(16, 17), TEXT_EAST = list(21, 7), TEXT_WEST = list(6, 7)))
- set_riding_offsets(3, list(TEXT_NORTH = list(8, 8), TEXT_SOUTH = list(-8, 21), TEXT_EAST = list(14, 11), TEXT_WEST = list(0, 2)))
- set_riding_offsets(4, list(TEXT_NORTH = list(-8, 16), TEXT_SOUTH = list(-16, 13), TEXT_EAST = list(-21, 2), TEXT_WEST = list(6, 11)))
- set_riding_offsets(5, list(TEXT_NORTH = list(8, 8), TEXT_SOUTH = list(8, 12), TEXT_EAST = list(21, 2), TEXT_WEST = list(-6, 11)))
- set_vehicle_dir_layer(SOUTH, ABOVE_MOB_LAYER)
- set_vehicle_dir_layer(NORTH, ABOVE_LYING_MOB_LAYER)
- set_vehicle_dir_layer(EAST, ABOVE_LYING_MOB_LAYER)
- set_vehicle_dir_layer(WEST, ABOVE_LYING_MOB_LAYER)
-
-/datum/component/riding/creature/widow/Initialize(mob/living/riding_mob, force = FALSE, check_loc, lying_buckle, hands_needed, target_hands_needed, silent)
- . = ..()
- riding_mob.density = FALSE
-
-// If we call parent here , we get registered for COMSIG_MOVABLE_BUMP, and when we do bump, there will be a bad index runtime
-/datum/component/riding/creature/widow/RegisterWithParent()
- RegisterSignal(parent, COMSIG_ATOM_DIR_CHANGE, PROC_REF(vehicle_turned))
- RegisterSignal(parent, COMSIG_MOVABLE_UNBUCKLE, PROC_REF(vehicle_mob_unbuckle))
- RegisterSignal(parent, COMSIG_MOVABLE_MOVED, PROC_REF(vehicle_moved))
- RegisterSignals(parent, list(COMSIG_XENOMORPH_ATTACK_LIVING, COMSIG_XENOMORPH_ATTACK_OBJ, COMSIG_XENOMORPH_ATTACK_HOSTILE_XENOMORPH), PROC_REF(check_widow_attack))
-
-/datum/component/riding/creature/widow/vehicle_mob_unbuckle(datum/source, mob/living/former_rider, force = FALSE)
- unequip_buckle_inhands(parent)
- former_rider.density = initial(former_rider.density)
- REMOVE_TRAIT(former_rider, TRAIT_IMMOBILE, WIDOW_ABILITY_TRAIT)
- return ..()
-
-/// If the widow gets knocked over, force the riding rounys off and see if someone got hurt
-/datum/component/riding/creature/widow/proc/check_widow_attack(mob/living/carbon/xenomorph/widow/carrying_widow)
- SIGNAL_HANDLER
- for(var/mob/living/rider AS in carrying_widow.buckled_mobs)
- carrying_widow.unbuckle_mob(rider)
- REMOVE_TRAIT(rider, TRAIT_IMMOBILE, WIDOW_ABILITY_TRAIT)
-
-// Spiderlings latch on to crit widows when guarding and cannot be kicked off..
-/datum/component/riding/creature/widow/ride_check(mob/living/rider)
- var/mob/living/widow = parent
- return widow.stat == UNCONSCIOUS
-
-//..nor can they be laid under widow..
-/datum/component/riding/creature/widow/handle_vehicle_layer(dir)
- var/mob/living/widow = parent
- if(widow.stat == UNCONSCIOUS)
- return
- return ..()
-
-//..and nor will they change direction.
-/datum/component/riding/creature/widow/handle_vehicle_offsets(dir)
- var/mob/living/widow = parent
- if(widow.stat == UNCONSCIOUS)
- dir = SOUTH
- return ..()
-*/
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/gamemodes/crash.dm b/code/datums/gamemodes/crash.dm
index 98b9ec0021b..a477016b622 100644
--- a/code/datums/gamemodes/crash.dm
+++ b/code/datums/gamemodes/crash.dm
@@ -115,11 +115,6 @@
if(isxenolarva(i)) // Larva
var/mob/living/carbon/xenomorph/larva/X = i
X.evolution_stored = X.xeno_caste.evolution_threshold //Immediate roundstart evo for larva.
- /* RUTGMC DELETION
- else // Handles Shrike etc
- var/mob/living/carbon/xenomorph/X = i
- X.upgrade_stored = X.xeno_caste.upgrade_threshold
- */
/datum/game_mode/infestation/crash/announce()
to_chat(world, span_round_header("The current map is - [SSmapping.configs[GROUND_MAP].map_name]!"))
diff --git a/code/datums/keybinding/xeno.dm b/code/datums/keybinding/xeno.dm
index d6489299253..29e8bb276bf 100644
--- a/code/datums/keybinding/xeno.dm
+++ b/code/datums/keybinding/xeno.dm
@@ -948,196 +948,6 @@
keybind_signal = COMSIG_XENOABILITY_FLURRY
hotkey_keys = list("Q")
-/* RUTGMC DELETION, WIDOW DELETION
-/datum/keybinding/xeno/burrow
- name = "burrow"
- full_name = "Widow: Burrow"
- description = "Dig to the ground, making you invisible."
- keybind_signal = COMSIG_XENOABILITY_BURROW
- hotkey_keys = list("C")
-
-/datum/keybinding/xeno/web_spit
- name = "Web Spit"
- full_name = "Widow: Web Spit"
- description = "Spit web at your target. Hitting the target will impede their functions depending on their hit location."
- keybind_signal = COMSIG_XENOABILITY_WEB_SPIT
- hotkey_keys = list("Q")
-
-/datum/keybinding/xeno/leash_ball
- name = "Leash Ball"
- full_name = "Widow: Leash Ball"
- description = "Spit a huge web ball of web that snares groups of targets for a brief while."
- keybind_signal = COMSIG_XENOABILITY_LEASH_BALL
- hotkey_keys = list("E")
-
-/datum/keybinding/xeno/create_spiderling
- name = "Birth Spiderling"
- full_name = "Widow: Birth Spiderling"
- description = "Give birth to a spiderling after a short charge-up."
- keybind_signal = COMSIG_XENOABILITY_CREATE_SPIDERLING
- hotkey_keys = list("F")
-
-/datum/keybinding/xeno/create_spiderling_using_cc
- name = "Birth Spiderling using Cannibalise charges"
- full_name = "Widow: Birth Spiderling using Cannibalise charges"
- description = "Give birth to a spiderling after a short charge-up if you have any Cannibalise charges available."
- keybind_signal = COMSIG_XENOABILITY_CREATE_SPIDERLING_USING_CC
- hotkey_keys = list("H")
-
-/datum/keybinding/xeno/attach_spiderlings
- name = "Attach Spiderlings"
- full_name = "Widow: Attach Spiderlings"
- description = "Scoop up and carry your spawn with you."
- keybind_signal = COMSIG_XENOABILITY_ATTACH_SPIDERLINGS
- hotkey_keys = list("X")
-
-/datum/keybinding/xeno/cannibalise
- name = "Cannibalise Spiderling"
- full_name = "Widow: Cannibalise Spiderling"
- description = "Eat your own young and store their biomass for later."
- keybind_signal = COMSIG_XENOABILITY_CANNIBALISE_SPIDERLING
- hotkey_keys = list("G")
-
-/datum/keybinding/xeno/web_hook
- name = "Web Hook"
- full_name = "Widow: Web Hook"
- description = "Shoot a strong web and pull yourself towards whatever it hits."
- keybind_signal = COMSIG_XENOABILITY_WEB_HOOK
- hotkey_keys = list("R")
-
-/datum/keybinding/xeno/spiderling_mark
- name = "Spiderling Mark"
- full_name = "Widow: Spiderling Mark"
- description = "Signal your spawn to a target they shall attack."
- keybind_signal = COMSIG_XENOABILITY_SPIDERLING_MARK
- hotkey_keys = list("V")
-*/
-
-/* RU TGMC EDIT START
-/datum/keybinding/xeno/rewind
- name = "rewind"
- full_name = "Wraith: Time Shift"
- description = "Save the location and status of the target. When the time is up, the target location and status are restored"
- keybind_signal = COMSIG_XENOABILITY_REWIND
- hotkey_keys = list("C")
-
-/datum/keybinding/xeno/portal
- name = "portal"
- full_name = "Wraith: Portal"
- description = "Place the first portal on your location. You can travel from portal one to portal two and vice versa."
- keybind_signal =COMSIG_XENOABILITY_PORTAL
- hotkey_keys = list("E")
-
-/datum/keybinding/xeno/portal_two
- name = "portal_two"
- full_name = "Wraith: Portal two"
- description = "Place the second portal on your location. You can travel from portal one to portal two and vice versa."
- keybind_signal =COMSIG_XENOABILITY_PORTAL_ALTERNATE
- hotkey_keys = list("R")
-
-/datum/keybinding/xeno/blink
- name = "wraith_blink"
- full_name = "Wraith: Blink"
- description = "Teleport to a space a short distance away within line of sight. Can teleport mobs you're dragging with you at the cost of higher cooldown."
- keybind_signal = COMSIG_XENOABILITY_BLINK
- hotkey_keys = list("Q")
-
-/datum/keybinding/xeno/banish
- name = "banish"
- full_name = "Wraith: Banish"
- description = "Banish a creature or object a short distance away within line of sight to null space. Can target oneself and allies. Can be manually cancelled with Recall."
- keybind_signal = COMSIG_XENOABILITY_BANISH
- hotkey_keys = list("F")
-
-/datum/keybinding/xeno/recall
- name = "recall"
- full_name = "Wraith: Recall"
- description = "Recall a target from netherspace, ending Banish's effect."
- keybind_signal = COMSIG_XENOABILITY_RECALL
- hotkey_keys = list("G")
-
-/datum/keybinding/xeno/timestop
- name = "timestop"
- full_name = "Wraith: Time stop"
- description = "Freezes bullets in their course, and they will start to move again only after a certain time"
- keybind_signal = COMSIG_XENOABILITY_TIMESTOP
- hotkey_keys = list("V")
-RU TGMC EDIT END*/
-/*RU TGMC EDIT PUPPETEER REMOVAL
-/datum/keybinding/xeno/flay
- name = "Flay"
- full_name = "Puppeteer: Flay"
- description = "Takes a chunk of flesh from the victim marine through a quick swiping motion, adding 100 biomass to your biomass collection."
- keybind_signal = COMSIG_XENOABILITY_FLAY
-
-/datum/keybinding/xeno/pincushion
- name = "Pincushion"
- full_name = "Puppeteer: Pincushion"
- description = "Launch a spine from your tail. This attack will help deter any organic as well as support your puppets and teammates in direct combat."
- keybind_signal = COMSIG_XENOABILITY_PINCUSHION
-
-/datum/keybinding/xeno/dread
- name = "Dreadful Presence"
- full_name = "Puppeteer: Dreadful Presence"
- description = "Emit a menacing presence, striking fear into the organics and slowing them for a short duration."
- keybind_signal = COMSIG_XENOABILITY_DREADFULPRESENCE
-
-/datum/keybinding/xeno/refurbish_husk
- name = "Refurbish Husk"
- full_name = "Puppeteer: Refurbish Husk"
- description = "Harvest the biomass and organs of a body in order to create a meat puppet to do your bidding."
- keybind_signal = COMSIG_XENOABILITY_REFURBISHHUSK
-
-/datum/keybinding/xeno/stitch_puppet
- name = "Stitch Puppet"
- full_name = "Puppeteer: Stitch Puppet"
- description = "Uses 350 biomass to create a flesh homunculus to do your bidding, at an adjacent target location."
- keybind_signal = COMSIG_XENOABILITY_PUPPET
-
-/datum/keybinding/xeno/organic_bomb
- name = "Organic Bomb"
- full_name = "Puppeteer: Organic Bomb"
- description = "Causes one of our puppets to detonate on selection, spewing acid out of the puppet's body in all directions, gibbing the puppet."
- keybind_signal = COMSIG_XENOABILITY_ORGANICBOMB
-
-/datum/keybinding/xeno/tendrils
- name = "Tendrils"
- full_name = "Puppeteer: Tendrils"
- description = "Burrow freshly created tendrils to tangle organics in a 3x3 patch."
- keybind_signal = COMSIG_XENOABILITY_TENDRILS
-
-/datum/keybinding/xeno/send_orders_puppet_radial
- name = "Give Orders to Puppets: Radial"
- full_name = "Puppeteer: Give Orders to Puppets (Radial)"
- description = "Give orders to your puppets, altering their behaviour."
- keybind_signal = COMSIG_XENOABILITY_SENDORDERS_RADIAL
-
-/datum/keybinding/xeno/send_attack_order_puppet
- name = "Give attack order"
- full_name = "Puppeteer: Give Attack Order"
- description = "Give your puppets order to attack"
- keybind_signal = COMSIG_XENOABILITY_ATTACKORDER
-
-/datum/keybinding/xeno/send_recall_orders_puppet
- name = "Give recall order"
- full_name = "Puppeteer: Give Recall Order"
- description = "Give your puppets order to recall"
- keybind_signal = COMSIG_XENOABILITY_RECALLORDER
-
-/datum/keybinding/xeno/bestow_blessing
- name = "Bestow Blessings"
- full_name = "Puppeteer: Bestow Blessings"
- description = "Give blessings to your puppets."
- keybind_signal = COMSIG_XENOABILITY_BESTOWBLESSINGS
-RU TGMC EDIT PUPPETEER REMOVAL*/
-/* RUTGMC DELETION
-/datum/keybinding/xeno/behemoth_roll
- name = "Roll"
- full_name = "Behemoth: Roll"
- description = "Curl up into a ball, sacrificing some offensive capabilities in exchange for greater movement speed."
- keybind_signal = COMSIG_XENOABILITY_BEHEMOTH_ROLL
-*/
-
/datum/keybinding/xeno/landslide
name = "Landslide"
full_name = "Behemoth: Landslide"
diff --git a/code/datums/round_statistics.dm b/code/datums/round_statistics.dm
index 02bb1ff416c..df7baadc0ce 100644
--- a/code/datums/round_statistics.dm
+++ b/code/datums/round_statistics.dm
@@ -76,9 +76,6 @@ GLOBAL_DATUM_INIT(round_statistics, /datum/round_statistics, new)
var/hivelord_healing_infusions = 0
var/spitter_acid_sprays = 0
var/spitter_scatter_spits = 0
- var/wraith_phase_shifts = 0
- var/wraith_blinks = 0
- var/wraith_banishes = 0
var/bull_crush_hit = 0
var/bull_gore_hit = 0
var/bull_headbutt_hit = 0
@@ -98,3 +95,4 @@ GLOBAL_DATUM_INIT(round_statistics, /datum/round_statistics, new)
var/psy_lances = 0
var/psy_shields = 0
var/psy_shield_blasts = 0
+ var/chimera_blinks = 0
diff --git a/code/datums/status_effects/xeno_buffs.dm b/code/datums/status_effects/xeno_buffs.dm
index 45ee88b8ce2..65ae6e42662 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 ..()
@@ -910,82 +910,3 @@
X.remove_filter("overbonus_vis");
qdel(src)
-
-
-/* RU TGMC EDIT
-// ***************************************
-// *********** Blessings
-// ***************************************
-/datum/status_effect/blessing
- duration = -1
- tick_interval = 5 SECONDS
- status_type = STATUS_EFFECT_REFRESH
- alert_type = null
- /// The owner of this buff.
- var/mob/living/carbon/xenomorph/buff_owner
- ///Aura strength of the puppeteer who gave this effect
- var/strength = 1
- ///weakref to the puppeteer to set strength
- var/datum/weakref/puppeteer
-
-/datum/status_effect/blessing/tick()
- var/mob/living/carbon/xenomorph/xeno = puppeteer?.resolve()
- if(!xeno)
- return
- strength = xeno.xeno_caste.aura_strength
-
-/datum/status_effect/blessing/on_creation(mob/living/new_owner, mob/living/carbon/xenomorph/caster)
- owner = new_owner
- puppeteer = WEAKREF(caster)
- strength = caster.xeno_caste.aura_strength
- return ..()
-
-/datum/status_effect/blessing/frenzy
- id = "blessing of frenzy"
-
-/datum/status_effect/blessing/frenzy/on_apply()
- buff_owner = owner
- if(!isxeno(buff_owner))
- return FALSE
- buff_owner.add_movespeed_modifier(type, TRUE, 0, NONE, TRUE, strength * -0.2)
- return TRUE
-
-/datum/status_effect/blessing/frenzy/on_remove()
- buff_owner.remove_movespeed_modifier(type)
- return ..()
-
-/datum/status_effect/blessing/fury
- id = "blessing of fury"
- ///the modifier we apply to the xenos melee damage modifier
- var/modifier
-
-/datum/status_effect/blessing/fury/on_apply()
- buff_owner = owner
- if(!isxeno(buff_owner))
- return FALSE
- modifier = strength * 0.07
- buff_owner.xeno_melee_damage_modifier += modifier
- return TRUE
-
-/datum/status_effect/blessing/fury/on_remove()
- buff_owner.xeno_melee_damage_modifier -= modifier
- return ..()
-
-/datum/status_effect/blessing/warding
- id = "blessing of warding"
- ///A holder for the exact armor modified by this status effect
- var/datum/armor/armor_modifier
-
-/datum/status_effect/blessing/warding/on_apply()
- buff_owner = owner
- if(!isxeno(buff_owner))
- return FALSE
- armor_modifier = buff_owner.soft_armor.scaleAllRatings(strength * 2.7)
- buff_owner.soft_armor = buff_owner.soft_armor.attachArmor(armor_modifier)
- return TRUE
-
-/datum/status_effect/blessing/warding/on_remove()
- buff_owner.soft_armor = buff_owner.soft_armor.detachArmor(armor_modifier)
- armor_modifier = null
- return ..()
-RU TGMC EDIT */
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/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/game/objects/effects/aliens.dm b/code/game/objects/effects/aliens.dm
index fc92346bd2e..df4993c62d6 100644
--- a/code/game/objects/effects/aliens.dm
+++ b/code/game/objects/effects/aliens.dm
@@ -218,18 +218,3 @@
visible_message(span_xenowarning("\The [acid_t]\s structure is being melted by the acid!"))
if(6)
visible_message(span_xenowarning("\The [acid_t] is barely holding up against the acid!"))
-
-/obj/effect/xenomorph/warp_shadow
- name = "warp shadow"
- desc = "A strange rift in space and time. You probably shouldn't touch this."
- icon = 'icons/Xeno/castes/wraith.dmi'
- icon_state = "Wraith Walking"
- color = COLOR_BLACK
- alpha = 128 //Translucent
- density = FALSE
- opacity = FALSE
- anchored = TRUE
-
-/obj/effect/xenomorph/warp_shadow/Initialize(mapload, target)
- . = ..()
- add_filter("wraith_warp_shadow", 4, list("type" = "blur", 5)) //Cool filter appear
diff --git a/code/game/objects/effects/temporary_visuals/miscellaneous.dm b/code/game/objects/effects/temporary_visuals/miscellaneous.dm
index 95439b0e33c..add18286b1e 100644
--- a/code/game/objects/effects/temporary_visuals/miscellaneous.dm
+++ b/code/game/objects/effects/temporary_visuals/miscellaneous.dm
@@ -225,13 +225,6 @@ GLOBAL_LIST_EMPTY(blood_particles)
layer = ABOVE_LYING_MOB_LAYER
duration = 0.5 SECONDS
-/obj/effect/temp_visual/banishment_portal
- name = "banishment portal"
- icon = 'icons/obj/objects.dmi'
- icon_state = "bhole3"
- layer = ABOVE_LYING_MOB_LAYER
- duration = WRAITH_BANISH_BASE_DURATION+1 //So we don't delete our contents early
-
/obj/effect/temp_visual/acid_splatter
name = "acid_splatter"
icon = 'icons/Xeno/Effects.dmi'
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..a7c983c80f1 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)
@@ -314,15 +314,11 @@ GLOBAL_LIST_INIT(channel_tokens, list(
SSminimaps.add_marker(wearer, marker_flags, image('icons/UI_icons/map_blips.dmi', null, "defibbable[stage]"))
return
if(wearer.assigned_squad)
- SSminimaps.add_marker(wearer, marker_flags, image('icons/UI_icons/map_blips.dmi', null, lowertext(wearer.assigned_squad.name)+"_"+wearer.job.minimap_icon))
- //почему это было в модульной папке?
- /* //Выключил ибо у нас свой набор иконок который и так не грейскейл
var/image/underlay = image('icons/UI_icons/map_blips.dmi', null, "squad_underlay")
var/image/overlay = image('icons/UI_icons/map_blips.dmi', null, wearer.job.minimap_icon)
overlay.color = wearer.assigned_squad.color
underlay.overlays += overlay
SSminimaps.add_marker(wearer, marker_flags, underlay)
- */
return
SSminimaps.add_marker(wearer, marker_flags, image('icons/UI_icons/map_blips.dmi', null, wearer.job.minimap_icon))
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/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/objects/structures/window.dm b/code/game/objects/structures/window.dm
index 586cd78d0b2..3feea2acd34 100644
--- a/code/game/objects/structures/window.dm
+++ b/code/game/objects/structures/window.dm
@@ -660,7 +660,6 @@
desc = "A glass window with a special rod matrice inside a wall frame. This one has an automatic shutter system to prevent any atmospheric breach."
max_integrity = 200
//icon_state = "rwindow0_debug" //Uncomment to check hull in the map editor
- resistance_flags = BANISH_IMMUNE
icon_state = "window-invincible"
/obj/structure/window/framed/prison/reinforced/hull/Initialize(mapload)
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/admin/topic.dm b/code/modules/admin/topic.dm
index 86bcc003ee0..101825b8ba9 100644
--- a/code/modules/admin/topic.dm
+++ b/code/modules/admin/topic.dm
@@ -426,8 +426,6 @@ Status: [status ? status : "Unknown"] | Damage: [health ? health : "None"]
newmob = M.change_mob_type(/mob/living/carbon/xenomorph/boiler, location, null, delmob)
if("crusher")
newmob = M.change_mob_type(/mob/living/carbon/xenomorph/crusher, location, null, delmob)
- //if("widow") //RUTGMC DELETION, WIDOW DELETION
- //newmob = M.change_mob_type(/mob/living/carbon/xenomorph/widow, location, null, delmob)
if("defiler")
newmob = M.change_mob_type(/mob/living/carbon/xenomorph/defiler, location, null, delmob)
if("gorger")
@@ -442,14 +440,6 @@ Status: [status ? status : "Unknown"] | Damage: [health ? health : "None"]
newmob = M.change_mob_type(/mob/living/carbon/xenomorph/queen, location, null, delmob)
if("king")
newmob = M.change_mob_type(/mob/living/carbon/xenomorph/king, location, null, delmob)
- /* RU TGMC EDIT START
- if("wraith")
- newmob = M.change_mob_type(/mob/living/carbon/xenomorph/wraith, location, null, delmob)
- RU TGMC EDIT END */
- /*RU TGMC EDIT
- if("puppeteer")
- newmob = M.change_mob_type(/mob/living/carbon/xenomorph/puppeteer, location, null, delmob)
- RU TGMC EDIT*/
if("behemoth")
newmob = M.change_mob_type(/mob/living/carbon/xenomorph/behemoth, location, null, delmob)
if("human")
@@ -476,7 +466,6 @@ Status: [status ? status : "Unknown"] | Damage: [health ? health : "None"]
newmob = M.change_mob_type(/mob/living/carbon/human/species/zombie, location, null, delmob, "Zombie")
if("ai")
newmob = M.change_mob_type(/mob/living/silicon/ai, location, null, delmob)
- //RUTGNC EDIT BEGIN
if("facehugger")
newmob = M.change_mob_type(/mob/living/carbon/xenomorph/facehugger, location, null, delmob)
if("panther")
@@ -492,7 +481,6 @@ Status: [status ? status : "Unknown"] | Damage: [health ? health : "None"]
newmob = M.change_mob_type(/mob/living/carbon/xenomorph/predalien, location, null, delmob)
if("yautja")
newmob = M.change_mob_type(/mob/living/carbon/human/species/yautja, location, null, delmob)
- //RUTGMC EDIT END
C.holder.show_player_panel(newmob)
@@ -2106,11 +2094,6 @@ Status: [status ? status : "Unknown"] | Damage: [health ? health : "None"]
return
X.upgrade_xeno(change)
- /* RUTGMC DELETION
- if(change != XENO_UPGRADE_NORMAL)
- var/datum/xeno_caste/previous_maturity = GLOB.xeno_caste_datums[X.caste_base_type][X.upgrade_prev()]
- X.upgrade_stored = previous_maturity.upgrade_threshold
- */
DIRECT_OUTPUT(usr, browse(null, "window=xeno_panel_[old_keyname]"))
usr.client.holder.xeno_panel(X)
diff --git a/code/modules/ai/ai_behaviors/ai_behavior.dm b/code/modules/ai/ai_behaviors/ai_behavior.dm
index 1a42bc57359..9591389d2ab 100644
--- a/code/modules/ai/ai_behaviors/ai_behavior.dm
+++ b/code/modules/ai/ai_behaviors/ai_behavior.dm
@@ -342,9 +342,6 @@ These are parameter based so the ai behavior can choose to (un)register the sign
/datum/ai_behavior/proc/ai_do_move()
if(!mob_parent?.canmove || mob_parent.do_actions)
return
- /// This allows minions to be buckled to their atom_to_escort without disrupting the movement of atom_to_escort
- //if(get_dist(mob_parent, atom_to_walk_to) <= 0) // RUTGMC DELETION, WIDOW REMOVAL
- //return
mob_parent.next_move_slowdown = 0
var/step_dir
if(get_dist(mob_parent, atom_to_walk_to) == distance_to_maintain)
diff --git a/code/modules/ai/ai_behaviors/xeno/puppet.dm b/code/modules/ai/ai_behaviors/xeno/puppet.dm
deleted file mode 100644
index 63fd4f082af..00000000000
--- a/code/modules/ai/ai_behaviors/xeno/puppet.dm
+++ /dev/null
@@ -1,187 +0,0 @@
-/* RU TGMC EDIT
-/datum/ai_behavior/puppet
- target_distance = 7
- base_action = IDLE
- identifier = IDENTIFIER_XENO
- ///should we go back to escorting the puppeteer if we stray too far
- var/too_far_escort = TRUE
- ///weakref to our puppeteer
- var/datum/weakref/master_ref
- ///the feed ability
- var/datum/action/ability/activable/xeno/feed
-
-
-/datum/ai_behavior/puppet/New(loc, parent_to_assign, escorted_atom)
- . = ..()
- master_ref = WEAKREF(escorted_atom)
- RegisterSignals(escorted_atom, list(COMSIG_MOB_DEATH, COMSIG_QDELETING), PROC_REF(die_on_master_death))
- change_order(null, PUPPET_RECALL)
- feed = mob_parent.actions_by_path[/datum/action/ability/activable/xeno/feed]
-
-///starts AI and registers obstructed move signal
-/datum/ai_behavior/puppet/start_ai()
- var/master = master_ref?.resolve()
- if(master)
- RegisterSignal(master, COMSIG_PUPPET_CHANGE_ALL_ORDER, PROC_REF(change_order))
- RegisterSignal(mob_parent, COMSIG_OBSTRUCTED_MOVE, PROC_REF(deal_with_obstacle))
- RegisterSignal(mob_parent, COMSIG_PUPPET_CHANGE_ORDER, PROC_REF(change_order))
- return ..()
-
-///cleans up signals and unregisters obstructed move signal
-/datum/ai_behavior/puppet/cleanup_signals()
- . = ..()
- UnregisterSignal(mob_parent, list(COMSIG_OBSTRUCTED_MOVE,COMSIG_PUPPET_CHANGE_ORDER))
- var/master = master_ref?.resolve()
- if(master)
- UnregisterSignal(master, COMSIG_PUPPET_CHANGE_ALL_ORDER)
-
-///signal handler for if the master (puppeteer) dies, gibs the puppet
-/datum/ai_behavior/puppet/proc/die_on_master_death(mob/living/source)
- SIGNAL_HANDLER
- if(!QDELETED(mob_parent))
- mob_parent.gib()
-
-///Signal handler to try to attack our target
-///Attack our current atom we are moving to, if targetted is specified attack that instead
-/datum/ai_behavior/puppet/proc/attack_target(datum/source, atom/targetted)
- SIGNAL_HANDLER
- if(world.time < mob_parent.next_move)
- return
- var/atom/target = targetted ? targetted : atom_to_walk_to
- if(!mob_parent.Adjacent(target))
- return
- if(mob_parent.z != target.z)
- return
- if(isliving(target))
- var/mob/living/victim = target
- if(victim.stat == DEAD)
- late_initialize()
- return
- do_feed(victim)
-
- mob_parent.face_atom(target)
- mob_parent.UnarmedAttack(target, mob_parent)
-
-///looks for a new state, handles recalling if too far and some AI shenanigans
-/datum/ai_behavior/puppet/look_for_new_state()
- switch(current_action)
- if(MOVING_TO_NODE, FOLLOWING_PATH)
- if(get_dist(mob_parent, escorted_atom) > PUPPET_WITHER_RANGE && too_far_escort)
- change_order(null, PUPPET_RECALL)
- return
- if(!change_order(null, PUPPET_SEEK_CLOSEST))
- change_action(MOVING_TO_NODE)
- return
- if(IDLE)
- if(!change_order(null, PUPPET_SEEK_CLOSEST))
- return
- if(ESCORTING_ATOM)
- if(!escorted_atom && master_ref)
- escorted_atom = master_ref.resolve()
- if(MOVING_TO_ATOM)
- if(!atom_to_walk_to) //edge case
- late_initialize()
- return ..()
-
-///override for MOVING_TO_ATOM to register signals for maintaining distance with our target and attacking
-/datum/ai_behavior/puppet/register_action_signals(action_type)
- if(action_type == MOVING_TO_ATOM)
- RegisterSignal(mob_parent, COMSIG_STATE_MAINTAINED_DISTANCE, PROC_REF(attack_target))
- if(!isobj(atom_to_walk_to))
- RegisterSignal(atom_to_walk_to, list(COMSIG_MOB_DEATH, COMSIG_QDELETING), PROC_REF(look_for_new_state))
- return ..()
-
-///override for MOVING_TO_ATOM to unregister signals for maintaining distance with our target and attacking
-/datum/ai_behavior/puppet/unregister_action_signals(action_type)
- if(action_type == MOVING_TO_ATOM)
- UnregisterSignal(mob_parent, COMSIG_STATE_MAINTAINED_DISTANCE)
- if(!isnull(atom_to_walk_to))
- UnregisterSignal(atom_to_walk_to, list(COMSIG_MOB_DEATH, COMSIG_QDELETING))
- return ..()
-
-///attack the first closest human, by moving towards it
-/datum/ai_behavior/puppet/proc/seek_and_attack_closest(mob/living/source)
- var/victim = get_nearest_target(mob_parent, target_distance, TARGET_HUMAN, mob_parent.faction)
- if(!victim)
- return FALSE
- change_action(MOVING_TO_ATOM, victim)
- return TRUE
-
-///seeks a living humans in a 9 tile range near our parent, picks one, then changes our action to move towards it and attack.
-/datum/ai_behavior/puppet/proc/seek_and_attack()
- var/list/mob/living/carbon/human/possible_victims = list()
- for(var/mob/living/carbon/human/victim in cheap_get_humans_near(mob_parent, 9))
- if(victim.stat == DEAD || isnestedhost(victim)) // RUTGMC ADDITION, no nest killing puppets
- continue
- possible_victims += victim
- if(!length(possible_victims))
- return FALSE
-
- change_action(MOVING_TO_ATOM, pick(possible_victims))
- return TRUE
-
-///changes our current behavior with a define (order), optionally with a target, FALSE means fail and TRUE means success
-/datum/ai_behavior/puppet/proc/change_order(mob/living/source, order, atom/target)
- SIGNAL_HANDLER
- if(!order)
- stack_trace("puppet AI was somehow passed a null order")
- return FALSE
- switch(order)
- if(PUPPET_SEEK_CLOSEST) //internal order, to attack closest enemy
- return seek_and_attack_closest()
- if(PUPPET_RECALL) //reset our escorted atom to master_ref and change our action to escorting it, and turn on recalling if out of range.
- escorted_atom = master_ref?.resolve()
- base_action = ESCORTING_ATOM
- change_action(ESCORTING_ATOM, escorted_atom)
- too_far_escort = TRUE
- return TRUE
- if(PUPPET_ATTACK) //turns on recalling out of range, if there is a target, attacks it, otherwise seeks and attacks one
- too_far_escort = TRUE
- if(target)
- change_action(MOVING_TO_ATOM, target)
- return TRUE
- else
- return seek_and_attack()
- if(PUPPET_SCOUT) //makes our parent wander and turn off recalling if out of range
- too_far_escort = FALSE
- base_action = MOVING_TO_NODE
- change_action(MOVING_TO_NODE)
- return TRUE
-
-///behavior to deal with obstacles
-/datum/ai_behavior/puppet/deal_with_obstacle(datum/source, direction)
- var/turf/obstacle_turf = get_step(mob_parent, direction)
- if(obstacle_turf.flags_atom & AI_BLOCKED)
- return
- for(var/thing in obstacle_turf.contents)
- if(istype(thing, /obj/structure/window_frame)) //if its a window, climb it after 2 seconds
- LAZYINCREMENT(mob_parent.do_actions, obstacle_turf)
- addtimer(CALLBACK(src, PROC_REF(climb_window_frame), obstacle_turf), 2 SECONDS)
- return COMSIG_OBSTACLE_DEALT_WITH
- if(istype(thing, /obj/alien)) //dont attack resin and such
- return
- if(istype(thing, /obj/structure/bed/nest)) //RUTGMC ADDITION, no nest breaking minions
- return
- if(isobj(thing)) //otherwise smash it if its damageable
- var/obj/obstacle = thing
- if(obstacle.resistance_flags & XENO_DAMAGEABLE)
- INVOKE_ASYNC(src, PROC_REF(attack_target), null, obstacle)
- return COMSIG_OBSTACLE_DEALT_WITH
- if(ISDIAGONALDIR(direction) && ((deal_with_obstacle(null, turn(direction, -45)) & COMSIG_OBSTACLE_DEALT_WITH) || (deal_with_obstacle(null, turn(direction, 45)) & COMSIG_OBSTACLE_DEALT_WITH)))
- return COMSIG_OBSTACLE_DEALT_WITH
-
-///makes our parent climb over a turf with a window by setting its location to it
-/datum/ai_behavior/puppet/proc/climb_window_frame(turf/window_turf)
- mob_parent.loc = window_turf
- mob_parent.last_move_time = world.time
- LAZYDECREMENT(mob_parent.do_actions, window_turf)
-
-///uses our feed ability if possible and it exists, on the target
-/datum/ai_behavior/puppet/proc/do_feed(atom/target)
- if(mob_parent.do_actions)
- return
- if(!feed)
- return
- if(feed.ai_should_use(target))
- feed.use_ability(target)
-RU TGMC EDIT*/
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/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/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/examine.dm b/code/modules/mob/living/carbon/human/examine.dm
index dca2c21dd0e..45475f2651e 100644
--- a/code/modules/mob/living/carbon/human/examine.dm
+++ b/code/modules/mob/living/carbon/human/examine.dm
@@ -488,13 +488,6 @@
msg += "\[Assign to a fireteam.\]\n"
msg += "[flavor_text]
"
-/* RU TGMC EDIT PUPPETEER REMOVAL
- if(HAS_TRAIT(src, TRAIT_HOLLOW))
- if(isxeno(user))
- msg += "[t_He] [t_is] hollow. Useless.\n"
- else
- msg += "[span_warning("[t_He] [t_is] hollowed out!")]\n"
-RU TGMC EDIT PUPPETEER REMOVAL */
if(isxeno(user))
if(species.species_flags & IS_SYNTHETIC)
msg += "[span_xenowarning("You sense [t_he] [t_is] not organic.")]\n"
diff --git a/code/modules/mob/living/carbon/human/human_defines.dm b/code/modules/mob/living/carbon/human/human_defines.dm
index 3de341f05f3..2d8022f688b 100644
--- a/code/modules/mob/living/carbon/human/human_defines.dm
+++ b/code/modules/mob/living/carbon/human/human_defines.dm
@@ -9,7 +9,7 @@
melee_damage = 5
m_intent = MOVE_INTENT_WALK
buckle_flags = CAN_BE_BUCKLED|CAN_BUCKLE
- resistance_flags = XENO_DAMAGEABLE|PORTAL_IMMUNE
+ resistance_flags = XENO_DAMAGEABLE
appearance_flags = KEEP_TOGETHER|TILE_BOUND|PIXEL_SCALE|LONG_GLIDE
hud_type = /datum/hud/human
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/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/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/behemoth/castedatum_behemoth.dm b/code/modules/mob/living/carbon/xenomorph/castes/behemoth/castedatum_behemoth.dm
index 4a3d163f076..fd67958b39c 100644
--- a/code/modules/mob/living/carbon/xenomorph/castes/behemoth/castedatum_behemoth.dm
+++ b/code/modules/mob/living/carbon/xenomorph/castes/behemoth/castedatum_behemoth.dm
@@ -22,9 +22,6 @@
// *** Health *** //
max_health = 750
- // *** Evolution *** //
- //upgrade_threshold = TIER_THREE_THRESHOLD // RUTGMC DELETION
-
deevolves_to = /mob/living/carbon/xenomorph/bull
// *** Flags *** //
diff --git a/code/modules/mob/living/carbon/xenomorph/castes/boiler/abilities_boiler.dm b/code/modules/mob/living/carbon/xenomorph/castes/boiler/abilities_boiler.dm
index cabd99a0dac..3c87b9e6335 100644
--- a/code/modules/mob/living/carbon/xenomorph/castes/boiler/abilities_boiler.dm
+++ b/code/modules/mob/living/carbon/xenomorph/castes/boiler/abilities_boiler.dm
@@ -33,7 +33,6 @@ GLOBAL_LIST_INIT(boiler_glob_image_list, list(
keybinding_signals = list(
KEYBINDING_NORMAL = COMSIG_XENOABILITY_LONG_RANGE_SIGHT,
)
- use_state_flags = ABILITY_USE_ROOTED
/datum/action/ability/xeno_action/toggle_long_range/action_activate()
var/mob/living/carbon/xenomorph/boiler/X = owner
@@ -170,7 +169,7 @@ GLOBAL_LIST_INIT(boiler_glob_image_list, list(
ability_cost = 150
cooldown_duration = 180 SECONDS
keybind_flags = ABILITY_KEYBIND_USE_ABILITY |ABILITY_IGNORE_SELECTED_ABILITY
- use_state_flags = ABILITY_USE_STAGGERED|ABILITY_USE_ROOTED
+ use_state_flags = ABILITY_USE_STAGGERED
keybinding_signals = list(
KEYBINDING_NORMAL = COMSIG_XENOABILITY_DUMP_ACID,
)
@@ -383,4 +382,3 @@ GLOBAL_LIST_INIT(boiler_glob_image_list, list(
// ***************************************
/datum/action/ability/activable/xeno/spray_acid/line/boiler
cooldown_duration = 9 SECONDS
- use_state_flags = ABILITY_USE_ROOTED
diff --git a/code/modules/mob/living/carbon/xenomorph/castes/boiler/castedatum_boiler.dm b/code/modules/mob/living/carbon/xenomorph/castes/boiler/castedatum_boiler.dm
index 07c9cc3a9b3..ebadec95ba0 100644
--- a/code/modules/mob/living/carbon/xenomorph/castes/boiler/castedatum_boiler.dm
+++ b/code/modules/mob/living/carbon/xenomorph/castes/boiler/castedatum_boiler.dm
@@ -25,9 +25,6 @@
// *** Health *** //
max_health = 325
- // *** Evolution *** //
- //upgrade_threshold = TIER_THREE_THRESHOLD // RUTGMC DELETION
-
deevolves_to = /mob/living/carbon/xenomorph/spitter
// *** Darksight *** ///
diff --git a/code/modules/mob/living/carbon/xenomorph/castes/bull/castedatum_bull.dm b/code/modules/mob/living/carbon/xenomorph/castes/bull/castedatum_bull.dm
index 5207c1a34d2..644ba6020ff 100644
--- a/code/modules/mob/living/carbon/xenomorph/castes/bull/castedatum_bull.dm
+++ b/code/modules/mob/living/carbon/xenomorph/castes/bull/castedatum_bull.dm
@@ -23,7 +23,6 @@
// *** Evolution *** //
evolution_threshold = 225
- // upgrade_threshold = TIER_TWO_THRESHOLD // RUTGMC DELETION
evolves_to = list(
/mob/living/carbon/xenomorph/crusher,
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/carrier/castedatum_carrier.dm b/code/modules/mob/living/carbon/xenomorph/castes/carrier/castedatum_carrier.dm
index d27837cdea6..7dabc895c8c 100644
--- a/code/modules/mob/living/carbon/xenomorph/castes/carrier/castedatum_carrier.dm
+++ b/code/modules/mob/living/carbon/xenomorph/castes/carrier/castedatum_carrier.dm
@@ -25,7 +25,6 @@
// *** Evolution *** //
evolution_threshold = 225
- // upgrade_threshold = TIER_TWO_THRESHOLD // RUTGMC DELETION
deevolves_to = /mob/living/carbon/xenomorph/drone
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..63a12c3eb3f 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
@@ -43,7 +43,6 @@
to_chat(owner, span_xenowarning("We cannot blink here!"))
return FALSE
-
return TRUE
///Check for whether the target turf has dense objects inside
@@ -61,7 +60,7 @@
var/mob/living/carbon/xenomorph/X = owner
var/turf/T = X.loc
var/turf/temp_turf = X.loc
- var/check_distance = min(X.xeno_caste.wraith_blink_range, get_dist(X,A))
+ var/check_distance = min(X.xeno_caste.blink_range, get_dist(X,A))
var/list/fully_legal_turfs = list()
for (var/x = 1 to check_distance)
@@ -86,11 +85,11 @@
if(pulled_target) //bring the pulled target with us if applicable but at the cost of sharply increasing the next cooldown
if(pulled_target.issamexenohive(X))
- cooldown_mod = X.xeno_caste.wraith_blink_drag_friendly_multiplier
+ cooldown_mod = X.xeno_caste.blink_drag_friendly_multiplier
else
if(!do_after(owner, 0.5 SECONDS, NONE, owner, BUSY_ICON_HOSTILE)) //Grap-porting hostiles has a slight wind up
return fail_activate()
- cooldown_mod = X.xeno_caste.wraith_blink_drag_nonfriendly_living_multiplier
+ cooldown_mod = X.xeno_caste.blink_drag_nonfriendly_living_multiplier
if(ishuman(pulled_target))
var/mob/living/carbon/human/H = pulled_target
if(H.stat == UNCONSCIOUS) //Apply critdrag damage as if they were quickly pulled the same distance
@@ -111,10 +110,10 @@
succeed_activate()
add_cooldown(cooldown_duration * cooldown_mod)
- GLOB.round_statistics.wraith_blinks++
- SSblackbox.record_feedback("tally", "round_statistics", 1, "wraith_blinks") //Statistics
+ GLOB.round_statistics.chimera_blinks++
+ SSblackbox.record_feedback("tally", "round_statistics", 1, "chimera_blinks") //Statistics
-///Called by many of the Wraith's teleportation effects
+///Called by many of the Chimera's teleportation effects
/datum/action/ability/activable/xeno/proc/teleport_debuff_aoe(atom/movable/teleporter, silent = FALSE)
var/mob/living/carbon/xenomorph/ghost = owner
@@ -135,13 +134,13 @@
if(X.issamexenohive(ghost)) //No friendly fire
continue
- living_target.adjust_stagger(WRAITH_TELEPORT_DEBUFF_STAGGER_STACKS)
- living_target.add_slowdown(WRAITH_TELEPORT_DEBUFF_SLOWDOWN_STACKS)
+ living_target.adjust_stagger(CHIMERA_TELEPORT_DEBUFF_STAGGER_STACKS)
+ living_target.add_slowdown(CHIMERA_TELEPORT_DEBUFF_SLOWDOWN_STACKS)
to_chat(living_target, span_warning("You feel nauseous as reality warps around you!"))
/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 +190,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 +267,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 +342,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/chimera/castedatum_chimera.dm b/code/modules/mob/living/carbon/xenomorph/castes/chimera/castedatum_chimera.dm
index 3a94acad4eb..a89f47c9356 100644
--- a/code/modules/mob/living/carbon/xenomorph/castes/chimera/castedatum_chimera.dm
+++ b/code/modules/mob/living/carbon/xenomorph/castes/chimera/castedatum_chimera.dm
@@ -23,8 +23,6 @@
max_health = 350
// *** Evolution *** //
- // upgrade_threshold = TIER_THREE_THRESHOLD // RUTGMC DELETION
-
deevolves_to = /mob/living/carbon/xenomorph/panther
// *** Flags *** //
@@ -35,7 +33,9 @@
// *** Defense *** //
soft_armor = list(MELEE = 50, BULLET = 40, LASER = 40, ENERGY = 40, BOMB = 0, BIO = 50, FIRE = 0, ACID = 50)
- wraith_blink_range = 5
+ blink_drag_nonfriendly_living_multiplier = 20
+ blink_drag_friendly_multiplier = 4
+ blink_range = 5
minimap_icon = "chimera"
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/crusher/castedatum_crusher.dm b/code/modules/mob/living/carbon/xenomorph/castes/crusher/castedatum_crusher.dm
index 76707b4dca2..1abc6dad8f5 100644
--- a/code/modules/mob/living/carbon/xenomorph/castes/crusher/castedatum_crusher.dm
+++ b/code/modules/mob/living/carbon/xenomorph/castes/crusher/castedatum_crusher.dm
@@ -27,8 +27,6 @@
max_health = 400
// *** Evolution *** //
- //upgrade_threshold = TIER_THREE_THRESHOLD // RUTGMC DELETION
-
deevolves_to = /mob/living/carbon/xenomorph/bull
// *** 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/defender/castedatum_defender.dm b/code/modules/mob/living/carbon/xenomorph/castes/defender/castedatum_defender.dm
index 9f22db0a570..5b74ac80035 100644
--- a/code/modules/mob/living/carbon/xenomorph/castes/defender/castedatum_defender.dm
+++ b/code/modules/mob/living/carbon/xenomorph/castes/defender/castedatum_defender.dm
@@ -25,8 +25,6 @@
// *** Evolution *** //
evolution_threshold = 100
- // upgrade_threshold = TIER_ONE_THRESHOLD // RUTGMC DELETION
-
evolves_to = list(
/mob/living/carbon/xenomorph/warrior,
/mob/living/carbon/xenomorph/bull,
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/defiler/castedatum_defiler.dm b/code/modules/mob/living/carbon/xenomorph/castes/defiler/castedatum_defiler.dm
index 52d055876f6..08b2a0c9df5 100644
--- a/code/modules/mob/living/carbon/xenomorph/castes/defiler/castedatum_defiler.dm
+++ b/code/modules/mob/living/carbon/xenomorph/castes/defiler/castedatum_defiler.dm
@@ -24,8 +24,6 @@
max_health = 400
// *** Evolution *** //
- //upgrade_threshold = TIER_THREE_THRESHOLD // RUTGMC DELETION
-
deevolves_to = /mob/living/carbon/xenomorph/carrier
// *** Flags *** //
diff --git a/code/modules/mob/living/carbon/xenomorph/castes/drone/castedatum_drone.dm b/code/modules/mob/living/carbon/xenomorph/castes/drone/castedatum_drone.dm
index 7ba51ce2e4f..5b130c0aa35 100644
--- a/code/modules/mob/living/carbon/xenomorph/castes/drone/castedatum_drone.dm
+++ b/code/modules/mob/living/carbon/xenomorph/castes/drone/castedatum_drone.dm
@@ -27,8 +27,6 @@
// *** Evolution *** //
evolution_threshold = 100
- //upgrade_threshold = TIER_ONE_THRESHOLD // RUTGMC DELETION
-
evolves_to = list(
/mob/living/carbon/xenomorph/shrike,
/mob/living/carbon/xenomorph/queen,
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/gorger/castedatum_gorger.dm b/code/modules/mob/living/carbon/xenomorph/castes/gorger/castedatum_gorger.dm
index 7392d53e70b..0b1d7e30c0d 100644
--- a/code/modules/mob/living/carbon/xenomorph/castes/gorger/castedatum_gorger.dm
+++ b/code/modules/mob/living/carbon/xenomorph/castes/gorger/castedatum_gorger.dm
@@ -27,8 +27,6 @@
max_health = 600
// *** Evolution *** //
- //upgrade_threshold = TIER_THREE_THRESHOLD // RUTGMC DELETION
-
deevolves_to = list(/mob/living/carbon/xenomorph/warrior, /mob/living/carbon/xenomorph/hivelord)
// *** Flags *** //
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/hivelord/castedatum_hivelord.dm b/code/modules/mob/living/carbon/xenomorph/castes/hivelord/castedatum_hivelord.dm
index f6852111788..d5b80f60611 100644
--- a/code/modules/mob/living/carbon/xenomorph/castes/hivelord/castedatum_hivelord.dm
+++ b/code/modules/mob/living/carbon/xenomorph/castes/hivelord/castedatum_hivelord.dm
@@ -26,7 +26,6 @@
// *** Evolution *** //
evolution_threshold = 225
- //upgrade_threshold = TIER_TWO_THRESHOLD // RUTGMC DELETION
deevolves_to = /mob/living/carbon/xenomorph/drone
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..186964a4c54 100644
--- a/code/modules/mob/living/carbon/xenomorph/castes/hivemind/hivemind.dm
+++ b/code/modules/mob/living/carbon/xenomorph/castes/hivemind/hivemind.dm
@@ -10,7 +10,7 @@
bubble_icon = "alienroyal"
icon = 'icons/Xeno/castes/hivemind.dmi'
status_flags = GODMODE | INCORPOREAL
- resistance_flags = RESIST_ALL|BANISH_IMMUNE
+ resistance_flags = RESIST_ALL
pass_flags = PASS_LOW_STRUCTURE|PASSABLE|PASS_FIRE //to prevent hivemind eye to catch fire when crossing lava
density = FALSE
@@ -128,7 +128,6 @@
update_movespeed()
if(status_flags & INCORPOREAL)
status_flags = NONE
- resistance_flags = BANISH_IMMUNE
pass_flags = PASS_LOW_STRUCTURE|PASS_MOB|PASS_XENO
density = TRUE
hive.xenos_by_upgrade[upgrade] -= src
@@ -404,7 +403,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/hunter/castedatum_hunter.dm b/code/modules/mob/living/carbon/xenomorph/castes/hunter/castedatum_hunter.dm
index 5f744ded309..df7dd7336fc 100644
--- a/code/modules/mob/living/carbon/xenomorph/castes/hunter/castedatum_hunter.dm
+++ b/code/modules/mob/living/carbon/xenomorph/castes/hunter/castedatum_hunter.dm
@@ -29,7 +29,6 @@
// *** Evolution *** //
evolution_threshold = 225
- //upgrade_threshold = TIER_TWO_THRESHOLD // RUTGMC DELETION
evolves_to = list(/mob/living/carbon/xenomorph/ravager, /mob/living/carbon/xenomorph/chimera)
deevolves_to = /mob/living/carbon/xenomorph/runner
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/castedatum_king.dm b/code/modules/mob/living/carbon/xenomorph/castes/king/castedatum_king.dm
index c9ad494ab80..7dcf09bf4fd 100644
--- a/code/modules/mob/living/carbon/xenomorph/castes/king/castedatum_king.dm
+++ b/code/modules/mob/living/carbon/xenomorph/castes/king/castedatum_king.dm
@@ -24,7 +24,6 @@
sunder_recover = 2
// *** Evolution *** //
- //upgrade_threshold = TIER_THREE_THRESHOLD // RUTGMC DELETION
maximum_active_caste = 1
evolve_min_xenos = 12
death_evolution_delay = 7 MINUTES
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/panther/castedatum_panther.dm b/code/modules/mob/living/carbon/xenomorph/castes/panther/castedatum_panther.dm
index e6f625c0b76..d777ac01ca6 100644
--- a/code/modules/mob/living/carbon/xenomorph/castes/panther/castedatum_panther.dm
+++ b/code/modules/mob/living/carbon/xenomorph/castes/panther/castedatum_panther.dm
@@ -29,7 +29,6 @@
// *** Evolution *** //
evolution_threshold = 225
- //upgrade_threshold = TIER_TWO_THRESHOLD // RUTGMC DELETION
evolves_to = list(/mob/living/carbon/xenomorph/ravager, /mob/living/carbon/xenomorph/chimera)
deevolves_to = /mob/living/carbon/xenomorph/runner
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/praetorian/castedatum_praetorian.dm b/code/modules/mob/living/carbon/xenomorph/castes/praetorian/castedatum_praetorian.dm
index 554f7bedb70..f88170065d7 100644
--- a/code/modules/mob/living/carbon/xenomorph/castes/praetorian/castedatum_praetorian.dm
+++ b/code/modules/mob/living/carbon/xenomorph/castes/praetorian/castedatum_praetorian.dm
@@ -22,8 +22,6 @@
max_health = 460
// *** Evolution *** //
- //upgrade_threshold = TIER_THREE_THRESHOLD // RUTGMC DELETION
-
deevolves_to = /mob/living/carbon/xenomorph/spitter
// *** Flags *** //
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/puppet/abilities_puppet.dm b/code/modules/mob/living/carbon/xenomorph/castes/puppet/abilities_puppet.dm
deleted file mode 100644
index 438aca53da4..00000000000
--- a/code/modules/mob/living/carbon/xenomorph/castes/puppet/abilities_puppet.dm
+++ /dev/null
@@ -1,28 +0,0 @@
-/*RU TGMC EDIT
-/datum/action/ability/activable/xeno/feed
- name = "Feed"
- action_icon_state = "lunge"
- desc = "Assault an organic, restoring health through the use of the their biomass."
- ability_cost = 0
- cooldown_duration = 35 SECONDS
- target_flags = ABILITY_MOB_TARGET
-
-/datum/action/ability/activable/xeno/feed/use_ability(mob/living/carbon/human/target_human)
- var/mob/living/carbon/xenomorph/owner_xeno = owner
- owner_xeno.face_atom(target_human)
- owner_xeno.do_attack_animation(target_human, ATTACK_EFFECT_REDSLASH)
- owner_xeno.visible_message(target_human, span_danger("[owner_xeno] tears into [target_human]!"))
- playsound(target_human, "alien_claw_flesh", 25, TRUE)
- target_human.emote("scream")
- target_human.apply_damage(damage = 25, damagetype = BRUTE, def_zone = BODY_ZONE_CHEST, blocked = 0, sharp = TRUE, edge = FALSE, updating_health = TRUE)
- var/amount = 15 //heal xeno damage needs a variable not a number
- HEAL_XENO_DAMAGE(owner_xeno, amount, FALSE)
- add_cooldown()
-
-/datum/action/ability/activable/xeno/feed/can_use_ability(mob/living/target, silent = FALSE, override_flags)
- . = ..()
- if(!ishuman(target))
- return FALSE
- if(!owner.Adjacent(target))
- return FALSE
-RU TGMC EDIT*/
diff --git a/code/modules/mob/living/carbon/xenomorph/castes/puppet/castedatum_puppet.dm b/code/modules/mob/living/carbon/xenomorph/castes/puppet/castedatum_puppet.dm
deleted file mode 100644
index 24d9fc87b4b..00000000000
--- a/code/modules/mob/living/carbon/xenomorph/castes/puppet/castedatum_puppet.dm
+++ /dev/null
@@ -1,26 +0,0 @@
-/*RU TGMC EDIT
-/datum/xeno_caste/puppet
- caste_name = "Puppet"
- display_name = "Puppet"
- upgrade_name = ""
- caste_desc = "A grotesque puppet of a puppeteer."
- wound_type = ""
-
- caste_type_path = /mob/living/carbon/xenomorph/puppet
-
- tier = XENO_TIER_MINION
- upgrade = XENO_UPGRADE_BASETYPE
- melee_damage = 15
- speed = -0.8
- plasma_max = 2
- plasma_gain = 0
- max_health = 250
- caste_flags = CASTE_NOT_IN_BIOSCAN|CASTE_DO_NOT_ANNOUNCE_DEATH|CASTE_DO_NOT_ALERT_LOW_LIFE
- minimap_icon = "puppet"
- soft_armor = list(MELEE = 14, BULLET = 3, LASER = 5, ENERGY = 3, BOMB = 0, BIO = 0, FIRE = 0, ACID = 0)
-
- actions = list(
- /datum/action/ability/xeno_action/xeno_resting,
- /datum/action/ability/activable/xeno/feed,
- )
-RU TGMC EDIT*/
diff --git a/code/modules/mob/living/carbon/xenomorph/castes/puppet/puppet.dm b/code/modules/mob/living/carbon/xenomorph/castes/puppet/puppet.dm
deleted file mode 100644
index 36fb756efaa..00000000000
--- a/code/modules/mob/living/carbon/xenomorph/castes/puppet/puppet.dm
+++ /dev/null
@@ -1,68 +0,0 @@
-/*RU TGMC EDIT
-/mob/living/carbon/xenomorph/puppet
- caste_base_type = /mob/living/carbon/xenomorph/puppet
- name = "Puppet"
- desc = "A reanimated body, crudely pieced together and held in place by an ominous energy tethered to some unknown force."
- icon = 'icons/Xeno/castes/puppet.dmi'
- icon_state = "Puppet Running"
- health = 250
- maxHealth = 250
- plasma_stored = 0
- pixel_x = 0
- old_x = 0
- tier = XENO_TIER_MINION
- upgrade = XENO_UPGRADE_BASETYPE
- pull_speed = -1
- allow_pass_flags = PASS_XENO
- pass_flags = PASS_XENO
- voice_filter = @{"[0:a] asplit [out0][out2]; [out0] asetrate=%SAMPLE_RATE%*0.9,aresample=%SAMPLE_RATE%,atempo=1/0.9,aformat=channel_layouts=mono,volume=0.2 [p0]; [out2] asetrate=%SAMPLE_RATE%*1.1,aresample=%SAMPLE_RATE%,atempo=1/1.1,aformat=channel_layouts=mono,volume=0.2[p2]; [p0][0][p2] amix=inputs=3"}
- ///our masters weakref
- var/datum/weakref/weak_master
-
-/mob/living/carbon/xenomorph/puppet/handle_special_state() //prevent us from using different run/walk sprites
- icon_state = "[xeno_caste.caste_name] Running"
- return TRUE
-
-/mob/living/carbon/xenomorph/puppet/Initialize(mapload, mob/living/carbon/xenomorph/puppeteer)
- . = ..()
- if(puppeteer)
- weak_master = WEAKREF(puppeteer)
- transfer_to_hive(puppeteer.hivenumber)
- AddComponent(/datum/component/ai_controller, /datum/ai_behavior/puppet, puppeteer)
-
-/mob/living/carbon/xenomorph/puppet/on_death()
- . = ..()
- if(!QDELETED(src))
- gib()
-
-/* /mob/living/carbon/xenomorph/puppet/Life()
- . = ..()
- var/atom/movable/master = weak_master?.resolve()
- if(!master)
- return
- if(get_dist(src, master) > PUPPET_WITHER_RANGE)
- adjustBruteLoss(15)
- else
- adjustBruteLoss(-5)
- Moved to Modularity
-*/
-/mob/living/carbon/xenomorph/puppet/can_receive_aura(aura_type, atom/source, datum/aura_bearer/bearer)
- . = ..()
- var/atom/movable/master = weak_master?.resolve()
- if(!master)
- return
- if(source != master) //puppeteer phero only
- return FALSE
-
-/mob/living/carbon/xenomorph/puppet/med_hud_set_status()
- . = ..()
- hud_set_blessings()
-
-/mob/living/carbon/xenomorph/puppet/proc/hud_set_blessings()
- var/image/holder = hud_list[XENO_BLESSING_HUD]
- if(!holder)
- return
- for(var/datum/status_effect/effect AS in status_effects)
- if(istype(effect, /datum/status_effect/blessing))
- holder.overlays += image('icons/mob/hud.dmi', icon_state = initial(effect.id))
-RU TGMC EDIT*/
diff --git a/code/modules/mob/living/carbon/xenomorph/castes/puppeteer/abilities_puppeteer.dm b/code/modules/mob/living/carbon/xenomorph/castes/puppeteer/abilities_puppeteer.dm
deleted file mode 100644
index ce2a725f6f6..00000000000
--- a/code/modules/mob/living/carbon/xenomorph/castes/puppeteer/abilities_puppeteer.dm
+++ /dev/null
@@ -1,527 +0,0 @@
-/* RUTGMC EDIT
-// ***************************************
-// *********** Flay
-// ***************************************
-/datum/action/ability/activable/xeno/flay
- name = "Flay"
- action_icon_state = "flay"
- desc = "Takes a chunk of flesh from the victim marine through a quick swiping motion, adding 100 biomass to your biomass collection."
- ability_cost = 0
- cooldown_duration = 20 SECONDS
- target_flags = ABILITY_MOB_TARGET
- keybinding_signals = list(
- KEYBINDING_NORMAL = COMSIG_XENOABILITY_FLAY,
- )
-
-/datum/action/ability/activable/xeno/flay/can_use_ability(atom/target, silent = FALSE, override_flags)
- . = ..()
- if(!.)
- return
-
- var/mob/living/carbon/xenomorph/owner_xeno = owner
- var/mob/living/carbon/human/target_human = target
- if(!ishuman(target))
- if(!silent)
- owner_xeno.balloon_alert(owner_xeno, "not suitable!")
- return FALSE
-
- if(!owner_xeno.Adjacent(target_human))
- if(!silent)
- owner_xeno.balloon_alert(owner_xeno, "not adjacent!")
- return FALSE
-
- if(target_human.stat == DEAD)
- if(!silent)
- owner_xeno.balloon_alert(owner_xeno, "dead!")
- return FALSE
-
-/datum/action/ability/activable/xeno/flay/use_ability(mob/living/carbon/human/target_human)
- var/mob/living/carbon/xenomorph/owner_xeno = owner
- owner_xeno.face_atom(target_human)
- owner_xeno.do_attack_animation(target_human, ATTACK_EFFECT_REDSLASH)
- owner_xeno.visible_message(target_human, span_danger("[owner_xeno] flays and rips skin and flesh from [target_human]!"))
- playsound(target_human, "alien_claw_flesh", 25, TRUE)
- target_human.emote("scream")
- owner_xeno.emote("roar")
- target_human.apply_damage(30, def_zone = BODY_ZONE_CHEST, blocked = MELEE, sharp = TRUE, edge = FALSE, updating_health = TRUE, penetration = 15)
- target_human.Paralyze(0.8 SECONDS)
-
- owner_xeno.gain_plasma(owner_xeno.xeno_caste.flay_plasma_gain)
-
- add_cooldown()
-
-// ***************************************
-// *********** Pincushion
-// ***************************************
-/datum/action/ability/activable/xeno/pincushion
- name = "Pincushion"
- action_icon_state = "pincushion"
- desc = "Launch a spine from your tail. This attack will help deter any organic as well as support your puppets and teammates in direct combat."
- cooldown_duration = 5 SECONDS
- keybinding_signals = list(
- KEYBINDING_NORMAL = COMSIG_XENOABILITY_PINCUSHION,
- )
-
-/datum/action/ability/activable/xeno/pincushion/can_use_ability(atom/victim, silent = FALSE, override_flags)
- . = ..()
- if(!.)
- return
- var/mob/living/carbon/xenomorph/X = owner
- if(X.do_actions)
- return FALSE
- X.face_atom(victim)
- if(!do_after(X, 0.3 SECONDS, IGNORE_HELD_ITEM|IGNORE_USER_LOC_CHANGE|IGNORE_TARGET_LOC_CHANGE, victim, BUSY_ICON_DANGER, extra_checks = CALLBACK(X, TYPE_PROC_REF(/mob, break_do_after_checks), list("health" = X.health))))
- return FALSE
- succeed_activate()
-
-/datum/action/ability/activable/xeno/pincushion/use_ability(atom/victim)
- var/mob/living/carbon/xenomorph/xeno = owner
- var/turf/current_turf = get_turf(owner)
- playsound(xeno.loc, 'sound/bullets/spear_armor1.ogg', 25, 1)
- xeno.visible_message(span_warning("[xeno] shoots a spike!"), span_xenonotice("We discharge a spinal spike from our body."))
-
- var/obj/projectile/spine = new /obj/projectile(current_turf)
- spine.generate_bullet(/datum/ammo/xeno/spine)
- spine.def_zone = xeno.get_limbzone_target()
- spine.fire_at(victim, xeno, null, range = 6, speed = 1)
-
- add_cooldown()
-// ***************************************
-// *********** Dreadful Presence
-// ***************************************
-#define DREAD_RANGE 6
-/datum/action/ability/xeno_action/dreadful_presence
- name = "Dreadful Presence"
- action_icon_state = "dreadful_presence"
- desc = "Emit a menacing presence, striking fear into the organics and slowing them for a short duration."
- ability_cost = 50
- cooldown_duration = 20 SECONDS
- keybinding_signals = list(
- KEYBINDING_NORMAL = COMSIG_XENOABILITY_DREADFULPRESENCE,
- )
-
-/datum/action/ability/xeno_action/dreadful_presence/action_activate()
- var/obj/effect/overlay/dread/effect = new
- owner.vis_contents += effect
- for(var/mob/living/carbon/human/human in view(DREAD_RANGE, owner.loc))
- to_chat(human, span_userdanger("An overwhelming sense of dread washes over you... You are temporarily slowed down!"))
- human.set_timed_status_effect(6 SECONDS, /datum/status_effect/dread)
- addtimer(CALLBACK(human, TYPE_PROC_REF(/mob/living/carbon/human, emote), "scream"), rand(1,2))
- addtimer(CALLBACK(src, PROC_REF(clear_effect), effect), 3 SECONDS)
- add_cooldown()
- succeed_activate()
-
-/datum/action/ability/xeno_action/dreadful_presence/proc/clear_effect(atom/effect)
- owner.vis_contents -= effect
- qdel(effect)
-
-#undef DREAD_RANGE
-// ***************************************
-// *********** Refurbish Husk
-// ***************************************
-/datum/action/ability/activable/xeno/refurbish_husk
- name = "Refurbish Husk"
- action_icon_state = "refurbish_husk"
- desc = "Harvest the biomass and organs of a body in order to create a meat puppet to do your bidding."
- cooldown_duration = 25 SECONDS
- target_flags = ABILITY_MOB_TARGET
- keybinding_signals = list(
- KEYBINDING_NORMAL = COMSIG_XENOABILITY_REFURBISHHUSK,
- )
- /// List of all our puppets
- var/list/mob/living/carbon/xenomorph/puppet/puppets = list()
-
-/datum/action/ability/activable/xeno/refurbish_husk/can_use_ability(atom/target, silent = FALSE, override_flags)
- . = ..()
- if(!.)
- return
- var/mob/living/carbon/xenomorph/owner_xeno = owner
- var/mob/living/carbon/human/target_human = target
- if(!ishuman(target))
- if(!silent)
- owner_xeno.balloon_alert(owner_xeno, "not suitable!")
- return FALSE
- if(length(puppets) >= owner_xeno.xeno_caste.max_puppets)
- if(!silent)
- owner_xeno.balloon_alert(owner_xeno, "too many puppets! (max: [owner_xeno.xeno_caste.max_puppets])")
- return FALSE
- if(HAS_TRAIT(target, TRAIT_MAPSPAWNED) || HAS_TRAIT(target, TRAIT_HOLLOW))
- if(!silent)
- owner_xeno.balloon_alert(owner_xeno, "of no use!")
- return FALSE
-
- if(!owner_xeno.Adjacent(target_human))
- if(!silent)
- owner_xeno.balloon_alert(owner_xeno, "not adjacent!")
- return FALSE
-
-#ifndef TESTING
- if(!HAS_TRAIT(target_human, TRAIT_UNDEFIBBABLE) || target_human.stat != DEAD)
- owner_xeno.balloon_alert(owner_xeno, "not dead and unrevivable!")
- return FALSE
-#endif
-
- owner_xeno.face_atom(target_human)
- owner_xeno.visible_message(target_human, span_danger("[owner_xeno] begins carving out, doing all sorts of horrible things to [target_human]!"))
- if(!do_after(owner_xeno, 8 SECONDS, IGNORE_HELD_ITEM, target_human, BUSY_ICON_DANGER, extra_checks = CALLBACK(owner_xeno, TYPE_PROC_REF(/mob, break_do_after_checks), list("health" = owner_xeno.health))))
- return FALSE
- succeed_activate()
-
-/datum/action/ability/activable/xeno/refurbish_husk/use_ability(mob/living/carbon/human/victim)
- var/turf/victim_turf = get_turf(victim)
-
- ADD_TRAIT(victim, TRAIT_HOLLOW, TRAIT_GENERIC)
- victim.spawn_gibs()
- var/mob/living/carbon/xenomorph/puppet/puppet = new(victim_turf, owner)
- puppet.voice = victim.voice
- add_puppet(puppet)
- add_cooldown()
-
-/// Adds a puppet to our list
-/datum/action/ability/activable/xeno/refurbish_husk/proc/add_puppet(mob/living/carbon/xenomorph/puppet/new_puppet)
- RegisterSignals(new_puppet, list(COMSIG_MOB_DEATH, COMSIG_QDELETING), PROC_REF(remove_puppet))
- RegisterSignal(new_puppet, COMSIG_XENOMORPH_POSTATTACK_LIVING, PROC_REF(postattack))
- puppets += new_puppet
-
-/// Cleans up puppet from our list
-/datum/action/ability/activable/xeno/refurbish_husk/proc/remove_puppet(datum/source)
- SIGNAL_HANDLER
- puppets -= source
- UnregisterSignal(source, list(COMSIG_MOB_DEATH, COMSIG_QDELETING, COMSIG_XENOMORPH_POSTATTACK_LIVING))
-
-/datum/action/ability/activable/xeno/refurbish_husk/proc/postattack(mob/living/source, mob/living/target, damage)
- SIGNAL_HANDLER
- var/mob/living/carbon/xenomorph/owner_xeno = owner
- if(target.stat == DEAD)
- return
- owner_xeno.plasma_stored = min(owner_xeno.plasma_stored + round(damage / 0.9), owner_xeno.xeno_caste.plasma_max)
-
-// ***************************************
-// *********** Stitch Puppet
-// ***************************************
-/datum/action/ability/activable/xeno/puppet
- name = "Stitch Puppet"
- action_icon_state = "stitch_puppet"
- desc = "Uses 125 biomass to create a flesh homunculus to do your bidding, at an adjacent target location."
- ability_cost = 125
- cooldown_duration = 25 SECONDS
- target_flags = ABILITY_TURF_TARGET
- keybinding_signals = list(
- KEYBINDING_NORMAL = COMSIG_XENOABILITY_PUPPET,
- )
-
-/datum/action/ability/activable/xeno/puppet/can_use_ability(atom/target, silent = FALSE, override_flags)
- . = ..()
- if(!.)
- return
-
- var/mob/living/carbon/xenomorph/owner_xeno = owner
- if(isclosedturf(target))
- if(!silent)
- target.balloon_alert(owner_xeno, "dense area")
- return FALSE
-
- var/datum/action/ability/activable/xeno/refurbish_husk/huskaction = owner.actions_by_path[/datum/action/ability/activable/xeno/refurbish_husk]
- if(length(huskaction.puppets) >= owner_xeno.xeno_caste.max_puppets)
- if(!silent)
- owner_xeno.balloon_alert(owner_xeno, "too many puppets! (max: [owner_xeno.xeno_caste.max_puppets])")
- return FALSE
-
- if(!owner_xeno.Adjacent(target))
- if(!silent)
- owner_xeno.balloon_alert(owner_xeno, "not adjacent!")
- return FALSE
-
- owner_xeno.face_atom(target)
- //reverse gib here
- owner_xeno.visible_message(span_warning("[owner_xeno] begins to vomit out biomass and skillfully sews various bits and pieces together!"))
- if(!do_after(owner_xeno, 8 SECONDS, IGNORE_HELD_ITEM, target, BUSY_ICON_CLOCK, extra_checks = CALLBACK(owner_xeno, TYPE_PROC_REF(/mob, break_do_after_checks), list("health" = owner_xeno.health))))
- return FALSE
- owner_xeno.visible_message(span_warning("[owner_xeno] forms a repulsive puppet!"))
- succeed_activate()
-
-/datum/action/ability/activable/xeno/puppet/use_ability(atom/target)
- var/turf/target_turf = get_turf(target)
-
- var/datum/action/ability/activable/xeno/refurbish_husk/huskaction = owner.actions_by_path[/datum/action/ability/activable/xeno/refurbish_husk]
- huskaction.add_puppet(new /mob/living/carbon/xenomorph/puppet(target_turf, owner))
- add_cooldown()
-
-// ***************************************
-// *********** Organic Bomb
-// ***************************************
-/datum/action/ability/activable/xeno/organic_bomb
- name = "Organic Bomb"
- action_icon_state = "organic_bomb"
- desc = "Causes one of our puppets to detonate on selection, spewing acid out of the puppet's body in all directions, gibbing the puppet."
- cooldown_duration = 30 SECONDS
- ability_cost = 100
- target_flags = ABILITY_MOB_TARGET
- keybinding_signals = list(
- KEYBINDING_NORMAL = COMSIG_XENOABILITY_ORGANICBOMB,
- )
-
-/datum/action/ability/activable/xeno/organic_bomb/use_ability(mob/living/victim)
- . = ..()
- var/datum/action/ability/activable/xeno/refurbish_husk/huskaction = owner.actions_by_path[/datum/action/ability/activable/xeno/refurbish_husk]
- if(length(huskaction.puppets) <= 0)
- owner.balloon_alert(owner, "no puppets")
- return fail_activate()
- if(!istype(victim, /mob/living/carbon/xenomorph/puppet) || !(victim in huskaction.puppets))
- victim.balloon_alert(owner, "not our puppet")
- return fail_activate()
- if(!SEND_SIGNAL(victim, COMSIG_PUPPET_CHANGE_ORDER, PUPPET_SEEK_CLOSEST))
- victim.balloon_alert(owner, "fail")
- return fail_activate()
- RegisterSignal(victim, COMSIG_XENOMORPH_ATTACK_LIVING, PROC_REF(start_exploding))
- RegisterSignal(victim, COMSIG_MOB_DEATH, PROC_REF(detonate))
- addtimer(CALLBACK(src, PROC_REF(detonate), victim), 15 SECONDS)
- add_cooldown()
-
-///asynchronous signal handler for start_exploding_async
-/datum/action/ability/activable/xeno/organic_bomb/proc/start_exploding(mob/living/puppet)
- SIGNAL_HANDLER
- INVOKE_ASYNC(src, PROC_REF(start_exploding_async), puppet)
-
-///makes a puppet start a do_after to dexplode
-/datum/action/ability/activable/xeno/organic_bomb/proc/start_exploding_async(mob/living/puppet)
- puppet.visible_message(span_danger("[puppet] bloats and slowly unfurls its stitched body!"))
- if(do_after(puppet, 1.5 SECONDS, IGNORE_HELD_ITEM, puppet, BUSY_ICON_DANGER))
- detonate(puppet)
-
-///detonates a puppet causing a spray of acid
-/datum/action/ability/activable/xeno/organic_bomb/proc/detonate(mob/living/puppet)
- SIGNAL_HANDLER
- UnregisterSignal(puppet, list(COMSIG_XENOMORPH_ATTACK_LIVING, COMSIG_MOB_DEATH))
- var/turf/our_turf = get_turf(puppet)
- our_turf.visible_message(span_danger("[puppet] ruptures, releasing corrosive acid!"))
- playsound(our_turf, 'sound/bullets/acid_impact1.ogg', 50, 1)
- if(!QDELETED(puppet))
- puppet.gib()
-
- for(var/turf/acid_tile AS in RANGE_TURFS(2, our_turf))
- if(!line_of_sight(our_turf,acid_tile) || isclosedturf(acid_tile))
- continue
- new /obj/effect/temp_visual/acid_splatter(acid_tile) //SFX
- if(!locate(/obj/effect/xenomorph/spray) in acid_tile.contents)
- new /obj/effect/xenomorph/spray(acid_tile, 12 SECONDS, 18)
-// ***************************************
-// *********** Articulate
-// ***************************************
-/datum/action/ability/activable/xeno/articulate
- name = "Articulate"
- action_icon_state = "mimicry"
- desc = "Takes direct control of a Puppet’s vocal chords. Allows you to speak directly through your puppet to the talls."
- cooldown_duration = 10 SECONDS
- target_flags = ABILITY_MOB_TARGET
- ///Whether we should cancel instead of doing the thing when activated
- var/talking = FALSE
- ///our current target
- var/mob/living/carbon/active_target
-
-/datum/action/ability/activable/xeno/articulate/use_ability(mob/living/victim)
- if(talking)
- cancel(owner)
- return fail_activate()
- var/datum/action/ability/activable/xeno/refurbish_husk/huskaction = owner.actions_by_path[/datum/action/ability/activable/xeno/refurbish_husk]
- if(!istype(victim, /mob/living/carbon/xenomorph/puppet) || !(victim in huskaction.puppets))
- victim.balloon_alert(owner, "not our puppet")
- return fail_activate()
- owner.balloon_alert(owner, "channeling voice, move or activate to cancel!")
- active_target = victim
- RegisterSignal(owner, COMSIG_MOB_SAY, PROC_REF(relay_speech))
- RegisterSignal(owner, COMSIG_MOVABLE_MOVED, PROC_REF(cancel))
- RegisterSignal(victim, COMSIG_QDELETING, PROC_REF(cancel))
- talking = TRUE
- add_cooldown()
-
-/datum/action/ability/activable/xeno/articulate/proc/relay_speech(mob/living/carbon/source, arguments)
- SIGNAL_HANDLER
- INVOKE_ASYNC(src, PROC_REF(relay_speech_async), active_target, arguments[SPEECH_MESSAGE])
-
-/datum/action/ability/activable/xeno/articulate/proc/relay_speech_async(mob/living/carbon/target, text)
- target.say(text, language = /datum/language/common, forced = "puppeteer articulate ability")
-
-/datum/action/ability/activable/xeno/articulate/proc/cancel(atom/target)
- SIGNAL_HANDLER
- if(talking)
- owner.balloon_alert(owner, "cancelled!")
- talking = FALSE
- active_target = null
- UnregisterSignal(owner, list(COMSIG_MOB_SAY, COMSIG_MOVABLE_MOVED, COMSIG_QDELETING))
-
-// ***************************************
-// *********** Tendrils (Primordial)
-// ***************************************
-/datum/action/ability/activable/xeno/tendril_patch
- name = "Tendrils"
- action_icon_state = "living_construct"
- desc = "Burrow freshly created tendrils to tangle organics in a 3x3 patch."
- ability_cost = 175
- cooldown_duration = 40 SECONDS
- keybinding_signals = list(
- KEYBINDING_NORMAL = COMSIG_XENOABILITY_TENDRILS,
- )
-
-/datum/action/ability/activable/xeno/tendril_patch/use_ability(atom/movable/victim)
- var/turf/their_turf = get_turf(victim)
- var/mob/living/living_owner = owner
- living_owner.face_atom(victim)
- living_owner.visible_message(span_warning("[living_owner] begins to form biomass and force it into the ground!"))
- if(!do_after(living_owner, 3 SECONDS, IGNORE_HELD_ITEM, victim, BUSY_ICON_DANGER, extra_checks = CALLBACK(living_owner, TYPE_PROC_REF(/mob, break_do_after_checks), list("health" = living_owner.health))))
- return FALSE
- their_turf.visible_message(span_warning("[living_owner]'s tendrils burst out from the ground!"))
- for(var/turf/tile AS in RANGE_TURFS(1, their_turf))
- if(!locate(/obj/effect/tentacle) in tile.contents)
- new /obj/effect/tentacle(tile)
- add_cooldown()
-
-/obj/effect/tentacle
- name = "tendril"
- icon = 'icons/effects/effects.dmi'
- icon_state = "tendril_1"
- layer = BELOW_MOB_LAYER
- plane = GAME_PLANE
- anchored = TRUE
-
-/obj/effect/tentacle/Initialize(mapload)
- . = ..()
- addtimer(CALLBACK(src, PROC_REF(start_grabbing)), 0.4 SECONDS)
-
-/// change our icon state and start a 0.3 second timer to call grab()
-/obj/effect/tentacle/proc/start_grabbing()
- icon_state = "tendril_2"
- addtimer(CALLBACK(src, PROC_REF(grab)), 0.3 SECONDS, TIMER_STOPPABLE)
-
-/// brute damage and paralyze everyone on our tile
-/obj/effect/tentacle/proc/grab()
- for (var/mob/living/victim in loc)
- if (victim.stat == DEAD)
- continue
- if(isxeno(victim))
- continue
- balloon_alert(victim, "tangled!")
- visible_message(span_danger("[src] tangles [victim]!"))
- victim.adjustBruteLoss(10)
- victim.Paralyze(2 SECONDS)
- addtimer(CALLBACK(src, PROC_REF(retract)), 0.3 SECONDS)
-
-/// change our icon to our retracting icon and delete in 0.3 seconds
-/obj/effect/tentacle/proc/retract()
- icon_state = "tendril_3"
- QDEL_IN(src, 0.4 SECONDS)
-
-// ***************************************
-// *********** Blessing
-// ***************************************
-/datum/action/ability/activable/xeno/puppet_blessings
- name = "Bestow Blessing"
- action_icon_state = "emit_pheromones"
- ability_cost = 200
- desc = "Give a permanent upgrade to a puppet."
- cooldown_duration = 30 SECONDS
- use_state_flags = ABILITY_USE_STAGGERED|ABILITY_USE_NOTTURF|ABILITY_USE_BUSY|ABILITY_USE_LYING
- target_flags = ABILITY_MOB_TARGET
- keybinding_signals = list(
- KEYBINDING_NORMAL = COMSIG_XENOABILITY_BESTOWBLESSINGS,
- )
-
-/datum/action/ability/activable/xeno/puppet_blessings/can_use_ability(mob/target, silent = FALSE, override_flags)
- . = ..()
- if(!.)
- return fail_activate()
- if(!istype(target, /mob/living/carbon/xenomorph/puppet))
- owner.balloon_alert(owner, "not a puppet")
- return fail_activate()
- succeed_activate()
-
-/datum/action/ability/activable/xeno/puppet_blessings/use_ability(mob/living/victim)
- var/mob/living/carbon/xenomorph/xeno = owner
- var/choice = show_radial_menu(owner, owner, GLOB.puppeteer_phero_images_list, radius = 35)
- if(!choice)
- return fail_activate()
- var/effect_path
- switch(choice)
- if(AURA_XENO_BLESSFRENZY)
- effect_path = /datum/status_effect/blessing/frenzy
- if(AURA_XENO_BLESSFURY)
- effect_path = /datum/status_effect/blessing/fury
- if(AURA_XENO_BLESSWARDING)
- effect_path = /datum/status_effect/blessing/warding
- if(victim.has_status_effect(effect_path))
- victim.balloon_alert(owner, "already has this blessing!")
- return fail_activate()
- victim.balloon_alert(owner, "[choice]")
- victim.apply_status_effect(effect_path, xeno)
- victim.med_hud_set_status()
- playsound(get_turf(xeno), "alien_drool", 25)
- add_cooldown()
-
-// ***************************************
-// *********** Radial Orders
-// ***************************************
-
-/datum/action/ability/xeno_action/puppeteer_orders_radial
- name = "Give Orders to Puppets"
- action_icon_state = "orders"
- desc = "Give orders to your puppets, altering their behaviour."
- keybinding_signals = list(
- KEYBINDING_NORMAL = COMSIG_XENOABILITY_SENDORDERS_RADIAL,
- )
-
-/datum/action/ability/xeno_action/puppeteer_orders_radial/action_activate(mob/living/victim)
- var/choice = show_radial_menu(owner, owner, GLOB.puppeteer_order_images_list, radius = 35)
- if(!choice)
- return
- if(SEND_SIGNAL(owner, COMSIG_PUPPET_CHANGE_ALL_ORDER, choice))
- owner.balloon_alert(owner, "success")
- switch(choice)
- if(PUPPET_ATTACK)
- owner.visible_message(span_warning("[owner] swiftly manipulates the psychic strings of the puppets, ordering them to attack!"))
- if(PUPPET_RECALL)
- owner.visible_message(span_warning("[owner] quickly manipulates the psychic strings of the puppets, drawing them near!"))
- else
- owner.balloon_alert(owner, "fail")
-
-// ***************************************
-// *********** Attack Order
-// ***************************************
-
-/datum/action/ability/xeno_action/puppeteer_attack_order
- name = "Give Order to Attack"
- desc = "Give your puppets order to attack"
- keybinding_signals = list(
- KEYBINDING_NORMAL = COMSIG_XENOABILITY_ATTACKORDER,
- )
-
-/datum/action/ability/xeno_action/puppeteer_attack_order/action_activate(mob/living/victim)
- var/puppet_attack = PUPPET_ATTACK
- if(SEND_SIGNAL(owner, COMSIG_PUPPET_CHANGE_ALL_ORDER, puppet_attack))
- owner.balloon_alert(owner, "success: attack")
- else
- owner.balloon_alert(owner, "fail")
-
-/datum/action/ability/xeno_action/puppeteer_attack_order/should_show()
- return FALSE
-
-// ***************************************
-// *********** Recall Order
-// ***************************************
-
-/datum/action/ability/xeno_action/puppeteer_recall_order
- name = "Give Order to Recall"
- desc = "Give your puppets order to recall"
- keybinding_signals = list(
- KEYBINDING_NORMAL = COMSIG_XENOABILITY_RECALLORDER,
- )
-
-/datum/action/ability/xeno_action/puppeteer_recall_order/action_activate(mob/living/victim)
- var/puppet_recall = PUPPET_RECALL
- if(SEND_SIGNAL(owner, COMSIG_PUPPET_CHANGE_ALL_ORDER, puppet_recall))
- owner.balloon_alert(owner, "success: recall")
-
-/datum/action/ability/xeno_action/puppeteer_recall_order/should_show()
- return FALSE
-
-
-RU TGMC EDIT*/
diff --git a/code/modules/mob/living/carbon/xenomorph/castes/puppeteer/castedatum_puppeteer.dm b/code/modules/mob/living/carbon/xenomorph/castes/puppeteer/castedatum_puppeteer.dm
deleted file mode 100644
index 6c2970dad80..00000000000
--- a/code/modules/mob/living/carbon/xenomorph/castes/puppeteer/castedatum_puppeteer.dm
+++ /dev/null
@@ -1,84 +0,0 @@
-/*RU TGMC EDIT
-/datum/xeno_caste/puppeteer
- caste_name = "Puppeteer"
- display_name = "Puppeteer"
- upgrade_name = ""
- caste_desc = "An alien creature of terrifying display, it has a tail adorned with needles that drips a strange chemical and elongated claws."
- caste_type_path = /mob/living/carbon/xenomorph/puppeteer
- primordial_message = "The organics will tremble at our swarm. We are legion."
-
- tier = XENO_TIER_TWO
- upgrade = XENO_UPGRADE_BASETYPE
- wound_type = "puppeteer"
- speed = -0.8
- melee_damage = 18
- plasma_max = 750
- plasma_gain = 0
- plasma_regen_limit = 0
- plasma_icon_state = "fury"
- max_health = 365
- //upgrade_threshold = TIER_TWO_THRESHOLD // RUTGMC DELETION
- evolution_threshold = 225
-
- //evolves_to = list(/mob/living/carbon/xenomorph/widow, /mob/living/carbon/xenomorph/warlock) // RUTGMC DELETION, WIDOW DELETION, moved to the other file
- deevolves_to = list(/mob/living/carbon/xenomorph/defender)
- caste_flags = CASTE_INNATE_PLASMA_REGEN|CASTE_PLASMADRAIN_IMMUNE|CASTE_EVOLUTION_ALLOWED
- can_flags = CASTE_CAN_BE_QUEEN_HEALED|CASTE_CAN_BE_LEADER
- caste_traits = null
- soft_armor = list(MELEE = 20, BULLET = 20, LASER = 20, ENERGY = 20, BOMB = 10, BIO = 20, FIRE = 20, ACID = 20)
- minimap_icon = "puppeteer"
- flay_plasma_gain = 100
- max_puppets = 3
- aura_strength = 2.8
-
- actions = list(
- /datum/action/ability/xeno_action/xeno_resting,
- /datum/action/ability/xeno_action/watch_xeno,
- /datum/action/ability/activable/xeno/psydrain/free,
- /datum/action/ability/activable/xeno/flay,
- /datum/action/ability/activable/xeno/pincushion,
- /datum/action/ability/xeno_action/dreadful_presence,
- /datum/action/ability/activable/xeno/refurbish_husk,
- /datum/action/ability/activable/xeno/puppet,
- /datum/action/ability/activable/xeno/organic_bomb,
- /datum/action/ability/xeno_action/puppeteer_attack_order,
- /datum/action/ability/xeno_action/puppeteer_recall_order,
- /datum/action/ability/xeno_action/puppeteer_orders_radial,
- /datum/action/ability/activable/xeno/articulate,
- /datum/action/ability/activable/xeno/puppet_blessings,
- )
-
-/datum/xeno_caste/puppeteer/normal
- upgrade = XENO_UPGRADE_NORMAL
-
-/datum/xeno_caste/puppeteer/primordial
- upgrade_name = "Primordial"
- caste_desc = "Being within mere eyeshot of this hulking monstrosity fills you with a deep, unshakeable sense of unease. You are unsure if you can even harm it."
- upgrade = XENO_UPGRADE_PRIMO
- speed = -0.8
- melee_damage = 18
- plasma_max = 750
- max_health = 385
- soft_armor = list(MELEE = 20, BULLET = 20, LASER = 20, ENERGY = 20, BOMB = 10, BIO = 20, FIRE = 20, ACID = 20)
- max_puppets = 3
-
- actions = list(
- /datum/action/ability/xeno_action/xeno_resting,
- /datum/action/ability/xeno_action/watch_xeno,
- /datum/action/ability/activable/xeno/psydrain/free,
- /datum/action/ability/activable/xeno/flay,
- /datum/action/ability/activable/xeno/pincushion,
- /datum/action/ability/xeno_action/dreadful_presence,
- /datum/action/ability/activable/xeno/refurbish_husk,
- /datum/action/ability/activable/xeno/puppet,
- /datum/action/ability/activable/xeno/organic_bomb,
- /datum/action/ability/activable/xeno/tendril_patch,
- /datum/action/ability/xeno_action/puppeteer_attack_order,
- /datum/action/ability/xeno_action/puppeteer_recall_order,
- /datum/action/ability/xeno_action/puppeteer_orders_radial,
- /datum/action/ability/activable/xeno/articulate,
- /datum/action/ability/activable/xeno/puppet_blessings,
- )
-
- aura_strength = 3
-RU TGMC EDIT*/
diff --git a/code/modules/mob/living/carbon/xenomorph/castes/puppeteer/puppeteer.dm b/code/modules/mob/living/carbon/xenomorph/castes/puppeteer/puppeteer.dm
deleted file mode 100644
index 20f08f48c95..00000000000
--- a/code/modules/mob/living/carbon/xenomorph/castes/puppeteer/puppeteer.dm
+++ /dev/null
@@ -1,29 +0,0 @@
-/*RU TGMC EDIT
-/mob/living/carbon/xenomorph/puppeteer
- caste_base_type = /mob/living/carbon/xenomorph/puppeteer
- name = "Puppeteer"
- desc = "A xenomorph of terrifying display, it has a tail adorned with needles that drips a strange chemical and elongated claws."
- icon = 'icons/Xeno/castes/puppeteer.dmi'
- icon_state = "Puppeteer Running"
- health = 250
- maxHealth = 250
- plasma_stored = 350
- pixel_x = -16
- old_x = -16
- tier = XENO_TIER_TWO
- upgrade = XENO_UPGRADE_NORMAL
- drag_delay = 5 //pulling a big dead xeno is hard
- bubble_icon = "alien"
-
-/mob/living/carbon/xenomorph/puppeteer/Initialize(mapload)
- . = ..()
- GLOB.huds[DATA_HUD_XENO_HEART].add_hud_to(src)
- RegisterSignal(src, COMSIG_XENOMORPH_POSTATTACK_LIVING, PROC_REF(postattack))
-
-/mob/living/carbon/xenomorph/puppeteer/proc/postattack(mob/living/source, mob/living/target, damage)
- SIGNAL_HANDLER
- if(target.stat == DEAD)
- return
- plasma_stored = min(plasma_stored + round(damage / 0.8), xeno_caste.plasma_max)
- SEND_SIGNAL(src, COMSIG_PUPPET_CHANGE_ALL_ORDER, PUPPET_ATTACK, target) //we are on harm intent so it probably means we want to kill the target
-RU TGMC EDIT*/
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/castedatum_queen.dm b/code/modules/mob/living/carbon/xenomorph/castes/queen/castedatum_queen.dm
index d114e8102c7..694f5693b86 100644
--- a/code/modules/mob/living/carbon/xenomorph/castes/queen/castedatum_queen.dm
+++ b/code/modules/mob/living/carbon/xenomorph/castes/queen/castedatum_queen.dm
@@ -26,7 +26,6 @@
sunder_recover = 1.5
// *** Evolution *** //
- //upgrade_threshold = TIER_THREE_THRESHOLD // RUTGMC DELETION
evolve_min_xenos = 8
maximum_active_caste = 1
death_evolution_delay = 5 MINUTES
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/ravager/castedatum_ravager.dm b/code/modules/mob/living/carbon/xenomorph/castes/ravager/castedatum_ravager.dm
index 0bd20765a77..9d867db42a0 100644
--- a/code/modules/mob/living/carbon/xenomorph/castes/ravager/castedatum_ravager.dm
+++ b/code/modules/mob/living/carbon/xenomorph/castes/ravager/castedatum_ravager.dm
@@ -25,8 +25,6 @@
max_health = 350
// *** Evolution *** //
- //upgrade_threshold = TIER_THREE_THRESHOLD // RUTGMC DELETION
-
deevolves_to = /mob/living/carbon/xenomorph/hunter
// *** Flags *** //
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/runner/castedatum_runner.dm b/code/modules/mob/living/carbon/xenomorph/castes/runner/castedatum_runner.dm
index 7ff31375d8e..992b58095bc 100644
--- a/code/modules/mob/living/carbon/xenomorph/castes/runner/castedatum_runner.dm
+++ b/code/modules/mob/living/carbon/xenomorph/castes/runner/castedatum_runner.dm
@@ -29,7 +29,6 @@
// *** Evolution *** //
evolution_threshold = 100
- //upgrade_threshold = TIER_ONE_THRESHOLD // RUTGMC DELETION
evolves_to = list(
/mob/living/carbon/xenomorph/hunter,
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/sentinel/castedatum_sentinel.dm b/code/modules/mob/living/carbon/xenomorph/castes/sentinel/castedatum_sentinel.dm
index 0503db7b2d4..94861c2220a 100644
--- a/code/modules/mob/living/carbon/xenomorph/castes/sentinel/castedatum_sentinel.dm
+++ b/code/modules/mob/living/carbon/xenomorph/castes/sentinel/castedatum_sentinel.dm
@@ -27,7 +27,6 @@
// *** Evolution *** //
evolution_threshold = 100
- //upgrade_threshold = TIER_ONE_THRESHOLD // RUTGMC DELETION
evolves_to = list(/mob/living/carbon/xenomorph/spitter)
diff --git a/code/modules/mob/living/carbon/xenomorph/castes/shrike/castedatum_shrike.dm b/code/modules/mob/living/carbon/xenomorph/castes/shrike/castedatum_shrike.dm
index 8aa04f2ce9f..4a88f5f548c 100644
--- a/code/modules/mob/living/carbon/xenomorph/castes/shrike/castedatum_shrike.dm
+++ b/code/modules/mob/living/carbon/xenomorph/castes/shrike/castedatum_shrike.dm
@@ -24,10 +24,7 @@
max_health = 400
// *** Evolution *** //
- // The only evolution path does not require threshold
- // evolution_threshold = 225
maximum_active_caste = 1
- //upgrade_threshold = TIER_TWO_THRESHOLD // RUTGMC DELETION
evolves_to = list(/mob/living/carbon/xenomorph/queen)
deevolves_to = /mob/living/carbon/xenomorph/drone
diff --git a/code/modules/mob/living/carbon/xenomorph/castes/spiderling/castedatum_spiderling.dm b/code/modules/mob/living/carbon/xenomorph/castes/spiderling/castedatum_spiderling.dm
deleted file mode 100644
index e220cbc53c5..00000000000
--- a/code/modules/mob/living/carbon/xenomorph/castes/spiderling/castedatum_spiderling.dm
+++ /dev/null
@@ -1,39 +0,0 @@
-/* RUTGMC DELETION, WIDOW REMOVAL
-/datum/xeno_caste/spiderling
- caste_name = "spiderling"
- display_name = "spiderling"
- upgrade_name = ""
- caste_desc = "An anthropod xenomorph without any qualms to obey their widow, even if it will never grow up and will face death."
- wound_type = ""
-
- caste_type_path = /mob/living/carbon/xenomorph/spiderling
-
- tier = XENO_TIER_MINION
- upgrade = XENO_UPGRADE_BASETYPE
-
- // *** Melee Attacks *** //
- melee_damage = 8
-
- // *** Speed *** //
- speed = -0.6
-
- // *** Plasma *** //
- plasma_max = 200
- plasma_gain = 1
-
- // *** Health *** //
- max_health = 125
-
- // *** Flags *** //
- caste_flags = CASTE_NOT_IN_BIOSCAN|CASTE_DO_NOT_ANNOUNCE_DEATH|CASTE_DO_NOT_ALERT_LOW_LIFE
-
- // *** Minimap Icon *** //
- minimap_icon = "spiderling"
-
- // *** Defense *** //
- soft_armor = list(MELEE = 15, BULLET = 0, LASER = 5, ENERGY = 0, BOMB = 0, BIO = 0, FIRE = 0, ACID = 0)
-
- actions = list(
- /datum/action/ability/xeno_action/burrow,
- )
-*/
diff --git a/code/modules/mob/living/carbon/xenomorph/castes/spiderling/spiderling.dm b/code/modules/mob/living/carbon/xenomorph/castes/spiderling/spiderling.dm
deleted file mode 100644
index c1952454be3..00000000000
--- a/code/modules/mob/living/carbon/xenomorph/castes/spiderling/spiderling.dm
+++ /dev/null
@@ -1,276 +0,0 @@
-/* RUTGMC DELETION, WIDOW REMOVAL
-#define SPIDERLING_ATTEMPTING_GUARD "spiderling_attempting_guard"
-#define SPIDERLING_NOT_GUARDING "spiderling_not_guarding"
-#define SPIDERLING_GUARDING "spiderling_guarding"
-#define SPIDERLING_ENRAGED "spiderling_enraged"
-#define SPIDERLING_NORMAL "spiderling_normal"
-
-/mob/living/carbon/xenomorph/spiderling
- caste_base_type = /mob/living/carbon/xenomorph/spiderling
- name = "Spiderling"
- desc = "A widow spawn, it chitters angrily without any sense of self-preservation, only to obey the widow's will."
- icon = 'icons/Xeno/Effects.dmi'
- icon_state = "Spiderling Running"
- health = 250
- maxHealth = 250
- plasma_stored = 200
- pixel_x = 0
- old_x = 0
- tier = XENO_TIER_MINION
- upgrade = XENO_UPGRADE_BASETYPE
- pull_speed = -2
- allow_pass_flags = PASS_XENO
- pass_flags = PASS_XENO|PASS_LOW_STRUCTURE
- density = FALSE
- /// The widow that this spiderling belongs to
- var/mob/living/carbon/xenomorph/spidermother
- /// What sprite state this - normal, enraged, guarding? Used for update_icons()
- var/spiderling_state = SPIDERLING_NORMAL
-
-/mob/living/carbon/xenomorph/spiderling/Initialize(mapload, mob/living/carbon/xenomorph/mother)
- . = ..()
- spidermother = mother
- if(spidermother)
- AddComponent(/datum/component/ai_controller, /datum/ai_behavior/spiderling, spidermother)
- transfer_to_hive(spidermother.get_xeno_hivenumber())
- else
- AddComponent(/datum/component/ai_controller, /datum/ai_behavior/xeno)
-
-/mob/living/carbon/xenomorph/spiderling/update_icons(state_change = TRUE)
- . = ..()
- if(state_change)
- if(spiderling_state == SPIDERLING_ENRAGED)
- icon_state = "[icon_state] Enraged"
- if(spiderling_state == SPIDERLING_GUARDING)
- icon_state = "[icon_state] Guarding"
-
-/mob/living/carbon/xenomorph/spiderling/on_death()
- //We QDEL them as cleanup and preventing them from being sold
- QDEL_IN(src, TIME_TO_DISSOLVE)
- return ..()
-
-///If we're covering our widow, any clicks should be transferred to them
-/mob/living/carbon/xenomorph/spiderling/attack_alien(mob/living/carbon/xenomorph/xeno_attacker, damage_amount, damage_type, damage_flag, effects, armor_penetration, isrightclick)
- if(!get_dist(src, spidermother) && isxeno(x))
- spidermother.attack_alien(X, damage_amount, damage_type, damage_flag, effects, armor_penetration, isrightclick)
- return
- return ..()
-
-// ***************************************
-// *********** Spiderling AI Section
-// ***************************************
-/datum/ai_behavior/spiderling
- target_distance = 1
- base_action = ESCORTING_ATOM
- //The atom that will be used in revert_to_default_escort proc, by default this atom is the spiderling's widow
- var/datum/weakref/default_escorted_atom
- //Whether we are currently guarding a crit widow or not
- var/guarding_status = SPIDERLING_NOT_GUARDING
-
-/datum/ai_behavior/spiderling/New(loc, parent_to_assign, escorted_atom, can_heal = FALSE)
- . = ..()
- default_escorted_atom = WEAKREF(escorted_atom)
- RegisterSignals(escorted_atom, list(COMSIG_XENOMORPH_ATTACK_LIVING, COMSIG_XENOMORPH_ATTACK_HOSTILE_XENOMORPH), PROC_REF(go_to_target))
- RegisterSignal(escorted_atom, COMSIG_XENOMORPH_ATTACK_OBJ, PROC_REF(go_to_obj_target))
- RegisterSignal(escorted_atom, COMSIG_SPIDERLING_GUARD, PROC_REF(attempt_guard))
- RegisterSignal(escorted_atom, COMSIG_SPIDERLING_UNGUARD, PROC_REF(attempt_unguard))
- RegisterSignal(escorted_atom, COMSIG_MOB_DEATH, PROC_REF(spiderling_rage))
- RegisterSignal(escorted_atom, COMSIG_LIVING_DO_RESIST, PROC_REF(parent_resist))
- RegisterSignal(escorted_atom, COMSIG_XENOMORPH_RESIN_JELLY_APPLIED, PROC_REF(apply_spiderling_jelly))
- RegisterSignal(escorted_atom, COMSIG_XENOMORPH_REST, PROC_REF(start_resting))
- RegisterSignal(escorted_atom, COMSIG_XENOMORPH_UNREST, PROC_REF(stop_resting))
- RegisterSignal(escorted_atom, COMSIG_ELEMENT_JUMP_STARTED, PROC_REF(do_jump))
- RegisterSignal(escorted_atom, COMSIG_SPIDERLING_MARK, PROC_REF(decide_mark))
- RegisterSignal(escorted_atom, COMSIG_SPIDERLING_RETURN, PROC_REF(revert_to_default_escort))
-
-/// Decides what to do when widow uses spiderling mark ability
-/datum/ai_behavior/spiderling/proc/decide_mark(source, atom/A)
- SIGNAL_HANDLER
- if(!A)
- revert_to_default_escort()
- return
- if(atom_to_walk_to == A)
- return
- escorted_atom = null
- if(ishuman(A))
- INVOKE_ASYNC(src, PROC_REF(triggered_spiderling_rage), source, A)
- return
- if(isobj(A))
- var/obj/obj_target = A
- RegisterSignal(obj_target, COMSIG_QDELETING, PROC_REF(revert_to_default_escort))
- go_to_obj_target(source, A)
- return
-
-/// Sets escorted atom to our pre-defined default escorted atom, which by default is this spiderling's widow, and commands the spiderling to follow it
-/datum/ai_behavior/spiderling/proc/revert_to_default_escort(source)
- SIGNAL_HANDLER
- escorted_atom = default_escorted_atom.resolve()
- change_action(ESCORTING_ATOM, escorted_atom)
-
-/// Signal handler to check if we can attack the obj's that our escorted_atom is attacking
-/datum/ai_behavior/spiderling/proc/go_to_obj_target(source, obj/target)
- SIGNAL_HANDLER
- if(QDELETED(target))
- return
- atom_to_walk_to = target
- change_action(MOVING_TO_ATOM, target)
-
-/// Signal handler to check if we can attack what our escorted_atom is attacking
-/datum/ai_behavior/spiderling/proc/go_to_target(source, mob/living/target)
- SIGNAL_HANDLER
- if(!isliving(target))
- return
- if(target.stat != CONSCIOUS)
- return
- if(mob_parent?.get_xeno_hivenumber() == target.get_xeno_hivenumber())
- return
- atom_to_walk_to = target
- change_action(MOVING_TO_ATOM, target)
-
-///Signal handler to try to attack our target
-/datum/ai_behavior/spiderling/proc/attack_target(datum/source)
- SIGNAL_HANDLER
- if(world.time < mob_parent?.next_move)
- return
- if(Adjacent(atom_to_walk_to))
- return
- if(isliving(atom_to_walk_to))
- var/mob/living/victim = atom_to_walk_to
- if(victim.stat != CONSCIOUS)
- change_action(ESCORTING_ATOM, escorted_atom)
- return
- mob_parent.face_atom(atom_to_walk_to)
- mob_parent.UnarmedAttack(atom_to_walk_to, mob_parent)
-
-/// Check if escorted_atom moves away from the spiderling while it's attacking something, this is to always keep them close to escorted_atom
-/datum/ai_behavior/spiderling/look_for_new_state()
- if(current_action == MOVING_TO_ATOM)
- if(escorted_atom)
- change_action(ESCORTING_ATOM, escorted_atom)
-
-/// Check so that we dont keep attacking our target beyond it's death
-/datum/ai_behavior/spiderling/register_action_signals(action_type)
- if(action_type == MOVING_TO_ATOM)
- RegisterSignal(mob_parent, COMSIG_STATE_MAINTAINED_DISTANCE, PROC_REF(attack_target))
- if(!isobj(atom_to_walk_to))
- RegisterSignals(atom_to_walk_to, list(COMSIG_MOB_DEATH, COMSIG_QDELETING), PROC_REF(look_for_new_state))
- return ..()
-
-/datum/ai_behavior/spiderling/unregister_action_signals(action_type)
- if(action_type == MOVING_TO_ATOM)
- UnregisterSignal(mob_parent, COMSIG_STATE_MAINTAINED_DISTANCE)
- if(!isnull(atom_to_walk_to))
- UnregisterSignal(atom_to_walk_to, list(COMSIG_MOB_DEATH, COMSIG_QDELETING))
- return ..()
-
-/// If the spiderling's mother goes into crit, the spiderlings will stop what they are doing and attempt to shield her
-/datum/ai_behavior/spiderling/proc/attempt_guard()
- SIGNAL_HANDLER
- if(guarding_status == SPIDERLING_NOT_GUARDING) //Nothing to cleanup
- INVOKE_ASYNC(src, PROC_REF(guard_owner))
- return
-
-/// Spiderling's mother woke up from crit; reset stuff back to normal
-/datum/ai_behavior/spiderling/proc/attempt_unguard()
- SIGNAL_HANDLER
- INVOKE_ASYNC(src, PROC_REF(revert_to_default_escort))
- guarding_status = SPIDERLING_NOT_GUARDING
- var/mob/living/carbon/xenomorph/spiderling/X = mob_parent
- X?.spiderling_state = SPIDERLING_NORMAL
- X?.update_icons()
-
-/datum/ai_behavior/spiderling/ai_do_move()
- if((guarding_status == SPIDERLING_ATTEMPTING_GUARD) && (get_dist(mob_parent, atom_to_walk_to) <= 1))
- var/mob/living/carbon/xenomorph/spiderling/X = mob_parent
- if(prob(50))
- X?.emote("hiss")
- guarding_status = SPIDERLING_GUARDING
- var/mob/living/carbon/xenomorph/widow/to_guard = escorted_atom
- to_guard.buckle_mob(X, TRUE, TRUE)
- X?.dir = SOUTH
- return ..()
-
-/// Moves spiderlings to the widow
-/datum/ai_behavior/spiderling/proc/guard_owner()
- var/mob/living/carbon/xenomorph/spiderling/X = mob_parent
- if(QDELETED(X))
- return
- if(prob(50))
- X.emote("roar")
- if(X.spiderling_state != SPIDERLING_ENRAGED)
- X.spiderling_state = SPIDERLING_GUARDING
- X.update_icons()
- distance_to_maintain = 0
- revert_to_default_escort()
- atom_to_walk_to = escorted_atom
- guarding_status = SPIDERLING_ATTEMPTING_GUARD
-
-/// This happens when the spiderlings mother dies, they move faster and will attack any nearby marines
-/datum/ai_behavior/spiderling/proc/spiderling_rage()
- SIGNAL_HANDLER
- escorted_atom = null
- var/mob/living/carbon/xenomorph/spiderling/x = mob_parent
- if(QDELETED(x))
- return
- var/list/mob/living/carbon/human/possible_victims = list()
- for(var/mob/living/victim in get_nearest_target(x, SPIDERLING_RAGE_RANGE))
- if(victim.stat == DEAD)
- continue
- possible_victims += victim
- if(!length(possible_victims))
- kill_parent()
- return
- x.spiderling_state = SPIDERLING_ENRAGED
- x.update_icons()
- // Makes the spiderlings roar at slightly different times so they don't stack their roars
- addtimer(CALLBACK(x, TYPE_PROC_REF(/mob, emote), "roar"), rand(1, 4))
- change_action(MOVING_TO_ATOM, pick(possible_victims))
- addtimer(CALLBACK(src, PROC_REF(kill_parent)), 10 SECONDS)
-
-/// Makes the spiderling roar and then kill themselves after some time
-/datum/ai_behavior/spiderling/proc/triggered_spiderling_rage(mob/M, mob/victim)
- var/mob/living/carbon/xenomorph/spiderling/spiderling_parent = mob_parent
- if(QDELETED(spiderling_parent))
- return
- change_action(MOVING_TO_ATOM, victim)
- spiderling_parent.spiderling_state = SPIDERLING_ENRAGED
- spiderling_parent.update_icons()
- addtimer(CALLBACK(spiderling_parent, TYPE_PROC_REF(/mob, emote), "roar"), rand(1, 4))
- addtimer(CALLBACK(src, PROC_REF(kill_parent)), 15 SECONDS)
-
-///This kills the spiderling
-/datum/ai_behavior/spiderling/proc/kill_parent()
- var/mob/living/carbon/xenomorph/spiderling/spiderling_parent = mob_parent
- spiderling_parent?.death(gibbing = FALSE)
-
-/// resist when widow does
-/datum/ai_behavior/spiderling/proc/parent_resist()
- SIGNAL_HANDLER
- var/mob/living/carbon/xenomorph/spiderling/spiderling_parent = mob_parent
- spiderling_parent?.do_resist()
-
-/// rest when widow does
-/datum/ai_behavior/spiderling/proc/start_resting(mob/source)
- SIGNAL_HANDLER
- var/mob/living/living = mob_parent
- living?.set_resting(TRUE)
-
-/// stop resting when widow does, plus unbuckle all mobs so the widow won't get stuck
-/datum/ai_behavior/spiderling/proc/stop_resting(mob/source)
- SIGNAL_HANDLER
- var/mob/living/living = mob_parent
- living?.set_resting(FALSE)
- source?.unbuckle_all_mobs()
-
-/// Signal handler to make the spiderling jump when widow does
-/datum/ai_behavior/spiderling/proc/do_jump()
- SIGNAL_HANDLER
- var/datum/component/jump/jumpy_spider = mob_parent.GetComponent(/datum/component/jump)
- jumpy_spider?.do_jump(mob_parent)
-
-/// Signal handler to apply resin jelly to the spiderling whenever widow gets it
-/datum/ai_behavior/spiderling/proc/apply_spiderling_jelly()
- SIGNAL_HANDLER
- var/mob/living/carbon/xenomorph/spiderling/beno_to_coat = mob_parent
- beno_to_coat?.apply_status_effect(STATUS_EFFECT_RESIN_JELLY_COATING)
-*/
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/spitter/castedatum_spitter.dm b/code/modules/mob/living/carbon/xenomorph/castes/spitter/castedatum_spitter.dm
index 2c5c94e9e96..7604de92dd2 100644
--- a/code/modules/mob/living/carbon/xenomorph/castes/spitter/castedatum_spitter.dm
+++ b/code/modules/mob/living/carbon/xenomorph/castes/spitter/castedatum_spitter.dm
@@ -23,7 +23,6 @@
// *** Evolution *** //
evolution_threshold = 225
- //upgrade_threshold = TIER_TWO_THRESHOLD // RUTGMC DELETION
evolves_to = list(
/mob/living/carbon/xenomorph/boiler,
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..81e75bc300a 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")
@@ -181,7 +181,7 @@
/obj/effect/xeno/shield
icon = 'icons/Xeno/96x96.dmi'
icon_state = "shield"
- resistance_flags = BANISH_IMMUNE|UNACIDABLE|PLASMACUTTER_IMMUNE
+ resistance_flags = UNACIDABLE|PLASMACUTTER_IMMUNE
max_integrity = 350
layer = ABOVE_MOB_LAYER
///Who created the shield
diff --git a/code/modules/mob/living/carbon/xenomorph/castes/warlock/castedatum_warlock.dm b/code/modules/mob/living/carbon/xenomorph/castes/warlock/castedatum_warlock.dm
index 1c749d8c17e..9c4f6bee6dc 100644
--- a/code/modules/mob/living/carbon/xenomorph/castes/warlock/castedatum_warlock.dm
+++ b/code/modules/mob/living/carbon/xenomorph/castes/warlock/castedatum_warlock.dm
@@ -13,7 +13,6 @@
plasma_max = 1700
plasma_gain = 60
max_health = 375
- //upgrade_threshold = TIER_THREE_THRESHOLD // RUTGMC DELETION
spit_types = list(/datum/ammo/energy/xeno/psy_blast)
deevolves_to = list(/mob/living/carbon/xenomorph/warrior)
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/warrior/castedatum_warrior.dm b/code/modules/mob/living/carbon/xenomorph/castes/warrior/castedatum_warrior.dm
index 5195686ef58..5d357100301 100644
--- a/code/modules/mob/living/carbon/xenomorph/castes/warrior/castedatum_warrior.dm
+++ b/code/modules/mob/living/carbon/xenomorph/castes/warrior/castedatum_warrior.dm
@@ -23,7 +23,6 @@
// *** Evolution *** //
evolution_threshold = 225
- //upgrade_threshold = TIER_TWO_THRESHOLD // RUTGMC DELETION
evolves_to = list(/mob/living/carbon/xenomorph/crusher, /mob/living/carbon/xenomorph/gorger, /mob/living/carbon/xenomorph/warlock, /mob/living/carbon/xenomorph/behemoth, /mob/living/carbon/xenomorph/chimera)
deevolves_to = /mob/living/carbon/xenomorph/defender
diff --git a/code/modules/mob/living/carbon/xenomorph/castes/widow/abilities_widow.dm b/code/modules/mob/living/carbon/xenomorph/castes/widow/abilities_widow.dm
deleted file mode 100644
index e402616164a..00000000000
--- a/code/modules/mob/living/carbon/xenomorph/castes/widow/abilities_widow.dm
+++ /dev/null
@@ -1,478 +0,0 @@
-/* RUTGMC DELETION, WIDOW REMOVAL
-/datum/action/ability/activable/xeno/web_spit
- name = "Web Spit"
- desc = "Spit a web to your target, this causes different effects depending on where you hit. Spitting the head causes the target to be temporarily blind, body and arms will cause the target to be weakened, and legs will snare the target for a brief while."
- action_icon_state = "web_spit"
- ability_cost = 125
- cooldown_duration = 10 SECONDS
- keybinding_signals = list(
- KEYBINDING_NORMAL = COMSIG_XENOABILITY_WEB_SPIT,
- )
-
-/datum/action/ability/activable/xeno/web_spit/use_ability(atom/target)
- var/mob/living/carbon/xenomorph/X = owner
- var/datum/ammo/xeno/web/web_spit = GLOB.ammo_list[/datum/ammo/xeno/web]
- var/obj/projectile/newspit = new /obj/projectile(get_turf(X))
-
- newspit.generate_bullet(web_spit, web_spit.damage * SPIT_UPGRADE_BONUS(X))
- newspit.def_zone = X.get_limbzone_target()
-
- newspit.fire_at(target, X, null, newspit.ammo.max_range)
- succeed_activate()
- add_cooldown()
-
-// ***************************************
-// *********** Leash Ball
-// ***************************************
-
-/datum/action/ability/activable/xeno/leash_ball
- name = "Leash Ball"
- desc = "Spit a huge web ball that snares groups of targets for a brief while."
- action_icon_state = "leash_ball"
- ability_cost = 250
- cooldown_duration = 20 SECONDS
- keybinding_signals = list(
- KEYBINDING_NORMAL = COMSIG_XENOABILITY_LEASH_BALL,
- )
-
-/datum/action/ability/activable/xeno/leash_ball/use_ability(atom/A)
- var/turf/target = get_turf(A)
- var/mob/living/carbon/xenomorph/X = owner
- X.face_atom(target)
- if(!do_after(X, 1 SECONDS, NONE, X, BUSY_ICON_DANGER))
- return fail_activate()
- var/datum/ammo/xeno/leash_ball = GLOB.ammo_list[/datum/ammo/xeno/leash_ball]
- leash_ball.hivenumber = X.hivenumber
- var/obj/projectile/newspit = new (get_turf(X))
-
- newspit.generate_bullet(leash_ball)
- newspit.fire_at(target, X, null, newspit.ammo.max_range)
- succeed_activate()
- add_cooldown()
-
-/obj/structure/xeno/aoe_leash
- name = "Snaring Web"
- icon = 'icons/Xeno/Effects.dmi'
- icon_state = "aoe_leash"
- desc = "Sticky and icky. Destroy it when you are stuck!"
- destroy_sound = "alien_resin_break"
- max_integrity = 75
- layer = ABOVE_ALL_MOB_LAYER
- anchored = TRUE
- allow_pass_flags = NONE
- density = FALSE
- obj_flags = CAN_BE_HIT | PROJ_IGNORE_DENSITY
- /// How long the leash ball lasts untill it dies
- var/leash_life = 10 SECONDS
- /// Radius for how far the leash should affect humans and how far away they may walk
- var/leash_radius = 5
- /// List of beams to be removed on obj_destruction
- var/list/obj/effect/ebeam/beams = list()
- /// List of victims to unregister aoe_leash is destroyed
- var/list/mob/living/carbon/human/leash_victims = list()
-
-/// Humans caught get beamed and registered for proc/check_dist, aoe_leash also gains increased integrity for each caught human
-/obj/structure/xeno/aoe_leash/Initialize(mapload, _hivenumber)
- . = ..()
- for(var/mob/living/carbon/human/victim in GLOB.humans_by_zlevel["[z]"])
- if(get_dist(src, victim) > leash_radius)
- continue
- if(victim.stat == DEAD) /// Add || CONSCIOUS after testing
- continue
- if(HAS_TRAIT(victim, TRAIT_LEASHED))
- continue
- if(!check_path(src, victim, projectile = TRUE))
- continue
- leash_victims += victim
- for(var/mob/living/carbon/human/snared_victim AS in leash_victims)
- ADD_TRAIT(snared_victim, TRAIT_LEASHED, src)
- beams += beam(snared_victim, "beam_web", 'icons/effects/beam.dmi', INFINITY, INFINITY)
- RegisterSignal(snared_victim, COMSIG_MOVABLE_PRE_MOVE, PROC_REF(check_dist))
- if(!length(beams))
- return INITIALIZE_HINT_QDEL
- QDEL_IN(src, leash_life)
-
-/// To remove beams after the leash_ball is destroyed and also unregister all victims
-/obj/structure/xeno/aoe_leash/Destroy()
- for(var/mob/living/carbon/human/victim AS in leash_victims)
- UnregisterSignal(victim, COMSIG_MOVABLE_PRE_MOVE)
- REMOVE_TRAIT(victim, TRAIT_LEASHED, src)
- leash_victims = null
- QDEL_LIST(beams)
- return ..()
-
-/// Humans caught in the aoe_leash will be pulled back if they leave it's radius
-/obj/structure/xeno/aoe_leash/proc/check_dist(datum/leash_victim, atom/newloc)
- SIGNAL_HANDLER
- if(get_dist(newloc, src) >= leash_radius)
- return COMPONENT_MOVABLE_BLOCK_PRE_MOVE
-
-/// This is so that xenos can remove leash balls
-/obj/structure/xeno/aoe_leash/attack_alien(mob/living/carbon/xenomorph/xeno_attacker, damage_amount = X.xeno_caste.melee_damage, damage_type = BRUTE, damage_flag = MELEE, effects = TRUE, armor_penetration = 0, isrightclick = FALSE)
- if(X.status_flags & INCORPOREAL)
- return
- X.visible_message(span_xenonotice("\The [X] starts tearing down \the [src]!"), \
- span_xenonotice("We start to tear down \the [src]."))
- if(!do_after(X, 1 SECONDS, NONE, X, BUSY_ICON_GENERIC) || QDELETED(src))
- return
- X.do_attack_animation(src, ATTACK_EFFECT_CLAW)
- X.visible_message(span_xenonotice("\The [X] tears down \the [src]!"), \
- span_xenonotice("We tear down \the [src]."))
- playsound(src, "alien_resin_break", 25)
- take_damage(max_integrity)
-
-// ***************************************
-// *********** Spiderling Section
-// ***************************************
-
-/datum/action/ability/xeno_action/create_spiderling
- name = "Birth Spiderling"
- desc = "Give birth to a spiderling after a short charge-up. The spiderlings will follow you until death. You can only deploy 5 spiderlings at one time. On alt-use, if any charges of Cannibalise are stored, create a spiderling at no plasma cost or cooldown."
- action_icon_state = "spawn_spiderling"
- ability_cost = 100
- cooldown_duration = 15 SECONDS
- keybinding_signals = list(
- KEYBINDING_NORMAL = COMSIG_XENOABILITY_CREATE_SPIDERLING,
- KEYBINDING_ALTERNATE = COMSIG_XENOABILITY_CREATE_SPIDERLING_USING_CC,
- )
-
- /// List of all our spiderlings
- var/list/mob/living/carbon/xenomorph/spiderling/spiderlings = list()
- /// Current amount of cannibalise charges
- var/cannibalise_charges = 0
-
-/datum/action/ability/xeno_action/create_spiderling/give_action(mob/living/L)
- . = ..()
- var/mob/living/carbon/xenomorph/X = L
- var/max_spiderlings = X?.xeno_caste.max_spiderlings ? X.xeno_caste.max_spiderlings : 5
- desc = "Give birth to a spiderling after a short charge-up. The spiderlings will follow you until death. You can only deploy [max_spiderlings] spiderlings at one time. On alt-use, if any charges of Cannibalise are stored, create a spiderling at no plasma cost or cooldown."
-
-/datum/action/ability/xeno_action/create_spiderling/can_use_action(silent = FALSE, override_flags)
- . = ..()
- if(!.)
- return FALSE
- var/mob/living/carbon/xenomorph/X = owner
- if(length(spiderlings) >= X.xeno_caste.max_spiderlings)
- if(!silent)
- X.balloon_alert(X, "Max Spiderlings")
- return FALSE
-
-/// The action to create spiderlings
-/datum/action/ability/xeno_action/create_spiderling/action_activate()
- . = ..()
- if(!do_after(owner, 0.5 SECONDS, NONE, owner, BUSY_ICON_DANGER))
- return fail_activate()
- add_spiderling()
- succeed_activate()
- add_cooldown()
-
-/datum/action/ability/xeno_action/create_spiderling/alternate_action_activate()
- var/mob/living/carbon/xenomorph/X = owner
- if(cannibalise_charges <= 0)
- X.balloon_alert(X, "No charges remaining!")
- return
- if(length(spiderlings) >= X.xeno_caste.max_spiderlings)
- X.balloon_alert(X, "Max Spiderlings")
- return
- INVOKE_ASYNC(src, PROC_REF(use_cannibalise))
- return COMSIG_KB_ACTIVATED
-
-/// Birth a spiderling and use up a charge of cannibalise
-/datum/action/ability/xeno_action/create_spiderling/proc/use_cannibalise()
- if(!do_after(owner, 0.5 SECONDS, NONE, owner, BUSY_ICON_DANGER))
- return FALSE
- var/mob/living/carbon/xenomorph/X = owner
- if(cannibalise_charges <= 0)
- X.balloon_alert(X, "No charges remaining!")
- return
- if(length(spiderlings) >= X.xeno_caste.max_spiderlings)
- X.balloon_alert(X, "Max Spiderlings")
- return
- add_spiderling()
- cannibalise_charges -= 1
- owner.balloon_alert(owner, "[cannibalise_charges]/3 charges remaining")
-
-/// Adds spiderlings to spiderling list and registers them for death so we can remove them later
-/datum/action/ability/xeno_action/create_spiderling/proc/add_spiderling()
- /// This creates and stores the spiderling so we can reassign the owner for spider swarm and cap how many spiderlings you can have at once
- var/mob/living/carbon/xenomorph/spiderling/new_spiderling = new(owner.loc, owner, owner)
- RegisterSignals(new_spiderling, list(COMSIG_MOB_DEATH, COMSIG_QDELETING), PROC_REF(remove_spiderling))
- spiderlings += new_spiderling
- new_spiderling.pixel_x = rand(-8, 8)
- new_spiderling.pixel_y = rand(-8, 8)
- return TRUE
-
-/// Removes spiderling from spiderling list and unregisters death signal
-/datum/action/ability/xeno_action/create_spiderling/proc/remove_spiderling(datum/source)
- SIGNAL_HANDLER
- spiderlings -= source
- UnregisterSignal(source, list(COMSIG_MOB_DEATH, COMSIG_QDELETING))
-
-// ***************************************
-// *********** Spiderling mark
-// ***************************************
-
-/datum/action/ability/activable/xeno/spiderling_mark
- name = "Spiderling Mark"
- desc = "Send your spawn on a valid target, they will automatically destroy themselves out of sheer fury after 15 seconds."
- action_icon_state = "spiderling_mark"
- ability_cost = 50
- cooldown_duration = 5 SECONDS
- keybinding_signals = list(
- KEYBINDING_NORMAL = COMSIG_XENOABILITY_SPIDERLING_MARK,
- )
-
-/datum/action/ability/activable/xeno/spiderling_mark/use_ability(atom/A)
- . = ..()
- // So the spiderlings can actually attack
- owner.unbuckle_all_mobs(TRUE)
- var/datum/action/ability/xeno_action/create_spiderling/create_spiderling_action = owner.actions_by_path[/datum/action/ability/xeno_action/create_spiderling]
- if(length(create_spiderling_action.spiderlings) <= 0)
- owner.balloon_alert(owner, "No spiderlings")
- return fail_activate()
- if(!isturf(A) && !istype(A, /obj/alien/weeds))
- owner.balloon_alert(owner, "Spiderlings attacking " + A.name)
- else
- for(var/item in A) //Autoaim at humans if weeds or turfs are clicked
- if(!ishuman(item))
- continue
- A = item
- owner.balloon_alert(owner, "Spiderlings attacking " + A.name)
- break
- if(!ishuman(A)) //If no human found, cancel ability
- owner.balloon_alert(owner, "Nothing to attack, cancelled")
- return fail_activate()
-
- succeed_activate()
- SEND_SIGNAL(owner, COMSIG_SPIDERLING_MARK, A)
- add_cooldown()
-
-// ***************************************
-// *********** Burrow
-// ***************************************
-
-/datum/action/ability/xeno_action/burrow
- name = "Burrow"
- desc = "Burrow into the ground, allowing you and your active spiderlings to hide in plain sight. You cannot use abilities, attack nor move while burrowed. Use the ability again to unburrow if you're already burrowed."
- action_icon_state = "burrow"
- ability_cost = 0
- cooldown_duration = 20 SECONDS
- keybinding_signals = list(
- KEYBINDING_NORMAL = COMSIG_XENOABILITY_BURROW,
- )
- use_state_flags = ABILITY_USE_BURROWED
-
-/datum/action/ability/xeno_action/burrow/action_activate()
- . = ..()
- /// We need the list of spiderlings so that we can burrow them
- var/datum/action/ability/xeno_action/create_spiderling/create_spiderling_action = owner.actions_by_path[/datum/action/ability/xeno_action/create_spiderling]
- /// Here we make every single spiderling that we have also burrow and assign a signal so that they unburrow too
- for(var/mob/living/carbon/xenomorph/spiderling/spiderling AS in create_spiderling_action?.spiderlings)
- /// Here we trigger the burrow proc, the registering happens there
- var/datum/action/ability/xeno_action/burrow/spiderling_burrow = spiderling.actions_by_path[/datum/action/ability/xeno_action/burrow]
- spiderling_burrow.xeno_burrow()
- xeno_burrow()
- succeed_activate()
-
-/// Burrow code for xenomorphs
-/datum/action/ability/xeno_action/burrow/proc/xeno_burrow()
- SIGNAL_HANDLER
- var/mob/living/carbon/xenomorph/X = owner
- if(!HAS_TRAIT(X, TRAIT_BURROWED))
- to_chat(X, span_xenowarning("We start burrowing into the ground..."))
- INVOKE_ASYNC(src, PROC_REF(xeno_burrow_doafter))
- return
- UnregisterSignal(X, COMSIG_XENOMORPH_TAKING_DAMAGE)
- ADD_TRAIT(X, TRAIT_NON_FLAMMABLE, initial(name))
- X.soft_armor = X.soft_armor.modifyRating(fire = 100)
- X.hard_armor = X.hard_armor.modifyRating(fire = 100)
- X.mouse_opacity = initial(X.mouse_opacity)
- X.density = TRUE
- X.allow_pass_flags &= ~PASSABLE
- REMOVE_TRAIT(X, TRAIT_IMMOBILE, WIDOW_ABILITY_TRAIT)
- REMOVE_TRAIT(X, TRAIT_BURROWED, WIDOW_ABILITY_TRAIT)
- REMOVE_TRAIT(X, TRAIT_HANDS_BLOCKED, WIDOW_ABILITY_TRAIT)
- X.update_icons()
- add_cooldown()
- owner.unbuckle_all_mobs(TRUE)
-
-/// Called by xeno_burrow only when burrowing
-/datum/action/ability/xeno_action/burrow/proc/xeno_burrow_doafter()
- if(!do_after(owner, 3 SECONDS, NONE, null, BUSY_ICON_DANGER))
- return
- to_chat(owner, span_xenowarning("We are now burrowed, hidden in plain sight and ready to strike."))
- // This part here actually burrows the xeno
- owner.mouse_opacity = MOUSE_OPACITY_TRANSPARENT
- owner.density = FALSE
- owner.allow_pass_flags |= PASSABLE
- // Here we prevent the xeno from moving or attacking or using abilities until they unburrow by clicking the ability
- ADD_TRAIT(owner, TRAIT_IMMOBILE, WIDOW_ABILITY_TRAIT)
- ADD_TRAIT(owner, TRAIT_BURROWED, WIDOW_ABILITY_TRAIT)
- ADD_TRAIT(owner, TRAIT_HANDS_BLOCKED, WIDOW_ABILITY_TRAIT)
- // We register for movement so that we unburrow if bombed
- var/mob/living/carbon/xenomorph/X = owner
- X.soft_armor = X.soft_armor.modifyRating(fire = -100)
- X.hard_armor = X.hard_armor.modifyRating(fire = -100)
- REMOVE_TRAIT(X, TRAIT_NON_FLAMMABLE, initial(name))
- // Update here without waiting for life
- X.update_icons()
- RegisterSignal(X, COMSIG_XENOMORPH_TAKING_DAMAGE, PROC_REF(xeno_burrow))
-
-// ***************************************
-// *********** Attach Spiderlings
-// ***************************************
-/datum/action/ability/xeno_action/attach_spiderlings
- name = "Attach Spiderlings"
- desc = "Attach your current spiderlings to you "
- action_icon_state = "attach_spiderling"
- ability_cost = 0
- cooldown_duration = 0 SECONDS
- keybinding_signals = list(
- KEYBINDING_NORMAL = COMSIG_XENOABILITY_ATTACH_SPIDERLINGS,
- )
- ///the attached spiderlings
- var/list/mob/living/carbon/xenomorph/spiderling/attached_spiderlings = list()
- ///how many times we attempt to attach adjacent spiderligns
- var/attach_attempts = 5
-
-/datum/action/ability/xeno_action/attach_spiderlings/action_activate()
- . = ..()
- if(owner.buckled_mobs)
- /// yeet off all spiderlings if we are carrying any
- owner.unbuckle_all_mobs(TRUE)
- return
- var/mob/living/carbon/xenomorph/widow/X = owner
- var/datum/action/ability/xeno_action/create_spiderling/create_spiderling_action = X.actions_by_path[/datum/action/ability/xeno_action/create_spiderling]
- if(!(length(create_spiderling_action.spiderlings)))
- X.balloon_alert(X, "No spiderlings")
- return fail_activate()
- var/list/mob/living/carbon/xenomorph/spiderling/remaining_spiderlings = create_spiderling_action.spiderlings.Copy()
- // First make the spiderlings stop what they are doing and return to the widow
- for(var/mob/spider in remaining_spiderlings)
- var/datum/component/ai_controller/AI = spider.GetComponent(/datum/component/ai_controller)
- AI?.ai_behavior.change_action(ESCORTING_ATOM, AI.ai_behavior.escorted_atom)
- grab_spiderlings(remaining_spiderlings, attach_attempts)
- succeed_activate()
-
-/// this proc scoops up adjacent spiderlings and then calls ride_widow on them
-/datum/action/ability/xeno_action/attach_spiderlings/proc/grab_spiderlings(list/mob/living/carbon/xenomorph/spiderling/remaining_list, number_of_attempts_left)
- if(number_of_attempts_left <= 0)
- return
- for(var/mob/living/carbon/xenomorph/spiderling/remaining_spiderling AS in remaining_list)
- SEND_SIGNAL(owner, COMSIG_SPIDERLING_RETURN) //So spiderlings move towards the buckle
- if(!owner.Adjacent(remaining_spiderling))
- continue
- remaining_list -= remaining_spiderling
- owner.buckle_mob(remaining_spiderling, TRUE, TRUE, 90, 1,0)
- ADD_TRAIT(remaining_spiderling, TRAIT_IMMOBILE, WIDOW_ABILITY_TRAIT)
- addtimer(CALLBACK(src, PROC_REF(grab_spiderlings), remaining_list, number_of_attempts_left - 1), 1)
-
-// ***************************************
-// *********** Cannibalise
-// ***************************************
-/datum/action/ability/activable/xeno/cannibalise
- name = "Cannibalise Spiderling"
- desc = "Consume one of your children, storing their biomass for future use. If any charges of Cannibalise are stored, alt-use of Birth Spiderling will create one spiderling in exchange for one charge of Cannibalise. Up to three charges of Cannibalise may be stored at once."
- action_icon_state = "cannibalise_spiderling"
- ability_cost = 150
- cooldown_duration = 2 SECONDS
- keybinding_signals = list(
- KEYBINDING_NORMAL = COMSIG_XENOABILITY_CANNIBALISE_SPIDERLING,
- )
-
-/datum/action/ability/activable/xeno/cannibalise/can_use_ability(atom/A, silent = FALSE, override_flags)
- . = ..()
- if(!.)
- return
- if(!owner.Adjacent(A))
- owner.balloon_alert(owner, "Not adjacent")
- return FALSE
- if(!istype(A, /mob/living/carbon/xenomorph/spiderling))
- owner.balloon_alert(owner, "We can't cannibalise this")
- return FALSE
- return TRUE
-
-/datum/action/ability/activable/xeno/cannibalise/use_ability(atom/A)
- if(!do_after(owner, 0.5 SECONDS, NONE, A, BUSY_ICON_DANGER))
- return fail_activate()
-
- var/mob/living/carbon/xenomorph/spiderling/to_cannibalise = A
- QDEL_NULL(to_cannibalise)
- var/datum/action/ability/xeno_action/create_spiderling/create_spiderling_action = owner.actions_by_path[/datum/action/ability/xeno_action/create_spiderling]
- if(!create_spiderling_action)
- return
-
- if(create_spiderling_action.cannibalise_charges < 3)
- create_spiderling_action.cannibalise_charges += 1
- owner.balloon_alert(owner, "[create_spiderling_action.cannibalise_charges]/3 charges")
- else
- owner.balloon_alert(owner, "We're full, no charges gained!")
- playsound(owner.loc, 'sound/items/eatfood.ogg', 15, TRUE)
- succeed_activate()
- add_cooldown()
-
-// ***************************************
-// *********** Web Hook
-// ***************************************
-/datum/action/ability/activable/xeno/web_hook
- name = "Web Hook"
- desc = "Shoot out a web and pull it to traverse forward"
- action_icon_state = "web_hook"
- ability_cost = 200
- cooldown_duration = 10 SECONDS
- keybinding_signals = list(
- KEYBINDING_NORMAL = COMSIG_XENOABILITY_WEB_HOOK,
- )
- //ref to beam for web hook
- var/datum/beam/web_beam
-
-/datum/action/ability/activable/xeno/web_hook/can_use_ability(atom/A)
- . = ..()
- if(!.)
- return
- if(isliving(A))
- owner.balloon_alert(owner, "We can't attach to that")
- return FALSE
- if(!isturf(A))
- return FALSE
- if(get_dist(owner, A) <= WIDOW_WEB_HOOK_MIN_RANGE)
- owner.balloon_alert(owner, "Too close")
- return FALSE
- var/turf/current = get_turf(owner)
- var/turf/target_turf = get_turf(A)
- if(get_dist(current, target_turf) > WIDOW_WEB_HOOK_RANGE)
- owner.balloon_alert(owner, "Too far")
- return FALSE
- current = get_step_towards(current, target_turf)
-
-/datum/action/ability/activable/xeno/web_hook/use_ability(atom/A)
- var/atom/movable/web_hook/web_hook = new (get_turf(owner))
- web_beam = owner.beam(web_hook,"beam_web",'icons/effects/beam.dmi')
- RegisterSignals(web_hook, list(COMSIG_MOVABLE_POST_THROW, COMSIG_MOVABLE_IMPACT), PROC_REF(drag_widow), TRUE)
- web_hook.throw_at(A, WIDOW_WEB_HOOK_RANGE, 3, owner, FALSE)
- succeed_activate()
- add_cooldown()
-
-/// This throws widow wherever the web_hook landed, distance is dependant on if the web_hook hit a wall or just ground
-/datum/action/ability/activable/xeno/web_hook/proc/drag_widow(datum/source, turf/target_turf)
- SIGNAL_HANDLER
- QDEL_NULL(web_beam)
- if(target_turf)
- owner.throw_at(target_turf, WIDOW_WEB_HOOK_RANGE, WIDOW_WEB_HOOK_SPEED, owner, FALSE)
- else
- // we throw widow half the distance if she hits the floor
- owner.throw_at(get_turf(source), WIDOW_WEB_HOOK_RANGE / 2, WIDOW_WEB_HOOK_SPEED, owner, FALSE)
- qdel(source)
- RegisterSignal(owner, COMSIG_MOVABLE_POST_THROW, PROC_REF(delete_beam))
-
-///signal handler to delete the web_hook after we are done draggging owner along
-/datum/action/ability/activable/xeno/web_hook/proc/delete_beam(datum/source)
- SIGNAL_HANDLER
- UnregisterSignal(source, COMSIG_MOVABLE_POST_THROW)
- QDEL_NULL(web_beam)
-
-/// Our web hook that we throw
-/atom/movable/web_hook
- name = "You can't see this"
- invisibility = INVISIBILITY_ABSTRACT
-*/
diff --git a/code/modules/mob/living/carbon/xenomorph/castes/widow/castedatum_widow.dm b/code/modules/mob/living/carbon/xenomorph/castes/widow/castedatum_widow.dm
deleted file mode 100644
index 960ba1ae5d7..00000000000
--- a/code/modules/mob/living/carbon/xenomorph/castes/widow/castedatum_widow.dm
+++ /dev/null
@@ -1,96 +0,0 @@
-/* RUTGMC DELETION, WIDOW REMOVAL
-/datum/xeno_caste/widow
- caste_name = "Widow"
- display_name = "Widow"
- upgrade_name = ""
- caste_desc = "You don't think you've seen a tarantula this giant before."
- caste_type_path = /mob/living/carbon/xenomorph/widow
-
- tier = XENO_TIER_THREE
- upgrade = XENO_UPGRADE_BASETYPE
- wound_type = "widow"
-
- // *** Melee Attacks *** //
- melee_damage = 18
-
- // *** Speed *** //
- speed = -0.5
-
- // *** Plasma *** //
- plasma_max = 600
- plasma_gain = 55
-
- // *** Health *** //
- max_health = 450
-
- // *** Evolution *** //
- upgrade_threshold = TIER_THREE_THRESHOLD
-
- deevolves_to = list(/mob/living/carbon/xenomorph/hunter, /mob/living/carbon/xenomorph/carrier, /mob/living/carbon/xenomorph/puppeteer)
-
- // *** Flags *** //
- caste_flags = CASTE_EVOLUTION_ALLOWED
- can_flags = CASTE_CAN_BE_QUEEN_HEALED|CASTE_CAN_BE_GIVEN_PLASMA|CASTE_CAN_BE_LEADER
- caste_traits = null
-
- // *** Defense *** //
- soft_armor = list(MELEE = 30, BULLET = 30, LASER = 30, ENERGY = 30, BOMB = 15, BIO = 10, FIRE = 15, ACID = 10)
-
- // *** Minimap Icon *** //
- minimap_icon = "widow"
-
- // *** Widow Abilities *** //
- max_spiderlings = 5
-
- // *** Abilities *** ///
- actions = list(
- /datum/action/ability/xeno_action/xeno_resting,
- /datum/action/ability/xeno_action/watch_xeno,
- /datum/action/ability/activable/xeno/psydrain,
- /datum/action/ability/activable/xeno/cocoon,
- /datum/action/ability/activable/xeno/web_spit,
- /datum/action/ability/xeno_action/burrow,
- /datum/action/ability/activable/xeno/leash_ball,
- /datum/action/ability/xeno_action/create_spiderling,
- /datum/action/ability/xeno_action/lay_egg,
- /datum/action/ability/xeno_action/attach_spiderlings,
- /datum/action/ability/activable/xeno/cannibalise,
- /datum/action/ability/activable/xeno/spiderling_mark,
- )
-
-/datum/xeno_caste/widow/on_caste_applied(mob/xenomorph)
- . = ..()
- xenomorph.AddElement(/datum/element/wall_speedup, WIDOW_SPEED_BONUS)
- xenomorph.AddElement(/datum/element/ridable, /datum/component/riding/creature/widow)
-
-/datum/xeno_caste/widow/on_caste_removed(mob/xenomorph)
- . = ..()
- xenomorph.RemoveElement(/datum/element/wall_speedup, WIDOW_SPEED_BONUS)
- xenomorph.RemoveElement(/datum/element/ridable, /datum/component/riding/creature/widow)
-
-/datum/xeno_caste/widow/normal
- upgrade = XENO_UPGRADE_NORMAL
-
-/datum/xeno_caste/widow/primordial
- upgrade_name = "Primordial"
- caste_desc = "At times, life is just like a web. You fall, and a spider called accident, at the center, takes you to hell."
- primordial_message = "We weave the threads of fate that our victims life hangs from."
- upgrade = XENO_UPGRADE_PRIMO
-
- // *** Abilities *** ///
- actions = list(
- /datum/action/ability/xeno_action/xeno_resting,
- /datum/action/ability/xeno_action/watch_xeno,
- /datum/action/ability/activable/xeno/psydrain,
- /datum/action/ability/activable/xeno/cocoon,
- /datum/action/ability/activable/xeno/web_spit,
- /datum/action/ability/xeno_action/burrow,
- /datum/action/ability/activable/xeno/leash_ball,
- /datum/action/ability/xeno_action/create_spiderling,
- /datum/action/ability/xeno_action/lay_egg,
- /datum/action/ability/xeno_action/attach_spiderlings,
- /datum/action/ability/activable/xeno/cannibalise,
- /datum/action/ability/activable/xeno/spiderling_mark,
- /datum/action/ability/activable/xeno/web_hook,
- )
-*/
diff --git a/code/modules/mob/living/carbon/xenomorph/castes/widow/widow.dm b/code/modules/mob/living/carbon/xenomorph/castes/widow/widow.dm
deleted file mode 100644
index c0e6a9530ca..00000000000
--- a/code/modules/mob/living/carbon/xenomorph/castes/widow/widow.dm
+++ /dev/null
@@ -1,66 +0,0 @@
-/* RUTGMC DELETION, WIDOW REMOVAL
-/mob/living/carbon/xenomorph/widow
- caste_base_type = /mob/living/carbon/xenomorph/widow
- name = "Widow"
- desc = "A large arachnid xenomorph, with fangs ready to bear and crawling with many little spiderlings ready to grow."
- icon = 'icons/Xeno/castes/widow.dmi'
- icon_state = "Widow Walking"
- bubble_icon = "alienroyal"
- health = 200
- maxHealth = 200
- plasma_stored = 150
- tier = XENO_TIER_THREE
- upgrade = XENO_UPGRADE_NORMAL
- buckle_flags = CAN_BUCKLE
- pixel_x = -16
- old_x = -16
- max_buckled_mobs = 5
-
-/mob/living/carbon/xenomorph/widow/Initialize(mapload)
- . = ..()
- ADD_TRAIT(src, TRAIT_LIGHT_STEP, XENO_TRAIT)
-
-/mob/living/carbon/xenomorph/widow/buckle_mob(mob/living/buckling_mob, force = FALSE, check_loc = TRUE, lying_buckle = FALSE, hands_needed = 0, target_hands_needed = 0, silent)
- if(!force)
- return FALSE
- return ..()
-
-/mob/living/carbon/xenomorph/widow/post_unbuckle_mob(mob/living/M)
- M.layer = initial(M.layer)
- M.pixel_x = rand(-8, 8)
- M.pixel_y = rand(-8, 8)
-
-
-//Prevents humans unbuckling spiderlings
-/mob/living/carbon/xenomorph/widow/user_unbuckle_mob(mob/living/buckled_mob, mob/user, silent)
- if(ishuman(user))
- return
- return ..()
-
-/mob/living/carbon/xenomorph/widow/set_stat(new_stat)
- . = ..()
- if(new_stat == UNCONSCIOUS)
- unbuckle_all_mobs(TRUE) //If we have spiderlings on us, get them off and ready for guard
- SEND_SIGNAL(src, COMSIG_SPIDERLING_GUARD)
- else if(new_stat == CONSCIOUS)
- unbuckle_all_mobs(TRUE)
- SEND_SIGNAL(src, COMSIG_SPIDERLING_UNGUARD)
-
-/mob/living/carbon/xenomorph/widow/death(gibbing, deathmessage, silent)
- unbuckle_all_mobs(TRUE) //RELEASE THE HORDE
- return ..()
-
-/mob/living/carbon/xenomorph/widow/transfer_to_hive(hivenumber)
- . = ..()
- var/mob/living/carbon/xenomorph/widow/X = src
- var/datum/action/ability/xeno_action/create_spiderling/create_spiderling_action = X.actions_by_path[/datum/action/ability/xeno_action/create_spiderling]
- for(var/mob/living/carbon/xenomorph/spider AS in create_spiderling_action.spiderlings)
- spider.transfer_to_hive(hivenumber)
-
-/mob/living/carbon/xenomorph/widow/on_eord(turf/destination)
- ..()
- var/datum/action/ability/xeno_action/create_spiderling/create_spiderling_action = actions_by_path[/datum/action/ability/xeno_action/create_spiderling]
- for(var/mob/living/carbon/xenomorph/spider AS in create_spiderling_action.spiderlings)
- spider.revive(TRUE)
- spider.forceMove(destination)
-*/
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
deleted file mode 100644
index b086e6e5fb6..00000000000
--- a/code/modules/mob/living/carbon/xenomorph/castes/wraith/abilities_wraith.dm
+++ /dev/null
@@ -1,749 +0,0 @@
-/* RU TGMC EDIT
-GLOBAL_LIST_INIT(wraith_banish_very_short_duration_list, typecacheof(list(
- /obj/vehicle/sealed,
- /obj/structure/barricade,
-)))
-
-// ***************************************
-// *********** Blink
-// ***************************************
-/datum/action/ability/activable/xeno/blink
- name = "Blink"
- action_icon_state = "blink"
- desc = "We teleport ourselves a short distance to a location within line of sight."
- use_state_flags = ABILITY_TURF_TARGET
- ability_cost = 30
- cooldown_duration = 0.5 SECONDS
- keybinding_signals = list(
- KEYBINDING_NORMAL = COMSIG_XENOABILITY_BLINK,
- )
-
-///Check target Blink turf to see if it can be blinked to
-/datum/action/ability/activable/xeno/blink/proc/check_blink_tile(turf/T, ignore_blocker = FALSE, silent = FALSE)
- if(isclosedturf(T) || isspaceturf(T) || isspacearea(T))
- if(!silent)
- to_chat(owner, span_xenowarning("We cannot blink here!"))
- return FALSE
-
- if(!line_of_sight(owner, T)) //Needs to be in line of sight.
- if(!silent)
- to_chat(owner, span_xenowarning("We can't blink without line of sight to our destination!"))
- return FALSE
-
- if(IS_OPAQUE_TURF(T))
- if(!silent)
- to_chat(owner, span_xenowarning("We can't blink into this space without vision!"))
- return FALSE
-
- if(ignore_blocker) //If we don't care about objects occupying the target square, return TRUE; used for checking pathing through transparents
- return TRUE
-
- if(turf_block_check(owner, T, FALSE, TRUE, TRUE, TRUE, TRUE)) //Check if there's anything that blocks us; we only care about Canpass here
- if(!silent)
- to_chat(owner, span_xenowarning("We can't blink here!"))
- return FALSE
-
- var/area/A = get_area(src)
- if(isspacearea(A))
- if(!silent)
- to_chat(owner, span_xenowarning("We cannot blink here!"))
- return FALSE
-
-
- return TRUE
-
-///Check for whether the target turf has dense objects inside
-/datum/action/ability/activable/xeno/blink/proc/check_blink_target_turf_density(turf/T, silent = FALSE)
- for(var/atom/blocker AS in T)
- if(!blocker.CanPass(owner, T))
- if(!silent)
- to_chat(owner, span_xenowarning("We can't blink into a solid object!"))
- return FALSE
-
- return TRUE
-
-/datum/action/ability/activable/xeno/blink/use_ability(atom/A)
- . = ..()
- var/mob/living/carbon/xenomorph/wraith/X = owner
- var/turf/T = X.loc
- var/turf/temp_turf = X.loc
- var/check_distance = min(X.xeno_caste.wraith_blink_range, get_dist(X,A))
- var/list/fully_legal_turfs = list()
-
- for (var/x = 1 to check_distance)
- temp_turf = get_step(T, get_dir(T, A))
- if (!temp_turf)
- break
- if(!check_blink_tile(temp_turf, TRUE, TRUE)) //Verify that the turf is legal; if not we cancel out. We ignore transparent dense objects like windows here for now
- break
- if(check_blink_target_turf_density(temp_turf, TRUE)) //If we could ultimately teleport to this square, it is fully legal; add it to the list
- fully_legal_turfs += temp_turf
- T = temp_turf
-
- check_distance = min(length(fully_legal_turfs), check_distance) //Cap the check distance to the number of fully legal turfs
- T = X.loc //Reset T to be our initial position
- if(check_distance)
- T = fully_legal_turfs[check_distance]
-
- X.face_atom(T) //Face the target so we don't look like an ass
-
- var/cooldown_mod = 1
- var/mob/pulled_target = owner.pulling
- if(pulled_target) //bring the pulled target with us if applicable but at the cost of sharply increasing the next cooldown
-
- if(pulled_target.issamexenohive(X))
- cooldown_mod = X.xeno_caste.wraith_blink_drag_friendly_multiplier
- else
- if(!do_after(owner, 0.5 SECONDS, NONE, owner, BUSY_ICON_HOSTILE)) //Grap-porting hostiles has a slight wind up
- return fail_activate()
- cooldown_mod = X.xeno_caste.wraith_blink_drag_nonfriendly_living_multiplier
- if(ishuman(pulled_target))
- var/mob/living/carbon/human/H = pulled_target
- if(H.stat == UNCONSCIOUS) //Apply critdrag damage as if they were quickly pulled the same distance
- var/critdamage = HUMAN_CRITDRAG_OXYLOSS * get_dist(H.loc, T)
- if(!H.adjustOxyLoss(critdamage))
- H.adjustBruteLoss(critdamage)
-
- to_chat(X, span_xenodanger("We bring [pulled_target] with us. We won't be ready to blink again for [cooldown_duration * cooldown_mod * 0.1] seconds due to the strain of doing so."))
-
- teleport_debuff_aoe(X) //Debuff when we vanish
-
- if(pulled_target) //Yes, duplicate check because otherwise we end up with the initial teleport debuff AoE happening prior to the wind up which looks really bad and is actually exploitable via deliberate do after cancels
- pulled_target.forceMove(T) //Teleport to our target turf
-
- X.forceMove(T) //Teleport to our target turf
- teleport_debuff_aoe(X) //Debuff when we reappear
-
- succeed_activate()
- add_cooldown(cooldown_duration * cooldown_mod)
-
- GLOB.round_statistics.wraith_blinks++
- SSblackbox.record_feedback("tally", "round_statistics", 1, "wraith_blinks") //Statistics
-
-///Called by many of the Wraith's teleportation effects
-/datum/action/ability/activable/xeno/proc/teleport_debuff_aoe(atom/movable/teleporter, silent = FALSE)
- var/mob/living/carbon/xenomorph/ghost = owner
-
- if(!silent) //Sound effects
- playsound(teleporter, 'sound/effects/EMPulse.ogg', 25, 1) //Sound at the location we are arriving at
-
- new /obj/effect/temp_visual/blink_portal(get_turf(teleporter))
-
- new /obj/effect/temp_visual/wraith_warp(get_turf(teleporter))
-
- for(var/mob/living/living_target in range(1, teleporter.loc))
-
- if(living_target.stat == DEAD)
- continue
-
- if(isxeno(living_target))
- var/mob/living/carbon/xenomorph/X = living_target
- if(X.issamexenohive(ghost)) //No friendly fire
- continue
-
- living_target.adjust_stagger(WRAITH_TELEPORT_DEBUFF_STAGGER_STACKS)
- living_target.add_slowdown(WRAITH_TELEPORT_DEBUFF_SLOWDOWN_STACKS)
- to_chat(living_target, span_warning("You feel nauseous as reality warps around you!"))
-
-/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)
- return ..()
-
-// ***************************************
-// *********** Banish
-// ***************************************
-/datum/action/ability/activable/xeno/banish
- name = "Banish"
- action_icon_state = "Banish"
- desc = "We banish a target object or creature within line of sight to nullspace for a short duration. Can target onself and allies. Non-friendlies are banished for half as long."
- use_state_flags = ABILITY_TARGET_SELF
- ability_cost = 50
- cooldown_duration = 20 SECONDS
- keybinding_signals = list(
- KEYBINDING_NORMAL = COMSIG_XENOABILITY_BANISH,
- )
- ///Target we've banished
- var/atom/movable/banishment_target = null
- ///SFX indicating the banished target's position
- var/obj/effect/temp_visual/banishment_portal/portal = null
- ///Backup coordinates to teleport the banished to, in case the portal gets destroyed (shuttles!!)
- var/list/backup_coordinates = list(0,0,0)
- /// living mobs in the banished object so we can check they didnt get ejected
- var/list/mob/living/contained_living = list()
- ///The timer ID of any Banish currently active
- var/banish_duration_timer_id
- ///Phantom zone reserved area
- var/datum/turf_reservation/reserved_area
- /// How far can you banish
- var/range = 3
-
-/datum/action/ability/activable/xeno/banish/Destroy()
- QDEL_NULL(reserved_area) //clean up
- return ..()
-
-/datum/action/ability/activable/xeno/banish/can_use_ability(atom/A, silent = FALSE, override_flags)
- . = ..()
-
- if(!ismovableatom(A) || iseffect(A) || istype(A, /obj/alien) || CHECK_BITFIELD(A.resistance_flags, INDESTRUCTIBLE) || CHECK_BITFIELD(A.resistance_flags, BANISH_IMMUNE)) //Cannot banish non-movables/things that are supposed to be invul; also we ignore effects
- if(!silent)
- to_chat(owner, span_xenowarning("We cannot banish this!"))
- return FALSE
-
- if(HAS_TRAIT(A, TRAIT_TIME_SHIFTED))
- to_chat(owner, span_xenowarning("That target is already affected by a time manipulation effect!"))
- return
-
- var/distance = get_dist(owner, A)
- if(distance > range) //Needs to be in range.
- if(!silent)
- to_chat(owner, span_xenowarning("Our target is too far away! It must be [distance - range] tiles closer!"))
- return FALSE
-
- if(!line_of_sight(owner, A, ignore_target_opacity = TRUE)) //Needs to be in line of sight.
- if(!silent)
- to_chat(owner, span_xenowarning("We can't banish without line of sight to our target!"))
- return FALSE
-
-
-/datum/action/ability/activable/xeno/banish/use_ability(atom/movable/A)
- . = ..()
- var/mob/living/carbon/xenomorph/wraith/ghost = owner
- var/banished_turf = get_turf(A) //Set the banishment turf.
- banishment_target = A //Set the banishment target
- backup_coordinates[1] = banishment_target.x //Set up backup coordinates in case banish portal gets destroyed
- backup_coordinates[2] = banishment_target.y
- backup_coordinates[3] = banishment_target.z
-
- ghost.face_atom(A) //Face the target so we don't look like an ass
-
- teleport_debuff_aoe(banishment_target) //Debuff when we disappear
- portal = new /obj/effect/temp_visual/banishment_portal(banished_turf)
- banishment_target.resistance_flags = RESIST_ALL
-
- if(isliving(A))
- var/mob/living/stasis_target = banishment_target
- stasis_target.apply_status_effect(/datum/status_effect/incapacitating/unconscious) //Force the target to KO
- stasis_target.notransform = TRUE //Stasis
- stasis_target.overlay_fullscreen("banish", /atom/movable/screen/fullscreen/blind) //Force the blind overlay
-
- if(!reserved_area) //If we don't have a reserved area, set one
- reserved_area = SSmapping.RequestBlockReservation(3,3, SSmapping.transit.z_value, /datum/turf_reservation/banish)
- if(!reserved_area) //If we *still* don't have a reserved area we've got a problem
- CRASH("failed to reserve an area for [owner]'s Banish.")
-
- var/turf/target_turf = reserved_area.reserved_turfs[5]
- new /area/arrival(target_turf) //So we don't get instagibbed from the space area
-
- if(isxeno(banishment_target)) //If we're a xeno, disgorge all vored contents
- var/mob/living/carbon/xenomorph/xeno_target = banishment_target
- xeno_target.eject_victim()
-
- for(var/mob/living/living_contents in banishment_target.GetAllContents()) //Safety measure so living mobs inside the target don't get lost in Brazilspace forever
- contained_living += living_contents
- living_contents.apply_status_effect(/datum/status_effect/incapacitating/unconscious)
- living_contents.notransform = TRUE
- living_contents.overlay_fullscreen("banish", /atom/movable/screen/fullscreen/blind)
-
- banishment_target.forceMove(target_turf)
-
- var/duration = ghost.xeno_caste.wraith_banish_base_duration //Set the duration
-
- portal.add_filter("banish_portal_1", 3, list("type" = "motion_blur", 0, 0)) //Cool filter appear
- portal.add_filter("banish_portal_2", 3, list("type" = "motion_blur", 0, 0)) //Cool filter appear
- animate(portal.get_filter("banish_portal_1"), x = 20*rand() - 10, y = 20*rand() - 10, time = 0.5 SECONDS, loop = -1)
- animate(portal.get_filter("banish_portal_2"), x = 20*rand() - 10, y = 20*rand() - 10, time = 0.5 SECONDS, loop = -1)
-
- var/cooldown_mod = 1
- var/plasma_mod = 1
- if(isliving(banishment_target) && !(banishment_target.issamexenohive(ghost))) //We halve the max duration for living non-allies
- duration *= WRAITH_BANISH_NONFRIENDLY_LIVING_MULTIPLIER
- else if(is_type_in_typecache(banishment_target, GLOB.wraith_banish_very_short_duration_list)) //Barricades should only be gone long enough to admit an infiltrator xeno or two; one way.
- duration *= WRAITH_BANISH_VERY_SHORT_MULTIPLIER
- else
- cooldown_mod = 0.6 //40% cooldown reduction if used on non-hostile, non-blacklisted targets.
- plasma_mod = 0.4 //60% plasma cost reduction if used on non-hostile, non-blacklisted targets.
-
- banishment_target.visible_message(span_warning("Space abruptly twists and warps around [banishment_target] as it suddenly vanishes!"), \
- span_highdanger("The world around you reels, reality seeming to twist and tear until you find yourself trapped in a forsaken void beyond space and time."))
- playsound(banished_turf, 'sound/weapons/emitter2.ogg', 50, 1) //this isn't quiet
-
- to_chat(ghost,span_xenodanger("We have banished [banishment_target] to nullspace for [duration * 0.1] seconds."))
- log_attack("[key_name(ghost)] has banished [key_name(banishment_target)] for [duration * 0.1] seconds at [AREACOORD(banishment_target)]")
-
- addtimer(CALLBACK(src, PROC_REF(banish_warning)), duration * 0.7) //Warn when Banish is about to end
- banish_duration_timer_id = addtimer(CALLBACK(src, PROC_REF(banish_deactivate)), duration, TIMER_STOPPABLE) //store the timer ID
-
- succeed_activate(ability_cost * plasma_mod)
- add_cooldown(cooldown_duration * cooldown_mod)
-
- GLOB.round_statistics.wraith_banishes++
- SSblackbox.record_feedback("tally", "round_statistics", 1, "wraith_banishes") //Statistics
-
-///Warns the user when Banish's duration is about to lapse.
-/datum/action/ability/activable/xeno/banish/proc/banish_warning()
-
- if(!banishment_target)
- 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)
-
-///Ends the effect of the Banish ability
-/datum/action/ability/activable/xeno/banish/proc/banish_deactivate()
- SIGNAL_HANDLER
- if(QDELETED(banishment_target))
- return
- var/turf/return_turf = get_turf(portal)
- if(!return_turf)
- return_turf = locate(backup_coordinates[1], backup_coordinates[2], backup_coordinates[3])
- banishment_target.resistance_flags = initial(banishment_target.resistance_flags)
- banishment_target.status_flags = initial(banishment_target.status_flags) //Remove stasis and temp invulerability
- banishment_target.forceMove(return_turf)
-
- var/list/all_contents = banishment_target.GetAllContents()
- for(var/mob/living/living_contents AS in contained_living)
- if(QDELETED(living_contents))
- continue
- living_contents.remove_status_effect(/datum/status_effect/incapacitating/unconscious)
- living_contents.notransform = initial(living_contents.notransform)
- living_contents.clear_fullscreen("banish")
- if(living_contents in all_contents)
- continue //if it is still inside then it is not stranded and we dont care
- living_contents.forceMove(return_turf)
- contained_living.Cut()
-
- teleport_debuff_aoe(banishment_target)
- banishment_target.add_filter("wraith_banishment_filter", 3, list("type" = "blur", 5))
- addtimer(CALLBACK(banishment_target, TYPE_PROC_REF(/atom, remove_filter), "wraith_banishment_filter"), 1 SECONDS)
-
- if(isliving(banishment_target))
- var/mob/living/living_target = banishment_target
- living_target = banishment_target
- living_target.remove_status_effect(/datum/status_effect/incapacitating/unconscious)
- living_target.notransform = initial(living_target.notransform)
- living_target.clear_fullscreen("banish")
-
- banishment_target.visible_message(span_warning("[banishment_target.name] abruptly reappears!"), \
- span_warning("You suddenly reappear back in what you believe to be reality."))
-
- to_chat(owner, span_highdanger("Our target [banishment_target] has returned to reality at [AREACOORD_NO_Z(banishment_target)]")) //Always alert the Wraith
- log_attack("[key_name(owner)] has unbanished [key_name(banishment_target)] at [AREACOORD(banishment_target)]")
-
- QDEL_NULL(portal) //Eliminate the Brazil portal if we need to
-
- banishment_target = null
-
- return TRUE //For the recall sub-ability
-
-/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)
- return ..()
-
-// ***************************************
-// *********** Recall
-// ***************************************
-/datum/action/ability/xeno_action/recall
- name = "Recall"
- action_icon_state = "Recall"
- desc = "We recall a target we've banished back from the depths of nullspace."
- use_state_flags = ABILITY_USE_NOTTURF|ABILITY_USE_CLOSEDTURF|ABILITY_USE_STAGGERED|ABILITY_USE_INCAP|ABILITY_USE_LYING //So we can recall ourselves from nether Brazil
- cooldown_duration = 1 SECONDS //Token for anti-spam
- keybinding_signals = list(
- KEYBINDING_NORMAL = COMSIG_XENOABILITY_RECALL,
- )
-
-/datum/action/ability/xeno_action/recall/can_use_action(silent = FALSE, override_flags)
- . = ..()
-
- var/datum/action/ability/activable/xeno/banish/banish_check = owner.actions_by_path[/datum/action/ability/activable/xeno/banish]
- if(!banish_check) //Mainly for when we transition on upgrading
- return FALSE
-
- if(!banish_check.banishment_target)
- if(!silent)
- to_chat(owner,span_xenodanger("We have no targets banished!"))
- return FALSE
-
-
-/datum/action/ability/xeno_action/recall/action_activate()
- . = ..()
- var/datum/action/ability/activable/xeno/banish/banish_check = owner.actions_by_path[/datum/action/ability/activable/xeno/banish]
- banish_check.banish_deactivate()
- succeed_activate()
- add_cooldown()
-
-///Return TRUE if we have a block, return FALSE otherwise
-/proc/turf_block_check(atom/subject, atom/target, ignore_can_pass = FALSE, ignore_density = FALSE, ignore_closed_turf = FALSE, ignore_invulnerable = FALSE, ignore_objects = FALSE, ignore_mobs = FALSE, ignore_space = FALSE)
- var/turf/T = get_turf(target)
- if(isspaceturf(T) && !ignore_space)
- return TRUE
- if(isclosedturf(T) && !ignore_closed_turf) //If we care about closed turfs
- return TRUE
- for(var/atom/blocker AS in T)
- if((blocker.flags_atom & ON_BORDER) || blocker == subject) //If they're a border entity or our subject, we don't care
- continue
- if(!blocker.CanPass(subject, T) && !ignore_can_pass) //If the subject atom can't pass and we care about that, we have a block
- return TRUE
- if(!blocker.density) //Check if we're dense
- continue
- if(!ignore_density) //If we care about all dense atoms or only certain types of dense atoms
- return TRUE
- if((blocker.resistance_flags & INDESTRUCTIBLE) && !ignore_invulnerable) //If we care about dense invulnerable objects
- return TRUE
- if(isobj(blocker) && !ignore_objects) //If we care about dense objects
- var/obj/obj_blocker = blocker
- if(!isstructure(obj_blocker)) //If it's not a structure and we care about objects, we have a block
- return TRUE
- var/obj/structure/blocker_structure = obj_blocker
- if(!blocker_structure.climbable) //If it's a structure and can't be climbed, we have a block
- return TRUE
- if(ismob(blocker) && !ignore_mobs) //If we care about mobs
- return TRUE
-
- return FALSE
-
-/datum/action/ability/xeno_action/timestop
- name = "Time stop"
- action_icon_state = "time_stop"
- desc = "Freezes bullets in their course, and they will start to move again only after a certain time"
- ability_cost = 100
- cooldown_duration = 1 MINUTES
- keybinding_signals = list(
- KEYBINDING_NORMAL = COMSIG_XENOABILITY_TIMESTOP,
- )
- ///The range of the ability
- var/range = 1
- ///How long is the bullet freeze staying
- var/duration = 7 SECONDS
-
-/datum/action/ability/xeno_action/timestop/action_activate()
- . = ..()
- var/list/turf/turfs_affected = list()
- var/turf/central_turf = get_turf(owner)
- for(var/turf/affected_turf in view(range, central_turf))
- ADD_TRAIT(affected_turf, TRAIT_TURF_BULLET_MANIPULATION, REF(src))
- turfs_affected += affected_turf
- affected_turf.add_filter("wraith_magic", 2, drop_shadow_filter(color = "#04080FAA", size = -10))
- playsound(owner, 'sound/magic/timeparadox2.ogg', 50, TRUE)
- succeed_activate()
- add_cooldown()
- new /obj/effect/overlay/temp/timestop_effect(central_turf, duration)
- addtimer(CALLBACK(src, PROC_REF(remove_bullet_freeze), turfs_affected, central_turf), duration)
- addtimer(CALLBACK(src, PROC_REF(play_sound_stop)), duration - 3 SECONDS)
-
-///Remove the bullet freeze effect on affected turfs
-/datum/action/ability/xeno_action/timestop/proc/remove_bullet_freeze(list/turf/turfs_affected, turf/central_turfA)
- for(var/turf/affected_turf AS in turfs_affected)
- REMOVE_TRAIT(affected_turf, TRAIT_TURF_BULLET_MANIPULATION, REF(src))
- if(HAS_TRAIT(affected_turf, TRAIT_TURF_BULLET_MANIPULATION))
- continue
- SEND_SIGNAL(affected_turf, COMSIG_TURF_RESUME_PROJECTILE_MOVE)
- affected_turf.remove_filter("wraith_magic")
-
-///Play the end ability sound
-/datum/action/ability/xeno_action/timestop/proc/play_sound_stop()
- playsound(owner, 'sound/magic/timeparadox2.ogg', 50, TRUE, frequency = -1)
-
-/datum/action/ability/xeno_action/portal
- name = "Portal"
- action_icon_state = "portal"
- desc = "Place a portal on your location. You can travel from portal to portal. Left click to create portal one, right click to create portal two"
- ability_cost = 50
- cooldown_duration = 5 SECONDS
- keybinding_signals = list(
- KEYBINDING_NORMAL = COMSIG_XENOABILITY_PORTAL,
- KEYBINDING_ALTERNATE = COMSIG_XENOABILITY_PORTAL_ALTERNATE,
- )
- /// How far can you link two portals
- var/range = 20
- /// The first portal
- var/obj/effect/wraith_portal/portal_one
- /// The second portal
- var/obj/effect/wraith_portal/portal_two
-
-/datum/action/ability/xeno_action/portal/remove_action(mob/M)
- clean_portals()
- return ..()
-
-/// Destroy the portals when the wraith is no longer supporting them
-/datum/action/ability/xeno_action/portal/proc/clean_portals()
- SIGNAL_HANDLER
-
- QDEL_NULL(portal_one)
- QDEL_NULL(portal_two)
-
-/datum/action/ability/xeno_action/portal/give_action(mob/M)
- . = ..()
- RegisterSignal(M, COMSIG_MOB_DEATH, PROC_REF(clean_portals))
-
-/datum/action/ability/xeno_action/portal/can_use_action(silent, override_flags)
- if(locate(/obj/effect/wraith_portal) in get_turf(owner))
- if(!silent)
- to_chat(owner, span_xenowarning("There is already a portal here!"))
- return FALSE
- var/area/area = get_area(owner)
- if(area.flags_area & MARINE_BASE)
- if(!silent)
- to_chat(owner, span_xenowarning("You cannot portal here!"))
- return FALSE
- return ..()
-
-/datum/action/ability/xeno_action/portal/action_activate()
- . = ..()
- qdel(portal_one)
- portal_one = new(get_turf(owner))
- succeed_activate()
- add_cooldown()
- playsound(owner.loc, 'sound/effects/portal_opening.ogg', 20)
- if(portal_two)
- link_portals()
-
-/datum/action/ability/xeno_action/portal/alternate_action_activate()
- if(!can_use_action())
- return
- qdel(portal_two)
- portal_two = new(get_turf(owner), TRUE)
- succeed_activate()
- add_cooldown()
- playsound(owner.loc, 'sound/effects/portal_opening.ogg', 20)
- if(portal_one)
- link_portals()
-
-/// Link the two portals if possible
-/datum/action/ability/xeno_action/portal/proc/link_portals()
- if(get_dist(portal_one, portal_two) > range || portal_one.z != portal_two.z)
- to_chat(owner, span_xenowarning("The other portal is too far away, they cannot link!"))
- return
- portal_two.link_portal(portal_one)
- portal_one.link_portal(portal_two)
-
-/obj/effect/wraith_portal
- icon_state = "portal"
- anchored = TRUE
- opacity = FALSE
- vis_flags = VIS_HIDE
- resistance_flags = UNACIDABLE | CRUSHER_IMMUNE | BANISH_IMMUNE
- /// Visual object for handling the viscontents
- var/obj/effect/portal_effect/portal_visuals
- /// The linked portal
- var/obj/effect/wraith_portal/linked_portal
- COOLDOWN_DECLARE(portal_cooldown)
-
-/obj/effect/wraith_portal/Initialize(mapload, portal_is_yellow = FALSE)
- . = ..()
- var/static/list/connections = list(
- COMSIG_ATOM_ENTERED = PROC_REF(teleport_atom)
- )
- if(portal_is_yellow)
- icon_state = "portal1"
- AddElement(/datum/element/connect_loc, connections)
- portal_visuals = new
- portal_visuals.layer = layer + 0.01
- vis_contents += portal_visuals
- add_filter("border_smoother", 1, gauss_blur_filter(1))
-
-/obj/effect/wraith_portal/Destroy()
- linked_portal?.unlink()
- linked_portal = null
- REMOVE_TRAIT(loc, TRAIT_TURF_BULLET_MANIPULATION, PORTAL_TRAIT)
- vis_contents -= portal_visuals
- QDEL_NULL(portal_visuals)
- return ..()
-
-/obj/effect/wraith_portal/attack_ghost(mob/dead/observer/user)
- . = ..()
- if(!linked_portal)
- return
- user.forceMove(get_turf(linked_portal))
-
-/// Link two portals
-/obj/effect/wraith_portal/proc/link_portal(obj/effect/wraith_portal/portal_to_link)
- linked_portal = portal_to_link
- ADD_TRAIT(loc, TRAIT_TURF_BULLET_MANIPULATION, PORTAL_TRAIT)
- RegisterSignal(loc, COMSIG_TURF_PROJECTILE_MANIPULATED, PROC_REF(teleport_bullet))
- portal_visuals.setup_visuals(portal_to_link)
-
-/// Unlink the portal
-/obj/effect/wraith_portal/proc/unlink()
- linked_portal = null
- REMOVE_TRAIT(loc, TRAIT_TURF_BULLET_MANIPULATION, PORTAL_TRAIT)
- UnregisterSignal(loc, COMSIG_TURF_PROJECTILE_MANIPULATED)
- portal_visuals.reset_visuals()
-
-/// Signal handler teleporting crossing atoms
-/obj/effect/wraith_portal/proc/teleport_atom/(datum/source, atom/movable/crosser)
- SIGNAL_HANDLER
- if(!linked_portal || !COOLDOWN_CHECK(src, portal_cooldown) || crosser.anchored || (crosser.resistance_flags & PORTAL_IMMUNE))
- return
- COOLDOWN_START(linked_portal, portal_cooldown, 1)
- crosser.pass_flags &= ~PASS_MOB
- RegisterSignal(crosser, COMSIG_MOVABLE_MOVED, PROC_REF(do_teleport_atom))
- playsound(loc, 'sound/effects/portal.ogg', 20)
-
-/// Signal handler to teleport the crossing atom when its move is done
-/obj/effect/wraith_portal/proc/do_teleport_atom(atom/movable/crosser)
- SIGNAL_HANDLER
- for(var/mob/rider AS in crosser.buckled_mobs)
- if(ishuman(rider))
- crosser.unbuckle_mob(rider)
- if(crosser.throwing)
- crosser.throw_source = get_turf(linked_portal)
- crosser.Move(get_turf(linked_portal), crosser.dir)
- UnregisterSignal(crosser, COMSIG_MOVABLE_MOVED)
-
-/// Signal handler for teleporting a crossing bullet
-/obj/effect/wraith_portal/proc/teleport_bullet(datum/source, obj/projectile/bullet)
- SIGNAL_HANDLER
- playsound(loc, 'sound/effects/portal.ogg', 20)
- var/new_range = bullet.proj_max_range - bullet.distance_travelled
- if(new_range <= 0)
- bullet.loc = get_turf(linked_portal)
- bullet.ammo.do_at_max_range(bullet)
- qdel(bullet)
- return
- if(!linked_portal) // A lot of racing conditions here
- return
- bullet.fire_at(shooter = bullet.firer, range = max(bullet.proj_max_range - bullet.distance_travelled, 0), angle = bullet.dir_angle, recursivity = TRUE, loc_override = get_turf(linked_portal))
-
-/obj/effect/portal_effect
- appearance_flags = KEEP_TOGETHER|TILE_BOUND|PIXEL_SCALE
- mouse_opacity = MOUSE_OPACITY_TRANSPARENT
- vis_flags = VIS_INHERIT_ID
- layer = DOOR_OPEN_LAYER
- ///turf destination to display
- var/turf/our_destination
-
-/obj/effect/portal_effect/proc/setup_visuals(atom/target)
- our_destination = get_turf(target)
- update_portal_filters()
-
-/obj/effect/portal_effect/proc/reset_visuals()
- our_destination = null
- update_portal_filters()
-
-/obj/effect/portal_effect/proc/update_portal_filters()
- clear_filters()
- vis_contents = null
-
- if(!our_destination)
- return
- var/static/icon/portal_mask = icon('icons/effects/effects.dmi', "portal_mask")
- add_filter("portal_alpha", 1, list("type" = "alpha", "icon" = portal_mask))
- add_filter("portal_blur", 1, list("type" = "blur", "size" = 0.5))
- add_filter("portal_ripple", 1, list("type" = "ripple", "size" = 2, "radius" = 1, "falloff" = 1, "y" = 7))
-
- animate(get_filter("portal_ripple"), time = 1.3 SECONDS, loop = -1, easing = LINEAR_EASING, radius = 32)
-
- vis_contents += our_destination
-/obj/effect/wraith_portal/ex_act()
- qdel(src)
-
-/datum/action/ability/activable/xeno/rewind
- name = "Time Shift"
- action_icon_state = "rewind"
- desc = "Save the location and status of the target. When the time is up, the target location and status are restored, unless the target is dead or unconscious."
- ability_cost = 100
- cooldown_duration = 30 SECONDS
- keybinding_signals = list(
- KEYBINDING_NORMAL = COMSIG_XENOABILITY_REWIND,
- )
- use_state_flags = ABILITY_TARGET_SELF
- /// How long till the time rewinds
- var/start_rewinding = 5 SECONDS
- /// The targeted atom
- var/mob/living/targeted
- /// List of locations the atom took since it was last saved
- var/list/turf/last_target_locs_list = list()
- /// Initial burn damage of the target
- var/target_initial_burn_damage = 0
- /// Initial brute damage of the target
- var/target_initial_brute_damage = 0
- /// Initial sunder of the target
- var/target_initial_sunder = 0
- /// How far can you rewind someone
- var/range = 5
-
-
-/datum/action/ability/activable/xeno/rewind/can_use_ability(atom/A, silent, override_flags)
- . = ..()
-
- var/distance = get_dist(owner, A)
- if(distance > range) //Needs to be in range.
- if(!silent)
- to_chat(owner, span_xenowarning("Our target is too far away! It must be [distance - range] tiles closer!"))
- return FALSE
-
- if(HAS_TRAIT(A, TRAIT_TIME_SHIFTED))
- to_chat(owner, span_xenowarning("That target is already affected by a time manipulation effect!"))
- return FALSE
-
- if(!isliving(A))
- to_chat(owner, span_xenowarning("We cannot target that!"))
- return FALSE
-
-
- var/mob/living/living_target = A
- if(living_target.stat != CONSCIOUS)
- to_chat(owner, span_xenowarning("The target is not in good enough shape!"))
-
-/datum/action/ability/activable/xeno/rewind/use_ability(atom/A)
- targeted = A
- last_target_locs_list = list(get_turf(A))
- target_initial_brute_damage = targeted.getBruteLoss()
- target_initial_burn_damage = targeted.getFireLoss()
- if(isxeno(A))
- var/mob/living/carbon/xenomorph/xeno_target = targeted
- target_initial_sunder = xeno_target.sunder
- addtimer(CALLBACK(src, PROC_REF(start_rewinding)), start_rewinding)
- RegisterSignal(targeted, COMSIG_MOVABLE_MOVED, PROC_REF(save_move))
- targeted.add_filter("prerewind_blur", 1, radial_blur_filter(0.04))
- targeted.balloon_alert(targeted, "You feel anchored to the past!")
- ADD_TRAIT(targeted, TRAIT_TIME_SHIFTED, XENO_TRAIT)
- add_cooldown()
- succeed_activate()
- return
-
-/// Signal handler
-/datum/action/ability/activable/xeno/rewind/proc/save_move(atom/movable/source, oldloc)
- SIGNAL_HANDLER
- last_target_locs_list += get_turf(oldloc)
-
-/// Start the reset process
-/datum/action/ability/activable/xeno/rewind/proc/start_rewinding()
- targeted.remove_filter("prerewind_blur")
- UnregisterSignal(targeted, COMSIG_MOVABLE_MOVED)
- if(QDELETED(targeted) || targeted.stat != CONSCIOUS)
- REMOVE_TRAIT(targeted, TRAIT_TIME_SHIFTED, XENO_TRAIT)
- targeted = null
- return
- targeted.add_filter("rewind_blur", 1, radial_blur_filter(0.3))
- targeted.status_flags |= (INCORPOREAL|GODMODE)
- INVOKE_NEXT_TICK(src, PROC_REF(rewind))
- ADD_TRAIT(owner, TRAIT_IMMOBILE, TIMESHIFT_TRAIT)
- playsound(targeted, 'sound/effects/woosh_swoosh.ogg', 50)
-
-/// Move the target two tiles per tick
-/datum/action/ability/activable/xeno/rewind/proc/rewind()
- var/turf/loc_a = pop(last_target_locs_list)
- if(loc_a)
- new /obj/effect/temp_visual/xenomorph/afterimage(targeted.loc, targeted)
-
- var/turf/loc_b = pop(last_target_locs_list)
- if(!loc_b)
- targeted.status_flags &= ~(INCORPOREAL|GODMODE)
- REMOVE_TRAIT(owner, TRAIT_IMMOBILE, TIMESHIFT_TRAIT)
- targeted.heal_overall_damage(targeted.getBruteLoss() - target_initial_brute_damage, targeted.getFireLoss() - target_initial_burn_damage, updating_health = TRUE)
- if(isxeno(target))
- var/mob/living/carbon/xenomorph/xeno_target = targeted
- xeno_target.sunder = target_initial_sunder
- targeted.remove_filter("rewind_blur")
- REMOVE_TRAIT(targeted, TRAIT_TIME_SHIFTED, XENO_TRAIT)
- targeted = null
- return
-
- targeted.Move(loc_b, get_dir(loc_b, loc_a))
- new /obj/effect/temp_visual/xenomorph/afterimage(loc_a, targeted)
- INVOKE_NEXT_TICK(src, PROC_REF(rewind))
-RU TGMC EDIT */
diff --git a/code/modules/mob/living/carbon/xenomorph/castes/wraith/castedatum_wraith.dm b/code/modules/mob/living/carbon/xenomorph/castes/wraith/castedatum_wraith.dm
deleted file mode 100644
index dddb8dd3caf..00000000000
--- a/code/modules/mob/living/carbon/xenomorph/castes/wraith/castedatum_wraith.dm
+++ /dev/null
@@ -1,79 +0,0 @@
-/* RU TGMC EDIT
-/datum/xeno_caste/wraith
- caste_name = "Wraith"
- display_name = "Wraith"
- upgrade_name = ""
- caste_desc = "A strange xeno that utilizes its psychic powers to move out of phase with reality."
- caste_type_path = /mob/living/carbon/xenomorph/wraith
- tier = XENO_TIER_TWO
- upgrade = XENO_UPGRADE_BASETYPE
- wound_type = "wraith" //used to match appropriate wound overlays
-
- // *** Melee Attacks *** //
- melee_damage = 20
-
- // *** Speed *** //
- speed = -1.25
-
- // *** Plasma *** //
- plasma_max = 400
- plasma_gain = 25
-
- // *** Health *** //
- max_health = 260
-
- // *** Evolution *** //
- evolution_threshold = 225
- //upgrade_threshold = TIER_TWO_THRESHOLD // RUTGMC DELETION
-
- evolves_to = list(
- /mob/living/carbon/xenomorph/defiler,
- /mob/living/carbon/xenomorph/ravager,
- /mob/living/carbon/xenomorph/warlock,
- )
- deevolves_to = /mob/living/carbon/xenomorph/runner
-
- // *** Flags *** //
- caste_flags = CASTE_EVOLUTION_ALLOWED
- can_flags = CASTE_CAN_BE_QUEEN_HEALED|CASTE_CAN_BE_GIVEN_PLASMA|CASTE_CAN_BE_LEADER
- caste_traits = list(TRAIT_CAN_VENTCRAWL)
-
- // *** Defense *** //
- soft_armor = list(MELEE = 40, BULLET = 40, LASER = 20, ENERGY = 20, BOMB = 0, BIO = 20, FIRE = 30, ACID = 20)
-
- // *** Minimap Icon *** //
- minimap_icon = "wraith"
-
- // *** Abilities *** //
- actions = list(
- /datum/action/ability/xeno_action/xeno_resting,
- /datum/action/ability/xeno_action/watch_xeno,
- /datum/action/ability/activable/xeno/psydrain,
- /datum/action/ability/activable/xeno/blink,
- /datum/action/ability/activable/xeno/banish,
- /datum/action/ability/xeno_action/recall,
- /datum/action/ability/activable/xeno/rewind,
- /datum/action/ability/xeno_action/portal,
- )
-
-/datum/xeno_caste/wraith/normal
- upgrade = XENO_UPGRADE_NORMAL
-
-/datum/xeno_caste/wraith/primordial
- upgrade_name = "Primordial"
- caste_desc = "A xenomorph that has perfected the manipulation of space and time. Its movements appear quick and distorted."
- primordial_message = "Mastery is achieved when \'telling time\' becomes \'telling time what to do\'."
- upgrade = XENO_UPGRADE_PRIMO
-
- actions = list(
- /datum/action/ability/xeno_action/xeno_resting,
- /datum/action/ability/xeno_action/watch_xeno,
- /datum/action/ability/activable/xeno/psydrain,
- /datum/action/ability/activable/xeno/blink,
- /datum/action/ability/activable/xeno/banish,
- /datum/action/ability/xeno_action/recall,
- /datum/action/ability/xeno_action/portal,
- /datum/action/ability/activable/xeno/rewind,
- /datum/action/ability/xeno_action/timestop,
- )
-RU TGMC EDIT */
diff --git a/code/modules/mob/living/carbon/xenomorph/castes/wraith/wraith.dm b/code/modules/mob/living/carbon/xenomorph/castes/wraith/wraith.dm
deleted file mode 100644
index 29c27a8c355..00000000000
--- a/code/modules/mob/living/carbon/xenomorph/castes/wraith/wraith.dm
+++ /dev/null
@@ -1,19 +0,0 @@
-/* RU TGMC EDIT
-/mob/living/carbon/xenomorph/wraith
- caste_base_type = /mob/living/carbon/xenomorph/wraith
- name = "Wraith"
- desc = "A strange tendriled alien. The air around it warps and shimmers like a heat mirage."
- icon = 'icons/Xeno/castes/wraith.dmi'
- icon_state = "Wraith Walking"
- bubble_icon = "alienleft"
- health = 150
- maxHealth = 150
- plasma_stored = 150
- pixel_x = -16
- old_x = -16
- tier = XENO_TIER_TWO
- upgrade = XENO_UPGRADE_NORMAL
- inherent_verbs = list(
- /mob/living/carbon/xenomorph/proc/vent_crawl,
- )
-RU TGMC EDIT */
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..7bdb2ace78e 100644
--- a/code/modules/mob/living/carbon/xenomorph/hive_datum.dm
+++ b/code/modules/mob/living/carbon/xenomorph/hive_datum.dm
@@ -180,10 +180,6 @@
.["user_evolution"] = isxeno(user) ? xeno_user.evolution_stored : 0
- /* RUTGMC DELETION
- .["user_maturity"] = isxeno(user) ? xeno_user.upgrade_stored : 0
- .["user_next_mat_level"] = isxeno(user) && xeno_user.upgrade_possible() ? xeno_user.xeno_caste.upgrade_threshold : 0
- */
.["user_tracked"] = isxeno(user) && !isnull(xeno_user.tracked) ? REF(xeno_user.tracked) : ""
.["user_show_empty"] = isxeno(user) ? xeno_user.status_toggle_flags & HIVE_STATUS_SHOW_EMPTY : 0
@@ -1266,7 +1262,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)
@@ -1519,10 +1515,7 @@ to_chat will check for valid clients itself already so no need to double check f
/mob/living/carbon/xenomorph/warrior/Corrupted
hivenumber = XENO_HIVE_CORRUPTED
-/* RU TGMC EDIT
-/mob/living/carbon/xenomorph/wraith/Corrupted
- hivenumber = XENO_HIVE_CORRUPTED
-RU TGMC EDIT */
+
/mob/living/carbon/xenomorph/king/Corrupted
hivenumber = XENO_HIVE_CORRUPTED
@@ -1597,10 +1590,7 @@ RU TGMC EDIT */
/mob/living/carbon/xenomorph/warrior/Alpha
hivenumber = XENO_HIVE_ALPHA
-/* RU TGMC EDIT
-/mob/living/carbon/xenomorph/wraith/Alpha
- hivenumber = XENO_HIVE_ALPHA
-RU TGMC EDIT */
+
/mob/living/carbon/xenomorph/king/Alpha
hivenumber = XENO_HIVE_ALPHA
@@ -1672,10 +1662,7 @@ RU TGMC EDIT */
/mob/living/carbon/xenomorph/warrior/Beta
hivenumber = XENO_HIVE_BETA
-/* RU TGMC EDIT
-/mob/living/carbon/xenomorph/wraith/Beta
- hivenumber = XENO_HIVE_BETA
-RU TGMC EDIT */
+
/mob/living/carbon/xenomorph/king/Beta
hivenumber = XENO_HIVE_BETA
@@ -1747,10 +1734,7 @@ RU TGMC EDIT */
/mob/living/carbon/xenomorph/warrior/Zeta
hivenumber = XENO_HIVE_ZETA
-/* RU TGMC EDIT
-/mob/living/carbon/xenomorph/wraith/Zeta
- hivenumber = XENO_HIVE_ZETA
-RU TGMC EDIT */
+
/mob/living/carbon/xenomorph/king/Zeta
hivenumber = XENO_HIVE_ZETA
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..5cc8fe1e882 100644
--- a/code/modules/mob/living/carbon/xenomorph/xeno_defines.dm
+++ b/code/modules/mob/living/carbon/xenomorph/xeno_defines.dm
@@ -58,9 +58,6 @@
// *** Evolution *** //
///Threshold amount of evo points to next evolution
var/evolution_threshold = 0
- ///Threshold amount of upgrade points to next maturity
- //var/upgrade_threshold = 0 // RUTGMC DELETION
-
///Type paths to the castes that this xenomorph can evolve to
var/list/evolves_to = list()
///Singular type path for the caste to deevolve to when forced to by the queen.
@@ -136,10 +133,6 @@
///delay between the throw hugger ability activation for carriers
var/hugger_delay = 0
- // *** Widow Abilities *** //
- ///maximum amount of spiderlings a widow can carry at one time.
- //var/max_spiderlings = 0 // RUTGMC DELETION, WIDOW DELETION
-
// *** Defender Abilities *** //
///modifying amount to the crest defense ability for defenders. Positive integers only.
var/crest_defense_armor = 0
@@ -147,11 +140,6 @@
var/fortify_armor = 0
///amount of slowdown to apply when the crest defense is active. trading defense for speed. Positive numbers makes it slower.
var/crest_defense_slowdown = 0
-/* RU TGMC EDIT
- // *** Puppeteer Abilities *** //
- var/flay_plasma_gain = 0
- var/max_puppets = 0
-RU TGMC EDIT */
// *** Crusher Abilities *** //
///The damage the stomp causes, counts armor
var/stomp_damage = 0
@@ -172,19 +160,6 @@ RU TGMC EDIT */
///Amount of leaders allowed
var/queen_leader_limit = 0
- // *** Wraith Abilities *** //
- //Banish - Values for the Wraith's Banish ability
- ///Base duration of Banish before modifiers
- var/wraith_banish_base_duration = WRAITH_BANISH_BASE_DURATION
-
- //Blink - Values for the Wraith's Blink ability
- ///Cooldown multiplier of Blink when used on non-friendlies
- var/wraith_blink_drag_nonfriendly_living_multiplier = WRAITH_BLINK_DRAG_NONFRIENDLY_MULTIPLIER
- ///Cooldown multiplier of Blink when used on friendlies
- var/wraith_blink_drag_friendly_multiplier = WRAITH_BLINK_DRAG_FRIENDLY_MULTIPLIER
- ///Base range of Blink
- var/wraith_blink_range = WRAITH_BLINK_RANGE
-
// *** Hunter Abilities ***
///Damage breakpoint to knock out of stealth
var/stealth_break_threshold = 0
@@ -205,6 +180,14 @@ RU TGMC EDIT */
/// The maximum amount of Wrath that we can have stored at a time.
var/wrath_max = 0
+ // *** Chimera Abilities ***
+ ///Cooldown multiplier of Blink when used on non-friendlies
+ var/blink_drag_nonfriendly_living_multiplier = 0
+ ///Cooldown multiplier of Blink when used on friendlies
+ var/blink_drag_friendly_multiplier = 0
+ ///Base range of Blink
+ var/blink_range = 0
+
///the 'abilities' available to a caste.
var/list/actions
@@ -283,7 +266,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..51faa256740 100644
--- a/code/modules/mob/living/carbon/xenomorph/xenoprocs.dm
+++ b/code/modules/mob/living/carbon/xenomorph/xenoprocs.dm
@@ -121,13 +121,6 @@
else
. += "Evolve Progress: [evolution_stored]/[xeno_caste.evolution_threshold]"
- /* RUTGMC DELETION
- if(upgrade_possible())
- . += "Upgrade Progress: [upgrade_stored]/[xeno_caste.upgrade_threshold]"
- else //Upgrade process finished or impossible
- . += "Upgrade Progress: (FINISHED)"
- */
-
. += "Health: [health]/[maxHealth][overheal ? " + [overheal]": ""]" //Changes with balance scalar, can't just use the caste
if(xeno_caste.plasma_max > 0)
@@ -135,6 +128,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 +186,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()
@@ -250,7 +254,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/carbon/xenomorph/xenoupgrade.dm b/code/modules/mob/living/carbon/xenomorph/xenoupgrade.dm
index 75f74c691de..de755efe4cd 100644
--- a/code/modules/mob/living/carbon/xenomorph/xenoupgrade.dm
+++ b/code/modules/mob/living/carbon/xenomorph/xenoupgrade.dm
@@ -82,7 +82,6 @@
/mob/living/carbon/xenomorph/runner/primordial
upgrade = XENO_UPGRADE_PRIMO
- //upgrade_stored = TIER_ONE_THRESHOLD // RUTGMC DELETION
//-----RUNNER END-----//
//================//
@@ -90,7 +89,6 @@
/mob/living/carbon/xenomorph/bull/primordial
upgrade = XENO_UPGRADE_PRIMO
- //upgrade_stored = TIER_TWO_THRESHOLD // RUTGMC DELETION
//-----BULL END-----//
//================//
@@ -98,7 +96,6 @@
/mob/living/carbon/xenomorph/drone/primordial
upgrade = XENO_UPGRADE_PRIMO
- //upgrade_stored = TIER_ONE_THRESHOLD // RUTGMC DELETION
//-----DRONE END-----//
//================//
@@ -127,7 +124,6 @@
/mob/living/carbon/xenomorph/carrier/primordial
upgrade = XENO_UPGRADE_PRIMO
- //upgrade_stored = TIER_TWO_THRESHOLD // RUTGMC DELETION
//-----CARRIER END-----//
//================//
@@ -138,7 +134,6 @@
/mob/living/carbon/xenomorph/hivelord/primordial
upgrade = XENO_UPGRADE_PRIMO
- //upgrade_stored = TIER_TWO_THRESHOLD // RUTGMC DELETION
//----HIVELORD END----//
//================//
@@ -151,7 +146,6 @@
/mob/living/carbon/xenomorph/praetorian/primordial
upgrade = XENO_UPGRADE_PRIMO
- //upgrade_stored = TIER_THREE_THRESHOLD // RUTGMC DELETION
//----PRAETORIAN END----//
//================//
@@ -162,7 +156,6 @@
/mob/living/carbon/xenomorph/ravager/primordial
upgrade = XENO_UPGRADE_PRIMO
- //upgrade_stored = TIER_THREE_THRESHOLD // RUTGMC DELETION
//----RAVAGER END----//
//================//
@@ -189,7 +182,6 @@
/mob/living/carbon/xenomorph/sentinel/primordial
upgrade = XENO_UPGRADE_PRIMO
- //upgrade_stored = TIER_ONE_THRESHOLD // RUTGMC DELETION
//----SENTINEL END----//
//================//
@@ -200,7 +192,6 @@
/mob/living/carbon/xenomorph/spitter/primordial
upgrade = XENO_UPGRADE_PRIMO
- //upgrade_stored = TIER_TWO_THRESHOLD // RUTGMC DELETION
//-----SPITTER END-----//
//================//
@@ -227,7 +218,6 @@
/mob/living/carbon/xenomorph/hunter/primordial
upgrade = XENO_UPGRADE_PRIMO
- //upgrade_stored = TIER_TWO_THRESHOLD // RUTGMC DELETION
//----HUNTER END----//
//================//
@@ -254,7 +244,6 @@
/mob/living/carbon/xenomorph/queen/primordial
upgrade = XENO_UPGRADE_PRIMO
- //upgrade_stored = TIER_THREE_THRESHOLD // RUTGMC DELETION
//----QUEEN END----//
//============//
@@ -265,7 +254,6 @@
/mob/living/carbon/xenomorph/king/primordial
upgrade = XENO_UPGRADE_PRIMO
- //upgrade_stored = TIER_THREE_THRESHOLD // RUTGMC DELETION
//----KING END----//
//============//
@@ -276,7 +264,6 @@
/mob/living/carbon/xenomorph/crusher/primordial
upgrade = XENO_UPGRADE_PRIMO
- //upgrade_stored = TIER_THREE_THRESHOLD // RUTGMC DELETION
//---CRUSHER END---//
//============//
@@ -287,7 +274,6 @@
/mob/living/carbon/xenomorph/gorger/primordial
upgrade = XENO_UPGRADE_PRIMO
- //upgrade_stored = TIER_THREE_THRESHOLD // RUTGMC DELETION
//---GORGER END---//
//============//
@@ -298,7 +284,6 @@
/mob/living/carbon/xenomorph/boiler/primordial
upgrade = XENO_UPGRADE_PRIMO
- //upgrade_stored = TIER_THREE_THRESHOLD // RUTGMC DELETION
//---BOILER END---//
//============//
@@ -309,7 +294,6 @@
/mob/living/carbon/xenomorph/defender/primordial
upgrade = XENO_UPGRADE_PRIMO
- //upgrade_stored = TIER_ONE_THRESHOLD // RUTGMC DELETION
//---DEFENDER END---//
//============//
@@ -320,7 +304,6 @@
/mob/living/carbon/xenomorph/warrior/primordial
upgrade = XENO_UPGRADE_PRIMO
- //upgrade_stored = TIER_TWO_THRESHOLD // RUTGMC DELETION
//----WARRIOR END----//
//============//
@@ -331,7 +314,6 @@
/mob/living/carbon/xenomorph/defiler/primordial
upgrade = XENO_UPGRADE_PRIMO
- //upgrade_stored = TIER_THREE_THRESHOLD // RUTGMC DELETION
//----DEFILER END----//
//============//
@@ -342,36 +324,9 @@
/mob/living/carbon/xenomorph/shrike/primordial
upgrade = XENO_UPGRADE_PRIMO
- //upgrade_stored = TIER_THREE_THRESHOLD // RUTGMC DELETION
//----SHRIKE END----//
-//============//
-/* RU TGMC EDITION START
-//----WRAITH START----//
-
-/mob/living/carbon/xenomorph/wraith
- upgrade = XENO_UPGRADE_NORMAL
-
-/mob/living/carbon/xenomorph/wraith/primordial
- upgrade = XENO_UPGRADE_PRIMO
- //upgrade_stored = TIER_TWO_THRESHOLD
-
-//----WRAITH END----//
-//============//
-RU TGMC EDITION END*/
-//----WIDOW START----//
-/* RUTGMC DELETION, WIDOW DELETION
-
-/mob/living/carbon/xenomorph/widow
- upgrade = XENO_UPGRADE_NORMAL
-
-/mob/living/carbon/xenomorph/widow/primordial
- upgrade = XENO_UPGRADE_PRIMO
- upgrade_stored = TIER_THREE_THRESHOLD
-*/
-//----WIDOW END----//
-//============//
//----WARLOCK START----//
/mob/living/carbon/xenomorph/warlock
@@ -382,18 +337,7 @@ RU TGMC EDITION END*/
//----WARLOCK END----//
//============//
-//============//
-/*RU TGMC EDIT
-//----PUPPETEER START----//
-/mob/living/carbon/xenomorph/puppeteer
- upgrade = XENO_UPGRADE_NORMAL
-
-/mob/living/carbon/xenomorph/puppeteer/primordial
- upgrade = XENO_UPGRADE_PRIMO
- //upgrade_stored = TIER_TWO_THRESHOLD // RUTGMC DELETION
-//----PUPPETEER END----//
-RU TGMC EDIT*/
//============//
//----BEHEMOTH START----//
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/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/predator/yautja/items.dm b/code/modules/predator/yautja/items.dm
index 51e027e658b..55c737bd164 100644
--- a/code/modules/predator/yautja/items.dm
+++ b/code/modules/predator/yautja/items.dm
@@ -699,7 +699,6 @@
icon_state = "yauttrap0"
desc = "A bizarre Yautja device used for trapping and killing prey."
- resistance_flags = BANISH_IMMUNE
layer = LOWER_ITEM_LAYER
var/armed = 0
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)
diff --git a/code/modules/projectiles/sentries.dm b/code/modules/projectiles/sentries.dm
index 2ebff4387c0..c13c8fcfe57 100644
--- a/code/modules/projectiles/sentries.dm
+++ b/code/modules/projectiles/sentries.dm
@@ -375,7 +375,7 @@
continue
potential_targets += nearby_human
for(var/mob/living/carbon/xenomorph/nearby_xeno AS in cheap_get_xenos_near(src, range))
- if(nearby_xeno.stat == DEAD || HAS_TRAIT(nearby_xeno, TRAIT_TURRET_HIDDEN) || CHECK_BITFIELD(nearby_xeno.status_flags, INCORPOREAL) || CHECK_BITFIELD(nearby_xeno.xeno_iff_check(), iff_signal)) //So wraiths wont be shot at when in phase shift
+ if(nearby_xeno.stat == DEAD || HAS_TRAIT(nearby_xeno, TRAIT_TURRET_HIDDEN) || CHECK_BITFIELD(nearby_xeno.status_flags, INCORPOREAL) || CHECK_BITFIELD(nearby_xeno.xeno_iff_check(), iff_signal)) //So hiveminds wont be shot at when in phase shift
continue
potential_targets += nearby_xeno
for(var/mob/illusion/nearby_illusion AS in cheap_get_illusions_near(src, range))
diff --git a/code/modules/vehicles/armored/__armored.dm b/code/modules/vehicles/armored/__armored.dm
index fe8162801d9..75fc3599cd1 100644
--- a/code/modules/vehicles/armored/__armored.dm
+++ b/code/modules/vehicles/armored/__armored.dm
@@ -10,7 +10,7 @@
move_resist = INFINITY
flags_atom = BUMP_ATTACKABLE|PREVENT_CONTENTS_EXPLOSION|CRITICAL_ATOM
allow_pass_flags = PASS_TANK|PASS_AIR|PASS_WALKOVER|PASS_THROW
- resistance_flags = XENO_DAMAGEABLE|UNACIDABLE|PLASMACUTTER_IMMUNE|PORTAL_IMMUNE
+ resistance_flags = XENO_DAMAGEABLE|UNACIDABLE|PLASMACUTTER_IMMUNE
move_delay = 0.7 SECONDS
max_integrity = 600
diff --git a/code/modules/vehicles/mecha/_mecha.dm b/code/modules/vehicles/mecha/_mecha.dm
index 3541225beef..7b1fe352dc7 100644
--- a/code/modules/vehicles/mecha/_mecha.dm
+++ b/code/modules/vehicles/mecha/_mecha.dm
@@ -23,7 +23,7 @@
icon = 'icons/mecha/mecha.dmi'
move_force = MOVE_FORCE_VERY_STRONG
move_resist = MOVE_FORCE_OVERPOWERING
- resistance_flags = UNACIDABLE|XENO_DAMAGEABLE|PORTAL_IMMUNE|PLASMACUTTER_IMMUNE
+ resistance_flags = UNACIDABLE|XENO_DAMAGEABLE|PLASMACUTTER_IMMUNE
flags_atom = BUMP_ATTACKABLE|PREVENT_CONTENTS_EXPLOSION|CRITICAL_ATOM
appearance_flags = TILE_BOUND|PIXEL_SCALE|KEEP_TOGETHER
max_integrity = 300
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/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/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..1bc6a028beb
--- /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..28747bb1f22
--- /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..a8cfea59a82
--- /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..2ad6d4487a5
--- /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
+ 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..3e01e6efda7
--- /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
+ 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/alien/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/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
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
diff --git a/html/changelogs/AutoChangeLog-pr-41.yml b/html/changelogs/AutoChangeLog-pr-41.yml
new file mode 100644
index 00000000000..05aa01a07cc
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-41.yml
@@ -0,0 +1,5 @@
+author: "Helg2"
+delete-after: True
+changes:
+ - rscdel: "Удалил старые неиспользуемые дефайны."
+ - imagedel: "Удалил неиспользуемые спрайты ксенокаст и мап блипов."
\ No newline at end of file
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
diff --git a/icons/UI_Icons/map_blips.dmi b/icons/UI_Icons/map_blips.dmi
index 6f9514cdc41..b4ea668a78f 100644
Binary files a/icons/UI_Icons/map_blips.dmi and b/icons/UI_Icons/map_blips.dmi differ
diff --git a/icons/Xeno/actions.dmi b/icons/Xeno/actions.dmi
index 88ae58bd94e..848c895052c 100644
Binary files a/icons/Xeno/actions.dmi and b/icons/Xeno/actions.dmi differ
diff --git a/icons/Xeno/castes/baneling.dmi b/icons/Xeno/castes/baneling.dmi
deleted file mode 100644
index 03d4964aa72..00000000000
Binary files a/icons/Xeno/castes/baneling.dmi and /dev/null differ
diff --git a/icons/Xeno/castes/puppeteer.dmi b/icons/Xeno/castes/puppeteer.dmi
deleted file mode 100644
index a6185e94fa7..00000000000
Binary files a/icons/Xeno/castes/puppeteer.dmi and /dev/null differ
diff --git a/icons/Xeno/castes/widow.dmi b/icons/Xeno/castes/widow.dmi
deleted file mode 100644
index 839a5e1245c..00000000000
Binary files a/icons/Xeno/castes/widow.dmi and /dev/null differ
diff --git a/icons/Xeno/castes/wraith.dmi b/icons/Xeno/castes/wraith.dmi
deleted file mode 100644
index 6d399aeedf9..00000000000
Binary files a/icons/Xeno/castes/wraith.dmi and /dev/null differ
diff --git a/icons/mob/hud.dmi b/icons/mob/hud.dmi
index cf1b9073338..b08d30e12f9 100644
Binary files a/icons/mob/hud.dmi and b/icons/mob/hud.dmi differ
diff --git a/icons/obj/machines/robotic_cradle.dmi b/icons/obj/machines/robotic_cradle.dmi
new file mode 100644
index 00000000000..47b9d949347
Binary files /dev/null and b/icons/obj/machines/robotic_cradle.dmi differ
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 52920063520..00000000000
Binary files a/sound/effects/footstep/alien_footstep_large1.ogg and /dev/null differ
diff --git a/sound/effects/footstep/alien_footstep_large2.ogg b/sound/effects/footstep/alien_footstep_large2.ogg
deleted file mode 100644
index c5ff7040a26..00000000000
Binary files a/sound/effects/footstep/alien_footstep_large2.ogg and /dev/null differ
diff --git a/sound/effects/footstep/alien_footstep_large3.ogg b/sound/effects/footstep/alien_footstep_large3.ogg
deleted file mode 100644
index d5a6d280dbb..00000000000
Binary files a/sound/effects/footstep/alien_footstep_large3.ogg and /dev/null differ
diff --git a/sound/effects/footstep/alien_footstep_medium1.ogg b/sound/effects/footstep/alien_footstep_medium1.ogg
deleted file mode 100644
index dd68658f8ae..00000000000
Binary files a/sound/effects/footstep/alien_footstep_medium1.ogg and /dev/null differ
diff --git a/sound/effects/footstep/alien_footstep_medium2.ogg b/sound/effects/footstep/alien_footstep_medium2.ogg
deleted file mode 100644
index 59acd63e2b7..00000000000
Binary files a/sound/effects/footstep/alien_footstep_medium2.ogg and /dev/null differ
diff --git a/sound/effects/footstep/alien_footstep_medium3.ogg b/sound/effects/footstep/alien_footstep_medium3.ogg
deleted file mode 100644
index bc1b6589de5..00000000000
Binary files a/sound/effects/footstep/alien_footstep_medium3.ogg and /dev/null differ
diff --git a/sound/voice/4_xeno_roars.ogg b/sound/voice/alien/4_roars.ogg
similarity index 100%
rename from sound/voice/4_xeno_roars.ogg
rename to sound/voice/alien/4_roars.ogg
diff --git a/sound/voice/alien_chestburst.ogg b/sound/voice/alien/chestburst.ogg
similarity index 100%
rename from sound/voice/alien_chestburst.ogg
rename to sound/voice/alien/chestburst.ogg
diff --git a/sound/voice/alien_chestburst2.ogg b/sound/voice/alien/chestburst2.ogg
similarity index 100%
rename from sound/voice/alien_chestburst2.ogg
rename to sound/voice/alien/chestburst2.ogg
diff --git a/sound/voice/alien_death.ogg b/sound/voice/alien/death.ogg
similarity index 100%
rename from sound/voice/alien_death.ogg
rename to sound/voice/alien/death.ogg
diff --git a/sound/voice/alien_death2.ogg b/sound/voice/alien/death2.ogg
similarity index 100%
rename from sound/voice/alien_death2.ogg
rename to sound/voice/alien/death2.ogg
diff --git a/sound/voice/alien_distantroar_3.ogg b/sound/voice/alien/distantroar_3.ogg
similarity index 100%
rename from sound/voice/alien_distantroar_3.ogg
rename to sound/voice/alien/distantroar_3.ogg
diff --git a/sound/voice/alien_drool1.ogg b/sound/voice/alien/drool1.ogg
similarity index 100%
rename from sound/voice/alien_drool1.ogg
rename to sound/voice/alien/drool1.ogg
diff --git a/sound/voice/alien_drool2.ogg b/sound/voice/alien/drool2.ogg
similarity index 100%
rename from sound/voice/alien_drool2.ogg
rename to sound/voice/alien/drool2.ogg
diff --git a/sound/voice/alien_facehugger_dies.ogg b/sound/voice/alien/facehugger_dies.ogg
similarity index 100%
rename from sound/voice/alien_facehugger_dies.ogg
rename to sound/voice/alien/facehugger_dies.ogg
diff --git a/sound/voice/alien_growl1.ogg b/sound/voice/alien/growl1.ogg
similarity index 100%
rename from sound/voice/alien_growl1.ogg
rename to sound/voice/alien/growl1.ogg
diff --git a/sound/voice/alien_growl2.ogg b/sound/voice/alien/growl2.ogg
similarity index 100%
rename from sound/voice/alien_growl2.ogg
rename to sound/voice/alien/growl2.ogg
diff --git a/sound/voice/alien_growl3.ogg b/sound/voice/alien/growl3.ogg
similarity index 100%
rename from sound/voice/alien_growl3.ogg
rename to sound/voice/alien/growl3.ogg
diff --git a/sound/voice/alien_growl4.ogg b/sound/voice/alien/growl4.ogg
similarity index 100%
rename from sound/voice/alien_growl4.ogg
rename to sound/voice/alien/growl4.ogg
diff --git a/sound/voice/alien_help1.ogg b/sound/voice/alien/help1.ogg
similarity index 100%
rename from sound/voice/alien_help1.ogg
rename to sound/voice/alien/help1.ogg
diff --git a/sound/voice/alien_help2.ogg b/sound/voice/alien/help2.ogg
similarity index 100%
rename from sound/voice/alien_help2.ogg
rename to sound/voice/alien/help2.ogg
diff --git a/sound/voice/alien_hiss1.ogg b/sound/voice/alien/hiss1.ogg
similarity index 100%
rename from sound/voice/alien_hiss1.ogg
rename to sound/voice/alien/hiss1.ogg
diff --git a/sound/voice/alien_hiss2.ogg b/sound/voice/alien/hiss2.ogg
similarity index 100%
rename from sound/voice/alien_hiss2.ogg
rename to sound/voice/alien/hiss2.ogg
diff --git a/sound/voice/alien_hiss3.ogg b/sound/voice/alien/hiss3.ogg
similarity index 100%
rename from sound/voice/alien_hiss3.ogg
rename to sound/voice/alien/hiss3.ogg
diff --git a/sound/voice/hiss1.ogg b/sound/voice/alien/hiss4.ogg
similarity index 100%
rename from sound/voice/hiss1.ogg
rename to sound/voice/alien/hiss4.ogg
diff --git a/sound/voice/hiss2.ogg b/sound/voice/alien/hiss5.ogg
similarity index 100%
rename from sound/voice/hiss2.ogg
rename to sound/voice/alien/hiss5.ogg
diff --git a/sound/voice/hiss3.ogg b/sound/voice/alien/hiss6.ogg
similarity index 100%
rename from sound/voice/hiss3.ogg
rename to sound/voice/alien/hiss6.ogg
diff --git a/sound/voice/hiss4.ogg b/sound/voice/alien/hiss7.ogg
similarity index 100%
rename from sound/voice/hiss4.ogg
rename to sound/voice/alien/hiss7.ogg
diff --git a/sound/voice/hiss5.ogg b/sound/voice/alien/hiss8.ogg
similarity index 100%
rename from sound/voice/hiss5.ogg
rename to sound/voice/alien/hiss8.ogg
diff --git a/sound/voice/hiss6.ogg b/sound/voice/alien/hiss9.ogg
similarity index 100%
rename from sound/voice/hiss6.ogg
rename to sound/voice/alien/hiss9.ogg
diff --git a/sound/voice/alien_king_died.ogg b/sound/voice/alien/king_died.ogg
similarity index 100%
rename from sound/voice/alien_king_died.ogg
rename to sound/voice/alien/king_died.ogg
diff --git a/sound/voice/ed209_20sec.ogg b/sound/voice/alien/king_roar.ogg
similarity index 100%
rename from sound/voice/ed209_20sec.ogg
rename to sound/voice/alien/king_roar.ogg
diff --git a/sound/voice/alien_roar_larva1.ogg b/sound/voice/alien/larva/roar1.ogg
similarity index 100%
rename from sound/voice/alien_roar_larva1.ogg
rename to sound/voice/alien/larva/roar1.ogg
diff --git a/sound/voice/alien_roar_larva2.ogg b/sound/voice/alien/larva/roar2.ogg
similarity index 100%
rename from sound/voice/alien_roar_larva2.ogg
rename to sound/voice/alien/larva/roar2.ogg
diff --git a/sound/voice/alien_roar_larva3.ogg b/sound/voice/alien/larva/roar3.ogg
similarity index 100%
rename from sound/voice/alien_roar_larva3.ogg
rename to sound/voice/alien/larva/roar3.ogg
diff --git a/sound/voice/alien_roar_larva4.ogg b/sound/voice/alien/larva/roar4.ogg
similarity index 100%
rename from sound/voice/alien_roar_larva4.ogg
rename to sound/voice/alien/larva/roar4.ogg
diff --git a/sound/voice/larva_talk1.ogg b/sound/voice/alien/larva/talk1.ogg
similarity index 100%
rename from sound/voice/larva_talk1.ogg
rename to sound/voice/alien/larva/talk1.ogg
diff --git a/sound/voice/larva_talk2.ogg b/sound/voice/alien/larva/talk2.ogg
similarity index 100%
rename from sound/voice/larva_talk2.ogg
rename to sound/voice/alien/larva/talk2.ogg
diff --git a/sound/voice/larva_talk3.ogg b/sound/voice/alien/larva/talk3.ogg
similarity index 100%
rename from sound/voice/larva_talk3.ogg
rename to sound/voice/alien/larva/talk3.ogg
diff --git a/sound/voice/larva_talk4.ogg b/sound/voice/alien/larva/talk4.ogg
similarity index 100%
rename from sound/voice/larva_talk4.ogg
rename to sound/voice/alien/larva/talk4.ogg
diff --git a/sound/voice/alien_pounce.ogg b/sound/voice/alien/pounce.ogg
similarity index 100%
rename from sound/voice/alien_pounce.ogg
rename to sound/voice/alien/pounce.ogg
diff --git a/sound/voice/alien_pounce2.ogg b/sound/voice/alien/pounce2.ogg
similarity index 100%
rename from sound/voice/alien_pounce2.ogg
rename to sound/voice/alien/pounce2.ogg
diff --git a/sound/voice/predalien_click.ogg b/sound/voice/alien/predalien/click.ogg
similarity index 100%
rename from sound/voice/predalien_click.ogg
rename to sound/voice/alien/predalien/click.ogg
diff --git a/sound/voice/predalien_click1.ogg b/sound/voice/alien/predalien/click1.ogg
similarity index 100%
rename from sound/voice/predalien_click1.ogg
rename to sound/voice/alien/predalien/click1.ogg
diff --git a/sound/voice/predalien_click2.ogg b/sound/voice/alien/predalien/click2.ogg
similarity index 100%
rename from sound/voice/predalien_click2.ogg
rename to sound/voice/alien/predalien/click2.ogg
diff --git a/sound/voice/predalien_click3.ogg b/sound/voice/alien/predalien/click3.ogg
similarity index 100%
rename from sound/voice/predalien_click3.ogg
rename to sound/voice/alien/predalien/click3.ogg
diff --git a/sound/voice/predalien_death.ogg b/sound/voice/alien/predalien/death.ogg
similarity index 100%
rename from sound/voice/predalien_death.ogg
rename to sound/voice/alien/predalien/death.ogg
diff --git a/sound/voice/predalien_growl.ogg b/sound/voice/alien/predalien/growl.ogg
similarity index 100%
rename from sound/voice/predalien_growl.ogg
rename to sound/voice/alien/predalien/growl.ogg
diff --git a/sound/voice/predalien_hiss.ogg b/sound/voice/alien/predalien/hiss.ogg
similarity index 100%
rename from sound/voice/predalien_hiss.ogg
rename to sound/voice/alien/predalien/hiss.ogg
diff --git a/sound/voice/predalien_pounce.ogg b/sound/voice/alien/predalien/pounce.ogg
similarity index 100%
rename from sound/voice/predalien_pounce.ogg
rename to sound/voice/alien/predalien/pounce.ogg
diff --git a/sound/voice/predalien_roar.ogg b/sound/voice/alien/predalien/roar.ogg
similarity index 100%
rename from sound/voice/predalien_roar.ogg
rename to sound/voice/alien/predalien/roar.ogg
diff --git a/sound/voice/alien_queen_breath1.ogg b/sound/voice/alien/queen/breath1.ogg
similarity index 100%
rename from sound/voice/alien_queen_breath1.ogg
rename to sound/voice/alien/queen/breath1.ogg
diff --git a/sound/voice/alien_queen_breath2.ogg b/sound/voice/alien/queen/breath2.ogg
similarity index 100%
rename from sound/voice/alien_queen_breath2.ogg
rename to sound/voice/alien/queen/breath2.ogg
diff --git a/sound/voice/alien_queen_command.ogg b/sound/voice/alien/queen/command.ogg
similarity index 100%
rename from sound/voice/alien_queen_command.ogg
rename to sound/voice/alien/queen/command.ogg
diff --git a/sound/voice/alien_queen_command2.ogg b/sound/voice/alien/queen/command2.ogg
similarity index 100%
rename from sound/voice/alien_queen_command2.ogg
rename to sound/voice/alien/queen/command2.ogg
diff --git a/sound/voice/alien_queen_command3.ogg b/sound/voice/alien/queen/command3.ogg
similarity index 100%
rename from sound/voice/alien_queen_command3.ogg
rename to sound/voice/alien/queen/command3.ogg
diff --git a/sound/voice/alien_queen_died.ogg b/sound/voice/alien/queen/died.ogg
similarity index 100%
rename from sound/voice/alien_queen_died.ogg
rename to sound/voice/alien/queen/died.ogg
diff --git a/sound/voice/alien_queen_screech.ogg b/sound/voice/alien/queen/screech.ogg
similarity index 100%
rename from sound/voice/alien_queen_screech.ogg
rename to sound/voice/alien/queen/screech.ogg
diff --git a/sound/voice/alien_frenzy_screech.ogg b/sound/voice/alien/queen/screech_frenzy.ogg
similarity index 100%
rename from sound/voice/alien_frenzy_screech.ogg
rename to sound/voice/alien/queen/screech_frenzy.ogg
diff --git a/sound/voice/alien_heal_screech.ogg b/sound/voice/alien/queen/screech_heal.ogg
similarity index 100%
rename from sound/voice/alien_heal_screech.ogg
rename to sound/voice/alien/queen/screech_heal.ogg
diff --git a/sound/voice/alien_plasma_screech.ogg b/sound/voice/alien/queen/screech_plasma.ogg
similarity index 100%
rename from sound/voice/alien_plasma_screech.ogg
rename to sound/voice/alien/queen/screech_plasma.ogg
diff --git a/sound/voice/alien_roar1.ogg b/sound/voice/alien/roar1.ogg
similarity index 100%
rename from sound/voice/alien_roar1.ogg
rename to sound/voice/alien/roar1.ogg
diff --git a/sound/voice/alien_roar10.ogg b/sound/voice/alien/roar10.ogg
similarity index 100%
rename from sound/voice/alien_roar10.ogg
rename to sound/voice/alien/roar10.ogg
diff --git a/sound/voice/alien_roar11.ogg b/sound/voice/alien/roar11.ogg
similarity index 100%
rename from sound/voice/alien_roar11.ogg
rename to sound/voice/alien/roar11.ogg
diff --git a/sound/voice/alien_roar12.ogg b/sound/voice/alien/roar12.ogg
similarity index 100%
rename from sound/voice/alien_roar12.ogg
rename to sound/voice/alien/roar12.ogg
diff --git a/sound/voice/alien_roar2.ogg b/sound/voice/alien/roar2.ogg
similarity index 100%
rename from sound/voice/alien_roar2.ogg
rename to sound/voice/alien/roar2.ogg
diff --git a/sound/voice/alien_roar3.ogg b/sound/voice/alien/roar3.ogg
similarity index 100%
rename from sound/voice/alien_roar3.ogg
rename to sound/voice/alien/roar3.ogg
diff --git a/sound/voice/alien_roar4.ogg b/sound/voice/alien/roar4.ogg
similarity index 100%
rename from sound/voice/alien_roar4.ogg
rename to sound/voice/alien/roar4.ogg
diff --git a/sound/voice/alien_roar5.ogg b/sound/voice/alien/roar5.ogg
similarity index 100%
rename from sound/voice/alien_roar5.ogg
rename to sound/voice/alien/roar5.ogg
diff --git a/sound/voice/alien_roar6.ogg b/sound/voice/alien/roar6.ogg
similarity index 100%
rename from sound/voice/alien_roar6.ogg
rename to sound/voice/alien/roar6.ogg
diff --git a/sound/voice/alien_roar7.ogg b/sound/voice/alien/roar7.ogg
similarity index 100%
rename from sound/voice/alien_roar7.ogg
rename to sound/voice/alien/roar7.ogg
diff --git a/sound/voice/alien_roar8.ogg b/sound/voice/alien/roar8.ogg
similarity index 100%
rename from sound/voice/alien_roar8.ogg
rename to sound/voice/alien/roar8.ogg
diff --git a/sound/voice/alien_roar9.ogg b/sound/voice/alien/roar9.ogg
similarity index 100%
rename from sound/voice/alien_roar9.ogg
rename to sound/voice/alien/roar9.ogg
diff --git a/sound/voice/alien_roar_warlock.ogg b/sound/voice/alien/roar_warlock.ogg
similarity index 100%
rename from sound/voice/alien_roar_warlock.ogg
rename to sound/voice/alien/roar_warlock.ogg
diff --git a/sound/voice/alien_spitacid.ogg b/sound/voice/alien/spitacid.ogg
similarity index 100%
rename from sound/voice/alien_spitacid.ogg
rename to sound/voice/alien/spitacid.ogg
diff --git a/sound/voice/alien_spitacid2.ogg b/sound/voice/alien/spitacid2.ogg
similarity index 100%
rename from sound/voice/alien_spitacid2.ogg
rename to sound/voice/alien/spitacid2.ogg
diff --git a/sound/voice/alien_talk.ogg b/sound/voice/alien/talk.ogg
similarity index 100%
rename from sound/voice/alien_talk.ogg
rename to sound/voice/alien/talk.ogg
diff --git a/sound/voice/alien_talk2.ogg b/sound/voice/alien/talk2.ogg
similarity index 100%
rename from sound/voice/alien_talk2.ogg
rename to sound/voice/alien/talk2.ogg
diff --git a/sound/voice/alien_talk3.ogg b/sound/voice/alien/talk3.ogg
similarity index 100%
rename from sound/voice/alien_talk3.ogg
rename to sound/voice/alien/talk3.ogg
diff --git a/sound/voice/xenos_roaring.ogg b/sound/voice/alien/xenos_roaring.ogg
similarity index 100%
rename from sound/voice/xenos_roaring.ogg
rename to sound/voice/alien/xenos_roaring.ogg
diff --git a/sound/voice/alien_yell_alt.ogg b/sound/voice/alien/yell_alt.ogg
similarity index 100%
rename from sound/voice/alien_yell_alt.ogg
rename to sound/voice/alien/yell_alt.ogg
diff --git a/sound/voice/alien_cena.ogg b/sound/voice/alien_cena.ogg
deleted file mode 100644
index cf9fc6d8ea4..00000000000
Binary files a/sound/voice/alien_cena.ogg and /dev/null differ
diff --git a/sound/voice/alien_queen_xmas.ogg b/sound/voice/alien_queen_xmas.ogg
deleted file mode 100644
index 5f191ba30f5..00000000000
Binary files a/sound/voice/alien_queen_xmas.ogg and /dev/null differ
diff --git a/sound/voice/b18_activate.ogg b/sound/voice/b18/activate.ogg
similarity index 100%
rename from sound/voice/b18_activate.ogg
rename to sound/voice/b18/activate.ogg
diff --git a/sound/voice/b18_antitoxin.ogg b/sound/voice/b18/antitoxin.ogg
similarity index 100%
rename from sound/voice/b18_antitoxin.ogg
rename to sound/voice/b18/antitoxin.ogg
diff --git a/sound/voice/b18_antitoxin2.ogg b/sound/voice/b18/antitoxin2.ogg
similarity index 100%
rename from sound/voice/b18_antitoxin2.ogg
rename to sound/voice/b18/antitoxin2.ogg
diff --git a/sound/voice/b18_brute.ogg b/sound/voice/b18/brute.ogg
similarity index 100%
rename from sound/voice/b18_brute.ogg
rename to sound/voice/b18/brute.ogg
diff --git a/sound/voice/b18_fracture.ogg b/sound/voice/b18/fracture.ogg
similarity index 100%
rename from sound/voice/b18_fracture.ogg
rename to sound/voice/b18/fracture.ogg
diff --git a/sound/voice/ib_detected.ogg b/sound/voice/b18/ib_detected.ogg
similarity index 100%
rename from sound/voice/ib_detected.ogg
rename to sound/voice/b18/ib_detected.ogg
diff --git a/sound/voice/b18_pain_suppress.ogg b/sound/voice/b18/pain_suppress.ogg
similarity index 100%
rename from sound/voice/b18_pain_suppress.ogg
rename to sound/voice/b18/pain_suppress.ogg
diff --git a/sound/voice/bcreep.ogg b/sound/voice/bcreep.ogg
deleted file mode 100644
index d1d4f043be4..00000000000
Binary files a/sound/voice/bcreep.ogg and /dev/null differ
diff --git a/sound/voice/bcriminal.ogg b/sound/voice/bcriminal.ogg
deleted file mode 100644
index 36621372b9a..00000000000
Binary files a/sound/voice/bcriminal.ogg and /dev/null differ
diff --git a/sound/voice/bfreeze.ogg b/sound/voice/bfreeze.ogg
deleted file mode 100644
index de1a5014441..00000000000
Binary files a/sound/voice/bfreeze.ogg and /dev/null differ
diff --git a/sound/voice/bgod.ogg b/sound/voice/bgod.ogg
deleted file mode 100644
index 3deab990caa..00000000000
Binary files a/sound/voice/bgod.ogg and /dev/null differ
diff --git a/sound/voice/biamthelaw.ogg b/sound/voice/biamthelaw.ogg
deleted file mode 100644
index c4405b24289..00000000000
Binary files a/sound/voice/biamthelaw.ogg and /dev/null differ
diff --git a/sound/voice/binsult.ogg b/sound/voice/binsult.ogg
deleted file mode 100644
index db996283c57..00000000000
Binary files a/sound/voice/binsult.ogg and /dev/null differ
diff --git a/sound/voice/bjustice.ogg b/sound/voice/bjustice.ogg
deleted file mode 100644
index 7c93abc0f31..00000000000
Binary files a/sound/voice/bjustice.ogg and /dev/null differ
diff --git a/sound/voice/bradio.ogg b/sound/voice/bradio.ogg
deleted file mode 100644
index 7d2681f2f28..00000000000
Binary files a/sound/voice/bradio.ogg and /dev/null differ
diff --git a/sound/voice/bsecureday.ogg b/sound/voice/bsecureday.ogg
deleted file mode 100644
index 594f8a8cbc0..00000000000
Binary files a/sound/voice/bsecureday.ogg and /dev/null differ
diff --git a/sound/voice/human_female_cough1.ogg b/sound/voice/human/female/cough1.ogg
similarity index 100%
rename from sound/voice/human_female_cough1.ogg
rename to sound/voice/human/female/cough1.ogg
diff --git a/sound/voice/human_female_cough2.ogg b/sound/voice/human/female/cough2.ogg
similarity index 100%
rename from sound/voice/human_female_cough2.ogg
rename to sound/voice/human/female/cough2.ogg
diff --git a/sound/voice/human_female_cry_1.ogg b/sound/voice/human/female/cry_1.ogg
similarity index 100%
rename from sound/voice/human_female_cry_1.ogg
rename to sound/voice/human/female/cry_1.ogg
diff --git a/sound/voice/human_female_facehugged1.ogg b/sound/voice/human/female/facehugged1.ogg
similarity index 100%
rename from sound/voice/human_female_facehugged1.ogg
rename to sound/voice/human/female/facehugged1.ogg
diff --git a/sound/voice/human_female_facehugged2.ogg b/sound/voice/human/female/facehugged2.ogg
similarity index 100%
rename from sound/voice/human_female_facehugged2.ogg
rename to sound/voice/human/female/facehugged2.ogg
diff --git a/sound/voice/human_female_gasp1.ogg b/sound/voice/human/female/gasp1.ogg
similarity index 100%
rename from sound/voice/human_female_gasp1.ogg
rename to sound/voice/human/female/gasp1.ogg
diff --git a/sound/voice/human_female_gasp2.ogg b/sound/voice/human/female/gasp2.ogg
similarity index 100%
rename from sound/voice/human_female_gasp2.ogg
rename to sound/voice/human/female/gasp2.ogg
diff --git a/sound/voice/human_female_giggle_1.ogg b/sound/voice/human/female/giggle_1.ogg
similarity index 100%
rename from sound/voice/human_female_giggle_1.ogg
rename to sound/voice/human/female/giggle_1.ogg
diff --git a/sound/voice/human_female_gored_1.ogg b/sound/voice/human/female/gored_1.ogg
similarity index 100%
rename from sound/voice/human_female_gored_1.ogg
rename to sound/voice/human/female/gored_1.ogg
diff --git a/sound/voice/human_female_gored_2.ogg b/sound/voice/human/female/gored_2.ogg
similarity index 100%
rename from sound/voice/human_female_gored_2.ogg
rename to sound/voice/human/female/gored_2.ogg
diff --git a/sound/voice/human_female_grenadethrow_1.ogg b/sound/voice/human/female/grenadethrow_1.ogg
similarity index 100%
rename from sound/voice/human_female_grenadethrow_1.ogg
rename to sound/voice/human/female/grenadethrow_1.ogg
diff --git a/sound/voice/human_female_grenadethrow_2.ogg b/sound/voice/human/female/grenadethrow_2.ogg
similarity index 100%
rename from sound/voice/human_female_grenadethrow_2.ogg
rename to sound/voice/human/female/grenadethrow_2.ogg
diff --git a/sound/voice/human_female_grenadethrow_3.ogg b/sound/voice/human/female/grenadethrow_3.ogg
similarity index 100%
rename from sound/voice/human_female_grenadethrow_3.ogg
rename to sound/voice/human/female/grenadethrow_3.ogg
diff --git a/sound/voice/human_female_laugh_1.ogg b/sound/voice/human/female/laugh_1.ogg
similarity index 100%
rename from sound/voice/human_female_laugh_1.ogg
rename to sound/voice/human/female/laugh_1.ogg
diff --git a/sound/voice/human_female_medic.ogg b/sound/voice/human/female/medic.ogg
similarity index 100%
rename from sound/voice/human_female_medic.ogg
rename to sound/voice/human/female/medic.ogg
diff --git a/sound/voice/human_female_moan_1.ogg b/sound/voice/human/female/moan_1.ogg
similarity index 100%
rename from sound/voice/human_female_moan_1.ogg
rename to sound/voice/human/female/moan_1.ogg
diff --git a/sound/voice/human_female_pain_1.ogg b/sound/voice/human/female/pain_1.ogg
similarity index 100%
rename from sound/voice/human_female_pain_1.ogg
rename to sound/voice/human/female/pain_1.ogg
diff --git a/sound/voice/human_female_pain_2.ogg b/sound/voice/human/female/pain_2.ogg
similarity index 100%
rename from sound/voice/human_female_pain_2.ogg
rename to sound/voice/human/female/pain_2.ogg
diff --git a/sound/voice/human_female_pain_3.ogg b/sound/voice/human/female/pain_3.ogg
similarity index 100%
rename from sound/voice/human_female_pain_3.ogg
rename to sound/voice/human/female/pain_3.ogg
diff --git a/sound/voice/human_female_preburst1.ogg b/sound/voice/human/female/preburst1.ogg
similarity index 100%
rename from sound/voice/human_female_preburst1.ogg
rename to sound/voice/human/female/preburst1.ogg
diff --git a/sound/voice/human_female_preburst2.ogg b/sound/voice/human/female/preburst2.ogg
similarity index 100%
rename from sound/voice/human_female_preburst2.ogg
rename to sound/voice/human/female/preburst2.ogg
diff --git a/sound/voice/human_female_preburst3.ogg b/sound/voice/human/female/preburst3.ogg
similarity index 100%
rename from sound/voice/human_female_preburst3.ogg
rename to sound/voice/human/female/preburst3.ogg
diff --git a/sound/voice/human_female_scream_1.ogg b/sound/voice/human/female/scream_1.ogg
similarity index 100%
rename from sound/voice/human_female_scream_1.ogg
rename to sound/voice/human/female/scream_1.ogg
diff --git a/sound/voice/human_female_scream_2.ogg b/sound/voice/human/female/scream_2.ogg
similarity index 100%
rename from sound/voice/human_female_scream_2.ogg
rename to sound/voice/human/female/scream_2.ogg
diff --git a/sound/voice/human_female_scream_3.ogg b/sound/voice/human/female/scream_3.ogg
similarity index 100%
rename from sound/voice/human_female_scream_3.ogg
rename to sound/voice/human/female/scream_3.ogg
diff --git a/sound/voice/human_female_scream_4.ogg b/sound/voice/human/female/scream_4.ogg
similarity index 100%
rename from sound/voice/human_female_scream_4.ogg
rename to sound/voice/human/female/scream_4.ogg
diff --git a/sound/voice/human_female_scream_5.ogg b/sound/voice/human/female/scream_5.ogg
similarity index 100%
rename from sound/voice/human_female_scream_5.ogg
rename to sound/voice/human/female/scream_5.ogg
diff --git a/sound/voice/human_female_sigh_1.ogg b/sound/voice/human/female/sigh_1.ogg
similarity index 100%
rename from sound/voice/human_female_sigh_1.ogg
rename to sound/voice/human/female/sigh_1.ogg
diff --git a/sound/voice/human_female_warcry_1.ogg b/sound/voice/human/female/warcry_1.ogg
similarity index 100%
rename from sound/voice/human_female_warcry_1.ogg
rename to sound/voice/human/female/warcry_1.ogg
diff --git a/sound/voice/human_female_warcry_10.ogg b/sound/voice/human/female/warcry_10.ogg
similarity index 100%
rename from sound/voice/human_female_warcry_10.ogg
rename to sound/voice/human/female/warcry_10.ogg
diff --git a/sound/voice/human_female_warcry_11.ogg b/sound/voice/human/female/warcry_11.ogg
similarity index 100%
rename from sound/voice/human_female_warcry_11.ogg
rename to sound/voice/human/female/warcry_11.ogg
diff --git a/sound/voice/human_female_warcry_12.ogg b/sound/voice/human/female/warcry_12.ogg
similarity index 100%
rename from sound/voice/human_female_warcry_12.ogg
rename to sound/voice/human/female/warcry_12.ogg
diff --git a/sound/voice/human_female_warcry_13.ogg b/sound/voice/human/female/warcry_13.ogg
similarity index 100%
rename from sound/voice/human_female_warcry_13.ogg
rename to sound/voice/human/female/warcry_13.ogg
diff --git a/sound/voice/human_female_warcry_14.ogg b/sound/voice/human/female/warcry_14.ogg
similarity index 100%
rename from sound/voice/human_female_warcry_14.ogg
rename to sound/voice/human/female/warcry_14.ogg
diff --git a/sound/voice/human_female_warcry_15.ogg b/sound/voice/human/female/warcry_15.ogg
similarity index 100%
rename from sound/voice/human_female_warcry_15.ogg
rename to sound/voice/human/female/warcry_15.ogg
diff --git a/sound/voice/human_female_warcry_16.ogg b/sound/voice/human/female/warcry_16.ogg
similarity index 100%
rename from sound/voice/human_female_warcry_16.ogg
rename to sound/voice/human/female/warcry_16.ogg
diff --git a/sound/voice/human_female_warcry_17.ogg b/sound/voice/human/female/warcry_17.ogg
similarity index 100%
rename from sound/voice/human_female_warcry_17.ogg
rename to sound/voice/human/female/warcry_17.ogg
diff --git a/sound/voice/human_female_warcry_18.ogg b/sound/voice/human/female/warcry_18.ogg
similarity index 100%
rename from sound/voice/human_female_warcry_18.ogg
rename to sound/voice/human/female/warcry_18.ogg
diff --git a/sound/voice/human_female_warcry_19.ogg b/sound/voice/human/female/warcry_19.ogg
similarity index 100%
rename from sound/voice/human_female_warcry_19.ogg
rename to sound/voice/human/female/warcry_19.ogg
diff --git a/sound/voice/human_female_warcry_2.ogg b/sound/voice/human/female/warcry_2.ogg
similarity index 100%
rename from sound/voice/human_female_warcry_2.ogg
rename to sound/voice/human/female/warcry_2.ogg
diff --git a/sound/voice/human_female_warcry_3.ogg b/sound/voice/human/female/warcry_3.ogg
similarity index 100%
rename from sound/voice/human_female_warcry_3.ogg
rename to sound/voice/human/female/warcry_3.ogg
diff --git a/sound/voice/human_female_warcry_4.ogg b/sound/voice/human/female/warcry_4.ogg
similarity index 100%
rename from sound/voice/human_female_warcry_4.ogg
rename to sound/voice/human/female/warcry_4.ogg
diff --git a/sound/voice/human_female_warcry_5.ogg b/sound/voice/human/female/warcry_5.ogg
similarity index 100%
rename from sound/voice/human_female_warcry_5.ogg
rename to sound/voice/human/female/warcry_5.ogg
diff --git a/sound/voice/human_female_warcry_6.ogg b/sound/voice/human/female/warcry_6.ogg
similarity index 100%
rename from sound/voice/human_female_warcry_6.ogg
rename to sound/voice/human/female/warcry_6.ogg
diff --git a/sound/voice/human_female_warcry_7.ogg b/sound/voice/human/female/warcry_7.ogg
similarity index 100%
rename from sound/voice/human_female_warcry_7.ogg
rename to sound/voice/human/female/warcry_7.ogg
diff --git a/sound/voice/human_female_warcry_8.ogg b/sound/voice/human/female/warcry_8.ogg
similarity index 100%
rename from sound/voice/human_female_warcry_8.ogg
rename to sound/voice/human/female/warcry_8.ogg
diff --git a/sound/voice/human_female_warcry_9.ogg b/sound/voice/human/female/warcry_9.ogg
similarity index 100%
rename from sound/voice/human_female_warcry_9.ogg
rename to sound/voice/human/female/warcry_9.ogg
diff --git a/sound/voice/human_female_yawn_1.ogg b/sound/voice/human/female/yawn_1.ogg
similarity index 100%
rename from sound/voice/human_female_yawn_1.ogg
rename to sound/voice/human/female/yawn_1.ogg
diff --git a/sound/voice/human_male_cough1.ogg b/sound/voice/human/male/cough1.ogg
similarity index 100%
rename from sound/voice/human_male_cough1.ogg
rename to sound/voice/human/male/cough1.ogg
diff --git a/sound/voice/human_male_cough2.ogg b/sound/voice/human/male/cough2.ogg
similarity index 100%
rename from sound/voice/human_male_cough2.ogg
rename to sound/voice/human/male/cough2.ogg
diff --git a/sound/voice/human_male_cry_1.ogg b/sound/voice/human/male/cry_1.ogg
similarity index 100%
rename from sound/voice/human_male_cry_1.ogg
rename to sound/voice/human/male/cry_1.ogg
diff --git a/sound/voice/human_male_facehugged1.ogg b/sound/voice/human/male/facehugged1.ogg
similarity index 100%
rename from sound/voice/human_male_facehugged1.ogg
rename to sound/voice/human/male/facehugged1.ogg
diff --git a/sound/voice/human_male_facehugged2.ogg b/sound/voice/human/male/facehugged2.ogg
similarity index 100%
rename from sound/voice/human_male_facehugged2.ogg
rename to sound/voice/human/male/facehugged2.ogg
diff --git a/sound/voice/human_male_facehugged3.ogg b/sound/voice/human/male/facehugged3.ogg
similarity index 100%
rename from sound/voice/human_male_facehugged3.ogg
rename to sound/voice/human/male/facehugged3.ogg
diff --git a/sound/voice/human_male_gasp1.ogg b/sound/voice/human/male/gasp1.ogg
similarity index 100%
rename from sound/voice/human_male_gasp1.ogg
rename to sound/voice/human/male/gasp1.ogg
diff --git a/sound/voice/human_male_gasp2.ogg b/sound/voice/human/male/gasp2.ogg
similarity index 100%
rename from sound/voice/human_male_gasp2.ogg
rename to sound/voice/human/male/gasp2.ogg
diff --git a/sound/voice/human_male_gasp3.ogg b/sound/voice/human/male/gasp3.ogg
similarity index 100%
rename from sound/voice/human_male_gasp3.ogg
rename to sound/voice/human/male/gasp3.ogg
diff --git a/sound/voice/human_male_giggle_1.ogg b/sound/voice/human/male/giggle_1.ogg
similarity index 100%
rename from sound/voice/human_male_giggle_1.ogg
rename to sound/voice/human/male/giggle_1.ogg
diff --git a/sound/voice/human_male_gored3.ogg b/sound/voice/human/male/gored3.ogg
similarity index 100%
rename from sound/voice/human_male_gored3.ogg
rename to sound/voice/human/male/gored3.ogg
diff --git a/sound/voice/human_male_gored_1.ogg b/sound/voice/human/male/gored_1.ogg
similarity index 100%
rename from sound/voice/human_male_gored_1.ogg
rename to sound/voice/human/male/gored_1.ogg
diff --git a/sound/voice/human_male_gored_2.ogg b/sound/voice/human/male/gored_2.ogg
similarity index 100%
rename from sound/voice/human_male_gored_2.ogg
rename to sound/voice/human/male/gored_2.ogg
diff --git a/sound/voice/human_male_grenadethrow_1.ogg b/sound/voice/human/male/grenadethrow_1.ogg
similarity index 100%
rename from sound/voice/human_male_grenadethrow_1.ogg
rename to sound/voice/human/male/grenadethrow_1.ogg
diff --git a/sound/voice/human_male_grenadethrow_2.ogg b/sound/voice/human/male/grenadethrow_2.ogg
similarity index 100%
rename from sound/voice/human_male_grenadethrow_2.ogg
rename to sound/voice/human/male/grenadethrow_2.ogg
diff --git a/sound/voice/human_male_grenadethrow_3.ogg b/sound/voice/human/male/grenadethrow_3.ogg
similarity index 100%
rename from sound/voice/human_male_grenadethrow_3.ogg
rename to sound/voice/human/male/grenadethrow_3.ogg
diff --git a/sound/voice/human_male_laugh_1.ogg b/sound/voice/human/male/laugh_1.ogg
similarity index 100%
rename from sound/voice/human_male_laugh_1.ogg
rename to sound/voice/human/male/laugh_1.ogg
diff --git a/sound/voice/human_male_laugh_2.ogg b/sound/voice/human/male/laugh_2.ogg
similarity index 100%
rename from sound/voice/human_male_laugh_2.ogg
rename to sound/voice/human/male/laugh_2.ogg
diff --git a/sound/voice/human_male_medic.ogg b/sound/voice/human/male/medic.ogg
similarity index 100%
rename from sound/voice/human_male_medic.ogg
rename to sound/voice/human/male/medic.ogg
diff --git a/sound/voice/human_male_medic2.ogg b/sound/voice/human/male/medic2.ogg
similarity index 100%
rename from sound/voice/human_male_medic2.ogg
rename to sound/voice/human/male/medic2.ogg
diff --git a/sound/voice/human_male_moan_1.ogg b/sound/voice/human/male/moan_1.ogg
similarity index 100%
rename from sound/voice/human_male_moan_1.ogg
rename to sound/voice/human/male/moan_1.ogg
diff --git a/sound/voice/human_male_pain_1.ogg b/sound/voice/human/male/pain_1.ogg
similarity index 100%
rename from sound/voice/human_male_pain_1.ogg
rename to sound/voice/human/male/pain_1.ogg
diff --git a/sound/voice/human_male_pain_10.ogg b/sound/voice/human/male/pain_10.ogg
similarity index 100%
rename from sound/voice/human_male_pain_10.ogg
rename to sound/voice/human/male/pain_10.ogg
diff --git a/sound/voice/human_male_pain_11.ogg b/sound/voice/human/male/pain_11.ogg
similarity index 100%
rename from sound/voice/human_male_pain_11.ogg
rename to sound/voice/human/male/pain_11.ogg
diff --git a/sound/voice/human_male_pain_2.ogg b/sound/voice/human/male/pain_2.ogg
similarity index 100%
rename from sound/voice/human_male_pain_2.ogg
rename to sound/voice/human/male/pain_2.ogg
diff --git a/sound/voice/human_male_pain_3.ogg b/sound/voice/human/male/pain_3.ogg
similarity index 100%
rename from sound/voice/human_male_pain_3.ogg
rename to sound/voice/human/male/pain_3.ogg
diff --git a/sound/voice/human_male_pain_4.ogg b/sound/voice/human/male/pain_4.ogg
similarity index 100%
rename from sound/voice/human_male_pain_4.ogg
rename to sound/voice/human/male/pain_4.ogg
diff --git a/sound/voice/human_male_pain_5.ogg b/sound/voice/human/male/pain_5.ogg
similarity index 100%
rename from sound/voice/human_male_pain_5.ogg
rename to sound/voice/human/male/pain_5.ogg
diff --git a/sound/voice/human_male_pain_6.ogg b/sound/voice/human/male/pain_6.ogg
similarity index 100%
rename from sound/voice/human_male_pain_6.ogg
rename to sound/voice/human/male/pain_6.ogg
diff --git a/sound/voice/human_male_pain_7.ogg b/sound/voice/human/male/pain_7.ogg
similarity index 100%
rename from sound/voice/human_male_pain_7.ogg
rename to sound/voice/human/male/pain_7.ogg
diff --git a/sound/voice/human_male_pain_8.ogg b/sound/voice/human/male/pain_8.ogg
similarity index 100%
rename from sound/voice/human_male_pain_8.ogg
rename to sound/voice/human/male/pain_8.ogg
diff --git a/sound/voice/human_male_pain_9.ogg b/sound/voice/human/male/pain_9.ogg
similarity index 100%
rename from sound/voice/human_male_pain_9.ogg
rename to sound/voice/human/male/pain_9.ogg
diff --git a/sound/voice/human_male_preburst1.ogg b/sound/voice/human/male/preburst1.ogg
similarity index 100%
rename from sound/voice/human_male_preburst1.ogg
rename to sound/voice/human/male/preburst1.ogg
diff --git a/sound/voice/human_male_preburst10.ogg b/sound/voice/human/male/preburst10.ogg
similarity index 100%
rename from sound/voice/human_male_preburst10.ogg
rename to sound/voice/human/male/preburst10.ogg
diff --git a/sound/voice/human_male_preburst2.ogg b/sound/voice/human/male/preburst2.ogg
similarity index 100%
rename from sound/voice/human_male_preburst2.ogg
rename to sound/voice/human/male/preburst2.ogg
diff --git a/sound/voice/human_male_preburst3.ogg b/sound/voice/human/male/preburst3.ogg
similarity index 100%
rename from sound/voice/human_male_preburst3.ogg
rename to sound/voice/human/male/preburst3.ogg
diff --git a/sound/voice/human_male_preburst4.ogg b/sound/voice/human/male/preburst4.ogg
similarity index 100%
rename from sound/voice/human_male_preburst4.ogg
rename to sound/voice/human/male/preburst4.ogg
diff --git a/sound/voice/human_male_preburst5.ogg b/sound/voice/human/male/preburst5.ogg
similarity index 100%
rename from sound/voice/human_male_preburst5.ogg
rename to sound/voice/human/male/preburst5.ogg
diff --git a/sound/voice/human_male_preburst6.ogg b/sound/voice/human/male/preburst6.ogg
similarity index 100%
rename from sound/voice/human_male_preburst6.ogg
rename to sound/voice/human/male/preburst6.ogg
diff --git a/sound/voice/human_male_preburst7.ogg b/sound/voice/human/male/preburst7.ogg
similarity index 100%
rename from sound/voice/human_male_preburst7.ogg
rename to sound/voice/human/male/preburst7.ogg
diff --git a/sound/voice/human_male_preburst8.ogg b/sound/voice/human/male/preburst8.ogg
similarity index 100%
rename from sound/voice/human_male_preburst8.ogg
rename to sound/voice/human/male/preburst8.ogg
diff --git a/sound/voice/human_male_preburst9.ogg b/sound/voice/human/male/preburst9.ogg
similarity index 100%
rename from sound/voice/human_male_preburst9.ogg
rename to sound/voice/human/male/preburst9.ogg
diff --git a/sound/voice/human_male_scream_1.ogg b/sound/voice/human/male/scream_1.ogg
similarity index 100%
rename from sound/voice/human_male_scream_1.ogg
rename to sound/voice/human/male/scream_1.ogg
diff --git a/sound/voice/human_male_scream_2.ogg b/sound/voice/human/male/scream_2.ogg
similarity index 100%
rename from sound/voice/human_male_scream_2.ogg
rename to sound/voice/human/male/scream_2.ogg
diff --git a/sound/voice/human_male_scream_3.ogg b/sound/voice/human/male/scream_3.ogg
similarity index 100%
rename from sound/voice/human_male_scream_3.ogg
rename to sound/voice/human/male/scream_3.ogg
diff --git a/sound/voice/human_male_scream_4.ogg b/sound/voice/human/male/scream_4.ogg
similarity index 100%
rename from sound/voice/human_male_scream_4.ogg
rename to sound/voice/human/male/scream_4.ogg
diff --git a/sound/voice/human_male_scream_5.ogg b/sound/voice/human/male/scream_5.ogg
similarity index 100%
rename from sound/voice/human_male_scream_5.ogg
rename to sound/voice/human/male/scream_5.ogg
diff --git a/sound/voice/human_male_scream_6.ogg b/sound/voice/human/male/scream_6.ogg
similarity index 100%
rename from sound/voice/human_male_scream_6.ogg
rename to sound/voice/human/male/scream_6.ogg
diff --git a/sound/voice/human_male_scream_7.ogg b/sound/voice/human/male/scream_7.ogg
similarity index 100%
rename from sound/voice/human_male_scream_7.ogg
rename to sound/voice/human/male/scream_7.ogg
diff --git a/sound/voice/human_male_sigh_1.ogg b/sound/voice/human/male/sigh_1.ogg
similarity index 100%
rename from sound/voice/human_male_sigh_1.ogg
rename to sound/voice/human/male/sigh_1.ogg
diff --git a/sound/voice/human_male_warcry_1.ogg b/sound/voice/human/male/warcry_1.ogg
similarity index 100%
rename from sound/voice/human_male_warcry_1.ogg
rename to sound/voice/human/male/warcry_1.ogg
diff --git a/sound/voice/human_male_warcry_10.ogg b/sound/voice/human/male/warcry_10.ogg
similarity index 100%
rename from sound/voice/human_male_warcry_10.ogg
rename to sound/voice/human/male/warcry_10.ogg
diff --git a/sound/voice/human_male_warcry_11.ogg b/sound/voice/human/male/warcry_11.ogg
similarity index 100%
rename from sound/voice/human_male_warcry_11.ogg
rename to sound/voice/human/male/warcry_11.ogg
diff --git a/sound/voice/human_male_warcry_12.ogg b/sound/voice/human/male/warcry_12.ogg
similarity index 100%
rename from sound/voice/human_male_warcry_12.ogg
rename to sound/voice/human/male/warcry_12.ogg
diff --git a/sound/voice/human_male_warcry_13.ogg b/sound/voice/human/male/warcry_13.ogg
similarity index 100%
rename from sound/voice/human_male_warcry_13.ogg
rename to sound/voice/human/male/warcry_13.ogg
diff --git a/sound/voice/human_male_warcry_14.ogg b/sound/voice/human/male/warcry_14.ogg
similarity index 100%
rename from sound/voice/human_male_warcry_14.ogg
rename to sound/voice/human/male/warcry_14.ogg
diff --git a/sound/voice/human_male_warcry_15.ogg b/sound/voice/human/male/warcry_15.ogg
similarity index 100%
rename from sound/voice/human_male_warcry_15.ogg
rename to sound/voice/human/male/warcry_15.ogg
diff --git a/sound/voice/human_male_warcry_16.ogg b/sound/voice/human/male/warcry_16.ogg
similarity index 100%
rename from sound/voice/human_male_warcry_16.ogg
rename to sound/voice/human/male/warcry_16.ogg
diff --git a/sound/voice/human_male_warcry_17.ogg b/sound/voice/human/male/warcry_17.ogg
similarity index 100%
rename from sound/voice/human_male_warcry_17.ogg
rename to sound/voice/human/male/warcry_17.ogg
diff --git a/sound/voice/human_male_warcry_18.ogg b/sound/voice/human/male/warcry_18.ogg
similarity index 100%
rename from sound/voice/human_male_warcry_18.ogg
rename to sound/voice/human/male/warcry_18.ogg
diff --git a/sound/voice/human_male_warcry_19.ogg b/sound/voice/human/male/warcry_19.ogg
similarity index 100%
rename from sound/voice/human_male_warcry_19.ogg
rename to sound/voice/human/male/warcry_19.ogg
diff --git a/sound/voice/human_male_warcry_2.ogg b/sound/voice/human/male/warcry_2.ogg
similarity index 100%
rename from sound/voice/human_male_warcry_2.ogg
rename to sound/voice/human/male/warcry_2.ogg
diff --git a/sound/voice/human_male_warcry_20.ogg b/sound/voice/human/male/warcry_20.ogg
similarity index 100%
rename from sound/voice/human_male_warcry_20.ogg
rename to sound/voice/human/male/warcry_20.ogg
diff --git a/sound/voice/human_male_warcry_21.ogg b/sound/voice/human/male/warcry_21.ogg
similarity index 100%
rename from sound/voice/human_male_warcry_21.ogg
rename to sound/voice/human/male/warcry_21.ogg
diff --git a/sound/voice/human_male_warcry_22.ogg b/sound/voice/human/male/warcry_22.ogg
similarity index 100%
rename from sound/voice/human_male_warcry_22.ogg
rename to sound/voice/human/male/warcry_22.ogg
diff --git a/sound/voice/human_male_warcry_23.ogg b/sound/voice/human/male/warcry_23.ogg
similarity index 100%
rename from sound/voice/human_male_warcry_23.ogg
rename to sound/voice/human/male/warcry_23.ogg
diff --git a/sound/voice/human_male_warcry_24.ogg b/sound/voice/human/male/warcry_24.ogg
similarity index 100%
rename from sound/voice/human_male_warcry_24.ogg
rename to sound/voice/human/male/warcry_24.ogg
diff --git a/sound/voice/human_male_warcry_25.ogg b/sound/voice/human/male/warcry_25.ogg
similarity index 100%
rename from sound/voice/human_male_warcry_25.ogg
rename to sound/voice/human/male/warcry_25.ogg
diff --git a/sound/voice/human_male_warcry_26.ogg b/sound/voice/human/male/warcry_26.ogg
similarity index 100%
rename from sound/voice/human_male_warcry_26.ogg
rename to sound/voice/human/male/warcry_26.ogg
diff --git a/sound/voice/human_male_warcry_27.ogg b/sound/voice/human/male/warcry_27.ogg
similarity index 100%
rename from sound/voice/human_male_warcry_27.ogg
rename to sound/voice/human/male/warcry_27.ogg
diff --git a/sound/voice/human_male_warcry_28.ogg b/sound/voice/human/male/warcry_28.ogg
similarity index 100%
rename from sound/voice/human_male_warcry_28.ogg
rename to sound/voice/human/male/warcry_28.ogg
diff --git a/sound/voice/human_male_warcry_29.ogg b/sound/voice/human/male/warcry_29.ogg
similarity index 100%
rename from sound/voice/human_male_warcry_29.ogg
rename to sound/voice/human/male/warcry_29.ogg
diff --git a/sound/voice/human_male_warcry_3.ogg b/sound/voice/human/male/warcry_3.ogg
similarity index 100%
rename from sound/voice/human_male_warcry_3.ogg
rename to sound/voice/human/male/warcry_3.ogg
diff --git a/sound/voice/human_male_warcry_4.ogg b/sound/voice/human/male/warcry_4.ogg
similarity index 100%
rename from sound/voice/human_male_warcry_4.ogg
rename to sound/voice/human/male/warcry_4.ogg
diff --git a/sound/voice/human_male_warcry_5.ogg b/sound/voice/human/male/warcry_5.ogg
similarity index 100%
rename from sound/voice/human_male_warcry_5.ogg
rename to sound/voice/human/male/warcry_5.ogg
diff --git a/sound/voice/human_male_warcry_6.ogg b/sound/voice/human/male/warcry_6.ogg
similarity index 100%
rename from sound/voice/human_male_warcry_6.ogg
rename to sound/voice/human/male/warcry_6.ogg
diff --git a/sound/voice/human_male_warcry_7.ogg b/sound/voice/human/male/warcry_7.ogg
similarity index 100%
rename from sound/voice/human_male_warcry_7.ogg
rename to sound/voice/human/male/warcry_7.ogg
diff --git a/sound/voice/human_male_warcry_8.ogg b/sound/voice/human/male/warcry_8.ogg
similarity index 100%
rename from sound/voice/human_male_warcry_8.ogg
rename to sound/voice/human/male/warcry_8.ogg
diff --git a/sound/voice/human_male_warcry_9.ogg b/sound/voice/human/male/warcry_9.ogg
similarity index 100%
rename from sound/voice/human_male_warcry_9.ogg
rename to sound/voice/human/male/warcry_9.ogg
diff --git a/sound/voice/human_male_yawn_1.ogg b/sound/voice/human/male/yawn_1.ogg
similarity index 100%
rename from sound/voice/human_male_yawn_1.ogg
rename to sound/voice/human/male/yawn_1.ogg
diff --git a/sound/voice/sound_voice_human_whistle1.ogg b/sound/voice/human/whistle1.ogg
similarity index 100%
rename from sound/voice/sound_voice_human_whistle1.ogg
rename to sound/voice/human/whistle1.ogg
diff --git a/sound/voice/liveagain.ogg b/sound/voice/liveagain.ogg
deleted file mode 100644
index c2c1df9bc37..00000000000
Binary files a/sound/voice/liveagain.ogg and /dev/null differ
diff --git a/sound/voice/pred_anytime.ogg b/sound/voice/predator/anytime.ogg
similarity index 100%
rename from sound/voice/pred_anytime.ogg
rename to sound/voice/predator/anytime.ogg
diff --git a/sound/voice/pred_click1.ogg b/sound/voice/predator/click1.ogg
similarity index 100%
rename from sound/voice/pred_click1.ogg
rename to sound/voice/predator/click1.ogg
diff --git a/sound/voice/pred_click2.ogg b/sound/voice/predator/click2.ogg
similarity index 100%
rename from sound/voice/pred_click2.ogg
rename to sound/voice/predator/click2.ogg
diff --git a/sound/voice/pred_click3.ogg b/sound/voice/predator/click3.ogg
similarity index 100%
rename from sound/voice/pred_click3.ogg
rename to sound/voice/predator/click3.ogg
diff --git a/sound/voice/pred_click4.ogg b/sound/voice/predator/click4.ogg
similarity index 100%
rename from sound/voice/pred_click4.ogg
rename to sound/voice/predator/click4.ogg
diff --git a/sound/voice/pred_click5.ogg b/sound/voice/predator/click5.ogg
similarity index 100%
rename from sound/voice/pred_click5.ogg
rename to sound/voice/predator/click5.ogg
diff --git a/sound/voice/pred_come_on_out.ogg b/sound/voice/predator/come_on_out.ogg
similarity index 100%
rename from sound/voice/pred_come_on_out.ogg
rename to sound/voice/predator/come_on_out.ogg
diff --git a/sound/voice/pred_deathlaugh.ogg b/sound/voice/predator/deathlaugh.ogg
similarity index 100%
rename from sound/voice/pred_deathlaugh.ogg
rename to sound/voice/predator/deathlaugh.ogg
diff --git a/sound/voice/pred_facehugged.ogg b/sound/voice/predator/facehugged.ogg
similarity index 100%
rename from sound/voice/pred_facehugged.ogg
rename to sound/voice/predator/facehugged.ogg
diff --git a/sound/voice/pred_helpme.ogg b/sound/voice/predator/helpme.ogg
similarity index 100%
rename from sound/voice/pred_helpme.ogg
rename to sound/voice/predator/helpme.ogg
diff --git a/sound/voice/pred_itsatrap.ogg b/sound/voice/predator/itsatrap.ogg
similarity index 100%
rename from sound/voice/pred_itsatrap.ogg
rename to sound/voice/predator/itsatrap.ogg
diff --git a/sound/voice/pred_laugh1.ogg b/sound/voice/predator/laugh1.ogg
similarity index 100%
rename from sound/voice/pred_laugh1.ogg
rename to sound/voice/predator/laugh1.ogg
diff --git a/sound/voice/pred_laugh2.ogg b/sound/voice/predator/laugh2.ogg
similarity index 100%
rename from sound/voice/pred_laugh2.ogg
rename to sound/voice/predator/laugh2.ogg
diff --git a/sound/voice/pred_laugh3.ogg b/sound/voice/predator/laugh3.ogg
similarity index 100%
rename from sound/voice/pred_laugh3.ogg
rename to sound/voice/predator/laugh3.ogg
diff --git a/sound/voice/pred_laugh4.ogg b/sound/voice/predator/laugh4.ogg
similarity index 100%
rename from sound/voice/pred_laugh4.ogg
rename to sound/voice/predator/laugh4.ogg
diff --git a/sound/voice/pred_over_there.ogg b/sound/voice/predator/over_there.ogg
similarity index 100%
rename from sound/voice/pred_over_there.ogg
rename to sound/voice/predator/over_there.ogg
diff --git a/sound/voice/pred_overhere.ogg b/sound/voice/predator/overhere.ogg
similarity index 100%
rename from sound/voice/pred_overhere.ogg
rename to sound/voice/predator/overhere.ogg
diff --git a/sound/voice/pred_pain1.ogg b/sound/voice/predator/pain1.ogg
similarity index 100%
rename from sound/voice/pred_pain1.ogg
rename to sound/voice/predator/pain1.ogg
diff --git a/sound/voice/pred_pain2.ogg b/sound/voice/predator/pain2.ogg
similarity index 100%
rename from sound/voice/pred_pain2.ogg
rename to sound/voice/predator/pain2.ogg
diff --git a/sound/voice/pred_pain3.ogg b/sound/voice/predator/pain3.ogg
similarity index 100%
rename from sound/voice/pred_pain3.ogg
rename to sound/voice/predator/pain3.ogg
diff --git a/sound/voice/pred_pain4.ogg b/sound/voice/predator/pain4.ogg
similarity index 100%
rename from sound/voice/pred_pain4.ogg
rename to sound/voice/predator/pain4.ogg
diff --git a/sound/voice/pred_pain5.ogg b/sound/voice/predator/pain5.ogg
similarity index 100%
rename from sound/voice/pred_pain5.ogg
rename to sound/voice/predator/pain5.ogg
diff --git a/sound/voice/pred_pain_rare1.ogg b/sound/voice/predator/pain_rare1.ogg
similarity index 100%
rename from sound/voice/pred_pain_rare1.ogg
rename to sound/voice/predator/pain_rare1.ogg
diff --git a/sound/voice/pred_roar1.ogg b/sound/voice/predator/roar1.ogg
similarity index 100%
rename from sound/voice/pred_roar1.ogg
rename to sound/voice/predator/roar1.ogg
diff --git a/sound/voice/pred_roar2.ogg b/sound/voice/predator/roar2.ogg
similarity index 100%
rename from sound/voice/pred_roar2.ogg
rename to sound/voice/predator/roar2.ogg
diff --git a/sound/voice/pred_roar3.ogg b/sound/voice/predator/roar3.ogg
similarity index 100%
rename from sound/voice/pred_roar3.ogg
rename to sound/voice/predator/roar3.ogg
diff --git a/sound/voice/pred_roar4.ogg b/sound/voice/predator/roar4.ogg
similarity index 100%
rename from sound/voice/pred_roar4.ogg
rename to sound/voice/predator/roar4.ogg
diff --git a/sound/voice/pred_roar5.ogg b/sound/voice/predator/roar5.ogg
similarity index 100%
rename from sound/voice/pred_roar5.ogg
rename to sound/voice/predator/roar5.ogg
diff --git a/sound/voice/pred_turnaround.ogg b/sound/voice/predator/turnaround.ogg
similarity index 100%
rename from sound/voice/pred_turnaround.ogg
rename to sound/voice/predator/turnaround.ogg
diff --git a/sound/voice/pred_ugly_freak.ogg b/sound/voice/predator/ugly_freak.ogg
similarity index 100%
rename from sound/voice/pred_ugly_freak.ogg
rename to sound/voice/predator/ugly_freak.ogg
diff --git a/sound/voice/pred_warcry.ogg b/sound/voice/predator/warcry.ogg
similarity index 100%
rename from sound/voice/pred_warcry.ogg
rename to sound/voice/predator/warcry.ogg
diff --git a/tgmc.dme b/tgmc.dme
index b270e7fba12..538661d656e 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"
@@ -1234,7 +1231,6 @@
#include "code\modules\admin\view_variables\reference_tracking.dm"
#include "code\modules\ai\ai_node.dm"
#include "code\modules\ai\ai_behaviors\ai_behavior.dm"
-#include "code\modules\ai\ai_behaviors\xeno\puppet.dm"
#include "code\modules\ai\ai_behaviors\xeno\xeno.dm"
#include "code\modules\ai\ai_behaviors\xeno\xeno_illusion.dm"
#include "code\modules\ai\ai_behaviors\xeno\zombie.dm"
@@ -1728,12 +1724,6 @@
#include "code\modules\mob\living\carbon\xenomorph\castes\predalien\abilities_predalien.dm"
#include "code\modules\mob\living\carbon\xenomorph\castes\predalien\castedatum_predalien.dm"
#include "code\modules\mob\living\carbon\xenomorph\castes\predalien\predalien.dm"
-#include "code\modules\mob\living\carbon\xenomorph\castes\puppet\abilities_puppet.dm"
-#include "code\modules\mob\living\carbon\xenomorph\castes\puppet\castedatum_puppet.dm"
-#include "code\modules\mob\living\carbon\xenomorph\castes\puppet\puppet.dm"
-#include "code\modules\mob\living\carbon\xenomorph\castes\puppeteer\abilities_puppeteer.dm"
-#include "code\modules\mob\living\carbon\xenomorph\castes\puppeteer\castedatum_puppeteer.dm"
-#include "code\modules\mob\living\carbon\xenomorph\castes\puppeteer\puppeteer.dm"
#include "code\modules\mob\living\carbon\xenomorph\castes\queen\abilities_queen.dm"
#include "code\modules\mob\living\carbon\xenomorph\castes\queen\castedatum_queen.dm"
#include "code\modules\mob\living\carbon\xenomorph\castes\queen\queen.dm"
@@ -1751,8 +1741,6 @@
#include "code\modules\mob\living\carbon\xenomorph\castes\shrike\abilities_shrike.dm"
#include "code\modules\mob\living\carbon\xenomorph\castes\shrike\castedatum_shrike.dm"
#include "code\modules\mob\living\carbon\xenomorph\castes\shrike\shrike.dm"
-#include "code\modules\mob\living\carbon\xenomorph\castes\spiderling\castedatum_spiderling.dm"
-#include "code\modules\mob\living\carbon\xenomorph\castes\spiderling\spiderling.dm"
#include "code\modules\mob\living\carbon\xenomorph\castes\spitter\abilities_spitter.dm"
#include "code\modules\mob\living\carbon\xenomorph\castes\spitter\castedatum_spitter.dm"
#include "code\modules\mob\living\carbon\xenomorph\castes\spitter\spitter.dm"
@@ -1762,12 +1750,6 @@
#include "code\modules\mob\living\carbon\xenomorph\castes\warrior\abilities_warrior.dm"
#include "code\modules\mob\living\carbon\xenomorph\castes\warrior\castedatum_warrior.dm"
#include "code\modules\mob\living\carbon\xenomorph\castes\warrior\warrior.dm"
-#include "code\modules\mob\living\carbon\xenomorph\castes\widow\abilities_widow.dm"
-#include "code\modules\mob\living\carbon\xenomorph\castes\widow\castedatum_widow.dm"
-#include "code\modules\mob\living\carbon\xenomorph\castes\widow\widow.dm"
-#include "code\modules\mob\living\carbon\xenomorph\castes\wraith\abilities_wraith.dm"
-#include "code\modules\mob\living\carbon\xenomorph\castes\wraith\castedatum_wraith.dm"
-#include "code\modules\mob\living\carbon\xenomorph\castes\wraith\wraith.dm"
#include "code\modules\mob\living\silicon\death.dm"
#include "code\modules\mob\living\silicon\say.dm"
#include "code\modules\mob\living\silicon\silicon.dm"
@@ -1875,8 +1857,8 @@
#include "code\modules\predator\yautja\machines.dm"
#include "code\modules\predator\yautja\mask.dm"
#include "code\modules\predator\yautja\procs.dm"
-#include "code\modules\predator\yautja\shield.dm"
#include "code\modules\predator\yautja\rope.dm"
+#include "code\modules\predator\yautja\shield.dm"
#include "code\modules\predator\yautja\weapons\misc_weapons.dm"
#include "code\modules\predator\yautja\weapons\one_handed.dm"
#include "code\modules\predator\yautja\weapons\ranged.dm"
@@ -2108,7 +2090,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"