diff --git a/code/__DEFINES/typecheck/xenos.dm b/code/__DEFINES/typecheck/xenos.dm index 34b70ac92f45..57d10f8e935b 100644 --- a/code/__DEFINES/typecheck/xenos.dm +++ b/code/__DEFINES/typecheck/xenos.dm @@ -3,6 +3,7 @@ #define isxeno_human(A) (isxeno(A) || ishuman(A)) //ask walter if i should turn into castechecks +#define isreaper(A) (istype(A, /mob/living/carbon/xenomorph/reaper)) #define isboiler(A) (istype(A, /mob/living/carbon/xenomorph/boiler)) #define iscarrier(A) (istype(A, /mob/living/carbon/xenomorph/carrier)) #define iscrusher(A) (istype(A, /mob/living/carbon/xenomorph/crusher)) diff --git a/code/__DEFINES/xeno.dm b/code/__DEFINES/xeno.dm index 6f6e4eef7c20..fcd13a995790 100644 --- a/code/__DEFINES/xeno.dm +++ b/code/__DEFINES/xeno.dm @@ -263,6 +263,7 @@ #define XENO_PLASMA_TIER_6 600 * XENO_UNIVERSAL_PLASMAMULT #define XENO_PLASMA_TIER_8 800 * XENO_UNIVERSAL_PLASMAMULT #define XENO_PLASMA_TIER_10 1000 * XENO_UNIVERSAL_PLASMAMULT +#define XENO_PLASMA_TIER_12 2000 * XENO_UNIVERSAL_PLASMAMULT // Plasma gain bands #define XENO_PLASMA_GAIN_TIER_1 1 @@ -685,11 +686,12 @@ #define XENO_CASTE_SPITTER "Spitter" #define XENO_T2_CASTES list(XENO_CASTE_BURROWER, XENO_CASTE_CARRIER, XENO_CASTE_HIVELORD, XENO_CASTE_LURKER, XENO_CASTE_WARRIOR, XENO_CASTE_SPITTER) //t3 +#define XENO_CASTE_REAPER "Reaper" #define XENO_CASTE_BOILER "Boiler" #define XENO_CASTE_PRAETORIAN "Praetorian" #define XENO_CASTE_CRUSHER "Crusher" #define XENO_CASTE_RAVAGER "Ravager" -#define XENO_T3_CASTES list(XENO_CASTE_BOILER, XENO_CASTE_PRAETORIAN, XENO_CASTE_CRUSHER, XENO_CASTE_RAVAGER) +#define XENO_T3_CASTES list(XENO_CASTE_BOILER, XENO_CASTE_PRAETORIAN, XENO_CASTE_CRUSHER, XENO_CASTE_RAVAGER, XENO_CASTE_REAPER) //special #define XENO_CASTE_QUEEN "Queen" #define XENO_CASTE_PREDALIEN "Predalien" diff --git a/code/_globalvars/global_lists.dm b/code/_globalvars/global_lists.dm index 7d9cd3324067..280b612e994e 100644 --- a/code/_globalvars/global_lists.dm +++ b/code/_globalvars/global_lists.dm @@ -70,6 +70,18 @@ GLOBAL_LIST_INIT(resin_build_order_drone, list( /datum/resin_construction/resin_obj/resin_spike )) +GLOBAL_LIST_INIT(resin_build_order_reaper, list( + /datum/resin_construction/resin_turf/wall/thick, + /datum/resin_construction/resin_turf/wall/reflective, + /datum/resin_construction/resin_turf/membrane/thick, + /datum/resin_construction/resin_obj/door/thick, + /datum/resin_construction/resin_obj/acid_pillar, + /datum/resin_construction/resin_obj/sticky_resin, + /datum/resin_construction/resin_obj/fast_resin, + /datum/resin_construction/resin_obj/resin_spike, + /datum/resin_construction/resin_obj/shield_dispenser +)) + GLOBAL_LIST_INIT(resin_build_order_hivelord, list( /datum/resin_construction/resin_turf/wall/thick, /datum/resin_construction/resin_turf/wall/reflective, @@ -78,7 +90,7 @@ GLOBAL_LIST_INIT(resin_build_order_hivelord, list( /datum/resin_construction/resin_obj/acid_pillar, /datum/resin_construction/resin_obj/sticky_resin, /datum/resin_construction/resin_obj/fast_resin, - /datum/resin_construction/resin_obj/resin_spike + /datum/resin_construction/resin_obj/resin_spike, )) GLOBAL_LIST_INIT(resin_build_order_hivelord_whisperer, list( diff --git a/code/game/jobs/role_authority.dm b/code/game/jobs/role_authority.dm index 58c9ad5b5092..c34f5b5516a7 100644 --- a/code/game/jobs/role_authority.dm +++ b/code/game/jobs/role_authority.dm @@ -760,6 +760,8 @@ I hope it's easier to tell what the heck this proc is even doing, unlike previou M = /mob/living/carbon/xenomorph/predalien if(XENO_CASTE_HELLHOUND) M = /mob/living/carbon/xenomorph/hellhound + if(XENO_CASTE_REAPER) + M = /mob/living/carbon/xenomorph/reaper return M diff --git a/code/game/objects/items/explosives/grenades/xeno_nades.dm b/code/game/objects/items/explosives/grenades/xeno_nades.dm index 7925434e2fb4..e037fe6504ee 100644 --- a/code/game/objects/items/explosives/grenades/xeno_nades.dm +++ b/code/game/objects/items/explosives/grenades/xeno_nades.dm @@ -15,3 +15,30 @@ create_shrapnel(loc, shrapnel_count, , ,shrapnel_type, cause_data) qdel(src) ..() + + + +/obj/item/explosive/grenade/xeno_weed_grenade + name = "Node Ball" + desc = "a small resin node pulsating and turning in itself." + icon_state = "neuro_nade" + det_time = 1 SECONDS + item_state = "neuro_nade" + + rebounds = FALSE + +/obj/item/explosive/grenade/xeno_weed_grenade/prime() + + + var/turf/current_turf = get_turf(src) + var/obj/effect/alien/weeds/weed = locate() in current_turf + + if((locate(/obj/effect/alien/weeds/node) in current_turf)) + qdel(src) + return + if(weed && weed.weed_strength >= WEED_LEVEL_HIVE) + qdel(src) + return + else + new /obj/effect/alien/weeds/node(current_turf) + qdel(src) diff --git a/code/modules/admin/player_panel/actions/transform.dm b/code/modules/admin/player_panel/actions/transform.dm index 91a62b1a1d02..0bf3c2b7f59a 100644 --- a/code/modules/admin/player_panel/actions/transform.dm +++ b/code/modules/admin/player_panel/actions/transform.dm @@ -122,6 +122,11 @@ GLOBAL_LIST_INIT(pp_transformables, list( name = XENO_CASTE_CRUSHER, key = /mob/living/carbon/xenomorph/crusher, color = "purple" + ), + list( + name = XENO_CASTE_REAPER, + key = /mob/living/carbon/xenomorph/reaper, + color = "purple" ) ), diff --git a/code/modules/cm_aliens/XenoStructures.dm b/code/modules/cm_aliens/XenoStructures.dm index ab38e59002d8..ee90c7327248 100644 --- a/code/modules/cm_aliens/XenoStructures.dm +++ b/code/modules/cm_aliens/XenoStructures.dm @@ -706,9 +706,9 @@ icon_state = "resin_pillar" invisibility = INVISIBILITY_MAXIMUM var/width = 3 - var/height = 3 - var/time_to_brittle = 45 SECONDS - var/time_to_collapse = 45 SECONDS + var/height = 1 + var/time_to_brittle = 5 SECONDS + var/time_to_collapse = 5 SECONDS var/turf_icon = WALL_THICKRESIN var/brittle_turf_icon = WALL_MEMBRANE diff --git a/code/modules/mob/living/carbon/xenomorph/Evolution.dm b/code/modules/mob/living/carbon/xenomorph/Evolution.dm index b6576b764b51..f4a03024780e 100644 --- a/code/modules/mob/living/carbon/xenomorph/Evolution.dm +++ b/code/modules/mob/living/carbon/xenomorph/Evolution.dm @@ -330,6 +330,8 @@ xeno_type = /mob/living/carbon/xenomorph/defender if(XENO_CASTE_BURROWER) xeno_type = /mob/living/carbon/xenomorph/burrower + if(XENO_CASTE_REAPER) + xeno_type = /mob/living/carbon/xenomorph/reaper var/mob/living/carbon/xenomorph/new_xeno = new xeno_type(get_turf(src), src) diff --git a/code/modules/mob/living/carbon/xenomorph/abilities/queen/queen_abilities.dm b/code/modules/mob/living/carbon/xenomorph/abilities/queen/queen_abilities.dm index 9ec61b4c95ca..f2d361f94302 100644 --- a/code/modules/mob/living/carbon/xenomorph/abilities/queen/queen_abilities.dm +++ b/code/modules/mob/living/carbon/xenomorph/abilities/queen/queen_abilities.dm @@ -161,21 +161,6 @@ SIGNAL_HANDLER hide_from(Q) - -/datum/action/xeno_action/activable/blockade - name = "Place Blockade" - action_icon_state = "place_blockade" - ability_name = "place blockade" - plasma_cost = 300 - action_type = XENO_ACTION_CLICK - - var/obj/effect/alien/resin/resin_pillar/pillar_type = /obj/effect/alien/resin/resin_pillar - var/time_taken = 6 SECONDS - charges = 0 - - var/brittle_time = 45 SECONDS - var/decay_time = 45 SECONDS - /datum/action/xeno_action/activable/blockade/give_to(mob/living/carbon/xenomorph/queen/Q) . = ..() if(!Q.ovipositor) diff --git a/code/modules/mob/living/carbon/xenomorph/abilities/queen/queen_powers.dm b/code/modules/mob/living/carbon/xenomorph/abilities/queen/queen_powers.dm index 1f37651b2c8e..9b993fe1521a 100644 --- a/code/modules/mob/living/carbon/xenomorph/abilities/queen/queen_powers.dm +++ b/code/modules/mob/living/carbon/xenomorph/abilities/queen/queen_powers.dm @@ -672,65 +672,6 @@ return TRUE -/datum/action/xeno_action/activable/blockade/use_ability(atom/A) - var/mob/living/carbon/xenomorph/queen/Q = owner - if(!Q.check_state()) - return FALSE - - if(!action_cooldown_check()) - return FALSE - - if(Q.action_busy) - return FALSE - - var/width = initial(pillar_type.width) - var/height = initial(pillar_type.height) - - var/turf/T = get_turf(A) - if(T.density) - to_chat(Q, SPAN_XENOWARNING("You can only construct this blockade in open areas!")) - return FALSE - - if(T.z != owner.z) - to_chat(Q, SPAN_XENOWARNING("That's too far away!")) - return FALSE - - if(!T.weeds) - to_chat(Q, SPAN_XENOWARNING("You can only construct this blockade on weeds!")) - return FALSE - - if(!Q.check_plasma(plasma_cost)) - return - - var/list/alerts = list() - for(var/i in RANGE_TURFS(Floor(width/2), T)) - alerts += new /obj/effect/warning/alien(i) - - if(!do_after(Q, time_taken, INTERRUPT_NO_NEEDHAND, BUSY_ICON_FRIENDLY)) - QDEL_NULL_LIST(alerts) - return FALSE - QDEL_NULL_LIST(alerts) - - if(!check_turf(Q, T)) - return FALSE - - if(!check_and_use_plasma_owner()) - return - - var/turf/new_turf = locate(max(T.x - Floor(width/2), 1), max(T.y - Floor(height/2), 1), T.z) - to_chat(Q, SPAN_XENONOTICE("You raise a blockade!")) - var/obj/effect/alien/resin/resin_pillar/RP = new pillar_type(new_turf) - RP.start_decay(brittle_time, decay_time) - - return ..() - -/datum/action/xeno_action/activable/blockade/proc/check_turf(mob/living/carbon/xenomorph/queen/Q, turf/T) - if(T.density) - to_chat(Q, SPAN_XENOWARNING("You can't place a blockade here.")) - return FALSE - - return TRUE - /mob/living/carbon/xenomorph/proc/xeno_tacmap() set name = "View Xeno Tacmap" set desc = "This opens a tactical map, where you can see where every xenomorph is." diff --git a/code/modules/mob/living/carbon/xenomorph/abilities/reaper/reaper_abilities.dm b/code/modules/mob/living/carbon/xenomorph/abilities/reaper/reaper_abilities.dm new file mode 100644 index 000000000000..04ece7d61400 --- /dev/null +++ b/code/modules/mob/living/carbon/xenomorph/abilities/reaper/reaper_abilities.dm @@ -0,0 +1,25 @@ +/datum/action/xeno_action/activable/blockade + name = "Place Blockade" + action_icon_state = "place_blockade" + ability_name = "place blockade" + plasma_cost = 300 + action_type = XENO_ACTION_CLICK + xeno_cooldown = 15 SECONDS + + var/obj/effect/alien/resin/resin_pillar/pillar_type = /obj/effect/alien/resin/resin_pillar + var/time_taken = 1 SECONDS + + var/brittle_time = 5 SECONDS + var/decay_time = 5 SECONDS + + +/datum/action/xeno_action/activable/weed_nade + name = "Lob Resin" + action_icon_state = "prae_dodge" + plasma_cost = 300 + action_type = XENO_ACTION_CLICK + xeno_cooldown = 10 SECONDS + + var/explode_delay = 1 SECONDS + var/priming_delay = 1 SECONDS + diff --git a/code/modules/mob/living/carbon/xenomorph/abilities/reaper/reaper_powers.dm b/code/modules/mob/living/carbon/xenomorph/abilities/reaper/reaper_powers.dm new file mode 100644 index 000000000000..4d2b3b50c825 --- /dev/null +++ b/code/modules/mob/living/carbon/xenomorph/abilities/reaper/reaper_powers.dm @@ -0,0 +1,84 @@ +/datum/action/xeno_action/activable/blockade/use_ability(atom/A) // blockade, this abiltiy should always either last a short time or the walls should be destructible in 1-3 hits. + var/mob/living/carbon/xenomorph/reaper = owner + if(!reaper.check_state()) + return FALSE + + if(!action_cooldown_check()) + return FALSE + + if(reaper.action_busy) + return FALSE + + var/width = initial(pillar_type.width) + var/height = initial(pillar_type.height) + + var/turf/active_turf = get_turf(A) + if((locate (/obj/effect/alien/weeds/node/pylon/core) in active_turf)) //core has resin node in it, wall ontop of resin node deletes it, wall ontop of hive core delets all hive weeds if put ontop of it. + return FALSE + if(active_turf.density) + to_chat(reaper, SPAN_XENOWARNING("We can only construct this blockade in open areas!")) + return FALSE + + if(active_turf.z != owner.z) + to_chat(reaper, SPAN_XENOWARNING("That's too far away!")) + return FALSE + + if(!active_turf.weeds) + to_chat(reaper, SPAN_XENOWARNING("We can only construct this blockade on weeds!")) + return FALSE + + if(!reaper.check_plasma(plasma_cost)) + return + + + if(!check_turf(reaper, active_turf)) + return FALSE + + if(!check_and_use_plasma_owner()) + return + + var/turf/new_turf = locate(max(active_turf.x - Floor(width/2), 1), max(active_turf.y - Floor(height/2), 1), active_turf.z) + to_chat(reaper, SPAN_XENONOTICE("We raise a blockade!")) + var/obj/effect/alien/resin/resin_pillar/resin_blockade = new pillar_type(new_turf) + resin_blockade.start_decay(brittle_time, decay_time) + apply_cooldown() + return ..() + + + +/datum/action/xeno_action/activable/blockade/proc/check_turf(mob/living/carbon/xenomorph/reaper, turf/T) + if(T.density) + to_chat(reaper, SPAN_XENOWARNING("We can't place a blockade here.")) + return FALSE + + return TRUE + + + + +/datum/action/xeno_action/activable/weed_nade/use_ability(atom/A) // weed nade + var/mob/living/carbon/xenomorph/reaper_spit = owner + if (!reaper_spit.check_state() || reaper_spit.action_busy) + return + if (!action_cooldown_check()) + return + if (!check_and_use_plasma_owner()) + return + + var/turf/current_turf = get_turf(reaper_spit) + + if (!current_turf) + return + + if (!do_after(reaper_spit, explode_delay, INTERRUPT_ALL | BEHAVIOR_IMMOBILE, BUSY_ICON_HOSTILE)) + to_chat(reaper_spit, SPAN_XENODANGER("We stop preparing a resin node in our glands.")) + return + + apply_cooldown() + to_chat(reaper_spit, SPAN_XENOWARNING("We throw a resin node through the air.")) + + var/obj/item/explosive/grenade/xeno_weed_grenade/reaper_grenade = new /obj/item/explosive/grenade/xeno_weed_grenade + reaper_grenade.cause_data = create_cause_data(initial(reaper_spit.caste_type), reaper_spit) + reaper_grenade.forceMove(get_turf(reaper_spit)) + reaper_grenade.throw_atom(A, 5, SPEED_SLOW, reaper_spit, TRUE) + addtimer(CALLBACK(reaper_grenade, TYPE_PROC_REF(/obj/item/explosive, prime)), priming_delay) diff --git a/code/modules/mob/living/carbon/xenomorph/castes/Drone.dm b/code/modules/mob/living/carbon/xenomorph/castes/Drone.dm index a0ce70316eb8..8a8d5d9269c0 100644 --- a/code/modules/mob/living/carbon/xenomorph/castes/Drone.dm +++ b/code/modules/mob/living/carbon/xenomorph/castes/Drone.dm @@ -20,7 +20,7 @@ build_time_mult = BUILD_TIME_MULT_BUILDER caste_desc = "A builder of hives. Only drones may evolve into Queens." - evolves_to = list(XENO_CASTE_QUEEN, XENO_CASTE_BURROWER, XENO_CASTE_CARRIER, XENO_CASTE_HIVELORD) //Add more here separated by commas + evolves_to = list(XENO_CASTE_QUEEN, XENO_CASTE_BURROWER, XENO_CASTE_CARRIER, XENO_CASTE_HIVELORD, XENO_CASTE_REAPER) //Add more here separated by commas deevolves_to = list("Larva") can_hold_facehuggers = 1 can_hold_eggs = CAN_HOLD_TWO_HANDS diff --git a/code/modules/mob/living/carbon/xenomorph/castes/Reaper.dm b/code/modules/mob/living/carbon/xenomorph/castes/Reaper.dm new file mode 100644 index 000000000000..ab10b86c5d1d --- /dev/null +++ b/code/modules/mob/living/carbon/xenomorph/castes/Reaper.dm @@ -0,0 +1,79 @@ +/datum/caste_datum/Reaper + caste_type = XENO_CASTE_REAPER + tier = 3 + + melee_damage_lower = XENO_DAMAGE_TIER_4 + melee_damage_upper = XENO_DAMAGE_TIER_5 + melee_vehicle_damage = XENO_DAMAGE_TIER_9 + max_health = XENO_HEALTH_TIER_9 + plasma_gain = XENO_PLASMA_GAIN_TIER_7 + plasma_max = XENO_PLASMA_TIER_12 + xeno_explosion_resistance = XENO_EXPLOSIVE_ARMOR_TIER_4 + armor_deflection = XENO_ARMOR_TIER_2 + evasion = XENO_EVASION_NONE + speed = XENO_SPEED_FASTMOD_TIER_6 + + build_time_mult = BUILD_TIME_MULT_BUILDER + max_build_dist = 1 + + is_intelligent = 1 + evolution_allowed = FALSE + caste_desc = "john reaper" // temporary + deevolves_to = list("Larva") + can_hold_facehuggers = 1 + can_hold_eggs = CAN_HOLD_ONE_HAND + acid_level = 2 + weed_level = WEED_LEVEL_STANDARD + can_be_revived = FALSE + + tackle_min = 2 + tackle_max = 6 + tackle_chance = 55 + + aura_strength = 4 + tacklestrength_min = 5 + tacklestrength_max = 6 + + +/mob/living/carbon/xenomorph/reaper + caste_type = XENO_CASTE_REAPER + name = XENO_CASTE_REAPER + desc = "An alien reaper" + icon_size = 64 + icon_state = "Reaper Walking" + plasma_types = list(PLASMA_EGG, PLASMA_CATECHOLAMINE) + tier = 3 + pixel_x = -12 + old_x = -12 + base_actions = list( + /datum/action/xeno_action/onclick/xeno_resting, + /datum/action/xeno_action/onclick/regurgitate, + /datum/action/xeno_action/watch_xeno, + /datum/action/xeno_action/activable/tail_stab, + /datum/action/xeno_action/activable/corrosive_acid/weak, + /datum/action/xeno_action/onclick/emit_pheromones, + /datum/action/xeno_action/activable/place_construction, + /datum/action/xeno_action/onclick/plant_weeds, //first macro + /datum/action/xeno_action/onclick/choose_resin, //second macro + /datum/action/xeno_action/activable/secrete_resin, //third macro + /datum/action/xeno_action/activable/queen_give_plasma, //fourth macro + /datum/action/xeno_action/onclick/tacmap, + /datum/action/xeno_action/activable/blockade, + /datum/action/xeno_action/activable/weed_nade, + ) + + icon_xeno = 'icons/mob/xenos/reaper.dmi' + icon_xenonid = 'icons/mob/xenonids/praetorian.dmi' + + inherent_verbs = list( + /mob/living/carbon/xenomorph/proc/rename_tunnel, + /mob/living/carbon/xenomorph/proc/set_hugger_reserve_for_morpher, + ) + +/datum/caste_datum/Reaper/New() + . = ..() + + resin_build_order = GLOB.resin_build_order_reaper + + + diff --git a/code/modules/mob/living/carbon/xenomorph/resin_constructions.dm b/code/modules/mob/living/carbon/xenomorph/resin_constructions.dm index 793ed45bcb13..73207bf58107 100644 --- a/code/modules/mob/living/carbon/xenomorph/resin_constructions.dm +++ b/code/modules/mob/living/carbon/xenomorph/resin_constructions.dm @@ -281,6 +281,7 @@ GLOBAL_VAR_INIT(resin_lz_allowed, FALSE) construction_name = "shield pillar" cost = XENO_RESIN_SHIELD_PILLAR_COST max_per_xeno = 1 + build_overlay_icon = /obj/effect/warning/alien/weak build_path = /obj/effect/alien/resin/shield_pillar build_time = 12 SECONDS diff --git a/colonialmarines.dme b/colonialmarines.dme index 602e4fa9de30..1d6049be9a9f 100644 --- a/colonialmarines.dme +++ b/colonialmarines.dme @@ -2013,6 +2013,8 @@ #include "code\modules\mob\living\carbon\xenomorph\abilities\ravager\ravager_abilities.dm" #include "code\modules\mob\living\carbon\xenomorph\abilities\ravager\ravager_macros.dm" #include "code\modules\mob\living\carbon\xenomorph\abilities\ravager\ravager_powers.dm" +#include "code\modules\mob\living\carbon\xenomorph\abilities\reaper\reaper_abilities.dm" +#include "code\modules\mob\living\carbon\xenomorph\abilities\reaper\reaper_powers.dm" #include "code\modules\mob\living\carbon\xenomorph\abilities\runner\runner_abilities.dm" #include "code\modules\mob\living\carbon\xenomorph\abilities\runner\runner_macros.dm" #include "code\modules\mob\living\carbon\xenomorph\abilities\runner\runner_powers.dm" @@ -2042,6 +2044,7 @@ #include "code\modules\mob\living\carbon\xenomorph\castes\Predalien.dm" #include "code\modules\mob\living\carbon\xenomorph\castes\Queen.dm" #include "code\modules\mob\living\carbon\xenomorph\castes\Ravager.dm" +#include "code\modules\mob\living\carbon\xenomorph\castes\Reaper.dm" #include "code\modules\mob\living\carbon\xenomorph\castes\Runner.dm" #include "code\modules\mob\living\carbon\xenomorph\castes\Sentinel.dm" #include "code\modules\mob\living\carbon\xenomorph\castes\Spitter.dm" diff --git a/icons/mob/xenos/reaper.dmi b/icons/mob/xenos/reaper.dmi new file mode 100644 index 000000000000..738fd0df7358 Binary files /dev/null and b/icons/mob/xenos/reaper.dmi differ