diff --git a/code/__DEFINES/mobs.dm b/code/__DEFINES/mobs.dm index b08a22f9ba5..5ed89d3490d 100644 --- a/code/__DEFINES/mobs.dm +++ b/code/__DEFINES/mobs.dm @@ -356,11 +356,18 @@ #define ENVIRONMENT_SMASH_WALLS 2 //walls #define ENVIRONMENT_SMASH_RWALLS 3 //rwalls +// Slip flags, also known as lube flags +/// The mob will not slip if they're walking intent #define NO_SLIP_WHEN_WALKING (1<<0) +/// Slipping on this will send them sliding a few tiles down #define SLIDE (1<<1) -#define GALOSHES_DONT_HELP (1<<2) -#define SLIDE_ICE (1<<3) -#define SLIP_WHEN_CRAWLING (1<<4) //clown planet ruin +/// Ice slides only go one tile and don't knock you over, they're intended to cause a "slip chain" +/// where you slip on ice until you reach a non-slippable tile (ice puzzles) +#define SLIDE_ICE (1<<2) +/// [TRAIT_NO_SLIP_WATER] does not work on this slip. ONLY [TRAIT_NO_SLIP_ALL] will +#define GALOSHES_DONT_HELP (1<<3) +/// Slip works even if you're already on the ground +#define SLIP_WHEN_CRAWLING (1<<4) #define MAX_CHICKENS 50 diff --git a/code/__DEFINES/obj_flags.dm b/code/__DEFINES/obj_flags.dm index 7215f5b00d8..78291bb0a28 100644 --- a/code/__DEFINES/obj_flags.dm +++ b/code/__DEFINES/obj_flags.dm @@ -38,37 +38,51 @@ #define IGNORE_DIGITIGRADE (1<<18) /// Has contextual screentips when HOVERING OVER OTHER objects #define ITEM_HAS_CONTEXTUAL_SCREENTIPS (1 << 19) -/// No blood overlay is allowed to appear on this item, and it cannot gain blood DNA forensics +/// No blood overlay is allowed to appear on this item, and it cannot gain blood DNA forensics #define NO_BLOOD_ON_ITEM (1 << 20) // Flags for the clothing_flags var on /obj/item/clothing +/// SUIT and HEAD items which stop lava from hurting the wearer #define LAVAPROTECT (1<<0) -#define STOPSPRESSUREDAMAGE (1<<1) //SUIT and HEAD items which stop pressure damage. To stop you taking all pressure damage you must have both a suit and head item with this flag. -#define BLOCK_GAS_SMOKE_EFFECT (1<<2) // blocks the effect that chemical clouds would have on a mob --glasses, mask and helmets ONLY! -#define MASKINTERNALS (1<<3) // mask allows internals -#define GAS_FILTERING (1<<4) //mask filters toxins and other harmful gases -#define NOSLIP (1<<5) //prevents from slipping on wet floors, in space etc -#define NOSLIP_ICE (1<<6) //prevents from slipping on frozen floors -#define THICKMATERIAL (1<<7) //prevents syringes, parapens and hypos if the external suit or helmet (if targeting head) has this flag. Example: space suits, biosuit, bombsuits, thick suits that cover your body. -#define VOICEBOX_TOGGLABLE (1<<8) // The voicebox in this clothing can be toggled. -#define VOICEBOX_DISABLED (1<<9) // The voicebox is currently turned off. -#define BLOCKS_SHOVE_KNOCKDOWN (1<<11) // Prevents shovies against a dense object from knocking the wearer down. -#define SNUG_FIT (1<<12) //Prevents knock-off from things like hat-throwing. -#define ANTI_TINFOIL_MANEUVER (1<<13) //Hats with negative effects when worn (i.e the tinfoil hat). -#define DANGEROUS_OBJECT (1<<14) //Clothes that cause a larger notification when placed on a person. -#define LARGE_WORN_ICON (1<<15) //Clothes that use large icons, for applying the proper overlays like blood +/// SUIT and HEAD items which stop pressure damage. +/// To stop you taking all pressure damage you must have both a suit and head item with this flag. +#define STOPSPRESSUREDAMAGE (1<<1) +/// blocks the effect that chemical clouds would have on a mob --glasses, mask and helmets ONLY! +#define BLOCK_GAS_SMOKE_EFFECT (1<<2) +/// mask allows internals +#define MASKINTERNALS (1<<3) +/// mask filters toxins and other harmful gases +#define GAS_FILTERING (1<<4) +/// prevents syringes, parapens and hypos if the external suit or helmet (if targeting head) has this flag. +/// Example: space suits, biosuit, bombsuits, thick suits that cover your body. +#define THICKMATERIAL (1<<5) +/// The voicebox in this clothing can be toggled. +#define VOICEBOX_TOGGLABLE (1<<6) +/// The voicebox is currently turned off. +#define VOICEBOX_DISABLED (1<<7) +/// Prevents shovies against a dense object from knocking the wearer down. +#define BLOCKS_SHOVE_KNOCKDOWN (1<<8) +/// Prevents knock-off from things like hat-throwing. +#define SNUG_FIT (1<<9) +/// Hats with negative effects when worn (i.e the tinfoil hat). +#define ANTI_TINFOIL_MANEUVER (1<<10) +/// Clothes that cause a larger notification when placed on a person. +#define DANGEROUS_OBJECT (1<<11) +/// Clothes that use large icons, for applying the proper overlays like blood +#define LARGE_WORN_ICON (1<<12) /// Clothes that block speech (i.e the muzzle). Can be applied to any clothing piece. -#define BLOCKS_SPEECH (1<<16) -#define PLASMAMAN_HELMET_EXEMPT (1<<17) //prevents from placing on plasmaman helmet +#define BLOCKS_SPEECH (1<<13) +/// prevents from placing on plasmaman helmet +#define PLASMAMAN_HELMET_EXEMPT (1<<14) /// Prevents plasmamen from igniting when wearing this -#define PLASMAMAN_PREVENT_IGNITION (1<<18) +#define PLASMAMAN_PREVENT_IGNITION (1<<15) /// Usable as casting clothes by wizards (only matters for suits and headwear) -#define CASTING_CLOTHES (1<<19) +#define CASTING_CLOTHES (1<<16) ///Moths can't eat the clothing that has this flag. -#define INEDIBLE_CLOTHING (1<<20) +#define INEDIBLE_CLOTHING (1<<17) /// Headgear/helmet allows internals -#define HEADINTERNALS (1<<21) +#define HEADINTERNALS (1<<18) /// Integrity defines for clothing (not flags but close enough) #define CLOTHING_PRISTINE 0 // We have no damage on the clothing diff --git a/code/__DEFINES/traits.dm b/code/__DEFINES/traits.dm index 1c54682e5c8..d322c3e1ff5 100644 --- a/code/__DEFINES/traits.dm +++ b/code/__DEFINES/traits.dm @@ -244,8 +244,17 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai #define TRAIT_DEPRESSION "depression" #define TRAIT_JOLLY "jolly" #define TRAIT_NOCRITDAMAGE "no_crit" -#define TRAIT_NOSLIPWATER "noslip_water" -#define TRAIT_NOSLIPALL "noslip_all" + +/// Stops the mob from slipping on water, or banana peels, or pretty much anything that doesn't have [GALOSHES_DONT_HELP] set +#define TRAIT_NO_SLIP_WATER "noslip_water" +/// Stops the mob from slipping on permafrost ice (not any other ice) (but anything with [SLIDE_ICE] set) +#define TRAIT_NO_SLIP_ICE "noslip_ice" +/// Stop the mob from sliding around from being slipped, but not the slip part. +/// DOES NOT include ice slips. +#define TRAIT_NO_SLIP_SLIDE "noslip_slide" +/// Stops all slipping and sliding from ocurring +#define TRAIT_NO_SLIP_ALL "noslip_all" + #define TRAIT_NODEATH "nodeath" #define TRAIT_NOHARDCRIT "nohardcrit" #define TRAIT_NOSOFTCRIT "nosoftcrit" diff --git a/code/_globalvars/bitfields.dm b/code/_globalvars/bitfields.dm index 803615b8204..0887e213aba 100644 --- a/code/_globalvars/bitfields.dm +++ b/code/_globalvars/bitfields.dm @@ -94,7 +94,6 @@ DEFINE_BITFIELD(clothing_flags, list( "LARGE_WORN_ICON" = LARGE_WORN_ICON, "LAVAPROTECT" = LAVAPROTECT, "MASKINTERNALS" = MASKINTERNALS, - "NOSLIP" = NOSLIP, "PLASMAMAN_HELMET_EXEMPT" = PLASMAMAN_HELMET_EXEMPT, "PLASMAMAN_PREVENT_IGNITION" = PLASMAMAN_PREVENT_IGNITION, "SNUG_FIT" = SNUG_FIT, diff --git a/code/_globalvars/traits.dm b/code/_globalvars/traits.dm index a693dfa1167..cf771cb1da2 100644 --- a/code/_globalvars/traits.dm +++ b/code/_globalvars/traits.dm @@ -79,8 +79,10 @@ GLOBAL_LIST_INIT(traits_by_type, list( "TRAIT_DEPRESSION" = TRAIT_DEPRESSION, "TRAIT_JOLLY" = TRAIT_JOLLY, "TRAIT_NOCRITDAMAGE" = TRAIT_NOCRITDAMAGE, - "TRAIT_NOSLIPWATER" = TRAIT_NOSLIPWATER, - "TRAIT_NOSLIPALL" = TRAIT_NOSLIPALL, + "TRAIT_NO_SLIP_WATER" = TRAIT_NO_SLIP_WATER, + "TRAIT_NO_SLIP_ICE" = TRAIT_NO_SLIP_ICE, + "TRAIT_NO_SLIP_SLIDE" = TRAIT_NO_SLIP_SLIDE, + "TRAIT_NO_SLIP_ALL" = TRAIT_NO_SLIP_ALL, "TRAIT_NODEATH" = TRAIT_NODEATH, "TRAIT_NOHARDCRIT" = TRAIT_NOHARDCRIT, "TRAIT_NOSOFTCRIT" = TRAIT_NOSOFTCRIT, diff --git a/code/game/objects/items/religion.dm b/code/game/objects/items/religion.dm index 70c8264f778..49fc381b4ad 100644 --- a/code/game/objects/items/religion.dm +++ b/code/game/objects/items/religion.dm @@ -377,7 +377,7 @@ icon_state = "crusader" w_class = WEIGHT_CLASS_NORMAL armor_type = /datum/armor/shoes_plate - clothing_flags = NOSLIP + clothing_traits = list(TRAIT_NO_SLIP_WATER) cold_protection = FEET min_cold_protection_temperature = SHOES_MIN_TEMP_PROTECT heat_protection = FEET diff --git a/code/game/turfs/open/_open.dm b/code/game/turfs/open/_open.dm index 7bd53da6d1f..8afb3c5ee8d 100644 --- a/code/game/turfs/open/_open.dm +++ b/code/game/turfs/open/_open.dm @@ -225,16 +225,22 @@ return FALSE var/slide_distance = 4 - if(HAS_TRAIT(slipper, TRAIT_CURSED)) - if(!(lube & SLIDE_ICE)) // Ensures we are at least sliding - lube |= SLIDE + if(lube & SLIDE_ICE) + // Ice slides only go 1 tile, this is so you will slip across ice until you reach a non-slip tile + slide_distance = 1 + else if(HAS_TRAIT(slipper, TRAIT_CURSED)) + // When cursed, all slips send you flying + lube |= SLIDE slide_distance = rand(5, 9) + else if(HAS_TRAIT(slipper, TRAIT_NO_SLIP_SLIDE)) + // Stops sliding + slide_distance = 0 var/obj/buckled_obj if(slipper.buckled) - buckled_obj = slipper.buckled if(!(lube & GALOSHES_DONT_HELP)) //can't slip while buckled unless it's lube. return FALSE + buckled_obj = slipper.buckled else if(!(lube & SLIP_WHEN_CRAWLING) && (slipper.body_position == LYING_DOWN || !(slipper.status_flags & CANKNOCKDOWN))) // can't slip unbuckled mob if they're lying or can't fall. return FALSE @@ -242,6 +248,7 @@ return FALSE if(!(lube & SLIDE_ICE)) + // Ice slides are intended to be combo'd so don't give the feedback to_chat(slipper, span_notice("You slipped[ slippable ? " on the [slippable.name]" : ""]!")) playsound(slipper.loc, 'sound/misc/slip.ogg', 50, TRUE, -3) @@ -253,22 +260,27 @@ var/olddir = slipper.dir slipper.moving_diagonally = 0 //If this was part of diagonal move slipping will stop it. - if(!(lube & SLIDE_ICE)) + if(lube & SLIDE_ICE) + // They need to be kept upright to maintain the combo effect (So don't knockdown) + slipper.Immobilize(1 SECONDS) + slipper.incapacitate(1 SECONDS) + else slipper.Knockdown(knockdown_amount) slipper.Paralyze(paralyze_amount) slipper.stop_pulling() - else - slipper.Knockdown(20) if(buckled_obj) buckled_obj.unbuckle_mob(slipper) + // This is added onto the end so they slip "out of their chair" (one tile) lube |= SLIDE_ICE + slide_distance = 1 - var/turf/target = get_ranged_target_turf(slipper, olddir, slide_distance) - if(lube & SLIDE) - slipper.AddComponent(/datum/component/force_move, target, TRUE) - else if(lube & SLIDE_ICE) - slipper.AddComponent(/datum/component/force_move, target, FALSE)//spinning would be bad for ice, fucks up the next dir + if(slide_distance) + var/turf/target = get_ranged_target_turf(slipper, olddir, slide_distance) + if(lube & SLIDE) + slipper.AddComponent(/datum/component/force_move, target, TRUE) + else if(lube & SLIDE_ICE) + slipper.AddComponent(/datum/component/force_move, target, FALSE)//spinning would be bad for ice, fucks up the next dir return TRUE /turf/open/proc/MakeSlippery(wet_setting = TURF_WET_WATER, min_wet_time = 0, wet_time_to_add = 0, max_wet_time = MAXIMUM_WET_TIME, permanent) diff --git a/code/modules/antagonists/clown_ops/clown_weapons.dm b/code/modules/antagonists/clown_ops/clown_weapons.dm index 2387c8a42b9..442fd4d7903 100644 --- a/code/modules/antagonists/clown_ops/clown_weapons.dm +++ b/code/modules/antagonists/clown_ops/clown_weapons.dm @@ -15,7 +15,7 @@ /obj/item/clothing/shoes/clown_shoes/combat name = "combat clown shoes" desc = "advanced clown shoes that protect the wearer and render them nearly immune to slipping on their own peels. They also squeak at 100% capacity." - clothing_flags = NOSLIP + clothing_traits = list(TRAIT_NO_SLIP_WATER) slowdown = SHOES_SLOWDOWN armor_type = /datum/armor/clown_shoes_combat strip_delay = 70 diff --git a/code/modules/antagonists/heretic/knowledge/rust_lore.dm b/code/modules/antagonists/heretic/knowledge/rust_lore.dm index 08bcd87b7cc..1adeefdea9e 100644 --- a/code/modules/antagonists/heretic/knowledge/rust_lore.dm +++ b/code/modules/antagonists/heretic/knowledge/rust_lore.dm @@ -217,7 +217,7 @@ TRAIT_SLEEPIMMUNE, TRAIT_PUSHIMMUNE, TRAIT_SHOCKIMMUNE, - TRAIT_NOSLIPALL, + TRAIT_NO_SLIP_ALL, TRAIT_RADIMMUNE, TRAIT_RESISTHIGHPRESSURE, TRAIT_RESISTLOWPRESSURE, diff --git a/code/modules/clothing/chameleon.dm b/code/modules/clothing/chameleon.dm index 10d83bf34ec..b8d441efcfa 100644 --- a/code/modules/clothing/chameleon.dm +++ b/code/modules/clothing/chameleon.dm @@ -710,7 +710,7 @@ chameleon_action.emp_randomise() /obj/item/clothing/shoes/chameleon/noslip - clothing_flags = NOSLIP + clothing_traits = list(TRAIT_NO_SLIP_WATER) can_be_bloody = FALSE /obj/item/clothing/shoes/chameleon/noslip/broken/Initialize(mapload) diff --git a/code/modules/clothing/clothing.dm b/code/modules/clothing/clothing.dm index f0d28427697..7dea58234ec 100644 --- a/code/modules/clothing/clothing.dm +++ b/code/modules/clothing/clothing.dm @@ -251,6 +251,40 @@ LAZYSET(user_vars_remembered, variable, user.vars[variable]) user.vv_edit_var(variable, user_vars_to_edit[variable]) +/** + * Inserts a trait (or multiple traits) into the clothing traits list + * + * If worn, then we will also give the wearer the trait as if equipped + * + * This is so you can add clothing traits without worrying about needing to equip or unequip them to gain effects + */ +/obj/item/clothing/proc/attach_clothing_traits(trait_or_traits) + if(!islist(trait_or_traits)) + trait_or_traits = list(trait_or_traits) + + LAZYOR(clothing_traits, trait_or_traits) + var/mob/wearer = loc + if(istype(wearer) && (wearer.get_slot_by_item(src) & slot_flags)) + for(var/new_trait in trait_or_traits) + ADD_CLOTHING_TRAIT(wearer, new_trait) + +/** + * Removes a trait (or multiple traits) from the clothing traits list + * + * If worn, then we will also remove the trait from the wearer as if unequipped + * + * This is so you can add clothing traits without worrying about needing to equip or unequip them to gain effects + */ +/obj/item/clothing/proc/detach_clothing_traits(trait_or_traits) + if(!islist(trait_or_traits)) + trait_or_traits = list(trait_or_traits) + + LAZYREMOVE(clothing_traits, trait_or_traits) + var/mob/wearer = loc + if(istype(wearer)) + for(var/new_trait in trait_or_traits) + REMOVE_CLOTHING_TRAIT(wearer, new_trait) + /obj/item/clothing/examine(mob/user) . = ..() if(damaged_clothes == CLOTHING_SHREDDED) diff --git a/code/modules/clothing/glasses/_glasses.dm b/code/modules/clothing/glasses/_glasses.dm index 83cd1f46718..a169aa15ab9 100644 --- a/code/modules/clothing/glasses/_glasses.dm +++ b/code/modules/clothing/glasses/_glasses.dm @@ -268,7 +268,7 @@ /obj/item/clothing/glasses/regular/atom_destruction(damage_flag) . = ..() - clothing_traits -= TRAIT_NEARSIGHTED_CORRECTED + detach_clothing_traits(TRAIT_NEARSIGHTED_CORRECTED) /obj/item/clothing/glasses/regular/welder_act(mob/living/user, obj/item/I) . = ..() @@ -284,7 +284,7 @@ /obj/item/clothing/glasses/regular/repair() . = ..() - clothing_traits |= TRAIT_NEARSIGHTED_CORRECTED + attach_clothing_traits(TRAIT_NEARSIGHTED_CORRECTED) /obj/item/clothing/glasses/regular/thin name = "thin prescription glasses" diff --git a/code/modules/clothing/shoes/bananashoes.dm b/code/modules/clothing/shoes/bananashoes.dm index d215cb42668..ed7f56e0fbe 100644 --- a/code/modules/clothing/shoes/bananashoes.dm +++ b/code/modules/clothing/shoes/bananashoes.dm @@ -5,8 +5,14 @@ desc = "Lost prototype of advanced clown tech. Powered by bananium, these shoes leave a trail of chaos in their wake." icon_state = "clown_prototype_off" actions_types = list(/datum/action/item_action/toggle) + /// Whether the clown shoes are active (spawning bananas) var/on = FALSE + /// If TRUE, we will always have the noslip trait no matter whether they're on or off var/always_noslip = FALSE + /// How many materials we consume per banana created + var/material_per_banana = 100 + /// Typepath of created banana + var/banana_type = /obj/item/grown/bananapeel/specialpeel /obj/item/clothing/shoes/clown_shoes/banana_shoes/Initialize(mapload) . = ..() @@ -15,23 +21,33 @@ AddComponent(/datum/component/squeak, list('sound/items/bikehorn.ogg'=1), 75, falloff_exponent = 20) RegisterSignal(src, COMSIG_SHOES_STEP_ACTION, PROC_REF(on_step)) if(always_noslip) - clothing_flags |= NOSLIP + LAZYOR(clothing_traits, TRAIT_NO_SLIP_WATER) + +/obj/item/clothing/shoes/clown_shoes/banana_shoes/proc/toggle_clowning_action() + on = !on + update_appearance() + if(always_noslip) + return + + if(on) + attach_clothing_traits(TRAIT_NO_SLIP_WATER) + else + detach_clothing_traits(TRAIT_NO_SLIP_WATER) /obj/item/clothing/shoes/clown_shoes/banana_shoes/proc/on_step() SIGNAL_HANDLER var/mob/wearer = loc var/datum/component/material_container/bananium = GetComponent(/datum/component/material_container) - if(on && istype(wearer)) - if(bananium.get_material_amount(/datum/material/bananium) < 100) - on = !on - if(!always_noslip) - clothing_flags &= ~NOSLIP - update_appearance() - to_chat(loc, span_warning("You ran out of bananium!")) - else - new /obj/item/grown/bananapeel/specialpeel(get_step(src,turn(wearer.dir, 180))) //honk - bananium.use_amount_mat(100, /datum/material/bananium) + if(!on || !istype(wearer)) + return + + if(bananium.use_amount_mat(material_per_banana, /datum/material/bananium)) + new banana_type(get_step(src, turn(wearer.dir, 180))) //honk + return + + toggle_clowning_action() + to_chat(wearer, span_warning("You ran out of bananium!")) /obj/item/clothing/shoes/clown_shoes/banana_shoes/attack_self(mob/user) var/datum/component/material_container/bananium = GetComponent(/datum/component/material_container) @@ -47,15 +63,9 @@ /obj/item/clothing/shoes/clown_shoes/banana_shoes/ui_action_click(mob/user) var/datum/component/material_container/bananium = GetComponent(/datum/component/material_container) - if(bananium.get_material_amount(/datum/material/bananium)) - on = !on - update_appearance() + if(bananium.get_material_amount(/datum/material/bananium) >= material_per_banana) + toggle_clowning_action() to_chat(user, span_notice("You [on ? "activate" : "deactivate"] the prototype shoes.")) - if(!always_noslip) - if(on) - clothing_flags |= NOSLIP - else - clothing_flags &= ~NOSLIP else to_chat(user, span_warning("You need bananium to turn the prototype shoes on!")) diff --git a/code/modules/clothing/shoes/boots.dm b/code/modules/clothing/shoes/boots.dm index 44425ff2d96..df7f6da84e4 100644 --- a/code/modules/clothing/shoes/boots.dm +++ b/code/modules/clothing/shoes/boots.dm @@ -26,7 +26,7 @@ /obj/item/clothing/shoes/combat/swat //overpowered boots for death squads name = "\improper SWAT boots" desc = "High speed, no drag combat boots." - clothing_flags = NOSLIP + clothing_traits = list(TRAIT_NO_SLIP_WATER) armor_type = /datum/armor/combat_swat /datum/armor/combat_swat @@ -89,7 +89,7 @@ desc = "A pair of winter boots with special grips on the bottom, designed to prevent slipping on frozen surfaces." icon_state = "iceboots" inhand_icon_state = null - clothing_flags = NOSLIP_ICE + clothing_traits = list(TRAIT_NO_SLIP_ICE, TRAIT_NO_SLIP_SLIDE) // A pair of ice boots intended for general crew EVA use - see EVA winter coat for comparison. /obj/item/clothing/shoes/winterboots/ice_boots/eva @@ -101,7 +101,7 @@ armor_type = /datum/armor/ice_boots_eva strip_delay = 4 SECONDS equip_delay_other = 4 SECONDS - clothing_flags = NOSLIP_ICE|THICKMATERIAL + clothing_flags = THICKMATERIAL resistance_flags = NONE /datum/armor/ice_boots_eva diff --git a/code/modules/clothing/shoes/galoshes.dm b/code/modules/clothing/shoes/galoshes.dm index 8a34c68c05d..e743db6b742 100644 --- a/code/modules/clothing/shoes/galoshes.dm +++ b/code/modules/clothing/shoes/galoshes.dm @@ -3,7 +3,7 @@ name = "galoshes" icon_state = "galoshes" inhand_icon_state = "galoshes" - clothing_flags = NOSLIP + clothing_traits = list(TRAIT_NO_SLIP_WATER) slowdown = SHOES_SLOWDOWN+1 strip_delay = 30 equip_delay_other = 50 diff --git a/code/modules/clothing/shoes/magboots.dm b/code/modules/clothing/shoes/magboots.dm index 10c4ab48c96..dace486c41a 100644 --- a/code/modules/clothing/shoes/magboots.dm +++ b/code/modules/clothing/shoes/magboots.dm @@ -1,76 +1,79 @@ +/datum/armor/shoes_magboots + bio = 90 + /obj/item/clothing/shoes/magboots - desc = "Magnetic boots, often used during extravehicular activity to ensure the user remains safely attached to the vehicle." name = "magboots" + desc = "Magnetic boots, often used during extravehicular activity to ensure the user remains safely attached to the vehicle." icon_state = "magboots0" + base_icon_state = "magboots" inhand_icon_state = "magboots" - var/magboot_state = "magboots" - var/magpulse = FALSE - var/slowdown_active = 2 armor_type = /datum/armor/shoes_magboots actions_types = list(/datum/action/item_action/toggle) strip_delay = 70 equip_delay_other = 70 resistance_flags = FIRE_PROOF -/datum/armor/shoes_magboots - bio = 90 + slowdown = SHOES_SLOWDOWN + /// Whether the magpulse system is active + var/magpulse = FALSE + /// Slowdown applied wwhen magpulse is active. This is added onto existing slowdown + var/slowdown_active = 2 + /// A list of traits we apply when we get activated + var/list/active_traits = list(TRAIT_NO_SLIP_WATER, TRAIT_NO_SLIP_ICE, TRAIT_NO_SLIP_SLIDE, TRAIT_NEGATES_GRAVITY) -/obj/item/clothing/shoes/magboots/equipped(mob/user, slot) +/obj/item/clothing/shoes/magboots/Initialize(mapload) . = ..() - if(slot & ITEM_SLOT_FEET) - update_gravity_trait(user) - else - REMOVE_TRAIT(user, TRAIT_NEGATES_GRAVITY, type) + AddElement(/datum/element/update_icon_updates_onmob, slot_flags) + RegisterSignal(src, COMSIG_SPEED_POTION_APPLIED, PROC_REF(on_speed_potioned)) -/obj/item/clothing/shoes/magboots/dropped(mob/user) - . = ..() - REMOVE_TRAIT(user, TRAIT_NEGATES_GRAVITY, type) +/// Signal handler for [COMSIG_SPEED_POTION_APPLIED]. Speed potion removes the active slowdown +/obj/item/clothing/shoes/magboots/proc/on_speed_potioned(datum/source) + SIGNAL_HANDLER + + slowdown_active = 0 + // Don't need to touch the actual slowdown here, since the speed potion does it for us /obj/item/clothing/shoes/magboots/verb/toggle() set name = "Toggle Magboots" set category = "Object" set src in usr + if(!can_use(usr)) return attack_self(usr) /obj/item/clothing/shoes/magboots/attack_self(mob/user) - if(magpulse) - clothing_flags &= ~NOSLIP - slowdown = SHOES_SLOWDOWN - else - clothing_flags |= NOSLIP - slowdown = slowdown_active magpulse = !magpulse - icon_state = "[magboot_state][magpulse]" - to_chat(user, span_notice("You [magpulse ? "enable" : "disable"] the mag-pulse traction system.")) - update_gravity_trait(user) - user.update_worn_shoes() //so our mob-overlays update - user.update_gravity(user.has_gravity()) - user.update_equipment_speed_mods() //we want to update our speed so we arent running at max speed in regular magboots - update_item_action_buttons() + if(magpulse) + attach_clothing_traits(active_traits) + slowdown += slowdown_active + else + detach_clothing_traits(active_traits) + slowdown = max(initial(slowdown), slowdown - slowdown_active) // Just in case, for speed pot shenanigans + + update_appearance() + balloon_alert(user, "mag-pulse [magpulse ? "enabled" : "disabled"]") + //we want to update our speed so we arent running at max speed in regular magboots + user.update_equipment_speed_mods() /obj/item/clothing/shoes/magboots/examine(mob/user) . = ..() . += "Its mag-pulse traction system appears to be [magpulse ? "enabled" : "disabled"]." -///Adds/removes the gravity negation trait from the wearer depending on if the magpulse system is turned on. -/obj/item/clothing/shoes/magboots/proc/update_gravity_trait(mob/user) - if(magpulse) - ADD_TRAIT(user, TRAIT_NEGATES_GRAVITY, type) - else - REMOVE_TRAIT(user, TRAIT_NEGATES_GRAVITY, type) +/obj/item/clothing/shoes/magboots/update_icon_state() + . = ..() + icon_state = "[base_icon_state][magpulse]" /obj/item/clothing/shoes/magboots/advance - desc = "Advanced magnetic boots that have a lighter magnetic pull, placing less burden on the wearer." name = "advanced magboots" + desc = "Advanced magnetic boots that have a lighter magnetic pull, placing less burden on the wearer." icon_state = "advmag0" - magboot_state = "advmag" - slowdown_active = SHOES_SLOWDOWN + base_icon_state = "advmag" + slowdown_active = SHOES_SLOWDOWN // ZERO active slowdown resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF /obj/item/clothing/shoes/magboots/syndie - desc = "Reverse-engineered magnetic boots that have a heavy magnetic pull. Property of Gorlex Marauders." name = "blood-red magboots" + desc = "Reverse-engineered magnetic boots that have a heavy magnetic pull. Property of Gorlex Marauders." icon_state = "syndiemag0" - magboot_state = "syndiemag" + base_icon_state = "syndiemag" diff --git a/code/modules/mob/living/carbon/carbon_movement.dm b/code/modules/mob/living/carbon/carbon_movement.dm index dde0e0afe34..e71d6a98e37 100644 --- a/code/modules/mob/living/carbon/carbon_movement.dm +++ b/code/modules/mob/living/carbon/carbon_movement.dm @@ -1,10 +1,10 @@ -/mob/living/carbon/slip(knockdown_amount, obj/O, lube, paralyze, force_drop) +/mob/living/carbon/slip(knockdown_amount, obj/slipped_on, lube_flags, paralyze, force_drop = FALSE) if(movement_type & (FLYING | FLOATING)) return FALSE - if(!(lube&SLIDE_ICE)) - log_combat(src, (O ? O : get_turf(src)), "slipped on the", null, ((lube & SLIDE) ? "(LUBE)" : null)) + if(!(lube_flags & SLIDE_ICE)) + log_combat(src, (slipped_on || get_turf(src)), "slipped on the", null, ((lube_flags & SLIDE) ? "(SLIDING)" : null)) ..() - return loc.handle_slip(src, knockdown_amount, O, lube, paralyze, force_drop) + return loc.handle_slip(src, knockdown_amount, slipped_on, lube_flags, paralyze, force_drop) /mob/living/carbon/Move(NewLoc, direct) . = ..() diff --git a/code/modules/mob/living/carbon/human/human_movement.dm b/code/modules/mob/living/carbon/human/human_movement.dm index 3b8c1cd1e02..14003b86da4 100644 --- a/code/modules/mob/living/carbon/human/human_movement.dm +++ b/code/modules/mob/living/carbon/human/human_movement.dm @@ -9,21 +9,16 @@ return return considering -/mob/living/carbon/human/slip(knockdown_amount, obj/O, lube, paralyze, forcedrop) - if(HAS_TRAIT(src, TRAIT_NOSLIPALL)) +/mob/living/carbon/human/slip(knockdown_amount, obj/slipped_on, lube_flags, paralyze, force_drop = FALSE) + if(HAS_TRAIT(src, TRAIT_NO_SLIP_ALL)) return FALSE - if (!(lube & GALOSHES_DONT_HELP)) - if(HAS_TRAIT(src, TRAIT_NOSLIPWATER)) - return FALSE - if(shoes && isclothing(shoes)) - var/obj/item/clothing/CS = shoes - if (CS.clothing_flags & NOSLIP) - return FALSE - if (lube & SLIDE_ICE) - if(shoes && isclothing(shoes)) - var/obj/item/clothing/CS = shoes - if (CS.clothing_flags & NOSLIP_ICE) - return FALSE + + if(HAS_TRAIT(src, TRAIT_NO_SLIP_WATER) && !(lube_flags & GALOSHES_DONT_HELP)) + return FALSE + + if(HAS_TRAIT(src, TRAIT_NO_SLIP_ICE) && (lube_flags & SLIDE_ICE)) + return FALSE + return ..() /mob/living/carbon/human/mob_negates_gravity() diff --git a/code/modules/mob/living/carbon/human/species_types/snail.dm b/code/modules/mob/living/carbon/human/species_types/snail.dm index 5e91d37a0be..5de220832e3 100644 --- a/code/modules/mob/living/carbon/human/species_types/snail.dm +++ b/code/modules/mob/living/carbon/human/species_types/snail.dm @@ -6,7 +6,7 @@ NO_UNDERWEAR, ) inherent_traits = list( - TRAIT_NOSLIPALL, + TRAIT_NO_SLIP_ALL, ) coldmod = 0.5 //snails only come out when its cold and wet diff --git a/code/modules/mob/living/init_signals.dm b/code/modules/mob/living/init_signals.dm index 50fd7b890cd..3fdd1a2059c 100644 --- a/code/modules/mob/living/init_signals.dm +++ b/code/modules/mob/living/init_signals.dm @@ -44,6 +44,8 @@ RegisterSignal(src, SIGNAL_ADDTRAIT(TRAIT_SKITTISH), PROC_REF(on_skittish_trait_gain)) RegisterSignal(src, SIGNAL_REMOVETRAIT(TRAIT_SKITTISH), PROC_REF(on_skittish_trait_loss)) + RegisterSignals(src, list(SIGNAL_ADDTRAIT(TRAIT_NEGATES_GRAVITY), SIGNAL_REMOVETRAIT(TRAIT_NEGATES_GRAVITY)), PROC_REF(on_negate_gravity)) + /// Called when [TRAIT_KNOCKEDOUT] is added to the mob. /mob/living/proc/on_knockedout_trait_gain(datum/source) SIGNAL_HANDLER @@ -213,3 +215,8 @@ /mob/living/proc/on_skittish_trait_loss(datum/source) SIGNAL_HANDLER RemoveElement(/datum/element/skittish) + +/// Called with [TRAIT_NEGATES_GRAVITY] is gained or lost +/mob/living/proc/on_negate_gravity(datum/source) + SIGNAL_HANDLER + update_gravity(has_gravity()) diff --git a/code/modules/mob/mob_movement.dm b/code/modules/mob/mob_movement.dm index 2c0c06e1ca5..d315fc1e154 100644 --- a/code/modules/mob/mob_movement.dm +++ b/code/modules/mob/mob_movement.dm @@ -355,9 +355,17 @@ var/turf/turf = get_turf(src) return !isgroundlessturf(turf) && HAS_TRAIT(src, TRAIT_NEGATES_GRAVITY) -/// Called when this mob slips over, override as needed -/mob/proc/slip(knockdown_amount, obj/O, lube, paralyze, force_drop) - add_mob_memory(/datum/memory/was_slipped, antagonist = O) +/** + * Called when this mob slips over, override as needed + * + * knockdown_amount - time (in deciseconds) the slip leaves them on the ground + * slipped_on - optional, what'd we slip on? if not set, we assume they just fell over + * lube - bitflag of "lube flags", see [mobs.dm] for more information + * paralyze - time (in deciseconds) the slip leaves them paralyzed / unable to move + * force_drop = the slip forces them to drop held items + */ +/mob/proc/slip(knockdown_amount, obj/slipped_on, lube_flags, paralyze, force_drop = FALSE) + add_mob_memory(/datum/memory/was_slipped, antagonist = slipped_on) /// Update the gravity status of this mob /mob/proc/update_gravity(has_gravity, override=FALSE) diff --git a/code/modules/mod/modules/modules_antag.dm b/code/modules/mod/modules/modules_antag.dm index 20e598d220d..a1c6b39cac7 100644 --- a/code/modules/mod/modules/modules_antag.dm +++ b/code/modules/mod/modules/modules_antag.dm @@ -239,10 +239,10 @@ incompatible_modules = list(/obj/item/mod/module/noslip) /obj/item/mod/module/noslip/on_suit_activation() - ADD_TRAIT(mod.wearer, TRAIT_NOSLIPWATER, MOD_TRAIT) + ADD_TRAIT(mod.wearer, TRAIT_NO_SLIP_WATER, MOD_TRAIT) /obj/item/mod/module/noslip/on_suit_deactivation(deleting = FALSE) - REMOVE_TRAIT(mod.wearer, TRAIT_NOSLIPWATER, MOD_TRAIT) + REMOVE_TRAIT(mod.wearer, TRAIT_NO_SLIP_WATER, MOD_TRAIT) //Bite of 87 Springlock - Equips faster, disguised as DNA lock. /obj/item/mod/module/springlock/bite_of_87 diff --git a/code/modules/mod/modules/modules_engineering.dm b/code/modules/mod/modules/modules_engineering.dm index f818b08968c..5fbf6747581 100644 --- a/code/modules/mod/modules/modules_engineering.dm +++ b/code/modules/mod/modules/modules_engineering.dm @@ -52,25 +52,25 @@ cooldown_time = 0.5 SECONDS /// Slowdown added onto the suit. var/slowdown_active = 0.5 + /// A list of traits to add to the wearer when we're active (see: Magboots) + var/list/active_traits = list(TRAIT_NO_SLIP_WATER, TRAIT_NO_SLIP_ICE, TRAIT_NO_SLIP_SLIDE, TRAIT_NEGATES_GRAVITY) /obj/item/mod/module/magboot/on_activation() . = ..() if(!.) return - ADD_TRAIT(mod.wearer, TRAIT_NEGATES_GRAVITY, MOD_TRAIT) - ADD_TRAIT(mod.wearer, TRAIT_NOSLIPWATER, MOD_TRAIT) + for(var/new_trait in active_traits) + ADD_TRAIT(mod.wearer, new_trait, MOD_TRAIT) mod.slowdown += slowdown_active - mod.wearer.update_gravity(mod.wearer.has_gravity()) mod.wearer.update_equipment_speed_mods() /obj/item/mod/module/magboot/on_deactivation(display_message = TRUE, deleting = FALSE) . = ..() if(!.) return - REMOVE_TRAIT(mod.wearer, TRAIT_NEGATES_GRAVITY, MOD_TRAIT) - REMOVE_TRAIT(mod.wearer, TRAIT_NOSLIPWATER, MOD_TRAIT) + for(var/old_trait in active_traits) + REMOVE_TRAIT(mod.wearer, old_trait, MOD_TRAIT) mod.slowdown -= slowdown_active - mod.wearer.update_gravity(mod.wearer.has_gravity()) mod.wearer.update_equipment_speed_mods() /obj/item/mod/module/magboot/advanced diff --git a/code/modules/mod/modules/modules_supply.dm b/code/modules/mod/modules/modules_supply.dm index 49ebc5cd625..21c232b08de 100644 --- a/code/modules/mod/modules/modules_supply.dm +++ b/code/modules/mod/modules/modules_supply.dm @@ -498,7 +498,7 @@ ADD_TRAIT(mod.wearer, TRAIT_LAVA_IMMUNE, MOD_TRAIT) ADD_TRAIT(mod.wearer, TRAIT_HANDS_BLOCKED, MOD_TRAIT) ADD_TRAIT(mod.wearer, TRAIT_FORCED_STANDING, MOD_TRAIT) - ADD_TRAIT(mod.wearer, TRAIT_NOSLIPALL, MOD_TRAIT) + ADD_TRAIT(mod.wearer, TRAIT_NO_SLIP_ALL, MOD_TRAIT) mod.wearer.RemoveElement(/datum/element/footstep, FOOTSTEP_MOB_HUMAN, 1, -6) mod.wearer.AddElement(/datum/element/footstep, FOOTSTEP_OBJ_ROBOT, 1, -6, sound_vary = TRUE) mod.wearer.add_movespeed_modifier(/datum/movespeed_modifier/sphere) @@ -516,7 +516,7 @@ REMOVE_TRAIT(mod.wearer, TRAIT_LAVA_IMMUNE, MOD_TRAIT) REMOVE_TRAIT(mod.wearer, TRAIT_HANDS_BLOCKED, MOD_TRAIT) REMOVE_TRAIT(mod.wearer, TRAIT_FORCED_STANDING, MOD_TRAIT) - REMOVE_TRAIT(mod.wearer, TRAIT_NOSLIPALL, MOD_TRAIT) + REMOVE_TRAIT(mod.wearer, TRAIT_NO_SLIP_ALL, MOD_TRAIT) mod.wearer.remove_movespeed_mod_immunities(MOD_TRAIT, /datum/movespeed_modifier/damage_slowdown) mod.wearer.RemoveElement(/datum/element/footstep, FOOTSTEP_OBJ_ROBOT, 1, -6, sound_vary = TRUE) mod.wearer.AddElement(/datum/element/footstep, FOOTSTEP_MOB_HUMAN, 1, -6) diff --git a/code/modules/research/xenobiology/crossbreeding/_status_effects.dm b/code/modules/research/xenobiology/crossbreeding/_status_effects.dm index dccf1761b13..b0b5cc6ca44 100644 --- a/code/modules/research/xenobiology/crossbreeding/_status_effects.dm +++ b/code/modules/research/xenobiology/crossbreeding/_status_effects.dm @@ -258,7 +258,7 @@ duration = 100 /datum/status_effect/watercookie/on_apply() - ADD_TRAIT(owner, TRAIT_NOSLIPWATER,"watercookie") + ADD_TRAIT(owner, TRAIT_NO_SLIP_WATER,"watercookie") return ..() /datum/status_effect/watercookie/tick() @@ -266,7 +266,7 @@ T.MakeSlippery(TURF_WET_WATER, min_wet_time = 10, wet_time_to_add = 5) /datum/status_effect/watercookie/on_remove() - REMOVE_TRAIT(owner, TRAIT_NOSLIPWATER,"watercookie") + REMOVE_TRAIT(owner, TRAIT_NO_SLIP_WATER,"watercookie") /datum/status_effect/metalcookie id = "metalcookie" @@ -527,11 +527,11 @@ colour = "blue" /datum/status_effect/stabilized/blue/on_apply() - ADD_TRAIT(owner, TRAIT_NOSLIPWATER, "slimestatus") + ADD_TRAIT(owner, TRAIT_NO_SLIP_WATER, "slimestatus") return ..() /datum/status_effect/stabilized/blue/on_remove() - REMOVE_TRAIT(owner, TRAIT_NOSLIPWATER, "slimestatus") + REMOVE_TRAIT(owner, TRAIT_NO_SLIP_WATER, "slimestatus") /datum/status_effect/stabilized/metal id = "stabilizedmetal"