diff --git a/code/__DEFINES/atmospherics.dm b/code/__DEFINES/atmospherics.dm index fcc3e7784cb5..3abd79708f7a 100644 --- a/code/__DEFINES/atmospherics.dm +++ b/code/__DEFINES/atmospherics.dm @@ -41,3 +41,4 @@ var/MAX_EXPLOSION_RANGE = 14 /// Used in /obj/structure/pipes/vents/proc/create_gas #define VENT_GAS_SMOKE "Smoke" #define VENT_GAS_CN20 "CN20 Nerve Gas" +#define VENT_GAS_CN20_XENO "CN20-X Nerve Gas" diff --git a/code/__DEFINES/vv.dm b/code/__DEFINES/vv.dm index ecdd9f64ec38..eb248e8a30a7 100644 --- a/code/__DEFINES/vv.dm +++ b/code/__DEFINES/vv.dm @@ -134,3 +134,6 @@ #define VV_HK_TOGGLEPOWER "togglepower" #define VV_HK_ADD_ITEMS_TO_VENDOR "add_items_to_vendor" + +// /obj/structure/pipes/vents +#define VV_HK_GAS "release_gas" diff --git a/code/game/objects/effects/effect_system/smoke.dm b/code/game/objects/effects/effect_system/smoke.dm index dbbc50a01204..78aa01b5dacb 100644 --- a/code/game/objects/effects/effect_system/smoke.dm +++ b/code/game/objects/effects/effect_system/smoke.dm @@ -51,7 +51,8 @@ qdel(src) return else if(time_to_live == 1) - alpha = 180 + if(alpha > 180) + alpha = 180 amount = 0 set_opacity(0) @@ -254,45 +255,79 @@ name = "CN20 nerve gas" smokeranking = SMOKE_RANK_HIGH color = "#80c7e4" + var/xeno_affecting = FALSE + opacity = FALSE + alpha = 75 + +/obj/effect/particle_effect/smoke/cn20/xeno + name = "CN20-X nerve gas" + color = "#2da9da" + xeno_affecting = TRUE /obj/effect/particle_effect/smoke/cn20/Move() . = ..() - for(var/mob/living/carbon/human/creature in get_turf(src)) - affect(creature) - -/obj/effect/particle_effect/smoke/cn20/affect(mob/living/carbon/human/creature) + if(!xeno_affecting) + for(var/mob/living/carbon/human/human in get_turf(src)) + affect(human) + else + for(var/mob/living/carbon/creature in get_turf(src)) + affect(creature) + +/obj/effect/particle_effect/smoke/cn20/affect(mob/living/carbon/creature) + var/mob/living/carbon/xenomorph/xeno_creature + var/mob/living/carbon/human/human_creature + if(isxeno(creature)) + xeno_creature = creature + else if(ishuman(creature)) + human_creature = creature if(!istype(creature) || issynth(creature) || creature.stat == DEAD) return FALSE + if(!xeno_affecting && xeno_creature) + return FALSE if(isyautja(creature) && prob(75)) return FALSE - if (creature.wear_mask && (creature.wear_mask.flags_inventory & BLOCKGASEFFECT)) + if(creature.wear_mask && (creature.wear_mask.flags_inventory & BLOCKGASEFFECT)) + return FALSE + if(human_creature && (human_creature.head && (human_creature.head.flags_inventory & BLOCKGASEFFECT))) return FALSE var/effect_amt = round(6 + amount*6) - creature.apply_damage(12, OXY) + if(xeno_creature) + if(xeno_creature.interference < 4) + to_chat(xeno_creature, SPAN_XENOHIGHDANGER("Your awareness dims to a small area!")) + xeno_creature.interference = 10 + xeno_creature.blinded = TRUE + else + creature.apply_damage(12, OXY) creature.SetEarDeafness(max(creature.ear_deaf, round(effect_amt*1.5))) //Paralysis of hearing system, aka deafness - if(!creature.eye_blind) //Eye exposure damage + if(!xeno_creature && !creature.eye_blind) //Eye exposure damage to_chat(creature, SPAN_DANGER("Your eyes sting. You can't see!")) - creature.SetEyeBlind(round(effect_amt/3)) - if(creature.coughedtime != 1 && !creature.stat) //Coughing/gasping + creature.SetEyeBlind(round(effect_amt/3)) + if(!xeno_creature && creature.coughedtime != 1 && !creature.stat) //Coughing/gasping creature.coughedtime = 1 if(prob(50)) creature.emote("cough") else creature.emote("gasp") addtimer(VARSET_CALLBACK(creature, coughedtime, 0), 1.5 SECONDS) - if (prob(20)) + var/stun_chance = 20 + if(xeno_affecting) + stun_chance = 35 + if(prob(stun_chance)) creature.apply_effect(1, WEAKEN) //Topical damage (neurotoxin on exposed skin) - to_chat(creature, SPAN_DANGER("Your body is going numb, almost as if paralyzed!")) + if(xeno_creature) + to_chat(xeno_creature, SPAN_XENODANGER("You are struggling to move, it's as if you're paralyzed!")) + else + to_chat(creature, SPAN_DANGER("Your body is going numb, almost as if paralyzed!")) if(prob(60 + round(amount*15))) //Highly likely to drop items due to arms/hands seizing up creature.drop_held_item() - if(ishuman(creature)) - creature.temporary_slowdown = max(creature.temporary_slowdown, 4) //One tick every two second - creature.recalculate_move_delay = TRUE + if(human_creature) + human_creature.temporary_slowdown = max(human_creature.temporary_slowdown, 4) //One tick every two second + human_creature.recalculate_move_delay = TRUE return TRUE ////////////////////////////////////// @@ -595,6 +630,9 @@ /datum/effect_system/smoke_spread/cn20 smoke_type = /obj/effect/particle_effect/smoke/cn20 +/datum/effect_system/smoke_spread/cn20/xeno + smoke_type = /obj/effect/particle_effect/smoke/cn20/xeno + // XENO SMOKES /datum/effect_system/smoke_spread/xeno_acid diff --git a/code/game/objects/items/explosives/grenades/marines.dm b/code/game/objects/items/explosives/grenades/marines.dm index 5b72168b0851..2abb28075496 100644 --- a/code/game/objects/items/explosives/grenades/marines.dm +++ b/code/game/objects/items/explosives/grenades/marines.dm @@ -465,6 +465,45 @@ icon_state = "grenade_phos_clf" item_state = "grenade_phos_clf" +/* +//================================================ + Nerve Gas Grenades +//================================================ +*/ +/obj/item/explosive/grenade/nerve_gas + name = "\improper CN20 canister grenade" + desc = "A canister grenade of deadly nerve gas. It is set to detonate in 4 seconds." + icon_state = "flashbang2"//temp icon + det_time = 40 + item_state = "grenade_phos_clf"//temp icon + underslug_launchable = FALSE + harmful = TRUE + antigrief_protection = TRUE + var/datum/effect_system/smoke_spread/cn20/nerve_gas + var/nerve_gas_radius = 2 + +/obj/item/explosive/grenade/nerve_gas/New() + ..() + nerve_gas = new /datum/effect_system/smoke_spread/cn20 + nerve_gas.attach(src) + +/obj/item/explosive/grenade/nerve_gas/Destroy() + QDEL_NULL(nerve_gas) + return ..() + +/obj/item/explosive/grenade/nerve_gas/prime() + playsound(src.loc, 'sound/effects/smoke.ogg', 25, 1, 4) + nerve_gas.set_up(nerve_gas_radius, 0, get_turf(src), null, 6) + nerve_gas.start() + qdel(src) + +/obj/item/explosive/grenade/nerve_gas/xeno + name = "\improper CN20-X canister grenade" + +/obj/item/explosive/grenade/nerve_gas/xeno/New() + nerve_gas = new /datum/effect_system/smoke_spread/cn20/xeno + nerve_gas.attach(src) + /* //================================================ Airburst Smoke Grenades diff --git a/code/game/objects/structures/pipes/vents/vents.dm b/code/game/objects/structures/pipes/vents/vents.dm index d540414e4c8e..298fbc57f4ad 100644 --- a/code/game/objects/structures/pipes/vents/vents.dm +++ b/code/game/objects/structures/pipes/vents/vents.dm @@ -128,6 +128,32 @@ initial_loc.air_vent_names -= id_tag . = ..() +/obj/structure/pipes/vents/vv_get_dropdown() + . = ..() + VV_DROPDOWN_OPTION(VV_HK_GAS, "Release Gas") + +/obj/structure/pipes/vents/vv_do_topic(list/href_list) + . = ..() + var/mob/user = usr + if(href_list[VV_HK_GAS] && check_rights(R_EVENT)) + if(welded) + to_chat(usr, SPAN_WARNING("You cannot release gas from a welded vent.")) + return FALSE + var/list/options = list(VENT_GAS_SMOKE, VENT_GAS_CN20, VENT_GAS_CN20_XENO) + var/gas_choice = tgui_input_list(user, "What gas do you wish to use?", "Gas Choice", options, 20 SECONDS) + if(!gas_choice) + return FALSE + var/radius_choice = tgui_input_number(user, "What radius do you wish to use?", "Gas Radius", 4, 10, 1, 20 SECONDS) + var/warn_choice = tgui_input_number(user, "How many seconds warning do you wish to give?", "Release Warning", 5, 30, 1, 20 SECONDS) + warn_choice = warn_choice SECONDS + + var/confirm = alert(user, "Confirm gas setup. \n\nGas: '[gas_choice]'\nRadius: '[radius_choice]'\nWarn Time: '[warn_choice / 10] seconds' \n\n Is this correct?", "Confirmation", "Yes", "No") + if(confirm != "Yes") + return FALSE + log_admin("[key_name(user)] released gas (Gas: [gas_choice], Radius: [radius_choice], Delay: [warn_choice]) from [name] at X[x], Y[y], Z[z].") + create_gas(gas_choice, radius_choice, warn_choice) + return TRUE + /obj/structure/pipes/vents/proc/create_gas(gas_type = VENT_GAS_SMOKE, radius = 4, warning_time = 5 SECONDS) if(welded) to_chat(usr, SPAN_WARNING("You cannot release gas from a welded vent.")) @@ -138,6 +164,8 @@ spreader = new /datum/effect_system/smoke_spread/bad if(VENT_GAS_CN20) spreader = new /datum/effect_system/smoke_spread/cn20 + if(VENT_GAS_CN20_XENO) + spreader = new /datum/effect_system/smoke_spread/cn20/xeno if(!spreader) return FALSE gas_holder = spreader diff --git a/code/modules/mob/living/carbon/xenomorph/life.dm b/code/modules/mob/living/carbon/xenomorph/life.dm index 0542594f1ab6..65839e9c8caf 100644 --- a/code/modules/mob/living/carbon/xenomorph/life.dm +++ b/code/modules/mob/living/carbon/xenomorph/life.dm @@ -201,7 +201,8 @@ blinded = TRUE set_stat(UNCONSCIOUS) else - blinded = FALSE + if(!interference)//If their connection to hivemind is affected, their vision should be too. + blinded = FALSE set_stat(CONSCIOUS) if(regular_update && halloss > 0) if(resting) diff --git a/maps/map_files/USS_Almayer/USS_Almayer.dmm b/maps/map_files/USS_Almayer/USS_Almayer.dmm index 5631a5a6baed..085e7c14393e 100644 --- a/maps/map_files/USS_Almayer/USS_Almayer.dmm +++ b/maps/map_files/USS_Almayer/USS_Almayer.dmm @@ -74682,6 +74682,10 @@ /obj/structure/bed/chair/comfy/ares{ dir = 1 }, +/obj/structure/pipes/vents/pump/no_boom{ + name = "Security Vent"; + desc = "Has a valve and pump attached to it, connected to multiple gas tanks." + }, /turf/open/floor/almayer/no_build{ icon_state = "plating" },