diff --git a/aurorastation.dme b/aurorastation.dme index 4c137412778..5c863f7a43a 100644 --- a/aurorastation.dme +++ b/aurorastation.dme @@ -97,8 +97,10 @@ #include "code\__DEFINES\modular_guns.dm" #include "code\__DEFINES\move_force.dm" #include "code\__DEFINES\movement.dm" +#include "code\__DEFINES\movespeed_modification.dm" #include "code\__DEFINES\multiz.dm" #include "code\__DEFINES\obj.dm" +#include "code\__DEFINES\obj_flags.dm" #include "code\__DEFINES\organs.dm" #include "code\__DEFINES\origin_traits.dm" #include "code\__DEFINES\outfit.dm" @@ -258,6 +260,7 @@ #include "code\_globalvars\edible.dm" #include "code\_globalvars\logging.dm" #include "code\_globalvars\tgui.dm" +#include "code\_globalvars\lists\mobs.dm" #include "code\_onclick\adjacent.dm" #include "code\_onclick\ai.dm" #include "code\_onclick\click.dm" @@ -2919,6 +2922,10 @@ #include "code\modules\modular_computers\NTNet\NTNRC\message.dm" #include "code\modules\modular_computers\NTNet\NTNRC\ntnrc.dm" #include "code\modules\modular_computers\NTNet\NTNRC\user.dm" +#include "code\modules\movespeed\_movespeed_modifier.dm" +#include "code\modules\movespeed\modifiers\mobs.dm" +#include "code\modules\movespeed\modifiers\reagents.dm" +#include "code\modules\movespeed\modifiers\spells.dm" #include "code\modules\multiz\_stubs.dm" #include "code\modules\multiz\basic.dm" #include "code\modules\multiz\hoist.dm" diff --git a/code/__DEFINES/_flags.dm b/code/__DEFINES/_flags.dm index e577d92a625..c9e1c03fd85 100644 --- a/code/__DEFINES/_flags.dm +++ b/code/__DEFINES/_flags.dm @@ -51,6 +51,16 @@ GLOBAL_LIST_INIT(bitflags, list(1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 204 #define PASSTRACE (1<<16) //Used by turrets in the check_trajectory proc to target mobs hiding behind certain things (such as closets) #define PASSRAILING (1<<17) +//Movement Types +#define GROUND (1<<0) +#define FLYING (1<<1) +#define VENTCRAWLING (1<<2) +#define FLOATING (1<<3) +/// When moving, will Cross() everything, but won't stop or Bump() anything. +#define PHASING (1<<4) +/// The mob is walking on the ceiling. Or is generally just, upside down. +#define UPSIDE_DOWN (1<<5) + //TURF FLAGS /// If a turf is an usused reservation turf awaiting assignment #define UNUSED_RESERVATION_TURF BITFLAG(1) diff --git a/code/__DEFINES/chemistry.dm b/code/__DEFINES/chemistry.dm index c7412b08a98..b2e5613cd79 100644 --- a/code/__DEFINES/chemistry.dm +++ b/code/__DEFINES/chemistry.dm @@ -59,7 +59,6 @@ #define CE_NOPULSE "heartstop" // Stops heartbeat #define CE_SEDATE "sedation" #define CE_SLOWDOWN "goslow" -#define CE_SPEEDBOOST "gofast" // Hyperzine #define CE_STABLE "stable" // Epinephrine #define CE_PACIFIED "pacified" #define CE_PAINKILLER "painkiller" diff --git a/code/__DEFINES/dcs/signals/signals_mob/signals_mob_main.dm b/code/__DEFINES/dcs/signals/signals_mob/signals_mob_main.dm index 055e35bb49a..390b3d0c4de 100644 --- a/code/__DEFINES/dcs/signals/signals_mob/signals_mob_main.dm +++ b/code/__DEFINES/dcs/signals/signals_mob/signals_mob_main.dm @@ -11,3 +11,6 @@ #define MOVE_ARG_NEW_LOC 1 /// The arugment of move_args which dictates our movement direction #define MOVE_ARG_DIRECTION 2 + +///From base of mob/update_movespeed():area +#define COMSIG_MOB_MOVESPEED_UPDATED "mob_update_movespeed" diff --git a/code/__DEFINES/movespeed_modification.dm b/code/__DEFINES/movespeed_modification.dm new file mode 100644 index 00000000000..23c600aae70 --- /dev/null +++ b/code/__DEFINES/movespeed_modification.dm @@ -0,0 +1,15 @@ +//flags +#define IGNORE_NOSLOW (1 << 0) + +//conflict types + +#define MOVE_CONFLICT_JETPACK "JETPACK" + +//ids +#define MOVESPEED_ID_SANITY "sanity_component" +#define MOVESPEED_ID_STIMULANTS "movespeed_stimulants" + +#define MOVESPEED_ID_MOB_GRAB_STATE "mob_grab_state" +#define MOVESPEED_ID_MOB_WALK_RUN "mob_walk_run" + +#define MOVESPEED_ID_MIDAS_BLIGHT "midas_blight_debuff" diff --git a/code/__DEFINES/obj_flags.dm b/code/__DEFINES/obj_flags.dm new file mode 100644 index 00000000000..1aad638293e --- /dev/null +++ b/code/__DEFINES/obj_flags.dm @@ -0,0 +1,4 @@ +/// Flags for specifically what kind of items to get in get_equipped_items +#define INCLUDE_POCKETS (1<<0) +// #define INCLUDE_ACCESSORIES (1<<1) //We use a different system for this +#define INCLUDE_HELD (1<<2) diff --git a/code/_globalvars/lists/mobs.dm b/code/_globalvars/lists/mobs.dm new file mode 100644 index 00000000000..f38fd88dee8 --- /dev/null +++ b/code/_globalvars/lists/mobs.dm @@ -0,0 +1 @@ +GLOBAL_LIST_EMPTY(mob_config_movespeed_type_lookup) diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index 28f1117d8cf..0859d7442d3 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -57,6 +57,13 @@ /// We do it like this to prevent people trying to mutate them and to save memory on holding the lists ourselves var/spatial_grid_key + /** + * In case you have multiple types, you automatically use the most useful one. + * IE: Skating on ice, flippers on water, flying over chasm/space, etc. + * I recommend you use the movetype_handler system and not modify this directly, especially for living mobs. -- this isn't in our codebase yet, however + */ + var/movement_type = GROUND + /// Either [EMISSIVE_BLOCK_NONE], [EMISSIVE_BLOCK_GENERIC], or [EMISSIVE_BLOCK_UNIQUE] var/blocks_emissive = EMISSIVE_BLOCK_NONE ///Internal holder for emissive blocker object, DO NOT USE DIRECTLY. Use blocks_emissive @@ -274,7 +281,7 @@ //They are moving! Wouldn't it be cool if we calculated their momentum and added it to the throw? if (thrower && thrower.last_move && thrower.client && thrower.client.move_delay >= world.time + world.tick_lag*2) - var/user_momentum = world.tick_lag //Used to be thrower.cached_multiplicative_slowdown but we don't have this + var/user_momentum = thrower.cached_multiplicative_slowdown if (!user_momentum) //no movement_delay, this means they move once per byond tick, lets calculate from that instead. user_momentum = world.tick_lag diff --git a/code/game/gamemodes/endgame/bluespace_jump/bluespace_jump.dm b/code/game/gamemodes/endgame/bluespace_jump/bluespace_jump.dm index c59e252526a..3eab559f814 100644 --- a/code/game/gamemodes/endgame/bluespace_jump/bluespace_jump.dm +++ b/code/game/gamemodes/endgame/bluespace_jump/bluespace_jump.dm @@ -114,7 +114,7 @@ H.dna = daddy.dna.Clone() H.sync_organ_dna() H.UpdateAppearance() - for(var/obj/item/entry in daddy.get_equipped_items(TRUE)) + for(var/obj/item/entry in daddy.get_equipped_items(INCLUDE_POCKETS|INCLUDE_HELD)) daddy.remove_from_mob(entry) //steals instead of copies so we don't end up with duplicates H.equip_to_appropriate_slot(entry) else diff --git a/code/game/gamemodes/technomancer/spells/modifier/haste.dm b/code/game/gamemodes/technomancer/spells/modifier/haste.dm index e422e7ed262..f8c1d7b3ee3 100644 --- a/code/game/gamemodes/technomancer/spells/modifier/haste.dm +++ b/code/game/gamemodes/technomancer/spells/modifier/haste.dm @@ -25,13 +25,12 @@ . = ..() if(ishuman(target)) var/mob/living/carbon/human/H = target - H.move_delay_mod += -0.8 + H.add_movespeed_modifier(/datum/movespeed_modifier/spell/technomancer/haste) H.sprint_cost_factor += -0.2 /datum/modifier/technomancer/haste/deactivate() . = ..() if(ishuman(target)) var/mob/living/carbon/human/H = target - H.move_delay_mod += 0.8 + H.remove_movespeed_modifier(/datum/movespeed_modifier/spell/technomancer/haste) H.sprint_cost_factor += 0.2 - diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index 6f1a12a2325..553d2c029f8 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -488,7 +488,7 @@ * This is called after the _new_ location (`loc`) is set on the object, so if it's eg. put in a container, * the loc inside here would point to the container, not the mob that had it in hand * - * * user - The `/mob` that dropped the object + * * user - The `/mob` that dropped the object (was removed from, not necessarily who clicked the button) */ /obj/item/proc/dropped(mob/user) SHOULD_CALL_PARENT(TRUE) @@ -508,6 +508,8 @@ if(user && (z_flags & ZMM_MANGLE_PLANES)) addtimer(CALLBACK(user, /mob/proc/check_emissive_equipment), 0, TIMER_UNIQUE) + user?.update_equipment_speed_mods() + /obj/item/proc/remove_item_verbs(mob/user) if(ismech(user)) //very snowflake, but necessary due to how mechs work return @@ -616,6 +618,8 @@ if(user && (z_flags & ZMM_MANGLE_PLANES)) addtimer(CALLBACK(user, /mob/proc/check_emissive_equipment), 0, TIMER_UNIQUE) + user.update_equipment_speed_mods() + /obj/item/proc/check_equipped(var/mob/user, var/slot, var/assisted_equip = FALSE) return TRUE diff --git a/code/modules/admin/callproc/callproc.dm b/code/modules/admin/callproc/callproc.dm index 790065f4b35..517d41abf12 100644 --- a/code/modules/admin/callproc/callproc.dm +++ b/code/modules/admin/callproc/callproc.dm @@ -92,22 +92,24 @@ if(!object) return - var/list/types = typesof(/atom) + var/list/types = typesof(/datum) var/list/matches = new() for(var/path in types) if(findtext("[path]", object)) matches += path - if(matches.len==0) + if(!length(matches)) + tgui_alert("No matches found for typepath [object].") return if(matches.len==1) current = matches[1] else - current = input("Select an atom type", "Spawn Atom", matches[1]) as null|anything in matches + current = input("Select a typepath", "Typepath Selection", matches[1]) as null|anything in matches - if(isnull(current)) return + if(isnull(current)) + return if("obj reference") current = input("Select object for [arguments.len+1]\th argument") as null|obj in world diff --git a/code/modules/cargo/delivery/backpack.dm b/code/modules/cargo/delivery/backpack.dm index 4c54a8ac98c..0845615ebc8 100644 --- a/code/modules/cargo/delivery/backpack.dm +++ b/code/modules/cargo/delivery/backpack.dm @@ -47,12 +47,13 @@ return data -/obj/item/cargo_backpack/proc/update_state() +/obj/item/cargo_backpack/proc/update_state(mob/user) if(LAZYLEN(contained_packages)) slowdown = 1 else slowdown = 0 update_icon() + user.update_equipment_speed_mods() /obj/item/cargo_backpack/update_icon() if(LAZYLEN(contained_packages)) @@ -97,7 +98,7 @@ if(user.species.mob_size < 12) package.wield(user) LAZYREMOVE(contained_packages, package) - update_state() + update_state(user) /obj/item/cargo_backpack/attackby(obj/item/attacking_item, mob/user) if(!ishuman(user)) @@ -119,4 +120,4 @@ user.visible_message("[user] loads \the [attacking_item] onto \the [src]!", SPAN_NOTICE("You load \the [attacking_item] onto \the [src]!")) user.drop_from_inventory(attacking_item, src) LAZYADD(contained_packages, attacking_item) - update_state() + update_state(user) diff --git a/code/modules/cargo/delivery/package.dm b/code/modules/cargo/delivery/package.dm index de4394908fa..99cbd0bb2cc 100644 --- a/code/modules/cargo/delivery/package.dm +++ b/code/modules/cargo/delivery/package.dm @@ -83,6 +83,9 @@ slowdown = 2 else slowdown = 0 + + user.update_equipment_speed_mods() + return TRUE return FALSE diff --git a/code/modules/clothing/clothing.dm b/code/modules/clothing/clothing.dm index 5d97e9070af..3207a079826 100644 --- a/code/modules/clothing/clothing.dm +++ b/code/modules/clothing/clothing.dm @@ -380,6 +380,9 @@ if(!isnull(material.conductivity)) siemens_coefficient = between(0, material.conductivity / 10, 10) slowdown = between(0, round(material.weight / 10, 0.1), 6) + if(ismob(src.loc)) + var/mob/user = src.loc + user.update_equipment_speed_mods() /obj/item/clothing/proc/get_accessory(var/typepath) if(istype(src, typepath)) diff --git a/code/modules/clothing/clothing_accessories.dm b/code/modules/clothing/clothing_accessories.dm index 8b0b9649831..468ba9708be 100644 --- a/code/modules/clothing/clothing_accessories.dm +++ b/code/modules/clothing/clothing_accessories.dm @@ -103,17 +103,18 @@ for(var/obj/item/clothing/accessory/A in accessories) . += SPAN_NOTICE("\A [A] [A.gender == PLURAL ? "are" : "is"] attached to it.") -/obj/item/clothing/proc/update_accessory_slowdown() +/obj/item/clothing/proc/update_accessory_slowdown(mob/user) slowdown_accessory = 0 for(var/obj/item/clothing/accessory/bling in accessories) slowdown_accessory += bling.slowdown + user?.update_equipment_speed_mods() /obj/item/clothing/proc/attach_accessory(mob/user, obj/item/clothing/accessory/A) LAZYADD(accessories, A) A.on_attached(src, user) src.verbs |= /obj/item/clothing/proc/removetie_verb update_clothing_icon() - update_accessory_slowdown() + update_accessory_slowdown(user) recalculate_body_temperature_change() /obj/item/clothing/proc/remove_accessory(mob/user, obj/item/clothing/accessory/A) @@ -123,7 +124,7 @@ A.on_removed(user) LAZYREMOVE(accessories, A) update_clothing_icon() - update_accessory_slowdown() + update_accessory_slowdown(user) recalculate_body_temperature_change() /obj/item/clothing/proc/removetie_verb() diff --git a/code/modules/clothing/shoes/magboots.dm b/code/modules/clothing/shoes/magboots.dm index 422fec2d2d6..3e5a0aed2ea 100644 --- a/code/modules/clothing/shoes/magboots.dm +++ b/code/modules/clothing/shoes/magboots.dm @@ -24,10 +24,11 @@ src.shoes = null src.wearer = null -/obj/item/clothing/shoes/magboots/proc/set_slowdown() +/obj/item/clothing/shoes/magboots/proc/set_slowdown(mob/user) slowdown = shoes? max(0, shoes.slowdown): 0 //So you can't put on magboots to make you walk faster. if(magpulse) slowdown += slowdown_active + user.update_equipment_speed_mods() /obj/item/clothing/shoes/magboots/proc/update_wearer() if(QDELETED(wearer)) @@ -45,7 +46,7 @@ if(magpulse) item_flags &= ~ITEM_FLAG_NO_SLIP magpulse = 0 - set_slowdown() + set_slowdown(user) force = 3 if(icon_base) icon_state = "[icon_base]0" @@ -54,7 +55,7 @@ else item_flags |= ITEM_FLAG_NO_SLIP magpulse = 1 - set_slowdown() + set_slowdown(user) force = 11 if(icon_base) icon_state = "[icon_base]1" @@ -92,7 +93,7 @@ if (shoes) to_chat(user, "You slip \the [src] on over \the [shoes].") - set_slowdown() + set_slowdown(user) wearer = H return 1 diff --git a/code/modules/clothing/shoes/sneakers.dm b/code/modules/clothing/shoes/sneakers.dm index 26180526a46..4f6a14cf20e 100644 --- a/code/modules/clothing/shoes/sneakers.dm +++ b/code/modules/clothing/shoes/sneakers.dm @@ -31,6 +31,9 @@ src.slowdown = 15 src.icon_state = "orange1" src.item_state = "orange1" + if(ismob(src.loc)) + var/mob/holder_user = src.loc + holder_user.update_equipment_speed_mods() /obj/item/clothing/shoes/sneakers/orange/proc/remove_cuffs(mob/user as mob) if (!src.chained) return @@ -42,6 +45,9 @@ src.icon_state = "orange" src.item_state = "orange" src.chained = null + if(ismob(src.loc)) + var/mob/holder_user = src.loc + holder_user.update_equipment_speed_mods() /obj/item/clothing/shoes/sneakers/orange/attack_self(mob/user as mob) ..() diff --git a/code/modules/clothing/spacesuits/rig/rig.dm b/code/modules/clothing/spacesuits/rig/rig.dm index d9154e7595d..867c9ef7747 100644 --- a/code/modules/clothing/spacesuits/rig/rig.dm +++ b/code/modules/clothing/spacesuits/rig/rig.dm @@ -426,7 +426,9 @@ offline = 0 if(istype(wearer) && !wearer.wearing_rig) wearer.wearing_rig = src - slowdown = initial(slowdown) + if(slowdown != initial(slowdown)) + slowdown = initial(slowdown) + wearer?.update_equipment_speed_mods() set_vision(!offline) if(offline) @@ -435,7 +437,9 @@ for(var/obj/item/rig_module/module in installed_modules) module.deactivate() offline = 2 - slowdown = offline_slowdown + if(slowdown != offline_slowdown) + slowdown = offline_slowdown + wearer?.update_equipment_speed_mods() return if(crushing) diff --git a/code/modules/mob/inventory.dm b/code/modules/mob/inventory.dm index 80dd14f298e..e9202a9e020 100644 --- a/code/modules/mob/inventory.dm +++ b/code/modules/mob/inventory.dm @@ -377,15 +377,24 @@ var/list/slot_equipment_priority = list( \ if(slot_wear_mask) return wear_mask return null -//Outdated but still in use apparently. This should at least be a human proc. -/mob/proc/get_equipped_items(var/include_carried = 0) +/** + * Used to return a list of equipped items on a human mob; does not by default include held items, see include_flags + * + * Argument(s): + * * Optional - include_flags, (see `code\__DEFINES\obj_flags.dm`) describes which optional things to include or not (pockets, accessories, held items) + */ +/mob/proc/get_equipped_items(include_flags = NONE) . = list() - if(back) . += back - if(wear_mask) . += wear_mask + if(back) + . += back + if(wear_mask) + . += wear_mask - if(include_carried) - if(l_hand) . += l_hand - if(r_hand) . += r_hand + if(include_flags & INCLUDE_HELD) + if(l_hand) + . += l_hand + if(r_hand) + . += r_hand @@ -510,7 +519,7 @@ var/list/slot_equipment_priority = list( \ return FALSE /mob/proc/delete_inventory(var/include_carried = FALSE) - for(var/obj/item/I as anything in get_equipped_items(include_carried)) + for(var/obj/item/I as anything in get_equipped_items(include_carried ? INCLUDE_POCKETS|INCLUDE_HELD : 0)) drop_from_inventory(I) qdel(I) diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm index 562bbc875c8..89d08324045 100644 --- a/code/modules/mob/living/carbon/carbon.dm +++ b/code/modules/mob/living/carbon/carbon.dm @@ -558,3 +558,6 @@ /mob/living/carbon/proc/should_have_limb(var/organ_check) return FALSE + +/mob/living/carbon/get_equipped_speed_mod_items() + return ..() + get_equipped_items() diff --git a/code/modules/mob/living/carbon/human/human_movement.dm b/code/modules/mob/living/carbon/human/human_movement.dm index bf41dfd4b03..d295f52d1cb 100644 --- a/code/modules/mob/living/carbon/human/human_movement.dm +++ b/code/modules/mob/living/carbon/human/human_movement.dm @@ -1,3 +1,5 @@ +//I would have rewritten this whole thing, but it requires to change half a million systems for it to be proper, therefore +//i declare this shit legacy code, to be slowly phased out as things get updated /mob/living/carbon/human/movement_delay() var/tally = 0 @@ -24,8 +26,6 @@ if(shock >= 10) tally += (shock / 30) //get_shock checks if we can feel pain - tally += ClothesSlowdown() - if(species) tally += species.get_species_tally(src) @@ -34,7 +34,7 @@ if(is_asystole()) tally += 10 //heart attacks are kinda distracting - if(aiming && aiming.aiming_at) + if(aiming?.aiming_at) tally += 5 // Iron sights make you slower, it's a well-known fact. if (is_drowsy()) @@ -50,23 +50,10 @@ if((mutations & mRun)) tally = 0 - tally = max(-2, tally + move_delay_mod) - - var/obj/item/AH = get_active_hand() - if(istype(AH)) - tally += AH.slowdown - - var/obj/item/IH = get_inactive_hand() - if(istype(IH)) - tally += IH.slowdown - if(isitem(pulling)) var/obj/item/P = pulling tally += P.slowdown - if(tally > 0 && (CE_SPEEDBOOST in chem_effects)) - tally = max(-2, tally - 3) - var/turf/T = get_turf(src) if(T) // changelings don't get movement costs var/datum/changeling/changeling @@ -193,11 +180,6 @@ /mob/living/carbon/human/mob_negates_gravity() return (shoes && shoes.negates_gravity()) -/mob/living/carbon/human/proc/ClothesSlowdown() - for(var/obj/item/I in list(wear_suit, w_uniform, back, gloves, head, wear_mask, shoes, l_ear, r_ear, glasses, belt)) - . += I.slowdown - . += I.slowdown_accessory - /mob/living/carbon/human/get_pulling_movement_delay() . = ..() @@ -205,4 +187,4 @@ var/mob/living/carbon/human/H = pulling if(H.species.slowdown > species.slowdown) . += H.species.slowdown - species.slowdown - . += H.ClothesSlowdown() + // . += H.ClothesSlowdown() diff --git a/code/modules/mob/living/carbon/human/intoxication.dm b/code/modules/mob/living/carbon/human/intoxication.dm index 32f3ad3efee..ce6fc92a8ad 100644 --- a/code/modules/mob/living/carbon/human/intoxication.dm +++ b/code/modules/mob/living/carbon/human/intoxication.dm @@ -35,10 +35,18 @@ var/target_dizziness = BASE_DIZZY + ((bac - INTOX_JUDGEIMP*SR)*DIZZY_ADD_SCALE*100) make_dizzy(target_dizziness - dizziness) + //To handle the speed modifier, because this system was made stupidly + //If there's enough alcohol and the modifier wasn't applied yet, apply it + //if there's not enough alcohol and the modifier was applied, remove it + var/datum/movespeed_modifier/has_alcohol_modifier = src.has_movespeed_modifier(/datum/movespeed_modifier/alcohol/intoxication) + if((bac > INTOX_MUSCLEIMP*SR) && !has_alcohol_modifier) + src.add_movespeed_modifier(/datum/movespeed_modifier/alcohol/intoxication) + else if(has_alcohol_modifier) + src.remove_movespeed_modifier(/datum/movespeed_modifier/alcohol/intoxication) + if(bac > INTOX_MUSCLEIMP*SR && bac < INTOX_REACTION*SR) if (prob(3)) to_chat(src, SPAN_GOOD(pick("You feel drunk!", "You feel great!", "Your inhibitions fall away...", "All your anxieties melt away."))) - move_delay_mod += 2 sprint_cost_factor += 0.2 if(bac > INTOX_REACTION*SR) @@ -50,7 +58,9 @@ slurring = max(slurring, target_slurring) confused = max(confused, 10) eye_blurry = max(eye_blurry, 10) - move_delay_mod += 2 + //Change the speed modifier, but only if it's not already what we want + if(has_alcohol_modifier.multiplicative_slowdown < 4) + src.add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/alcohol/intoxication, TRUE, 4) sprint_cost_factor += 0.2 if(bac > INTOX_VOMIT*SR)//Vomiting starts here. 1% chance every 10 ticks, escalating with increased intoxication (1% per 0.01 BAC) diff --git a/code/modules/mob/living/carbon/human/inventory.dm b/code/modules/mob/living/carbon/human/inventory.dm index b83b4c56e82..7e70d5b9ddd 100644 --- a/code/modules/mob/living/carbon/human/inventory.dm +++ b/code/modules/mob/living/carbon/human/inventory.dm @@ -433,31 +433,51 @@ This saves us from having to call add_fingerprint() any time something is put in if(slot_wrists) return wrists return ..() -/mob/living/carbon/human/get_equipped_items(var/include_carried = 0) +/mob/living/carbon/human/get_equipped_items(include_flags = NONE) var/list/items = new/list() - if(back) items += back - if(belt) items += belt - if(l_ear) items += l_ear - if(r_ear) items += r_ear - if(glasses) items += glasses - if(gloves) items += gloves - if(head) items += head - if(shoes) items += shoes - if(wear_id) items += wear_id - if(wear_mask) items += wear_mask - if(wear_suit) items += wear_suit - if(w_uniform) items += w_uniform - if(wrists) items += wrists + if(back) + items += back + if(belt) + items += belt + if(l_ear) + items += l_ear + if(r_ear) + items += r_ear + if(glasses) + items += glasses + if(gloves) + items += gloves + if(head) + items += head + if(shoes) + items += shoes + if(wear_id) + items += wear_id + if(wear_mask) + items += wear_mask + if(wear_suit) + items += wear_suit + if(w_uniform) + items += w_uniform + if(wrists) + items += wrists + if(legcuffed) + items += legcuffed + if(handcuffed) + items += handcuffed - if(include_carried) - if(l_hand) items += l_hand - if(r_hand) items += r_hand + if(include_flags & INCLUDE_HELD) + if(l_hand) + items += l_hand + if(r_hand) + items += r_hand + if(s_store) + items += s_store + + if(include_flags & INCLUDE_POCKETS) if(l_store) items += l_store if(r_store) items += r_store - if(legcuffed) items += legcuffed - if(handcuffed) items += handcuffed - if(s_store) items += s_store return items diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm index 90484088239..f84648d1cc2 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -642,7 +642,6 @@ max_stamina *= 1.1 stamina_recovery = species.stamina_recovery sprint_cost_factor = species.sprint_cost_factor - move_delay_mod = 0 if(CE_ADRENALINE in chem_effects) sprint_speed_factor += 0.1*chem_effects[CE_ADRENALINE] @@ -650,11 +649,6 @@ sprint_cost_factor -= 0.35 * chem_effects[CE_ADRENALINE] stamina_recovery += max ((stamina_recovery * 0.7 * chem_effects[CE_ADRENALINE]), 5) - if(CE_SPEEDBOOST in chem_effects) - sprint_speed_factor += 0.2 * chem_effects[CE_SPEEDBOOST] - stamina_recovery *= 1 + 0.3 * chem_effects[CE_SPEEDBOOST] - move_delay_mod += -1.5 * chem_effects[CE_SPEEDBOOST] - var/obj/item/clothing/C = wear_suit if(!(C && (C.body_parts_covered & HANDS) && !(C.heat_protection & HANDS)) && !gloves) for(var/obj/item/I in src) diff --git a/code/modules/mob/living/carbon/human/species/species.dm b/code/modules/mob/living/carbon/human/species/species.dm index eec7702ac2e..aa4833dfbec 100644 --- a/code/modules/mob/living/carbon/human/species/species.dm +++ b/code/modules/mob/living/carbon/human/species/species.dm @@ -794,6 +794,9 @@ /datum/species/proc/set_default_tail(var/mob/living/carbon/human/H) H.set_tail_style(H.species.tail) +/** + * DEPRECATED: Use `/datum/movespeed_modifier` instead + */ /datum/species/proc/get_species_tally(var/mob/living/carbon/human/H) return 0 @@ -850,6 +853,9 @@ /datum/species/proc/handle_emp_act(var/mob/living/carbon/human/H, var/severity) return FALSE +/** + * DEPRECATED: Use `/datum/movespeed_modifier` instead + */ /datum/species/proc/handle_movement_tally(var/mob/living/carbon/human/H) var/tally = 0 if(istype(H.buckled_to, /obj/structure/bed/stool/chair/office/wheelchair)) diff --git a/code/modules/mob/living/living_defines.dm b/code/modules/mob/living/living_defines.dm index 29b4cf4e628..20239d9891b 100644 --- a/code/modules/mob/living/living_defines.dm +++ b/code/modules/mob/living/living_defines.dm @@ -58,8 +58,6 @@ var/exhaust_threshold = 50 var/datum/progressbar/stamina_bar // Progress bar shown when stamina is not at full, and the mob supports stamina. Deleted on Logout or when stamina is full. - var/move_delay_mod = 0//Added to move delay, used for calculating movement speeds. Provides a centralised value for modifiers to alter - var/total_radiation = 0 // DON'T MODIFY THIS DIRECTLY. USE apply_radiation()! var/cloaked = 0//Set to 1 by cloaking devices, optimises update_icons diff --git a/code/modules/mob/living/silicon/robot/robot_movement.dm b/code/modules/mob/living/silicon/robot/robot_movement.dm index 458b2e63099..3e54d9f1755 100644 --- a/code/modules/mob/living/silicon/robot/robot_movement.dm +++ b/code/modules/mob/living/silicon/robot/robot_movement.dm @@ -82,4 +82,4 @@ var/mob/living/carbon/human/H = pulling if(H.species.slowdown > speed) . += H.species.slowdown - speed - . += H.ClothesSlowdown() + // . += H.ClothesSlowdown() diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index ad3f9865fc8..5d0a6e25e08 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -267,7 +267,13 @@ return M return 0 +/** + * OLD PROC, DO NOT ADD SHIT TO IT ANYMORE + * USE `/datum/movespeed_modifier`s instead! + */ /mob/proc/movement_delay() + SHOULD_NOT_SLEEP(TRUE) + if(lying) //Crawling, it's slower . += (8 + ((weakened * 3) + (confused * 2))) . = get_pulling_movement_delay() @@ -1511,10 +1517,36 @@ return WEATHER_EXPOSED +///Apply a proper movespeed modifier based on items we have equipped +/mob/proc/update_equipment_speed_mods() + var/speedies = 0 + for(var/obj/item/thing in get_equipped_speed_mod_items()) + speedies += (thing.slowdown + thing.slowdown_accessory) + + if(speedies) + add_or_update_variable_movespeed_modifier( + /datum/movespeed_modifier/equipment_speedmod, + multiplicative_slowdown = speedies, + ) + else + remove_movespeed_modifier(/datum/movespeed_modifier/equipment_speedmod) + +///Get all items in our possession that should affect our movespeed +/mob/proc/get_equipped_speed_mod_items() + . = list() + //Aurora BS + var/list/held_items = list() + held_items += l_hand + held_items += r_hand + //END AURORA BS + for(var/obj/item/thing in held_items) + // if(thing.item_flags & SLOWS_WHILE_IN_HAND) + . += thing + /mob/proc/check_emissive_equipment() var/old_zflags = z_flags z_flags &= ~ZMM_MANGLE_PLANES - for(var/atom/movable/AM in get_equipped_items(TRUE)) + for(var/atom/movable/AM in get_equipped_items(INCLUDE_POCKETS|INCLUDE_HELD)) if(AM.z_flags & ZMM_MANGLE_PLANES) z_flags |= ZMM_MANGLE_PLANES break diff --git a/code/modules/mob/mob_defines.dm b/code/modules/mob/mob_defines.dm index 10ee2bae587..30a7e4b560b 100644 --- a/code/modules/mob/mob_defines.dm +++ b/code/modules/mob/mob_defines.dm @@ -8,6 +8,13 @@ var/datum/mind/mind var/static/next_mob_id = 0 + /// List of movement speed modifiers applying to this mob + var/list/movespeed_modification //Lazy list, see mob_movespeed.dm + /// List of movement speed modifiers ignored by this mob. List -> List (id) -> List (sources) + var/list/movespeed_mod_immunities //Lazy list, see mob_movespeed.dm + /// The calculated mob speed slowdown based on the modifiers list + var/cached_multiplicative_slowdown + // we never want to hide a turf because it's not lit // We can rely on the lighting plane to handle that for us see_in_dark = 1e6 diff --git a/code/modules/mob/mob_movement.dm b/code/modules/mob/mob_movement.dm index 34d4bde51c4..75ceb33e58b 100644 --- a/code/modules/mob/mob_movement.dm +++ b/code/modules/mob/mob_movement.dm @@ -268,6 +268,8 @@ if(mob.transforming) return //This is sota the goto stop mobs from moving var + var/add_delay = mob.cached_multiplicative_slowdown + if(isliving(mob)) if(SEND_SIGNAL(mob, COMSIG_MOB_CLIENT_PRE_LIVING_MOVE, new_loc, direct) & COMSIG_MOB_CLIENT_BLOCK_PRE_LIVING_MOVE) return FALSE @@ -393,6 +395,7 @@ tally *= GLOB.config.walk_delay_multiplier move_delay += tally + move_delay += add_delay if(mob_is_human && mob.lying) var/mob/living/carbon/human/H = mob diff --git a/code/modules/movespeed/_movespeed_modifier.dm b/code/modules/movespeed/_movespeed_modifier.dm new file mode 100644 index 00000000000..fea932650f6 --- /dev/null +++ b/code/modules/movespeed/_movespeed_modifier.dm @@ -0,0 +1,201 @@ +/*! Movespeed modification datums. + + How move speed for mobs works + +Move speed is now calculated by using modifier datums which are added to mobs. Some of them (nonvariable ones) are globally cached, the variable ones are instanced and changed based on need. + +This gives us the ability to have multiple sources of movespeed, reliabily keep them applied and remove them when they should be + +THey can have unique sources and a bunch of extra fancy flags that control behaviour + +Previously trying to update move speed was a shot in the dark that usually meant mobs got stuck going faster or slower + +Movespeed modification list is a simple key = datum system. Key will be the datum's ID if it is overridden to not be null, or type if it is not. + +DO NOT override datum IDs unless you are going to have multiple types that must overwrite each other. It's more efficient to use types, ID functionality is only kept for cases where dynamic creation of modifiers need to be done. + +When update movespeed is called, the list of items is iterated, according to flags priority and a bunch of conditions +this spits out a final calculated value which is used as a modifer to last_move + modifier for calculating when a mob +can next move + +Key procs +* [add_movespeed_modifier](mob.html#proc/add_movespeed_modifier) +* [remove_movespeed_modifier](mob.html#proc/remove_movespeed_modifier) +* [has_movespeed_modifier](mob.html#proc/has_movespeed_modifier) +* [update_movespeed](mob.html#proc/update_movespeed) +*/ + +/datum/movespeed_modifier + /// Whether or not this is a variable modifier. Variable modifiers can NOT be ever auto-cached. ONLY CHECKED VIA INITIAL(), EFFECTIVELY READ ONLY (and for very good reason) + var/variable = FALSE + + /// Unique ID. You can never have different modifications with the same ID. By default, this SHOULD NOT be set. Only set it for cases where you're dynamically making modifiers/need to have two types overwrite each other. If unset, uses path (converted to text) as ID. + var/id + + /// Higher ones override lower priorities. This is NOT used for ID, ID must be unique, if it isn't unique the newer one overwrites automatically if overriding. + var/priority = 0 + var/flags = NONE + + /// Multiplicative slowdown + var/multiplicative_slowdown = 0 + + /// Movetypes this applies to + var/movetypes = ALL + + /// Movetypes this never applies to + var/blacklisted_movetypes = NONE + + /// Other modification datums this conflicts with. + var/conflicts_with + +/datum/movespeed_modifier/New() + . = ..() + if(!id) + id = "[type]" //We turn the path into a string. + +GLOBAL_LIST_EMPTY(movespeed_modification_cache) + +/// Grabs a STATIC MODIFIER datum from cache. YOU MUST NEVER EDIT THESE DATUMS, OR IT WILL AFFECT ANYTHING ELSE USING IT TOO! +/proc/get_cached_movespeed_modifier(modtype) + if(!ispath(modtype, /datum/movespeed_modifier)) + CRASH("[modtype] is not a movespeed modification typepath.") + var/datum/movespeed_modifier/M = modtype + if(initial(M.variable)) + CRASH("[modtype] is a variable modifier, and can never be cached.") + M = GLOB.movespeed_modification_cache[modtype] + if(!M) + M = GLOB.movespeed_modification_cache[modtype] = new modtype + return M + +///Add a move speed modifier to a mob. If a variable subtype is passed in as the first argument, it will make a new datum. If ID conflicts, it will overwrite the old ID. +/mob/proc/add_movespeed_modifier(datum/movespeed_modifier/type_or_datum, update = TRUE) + if(ispath(type_or_datum)) + if(!initial(type_or_datum.variable)) + type_or_datum = get_cached_movespeed_modifier(type_or_datum) + else + type_or_datum = new type_or_datum + var/datum/movespeed_modifier/existing = LAZYACCESS(movespeed_modification, type_or_datum.id) + if(existing) + if(existing == type_or_datum) //same thing don't need to touch + return TRUE + remove_movespeed_modifier(existing, FALSE) + if(length(movespeed_modification)) + BINARY_INSERT(type_or_datum.id, movespeed_modification, /datum/movespeed_modifier, type_or_datum, priority, COMPARE_VALUE) + LAZYSET(movespeed_modification, type_or_datum.id, type_or_datum) + if(update) + update_movespeed() + return TRUE + +/// Remove a move speed modifier from a mob, whether static or variable. +/mob/proc/remove_movespeed_modifier(datum/movespeed_modifier/type_id_datum, update = TRUE) + var/key + if(ispath(type_id_datum)) + key = initial(type_id_datum.id) || "[type_id_datum]" //id if set, path set to string if not. + else if(!istext(type_id_datum)) //if it isn't text it has to be a datum, as it isn't a type. + key = type_id_datum.id + else //assume it's an id + key = type_id_datum + if(!LAZYACCESS(movespeed_modification, key)) + return FALSE + LAZYREMOVE(movespeed_modification, key) + if(update) + update_movespeed(FALSE) + return TRUE + +/*! Used for variable slowdowns like hunger/health loss/etc, works somewhat like the old list-based modification adds. Returns the modifier datum if successful + How this SHOULD work is: + 1. Ensures type_id_datum one way or another refers to a /variable datum. This makes sure it can't be cached. This includes if it's already in the modification list. + 2. Instantiate a new datum if type_id_datum isn't already instantiated + in the list, using the type. Obviously, wouldn't work for ID only. + 3. Add the datum if necessary using the regular add proc + 4. If any of the rest of the args are not null (see: multiplicative slowdown), modify the datum + 5. Update if necessary +*/ +/mob/proc/add_or_update_variable_movespeed_modifier(datum/movespeed_modifier/type_id_datum, update = TRUE, multiplicative_slowdown) + var/modified = FALSE + var/inject = FALSE + var/datum/movespeed_modifier/final + if(istext(type_id_datum)) + final = LAZYACCESS(movespeed_modification, type_id_datum) + if(!final) + CRASH("Couldn't find existing modification when provided a text ID.") + else if(ispath(type_id_datum)) + if(!initial(type_id_datum.variable)) + CRASH("Not a variable modifier") + final = LAZYACCESS(movespeed_modification, initial(type_id_datum.id) || "[type_id_datum]") + if(!final) + final = new type_id_datum + inject = TRUE + modified = TRUE + else + if(!initial(type_id_datum.variable)) + CRASH("Not a variable modifier") + final = type_id_datum + if(!LAZYACCESS(movespeed_modification, final.id)) + inject = TRUE + modified = TRUE + if(!isnull(multiplicative_slowdown)) + final.multiplicative_slowdown = multiplicative_slowdown + modified = TRUE + if(inject) + add_movespeed_modifier(final, FALSE) + if(update && modified) + update_movespeed(TRUE) + return final + + +///Is there a movespeed modifier for this mob +/mob/proc/has_movespeed_modifier(datum/movespeed_modifier/datum_type_id) + var/key + if(ispath(datum_type_id)) + key = initial(datum_type_id.id) || "[datum_type_id]" + else if(istext(datum_type_id)) + key = datum_type_id + else + key = datum_type_id.id + return LAZYACCESS(movespeed_modification, key) + +/// Set or update the global movespeed config on a mob +/mob/proc/update_config_movespeed() + add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/mob_config_speedmod, multiplicative_slowdown = get_config_multiplicative_speed()) + +/// Get the global config movespeed of a mob by type +/mob/proc/get_config_multiplicative_speed() + if(!islist(GLOB.mob_config_movespeed_type_lookup) || !GLOB.mob_config_movespeed_type_lookup[type]) + return 0 + else + return GLOB.mob_config_movespeed_type_lookup[type] + +/// Go through the list of movespeed modifiers and calculate a final movespeed. ANY ADD/REMOVE DONE IN UPDATE_MOVESPEED MUST HAVE THE UPDATE ARGUMENT SET AS FALSE! +/mob/proc/update_movespeed() + . = 0 + var/list/conflict_tracker = list() + for(var/key in get_movespeed_modifiers()) + var/datum/movespeed_modifier/M = movespeed_modification[key] + if(!(M.movetypes & movement_type)) // We don't affect any of these move types, skip + continue + if(M.blacklisted_movetypes & movement_type) // There's a movetype here that disables this modifier, skip + continue + var/conflict = M.conflicts_with + var/amt = M.multiplicative_slowdown + if(conflict) + // Conflicting modifiers prioritize the larger slowdown or the larger speedup + // We purposefuly don't handle mixing speedups and slowdowns on the same id + if(abs(conflict_tracker[conflict]) < abs(amt)) + conflict_tracker[conflict] = amt + else + continue + . += amt + cached_multiplicative_slowdown = . + SEND_SIGNAL(src, COMSIG_MOB_MOVESPEED_UPDATED) + +/// Get the move speed modifiers list of the mob +/mob/proc/get_movespeed_modifiers() + . = LAZYCOPY(movespeed_modification) + for(var/id in movespeed_mod_immunities) + . -= id + +/// Checks if a move speed modifier is valid and not missing any data +/proc/movespeed_data_null_check(datum/movespeed_modifier/M) //Determines if a data list is not meaningful and should be discarded. + . = TRUE + if(M.multiplicative_slowdown) + . = FALSE diff --git a/code/modules/movespeed/modifiers/mobs.dm b/code/modules/movespeed/modifiers/mobs.dm new file mode 100644 index 00000000000..82608ce29e5 --- /dev/null +++ b/code/modules/movespeed/modifiers/mobs.dm @@ -0,0 +1,34 @@ +/// Movespeed modifier applied by worn equipment. +/datum/movespeed_modifier/equipment_speedmod + variable = TRUE + blacklisted_movetypes = FLOATING + +/// Movespeed modifier applied by immutably slow worn equipment. Should never be ignored, because that's the point. +/datum/movespeed_modifier/equipment_speedmod/immutable + +/datum/movespeed_modifier/config_walk_run + multiplicative_slowdown = 1 + id = MOVESPEED_ID_MOB_WALK_RUN + flags = IGNORE_NOSLOW + +/datum/movespeed_modifier/config_walk_run/proc/sync() + +/datum/movespeed_modifier/config_walk_run/walk/sync() + var/mod = GLOB.config.walk_speed //used to be CONFIG_GET(number/movedelay/walk_delay) + multiplicative_slowdown = isnum(mod)? mod : initial(multiplicative_slowdown) + +/datum/movespeed_modifier/config_walk_run/run/sync() + var/mod = GLOB.config.walk_speed * GLOB.config.run_delay_multiplier//CONFIG_GET(number/movedelay/run_delay) + multiplicative_slowdown = isnum(mod)? mod : initial(multiplicative_slowdown) + +/datum/movespeed_modifier/mob_config_speedmod + variable = TRUE + flags = IGNORE_NOSLOW + +/datum/movespeed_modifier/encumbered + multiplicative_slowdown = 2 + id = "encumbered" + +/datum/movespeed_modifier/zoomzoomkitty + multiplicative_slowdown = -0.5 + id = "zoomzoomkitty" diff --git a/code/modules/movespeed/modifiers/reagents.dm b/code/modules/movespeed/modifiers/reagents.dm new file mode 100644 index 00000000000..764baabe816 --- /dev/null +++ b/code/modules/movespeed/modifiers/reagents.dm @@ -0,0 +1,43 @@ +ABSTRACT_TYPE(/datum/movespeed_modifier/reagent) + blacklisted_movetypes = (FLYING|FLOATING) + +//Depends on the amount of caffeine in the drink +/datum/movespeed_modifier/reagent/caffeine + variable = TRUE + +/datum/movespeed_modifier/reagent/hyperzine + multiplicative_slowdown = -1 + +/datum/movespeed_modifier/reagent/stimm + multiplicative_slowdown = -1.5 + +/datum/movespeed_modifier/reagent/skrell_nootropic + multiplicative_slowdown = -0.5 + +/datum/movespeed_modifier/reagent/dionae_stimulant + multiplicative_slowdown = -1 + +/datum/movespeed_modifier/reagent/kokoreed + multiplicative_slowdown = -1 + +/datum/movespeed_modifier/reagent/kilosemine + multiplicative_slowdown = -1 + +ABSTRACT_TYPE(/datum/movespeed_modifier/reagent/zorasoda) + +/datum/movespeed_modifier/reagent/zorasoda/drone + multiplicative_slowdown = -1 + + +ABSTRACT_TYPE(/datum/movespeed_modifier/alcohol) + +///This is ONLY for the intoxication management of alcohol, NOT for anything else +///if you're not using it in `code\modules\mob\living\carbon\human\intoxication.dm`, you're doing it wrong +/datum/movespeed_modifier/alcohol/intoxication + multiplicative_slowdown = 2 + variable = TRUE + +//Only speed boost for unathi +/datum/movespeed_modifier/alcohol/butanol + multiplicative_slowdown = 0 + variable = TRUE diff --git a/code/modules/movespeed/modifiers/spells.dm b/code/modules/movespeed/modifiers/spells.dm new file mode 100644 index 00000000000..8b57e35ea95 --- /dev/null +++ b/code/modules/movespeed/modifiers/spells.dm @@ -0,0 +1,6 @@ +ABSTRACT_TYPE(/datum/movespeed_modifier/spell) + +ABSTRACT_TYPE(/datum/movespeed_modifier/spell/technomancer) + +/datum/movespeed_modifier/spell/technomancer/haste + multiplicative_slowdown = -0.8 diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Dispenser.dm b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Dispenser.dm index 831d903ad56..dd666cd4942 100644 --- a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Dispenser.dm +++ b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Dispenser.dm @@ -191,7 +191,6 @@ ABSTRACT_TYPE(/singleton/reagent/alcohol) M.hallucination = max(M.hallucination, halluci) if(caffeine) M.add_chemical_effect(CE_PULSE, caffeine*2) - M.add_up_to_chemical_effect(CE_SPEEDBOOST, 1) M.adjustNutritionLoss(-nutriment_factor * removed) M.adjustHydrationLoss(-hydration_factor * removed) @@ -263,7 +262,7 @@ ABSTRACT_TYPE(/singleton/reagent/alcohol) M.hallucination = max(M.hallucination, halluci) if(caffeine) M.add_chemical_effect(CE_PULSE, caffeine*2) - M.add_up_to_chemical_effect(CE_SPEEDBOOST, 1) + M.add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/alcohol/butanol, TRUE, caffeine*2) M.adjustNutritionLoss(-nutriment_factor * removed) M.adjustHydrationLoss(-hydration_factor * removed) @@ -273,6 +272,10 @@ ABSTRACT_TYPE(/singleton/reagent/alcohol) if (adj_temp < 0 && M.bodytemperature > targ_temp) M.bodytemperature = min(targ_temp, M.bodytemperature - (adj_temp * TEMPERATURE_DAMAGE_COEFFICIENT)) +/singleton/reagent/alcohol/butanol/final_effect(mob/living/carbon/M, datum/reagents/holder) + M.remove_movespeed_modifier(/datum/movespeed_modifier/alcohol/butanol) + . = ..() + /singleton/reagent/hydrazine name = "Hydrazine" diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Drugs.dm b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Drugs.dm index fac7a7eb166..f94dc28bba2 100644 --- a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Drugs.dm +++ b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Drugs.dm @@ -335,7 +335,6 @@ M.make_jittery(5 + holder.reagent_data[type]["special"]) M.drowsiness = max(0,M.drowsiness - (1 + holder.reagent_data[type]["special"]*0.1)) if(holder.reagent_data[type]["special"] > 5) - M.add_chemical_effect(CE_SPEEDBOOST, 1) M.apply_effect(1 + holder.reagent_data[type]["special"]*0.25, STUTTER) M.druggy = max(M.druggy, holder.reagent_data[type]["special"]*0.25) M.make_jittery(holder.reagent_data[type]["special"]) @@ -392,6 +391,10 @@ overdose = 10 strength = 3 +/singleton/reagent/toxin/stimm/initial_effect(mob/living/carbon/M, alien, datum/reagents/holder) + . = ..() + M.add_movespeed_modifier(/datum/movespeed_modifier/reagent/stimm) + /singleton/reagent/toxin/stimm/affect_blood(mob/living/carbon/M, alien, removed, datum/reagents/holder) if(alien == IS_TAJARA) removed *= 1.25 @@ -403,7 +406,10 @@ if(prob(5)) // average of 6 brute every 20 seconds. M.visible_message("[M] shudders violently.", "You shudder uncontrollably, it hurts.") M.take_organ_damage(6 * removed, 0) - M.add_up_to_chemical_effect(CE_SPEEDBOOST, 1) + +/singleton/reagent/toxin/stimm/final_effect(mob/living/carbon/M, datum/reagents/holder) + M.remove_movespeed_modifier(/datum/movespeed_modifier/reagent/stimm) + . = ..() /singleton/reagent/toxin/krok name = "Krok Juice" @@ -589,18 +595,20 @@ if(prob(2)) to_chat(M, SPAN_GOOD(pick("You have a renewed sense of focus.", "You feel more determined to get things done.", "You feel more confident in your own abilities.", "Your head-space feels tidy and organised - now's the time to get to work.", "You could climb a mountain right now!"))) -/singleton/reagent/drugs/skrell_nootropic/final_effect(mob/living/carbon/M, alien, removed, datum/reagents/holder) - if(M.psi && psi_boosted) - M.psi.max_stamina = initial_stamina - psi_boosted = FALSE - /singleton/reagent/drugs/skrell_nootropic/overdose(mob/living/carbon/M, alien, removed, datum/reagents/holder) - M.add_chemical_effect(CE_SPEEDBOOST, 0.5) + M.add_movespeed_modifier(/datum/movespeed_modifier/reagent/skrell_nootropic) if(prob(25)) M.add_chemical_effect(CE_NEPHROTOXIC, 0.5) if(prob(2)) to_chat(M, SPAN_WARNING(pick("You can't allow anyone to get between you and your tasks.", "You feel like screaming at the next person who interrupts you.", "No one can stop you!", "You can power through this..."))) +/singleton/reagent/drugs/skrell_nootropic/final_effect(mob/living/carbon/M, alien, removed, datum/reagents/holder) + M.remove_movespeed_modifier(/datum/movespeed_modifier/reagent/skrell_nootropic) + if(M.psi && psi_boosted) + M.psi.max_stamina = initial_stamina + psi_boosted = FALSE + . = ..() + /singleton/reagent/drugs/cocaine name = "Cocaine" description = "A recreational drug known for its sharp, but short, energy boost. Very commonly used by cytherians on Venus." @@ -723,10 +731,14 @@ initial_effect_message_list = list("A heat builds within you.", ) sober_message_list = list("The heat within you begins to dull...") +/singleton/reagent/drugs/dionae_stimulant/initial_effect(mob/living/carbon/M, alien, datum/reagents/holder) + . = ..() + if(alien == IS_DIONA) + M.add_movespeed_modifier(/datum/movespeed_modifier/reagent/dionae_stimulant) + /singleton/reagent/drugs/dionae_stimulant/affect_blood(mob/living/carbon/M, alien, removed, datum/reagents/holder) M.apply_damage(10, DAMAGE_RADIATION, damage_flags = DAMAGE_FLAG_DISPERSED) if(alien == IS_DIONA) - M.add_chemical_effect(CE_SPEEDBOOST, 1) if(prob(5)) to_chat(M, SPAN_GOOD(pick("A bubbling sensation is felt by your nymphs.", "A nymph comments that this is the most energetic it has ever been!", "A warm energy builds within your central structure.", "Your nymphs can't stay still!"))) M.emote(pick("chirp", "twitch", "shiver")) @@ -748,5 +760,10 @@ new /obj/effect/decal/cleanable/greenglow(T) return +/singleton/reagent/drugs/dionae_stimulant/final_effect(mob/living/carbon/M, alien, removed, datum/reagents/holder) + if(alien == IS_DIONA) + M.remove_movespeed_modifier(/datum/movespeed_modifier/reagent/dionae_stimulant) + . = ..() + #undef DRUG_MESSAGE_DELAY diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Food-Drinks.dm b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Food-Drinks.dm index 20e3a12ea9c..726b953afa6 100644 --- a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Food-Drinks.dm +++ b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Food-Drinks.dm @@ -1014,7 +1014,10 @@ var/adj_drowsy = 0 var/adj_sleepy = 0 var/adj_temp = 0 //do NOT use for temp changes based on the temperature of the drinks, only for things such as spices. - var/caffeine = 0 // strength of stimulant effect, since so many drinks use it + + ///Strength of stimulant effect, since so many drinks use it - how fast it makes you move + var/caffeine = 0 + unaffected_species = IS_MACHINE var/blood_to_ingest_scale = 2 fallback_specific_heat = 1.75 @@ -1025,10 +1028,15 @@ /singleton/reagent/drink/affect_ingest(var/mob/living/carbon/M, var/alien, var/removed, var/datum/reagents/holder) digest(M, alien, removed, holder = holder) +/singleton/reagent/drink/initial_effect(mob/living/carbon/M, alien, datum/reagents/holder) + . = ..() + + if(caffeine && (alien != IS_DIONA)) + M.add_movespeed_modifier(/datum/movespeed_modifier/reagent/caffeine) + M.add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/reagent/caffeine, TRUE, (caffeine * -1)) + /singleton/reagent/drink/proc/digest(var/mob/living/carbon/M, var/alien, var/removed, var/add_nutrition = TRUE, var/datum/reagents/holder) if(alien != IS_DIONA) - if (caffeine) - M.add_up_to_chemical_effect(CE_SPEEDBOOST, caffeine) M.dizziness = max(0, M.dizziness + adj_dizzy) M.drowsiness = max(0, M.drowsiness + adj_drowsy) M.sleeping = max(0, M.sleeping + adj_sleepy) @@ -1042,6 +1050,12 @@ if(adj_temp < 0 && M.bodytemperature > 310) M.bodytemperature = min(310, M.bodytemperature - (adj_temp * TEMPERATURE_DAMAGE_COEFFICIENT)) +/singleton/reagent/drink/final_effect(mob/living/carbon/M, alien, removed, datum/reagents/holder) + if(caffeine && (alien != IS_DIONA)) + M.remove_movespeed_modifier(/datum/movespeed_modifier/reagent/caffeine) + + . = ..() + // Juices /singleton/reagent/drink/banana name = "Banana Juice" @@ -5997,7 +6011,7 @@ var/obj/item/organ/internal/parasite/P = M.internal_organs_by_name["blackkois"] if((alien == IS_VAURCA) || (istype(P) && P.stage >= 3)) - M.add_chemical_effect(CE_SPEEDBOOST, 1) + M.add_movespeed_modifier(/datum/movespeed_modifier/reagent/zorasoda/drone) M.add_chemical_effect(CE_BLOODRESTORE, 2 * removed) M.make_jittery(5) else if(alien != IS_DIONA) @@ -6005,6 +6019,12 @@ to_chat(M, pick(SPAN_WARNING("You feel nauseous!"), SPAN_WARNING("Ugh... You're going to be sick!"), SPAN_WARNING("Your stomach churns uncomfortably!"), SPAN_WARNING("You feel like you're about to throw up!"), SPAN_WARNING("You feel queasy!"))) M.vomit() +/singleton/reagent/drink/zorasoda/drone/final_effect(mob/living/carbon/M, alien, removed, datum/reagents/holder) + M.remove_movespeed_modifier(/datum/movespeed_modifier/reagent/zorasoda/drone) + + . = ..() + + /singleton/reagent/drink/zorasoda/jelly name = "Royal Vaurca Jelly" description = "It looks like mucus, but tastes like heaven. Royal jelly is a nutritious concentrated substance commonly created by Caretaker Vaurca in order to feed larvae. It is known to have a stimulating effect in most, if not all, species." diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Medicine.dm b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Medicine.dm index 9be275f7b62..ca421a3ee70 100644 --- a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Medicine.dm +++ b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Medicine.dm @@ -728,11 +728,14 @@ color = "#FF3300" metabolism = REM * 0.15 overdose = 15 - var/datum/modifier = null taste_description = "acid" metabolism_min = REM * 0.025 breathe_met = REM * 0.15 * 0.5 +/singleton/reagent/hyperzine/initial_effect(mob/living/carbon/M, alien, datum/reagents/holder) + . = ..() + M.add_movespeed_modifier(/datum/movespeed_modifier/reagent/hyperzine) + /singleton/reagent/hyperzine/get_overdose(mob/living/carbon/M, location, datum/reagents/holder) if(REAGENT_VOLUME(M.reagents, /singleton/reagent/adrenaline) > 5) return 10 //Volume of hyperzine required to OD reduced from 15u to 10u. @@ -748,7 +751,6 @@ M.emote(pick("twitch", "blink_r", "shiver")) to_chat(M, SPAN_GOOD(pick("You feel pumped!", "Energy, energy, energy - so much energy!", "You could run a marathon!", "You can't sit still!", "It's difficult to focus right now... but that's not important!"))) if(check_min_dose(M, 0.5)) - M.add_chemical_effect(CE_SPEEDBOOST, 1) M.add_chemical_effect(CE_PULSE, 1) /singleton/reagent/hyperzine/overdose(var/mob/living/carbon/M, var/alien, var/removed, var/datum/reagents/holder) @@ -761,9 +763,9 @@ M.take_organ_damage(5 * removed, 0) M.adjustHalLoss(15) -/singleton/reagent/hyperzine/Destroy() - QDEL_NULL(modifier) - return ..() +/singleton/reagent/hyperzine/final_effect(mob/living/carbon/M, datum/reagents/holder) + M.remove_movespeed_modifier(/datum/movespeed_modifier/reagent/hyperzine) + . = ..() #define ETHYL_INTOX_COST 3 //The cost of power to remove one unit of intoxication from the patient #define ETHYL_REAGENT_POWER 20 //The amount of power in one unit of ethyl @@ -1346,13 +1348,21 @@ /singleton/reagent/mental/kokoreed/affect_blood(var/mob/living/carbon/M, var/alien, var/removed, var/datum/reagents/holder) . = ..() + if(M.bodytemperature > 310) M.bodytemperature = max(310, M.bodytemperature - (5 * TEMPERATURE_DAMAGE_COEFFICIENT)) /singleton/reagent/mental/kokoreed/overdose(var/mob/living/carbon/M, var/alien, var/removed, var/scale, var/datum/reagents/holder) . = ..() + if(isunathi(M)) - M.add_up_to_chemical_effect(CE_SPEEDBOOST, 1) + M.add_movespeed_modifier(/datum/movespeed_modifier/reagent/kokoreed) + +/singleton/reagent/mental/kokoreed/final_effect(mob/living/carbon/M, alien, removed, datum/reagents/holder) + if(isunathi(M)) + M.remove_movespeed_modifier(/datum/movespeed_modifier/reagent/kokoreed) + + . = ..() /singleton/reagent/cataleptinol name = "Cataleptinol" @@ -1849,7 +1859,7 @@ /singleton/reagent/kilosemine/affect_chem_effect(var/mob/living/carbon/M, var/alien, var/removed) . = ..() if(.) - M.add_chemical_effect(CE_SPEEDBOOST, 1) + M.add_movespeed_modifier(/datum/movespeed_modifier/reagent/kilosemine) M.add_chemical_effect(CE_CLEARSIGHT) M.add_chemical_effect(CE_STRAIGHTWALK) M.add_chemical_effect(CE_PAINKILLER, 30) @@ -1876,6 +1886,10 @@ to_chat(H, SPAN_DANGER("Your heart skips a beat and screams out in pain!")) heart.take_internal_damage(10) +/singleton/reagent/kilosemine/final_effect(mob/living/carbon/M, alien, removed, datum/reagents/holder) + M.remove_movespeed_modifier(/datum/movespeed_modifier/reagent/kilosemine) + . = ..() + /singleton/reagent/antiparasitic name = "Helmizole" description = "Helmizole is an anti-helminthic medication which combats parasitic worm infections, compromising their nervous system and inducing respiratory paralysis." @@ -1933,6 +1947,11 @@ metabolism_min = REM * 0.025 breathe_met = REM * 0.15 * 0.5 +/singleton/reagent/caffeine/initial_effect(mob/living/carbon/M, alien, datum/reagents/holder) + . = ..() + M.add_movespeed_modifier(/datum/movespeed_modifier/reagent/caffeine) + M.add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/reagent/caffeine, TRUE, -0.35) + /singleton/reagent/caffeine/get_od_min_dose(mob/living/carbon/M, location, datum/reagents/holder) if(REAGENT_VOLUME(M.reagents, /singleton/reagent/adrenaline) > 5) return 0 // Takes effect instantly. @@ -1947,7 +1966,6 @@ /singleton/reagent/caffeine/overdose(var/mob/living/carbon/M, var/alien, var/removed, var/datum/reagents/holder) M.adjustNutritionLoss(5*removed) M.add_chemical_effect(CE_PULSE, 2) - M.add_chemical_effect(CE_SPEEDBOOST, 0.35) // Coffee = 0.3, Zora Soda = 0.4, Thirteen Loko = 0.5. Seems fine here, if a bit low. M.make_jittery(5) if(prob(5)) to_chat(M, SPAN_WARNING(pick("You have a headache!", "Energy, energy, energy - so much energy!", "You can't sit still!", "It's difficult to focus right now... but that's not important!", "Your heart is beating rapidly!", "Your chest hurts!", "You've totally over-exerted yourself!"))) @@ -1956,6 +1974,10 @@ M.take_organ_damage(5 * removed, 0) M.adjustHalLoss(15) +/singleton/reagent/caffeine/final_effect(mob/living/carbon/M, alien, removed, datum/reagents/holder) + M.remove_movespeed_modifier(/datum/movespeed_modifier/reagent/caffeine) + . = ..() + /singleton/reagent/caffeine/Destroy() QDEL_NULL(modifier) return ..() diff --git a/html/changelogs/fluffyghost-movespeedmodifiers.yml b/html/changelogs/fluffyghost-movespeedmodifiers.yml new file mode 100644 index 00000000000..aad366f27f7 --- /dev/null +++ b/html/changelogs/fluffyghost-movespeedmodifiers.yml @@ -0,0 +1,60 @@ +################################ +# Example Changelog File +# +# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb. +# +# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.) +# When it is, any changes listed below will disappear. +# +# Valid Prefixes: +# bugfix +# - (fixes bugs) +# wip +# - (work in progress) +# qol +# - (quality of life) +# soundadd +# - (adds a sound) +# sounddel +# - (removes a sound) +# rscadd +# - (adds a feature) +# rscdel +# - (removes a feature) +# imageadd +# - (adds an image or sprite) +# imagedel +# - (removes an image or sprite) +# spellcheck +# - (fixes spelling or grammar) +# experiment +# - (experimental change) +# balance +# - (balance changes) +# code_imp +# - (misc internal code change) +# refactor +# - (refactors code) +# config +# - (makes a change to the config files) +# admin +# - (makes changes to administrator tools) +# server +# - (miscellaneous changes to server) +################################# + +# Your name. +author: FluffyGhost + +# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again. +delete-after: True + +# Any changes you've made. See valid prefix list above. +# INDENT WITH TWO SPACES. NOT TABS. SPACES. +# SCREW THIS UP AND IT WON'T WORK. +# Also, this gets changed to [] after reading. Just remove the brackets when you add new shit. +# Please surround your changes in double quotes ("). It works without them, but if you use certain characters it screws up compiling. The quotes will not show up in the changelog. +changes: + - refactor: "Ported and implemented movespeed_modifer, for most things, from TG." + - code_imp: "Gave deprecation DMDocs to the old calculation system." + - code_imp: "Some code cleanup around."