diff --git a/code/game/objects/items/storage/backpack.dm b/code/game/objects/items/storage/backpack.dm index a0b88d2b639..13cdd8eb265 100644 --- a/code/game/objects/items/storage/backpack.dm +++ b/code/game/objects/items/storage/backpack.dm @@ -646,8 +646,7 @@ /obj/item/storage/backpack/duffelbag/syndie/firestarter/PopulateContents() new /obj/item/clothing/under/syndicate/soviet(src) - new /obj/item/watertank/op(src) - new /obj/item/mod/control/pre_equipped/elite(src) + new /obj/item/mod/control/pre_equipped/elite/flamethrower(src) new /obj/item/gun/ballistic/automatic/pistol/aps(src) new /obj/item/ammo_box/magazine/m9mm_aps/fire(src) new /obj/item/ammo_box/magazine/m9mm_aps/fire(src) diff --git a/code/game/objects/items/tanks/watertank.dm b/code/game/objects/items/tanks/watertank.dm index 8cff0afa27f..061cf2412b3 100644 --- a/code/game/objects/items/tanks/watertank.dm +++ b/code/game/objects/items/tanks/watertank.dm @@ -22,7 +22,7 @@ . = ..() create_reagents(volume, OPENCONTAINER) noz = make_noz() - + RegisterSignal(noz, COMSIG_MOVABLE_MOVED, .proc/noz_move) /obj/item/watertank/Destroy() QDEL_NULL(noz) @@ -33,13 +33,13 @@ toggle_mister(user) /obj/item/watertank/item_action_slot_check(slot, mob/user) - if(slot == user.getBackSlot() || slot == ITEM_SLOT_SUITSTORE) + if(slot == user.getBackSlot()) return 1 /obj/item/watertank/proc/toggle_mister(mob/living/user) if(!istype(user)) return - if(user.get_item_by_slot(user.getBackSlot()) != src && user.get_item_by_slot(ITEM_SLOT_SUITSTORE) != src) + if(user.get_item_by_slot(user.getBackSlot()) != src) to_chat(user, span_warning("The watertank must be worn properly to use!")) return if(user.incapacitated()) @@ -47,6 +47,7 @@ if(QDELETED(noz)) noz = make_noz() + RegisterSignal(noz, COMSIG_MOVABLE_MOVED, .proc/noz_move) if(noz in src) //Detach the nozzle into the user's hands if(!user.put_in_hands(noz)) @@ -64,6 +65,12 @@ /obj/item/watertank/proc/make_noz() return new /obj/item/reagent_containers/spray/mister(src) +/obj/item/watertank/proc/noz_move(atom/movable/mover, atom/oldloc, direction) + if(mover.loc == src || mover.loc == loc) + return + balloon_alert(loc, "nozzle snaps back") + mover.forceMove(src) + /obj/item/watertank/equipped(mob/user, slot) ..() if(slot != ITEM_SLOT_BACK) @@ -89,10 +96,10 @@ M.putItemFromInventoryInHandIfPossible(src, H.held_index) return ..() -/obj/item/watertank/attackby(obj/item/W, mob/user, params) - if(W == noz) +/obj/item/watertank/attackby(obj/item/attacking_item, mob/user, params) + if(attacking_item == noz) remove_noz() - return 1 + return TRUE else return ..() @@ -125,17 +132,10 @@ /obj/item/reagent_containers/spray/mister/Initialize(mapload) . = ..() tank = loc - if(!istype(tank)) + if(!tank?.reagents) return INITIALIZE_HINT_QDEL reagents = tank.reagents //This mister is really just a proxy for the tank's reagents -/obj/item/reagent_containers/spray/mister/doMove(atom/destination) - if(destination && (destination != tank.loc || !ismob(destination))) - if (loc != tank) - to_chat(tank.loc, span_notice("The mister snaps back onto the watertank.")) - destination = tank - ..() - /obj/item/reagent_containers/spray/mister/afterattack(obj/target, mob/user, proximity) if(target.loc == loc) //Safety check so you don't fill your mister with mutagen or something and then blast yourself in the face with it return @@ -179,10 +179,11 @@ icon_state = "pepperbackpacksec" inhand_icon_state = "pepperbackpacksec" custom_price = PAYCHECK_MEDIUM * 2 + volume = 1000 /obj/item/watertank/pepperspray/Initialize(mapload) . = ..() - reagents.add_reagent(/datum/reagent/consumable/condensedcapsaicin, 500) + reagents.add_reagent(/datum/reagent/consumable/condensedcapsaicin, 1000) /obj/item/reagent_containers/spray/mister/pepperspray name = "security spray nozzle" @@ -248,7 +249,7 @@ w_class = WEIGHT_CLASS_HUGE item_flags = ABSTRACT // don't put in storage chem = null //holds no chems of its own, it takes from the tank. - var/obj/item/watertank/tank + var/obj/item/tank var/nozzle_mode = 0 var/metal_synthesis_cooldown = 0 COOLDOWN_DECLARE(resin_cooldown) @@ -256,10 +257,10 @@ /obj/item/extinguisher/mini/nozzle/Initialize(mapload) . = ..() tank = loc - if (!istype(tank)) + if (!tank?.reagents) return INITIALIZE_HINT_QDEL reagents = tank.reagents - max_water = tank.volume + max_water = tank.reagents.maximum_volume /obj/item/extinguisher/mini/nozzle/Destroy() @@ -267,30 +268,26 @@ tank = null return ..() - -/obj/item/extinguisher/mini/nozzle/doMove(atom/destination) - if(destination && (destination != tank.loc || !ismob(destination))) - if(loc != tank) - to_chat(tank.loc, span_notice("The nozzle snaps back onto the tank.")) - destination = tank - ..() - /obj/item/extinguisher/mini/nozzle/attack_self(mob/user) + var/uses_pack = istype(tank, /obj/item/watertank/atmos) switch(nozzle_mode) if(EXTINGUISHER) nozzle_mode = RESIN_LAUNCHER - tank.icon_state = "waterbackpackatmos_1" - to_chat(user, span_notice("Swapped to resin launcher.")) + if(uses_pack) + tank.icon_state = "waterbackpackatmos_1" + balloon_alert(user, "switched to resin launcher") return if(RESIN_LAUNCHER) nozzle_mode = RESIN_FOAM - tank.icon_state = "waterbackpackatmos_2" - to_chat(user, span_notice("Swapped to resin foamer.")) + if(uses_pack) + tank.icon_state = "waterbackpackatmos_2" + balloon_alert(user, "switched to resin foam") return if(RESIN_FOAM) nozzle_mode = EXTINGUISHER - tank.icon_state = "waterbackpackatmos_0" - to_chat(user, span_notice("Swapped to water extinguisher.")) + if(uses_pack) + tank.icon_state = "waterbackpackatmos_0" + balloon_alert(user, "switched to fire extinguisher") return return @@ -306,10 +303,10 @@ return //Safety check so you don't blast yourself trying to refill your tank var/datum/reagents/R = reagents if(R.total_volume < 100) - to_chat(user, span_warning("You need at least 100 units of water to use the resin launcher!")) + balloon_alert(user, "not enough water!") return if(!COOLDOWN_FINISHED(src, resin_cooldown)) - to_chat(user, span_warning("Resin launcher is still recharging...")) + balloon_alert(user, "still recharging!") return COOLDOWN_START(src, resin_cooldown, 10 SECONDS) R.remove_any(100) @@ -324,10 +321,11 @@ if(nozzle_mode == RESIN_FOAM) if(!Adj|| !isturf(target)) + balloon_alert(user, "too far!") return for(var/S in target) if(istype(S, /obj/effect/particle_effect/foam/metal/resin) || istype(S, /obj/structure/foamedmetal/resin)) - to_chat(user, span_warning("There's already resin here!")) + balloon_alert(user, "already has resin!") return if(metal_synthesis_cooldown < 5) var/obj/effect/particle_effect/foam/metal/resin/F = new (get_turf(target)) @@ -335,7 +333,7 @@ metal_synthesis_cooldown++ addtimer(CALLBACK(src, .proc/reduce_metal_synth_cooldown), 10 SECONDS) else - to_chat(user, span_warning("Resin foam mix is still being synthesized...")) + balloon_alert(user, "still being synthesized!") return /obj/item/extinguisher/mini/nozzle/proc/resin_stop_check(datum/move_loop/source, succeeded) @@ -470,37 +468,3 @@ reagents.trans_to(user, used_amount, multiplier=usage_ratio, methods = INJECT) update_appearance() user.update_inv_back() //for overlays update - -//Operator backpack spray -/obj/item/watertank/op - name = "backpack water tank" - desc = "A New Russian backpack spray for systematic cleansing of carbon lifeforms." - icon_state = "waterbackpackop" - inhand_icon_state = "waterbackpackop" - w_class = WEIGHT_CLASS_NORMAL - volume = 2000 - slowdown = 0 - -/obj/item/watertank/op/Initialize(mapload) - . = ..() - reagents.add_reagent(/datum/reagent/toxin/mutagen,350) - reagents.add_reagent(/datum/reagent/napalm,125) - reagents.add_reagent(/datum/reagent/fuel,125) - reagents.add_reagent(/datum/reagent/clf3,300) - reagents.add_reagent(/datum/reagent/cryptobiolin,350) - reagents.add_reagent(/datum/reagent/toxin/plasma,250) - reagents.add_reagent(/datum/reagent/consumable/condensedcapsaicin,500) - -/obj/item/reagent_containers/spray/mister/op - desc = "A mister nozzle attached to several extended water tanks. It suspiciously has a compressor in the system and is labelled entirely in New Cyrillic." - icon = 'icons/obj/hydroponics/equipment.dmi' - icon_state = "misterop" - inhand_icon_state = "misterop" - lefthand_file = 'icons/mob/inhands/equipment/mister_lefthand.dmi' - righthand_file = 'icons/mob/inhands/equipment/mister_righthand.dmi' - w_class = WEIGHT_CLASS_BULKY - amount_per_transfer_from_this = 100 - possible_transfer_amounts = list(75,100,150) - -/obj/item/watertank/op/make_noz() - return new /obj/item/reagent_containers/spray/mister/op(src) diff --git a/code/modules/mod/mod_theme.dm b/code/modules/mod/mod_theme.dm index 526b5a1a026..2626d765fa6 100644 --- a/code/modules/mod/mod_theme.dm +++ b/code/modules/mod/mod_theme.dm @@ -153,7 +153,6 @@ max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT slowdown_inactive = 1.5 slowdown_active = 1 - allowed_suit_storage = list(/obj/item/flashlight, /obj/item/tank/internals, /obj/item/watertank/atmos) skins = list( "atmospheric" = list( HELMET_LAYER = NECK_LAYER, diff --git a/code/modules/mod/mod_types.dm b/code/modules/mod/mod_types.dm index 230b8f998ec..0a144541784 100644 --- a/code/modules/mod/mod_types.dm +++ b/code/modules/mod/mod_types.dm @@ -110,6 +110,7 @@ /obj/item/mod/module/storage, /obj/item/mod/module/flashlight, /obj/item/mod/module/holster, + /obj/item/mod/module/mister/security, ) /obj/item/mod/control/pre_equipped/safeguard @@ -120,6 +121,7 @@ /obj/item/mod/module/flashlight, /obj/item/mod/module/jetpack, /obj/item/mod/module/holster, + /obj/item/mod/module/mister/security, ) /obj/item/mod/control/pre_equipped/magnate @@ -175,6 +177,17 @@ /obj/item/mod/module/injector, ) +/obj/item/mod/control/pre_equipped/elite/flamethrower + initial_modules = list( + /obj/item/mod/module/storage/syndicate, + /obj/item/mod/module/emp_shield, + /obj/item/mod/module/thermal_regulator, + /obj/item/mod/module/jetpack/advanced, + /obj/item/mod/module/flashlight, + /obj/item/mod/module/holster, + /obj/item/mod/module/flamethrower, + ) + /obj/item/mod/control/pre_equipped/enchanted theme = /datum/mod_theme/enchanted applied_core = /obj/item/mod/core/infinite diff --git a/code/modules/mod/modules/_module.dm b/code/modules/mod/modules/_module.dm index c396f5d02b4..d00f0cb148c 100644 --- a/code/modules/mod/modules/_module.dm +++ b/code/modules/mod/modules/_module.dm @@ -119,7 +119,7 @@ return FALSE if(module_type == MODULE_ACTIVE) if(mod.selected_module && !mod.selected_module.on_deactivation(display_message = FALSE)) - return + return FALSE mod.selected_module = src if(device) if(mod.wearer.put_in_hands(device)) @@ -129,7 +129,7 @@ else balloon_alert(mod.wearer, "can't extend [device]!") mod.wearer.transferItemToLoc(device, src, force = TRUE) - return + return FALSE else var/used_button = mod.wearer.client?.prefs.read_preference(/datum/preference/choiced/mod_select) || MIDDLE_CLICK update_signal(used_button) @@ -301,6 +301,7 @@ if(user.get_active_held_item() != device) return on_deactivation() + return COMSIG_KB_ACTIVATED ///Anomaly Locked - Causes the module to not function without an anomaly. /obj/item/mod/module/anomaly_locked diff --git a/code/modules/mod/modules/modules_antag.dm b/code/modules/mod/modules/modules_antag.dm index 395e6abce1a..9e18d63a140 100644 --- a/code/modules/mod/modules/modules_antag.dm +++ b/code/modules/mod/modules/modules_antag.dm @@ -258,3 +258,30 @@ part.add_atom_colour("#b17f00", FIXED_COLOUR_PRIORITY) mod.wearer.remove_atom_colour(WASHABLE_COLOUR_PRIORITY) // turns purple guy purple mod.wearer.add_atom_colour("#704b96", FIXED_COLOUR_PRIORITY) + +///Flamethrower - Launches fire across the area. +/obj/item/mod/module/flamethrower + name = "MOD flamethrower module" + desc = "A custom-manufactured flamethrower, used to burn through your path. Burn well." + icon_state = "flamethrower" + module_type = MODULE_ACTIVE + complexity = 3 + use_power_cost = DEFAULT_CHARGE_DRAIN * 3 + incompatible_modules = list(/obj/item/mod/module/flamethrower) + cooldown_time = 2.5 SECONDS + overlay_state_inactive = "module_flamethrower" + overlay_state_active = "module_flamethrower_on" + +/obj/item/mod/module/flamethrower/on_select_use(atom/target) + . = ..() + if(!.) + return + var/obj/projectile/flame = new /obj/projectile/bullet/incendiary/backblast/flamethrower(mod.wearer.loc) + flame.preparePixelProjectile(target, mod.wearer) + flame.firer = mod.wearer + playsound(src, 'sound/items/modsuit/flamethrower.ogg', 75, TRUE) + INVOKE_ASYNC(flame, /obj/projectile.proc/fire) + drain_power(use_power_cost) + +/obj/projectile/bullet/incendiary/backblast/flamethrower + range = 6 diff --git a/code/modules/mod/modules/modules_engineering.dm b/code/modules/mod/modules/modules_engineering.dm index e1273ba9651..cafa27d2e22 100644 --- a/code/modules/mod/modules/modules_engineering.dm +++ b/code/modules/mod/modules/modules_engineering.dm @@ -203,3 +203,35 @@ return rcd_scan(src, fade_time = 10 SECONDS) drain_power(use_power_cost) + +///Mister - Sprays water over an area. +/obj/item/mod/module/mister + name = "MOD water mister module" + desc = "A module containing a mister, able to spray it over areas." + icon_state = "mister" + module_type = MODULE_ACTIVE + complexity = 2 + active_power_cost = DEFAULT_CHARGE_DRAIN * 0.3 + device = /obj/item/reagent_containers/spray/mister + incompatible_modules = list(/obj/item/mod/module/mister) + cooldown_time = 0.5 SECONDS + var/volume = 500 + +/obj/item/mod/module/mister/Initialize(mapload) + create_reagents(volume, OPENCONTAINER) + return ..() + +///Resin Mister - Sprays resin over an area. +/obj/item/mod/module/mister/atmos + name = "MOD resin mister module" + desc = "An atmospheric resin mister, able to fix up areas quickly." + device = /obj/item/extinguisher/mini/nozzle/mod + volume = 250 + +/obj/item/mod/module/mister/atmos/Initialize(mapload) + . = ..() + reagents.add_reagent(/datum/reagent/water, volume) + +/obj/item/extinguisher/mini/nozzle/mod + name = "MOD atmospheric mister" + desc = "An atmospheric resin mister with three modes, mounted as a module." diff --git a/code/modules/mod/modules/modules_security.dm b/code/modules/mod/modules/modules_security.dm index d530936be34..17bc3dc7b60 100644 --- a/code/modules/mod/modules/modules_security.dm +++ b/code/modules/mod/modules/modules_security.dm @@ -124,3 +124,18 @@ /obj/item/mod/module/holster/Destroy() QDEL_NULL(holstered) return ..() + +///Pepper Spray Mister - Sprays pepper spray over criminals. +/obj/item/mod/module/mister/security + name = "MOD pepper spray mister module" + desc = "A module containing a container of pepper spray to spray over areas." + device = /obj/item/reagent_containers/spray/mister/pepperspray/mod + complexity = 1 + +/obj/item/mod/module/mister/security/Initialize(mapload) + . = ..() + reagents.add_reagent(/datum/reagent/consumable/condensedcapsaicin, volume) + +/obj/item/reagent_containers/spray/mister/pepperspray/mod + name = "MOD pepper spray mister" + desc = "A mister full of pepper spray, perfect for riots." diff --git a/code/modules/projectiles/projectile/bullets/_incendiary.dm b/code/modules/projectiles/projectile/bullets/_incendiary.dm index bbb77e853b9..4f60f8940ab 100644 --- a/code/modules/projectiles/projectile/bullets/_incendiary.dm +++ b/code/modules/projectiles/projectile/bullets/_incendiary.dm @@ -25,6 +25,7 @@ sharpness = NONE shrapnel_type = null embedding = null + impact_effect_type = null ricochet_chance = 10000 ricochets_max = 4 ricochet_incidence_leeway = 0 @@ -45,6 +46,13 @@ /// we only try to knock back the first 6 items per tile #define BACKBLAST_MAX_ITEM_KNOCKBACK 6 +/obj/projectile/bullet/incendiary/backblast/on_hit(atom/target, blocked) + . = ..() + var/turf/location = get_turf(target) + if(isopenturf(location)) + new /obj/effect/hotspot(location) + location.hotspot_expose(700, 50, 1) + /obj/projectile/bullet/incendiary/backblast/Move() . = ..() if(knockback_range <= 0) diff --git a/code/modules/research/designs/mechfabricator_designs.dm b/code/modules/research/designs/mechfabricator_designs.dm index b93426b896f..86a535ac62f 100644 --- a/code/modules/research/designs/mechfabricator_designs.dm +++ b/code/modules/research/designs/mechfabricator_designs.dm @@ -1342,6 +1342,13 @@ materials = list(/datum/material/iron = 750, /datum/material/glass = 500) build_path = /obj/item/mod/module/signlang_radio +/datum/design/module/mister_atmos + name = "MOD Module: Resin Mister" + id = "mod_mister_atmos" + materials = list(/datum/material/iron = 1500, /datum/material/glass = 500, /datum/material/silver = 1000, /datum/material/titanium = 1500, /datum/material/uranium = 500) + build_path = /obj/item/mod/module/mister/atmos + department_type = MODULE_ENGINEERING + //MODsuit bepis modules /datum/design/module/disposal diff --git a/code/modules/research/techweb/all_nodes.dm b/code/modules/research/techweb/all_nodes.dm index 3204972fdec..a8329ceee74 100644 --- a/code/modules/research/techweb/all_nodes.dm +++ b/code/modules/research/techweb/all_nodes.dm @@ -1470,6 +1470,7 @@ "mod_magboot", "mod_tether", "mod_constructor", + "mod_mister_atmos", ) research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) diff --git a/code/modules/surgery/organs/augments_arms.dm b/code/modules/surgery/organs/augments_arms.dm index cc0a0475317..f12bbaaf8dd 100644 --- a/code/modules/surgery/organs/augments_arms.dm +++ b/code/modules/surgery/organs/augments_arms.dm @@ -115,6 +115,7 @@ if(hand != host.hand_bodyparts[host.active_hand_index]) return //wrong hand Retract() + return COMSIG_KB_ACTIVATED /obj/item/organ/cyberimp/arm/proc/Retract() if(!active_item || (active_item in src)) diff --git a/icons/mob/clothing/belt_mirror.dmi b/icons/mob/clothing/belt_mirror.dmi index e84d0eacd2a..bf314ba1ea7 100644 Binary files a/icons/mob/clothing/belt_mirror.dmi and b/icons/mob/clothing/belt_mirror.dmi differ diff --git a/icons/mob/clothing/mod.dmi b/icons/mob/clothing/mod.dmi index 4fa4445a1a7..684e1e797d3 100644 Binary files a/icons/mob/clothing/mod.dmi and b/icons/mob/clothing/mod.dmi differ diff --git a/icons/obj/clothing/modsuit/mod_modules.dmi b/icons/obj/clothing/modsuit/mod_modules.dmi index 8d8f121c45b..f838dbd4aeb 100644 Binary files a/icons/obj/clothing/modsuit/mod_modules.dmi and b/icons/obj/clothing/modsuit/mod_modules.dmi differ diff --git a/icons/obj/hydroponics/equipment.dmi b/icons/obj/hydroponics/equipment.dmi index fa9755543a5..385bed4d95e 100644 Binary files a/icons/obj/hydroponics/equipment.dmi and b/icons/obj/hydroponics/equipment.dmi differ diff --git a/sound/items/modsuit/flamethrower.ogg b/sound/items/modsuit/flamethrower.ogg new file mode 100644 index 00000000000..447245d50b6 Binary files /dev/null and b/sound/items/modsuit/flamethrower.ogg differ