diff --git a/code/__DEFINES/obj_flags.dm b/code/__DEFINES/obj_flags.dm index be0da9a61ff..660d05854fd 100644 --- a/code/__DEFINES/obj_flags.dm +++ b/code/__DEFINES/obj_flags.dm @@ -77,8 +77,8 @@ #define LARGE_WORN_ICON (1<<12) /// Clothes that block speech (i.e the muzzle). Can be applied to any clothing piece. #define BLOCKS_SPEECH (1<<13) -/// prevents from placing on plasmaman helmet -#define PLASMAMAN_HELMET_EXEMPT (1<<14) +/// prevents from placing on plasmaman helmet or modsuit hat holder +#define STACKABLE_HELMET_EXEMPT (1<<14) /// Prevents plasmamen from igniting when wearing this #define PLASMAMAN_PREVENT_IGNITION (1<<15) /// Usable as casting clothes by wizards (matters for suits, glasses and headwear) diff --git a/code/_globalvars/bitfields.dm b/code/_globalvars/bitfields.dm index 29e2a791229..092830751d3 100644 --- a/code/_globalvars/bitfields.dm +++ b/code/_globalvars/bitfields.dm @@ -93,7 +93,7 @@ DEFINE_BITFIELD(clothing_flags, list( "LARGE_WORN_ICON" = LARGE_WORN_ICON, "LAVAPROTECT" = LAVAPROTECT, "MASKINTERNALS" = MASKINTERNALS, - "PLASMAMAN_HELMET_EXEMPT" = PLASMAMAN_HELMET_EXEMPT, + "STACKABLE_HELMET_EXEMPT" = STACKABLE_HELMET_EXEMPT, "PLASMAMAN_PREVENT_IGNITION" = PLASMAMAN_PREVENT_IGNITION, "SNUG_FIT" = SNUG_FIT, "STOPSPRESSUREDAMAGE" = STOPSPRESSUREDAMAGE, diff --git a/code/modules/antagonists/cult/cult_items.dm b/code/modules/antagonists/cult/cult_items.dm index 19d45880655..a0beb89254a 100644 --- a/code/modules/antagonists/cult/cult_items.dm +++ b/code/modules/antagonists/cult/cult_items.dm @@ -326,7 +326,7 @@ Striking a noncultist, however, will tear their flesh."} icon_state = "cult_helmet" inhand_icon_state = null armor_type = /datum/armor/cult_hoodie_hardened - clothing_flags = STOPSPRESSUREDAMAGE | THICKMATERIAL | SNUG_FIT | PLASMAMAN_HELMET_EXEMPT | HEADINTERNALS + clothing_flags = STOPSPRESSUREDAMAGE | THICKMATERIAL | SNUG_FIT | STACKABLE_HELMET_EXEMPT | HEADINTERNALS flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDEFACIALHAIR|HIDESNOUT min_cold_protection_temperature = SPACE_HELM_MIN_TEMP_PROTECT max_heat_protection_temperature = SPACE_HELM_MAX_TEMP_PROTECT diff --git a/code/modules/clothing/head/costume.dm b/code/modules/clothing/head/costume.dm index 0331cf412e3..ec5ee81741f 100644 --- a/code/modules/clothing/head/costume.dm +++ b/code/modules/clothing/head/costume.dm @@ -22,7 +22,7 @@ icon_state = "syndicate-helm-black-red" inhand_icon_state = "syndicate-helm-black-red" desc = "A plastic replica of a Syndicate agent's space helmet. You'll look just like a real murderous Syndicate agent in this! This is a toy, it is not made for use in space!" - clothing_flags = SNUG_FIT + clothing_flags = SNUG_FIT | STACKABLE_HELMET_EXEMPT flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDEFACIALHAIR|HIDESNOUT /obj/item/clothing/head/costume/cueball diff --git a/code/modules/clothing/head/hardhat.dm b/code/modules/clothing/head/hardhat.dm index 5552688e991..71be68036bf 100644 --- a/code/modules/clothing/head/hardhat.dm +++ b/code/modules/clothing/head/hardhat.dm @@ -10,7 +10,7 @@ armor_type = /datum/armor/utility_hardhat flags_inv = 0 actions_types = list(/datum/action/item_action/toggle_helmet_light) - clothing_flags = SNUG_FIT | PLASMAMAN_HELMET_EXEMPT + clothing_flags = SNUG_FIT | STACKABLE_HELMET_EXEMPT resistance_flags = FIRE_PROOF light_system = MOVABLE_LIGHT_DIRECTIONAL @@ -73,7 +73,7 @@ hat_type = "red" dog_fashion = null name = "firefighter helmet" - clothing_flags = STOPSPRESSUREDAMAGE | PLASMAMAN_HELMET_EXEMPT + clothing_flags = STOPSPRESSUREDAMAGE | STACKABLE_HELMET_EXEMPT heat_protection = HEAD max_heat_protection_temperature = FIRE_HELM_MAX_TEMP_PROTECT cold_protection = HEAD @@ -93,7 +93,7 @@ icon_state = "hardhat0_white" inhand_icon_state = null hat_type = "white" - clothing_flags = STOPSPRESSUREDAMAGE | PLASMAMAN_HELMET_EXEMPT + clothing_flags = STOPSPRESSUREDAMAGE | STACKABLE_HELMET_EXEMPT heat_protection = HEAD max_heat_protection_temperature = FIRE_HELM_MAX_TEMP_PROTECT cold_protection = HEAD @@ -166,7 +166,7 @@ inhand_icon_state = null light_range = 4 //Boss always takes the best stuff hat_type = "white" - clothing_flags = STOPSPRESSUREDAMAGE | PLASMAMAN_HELMET_EXEMPT + clothing_flags = STOPSPRESSUREDAMAGE | STACKABLE_HELMET_EXEMPT heat_protection = HEAD max_heat_protection_temperature = FIRE_HELM_MAX_TEMP_PROTECT cold_protection = HEAD @@ -184,7 +184,7 @@ dog_fashion = null name = "atmospheric firefighter helmet" desc = "A firefighter's helmet, able to keep the user cool in any situation. Comes with a light and a welding visor." - clothing_flags = STOPSPRESSUREDAMAGE | THICKMATERIAL | BLOCK_GAS_SMOKE_EFFECT | PLASMAMAN_HELMET_EXEMPT | HEADINTERNALS + clothing_flags = STOPSPRESSUREDAMAGE | THICKMATERIAL | BLOCK_GAS_SMOKE_EFFECT | STACKABLE_HELMET_EXEMPT | HEADINTERNALS heat_protection = HEAD max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT cold_protection = HEAD @@ -208,7 +208,7 @@ icon_state = "hardhat0_pumpkin" inhand_icon_state = null hat_type = "pumpkin" - clothing_flags = SNUG_FIT | PLASMAMAN_HELMET_EXEMPT + clothing_flags = SNUG_FIT | STACKABLE_HELMET_EXEMPT flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDEFACIALHAIR|HIDESNOUT armor_type = /datum/armor/none light_range = 2 //luminosity when on diff --git a/code/modules/clothing/head/hat.dm b/code/modules/clothing/head/hat.dm index fac31c43206..ccc8e903f33 100644 --- a/code/modules/clothing/head/hat.dm +++ b/code/modules/clothing/head/hat.dm @@ -55,7 +55,7 @@ name = "plague doctor's hat" desc = "These were once used by plague doctors. Will protect you from exposure to the Pestilence." icon_state = "plaguedoctor" - clothing_flags = THICKMATERIAL | BLOCK_GAS_SMOKE_EFFECT | SNUG_FIT | PLASMAMAN_HELMET_EXEMPT + clothing_flags = THICKMATERIAL | BLOCK_GAS_SMOKE_EFFECT | SNUG_FIT | STACKABLE_HELMET_EXEMPT armor_type = /datum/armor/bio_hood_plague flags_inv = NONE diff --git a/code/modules/clothing/head/helmet.dm b/code/modules/clothing/head/helmet.dm index 7c0b53fc7a6..488bd7448a7 100644 --- a/code/modules/clothing/head/helmet.dm +++ b/code/modules/clothing/head/helmet.dm @@ -11,7 +11,7 @@ heat_protection = HEAD max_heat_protection_temperature = HELMET_MAX_TEMP_PROTECT strip_delay = 60 - clothing_flags = SNUG_FIT | PLASMAMAN_HELMET_EXEMPT + clothing_flags = SNUG_FIT | STACKABLE_HELMET_EXEMPT flags_cover = HEADCOVERSEYES flags_inv = HIDEHAIR dog_fashion = /datum/dog_fashion/head/helmet @@ -89,7 +89,7 @@ inhand_icon_state = "marine_helmet" armor_type = /datum/armor/helmet_marine min_cold_protection_temperature = SPACE_HELM_MIN_TEMP_PROTECT - clothing_flags = STOPSPRESSUREDAMAGE | PLASMAMAN_HELMET_EXEMPT + clothing_flags = STOPSPRESSUREDAMAGE | STACKABLE_HELMET_EXEMPT resistance_flags = FIRE_PROOF | ACID_PROOF dog_fashion = null @@ -243,7 +243,7 @@ min_cold_protection_temperature = SPACE_HELM_MIN_TEMP_PROTECT heat_protection = HEAD max_heat_protection_temperature = SPACE_HELM_MAX_TEMP_PROTECT - clothing_flags = STOPSPRESSUREDAMAGE | PLASMAMAN_HELMET_EXEMPT + clothing_flags = STOPSPRESSUREDAMAGE | STACKABLE_HELMET_EXEMPT strip_delay = 80 resistance_flags = FIRE_PROOF | ACID_PROOF dog_fashion = null @@ -264,7 +264,7 @@ desc = "An extremely robust helmet with the Nanotrasen logo emblazoned on the top." icon_state = "swat" inhand_icon_state = "swat_helmet" - clothing_flags = PLASMAMAN_HELMET_EXEMPT + clothing_flags = STACKABLE_HELMET_EXEMPT cold_protection = HEAD min_cold_protection_temperature = SPACE_HELM_MIN_TEMP_PROTECT heat_protection = HEAD diff --git a/code/modules/clothing/head/welding.dm b/code/modules/clothing/head/welding.dm index 287ab800c1f..bccb1d4524d 100644 --- a/code/modules/clothing/head/welding.dm +++ b/code/modules/clothing/head/welding.dm @@ -15,7 +15,7 @@ visor_flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDESNOUT visor_flags_cover = HEADCOVERSEYES | HEADCOVERSMOUTH | PEPPERPROOF resistance_flags = FIRE_PROOF - clothing_flags = SNUG_FIT | PLASMAMAN_HELMET_EXEMPT + clothing_flags = SNUG_FIT | STACKABLE_HELMET_EXEMPT /datum/armor/utility_welding melee = 10 diff --git a/code/modules/clothing/spacesuits/_spacesuits.dm b/code/modules/clothing/spacesuits/_spacesuits.dm index d26a8f08400..c765d6b2fb4 100644 --- a/code/modules/clothing/spacesuits/_spacesuits.dm +++ b/code/modules/clothing/spacesuits/_spacesuits.dm @@ -9,7 +9,7 @@ icon_state = "spaceold" inhand_icon_state = "space_helmet" desc = "A special helmet with solar UV shielding to protect your eyes from harmful rays." - clothing_flags = STOPSPRESSUREDAMAGE | THICKMATERIAL | SNUG_FIT | PLASMAMAN_HELMET_EXEMPT | HEADINTERNALS + clothing_flags = STOPSPRESSUREDAMAGE | THICKMATERIAL | SNUG_FIT | STACKABLE_HELMET_EXEMPT | HEADINTERNALS armor_type = /datum/armor/helmet_space flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDEFACIALHAIR|HIDESNOUT diff --git a/code/modules/clothing/spacesuits/plasmamen.dm b/code/modules/clothing/spacesuits/plasmamen.dm index 7b73e5b3383..1e75acacca6 100644 --- a/code/modules/clothing/spacesuits/plasmamen.dm +++ b/code/modules/clothing/spacesuits/plasmamen.dm @@ -44,7 +44,7 @@ desc = "A special containment helmet that allows plasma-based lifeforms to exist safely in an oxygenated environment. It is space-worthy, and may be worn in tandem with other EVA gear." icon = 'icons/obj/clothing/head/plasmaman_hats.dmi' worn_icon = 'icons/mob/clothing/head/plasmaman_head.dmi' - clothing_flags = STOPSPRESSUREDAMAGE | THICKMATERIAL | SNUG_FIT | PLASMAMAN_HELMET_EXEMPT | PLASMAMAN_PREVENT_IGNITION | HEADINTERNALS + clothing_flags = STOPSPRESSUREDAMAGE | THICKMATERIAL | SNUG_FIT | STACKABLE_HELMET_EXEMPT | PLASMAMAN_PREVENT_IGNITION | HEADINTERNALS icon_state = "plasmaman-helm" inhand_icon_state = "plasmaman-helm" strip_delay = 80 @@ -126,7 +126,7 @@ return if(istype(hitting_item, /obj/item/clothing/head)) var/obj/item/clothing/hitting_clothing = hitting_item - if(hitting_clothing.clothing_flags & PLASMAMAN_HELMET_EXEMPT) + if(hitting_clothing.clothing_flags & STACKABLE_HELMET_EXEMPT) to_chat(user, span_notice("You cannot place [hitting_clothing.name] on helmet!")) return if(attached_hat) diff --git a/code/modules/clothing/suits/bio.dm b/code/modules/clothing/suits/bio.dm index ffbef12d1ef..4ddfd31631d 100644 --- a/code/modules/clothing/suits/bio.dm +++ b/code/modules/clothing/suits/bio.dm @@ -6,7 +6,7 @@ worn_icon = 'icons/mob/clothing/head/bio.dmi' icon_state = "bio" inhand_icon_state = "bio_hood" - clothing_flags = THICKMATERIAL | BLOCK_GAS_SMOKE_EFFECT | SNUG_FIT | PLASMAMAN_HELMET_EXEMPT | HEADINTERNALS + clothing_flags = THICKMATERIAL | BLOCK_GAS_SMOKE_EFFECT | SNUG_FIT | STACKABLE_HELMET_EXEMPT | HEADINTERNALS armor_type = /datum/armor/head_bio_hood flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEHAIR|HIDEFACIALHAIR|HIDEFACE|HIDESNOUT resistance_flags = ACID_PROOF diff --git a/code/modules/clothing/suits/costume.dm b/code/modules/clothing/suits/costume.dm index 129042e0cd8..55b8b96e00a 100644 --- a/code/modules/clothing/suits/costume.dm +++ b/code/modules/clothing/suits/costume.dm @@ -304,7 +304,7 @@ min_cold_protection_temperature = SPACE_HELM_MIN_TEMP_PROTECT heat_protection = HEAD max_heat_protection_temperature = SPACE_HELM_MAX_TEMP_PROTECT - clothing_flags = STOPSPRESSUREDAMAGE|THICKMATERIAL|SNUG_FIT|PLASMAMAN_HELMET_EXEMPT + clothing_flags = STOPSPRESSUREDAMAGE|THICKMATERIAL|SNUG_FIT|STACKABLE_HELMET_EXEMPT body_parts_covered = HEAD resistance_flags = NONE flash_protect = FLASH_PROTECTION_WELDER diff --git a/code/modules/mob/living/basic/vermin/butterfly.dm b/code/modules/mob/living/basic/vermin/butterfly.dm index 77f89d4d4d1..cbc847aa9e8 100644 --- a/code/modules/mob/living/basic/vermin/butterfly.dm +++ b/code/modules/mob/living/basic/vermin/butterfly.dm @@ -80,6 +80,8 @@ /// Checks whether the butterfly should be despawned after the next check, based on distance from source /mob/living/basic/butterfly/lavaland/temporary/proc/should_despawn() + if(QDELETED(source)) + return TRUE if(get_dist(source, src) > max_distance) return TRUE return FALSE diff --git a/code/modules/mod/mod_construction.dm b/code/modules/mod/mod_construction.dm index a79d216039c..398ba2f216e 100644 --- a/code/modules/mod/mod_construction.dm +++ b/code/modules/mod/mod_construction.dm @@ -46,7 +46,9 @@ /obj/item/mod/construction/broken_core/screwdriver_act(mob/living/user, obj/item/tool) . = ..() + balloon_alert(user, "repairing...") if(!tool.use_tool(src, user, 5 SECONDS, volume = 30)) + balloon_alert(user, "interrupted!") return new /obj/item/mod/core/standard(drop_location()) qdel(src) @@ -66,20 +68,16 @@ /obj/item/mod/construction/lavalandcore/attackby(obj/item/weapon, mob/user, params) if(!istype(weapon, /obj/item/stack/cable_coil)) - return - + return ..() if(!weapon.tool_start_check(user, amount=2)) return - - to_chat(user, span_notice("You start pushing the wires into the core...")) + balloon_alert(user, "installing wires...") if(!weapon.use_tool(src, user, 5 SECONDS, amount = 2, volume = 30)) + balloon_alert(user, "interrupted!") return - - to_chat(user, span_notice("You add the wires to the core.")) new /obj/item/mod/core/plasma/lavaland(drop_location()) qdel(src) - /obj/item/mod/construction/plating name = "MOD external plating" desc = "External plating used to finish a MOD control unit." diff --git a/code/modules/mod/mod_core.dm b/code/modules/mod/mod_core.dm index 06dace8b5b0..45fa61677b2 100644 --- a/code/modules/mod/mod_core.dm +++ b/code/modules/mod/mod_core.dm @@ -370,49 +370,23 @@ light_system = MOVABLE_LIGHT light_color = "#cc00cc" light_range = 2 - // Slightly better than the normal plasma core. // Not super sure if this should just be the same, but will see. maxcharge = 15000 charge = 15000 - /// The mob to be spawned by the core var/mob/living/spawned_mob_type = /mob/living/basic/butterfly/lavaland/temporary /// Max number of mobs it can spawn var/max_spawns = 3 - /// Mob spawner for the core var/datum/component/spawner/mob_spawner - + /// Particle holder for pollen particles + var/obj/effect/abstract/particle_holder/particle_effect /obj/item/mod/core/plasma/lavaland/Destroy() - if(mod?.wearer) - mod.wearer.particles = null + QDEL_NULL(particle_effect) return ..() -/obj/item/mod/core/plasma/lavaland/proc/new_mob(spawner, mob/living/basic/butterfly/lavaland/temporary/spawned) - SIGNAL_HANDLER - if(spawned) - spawned.source = src - -/obj/item/mod/core/plasma/lavaland/proc/on_toggle() - SIGNAL_HANDLER - if(mod.active) - START_PROCESSING(SSprocessing, src) - mod.wearer.particles = new /particles/pollen() - mob_spawner = mod.wearer.AddComponent(/datum/component/spawner, spawn_types=list(spawned_mob_type), spawn_time=5 SECONDS, max_spawned=3) - RegisterSignal(mob_spawner, COMSIG_SPAWNER_SPAWNED, PROC_REF(new_mob)) - RegisterSignal(mod.wearer, COMSIG_MOVABLE_PRE_MOVE, PROC_REF(flowas)) - - else - STOP_PROCESSING(SSprocessing, src) - mod.wearer.particles = null - UnregisterSignal(mob_spawner, COMSIG_SPAWNER_SPAWNED) - UnregisterSignal(mod.wearer, COMSIG_MOVABLE_PRE_MOVE) - for(var/datum/mob in mob_spawner.spawned_things) - qdel(mob) - qdel(mob_spawner) - /obj/item/mod/core/plasma/lavaland/install(obj/item/mod/control/mod_unit) . = ..() RegisterSignal(mod_unit, COMSIG_MOD_TOGGLED, PROC_REF(on_toggle)) @@ -421,7 +395,28 @@ . = ..() UnregisterSignal(mod_unit, COMSIG_MOD_TOGGLED) -/obj/item/mod/core/plasma/lavaland/proc/flowas(mob/living/wearer) +/obj/item/mod/core/plasma/lavaland/proc/on_toggle() + SIGNAL_HANDLER + if(mod.active) + particle_effect = new(mod.wearer, /particles/pollen, PARTICLE_ATTACH_MOB) + mob_spawner = mod.wearer.AddComponent(/datum/component/spawner, spawn_types=list(spawned_mob_type), spawn_time=5 SECONDS, max_spawned=3) + RegisterSignal(mob_spawner, COMSIG_SPAWNER_SPAWNED, PROC_REF(new_mob)) + RegisterSignal(mod.wearer, COMSIG_MOVABLE_MOVED, PROC_REF(spread_flowers)) + + else + QDEL_NULL(particle_effect) + UnregisterSignal(mob_spawner, COMSIG_SPAWNER_SPAWNED) + UnregisterSignal(mod.wearer, COMSIG_MOVABLE_MOVED) + for(var/datum/mob in mob_spawner.spawned_things) + qdel(mob) + qdel(mob_spawner) + +/obj/item/mod/core/plasma/lavaland/proc/new_mob(spawner, mob/living/basic/butterfly/lavaland/temporary/spawned) + SIGNAL_HANDLER + if(spawned) + spawned.source = src + +/obj/item/mod/core/plasma/lavaland/proc/spread_flowers(atom/source, atom/oldloc, dir, forced) SIGNAL_HANDLER var/static/list/possible_flower_types = list( /obj/structure/flora/bush/lavendergrass/style_random, @@ -430,6 +425,6 @@ /obj/structure/flora/bush/flowers_pp/style_random, ) var/chosen_type = pick(possible_flower_types) - var/flower_boots = new chosen_type(get_turf(wearer)) + var/flower_boots = new chosen_type(get_turf(mod.wearer)) animate(flower_boots, alpha = 0, 1 SECONDS) QDEL_IN(flower_boots, 1 SECONDS) diff --git a/code/modules/mod/mod_theme.dm b/code/modules/mod/mod_theme.dm index 9f989ce4c96..209bb40ac35 100644 --- a/code/modules/mod/mod_theme.dm +++ b/code/modules/mod/mod_theme.dm @@ -1389,7 +1389,7 @@ slowdown_inactive = 1.5 slowdown_active = 1 ui_theme = "hackerman" - inbuilt_modules = list(/obj/item/mod/module/anomaly_locked/kinesis/prebuilt/prototype) + inbuilt_modules = list(/obj/item/mod/module/anomaly_locked/kinesis/prototype) allowed_suit_storage = list( /obj/item/analyzer, /obj/item/t_scanner, @@ -1717,7 +1717,7 @@ siemens_coefficient = 0 slowdown_inactive = 0.5 slowdown_active = 0 - activation_step_time = 0.4 SECONDS + activation_step_time = MOD_ACTIVATION_STEP_TIME * 0.2 allowed_suit_storage = list( /obj/item/gun, ) @@ -1777,7 +1777,7 @@ siemens_coefficient = 0 slowdown_inactive = 0 slowdown_active = 0 - activation_step_time = 0.1 SECONDS + activation_step_time = MOD_ACTIVATION_STEP_TIME * 0.01 allowed_suit_storage = list( /obj/item/gun, ) diff --git a/code/modules/mod/mod_types.dm b/code/modules/mod/mod_types.dm index b5de82895ac..e820525ff9a 100644 --- a/code/modules/mod/mod_types.dm +++ b/code/modules/mod/mod_types.dm @@ -344,7 +344,7 @@ ) default_pins = list( /obj/item/mod/module/tether, - /obj/item/mod/module/anomaly_locked/kinesis/prebuilt/prototype, + /obj/item/mod/module/anomaly_locked/kinesis/prototype, ) /obj/item/mod/control/pre_equipped/responsory @@ -505,13 +505,13 @@ /obj/item/mod/module/quick_carry/advanced, /obj/item/mod/module/magboot/advanced, /obj/item/mod/module/jetpack/advanced, - /obj/item/mod/module/anomaly_locked/kinesis/plus, + /obj/item/mod/module/anomaly_locked/kinesis/admin, ) default_pins = list( /obj/item/mod/module/stealth/ninja, /obj/item/mod/module/magboot/advanced, /obj/item/mod/module/jetpack/advanced, - /obj/item/mod/module/anomaly_locked/kinesis/plus, + /obj/item/mod/module/anomaly_locked/kinesis/admin, ) //these exist for the prefs menu diff --git a/code/modules/mod/modules/module_kinesis.dm b/code/modules/mod/modules/module_kinesis.dm index 8fe4ba9f07c..84dc503af1f 100644 --- a/code/modules/mod/modules/module_kinesis.dm +++ b/code/modules/mod/modules/module_kinesis.dm @@ -21,8 +21,6 @@ var/hit_cooldown_time = 1 SECONDS /// Stat required for us to grab a mob. var/stat_required = DEAD - /// How long we stun a mob for. - var/mob_stun_time = 5 SECONDS /// Atom we grabbed with kinesis. var/atom/movable/grabbed_atom /// Ref of the beam following the grabbed atom. @@ -51,8 +49,9 @@ if(!mod.wearer.client) return if(grabbed_atom) - launch() + var/launched_object = grabbed_atom clear_grab(playsound = FALSE) + launch(launched_object) return if(!range_check(target)) balloon_alert(mod.wearer, "too far!") @@ -61,20 +60,7 @@ balloon_alert(mod.wearer, "can't grab!") return drain_power(use_power_cost) - grabbed_atom = target - if(isliving(grabbed_atom)) - var/mob/living/grabbed_mob = grabbed_atom - grabbed_mob.Stun(mob_stun_time) - playsound(grabbed_atom, 'sound/effects/contractorbatonhit.ogg', 75, TRUE) - kinesis_icon = mutable_appearance(icon = 'icons/effects/effects.dmi', icon_state = "kinesis", layer = grabbed_atom.layer - 0.1) - kinesis_icon.appearance_flags = RESET_ALPHA|RESET_COLOR|RESET_TRANSFORM - kinesis_icon.overlays += emissive_appearance(icon = 'icons/effects/effects.dmi', icon_state = "kinesis", offset_spokesman = grabbed_atom) - grabbed_atom.add_overlay(kinesis_icon) - kinesis_beam = mod.wearer.Beam(grabbed_atom, "kinesis") - kinesis_catcher = mod.wearer.overlay_fullscreen("kinesis", /atom/movable/screen/fullscreen/cursor_catcher/kinesis, 0) - kinesis_catcher.assign_to_mob(mod.wearer) - soundloop.start() - START_PROCESSING(SSfastprocess, src) + grab_atom(target) /obj/item/mod/module/anomaly_locked/kinesis/on_deactivation(display_message = TRUE, deleting = FALSE) . = ..() @@ -158,6 +144,8 @@ if(!isliving(movable_target)) return FALSE var/mob/living/living_target = movable_target + if(living_target.buckled) + return FALSE if(living_target.stat < stat_required) return FALSE else if(isitem(movable_target)) @@ -168,9 +156,29 @@ return FALSE return TRUE +/obj/item/mod/module/anomaly_locked/kinesis/proc/grab_atom(atom/movable/target) + grabbed_atom = target + if(isliving(grabbed_atom)) + add_traits(grabbed_atom, list(TRAIT_IMMOBILIZED, TRAIT_HANDS_BLOCKED), REF(src)) + RegisterSignal(grabbed_atom, COMSIG_MOB_STATCHANGE, PROC_REF(on_statchange)) + ADD_TRAIT(grabbed_atom, TRAIT_NO_FLOATING_ANIM, REF(src)) + RegisterSignal(grabbed_atom, COMSIG_MOVABLE_SET_ANCHORED, PROC_REF(on_setanchored)) + playsound(grabbed_atom, 'sound/effects/contractorbatonhit.ogg', 75, TRUE) + kinesis_icon = mutable_appearance(icon = 'icons/effects/effects.dmi', icon_state = "kinesis", layer = grabbed_atom.layer - 0.1) + kinesis_icon.appearance_flags = RESET_ALPHA|RESET_COLOR|RESET_TRANSFORM + kinesis_icon.overlays += emissive_appearance(icon = 'icons/effects/effects.dmi', icon_state = "kinesis", offset_spokesman = grabbed_atom) + grabbed_atom.add_overlay(kinesis_icon) + kinesis_beam = mod.wearer.Beam(grabbed_atom, "kinesis") + kinesis_catcher = mod.wearer.overlay_fullscreen("kinesis", /atom/movable/screen/fullscreen/cursor_catcher/kinesis, 0) + kinesis_catcher.assign_to_mob(mod.wearer) + RegisterSignal(kinesis_catcher, COMSIG_CLICK, PROC_REF(on_catcher_click)) + soundloop.start() + START_PROCESSING(SSfastprocess, src) + /obj/item/mod/module/anomaly_locked/kinesis/proc/clear_grab(playsound = TRUE) if(!grabbed_atom) return + . = grabbed_atom if(playsound) playsound(grabbed_atom, 'sound/effects/empulse.ogg', 75, TRUE) STOP_PROCESSING(SSfastprocess, src) @@ -178,6 +186,9 @@ mod.wearer.clear_fullscreen("kinesis") grabbed_atom.cut_overlay(kinesis_icon) QDEL_NULL(kinesis_beam) + if(isliving(grabbed_atom)) + remove_traits(grabbed_atom, list(TRAIT_IMMOBILIZED, TRAIT_HANDS_BLOCKED), REF(src)) + REMOVE_TRAIT(grabbed_atom, TRAIT_NO_FLOATING_ANIM, REF(src)) if(!isitem(grabbed_atom)) animate(grabbed_atom, 0.2 SECONDS, pixel_x = grabbed_atom.base_pixel_x, pixel_y = grabbed_atom.base_pixel_y) grabbed_atom = null @@ -192,11 +203,31 @@ return FALSE return TRUE -/obj/item/mod/module/anomaly_locked/kinesis/proc/launch() - playsound(grabbed_atom, 'sound/magic/repulse.ogg', 100, TRUE) - RegisterSignal(grabbed_atom, COMSIG_MOVABLE_IMPACT, PROC_REF(launch_impact)) - var/turf/target_turf = get_turf_in_angle(get_angle(mod.wearer, grabbed_atom), get_turf(src), 10) - grabbed_atom.throw_at(target_turf, range = grab_range, speed = grabbed_atom.density ? 3 : 4, thrower = mod.wearer, spin = isitem(grabbed_atom)) + +/obj/item/mod/module/anomaly_locked/kinesis/proc/on_catcher_click(atom/source, location, control, params, user) + SIGNAL_HANDLER + + var/list/modifiers = params2list(params) + if(LAZYACCESS(modifiers, RIGHT_CLICK)) + clear_grab() + +/obj/item/mod/module/anomaly_locked/kinesis/proc/on_statchange(mob/grabbed_mob, new_stat) + SIGNAL_HANDLER + + if(new_stat < stat_required) + clear_grab() + +/obj/item/mod/module/anomaly_locked/kinesis/proc/on_setanchored(atom/movable/grabbed_atom, anchorvalue) + SIGNAL_HANDLER + + if(grabbed_atom.anchored) + clear_grab() + +/obj/item/mod/module/anomaly_locked/kinesis/proc/launch(atom/movable/launched_object) + playsound(launched_object, 'sound/magic/repulse.ogg', 100, TRUE) + RegisterSignal(launched_object, COMSIG_MOVABLE_IMPACT, PROC_REF(launch_impact)) + var/turf/target_turf = get_turf_in_angle(get_angle(mod.wearer, launched_object), get_turf(src), 10) + launched_object.throw_at(target_turf, range = grab_range, speed = launched_object.density ? 3 : 4, thrower = mod.wearer, spin = isitem(launched_object)) /obj/item/mod/module/anomaly_locked/kinesis/proc/launch_impact(atom/movable/source, atom/hit_atom, datum/thrownthing/thrownthing) UnregisterSignal(source, COMSIG_MOVABLE_IMPACT) @@ -215,25 +246,88 @@ if(damage_self && source.uses_integrity) source.take_damage(source.max_integrity/5, BRUTE, MELEE) +/atom/movable/screen/fullscreen/cursor_catcher/kinesis + icon_state = "kinesis" + /obj/item/mod/module/anomaly_locked/kinesis/prebuilt prebuilt = TRUE -/obj/item/mod/module/anomaly_locked/kinesis/prebuilt/prototype +/obj/item/mod/module/anomaly_locked/kinesis/prototype name = "MOD prototype kinesis module" + prebuilt = TRUE complexity = 0 use_power_cost = DEFAULT_CHARGE_DRAIN * 5 removable = FALSE -/atom/movable/screen/fullscreen/cursor_catcher/kinesis - icon_state = "kinesis" - /obj/item/mod/module/anomaly_locked/kinesis/plus name = "MOD kinesis+ module" desc = "A modular plug-in to the forearm, this module was recently redeveloped in secret. \ The bane of all ne'er-do-wells, the kinesis+ module is a powerful tool that allows the user \ to manipulate the world around them. Like it's older counterpart, it's capable of manipulating \ - structures, machinery, vehicles, and, thanks to the fruitful efforts of it's creators - living \ - beings. They can, however, still struggle after an initial burst of inertia." + structures, machinery, vehicles, and, thanks to the fruitful efforts of its creators - living beings." complexity = 0 prebuilt = TRUE stat_required = CONSCIOUS + +/// Admin suit version of kinesis. Can grab anything at any range, may enable phasing through walls. +/obj/item/mod/module/anomaly_locked/kinesis/admin + name = "MOD kinesis++ module" + desc = "A modular plug-in to the forearm, this module was recently reredeveloped in super secret. \ + This one can force some of the grasped objects to phase through walls. Oh no." + complexity = 0 + grab_range = INFINITY + use_power_cost = DEFAULT_CHARGE_DRAIN * 0 + prebuilt = TRUE + stat_required = CONSCIOUS + /// Does our object phase through stuff? + var/phasing = FALSE + +/obj/item/mod/module/anomaly_locked/kinesis/admin/grab_atom(atom/movable/target) + . = ..() + if(phasing) + ADD_TRAIT(grabbed_atom, TRAIT_MOVE_PHASING, REF(src)) + +/obj/item/mod/module/anomaly_locked/kinesis/admin/clear_grab(playsound) + . = ..() + if(!.) + return + var/atom/movable/previous_grab = . + if(phasing) + REMOVE_TRAIT(previous_grab, TRAIT_MOVE_PHASING, REF(src)) + +/obj/item/mod/module/anomaly_locked/kinesis/admin/can_grab(atom/target) + if(mod.wearer == target) + return FALSE + if(!ismovable(target)) + return FALSE + var/atom/movable/movable_target = target + if(movable_target.throwing) + return FALSE + return TRUE + +/obj/item/mod/module/anomaly_locked/kinesis/admin/range_check(atom/target) + if(!isturf(mod.wearer.loc)) + return FALSE + if(ismovable(target) && !isturf(target.loc)) + return FALSE + if(target.z != mod.wearer.z) + return FALSE + return TRUE + +/obj/item/mod/module/anomaly_locked/kinesis/admin/on_setanchored(atom/movable/grabbed_atom, anchorvalue) + return //thog dont care + +/obj/item/mod/module/anomaly_locked/kinesis/admin/get_configuration() + . = ..() + .["phasing"] = add_ui_configuration("Phasing", "bool", phasing) + +/obj/item/mod/module/anomaly_locked/kinesis/admin/configure_edit(key, value) + switch(key) + if("phasing") + phasing = value + if(!grabbed_atom) + return + if(phasing) + ADD_TRAIT(grabbed_atom, TRAIT_MOVE_PHASING, REF(src)) + else + REMOVE_TRAIT(grabbed_atom, TRAIT_MOVE_PHASING, REF(src)) diff --git a/code/modules/mod/modules/module_pathfinder.dm b/code/modules/mod/modules/module_pathfinder.dm index 2b4f9c70f5f..85d1ce7a00a 100644 --- a/code/modules/mod/modules/module_pathfinder.dm +++ b/code/modules/mod/modules/module_pathfinder.dm @@ -21,9 +21,19 @@ implant = new(src) /obj/item/mod/module/pathfinder/Destroy() - implant = null + QDEL_NULL(implant) return ..() +/obj/item/mod/module/pathfinder/Exited(atom/movable/gone, direction) + if(gone == implant) + implant = null + update_icon_state() + return ..() + +/obj/item/mod/module/pathfinder/update_icon_state() + . = ..() + icon_state = implant ? "pathfinder" : "pathfinder_empty" + /obj/item/mod/module/pathfinder/examine(mob/user) . = ..() if(implant) @@ -45,8 +55,6 @@ else target.visible_message(span_notice("[user] implants [target]."), span_notice("[user] implants you with [implant].")) playsound(src, 'sound/effects/spray.ogg', 30, TRUE, -6) - icon_state = "pathfinder_empty" - implant = null /obj/item/mod/module/pathfinder/proc/attach(mob/living/user) if(!ishuman(user)) diff --git a/code/modules/mod/modules/modules_general.dm b/code/modules/mod/modules/modules_general.dm index e297aeb1851..133bf25b833 100644 --- a/code/modules/mod/modules/modules_general.dm +++ b/code/modules/mod/modules/modules_general.dm @@ -105,7 +105,9 @@ overlay_state_active = "module_jetpack_on" /// Do we give the wearer a speed buff. var/full_speed = FALSE + /// Do we have stabilizers? If yes the user won't move from inertia. var/stabilize = TRUE + /// Callback to see if we can thrust the user. var/thrust_callback /obj/item/mod/module/jetpack/Initialize(mapload) @@ -585,7 +587,7 @@ incompatible_modules = list(/obj/item/mod/module/hat_stabilizer) /*Intentionally left inheriting 0 complexity and removable = TRUE; even though it comes inbuilt into the Magnate/Corporate MODS and spawns in maints, I like the idea of stealing them*/ - /// Currently "stored" hat. No armor or function will be inherited, ONLY the icon. + /// Currently "stored" hat. No armor or function will be inherited, only the icon and cover flags. var/obj/item/clothing/head/attached_hat /// Original cover flags for the MOD helmet, before a hat is placed var/former_flags @@ -616,14 +618,18 @@ SIGNAL_HANDLER if(!istype(hitting_item, /obj/item/clothing/head)) return + var/obj/item/clothing/hat = hitting_item if(!mod.active) balloon_alert(user, "suit must be active!") return if(attached_hat) balloon_alert(user, "hat already attached!") return + if(hat.clothing_flags & STACKABLE_HELMET_EXEMPT) + balloon_alert(user, "invalid hat!") + return if(mod.wearer.transferItemToLoc(hitting_item, src, force = FALSE, silent = TRUE)) - attached_hat = hitting_item + attached_hat = hat former_flags = mod.helmet.flags_cover former_visor_flags = mod.helmet.visor_flags_cover mod.helmet.flags_cover |= attached_hat.flags_cover diff --git a/code/modules/mod/modules/modules_security.dm b/code/modules/mod/modules/modules_security.dm index 38cb4736aa5..c2b77b2650e 100644 --- a/code/modules/mod/modules/modules_security.dm +++ b/code/modules/mod/modules/modules_security.dm @@ -137,9 +137,9 @@ holstered.forceMove(drop_location()) /obj/item/mod/module/holster/Exited(atom/movable/gone, direction) - . = ..() if(gone == holstered) holstered = null + return ..() /obj/item/mod/module/holster/Destroy() QDEL_NULL(holstered)