diff --git a/code/__DEFINES/dcs/signals/signals_object.dm b/code/__DEFINES/dcs/signals/signals_object.dm index f978c0ff77d..edec22ac708 100644 --- a/code/__DEFINES/dcs/signals/signals_object.dm +++ b/code/__DEFINES/dcs/signals/signals_object.dm @@ -96,6 +96,8 @@ #define COMSIG_ITEM_EQUIPPED "item_equip" /// A mob has just equipped an item. Called on [/mob] from base of [/obj/item/equipped()]: (/obj/item/equipped_item, slot) #define COMSIG_MOB_EQUIPPED_ITEM "mob_equipped_item" +/// A mob has just unequipped an item. +#define COMSIG_MOB_UNEQUIPPED_ITEM "mob_unequipped_item" ///called on [/obj/item] before unequip from base of [mob/proc/doUnEquip]: (force, atom/newloc, no_move, invdrop, silent) #define COMSIG_ITEM_PRE_UNEQUIP "item_pre_unequip" ///only the pre unequip can be cancelled diff --git a/code/game/objects/effects/effect_system/effects_smoke.dm b/code/game/objects/effects/effect_system/effects_smoke.dm index 24b1af4ee2a..69609a41026 100644 --- a/code/game/objects/effects/effect_system/effects_smoke.dm +++ b/code/game/objects/effects/effect_system/effects_smoke.dm @@ -371,3 +371,11 @@ /datum/effect_system/smoke_spread/quick effect_type = /obj/effect/particle_effect/smoke/quick + +/obj/effect/particle_effect/smoke/chem/quick + lifetime = 2 //under lifetime 1, this kills itself the first time it processes, not working. i hate smoke code + opaque = FALSE + alpha = 100 + +/datum/effect_system/smoke_spread/chem/quick + effect_type = /obj/effect/particle_effect/smoke/chem/quick diff --git a/code/modules/mob/inventory.dm b/code/modules/mob/inventory.dm index d7b8327fbd2..f9407e17bab 100644 --- a/code/modules/mob/inventory.dm +++ b/code/modules/mob/inventory.dm @@ -331,6 +331,7 @@ I.forceMove(newloc) I.dropped(src, silent) SEND_SIGNAL(I, COMSIG_ITEM_POST_UNEQUIP, force, newloc, no_move, invdrop, silent) + SEND_SIGNAL(src, COMSIG_MOB_UNEQUIPPED_ITEM, I, force, newloc, no_move, invdrop, silent) return TRUE /** diff --git a/code/modules/mod/adding_new_mod.md b/code/modules/mod/adding_new_mod.md index 657e3d8d52a..1f18f3c4443 100644 --- a/code/modules/mod/adding_new_mod.md +++ b/code/modules/mod/adding_new_mod.md @@ -29,7 +29,7 @@ For people that want to see additional stuff, we add an extended description wit ``` Next we want to set the statistics, you can view them all in the theme file, so let's just grab our relevant ones, armor, charge and capacity and set them to what we establilished. \ -Currently crew MODsuits should be unarmored in combat relevant stats. +Currently crew MODsuits should be lightly armored in combat relevant stats. ```dm /datum/mod_theme/psychological @@ -40,7 +40,7 @@ Currently crew MODsuits should be unarmored in combat relevant stats. for operating at lower power levels, keeping people sane. As consequence, the capacity \ of the suit has decreased, not being able to fit many modules at all." default_skin = "psychological" - armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 100, FIRE = 10, ACID = 75, WOUND = 5) + armor = list(MELEE = 10, BULLET = 5, LASER = 5, ENERGY = 5, BOMB = 0, BIO = 100, FIRE = 10, ACID = 75, WOUND = 5) complexity_max = DEFAULT_MAX_COMPLEXITY - 7 charge_drain = DEFAULT_CHARGE_DRAIN * 0.5 ``` @@ -206,6 +206,7 @@ As we want this effect to be on demand, we probably want this to be an usable mo - Togglable: You can turn these on and off. - Usable: You can use these for a one time effect. - Active: You can only have one selected at a time. It gives you a special click effect. + As we have an usable module, we want to set a cooldown time. All modules are also incompatible with themselves, have a specific power cost and complexity varying on how powerful they are, so let's update our definition, and also add a new variable for how much brain damage we'll heal. ```dm @@ -320,4 +321,4 @@ Now we want to add it to the psychological theme, which is very simple, finishin ``` ## Ending -This finishes this hopefully easy to follow along tutorial. You should now know how to make a basic theme a skin for it and a module. +This finishes this hopefully easy to follow along tutorial. You should now know how to make a basic theme, a skin for it, and a module. diff --git a/code/modules/mod/mod_control.dm b/code/modules/mod/mod_control.dm index b307fa2018b..607392b3a91 100644 --- a/code/modules/mod/mod_control.dm +++ b/code/modules/mod/mod_control.dm @@ -114,7 +114,7 @@ mod_parts += helmet chestplate = new /obj/item/clothing/suit/mod(src) chestplate.mod = src - chestplate.allowed = theme.allowed_suit_storage.Copy() + chestplate.allowed = typecacheof(theme.allowed_suit_storage) mod_parts += chestplate gauntlets = new /obj/item/clothing/gloves/mod(src) gauntlets.mod = src @@ -148,8 +148,7 @@ if(active) STOP_PROCESSING(SSobj, src) for(var/obj/item/mod/module/module as anything in modules) - module.mod = null - modules -= module + uninstall(module, deleting = TRUE) var/atom/deleting_atom if(!QDELETED(helmet)) deleting_atom = helmet @@ -184,6 +183,7 @@ for(var/obj/item/mod/module/module as anything in modules) for(var/obj/item/item in module) item.forceMove(drop_location()) + uninstall(module) remove_pai(forced = TRUE) // SKYRAT EDIT - pAIs in MODsuits return ..() @@ -529,15 +529,14 @@ var/check_range = TRUE return electrocute_mob(user, get_charge_source(), src, 0.7, check_range) -/obj/item/mod/control/proc/install(module, mob/user) - var/obj/item/mod/module/new_module = module +/obj/item/mod/control/proc/install(obj/item/mod/module/new_module, mob/user) for(var/obj/item/mod/module/old_module as anything in modules) if(is_type_in_list(new_module, old_module.incompatible_modules) || is_type_in_list(old_module, new_module.incompatible_modules)) if(user) balloon_alert(user, "[new_module] incompatible with [old_module]!") playsound(src, 'sound/machines/scanbuzz.ogg', 25, TRUE, SILENCED_SOUND_EXTRARANGE) return - if(is_type_in_list(module, theme.module_blacklist)) + if(is_type_in_list(new_module, theme.module_blacklist)) if(user) balloon_alert(user, "[src] doesn't accept [new_module]!") playsound(src, 'sound/machines/scanbuzz.ogg', 25, TRUE, SILENCED_SOUND_EXTRARANGE) @@ -569,16 +568,15 @@ balloon_alert(user, "[new_module] added") playsound(src, 'sound/machines/click.ogg', 50, TRUE, SILENCED_SOUND_EXTRARANGE) -/obj/item/mod/control/proc/uninstall(module) - var/obj/item/mod/module/old_module = module +/obj/item/mod/control/proc/uninstall(obj/item/mod/module/old_module, deleting = FALSE) modules -= old_module complexity -= old_module.complexity if(active) - old_module.on_suit_deactivation() + old_module.on_suit_deactivation(deleting = deleting) if(old_module.active) - old_module.on_deactivation(display_message = TRUE) + old_module.on_deactivation(display_message = !deleting, deleting = deleting) + old_module.on_uninstall(deleting = deleting) QDEL_LIST(old_module.pinned_to) - old_module.on_uninstall() old_module.mod = null /obj/item/mod/control/proc/update_access(mob/user, obj/item/card/id/card) diff --git a/code/modules/mod/mod_theme.dm b/code/modules/mod/mod_theme.dm index 7086ddf1aab..c17bf2f0166 100644 --- a/code/modules/mod/mod_theme.dm +++ b/code/modules/mod/mod_theme.dm @@ -947,6 +947,7 @@ /obj/item/tank/internals, /obj/item/teleportation_scroll, /obj/item/highfrequencyblade/wizard, + /obj/item/gun/magic, ) skins = list( "enchanted" = list( diff --git a/code/modules/mod/mod_types.dm b/code/modules/mod/mod_types.dm index a1941dbded8..ab1365ba36d 100644 --- a/code/modules/mod/mod_types.dm +++ b/code/modules/mod/mod_types.dm @@ -106,9 +106,9 @@ theme = /datum/mod_theme/security initial_modules = list( /obj/item/mod/module/storage, + /obj/item/mod/module/magnetic_harness, /obj/item/mod/module/flashlight, - /obj/item/mod/module/holster, - /obj/item/mod/module/mister/security, + /obj/item/mod/module/pepper_shoulders, ) /obj/item/mod/control/pre_equipped/safeguard @@ -116,10 +116,10 @@ applied_cell = /obj/item/stock_parts/cell/super initial_modules = list( /obj/item/mod/module/storage/large_capacity, + /obj/item/mod/module/magnetic_harness, /obj/item/mod/module/flashlight, /obj/item/mod/module/jetpack, - /obj/item/mod/module/holster, - /obj/item/mod/module/mister/security, + /obj/item/mod/module/pepper_shoulders, ) /obj/item/mod/control/pre_equipped/magnate @@ -128,8 +128,8 @@ initial_modules = list( /obj/item/mod/module/storage/large_capacity, /obj/item/mod/module/hat_stabilizer, + /obj/item/mod/module/magnetic_harness, /obj/item/mod/module/jetpack/advanced, - /obj/item/mod/module/holster, /obj/item/mod/module/pathfinder, ) @@ -137,6 +137,7 @@ theme = /datum/mod_theme/cosmohonk initial_modules = list( /obj/item/mod/module/storage, + /obj/item/mod/module/waddle, /obj/item/mod/module/bikehorn, ) @@ -145,11 +146,11 @@ applied_cell = /obj/item/stock_parts/cell/super initial_modules = list( /obj/item/mod/module/storage/syndicate, + /obj/item/mod/module/magnetic_harness, /obj/item/mod/module/jetpack, /obj/item/mod/module/pathfinder, /obj/item/mod/module/flashlight, /obj/item/mod/module/dna_lock, - /obj/item/mod/module/holster, ) /obj/item/mod/control/pre_equipped/nuclear @@ -158,10 +159,9 @@ req_access = list(ACCESS_SYNDICATE) initial_modules = list( /obj/item/mod/module/storage/syndicate, + /obj/item/mod/module/magnetic_harness, /obj/item/mod/module/jetpack/advanced, /obj/item/mod/module/flashlight, - /obj/item/mod/module/holster, - /obj/item/mod/module/injector, ) /obj/item/mod/control/pre_equipped/elite @@ -171,20 +171,19 @@ initial_modules = list( /obj/item/mod/module/storage/syndicate, /obj/item/mod/module/emp_shield, + /obj/item/mod/module/magnetic_harness, /obj/item/mod/module/jetpack/advanced, /obj/item/mod/module/flashlight, - /obj/item/mod/module/holster, - /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/magnetic_harness, /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, ) @@ -216,8 +215,8 @@ /obj/item/mod/module/storage/large_capacity, /obj/item/mod/module/welding, /obj/item/mod/module/emp_shield, + /obj/item/mod/module/magnetic_harness, /obj/item/mod/module/flashlight, - /obj/item/mod/module/holster, ) /// The insignia type, insignias show what sort of member of the ERT you're dealing with. var/insignia_type = /obj/item/mod/module/insignia @@ -264,8 +263,8 @@ /obj/item/mod/module/storage/large_capacity, /obj/item/mod/module/welding, /obj/item/mod/module/emp_shield, + /obj/item/mod/module/magnetic_harness, /obj/item/mod/module/flashlight, - /obj/item/mod/module/holster, ) /obj/item/mod/control/pre_equipped/responsory/inquisitory/commander @@ -292,8 +291,8 @@ /obj/item/mod/module/storage/bluespace, /obj/item/mod/module/welding, /obj/item/mod/module/emp_shield, + /obj/item/mod/module/magnetic_harness, /obj/item/mod/module/jetpack, - /obj/item/mod/module/holster, ) /obj/item/mod/control/pre_equipped/corporate @@ -303,7 +302,7 @@ initial_modules = list( /obj/item/mod/module/storage/bluespace, /obj/item/mod/module/hat_stabilizer, - /obj/item/mod/module/holster, + /obj/item/mod/module/magnetic_harness, ) /obj/item/mod/control/pre_equipped/timeline diff --git a/code/modules/mod/modules/_module.dm b/code/modules/mod/modules/_module.dm index f352abc6983..2ec7b5226ad 100644 --- a/code/modules/mod/modules/_module.dm +++ b/code/modules/mod/modules/_module.dm @@ -73,7 +73,7 @@ return /// Called from MODsuit's uninstall() proc, so when the module is uninstalled. -/obj/item/mod/module/proc/on_uninstall() +/obj/item/mod/module/proc/on_uninstall(deleting = FALSE) return /// Called when the MODsuit is activated @@ -81,7 +81,7 @@ return /// Called when the MODsuit is deactivated -/obj/item/mod/module/proc/on_suit_deactivation() +/obj/item/mod/module/proc/on_suit_deactivation(deleting = FALSE) return /// Called when the MODsuit is equipped @@ -145,7 +145,7 @@ return TRUE /// Called when the module is deactivated -/obj/item/mod/module/proc/on_deactivation(display_message = TRUE) +/obj/item/mod/module/proc/on_deactivation(display_message = TRUE, deleting = FALSE) active = FALSE if(module_type == MODULE_ACTIVE) mod.selected_module = null @@ -177,7 +177,7 @@ if(SEND_SIGNAL(src, COMSIG_MODULE_TRIGGERED) & MOD_ABORT_USE) return FALSE COOLDOWN_START(src, cooldown_timer, cooldown_time) - addtimer(CALLBACK(mod.wearer, /mob.proc/update_inv_back), cooldown_time) + addtimer(CALLBACK(mod.wearer, /mob.proc/update_inv_back), cooldown_time+1) //need to run it a bit after the cooldown starts to avoid conflicts mod.wearer.update_inv_back() SEND_SIGNAL(src, COMSIG_MODULE_USED) return TRUE diff --git a/code/modules/mod/modules/module_kinesis.dm b/code/modules/mod/modules/module_kinesis.dm index e90170c2873..840ae7d45fc 100644 --- a/code/modules/mod/modules/module_kinesis.dm +++ b/code/modules/mod/modules/module_kinesis.dm @@ -66,11 +66,11 @@ kinesis_catcher.RegisterSignal(mod.wearer, COMSIG_MOVABLE_MOVED, /atom/movable/screen/fullscreen/kinesis.proc/on_move) soundloop.start() -/obj/item/mod/module/anomaly_locked/kinesis/on_deactivation(display_message = TRUE) +/obj/item/mod/module/anomaly_locked/kinesis/on_deactivation(display_message = TRUE, deleting = FALSE) . = ..() if(!.) return - clear_grab() + clear_grab(playsound = !deleting) /obj/item/mod/module/anomaly_locked/kinesis/process(delta_time) if(!mod.wearer.client || mod.wearer.incapacitated(IGNORE_GRAB)) @@ -97,6 +97,7 @@ if(grabbed_atom.Move(next_turf)) if(isitem(grabbed_atom) && (mod.wearer in next_turf)) var/obj/item/grabbed_item = grabbed_atom + clear_grab() grabbed_item.pickup(mod.wearer) mod.wearer.put_in_hands(grabbed_item) return @@ -219,6 +220,8 @@ COOLDOWN_DECLARE(coordinate_cooldown) /atom/movable/screen/fullscreen/kinesis/proc/on_move(atom/source, atom/oldloc, dir, forced) + SIGNAL_HANDLER + if(given_turf) var/x_offset = source.loc.x - oldloc.x var/y_offset = source.loc.y - oldloc.y diff --git a/code/modules/mod/modules/modules_antag.dm b/code/modules/mod/modules/modules_antag.dm index 5d9fd9b54b1..5867d8fd991 100644 --- a/code/modules/mod/modules/modules_antag.dm +++ b/code/modules/mod/modules/modules_antag.dm @@ -28,7 +28,9 @@ /obj/item/mod/module/armor_booster/on_suit_activation() mod.helmet.flash_protect = FLASH_PROTECTION_WELDER -/obj/item/mod/module/armor_booster/on_suit_deactivation() +/obj/item/mod/module/armor_booster/on_suit_deactivation(deleting = FALSE) + if(deleting) + return mod.helmet.flash_protect = initial(mod.helmet.flash_protect) /obj/item/mod/module/armor_booster/on_activation() @@ -48,11 +50,12 @@ clothing_part.clothing_flags &= ~STOPSPRESSUREDAMAGE spaceproofed[clothing_part] = TRUE -/obj/item/mod/module/armor_booster/on_deactivation(display_message = TRUE) +/obj/item/mod/module/armor_booster/on_deactivation(display_message = TRUE, deleting = FALSE) . = ..() if(!.) return - playsound(src, 'sound/mecha/mechmove03.ogg', 25, TRUE, SHORT_RANGE_SOUND_EXTRARANGE) + if(!deleting) + playsound(src, 'sound/mecha/mechmove03.ogg', 25, TRUE, SHORT_RANGE_SOUND_EXTRARANGE) mod.slowdown -= added_slowdown mod.wearer.update_equipment_speed_mods() var/list/parts = mod.mod_parts + mod @@ -113,7 +116,7 @@ charge_recovery = charge_recovery, lose_multiple_charges = lose_multiple_charges, recharge_path = recharge_path, starting_charges = charges, shield_icon_file = shield_icon_file, shield_icon = shield_icon) RegisterSignal(mod.wearer, COMSIG_HUMAN_CHECK_SHIELDS, .proc/shield_reaction) -/obj/item/mod/module/energy_shield/on_suit_deactivation() +/obj/item/mod/module/energy_shield/on_suit_deactivation(deleting = FALSE) var/datum/component/shielded/shield = mod.GetComponent(/datum/component/shielded) charges = shield.current_charges qdel(shield) @@ -157,7 +160,7 @@ ADD_TRAIT(mod.wearer, TRAIT_ANTIMAGIC, MOD_TRAIT) ADD_TRAIT(mod.wearer, TRAIT_HOLY, MOD_TRAIT) -/obj/item/mod/module/anti_magic/on_suit_deactivation() +/obj/item/mod/module/anti_magic/on_suit_deactivation(deleting = FALSE) REMOVE_TRAIT(mod.wearer, TRAIT_ANTIMAGIC, MOD_TRAIT) REMOVE_TRAIT(mod.wearer, TRAIT_HOLY, MOD_TRAIT) @@ -172,7 +175,7 @@ /obj/item/mod/module/anti_magic/wizard/on_suit_activation() ADD_TRAIT(mod.wearer, TRAIT_ANTIMAGIC_NO_SELFBLOCK, MOD_TRAIT) -/obj/item/mod/module/anti_magic/wizard/on_suit_deactivation() +/obj/item/mod/module/anti_magic/wizard/on_suit_deactivation(deleting = FALSE) REMOVE_TRAIT(mod.wearer, TRAIT_ANTIMAGIC_NO_SELFBLOCK, MOD_TRAIT) ///Insignia - Gives you a skin specific stripe. @@ -230,7 +233,7 @@ /obj/item/mod/module/noslip/on_suit_activation() ADD_TRAIT(mod.wearer, TRAIT_NOSLIPWATER, MOD_TRAIT) -/obj/item/mod/module/noslip/on_suit_deactivation() +/obj/item/mod/module/noslip/on_suit_deactivation(deleting = FALSE) REMOVE_TRAIT(mod.wearer, TRAIT_NOSLIPWATER, MOD_TRAIT) /obj/item/mod/module/springlock/bite_of_87 @@ -247,16 +250,13 @@ /obj/item/mod/module/springlock/bite_of_87/on_install() mod.activation_step_time *= 0.1 -/obj/item/mod/module/springlock/bite_of_87/on_uninstall() +/obj/item/mod/module/springlock/bite_of_87/on_uninstall(deleting = FALSE) mod.activation_step_time *= 10 /obj/item/mod/module/springlock/bite_of_87/on_suit_activation() ..() if(SSevents.holidays && SSevents.holidays[APRIL_FOOLS] || prob(1)) - var/list/all_parts = mod.mod_parts.Copy() + mod - for(var/obj/item/part in all_parts) // turns the suit yellow - part.remove_atom_colour(WASHABLE_COLOUR_PRIORITY) - part.add_atom_colour("#b17f00", FIXED_COLOUR_PRIORITY) + mod.set_mod_color("#b17f00") mod.wearer.remove_atom_colour(WASHABLE_COLOUR_PRIORITY) // turns purple guy purple mod.wearer.add_atom_colour("#704b96", FIXED_COLOUR_PRIORITY) diff --git a/code/modules/mod/modules/modules_engineering.dm b/code/modules/mod/modules/modules_engineering.dm index cafa27d2e22..343000e19dd 100644 --- a/code/modules/mod/modules/modules_engineering.dm +++ b/code/modules/mod/modules/modules_engineering.dm @@ -14,7 +14,9 @@ /obj/item/mod/module/welding/on_suit_activation() mod.helmet.flash_protect = FLASH_PROTECTION_WELDER -/obj/item/mod/module/welding/on_suit_deactivation() +/obj/item/mod/module/welding/on_suit_deactivation(deleting = FALSE) + if(deleting) + return mod.helmet.flash_protect = initial(mod.helmet.flash_protect) ///T-Ray Scan - Scans the terrain for undertile objects. @@ -61,7 +63,7 @@ mod.wearer.update_gravity(mod.wearer.has_gravity()) mod.wearer.update_equipment_speed_mods() -/obj/item/mod/module/magboot/on_deactivation(display_message = TRUE) +/obj/item/mod/module/magboot/on_deactivation(display_message = TRUE, deleting = FALSE) . = ..() if(!.) return @@ -156,7 +158,7 @@ for(var/obj/item/part in mod.mod_parts) ADD_TRAIT(part, TRAIT_RADIATION_PROTECTED_CLOTHING, MOD_TRAIT) -/obj/item/mod/module/rad_protection/on_suit_deactivation() +/obj/item/mod/module/rad_protection/on_suit_deactivation(deleting = FALSE) qdel(GetComponent(/datum/component/geiger_sound)) REMOVE_TRAIT(mod.wearer, TRAIT_BYPASS_EARLY_IRRADIATED_CHECK, MOD_TRAIT) UnregisterSignal(mod.wearer, COMSIG_IN_RANGE_OF_IRRADIATION) @@ -194,7 +196,7 @@ /obj/item/mod/module/constructor/on_suit_activation() ADD_TRAIT(mod.wearer, TRAIT_QUICK_BUILD, MOD_TRAIT) -/obj/item/mod/module/constructor/on_suit_deactivation() +/obj/item/mod/module/constructor/on_suit_deactivation(deleting = FALSE) REMOVE_TRAIT(mod.wearer, TRAIT_QUICK_BUILD, MOD_TRAIT) /obj/item/mod/module/constructor/on_use() diff --git a/code/modules/mod/modules/modules_general.dm b/code/modules/mod/modules/modules_general.dm index e7c5649a313..5e3dfcfc3ff 100644 --- a/code/modules/mod/modules/modules_general.dm +++ b/code/modules/mod/modules/modules_general.dm @@ -34,14 +34,14 @@ SEND_SIGNAL(src, COMSIG_TRY_STORAGE_SET_LOCKSTATE, FALSE) RegisterSignal(mod.chestplate, COMSIG_ITEM_PRE_UNEQUIP, .proc/on_chestplate_unequip) -/obj/item/mod/module/storage/on_uninstall() +/obj/item/mod/module/storage/on_uninstall(deleting = FALSE) var/datum/component/storage/modstorage = mod.GetComponent(/datum/component/storage) storage.slaves -= modstorage qdel(modstorage) - SEND_SIGNAL(src, COMSIG_TRY_STORAGE_QUICK_EMPTY, drop_location()) - SEND_SIGNAL(src, COMSIG_TRY_STORAGE_SET_LOCKSTATE, TRUE) UnregisterSignal(mod.chestplate, COMSIG_ITEM_PRE_UNEQUIP) - + if(!deleting) + SEND_SIGNAL(src, COMSIG_TRY_STORAGE_QUICK_EMPTY, drop_location()) + SEND_SIGNAL(src, COMSIG_TRY_STORAGE_SET_LOCKSTATE, TRUE) /obj/item/mod/module/storage/proc/on_chestplate_unequip(obj/item/source, force, atom/newloc, no_move, invdrop, silent) if(QDELETED(source) || newloc == mod.wearer || !mod.wearer.s_store) return @@ -119,7 +119,7 @@ if(full_speed) mod.wearer.add_movespeed_modifier(/datum/movespeed_modifier/jetpack/fullspeed) -/obj/item/mod/module/jetpack/on_deactivation(display_message = TRUE) +/obj/item/mod/module/jetpack/on_deactivation(display_message = TRUE, deleting = FALSE) . = ..() if(!.) return @@ -199,16 +199,14 @@ /obj/item/mod/module/mouthhole/on_install() former_flags = mod.helmet.flags_cover former_visor_flags = mod.helmet.visor_flags_cover - if(former_flags & HEADCOVERSMOUTH) - mod.helmet.flags_cover &= ~HEADCOVERSMOUTH - if(former_visor_flags & HEADCOVERSMOUTH) - mod.helmet.visor_flags_cover &= ~HEADCOVERSMOUTH + mod.helmet.flags_cover &= ~HEADCOVERSMOUTH|PEPPERPROOF + mod.helmet.visor_flags_cover &= ~HEADCOVERSMOUTH|PEPPERPROOF -/obj/item/mod/module/mouthhole/on_uninstall() - if(former_flags & HEADCOVERSMOUTH) - mod.helmet.flags_cover |= HEADCOVERSMOUTH - if(former_visor_flags & HEADCOVERSMOUTH) - mod.helmet.visor_flags_cover |= HEADCOVERSMOUTH +/obj/item/mod/module/mouthhole/on_uninstall(deleting = FALSE) + if(deleting) + return + mod.helmet.flags_cover |= former_flags + mod.helmet.visor_flags_cover |= former_visor_flags ///EMP Shield - Protects the suit from EMPs. /obj/item/mod/module/emp_shield @@ -224,7 +222,7 @@ /obj/item/mod/module/emp_shield/on_install() mod.AddElement(/datum/element/empprotection, EMP_PROTECT_SELF|EMP_PROTECT_WIRES|EMP_PROTECT_CONTENTS) -/obj/item/mod/module/emp_shield/on_uninstall() +/obj/item/mod/module/emp_shield/on_uninstall(deleting = FALSE) mod.RemoveElement(/datum/element/empprotection, EMP_PROTECT_SELF|EMP_PROTECT_WIRES|EMP_PROTECT_CONTENTS) ///Flashlight - Gives the suit a customizable flashlight. @@ -260,7 +258,7 @@ set_light_on(active) active_power_cost = base_power * light_range -/obj/item/mod/module/flashlight/on_deactivation(display_message = TRUE) +/obj/item/mod/module/flashlight/on_deactivation(display_message = TRUE, deleting = FALSE) . = ..() if(!.) return @@ -347,7 +345,7 @@ /obj/item/mod/module/longfall/on_suit_activation() RegisterSignal(mod.wearer, COMSIG_LIVING_Z_IMPACT, .proc/z_impact_react) -/obj/item/mod/module/longfall/on_suit_deactivation() +/obj/item/mod/module/longfall/on_suit_deactivation(deleting = FALSE) UnregisterSignal(mod.wearer, COMSIG_LIVING_Z_IMPACT) /obj/item/mod/module/longfall/proc/z_impact_react(datum/source, levels, turf/fell_on) @@ -410,7 +408,7 @@ RegisterSignal(mod, COMSIG_ATOM_EMP_ACT, .proc/on_emp) RegisterSignal(mod, COMSIG_ATOM_EMAG_ACT, .proc/on_emag) -/obj/item/mod/module/dna_lock/on_uninstall() +/obj/item/mod/module/dna_lock/on_uninstall(deleting = FALSE) UnregisterSignal(mod, COMSIG_MOD_ACTIVATE) UnregisterSignal(mod, COMSIG_MOD_MODULE_REMOVAL) UnregisterSignal(mod, COMSIG_ATOM_EMP_ACT) @@ -535,7 +533,9 @@ RegisterSignal(mod.helmet, COMSIG_PARENT_ATTACKBY, .proc/place_hat) RegisterSignal(mod.helmet, COMSIG_ATOM_ATTACK_HAND_SECONDARY, .proc/remove_hat) -/obj/item/mod/module/hat_stabilizer/on_suit_deactivation() +/obj/item/mod/module/hat_stabilizer/on_suit_deactivation(deleting = FALSE) + if(deleting) + return if(attached_hat) //knock off the helmet if its on their head. Or, technically, auto-rightclick it for them; that way it saves us code, AND gives them the bubble remove_hat(src, mod.wearer) UnregisterSignal(mod.helmet, COMSIG_PARENT_EXAMINE) @@ -599,5 +599,5 @@ /obj/item/mod/module/signlang_radio/on_suit_activation() ADD_TRAIT(mod.wearer, TRAIT_CAN_SIGN_ON_COMMS, MOD_TRAIT) -/obj/item/mod/module/signlang_radio/on_suit_deactivation() +/obj/item/mod/module/signlang_radio/on_suit_deactivation(deleting = FALSE) REMOVE_TRAIT(mod.wearer, TRAIT_CAN_SIGN_ON_COMMS, MOD_TRAIT) diff --git a/code/modules/mod/modules/modules_maint.dm b/code/modules/mod/modules/modules_maint.dm index 61f676827d7..3b9f075b585 100644 --- a/code/modules/mod/modules/modules_maint.dm +++ b/code/modules/mod/modules/modules_maint.dm @@ -14,13 +14,13 @@ /obj/item/mod/module/springlock/on_install() mod.activation_step_time *= 0.5 -/obj/item/mod/module/springlock/on_uninstall() +/obj/item/mod/module/springlock/on_uninstall(deleting = FALSE) mod.activation_step_time *= 2 /obj/item/mod/module/springlock/on_suit_activation() RegisterSignal(mod.wearer, COMSIG_ATOM_EXPOSE_REAGENTS, .proc/on_wearer_exposed) -/obj/item/mod/module/springlock/on_suit_deactivation() +/obj/item/mod/module/springlock/on_suit_deactivation(deleting = FALSE) UnregisterSignal(mod.wearer, COMSIG_ATOM_EXPOSE_REAGENTS) ///Signal fired when wearer is exposed to reagents @@ -107,13 +107,15 @@ if(selection) SEND_SOUND(mod.wearer, sound(selection.song_path, volume = 50, channel = CHANNEL_JUKEBOX)) -/obj/item/mod/module/visor/rave/on_deactivation(display_message = TRUE) +/obj/item/mod/module/visor/rave/on_deactivation(display_message = TRUE, deleting = FALSE) . = ..() if(!.) return QDEL_NULL(rave_screen) if(selection) mod.wearer.stop_sound_channel(CHANNEL_JUKEBOX) + if(deleting) + return SEND_SOUND(mod.wearer, sound('sound/machines/terminal_off.ogg', volume = 50, channel = CHANNEL_JUKEBOX)) /obj/item/mod/module/visor/rave/generate_worn_overlay(mutable_appearance/standing) @@ -286,14 +288,15 @@ ADD_TRAIT(mod.wearer, TRAIT_SILENT_FOOTSTEPS, MOD_TRAIT) check_upstairs() //todo at some point flip your screen around -/obj/item/mod/module/atrocinator/on_deactivation(display_message = TRUE) - if(you_fucked_up) +/obj/item/mod/module/atrocinator/on_deactivation(display_message = TRUE, deleting = FALSE) + if(you_fucked_up && !deleting) to_chat(mod.wearer, span_danger("It's too late.")) return FALSE . = ..() if(!.) return - playsound(src, 'sound/effects/curseattack.ogg', 50) + if(deleting) + playsound(src, 'sound/effects/curseattack.ogg', 50) qdel(mod.wearer.RemoveElement(/datum/element/forced_gravity, NEGATIVE_GRAVITY)) UnregisterSignal(mod.wearer, COMSIG_MOVABLE_MOVED) step_count = 0 diff --git a/code/modules/mod/modules/modules_medical.dm b/code/modules/mod/modules/modules_medical.dm index 9f42354b48f..40a110c8bb4 100644 --- a/code/modules/mod/modules/modules_medical.dm +++ b/code/modules/mod/modules/modules_medical.dm @@ -73,7 +73,7 @@ /obj/item/mod/module/quick_carry/on_suit_activation() ADD_TRAIT(mod.wearer, TRAIT_QUICK_CARRY, MOD_TRAIT) -/obj/item/mod/module/quick_carry/on_suit_deactivation() +/obj/item/mod/module/quick_carry/on_suit_deactivation(deleting = FALSE) REMOVE_TRAIT(mod.wearer, TRAIT_QUICK_CARRY, MOD_TRAIT) /obj/item/mod/module/quick_carry/advanced @@ -85,7 +85,7 @@ ADD_TRAIT(mod.wearer, TRAIT_QUICKER_CARRY, MOD_TRAIT) ADD_TRAIT(mod.wearer, TRAIT_FASTMED, MOD_TRAIT) -/obj/item/mod/module/quick_carry/on_suit_deactivation() +/obj/item/mod/module/quick_carry/on_suit_deactivation(deleting = FALSE) REMOVE_TRAIT(mod.wearer, TRAIT_QUICKER_CARRY, MOD_TRAIT) REMOVE_TRAIT(mod.wearer, TRAIT_FASTMED, MOD_TRAIT) diff --git a/code/modules/mod/modules/modules_science.dm b/code/modules/mod/modules/modules_science.dm index dfed572fe7c..1db740b9791 100644 --- a/code/modules/mod/modules/modules_science.dm +++ b/code/modules/mod/modules/modules_science.dm @@ -19,7 +19,7 @@ return ADD_TRAIT(mod.wearer, TRAIT_REAGENT_SCANNER, MOD_TRAIT) -/obj/item/mod/module/reagent_scanner/on_deactivation(display_message = TRUE) +/obj/item/mod/module/reagent_scanner/on_deactivation(display_message = TRUE, deleting = FALSE) . = ..() if(!.) return @@ -38,7 +38,7 @@ mod.wearer.research_scanner++ RegisterSignal(SSdcs, COMSIG_GLOB_EXPLOSION, .proc/sense_explosion) -/obj/item/mod/module/reagent_scanner/advanced/on_deactivation(display_message = TRUE) +/obj/item/mod/module/reagent_scanner/advanced/on_deactivation(display_message = TRUE, deleting = FALSE) . = ..() if(!.) return @@ -77,12 +77,14 @@ mod.wearer.update_gravity(mod.wearer.has_gravity()) playsound(src, 'sound/effects/gravhit.ogg', 50) -/obj/item/mod/module/anomaly_locked/antigrav/on_deactivation(display_message = TRUE) +/obj/item/mod/module/anomaly_locked/antigrav/on_deactivation(display_message = TRUE, deleting = FALSE) . = ..() if(!.) return mod.wearer.RemoveElement(/datum/element/forced_gravity, 0) mod.wearer.update_gravity(mod.wearer.has_gravity()) + if(deleting) + return if(mod.wearer.has_gravity()) new /obj/effect/temp_visual/mook_dust(get_turf(src)) playsound(src, 'sound/effects/gravhit.ogg', 50) diff --git a/code/modules/mod/modules/modules_security.dm b/code/modules/mod/modules/modules_security.dm index 17bc3dc7b60..067735b092d 100644 --- a/code/modules/mod/modules/modules_security.dm +++ b/code/modules/mod/modules/modules_security.dm @@ -30,7 +30,7 @@ animate(mod.wearer, alpha = stealth_alpha, time = 1.5 SECONDS) drain_power(use_power_cost) -/obj/item/mod/module/stealth/on_deactivation(display_message = TRUE) +/obj/item/mod/module/stealth/on_deactivation(display_message = TRUE, deleting = FALSE) . = ..() if(!.) return @@ -45,7 +45,7 @@ to_chat(mod.wearer, span_warning("[src] gets discharged from contact!")) do_sparks(2, TRUE, src) drain_power(use_power_cost) - on_deactivation(display_message = TRUE) + on_deactivation(display_message = TRUE, deleting = FALSE) /obj/item/mod/module/stealth/proc/on_unarmed_attack(datum/source, atom/target) SIGNAL_HANDLER @@ -75,67 +75,95 @@ use_power_cost = DEFAULT_CHARGE_DRAIN * 5 cooldown_time = 3 SECONDS -///Holster - Instantly holsters any not huge gun. -/obj/item/mod/module/holster - name = "MOD holster module" - desc = "Based off typical storage compartments, this system allows the suit to holster a \ - standard firearm across its surface and allow for extremely quick retrieval. \ - While some users prefer the chest, others the forearm for quick deployment, \ - some law enforcement prefer the holster to extend from the thigh." - icon_state = "holster" - module_type = MODULE_USABLE +///Magnetic Harness - Automatically puts guns in your suit storage when you drop them. +/obj/item/mod/module/magnetic_harness + name = "MOD magnetic harness module" + desc = "Based off old TerraGov harness kits, this magnetic harness automatically attaches dropped guns back to the wearer." + icon_state = "mag_harness" complexity = 2 - use_power_cost = DEFAULT_CHARGE_DRAIN * 0.5 - incompatible_modules = list(/obj/item/mod/module/holster) - cooldown_time = 0.5 SECONDS - /// Gun we have holstered. - var/obj/item/gun/holstered + use_power_cost = DEFAULT_CHARGE_DRAIN + incompatible_modules = list(/obj/item/mod/module/magnetic_harness) + /// Time before we activate the magnet. + var/magnet_delay = 0.8 SECONDS + /// The typecache of all guns we allow. + var/static/list/guns_typecache + /// The guns already allowed by the modsuit chestplate. + var/list/already_allowed_guns = list() -/obj/item/mod/module/holster/on_use() +/obj/item/mod/module/magnetic_harness/Initialize(mapload) + . = ..() + if(!guns_typecache) + guns_typecache = typecacheof(list(/obj/item/gun/ballistic, /obj/item/gun/energy, /obj/item/gun/grenadelauncher, /obj/item/gun/chem, /obj/item/gun/syringe)) + +/obj/item/mod/module/magnetic_harness/on_install() + already_allowed_guns = guns_typecache & mod.chestplate.allowed + mod.chestplate.allowed |= guns_typecache + +/obj/item/mod/module/magnetic_harness/on_uninstall(deleting = FALSE) + if(deleting) + return + mod.chestplate.allowed -= (guns_typecache - already_allowed_guns) + +/obj/item/mod/module/magnetic_harness/on_suit_activation() + RegisterSignal(mod.wearer, COMSIG_MOB_UNEQUIPPED_ITEM, .proc/check_dropped_item) + +/obj/item/mod/module/magnetic_harness/on_suit_deactivation(deleting = FALSE) + UnregisterSignal(mod.wearer, COMSIG_MOB_UNEQUIPPED_ITEM) + +/obj/item/mod/module/magnetic_harness/proc/check_dropped_item(datum/source, obj/item/dropped_item, force, new_location) + SIGNAL_HANDLER + + if(!is_type_in_typecache(dropped_item, guns_typecache)) + return + if(new_location != get_turf(src)) + return + addtimer(CALLBACK(src, .proc/pick_up_item, dropped_item), magnet_delay) + +/obj/item/mod/module/magnetic_harness/proc/pick_up_item(obj/item/item) + if(!isturf(item.loc) || !item.Adjacent(mod.wearer)) + return + if(!mod.wearer.equip_to_slot_if_possible(item, ITEM_SLOT_SUITSTORE, qdel_on_fail = FALSE, disable_warning = TRUE)) + return + playsound(src, 'sound/items/modsuit/magnetic_harness.ogg', 50, TRUE) + balloon_alert(mod.wearer, "[item] reattached") + drain_power(use_power_cost) + +///Pepper Shoulders - When hit, reacts with a spray of pepper spray around the user. +/obj/item/mod/module/pepper_shoulders + name = "MOD pepper shoulders module" + desc = "A module that attaches two pepper sprayers on shoulders of a MODsuit, reacting to touch with a spray around the user." + icon_state = "pepper_shoulder" + module_type = MODULE_USABLE + complexity = 1 + use_power_cost = DEFAULT_CHARGE_DRAIN + incompatible_modules = list(/obj/item/mod/module/pepper_shoulders) + cooldown_time = 5 SECONDS + overlay_state_inactive = "module_pepper" + overlay_state_use = "module_pepper_used" + +/obj/item/mod/module/pepper_shoulders/on_suit_activation() + RegisterSignal(mod.wearer, COMSIG_HUMAN_CHECK_SHIELDS, .proc/on_check_shields) + +/obj/item/mod/module/pepper_shoulders/on_suit_deactivation(deleting = FALSE) + UnregisterSignal(mod.wearer, COMSIG_HUMAN_CHECK_SHIELDS) + +/obj/item/mod/module/pepper_shoulders/on_use() . = ..() if(!.) return - if(!holstered) - var/obj/item/gun/holding = mod.wearer.get_active_held_item() - if(!holding) - balloon_alert(mod.wearer, "nothing to holster!") - return - if(!istype(holding) || holding.w_class > WEIGHT_CLASS_BULKY) - balloon_alert(mod.wearer, "it doesn't fit!") - return - if(mod.wearer.transferItemToLoc(holding, src, force = FALSE, silent = TRUE)) - holstered = holding - balloon_alert(mod.wearer, "weapon holstered") - playsound(src, 'sound/weapons/gun/revolver/empty.ogg', 100, TRUE) - drain_power(use_power_cost) - else if(mod.wearer.put_in_active_hand(holstered, forced = FALSE, ignore_animation = TRUE)) - balloon_alert(mod.wearer, "weapon drawn") - holstered = null - playsound(src, 'sound/weapons/gun/revolver/empty.ogg', 100, TRUE) - drain_power(use_power_cost) - else - balloon_alert(mod.wearer, "holster full!") + playsound(src, 'sound/effects/spray.ogg', 30, TRUE, -6) + var/datum/reagents/capsaicin_holder = new(10) + capsaicin_holder.add_reagent(/datum/reagent/consumable/condensedcapsaicin, 10) + var/datum/effect_system/smoke_spread/chem/quick/smoke = new + smoke.set_up(capsaicin_holder, 1, get_turf(src)) + smoke.start() -/obj/item/mod/module/holster/on_uninstall() - if(holstered) - holstered.forceMove(drop_location()) - holstered = null +/obj/item/mod/module/pepper_shoulders/proc/on_check_shields() + SIGNAL_HANDLER -/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." + if(!COOLDOWN_FINISHED(src, cooldown_timer)) + return + if(!check_power(use_power_cost)) + return + mod.wearer.visible_message(span_warning("[src] reacts to the attack with a smoke of pepper spray!"), span_notice("Your [src] releases a cloud of pepper spray!")) + on_use() diff --git a/code/modules/mod/modules/modules_service.dm b/code/modules/mod/modules/modules_service.dm index 3c5526232b6..210472cfb4a 100644 --- a/code/modules/mod/modules/modules_service.dm +++ b/code/modules/mod/modules/modules_service.dm @@ -58,7 +58,7 @@ //Waddle - Makes you waddle and squeak. /obj/item/mod/module/waddle name = "MOD waddle module" - desc = "Some of the most primitive technology in use by HonkCo. This module works off an automatic intention system, \ + desc = "Some of the most primitive technology in use by Honk Co. This module works off an automatic intention system, \ utilizing its' sensitivity to the pilot's often-limited brainwaves to directly read their next step, \ affecting the boots they're installed in. Employing a twin-linked gravitonic drive to create \ miniaturized etheric blasts of space-time beneath the user's feet, this enables them to... \ @@ -74,8 +74,9 @@ if(is_clown_job(mod.wearer.mind?.assigned_role)) SEND_SIGNAL(mod.wearer, COMSIG_ADD_MOOD_EVENT, "clownshoes", /datum/mood_event/clownshoes) -/obj/item/mod/module/waddle/on_suit_deactivation() - qdel(mod.boots.GetComponent(/datum/component/squeak)) +/obj/item/mod/module/waddle/on_suit_deactivation(deleting = FALSE) + if(!deleting) + qdel(mod.boots.GetComponent(/datum/component/squeak)) mod.wearer.RemoveElement(/datum/element/waddling) if(is_clown_job(mod.wearer.mind?.assigned_role)) SEND_SIGNAL(mod.wearer, COMSIG_CLEAR_MOOD_EVENT, "clownshoes") diff --git a/code/modules/mod/modules/modules_supply.dm b/code/modules/mod/modules/modules_supply.dm index 32abb6cddd2..79b2300b4eb 100644 --- a/code/modules/mod/modules/modules_supply.dm +++ b/code/modules/mod/modules/modules_supply.dm @@ -52,17 +52,19 @@ return if(istype(target, /obj/structure/closet/crate) || istype(target, /obj/item/delivery/big)) var/atom/movable/picked_crate = target - if(length(stored_crates) >= max_crates) - balloon_alert(mod.wearer, "too many crates!") + if(!check_crate_pickup(picked_crate)) return playsound(src, 'sound/mecha/hydraulic.ogg', 25, TRUE) if(!do_after(mod.wearer, load_time, target = target)) balloon_alert(mod.wearer, "interrupted!") return + if(!check_crate_pickup(picked_crate)) + return stored_crates += picked_crate picked_crate.forceMove(src) balloon_alert(mod.wearer, "picked up [picked_crate]") drain_power(use_power_cost) + mod.wearer.update_inv_back() else if(length(stored_crates)) var/turf/target_turf = get_turf(target) if(target_turf.is_blocked_turf()) @@ -77,14 +79,28 @@ dropped_crate.forceMove(target_turf) balloon_alert(mod.wearer, "dropped [dropped_crate]") drain_power(use_power_cost) + mod.wearer.update_inv_back() else balloon_alert(mod.wearer, "invalid target!") -/obj/item/mod/module/clamp/on_suit_deactivation() +/obj/item/mod/module/clamp/on_suit_deactivation(deleting = FALSE) + if(deleting) + return for(var/atom/movable/crate as anything in stored_crates) crate.forceMove(drop_location()) stored_crates -= crate +/obj/item/mod/module/clamp/proc/check_crate_pickup(atom/movable/target) + if(length(stored_crates) >= max_crates) + balloon_alert(mod.wearer, "too many crates!") + return FALSE + for(var/mob/living/mob in target.get_all_contents()) + if(mob.mob_size < MOB_SIZE_HUMAN) + continue + balloon_alert(mod.wearer, "crate too heavy!") + return FALSE + return TRUE + /obj/item/mod/module/clamp/loader name = "MOD loader hydraulic clamp module" icon_state = "clamp_loader" @@ -115,7 +131,7 @@ return RegisterSignal(mod.wearer, COMSIG_MOVABLE_BUMP, .proc/bump_mine) -/obj/item/mod/module/drill/on_deactivation(display_message = TRUE) +/obj/item/mod/module/drill/on_deactivation(display_message = TRUE, deleting = FALSE) . = ..() if(!.) return @@ -210,11 +226,11 @@ var/launch_time = 2 SECONDS /// User overlay var/mutable_appearance/lightning - + /obj/item/mod/module/hydraulic/on_suit_activation() ADD_TRAIT(mod.wearer, TRAIT_TRASHMAN, MOD_TRAIT) -/obj/item/mod/module/hydraulic/on_suit_deactivation() +/obj/item/mod/module/hydraulic/on_suit_deactivation(deleting = FALSE) //SKYRAT EDIT REMOVE_TRAIT(mod.wearer, TRAIT_TRASHMAN, MOD_TRAIT) /obj/item/mod/module/hydraulic/on_select_use(atom/target) @@ -269,7 +285,7 @@ /obj/item/mod/module/disposal_connector/on_suit_activation() RegisterSignal(mod.wearer, COMSIG_MOVABLE_DISPOSING, .proc/disposal_handling) -/obj/item/mod/module/disposal_connector/on_suit_deactivation() +/obj/item/mod/module/disposal_connector/on_suit_deactivation(deleting = FALSE) UnregisterSignal(mod.wearer, COMSIG_MOVABLE_DISPOSING) /obj/item/mod/module/disposal_connector/get_configuration() @@ -323,7 +339,7 @@ locker.throw_at(mod.wearer, range = 7, speed = 3, force = MOVE_FORCE_WEAK, \ callback = CALLBACK(src, .proc/check_locker, locker)) -/obj/item/mod/module/magnet/on_deactivation(display_message = TRUE) +/obj/item/mod/module/magnet/on_deactivation(display_message = TRUE, deleting = FALSE) . = ..() if(!.) return @@ -394,7 +410,7 @@ ADD_TRAIT(mod.wearer, TRAIT_SNOWSTORM_IMMUNE, MOD_TRAIT) RegisterSignal(mod.wearer, COMSIG_MOVABLE_MOVED, .proc/on_move) -/obj/item/mod/module/ash_accretion/on_suit_deactivation() +/obj/item/mod/module/ash_accretion/on_suit_deactivation(deleting = FALSE) REMOVE_TRAIT(mod.wearer, TRAIT_ASHSTORM_IMMUNE, MOD_TRAIT) REMOVE_TRAIT(mod.wearer, TRAIT_SNOWSTORM_IMMUNE, MOD_TRAIT) UnregisterSignal(mod.wearer, COMSIG_MOVABLE_MOVED) @@ -490,11 +506,12 @@ mod.wearer.add_movespeed_modifier(/datum/movespeed_modifier/sphere) RegisterSignal(mod.wearer, COMSIG_MOB_STATCHANGE, .proc/on_statchange) -/obj/item/mod/module/sphere_transform/on_deactivation(display_message = TRUE) +/obj/item/mod/module/sphere_transform/on_deactivation(display_message = TRUE, deleting = FALSE) . = ..() if(!.) return - playsound(src, 'sound/items/modsuit/ballout.ogg', 100) + if(!deleting) + playsound(src, 'sound/items/modsuit/ballout.ogg', 100) mod.wearer.base_pixel_y = 0 animate(mod.wearer, animate_time, pixel_y = mod.wearer.base_pixel_y) addtimer(CALLBACK(mod.wearer, /atom.proc/remove_filter, list("mod_ball", "mod_blur", "mod_outline")), animate_time) diff --git a/code/modules/mod/modules/modules_timeline.dm b/code/modules/mod/modules/modules_timeline.dm index 69bcbe667c2..b52f2dfbfb0 100644 --- a/code/modules/mod/modules/modules_timeline.dm +++ b/code/modules/mod/modules/modules_timeline.dm @@ -16,14 +16,14 @@ use_power_cost = DEFAULT_CHARGE_DRAIN * 3 incompatible_modules = list(/obj/item/mod/module/eradication_lock, /obj/item/mod/module/dna_lock) cooldown_time = 0.5 SECONDS - /// The ckey we lock with, to allow all alternate versions of the user, huhehuehe + /// The ckey we lock with, to allow all alternate versions of the user. var/true_owner_ckey /obj/item/mod/module/eradication_lock/on_install() RegisterSignal(mod, COMSIG_MOD_ACTIVATE, .proc/on_mod_activation) RegisterSignal(mod, COMSIG_MOD_MODULE_REMOVAL, .proc/on_mod_removal) -/obj/item/mod/module/eradication_lock/on_uninstall() +/obj/item/mod/module/eradication_lock/on_uninstall(deleting = FALSE) UnregisterSignal(mod, COMSIG_MOD_ACTIVATE) UnregisterSignal(mod, COMSIG_MOD_MODULE_REMOVAL) @@ -109,7 +109,7 @@ use_power_cost = DEFAULT_CHARGE_DRAIN * 5 incompatible_modules = list(/obj/item/mod/module/timestopper) cooldown_time = 60 SECONDS - ///the current timestop in progress + ///The current timestop in progress. var/obj/effect/timestop/channelled/timestop /obj/item/mod/module/timestopper/on_use() @@ -157,7 +157,7 @@ incompatible_modules = list(/obj/item/mod/module/timeline_jumper) cooldown_time = 5 SECONDS allowed_in_phaseout = TRUE - ///the dummy for phasing from this module, the wearer is phased out while this exists. + ///The dummy for phasing from this module, the wearer is phased out while this exists. var/obj/effect/dummy/phased_mob/chrono/phased_mob /obj/item/mod/module/timeline_jumper/on_use() @@ -190,7 +190,7 @@ /obj/item/mod/module/timeline_jumper/proc/on_activate_block(datum/source, user) SIGNAL_HANDLER //has to be a to_chat because you're phased out. - to_chat(user, span_boldwarning("Deactivating your suit while inbetween timelines would be a very bad idea.")) + to_chat(user, span_warning("Deactivating your suit while inbetween timelines would be a very bad idea.")) return MOD_CANCEL_ACTIVATE ///special subtype for phased mobs. @@ -210,9 +210,9 @@ use_power_cost = DEFAULT_CHARGE_DRAIN * 5 incompatible_modules = list(/obj/item/mod/module/tem) cooldown_time = 0.5 SECONDS - ///reference to the chrono field being controlled by this module + ///Reference to the chrono field being controlled by this module var/obj/structure/chrono_field/field = null - ///where the chronofield maker was when the field went up + ///Where the chronofield maker was when the field went up var/turf/startpos /obj/item/mod/module/tem/on_select_use(atom/target) @@ -223,16 +223,17 @@ if(field) field_disconnect(field) //fire projectile - var/obj/projectile/energy/chrono_beam/projectile = new /obj/projectile/energy/chrono_beam(get_turf(src)) + var/obj/projectile/energy/chrono_beam/chrono_beam = new /obj/projectile/energy/chrono_beam(get_turf(src)) + chrono_beam.tem_weakref = WEAKREF(src) + chrono_beam.preparePixelProjectile(target, mod.wearer) + chrono_beam.firer = mod.wearer playsound(src, 'sound/items/modsuit/time_anchor_set.ogg', 50, TRUE) - projectile.tem_weakref = WEAKREF(src) - projectile.firer = mod.wearer - projectile.fired_from = src - projectile.fire(get_angle(mod.wearer, target), target) + INVOKE_ASYNC(chrono_beam, /obj/projectile.proc/fire) -/obj/item/mod/module/tem/on_uninstall() - if(field) - field_disconnect(field) +/obj/item/mod/module/tem/on_uninstall(deleting = FALSE) + if(!field) + return + field_disconnect(field) /** * ### field_connect @@ -246,14 +247,14 @@ /obj/item/mod/module/tem/proc/field_connect(obj/structure/chrono_field/field) if(field.tem) if(field.captured) - to_chat(mod.wearer, span_alert("FAIL: [field.captured] already has an existing connection.")) + balloon_alert(mod.wearer, "already has connection!") field_disconnect(field) return startpos = get_turf(mod.wearer) src.field = field field.tem = src if(field.captured) - to_chat(mod.wearer, span_notice("Connection established with target: [field.captured]")) + balloon_alert(mod.wearer, "connection estabilished") /** * ### field_disconnect @@ -268,7 +269,7 @@ if(field.tem == src) field.tem = null if(field.captured) - to_chat(mod.wearer, span_alert("Disconnected from target: [field.captured]")) + balloon_alert(mod.wearer, "connection lost!") field = null startpos = null @@ -294,7 +295,7 @@ icon_state = "chronobolt" range = CHRONO_BEAM_RANGE nodamage = TRUE - ///reference to the tem... given by the tem! weakref because back in the day we didn't know about harddels- or maybe we didn't care. + ///Reference to the tem... given by the tem! weakref because back in the day we didn't know about harddels- or maybe we didn't care. var/datum/weakref/tem_weakref /obj/projectile/energy/chrono_beam/on_hit(atom/target) @@ -318,7 +319,7 @@ ///linked module. while this exists, the field will progress towards eradication. while it isn't, the field progresses away until it disappears. see attached for a special case var/obj/item/mod/module/tem/tem ///time in seconds before someone is eradicated, assuming progress isn't interrupted - var/timetokill = 30 + var/timetokill = 3 SECONDS ///the eradication appearance var/mutable_appearance/mob_underlay ///the actual frame the animation is at in eradication, only changing when the progress towards eradication progresses enough to move to the next frame. @@ -373,15 +374,15 @@ freed_movable.forceMove(drop_location()) qdel(src) else if(timetokill <= 0) - to_chat(captured, span_boldnotice("As the last essence of your being is erased from time, you are taken back to your most enjoyable memory. You feel happy...")) - var/mob/dead/observer/ghost = captured.ghostize(1) + to_chat(captured, span_notice("As the last essence of your being is erased from time, you are taken back to your most enjoyable memory. You feel happy...")) + var/mob/dead/observer/ghost = captured.ghostize(can_reenter_corpse = TRUE) if(captured.mind) if(ghost) ghost.mind = null qdel(captured) qdel(src) else - captured.Unconscious(80) + captured.Unconscious(8 SECONDS) if(captured.loc != src) captured.forceMove(src) update_appearance() diff --git a/code/modules/mod/modules/modules_visor.dm b/code/modules/mod/modules/modules_visor.dm index 82808568189..740489b5645 100644 --- a/code/modules/mod/modules/modules_visor.dm +++ b/code/modules/mod/modules/modules_visor.dm @@ -25,7 +25,7 @@ ADD_TRAIT(mod.wearer, trait, MOD_TRAIT) mod.wearer.update_sight() -/obj/item/mod/module/visor/on_deactivation(display_message = TRUE) +/obj/item/mod/module/visor/on_deactivation(display_message = TRUE, deleting = FALSE) . = ..() if(!.) return diff --git a/code/modules/research/designs/mechfabricator_designs.dm b/code/modules/research/designs/mechfabricator_designs.dm index b2b68f91065..c993b3f5b05 100644 --- a/code/modules/research/designs/mechfabricator_designs.dm +++ b/code/modules/research/designs/mechfabricator_designs.dm @@ -1186,11 +1186,11 @@ build_path = /obj/item/mod/module/magboot department_type = MODULE_ENGINEERING -/datum/design/module/mod_holster - name = "MOD Module: Holster" - id = "mod_holster" - materials = list(/datum/material/iron = 1500, /datum/material/glass = 500) - build_path = /obj/item/mod/module/holster +/datum/design/module/mod_mag_harness + name = "MOD Module: Magnetic Harness" + id = "mod_mag_harness" + materials = list(/datum/material/iron = 1500, /datum/material/silver = 500) + build_path = /obj/item/mod/module/magnetic_harness department_type = MODULE_SECURITY /datum/design/module/mod_tether diff --git a/code/modules/research/techweb/all_nodes.dm b/code/modules/research/techweb/all_nodes.dm index f4fdaedc702..5f5ed5385e7 100644 --- a/code/modules/research/techweb/all_nodes.dm +++ b/code/modules/research/techweb/all_nodes.dm @@ -1609,7 +1609,7 @@ "mod_plating_security", "mod_visor_sechud", "mod_stealth", - "mod_holster", + "mod_mag_harness", "mod_pathfinder", ) research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) diff --git a/code/modules/wiremod/shell/module.dm b/code/modules/wiremod/shell/module.dm index b3a8275d607..5bb837134b3 100644 --- a/code/modules/wiremod/shell/module.dm +++ b/code/modules/wiremod/shell/module.dm @@ -23,9 +23,13 @@ . = COMPONENT_OVERRIDE_POWER_USAGE /obj/item/mod/module/circuit/on_install() + if(!shell?.attached_circuit) + return RegisterSignal(shell?.attached_circuit, COMSIG_CIRCUIT_PRE_POWER_USAGE, .proc/override_power_usage) -/obj/item/mod/module/circuit/on_uninstall() +/obj/item/mod/module/circuit/on_uninstall(deleting = FALSE) + if(!shell?.attached_circuit) + return UnregisterSignal(shell?.attached_circuit, COMSIG_CIRCUIT_PRE_POWER_USAGE) /obj/item/mod/module/circuit/on_use() diff --git a/icons/mob/clothing/modsuit/mod_modules.dmi b/icons/mob/clothing/modsuit/mod_modules.dmi index e37f3e46416..aaf9541d5b7 100644 Binary files a/icons/mob/clothing/modsuit/mod_modules.dmi and b/icons/mob/clothing/modsuit/mod_modules.dmi differ diff --git a/icons/obj/clothing/modsuit/mod_modules.dmi b/icons/obj/clothing/modsuit/mod_modules.dmi index f838dbd4aeb..7a226fb59b5 100644 Binary files a/icons/obj/clothing/modsuit/mod_modules.dmi and b/icons/obj/clothing/modsuit/mod_modules.dmi differ diff --git a/modular_skyrat/modules/contractor/code/items/modsuit/modsuit.dm b/modular_skyrat/modules/contractor/code/items/modsuit/modsuit.dm index 97761b3a4f1..66523e225f7 100644 --- a/modular_skyrat/modules/contractor/code/items/modsuit/modsuit.dm +++ b/modular_skyrat/modules/contractor/code/items/modsuit/modsuit.dm @@ -9,7 +9,7 @@ /obj/item/mod/module/tether, /obj/item/mod/module/flashlight, /obj/item/mod/module/dna_lock, - /obj/item/mod/module/holster, + /obj/item/mod/module/magnetic_harness, ) /obj/item/mod/control/pre_equipped/contractor/upgraded @@ -18,7 +18,7 @@ /obj/item/mod/module/storage/syndicate, /obj/item/mod/module/jetpack, /obj/item/mod/module/dna_lock, - /obj/item/mod/module/holster, + /obj/item/mod/module/magnetic_harness, /obj/item/mod/module/baton_holster/preloaded, ) diff --git a/modular_skyrat/modules/contractor/code/items/modsuit/modules.dm b/modular_skyrat/modules/contractor/code/items/modsuit/modules.dm index 47f6dc32ad0..a5e845bbe31 100644 --- a/modular_skyrat/modules/contractor/code/items/modsuit/modules.dm +++ b/modular_skyrat/modules/contractor/code/items/modsuit/modules.dm @@ -133,7 +133,7 @@ chameleon_right = initial(mod.righthand_file) RegisterSignal(mod, COMSIG_MOD_ACTIVATE, .proc/reset_chameleon) -/obj/item/mod/module/chameleon/on_uninstall() +/obj/item/mod/module/chameleon/on_uninstall(deleting = FALSE) UnregisterSignal(mod, COMSIG_MOD_ACTIVATE) reset_chameleon() @@ -220,14 +220,14 @@ /obj/item/mod/module/springlock/on_suit_activation() // This module is actually *not* a death trap return -/obj/item/mod/module/springlock/on_suit_deactivation() +/obj/item/mod/module/springlock/on_suit_deactivation(deleting = FALSE) return /obj/item/mod/module/storage/syndicate var/chameleon_disguised = FALSE -/obj/item/mod/module/storage/syndicate/on_uninstall() +/obj/item/mod/module/storage/syndicate/on_uninstall(deleting = FALSE) if(chameleon_disguised) name = initial(name) chameleon_disguised = FALSE diff --git a/sound/items/modsuit/magnetic_harness.ogg b/sound/items/modsuit/magnetic_harness.ogg new file mode 100644 index 00000000000..3d19fccc569 Binary files /dev/null and b/sound/items/modsuit/magnetic_harness.ogg differ