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