From 1c0b13ecfbea1c05e47bae1715aa82cba1fe407e Mon Sep 17 00:00:00 2001 From: deathride58 Date: Sun, 11 Mar 2018 20:32:44 +0000 Subject: [PATCH] [READY FOR MERGE] The Giant Combat Reworks - Part 1: Goodbye stuns, hello staminacrit (#5463) * part 1 - resist out of resting, move and interact with the world while resting, and stamina regen nerf * makes beepsky check for stuns instead of knockdowns, adds message for getting up, makes gravity reduce standup time, and more * sprinting, staminacrit, balance changes, and more * adds stamina modifier to clickdelay, makes items deal stamina damage to the user when attacking, buffs resting stamina regen * combat mode, ability to toggle right-click context menu on/off, basic combat mode QOL, lays groundwork for 2-handing any item combat mode toggle sound is from Interbay. * commits dme changes * unarmed combat stamina, ability to right click in combat mode, balance changes * tosses in the HUD icons for later-ish * rolls back admin.txt * lotsa UI stuff * stamina checks, some balance stuff * adds support for best ui, adds right click to flush disposals, removes aggressive grab pinning in favor of neckgrab chokeholding * quick dogborg patch while i figure out what do do with them * oops - fixes prefbreaking for screenshake * trying to sprint from an elevated surface onto lower ground will now knock you down * right click to pull fire alarm, lets you bully people by pulling chairs out form under them, makes attacking objects cost stamina * makes accidents during slipping less likely to occur while combat mode is active, makes tripping off elevated surfaces cause accidents * makes pumping shotguns cost a tiiiny bit of stamina * makes eyestabbing and batoning cost stamina * makes failing stamina checks error out properly, adds stamina check to shotgun pumping * adds stamina check for chair pulling * readds aggressive grab pinning * fixes bug with being buckled preventing interaction * adds recoveringstam check to incapacitated * reduces stamina cost for attacking * oh this too * fixes bug where you can get stuck in recoveringstam if your stamina suddenly becomes 0 while you're in staminacrit * makes monkey transformation inherit staminaloss * adds the ability to wave or shake your fist at someone via right click * grammar and span closing * 99 annoying little bugs on the wall, 99 annoying little bugs. take one down, pass it around, 864 gamebreaking bugs on the wall * more distant right-click emotes. * buffs standing stamina regen a tiiiiiiny bit * adds aiming down sights for guns, makes firing guns cause trace amounts of staminaloss * crusher powercreep - gives crushers the ability to heal staminaloss * item throwing buff * adds 1:1 HUD layout * hopefully fixes issue with recoveringstamcrit not updating * giant hipfire nerf * halves the effect of staminaloss on movement speed * makes stamina recover faster in staminacrit, makes it easier to get disarmed out of combat mode * get_weight(), movedelay health_deficiency tweaking, combat and resting checks for item attacking * makes staminacrit automatically disable combat mode, it's now impossible to enter combat mode while in stamcrit * adds stamina buffer, halves the time needed to stand up after resting, increases stam penalty for firing weapons, and more * tweaks stamina buffer drain rate a little * makes buffered staminaloss redirect stamina to the actual stamloss proc when empty, makes stamina buffer stat() more precise * removes stamina modifier for clickdelays, makes stunbatons deal extra staminaloss * makes electrodes deal a lil extra staminaloss * drones cannot resist a rest, so now only carbons are forced to rest * restricts aiming down sights to carbon mobs, adds stamina display to stat() * makes gun accuracy and stamcosts more flexible, decreases base inaccuracy penalty, makes borgs immune to inaccuracy penalties * nerfs inaccuracy penalties just a lil more, fixes blooddrunk miner eye depleting all your stamina * getting used to tortoisegit * readds temp dogborg buff * stamina and stamina buffer HUD displays. Stamina sprite from hippiestation * makes afterattack call properly again * decreases stamina buffer regen time to 3 seconds * Yknow what? decreases it to 2 seconds. That's 3 entire attacks worth of waiting * makes stamina buffer influence movespeed a lil * nerfs compiling errors * tweaks the icons a little * adds autostanding, adds delimiters to attempts to stand * makes automatic standup attempts a little clearer * rest button now toggles intent to rest, fixes perma rest * oop - quick fixes * Makes crushers ignore recoil stamina on lavaland, makes burstfiring weapons deal less staminaloss * buffs highlander sword * makes stamina have less of an impact on the health display * fixes dogborgs shoving other borgs into infinite stuns * You can no longer shoot over tables or shoot through windows while resting. Also buffs turrets --- code/__DEFINES/citadel_defines.dm | 18 ++- code/_onclick/click.dm | 6 +- code/_onclick/hud/_defines.dm | 8 +- code/_onclick/hud/human.dm | 42 +++++- code/_onclick/item_attack.dm | 20 ++- code/datums/status_effects/buffs.dm | 4 +- code/game/machinery/dance_machine.dm | 7 +- .../machinery/porta_turret/portable_turret.dm | 2 +- code/game/objects/items.dm | 6 + .../objects/items/devices/dogborg_sleeper.dm | 2 +- code/game/objects/items/melee/misc.dm | 5 + code/game/objects/items/stunbaton.dm | 6 + code/game/objects/items/weaponry.dm | 1 + code/modules/client/preferences.dm | 4 + code/modules/client/preferences_savefile.dm | 3 + .../mining/equipment/kinetic_crusher.dm | 3 + code/modules/mob/inventory.dm | 2 +- code/modules/mob/living/carbon/carbon.dm | 19 ++- .../mob/living/carbon/carbon_defense.dm | 13 +- .../modules/mob/living/carbon/damage_procs.dm | 9 +- code/modules/mob/living/carbon/human/human.dm | 2 +- .../mob/living/carbon/human/species.dm | 58 +++++++-- code/modules/mob/living/carbon/life.dm | 13 +- .../mob/living/carbon/monkey/combat.dm | 2 +- code/modules/mob/living/living.dm | 27 +++- .../mob/living/simple_animal/bot/ed209bot.dm | 6 +- .../mob/living/simple_animal/bot/secbot.dm | 6 +- code/modules/mob/mob.dm | 4 + code/modules/mob/transform_procs.dm | 2 + code/modules/projectiles/gun.dm | 6 + .../projectiles/guns/ballistic/shotgun.dm | 5 + code/modules/projectiles/projectile.dm | 7 + modular_citadel/cit_screenshake.dm | 6 +- modular_citadel/cit_turfs.dm | 5 - modular_citadel/code/__HELPERS/list2list.dm | 12 ++ modular_citadel/code/_onclick/click.dm | 74 +++++++++++ .../code/_onclick/hud/screen_objects.dm | 49 +++++++ modular_citadel/code/_onclick/hud/stamina.dm | 73 +++++++++++ modular_citadel/code/_onclick/item_attack.dm | 25 ++++ modular_citadel/code/_onclick/other_mobs.dm | 29 +++++ .../code/datums/status_effects/debuffs.dm | 13 ++ .../code/game/machinery/firealarm.dm | 10 ++ modular_citadel/code/game/objects/items.dm | 2 + .../objects/structures/beds_chairs/chair.dm | 21 +++ .../code/modules/client/client_procs.dm | 8 ++ .../code/modules/client/preferences.dm | 1 + .../modules/keybindings/bindings_carbon.dm | 6 + .../modules/keybindings/bindings_human.dm | 13 ++ .../code/modules/mob/living/carbon/carbon.dm | 17 +++ .../modules/mob/living/carbon/damage_procs.dm | 10 ++ .../modules/mob/living/carbon/human/human.dm | 0 .../mob/living/carbon/human/human_defense.dm | 11 +- .../mob/living/carbon/human/human_movement.dm | 31 +++++ .../modules/mob/living/carbon/human/life.dm | 13 +- .../mob/living/carbon/human/species.dm | 57 ++++++++ .../code/modules/mob/living/damage_procs.dm | 2 + .../code/modules/mob/living/living.dm | 122 ++++++++++++++++++ .../living/silicon/robot/dogborg_equipment.dm | 2 +- modular_citadel/code/modules/mob/mob.dm | 2 + .../code/modules/projectiles/gun.dm | 36 ++++++ .../modules/projectiles/projectile/energy.dm | 2 + .../code/modules/recycling/disposal/bin.dm | 6 + modular_citadel/icons/ui/screen_clockwork.dmi | Bin 0 -> 3074 bytes modular_citadel/icons/ui/screen_gen.dmi | Bin 0 -> 5328 bytes modular_citadel/icons/ui/screen_midnight.dmi | Bin 0 -> 5406 bytes modular_citadel/icons/ui/screen_operative.dmi | Bin 0 -> 5287 bytes .../icons/ui/screen_plasmafire.dmi | Bin 0 -> 4769 bytes modular_citadel/icons/ui/screen_slimecore.dmi | Bin 0 -> 4470 bytes modular_citadel/sound/misc/sprintactivate.ogg | Bin 0 -> 5486 bytes .../sound/misc/sprintdeactivate.ogg | Bin 0 -> 5156 bytes modular_citadel/sound/misc/ui_toggle.ogg | Bin 0 -> 6537 bytes modular_citadel/sound/misc/ui_toggleoff.ogg | Bin 0 -> 6934 bytes tgstation.dme | 23 ++++ 73 files changed, 936 insertions(+), 63 deletions(-) create mode 100644 modular_citadel/code/__HELPERS/list2list.dm create mode 100644 modular_citadel/code/_onclick/click.dm create mode 100644 modular_citadel/code/_onclick/hud/screen_objects.dm create mode 100644 modular_citadel/code/_onclick/hud/stamina.dm create mode 100644 modular_citadel/code/_onclick/item_attack.dm create mode 100644 modular_citadel/code/_onclick/other_mobs.dm create mode 100644 modular_citadel/code/datums/status_effects/debuffs.dm create mode 100644 modular_citadel/code/game/machinery/firealarm.dm create mode 100644 modular_citadel/code/game/objects/items.dm create mode 100644 modular_citadel/code/game/objects/structures/beds_chairs/chair.dm create mode 100644 modular_citadel/code/modules/keybindings/bindings_carbon.dm create mode 100644 modular_citadel/code/modules/keybindings/bindings_human.dm create mode 100644 modular_citadel/code/modules/mob/living/carbon/carbon.dm create mode 100644 modular_citadel/code/modules/mob/living/carbon/damage_procs.dm create mode 100644 modular_citadel/code/modules/mob/living/carbon/human/human.dm create mode 100644 modular_citadel/code/modules/mob/living/carbon/human/human_movement.dm create mode 100644 modular_citadel/code/modules/mob/living/carbon/human/species.dm create mode 100644 modular_citadel/code/modules/mob/living/damage_procs.dm create mode 100644 modular_citadel/code/modules/mob/living/living.dm create mode 100644 modular_citadel/code/modules/mob/mob.dm create mode 100644 modular_citadel/code/modules/projectiles/gun.dm create mode 100644 modular_citadel/code/modules/projectiles/projectile/energy.dm create mode 100644 modular_citadel/code/modules/recycling/disposal/bin.dm create mode 100644 modular_citadel/icons/ui/screen_clockwork.dmi create mode 100644 modular_citadel/icons/ui/screen_gen.dmi create mode 100644 modular_citadel/icons/ui/screen_midnight.dmi create mode 100644 modular_citadel/icons/ui/screen_operative.dmi create mode 100644 modular_citadel/icons/ui/screen_plasmafire.dmi create mode 100644 modular_citadel/icons/ui/screen_slimecore.dmi create mode 100644 modular_citadel/sound/misc/sprintactivate.ogg create mode 100644 modular_citadel/sound/misc/sprintdeactivate.ogg create mode 100644 modular_citadel/sound/misc/ui_toggle.ogg create mode 100644 modular_citadel/sound/misc/ui_toggleoff.ogg diff --git a/code/__DEFINES/citadel_defines.dm b/code/__DEFINES/citadel_defines.dm index 97bcd1ff11..99b15362c8 100644 --- a/code/__DEFINES/citadel_defines.dm +++ b/code/__DEFINES/citadel_defines.dm @@ -2,8 +2,16 @@ //Be sure to update the min/max of these if you do change them. //Measurements are in imperial units. Inches, feet, yards, miles. Tsp, tbsp, cups, quarts, gallons, etc -//arousal HUD location +//HUD stuff #define ui_arousal "EAST-1:28,CENTER-4:8"//Below the health doll +#define ui_stamina "EAST-1:28,CENTER:17" // replacing internals button +#define ui_overridden_resist "EAST-3:24,SOUTH+1:7" +#define ui_combat_toggle "EAST-4:22,SOUTH:5" + +//1:1 HUD layout stuff +#define ui_boxcraft "EAST-4:22,SOUTH+1:6" +#define ui_boxarea "EAST-4:6,SOUTH+1:6" +#define ui_boxlang "EAST-5:22,SOUTH+1:6" //organ defines @@ -100,4 +108,10 @@ //Brainslugs #define isborer(A) (istype(A, /mob/living/simple_animal/borer)) -#define CITADEL_MENTOR_OOC_COLOUR "#ad396e" \ No newline at end of file +#define CITADEL_MENTOR_OOC_COLOUR "#ad396e" + +//stamina stuff +#define STAMINA_SOFTCRIT 100 //softcrit for stamina damage. prevents standing up, prevents performing actions that cost stamina, etc, but doesn't force a rest or stop movement +#define STAMINA_CRIT 140 //crit for stamina damage. forces a rest, and stops movement until stamina goes back to stamina softcrit +#define STAMINA_SOFTCRIT_TRADITIONAL 0 //same as STAMINA_SOFTCRIT except for the more traditional health calculations +#define STAMINA_CRIT_TRADITIONAL -40 //ditto, but for STAMINA_CRIT diff --git a/code/_onclick/click.dm b/code/_onclick/click.dm index ce9e1ead82..4c588c96fe 100644 --- a/code/_onclick/click.dm +++ b/code/_onclick/click.dm @@ -75,7 +75,7 @@ if(modifiers["middle"]) MiddleClickOn(A) return - if(modifiers["shift"]) + if(modifiers["shift"] && (client && client.show_popup_menus || modifiers["right"])) //CIT CHANGE - makes shift-click examine use right click instead of left click in combat mode ShiftClickOn(A) return if(modifiers["alt"]) // alt and alt-gr (rightalt) @@ -85,6 +85,10 @@ CtrlClickOn(A) return + if(modifiers["right"]) //CIT CHANGE - allows right clicking to perform actions + RightClickOn(A,params) //CIT CHANGE - ditto + return //CIT CHANGE - ditto + if(incapacitated(ignore_restraints = 1)) return diff --git a/code/_onclick/hud/_defines.dm b/code/_onclick/hud/_defines.dm index 9a325dfa1a..3225252520 100644 --- a/code/_onclick/hud/_defines.dm +++ b/code/_onclick/hud/_defines.dm @@ -82,9 +82,9 @@ #define ui_acti "EAST-3:24,SOUTH:5" #define ui_zonesel "EAST-1:28,SOUTH:5" #define ui_acti_alt "EAST-1:28,SOUTH:5" //alternative intent switcher for when the interface is hidden (F12) -#define ui_crafting "EAST-4:22,SOUTH:5" -#define ui_building "EAST-4:22,SOUTH:21" -#define ui_language_menu "EAST-4:6,SOUTH:21" +#define ui_crafting "EAST-5:20,SOUTH:5"//CIT CHANGE - moves this over one tile to accommodate for combat mode toggle +#define ui_building "EAST-5:20,SOUTH:21"//CIT CHANGE - ditto +#define ui_language_menu "EAST-5:4,SOUTH:21"//CIT CHANGE - ditto #define ui_borg_pull "EAST-2:26,SOUTH+1:7" #define ui_borg_radio "EAST-1:28,SOUTH+1:7" @@ -102,7 +102,7 @@ //Middle right (status indicators) #define ui_healthdoll "EAST-1:28,CENTER-2:13" #define ui_health "EAST-1:28,CENTER-1:15" -#define ui_internal "EAST-1:28,CENTER:17" +#define ui_internal "EAST-1:28,CENTER+1:19"//CIT CHANGE - moves internal icon up a little bit to accommodate for the stamina meter #define ui_mood "EAST-1:28,CENTER-3:10" //borgs diff --git a/code/_onclick/hud/human.dm b/code/_onclick/hud/human.dm index 455a0f20e1..c3288e61fc 100644 --- a/code/_onclick/hud/human.dm +++ b/code/_onclick/hud/human.dm @@ -89,19 +89,29 @@ ..() owner.overlay_fullscreen("see_through_darkness", /obj/screen/fullscreen/see_through_darkness) + var/widescreenlayout = FALSE //CIT CHANGE - adds support for different hud layouts depending on widescreen pref + if(owner.client && owner.client.prefs && owner.client.prefs.widescreenpref) //CIT CHANGE - ditto + widescreenlayout = TRUE // CIT CHANGE - ditto + var/obj/screen/using var/obj/screen/inventory/inv_box using = new /obj/screen/craft using.icon = ui_style + if(!widescreenlayout) // CIT CHANGE + using.screen_loc = ui_boxcraft // CIT CHANGE static_inventory += using using = new/obj/screen/language_menu using.icon = ui_style + if(!widescreenlayout) // CIT CHANGE + using.screen_loc = ui_boxlang // CIT CHANGE static_inventory += using using = new /obj/screen/area_creator using.icon = ui_style + if(!widescreenlayout) // CIT CHANGE + using.screen_loc = ui_boxarea // CIT CHANGE static_inventory += using action_intent = new /obj/screen/act_intent/segmented @@ -109,11 +119,19 @@ static_inventory += action_intent using = new /obj/screen/mov_intent - using.icon = ui_style + using.icon = tg_ui_icon_to_cit_ui(ui_style) // CIT CHANGE - overrides mov intent icon using.icon_state = (mymob.m_intent == MOVE_INTENT_RUN ? "running" : "walking") using.screen_loc = ui_movi static_inventory += using + //CITADEL CHANGES - sprint button + using = new /obj/screen/sprintbutton + using.icon = tg_ui_icon_to_cit_ui(ui_style) + using.icon_state = (owner.sprinting ? "act_sprint_on" : "act_sprint") + using.screen_loc = ui_movi + static_inventory += using + //END OF CITADEL CHANGES + using = new /obj/screen/drop() using.icon = ui_style using.screen_loc = ui_drop_throw @@ -207,9 +225,21 @@ using = new /obj/screen/resist() using.icon = ui_style - using.screen_loc = ui_pull_resist + using.screen_loc = ui_overridden_resist // CIT CHANGE - changes this to overridden resist hotkeybuttons += using + //CIT CHANGES - rest and combat mode buttons + using = new /obj/screen/restbutton() + using.icon = tg_ui_icon_to_cit_ui(ui_style) + using.screen_loc = ui_pull_resist + static_inventory += using + + using = new /obj/screen/combattoggle() + using.icon = tg_ui_icon_to_cit_ui(ui_style) + using.screen_loc = ui_combat_toggle + static_inventory += using + //END OF CIT CHANGES + using = new /obj/screen/human/toggle() using.icon = ui_style using.screen_loc = ui_inventory @@ -280,10 +310,16 @@ healths = new /obj/screen/healths() infodisplay += healths - //CIT CHANGE - adds arousal to hud + //CIT CHANGE - adds arousal and stamina to hud arousal = new /obj/screen/arousal() arousal.icon_state = (owner.canbearoused == 1 ? "arousal0" : "") infodisplay += arousal + + staminas = new /obj/screen/staminas() + infodisplay += staminas + + staminabuffer = new /obj/screen/staminabuffer() + infodisplay += staminabuffer //END OF CIT CHANGES healthdoll = new /obj/screen/healthdoll() diff --git a/code/_onclick/item_attack.dm b/code/_onclick/item_attack.dm index 1fc40d3007..8fc30e95e6 100644 --- a/code/_onclick/item_attack.dm +++ b/code/_onclick/item_attack.dm @@ -54,6 +54,10 @@ if(flags_1 & NOBLUDGEON_1) return + if(user.staminaloss >= STAMINA_SOFTCRIT) // CIT CHANGE - makes it impossible to attack in stamina softcrit + to_chat(user, "You're too exhausted.") // CIT CHANGE - ditto + return // CIT CHANGE - ditto + if(force && user.has_trait(TRAIT_PACIFISM)) to_chat(user, "You don't want to harm other living beings!") return @@ -72,12 +76,17 @@ add_logs(user, M, "attacked", src.name, "(INTENT: [uppertext(user.a_intent)]) (DAMTYPE: [uppertext(damtype)])") add_fingerprint(user) + user.adjustStaminaLossBuffered(getweight())//CIT CHANGE - makes attacking things cause stamina loss //the equivalent of the standard version of attack() but for object targets. /obj/item/proc/attack_obj(obj/O, mob/living/user) SendSignal(COMSIG_ITEM_ATTACK_OBJ, O, user) if(flags_1 & NOBLUDGEON_1) return + if(user.staminaloss >= STAMINA_SOFTCRIT) // CIT CHANGE - makes it impossible to attack in stamina softcrit + to_chat(user, "You're too exhausted.") // CIT CHANGE - ditto + return // CIT CHANGE - ditto + user.adjustStaminaLossBuffered(getweight()*1.2)//CIT CHANGE - makes attacking things cause stamina loss user.changeNext_move(CLICK_CD_MELEE) user.do_attack_animation(O) O.attacked_by(src, user) @@ -94,7 +103,16 @@ /mob/living/attacked_by(obj/item/I, mob/living/user) send_item_attack_message(I, user) if(I.force) - apply_damage(I.force, I.damtype) + //CIT CHANGES START HERE - combatmode and resting checks + var/totitemdamage = I.force + if(iscarbon(user)) + var/mob/living/carbon/tempcarb = user + if(!tempcarb.combatmode) + totitemdamage *= 0.5 + if(user.resting) + totitemdamage *= 0.5 + //CIT CHANGES END HERE + apply_damage(totitemdamage, I.damtype) //CIT CHANGE - replaces I.force with totitemdamage if(I.damtype == BRUTE) if(prob(33)) I.add_mob_blood(src) diff --git a/code/datums/status_effects/buffs.dm b/code/datums/status_effects/buffs.dm index 4457ff3ebd..f968f860b0 100644 --- a/code/datums/status_effects/buffs.dm +++ b/code/datums/status_effects/buffs.dm @@ -295,7 +295,7 @@ owner.toxloss *= 10 owner.oxyloss *= 10 owner.cloneloss *= 10 - owner.staminaloss *= 10 + owner.staminaloss += -10 // CIT CHANGE - makes blooddrunk status effect not exhaust you owner.updatehealth() last_health = owner.health last_bruteloss = owner.getBruteLoss() @@ -353,7 +353,7 @@ var/new_staminaloss = owner.getStaminaLoss() if(new_staminaloss < last_staminaloss) - var/heal_amount = (new_staminaloss - last_staminaloss) * 10 + var/heal_amount = -5 // CIT CHANGE - makes blood drunk status effect not exhaust you owner.adjustStaminaLoss(heal_amount, updating_health = FALSE) new_staminaloss = owner.getStaminaLoss() needs_health_update = TRUE diff --git a/code/game/machinery/dance_machine.dm b/code/game/machinery/dance_machine.dm index ea9eae906a..bd41e3aa3a 100644 --- a/code/game/machinery/dance_machine.dm +++ b/code/game/machinery/dance_machine.dm @@ -400,15 +400,16 @@ /obj/machinery/disco/proc/dance4(var/mob/living/M) - var/speed = rand(1,3) + //var/speed = rand(1,3) // CIT CHANGE set waitfor = 0 - var/time = 30 + /*var/time = 30 CIT CHANGE -- replaces dance4 with rapid spinning so that disco balls dont make weird shit happen while(time) sleep(speed) for(var/i in 1 to speed) M.setDir(pick(GLOB.cardinals)) M.lay_down(TRUE) - time-- + time--*/ + M.SpinAnimation(1,30) /obj/machinery/disco/proc/dance5(var/mob/living/M) animate(M, transform = matrix(180, MATRIX_ROTATE), time = 1, loop = 0) diff --git a/code/game/machinery/porta_turret/portable_turret.dm b/code/game/machinery/porta_turret/portable_turret.dm index dffb4650e8..3fb8110c9f 100644 --- a/code/game/machinery/porta_turret/portable_turret.dm +++ b/code/game/machinery/porta_turret/portable_turret.dm @@ -389,7 +389,7 @@ if(iscarbon(A)) var/mob/living/carbon/C = A //If not emagged, only target non downed carbons - if(mode != TURRET_LETHAL && (C.stat || C.handcuffed || C.lying)) + if(mode != TURRET_LETHAL && (C.stat || C.handcuffed || C.recoveringstam))//CIT CHANGE - replaces check for lying with check for recoveringstam continue //If emagged, target all but dead carbons diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index aeb7acb651..b5c4e5bfb8 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -510,12 +510,18 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE) to_chat(user, "You cannot locate any organic eyes on this brain!") return + if(user.staminaloss >= STAMINA_SOFTCRIT)//CIT CHANGE - makes eyestabbing impossible if you're in stamina softcrit + to_chat(user, "You're too exhausted for that.")//CIT CHANGE - ditto + return //CIT CHANGE - ditto + src.add_fingerprint(user) playsound(loc, src.hitsound, 30, 1, -1) user.do_attack_animation(M) + user.adjustStaminaLossBuffered(10)//CIT CHANGE - makes eyestabbing cost stamina + if(M != user) M.visible_message("[user] has stabbed [M] in the eye with [src]!", \ "[user] stabs you in the eye with [src]!") diff --git a/code/game/objects/items/devices/dogborg_sleeper.dm b/code/game/objects/items/devices/dogborg_sleeper.dm index 217786f142..1d9c669fc9 100644 --- a/code/game/objects/items/devices/dogborg_sleeper.dm +++ b/code/game/objects/items/devices/dogborg_sleeper.dm @@ -497,4 +497,4 @@ user.visible_message("[hound.name]'s garbage processor groans lightly as [trashman] slips inside.", "Your garbage compactor groans lightly as [trashman] slips inside.") playsound(hound, 'sound/effects/bin_close.ogg', 80, 1) return - return \ No newline at end of file + return diff --git a/code/game/objects/items/melee/misc.dm b/code/game/objects/items/melee/misc.dm index 670715dcd5..7d74a00ce6 100644 --- a/code/game/objects/items/melee/misc.dm +++ b/code/game/objects/items/melee/misc.dm @@ -106,6 +106,10 @@ if(!on) return ..() + if(user.staminaloss >= STAMINA_SOFTCRIT)//CIT CHANGE - makes batons unusuable in stamina softcrit + to_chat(user, "You're too exhausted for that.")//CIT CHANGE - ditto + return //CIT CHANGE - ditto + add_fingerprint(user) if((user.has_trait(TRAIT_CLUMSY)) && prob(50)) to_chat(user, "You club yourself over the head.") @@ -145,6 +149,7 @@ else target.LAssailant = user cooldown = world.time + 40 + user.adjustStaminaLossBuffered(getweight())//CIT CHANGE - makes swinging batons cost stamina /obj/item/melee/classic_baton/telescopic name = "telescopic baton" diff --git a/code/game/objects/items/stunbaton.dm b/code/game/objects/items/stunbaton.dm index 9f42a7c370..6e88a61349 100644 --- a/code/game/objects/items/stunbaton.dm +++ b/code/game/objects/items/stunbaton.dm @@ -115,6 +115,10 @@ deductcharge(hitcost) return + if(user.staminaloss >= STAMINA_SOFTCRIT)//CIT CHANGE - makes it impossible to baton in stamina softcrit + to_chat(user, "You're too exhausted for that.")//CIT CHANGE - ditto + return //CIT CHANGE - ditto + if(iscyborg(M)) ..() return @@ -129,6 +133,7 @@ if(status) if(baton_stun(M, user)) user.do_attack_animation(M) + user.adjustStaminaLossBuffered(getweight())//CIT CHANGE - makes stunbatonning others cost stamina return else M.visible_message("[user] has prodded [M] with [src]. Luckily it was off.", \ @@ -154,6 +159,7 @@ return 0 L.Knockdown(stunforce) + L.adjustStaminaLoss(stunforce*0.1)//CIT CHANGE - makes stunbatons deal extra staminaloss. Todo: make this also deal pain when pain gets implemented. L.apply_effect(STUTTER, stunforce) if(user) L.lastattacker = user.real_name diff --git a/code/game/objects/items/weaponry.dm b/code/game/objects/items/weaponry.dm index 2d82c3829b..713f5761c0 100644 --- a/code/game/objects/items/weaponry.dm +++ b/code/game/objects/items/weaponry.dm @@ -101,6 +101,7 @@ var/mob/living/carbon/human/H = loc loc.layer = LARGE_MOB_LAYER //NO HIDING BEHIND PLANTS FOR YOU, DICKWEED (HA GET IT, BECAUSE WEEDS ARE PLANTS) H.bleedsuppress = TRUE //AND WE WON'T BLEED OUT LIKE COWARDS + H.adjustStaminaLoss(-5) //CIT CHANGE - AND MAY HE NEVER SUCCUMB TO EXHAUSTION else if(!admin_spawned) qdel(src) diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm index c565847c18..dfc39a9f28 100644 --- a/code/modules/client/preferences.dm +++ b/code/modules/client/preferences.dm @@ -400,6 +400,8 @@ GLOBAL_LIST_EMPTY(preferences_datums) dat += "Widescreen: [widescreenpref ? "Enabled ([CONFIG_GET(string/default_view)])" : "Disabled (15x15)"]
" + dat += "Auto stand: [autostand ? "Enabled" : "Disabled"]
" + dat += "Screen Shake: [(screenshake==100) ? "Full" : ((screenshake==0) ? "None" : "[screenshake]")]
" if (!user.client.prefs.screenshake==0) @@ -1699,6 +1701,8 @@ GLOBAL_LIST_EMPTY(preferences_datums) if("widescreenpref") widescreenpref = !widescreenpref user.client.change_view(CONFIG_GET(string/default_view)) + if("autostand") + autostand = !autostand if ("screenshake") var/desiredshake = input(user, "Set the amount of screenshake you want. \n(0 = disabled, 100 = full, 200 = maximum.)", "Character Preference", screenshake) as null|num if (!isnull(desiredshake)) diff --git a/code/modules/client/preferences_savefile.dm b/code/modules/client/preferences_savefile.dm index 9b776c48b2..8bebf460e6 100644 --- a/code/modules/client/preferences_savefile.dm +++ b/code/modules/client/preferences_savefile.dm @@ -141,6 +141,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car S["screenshake"] >> screenshake S["damagescreenshake"] >> damagescreenshake S["widescreenpref"] >> widescreenpref + S["autostand"] >> autostand //try to fix any outdated data if necessary if(needs_update >= 0) @@ -171,6 +172,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car screenshake = sanitize_integer(screenshake, 0, 800, initial(screenshake)) damagescreenshake = sanitize_integer(damagescreenshake, 0, 2, initial(damagescreenshake)) widescreenpref = sanitize_integer(widescreenpref, 0, 1, initial(widescreenpref)) + autostand = sanitize_integer(autostand, 0, 1, initial(autostand)) return 1 @@ -219,6 +221,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car WRITE_FILE(S["damagescreenshake"], damagescreenshake) WRITE_FILE(S["arousable"], arousable) WRITE_FILE(S["widescreenpref"], widescreenpref) + WRITE_FILE(S["autostand"], autostand) return 1 diff --git a/code/modules/mining/equipment/kinetic_crusher.dm b/code/modules/mining/equipment/kinetic_crusher.dm index 2843c22038..5b86a2d340 100644 --- a/code/modules/mining/equipment/kinetic_crusher.dm +++ b/code/modules/mining/equipment/kinetic_crusher.dm @@ -115,6 +115,9 @@ C.total_damage += detonation_damage L.apply_damage(detonation_damage, BRUTE, blocked = def_check) + if(user && lavaland_equipment_pressure_check(get_turf(user))) //CIT CHANGE - makes sure below only happens in low pressure environments + user.adjustStaminaLoss(-13)//CIT CHANGE - makes crushers heal stamina + /obj/item/twohanded/required/kinetic_crusher/proc/Recharge() if(!charged) charged = TRUE diff --git a/code/modules/mob/inventory.dm b/code/modules/mob/inventory.dm index acef80b8ba..1e7f2210cf 100644 --- a/code/modules/mob/inventory.dm +++ b/code/modules/mob/inventory.dm @@ -197,7 +197,7 @@ /mob/proc/put_in_hand_check(obj/item/I) - if(lying && !(I.flags_1&ABSTRACT_1)) + if(incapacitated() && !(I.flags_1&ABSTRACT_1)) //Cit change - Changes lying to incapacitated so that it's plausible to pick things up while on the ground return FALSE if(!istype(I)) return FALSE diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm index 8a73f8812e..ac905ff827 100644 --- a/code/modules/mob/living/carbon/carbon.dm +++ b/code/modules/mob/living/carbon/carbon.dm @@ -148,6 +148,12 @@ if(istype(target, /obj/screen)) return +//CIT CHANGES - makes it impossible to throw while in stamina softcrit + if(staminaloss >= STAMINA_SOFTCRIT) + to_chat(src, "You're too exhausted.") + return +//END OF CIT CHANGES + var/atom/movable/thrown_thing var/obj/item/I = src.get_active_held_item() @@ -159,6 +165,7 @@ stop_pulling() if(has_trait(TRAIT_PACIFISM)) to_chat(src, "You gently let go of [throwable_mob].") + adjustStaminaLossBuffered(25)//CIT CHANGE - throwing an entire person shall be very tiring var/turf/start_T = get_turf(loc) //Get the start and target tile for the descriptors var/turf/end_T = get_turf(target) if(start_T && end_T) @@ -174,6 +181,8 @@ to_chat(src, "You set [I] down gently on the ground.") return + adjustStaminaLossBuffered(I.getweight()*2)//CIT CHANGE - throwing items shall be more tiring than swinging em. Doubly so. + if(thrown_thing) visible_message("[src] has thrown [thrown_thing].") add_logs(src, thrown_thing, "has thrown") @@ -399,12 +408,20 @@ if(!I || (I.flags_1 & (NODROP_1|ABSTRACT_1))) return - dropItemToGround(I) + //dropItemToGround(I) CIT CHANGE - makes it so the item doesn't drop if the modifier rolls above 100 var/modifier = 0 if(has_trait(TRAIT_CLUMSY)) modifier -= 40 //Clumsy people are more likely to hit themselves -Honk! + //CIT CHANGES START HERE + else if(combatmode) + modifier += 50 + + if(modifier < 100) + dropItemToGround(I) + //END OF CIT CHANGES + switch(rand(1,100)+modifier) //91-100=Nothing special happens if(-INFINITY to 0) //attack yourself I.attack(src,src) diff --git a/code/modules/mob/living/carbon/carbon_defense.dm b/code/modules/mob/living/carbon/carbon_defense.dm index 6192d9ad44..9b23204d98 100644 --- a/code/modules/mob/living/carbon/carbon_defense.dm +++ b/code/modules/mob/living/carbon/carbon_defense.dm @@ -77,7 +77,18 @@ affecting = bodyparts[1] send_item_attack_message(I, user, affecting.name) if(I.force) - apply_damage(I.force, I.damtype, affecting) + //CIT CHANGES START HERE - combatmode and resting checks + var/totitemdamage = I.force + if(iscarbon(user)) + var/mob/living/carbon/tempcarb = user + if(!tempcarb.combatmode) + totitemdamage *= 0.5 + if(user.resting) + totitemdamage *= 0.5 + if(!combatmode) + totitemdamage *= 1.5 + //CIT CHANGES END HERE + apply_damage(totitemdamage, I.damtype, affecting) //CIT CHANGE - replaces I.force with totitemdamage if(I.damtype == BRUTE && affecting.status == BODYPART_ORGANIC) if(prob(33)) I.add_mob_blood(src) diff --git a/code/modules/mob/living/carbon/damage_procs.dm b/code/modules/mob/living/carbon/damage_procs.dm index b437b6a4f2..715b4a2ed9 100644 --- a/code/modules/mob/living/carbon/damage_procs.dm +++ b/code/modules/mob/living/carbon/damage_procs.dm @@ -186,16 +186,16 @@ if(status_flags & GODMODE) return 0 staminaloss = CLAMP(staminaloss + amount, 0, maxHealth*2) - if(updating_stamina) - update_stamina() + //if(updating_stamina) CIT CHANGE - makes staminaloss changes always call update_stamina + update_stamina() /mob/living/carbon/setStaminaLoss(amount, updating_stamina = 1) if(status_flags & GODMODE) return 0 staminaloss = amount - if(updating_stamina) - update_stamina() + //if(updating_stamina) CIT CHANGE - makes staminaloss changes always call update_stamina + update_stamina() /mob/living/carbon/getBrainLoss() . = 0 @@ -237,4 +237,3 @@ if(B) var/adjusted_amount = amount - B.get_brain_damage() B.adjust_brain_damage(adjusted_amount, null) - diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index 8d8eead442..2bcb1d5189 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -778,7 +778,7 @@ return else if(hud_used.healths) - var/health_amount = health - staminaloss + var/health_amount = health - CLAMP(staminaloss-50, 0, 80)//CIT CHANGE - makes staminaloss have less of an impact on the health hud if(..(health_amount)) //not dead switch(hal_screwyhud) if(SCREWYHUD_CRIT) diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm index 8fdaa0a4f3..c60eafbad2 100644 --- a/code/modules/mob/living/carbon/human/species.dm +++ b/code/modules/mob/living/carbon/human/species.dm @@ -1290,12 +1290,13 @@ GLOBAL_LIST_EMPTY(roundstart_races) for(var/obj/item/I in H.held_items) if(I.flags_2 & SLOWS_WHILE_IN_HAND_2) . += I.slowdown - var/health_deficiency = (100 - H.health + H.staminaloss) + var/stambufferinfluence = (H.bufferedstam*(100/H.stambuffer))*0.2 //CIT CHANGE - makes stamina buffer influence movedelay + var/health_deficiency = ((100 + stambufferinfluence) - H.health + (H.staminaloss*0.75))//CIT CHANGE - reduces the impact of staminaloss on movement speed and makes stamina buffer influence movedelay if(health_deficiency >= 40) if(flight) - . += (health_deficiency / 75) + . += ((health_deficiency-39) / 75) // CIT CHANGE - adds -39 to health deficiency penalty to make the transition to low health movement a little less jarring else - . += (health_deficiency / 25) + . += ((health_deficiency-39) / 25) // CIT CHANGE - ditto GET_COMPONENT_FROM(mood, /datum/component/mood, H) if(mood && !flight) //How can depression slow you down if you can just fly away from your problems? @@ -1356,6 +1357,9 @@ GLOBAL_LIST_EMPTY(roundstart_races) if(user.has_trait(TRAIT_PACIFISM)) to_chat(user, "You don't want to harm [target]!") return FALSE + if(user.staminaloss >= STAMINA_SOFTCRIT) //CITADEL CHANGE - makes it impossible to punch while in stamina softcrit + to_chat(user, "You're too exhausted.") //CITADEL CHANGE - ditto + return FALSE //CITADEL CHANGE - ditto if(target.check_block()) target.visible_message("[target] blocks [user]'s attack!") return FALSE @@ -1377,8 +1381,19 @@ GLOBAL_LIST_EMPTY(roundstart_races) else user.do_attack_animation(target, ATTACK_EFFECT_PUNCH) + user.adjustStaminaLossBuffered(5) //CITADEL CHANGE - makes punching cause staminaloss + var/damage = rand(user.dna.species.punchdamagelow, user.dna.species.punchdamagehigh) + //CITADEL CHANGES - makes resting and disabled combat mode reduce punch damage, makes being out of combat mode result in you taking more damage + if(!target.combatmode && damage < user.dna.species.punchstunthreshold) + damage = user.dna.species.punchstunthreshold - 1 + if(user.resting) + damage *= 0.5 + if(!user.combatmode) + damage *= 0.25 + //END OF CITADEL CHANGES + var/obj/item/bodypart/affecting = target.get_bodypart(ran_zone(user.zone_selected)) if(!damage || !affecting) @@ -1420,6 +1435,9 @@ GLOBAL_LIST_EMPTY(roundstart_races) "You hear a slap.") target.endTailWag() return FALSE + else if(user.staminaloss >= STAMINA_SOFTCRIT) + to_chat(user, "You're too exhausted.") + return FALSE else if(target.check_block()) //END EDIT target.visible_message("[target] blocks [user]'s disarm attempt!") return 0 @@ -1428,22 +1446,31 @@ GLOBAL_LIST_EMPTY(roundstart_races) else user.do_attack_animation(target, ATTACK_EFFECT_DISARM) + user.adjustStaminaLossBuffered(3) //CITADEL CHANGE - makes disarmspam cause staminaloss + if(target.w_uniform) target.w_uniform.add_fingerprint(user) - var/randomized_zone = ran_zone(user.zone_selected) + //var/randomized_zone = ran_zone(user.zone_selected) CIT CHANGE - comments out to prevent compiling errors target.SendSignal(COMSIG_HUMAN_DISARM_HIT, user, user.zone_selected) - var/obj/item/bodypart/affecting = target.get_bodypart(randomized_zone) + //var/obj/item/bodypart/affecting = target.get_bodypart(randomized_zone) CIT CHANGE - comments this out to prevent compile errors due to the below commented out bit var/randn = rand(1, 100) - if(randn <= 25) + /*if(randn <= 25) CITADEL CHANGE - moves disarm push attempts to right click playsound(target, 'sound/weapons/thudswoosh.ogg', 50, 1, -1) target.visible_message("[user] has pushed [target]!", "[user] has pushed [target]!", null, COMBAT_MESSAGE_RANGE) target.apply_effect(40, KNOCKDOWN, target.run_armor_check(affecting, "melee", "Your armor prevents your fall!", "Your armor softens your fall!")) target.forcesay(GLOB.hit_appends) add_logs(user, target, "disarmed", " pushing them to the ground") - return + return*/ - if(randn <= 60) + if(!target.combatmode) // CITADEL CHANGE + randn += -10 //CITADEL CHANGE - being out of combat mode makes it easier for you to get disarmed + if(user.resting) //CITADEL CHANGE + randn += 60 //CITADEL CHANGE - No kosher disarming if you're resting + if(!user.combatmode) //CITADEL CHANGE + randn += 25 //CITADEL CHANGE - Makes it harder to disarm outside of combat mode + + if(randn <= 35)//CIT CHANGE - changes this back to a 35% chance to accomodate for the above being commented out in favor of right-click pushing var/obj/item/I = null if(target.pulling) target.visible_message("[user] has broken [target]'s grip on [target.pulling]!") @@ -1516,8 +1543,21 @@ GLOBAL_LIST_EMPTY(roundstart_races) armor_block = min(90,armor_block) //cap damage reduction at 90% var/Iforce = I.force //to avoid runtimes on the forcesay checks at the bottom. Some items might delete themselves if you drop them. (stunning yourself, ninja swords) + //CIT CHANGES START HERE - combatmode and resting checks + var/totitemdamage = I.force + if(iscarbon(user)) + var/mob/living/carbon/tempcarb = user + if(!tempcarb.combatmode) + totitemdamage *= 0.5 + if(user.resting) + totitemdamage *= 0.5 + if(istype(H)) + if(!H.combatmode) + totitemdamage *= 1.5 + //CIT CHANGES END HERE + var/weakness = H.check_weakness(I, user) - apply_damage(I.force * weakness, I.damtype, def_zone, armor_block, H) + apply_damage(totitemdamage * weakness, I.damtype, def_zone, armor_block, H) //CIT CHANGE - replaces I.force with totitemdamage H.send_item_attack_message(I, user, hit_area) diff --git a/code/modules/mob/living/carbon/life.dm b/code/modules/mob/living/carbon/life.dm index fec5ae0e63..dc939f8fc1 100644 --- a/code/modules/mob/living/carbon/life.dm +++ b/code/modules/mob/living/carbon/life.dm @@ -331,8 +331,17 @@ //this updates all special effects: stun, sleeping, knockdown, druggy, stuttering, etc.. /mob/living/carbon/handle_status_effects() ..() - if(staminaloss) - adjustStaminaLoss(-3) + if(staminaloss && !combatmode && !aimingdownsights)//CIT CHANGE - prevents stamina regen while combat mode is active + adjustStaminaLoss(resting ? (recoveringstam ? -7.5 : -3) : -1.5)//CIT CHANGE - decreases adjuststaminaloss to stop stamina damage from being such a joke + else if(aimingdownsights)//CIT CHANGE - makes aiming down sights drain stamina + adjustStaminaLoss(resting ? 0.2 : 0.5)//CIT CHANGE - ditto. Raw spaghetti + + //CIT CHANGES START HERE. STAMINA BUFFER STUFF + if(bufferedstam && world.time > stambufferregentime) + var/drainrate = max((bufferedstam*(bufferedstam/(5)))*0.1,1) + bufferedstam = max(bufferedstam - drainrate, 0) + adjustStaminaLoss(drainrate*0.5) + //END OF CIT CHANGES var/restingpwr = 1 + 4 * resting diff --git a/code/modules/mob/living/carbon/monkey/combat.dm b/code/modules/mob/living/carbon/monkey/combat.dm index 79c9613906..ec419ef94c 100644 --- a/code/modules/mob/living/carbon/monkey/combat.dm +++ b/code/modules/mob/living/carbon/monkey/combat.dm @@ -141,7 +141,7 @@ // Really no idea what needs to be returned but everything else is TRUE return TRUE - if(on_fire || buckled || restrained()) + if(on_fire || buckled || restrained() || (resting && canmove)) //CIT CHANGE - adds (resting && canmove) to make monkey ai attempt to resist out of resting if(!resisting && prob(MONKEY_RESIST_PROB)) resisting = TRUE walk_to(src,0) diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index 63f5be8ec8..ad9d76b6f4 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -320,7 +320,7 @@ death() /mob/living/incapacitated(ignore_restraints, ignore_grab) - if(stat || IsUnconscious() || IsStun() || IsKnockdown() || (!ignore_restraints && restrained(ignore_grab))) + if(stat || IsUnconscious() || IsStun() || IsKnockdown() || recoveringstam || (!ignore_restraints && restrained(ignore_grab))) // CIT CHANGE - adds recoveringstam check here return 1 /mob/living/proc/InCritical() @@ -377,6 +377,7 @@ /mob/proc/get_contents() +/*CIT CHANGE - comments out lay_down proc to be modified in modular_citadel /mob/living/proc/lay_down() set name = "Rest" set category = "IC" @@ -384,6 +385,7 @@ resting = !resting to_chat(src, "You are now [resting ? "resting" : "getting up"].") update_canmove() +*/ //Recursive function to find everything a mob is holding. /mob/living/get_contents(obj/item/storage/Storage = null) @@ -643,9 +645,9 @@ if(buckled && last_special <= world.time) resist_buckle() - // climbing out of a gut + // CIT CHANGE - climbing out of a gut if(attempt_vr(src,"vore_process_resist",args)) return TRUE - + //Breaking out of a container (Locker, sleeper, cryo...) else if(isobj(loc)) var/obj/C = loc @@ -662,6 +664,8 @@ else if(canmove) if(on_fire) resist_fire() //stop, drop, and roll + else if(resting) //cit change - allows resisting out of resting + resist_a_rest() // ditto else if(last_special <= world.time) resist_restraints() //trying to remove cuffs. @@ -865,6 +869,7 @@ return FALSE return TRUE +/*CIT CHANGE - comments out update_stamina to be modified in modular_citadel /mob/living/carbon/proc/update_stamina() if(staminaloss) var/total_health = (health - staminaloss) @@ -873,6 +878,7 @@ Knockdown(100) setStaminaLoss(health - 2) update_health_hud() +*/ /mob/living/carbon/alien/update_stamina() return @@ -1027,25 +1033,32 @@ var/ko = IsKnockdown() || IsUnconscious() || (stat && (stat != SOFT_CRIT || pulledby)) || (has_trait(TRAIT_FAKEDEATH)) var/move_and_fall = stat == SOFT_CRIT && !pulledby var/chokehold = pulledby && pulledby.grab_state >= GRAB_NECK + var/pinned = resting && pulledby && pulledby.grab_state >= GRAB_AGGRESSIVE // Cit change - adds pinning for aggressive-grabbing people on the ground var/buckle_lying = !(buckled && !buckled.buckle_lying) var/has_legs = get_num_legs() var/has_arms = get_num_arms() var/ignore_legs = get_leg_ignore() - if(ko || resting || move_and_fall || IsStun() || chokehold) + if(ko || move_and_fall || IsStun() || chokehold) // Cit change - makes resting not force you to drop everything drop_all_held_items() unset_machine() if(pulling) stop_pulling() + else if(resting) //CIT CHANGE - makes resting make you stop pulling and interacting with machines + unset_machine() //CIT CHANGE - Ditto! + if(pulling) //CIT CHANGE - Ditto. + stop_pulling() //CIT CHANGE - Ditto... else if(has_legs || ignore_legs) lying = 0 if(buckled) lying = 90*buckle_lying else if(!lying) if(resting) - fall() + lying = pick(90, 270) // Cit change - makes resting not force you to drop your held items + if(has_gravity()) // Cit change - Ditto + playsound(src, "bodyfall", 50, 1) // Cit change - Ditto! else if(ko || move_and_fall || (!has_legs && !ignore_legs) || chokehold) fall(forced = 1) - canmove = !(ko || resting || IsStun() || IsFrozen() || chokehold || buckled || (!has_legs && !ignore_legs && !has_arms)) + canmove = !(ko || recoveringstam || pinned || IsStun() || IsFrozen() || chokehold || buckled || (!has_legs && !ignore_legs && !has_arms)) //Cit change - makes it plausible to move while resting, adds pinning and stamina crit density = !lying if(lying) if(layer == initial(layer)) //to avoid special cases like hiding larvas. @@ -1058,6 +1071,8 @@ if(client) client.move_delay = world.time + movement_delay() lying_prev = lying + if(canmove && !intentionalresting && iscarbon(src) && client && client.prefs && client.prefs.autostand)//CIT CHANGE - adds autostanding as a preference + resist_a_rest(TRUE)//CIT CHANGE - ditto return canmove /mob/living/proc/AddAbility(obj/effect/proc_holder/A) diff --git a/code/modules/mob/living/simple_animal/bot/ed209bot.dm b/code/modules/mob/living/simple_animal/bot/ed209bot.dm index d265d19cb2..9b4386c727 100644 --- a/code/modules/mob/living/simple_animal/bot/ed209bot.dm +++ b/code/modules/mob/living/simple_animal/bot/ed209bot.dm @@ -274,7 +274,7 @@ Auto Patrol[]"}, if(BOT_PREP_ARREST) // preparing to arrest target // see if he got away. If he's no no longer adjacent or inside a closet or about to get up, we hunt again. - if(!Adjacent(target) || !isturf(target.loc) || target.AmountKnockdown() < 40) + if(!Adjacent(target) || !isturf(target.loc) || !target.recoveringstam || target.staminaloss <= 120) // CIT CHANGE - replaces amountknockdown with recoveringstam and staminaloss checks back_to_hunt() return @@ -301,7 +301,7 @@ Auto Patrol[]"}, back_to_idle() return - if(!Adjacent(target) || !isturf(target.loc) || (target.loc != target_lastloc && target.AmountKnockdown() < 40)) //if he's changed loc and about to get up or not adjacent or got into a closet, we prep arrest again. + if(!Adjacent(target) || !isturf(target.loc) || (target.loc != target_lastloc && !target.recoveringstam && target.staminaloss <= 120)) //if he's changed loc and about to get up or not adjacent or got into a closet, we prep arrest again. CIT CHANGE - replaces amountknockdown with recoveringstam and staminaloss checks back_to_hunt() return else @@ -523,7 +523,7 @@ Auto Patrol[]"}, return if(iscarbon(A)) var/mob/living/carbon/C = A - if(!C.IsStun() || arrest_type) + if(C.canmove || arrest_type) // CIT CHANGE - makes sentient ed209s check for canmove rather than !isstun. stun_attack(A) else if(C.canBeHandcuffed() && !C.handcuffed) cuff(A) diff --git a/code/modules/mob/living/simple_animal/bot/secbot.dm b/code/modules/mob/living/simple_animal/bot/secbot.dm index 68b82abb0e..1754a20b94 100644 --- a/code/modules/mob/living/simple_animal/bot/secbot.dm +++ b/code/modules/mob/living/simple_animal/bot/secbot.dm @@ -203,7 +203,7 @@ Auto Patrol: []"}, return if(iscarbon(A)) var/mob/living/carbon/C = A - if(!C.IsStun() || arrest_type) + if(C.canmove || arrest_type) // CIT CHANGE - makes sentient secbots check for canmove rather than !isstun. stun_attack(A) else if(C.canBeHandcuffed() && !C.handcuffed) cuff(A) @@ -305,7 +305,7 @@ Auto Patrol: []"}, if(BOT_PREP_ARREST) // preparing to arrest target // see if he got away. If he's no no longer adjacent or inside a closet or about to get up, we hunt again. - if( !Adjacent(target) || !isturf(target.loc) || target.AmountKnockdown() < 40) + if( !Adjacent(target) || !isturf(target.loc) || target.staminaloss <= 120 || !target.recoveringstam) //CIT CHANGE - replaces amountknockdown with checks for stamina so secbots dont run into an infinite loop back_to_hunt() return @@ -332,7 +332,7 @@ Auto Patrol: []"}, back_to_idle() return - if(!Adjacent(target) || !isturf(target.loc) || (target.loc != target_lastloc && target.AmountKnockdown() < 40)) //if he's changed loc and about to get up or not adjacent or got into a closet, we prep arrest again. + if(!Adjacent(target) || !isturf(target.loc) || (target.loc != target_lastloc && !target.recoveringstam && target.staminaloss <= 120)) //if he's changed loc and about to get up or not adjacent or got into a closet, we prep arrest again. CIT CHANGE - replaces amountknockdown with recoveringstam and staminaloss check back_to_hunt() return else //Try arresting again if the target escapes. diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index 7deed01390..f5e5d32428 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -365,6 +365,10 @@ I.attack_self(src) update_inv_hands() + if(!I)//CIT CHANGE - allows "using" empty hands + use_that_empty_hand() //CIT CHANGE - ditto + update_inv_hands() // CIT CHANGE - ditto. + /mob/verb/memory() set name = "Notes" set category = "IC" diff --git a/code/modules/mob/transform_procs.dm b/code/modules/mob/transform_procs.dm index 240c4edd9f..9178a2341b 100644 --- a/code/modules/mob/transform_procs.dm +++ b/code/modules/mob/transform_procs.dm @@ -76,6 +76,7 @@ O.setCloneLoss(getCloneLoss(), 0) O.adjustFireLoss(getFireLoss(), 0) O.setBrainLoss(getBrainLoss(), 0) + O.adjustStaminaLoss(getStaminaLoss(), 0)//CIT CHANGE - makes monkey transformations inherit stamina O.updatehealth() O.radiation = radiation @@ -233,6 +234,7 @@ O.setCloneLoss(getCloneLoss(), 0) O.adjustFireLoss(getFireLoss(), 0) O.setBrainLoss(getBrainLoss(), 0) + O.adjustStaminaLoss(getStaminaLoss(), 0)//CIT CHANGE - makes monkey transformations inherit stamina O.updatehealth() O.radiation = radiation diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm index afd14e5dcf..7b7daadc18 100644 --- a/code/modules/projectiles/gun.dm +++ b/code/modules/projectiles/gun.dm @@ -112,6 +112,9 @@ if(recoil) shake_camera(user, recoil + 1, recoil) + if(iscarbon(user)) //CIT CHANGE - makes gun recoil cause staminaloss + user.adjustStaminaLossBuffered(getstamcost(user)*(firing_burst && burst_size >= 2 ? 1/burst_size : 1)) //CIT CHANGE - ditto + if(suppressed) playsound(user, fire_sound, 10, 1) else @@ -170,6 +173,9 @@ //DUAL (or more!) WIELDING var/bonus_spread = 0 var/loop_counter = 0 + + bonus_spread += getinaccuracy(user) //CIT CHANGE - adds bonus spread while not aiming + if(ishuman(user) && user.a_intent == INTENT_HARM) var/mob/living/carbon/human/H = user for(var/obj/item/gun/G in H.held_items) diff --git a/code/modules/projectiles/guns/ballistic/shotgun.dm b/code/modules/projectiles/guns/ballistic/shotgun.dm index 315178368d..723e1b910c 100644 --- a/code/modules/projectiles/guns/ballistic/shotgun.dm +++ b/code/modules/projectiles/guns/ballistic/shotgun.dm @@ -37,8 +37,13 @@ /obj/item/gun/ballistic/shotgun/attack_self(mob/living/user) if(recentpump > world.time) return + if(istype(user) && user.staminaloss >= STAMINA_SOFTCRIT)//CIT CHANGE - makes pumping shotguns impossible in stamina softcrit + to_chat(user, "You're too exhausted for that.")//CIT CHANGE - ditto + return//CIT CHANGE - ditto pump(user) recentpump = world.time + 10 + if(istype(user))//CIT CHANGE - makes pumping shotguns cost a lil bit of stamina. + user.adjustStaminaLossBuffered(5) //CIT CHANGE - DITTO. make this scale inversely to the strength stat when stats/skills are added return /obj/item/gun/ballistic/shotgun/blow_up(mob/user) diff --git a/code/modules/projectiles/projectile.dm b/code/modules/projectiles/projectile.dm index e7a87e0132..db43917d6c 100644 --- a/code/modules/projectiles/projectile.dm +++ b/code/modules/projectiles/projectile.dm @@ -462,6 +462,13 @@ xo = targloc.x - curloc.x setAngle(Get_Angle(src, targloc)) + //CIT CHANGES START HERE - makes it so laying down makes you unable to shoot through most objects + if(iscarbon(source)) + var/mob/living/carbon/checklad = source + if(istype(checklad) && checklad.resting) + pass_flags = 0 + //END OF CIT CHANGES + if(isliving(source) && params) var/list/calculated = calculate_projectile_angle_and_pixel_offsets(source, params) p_x = calculated[2] diff --git a/modular_citadel/cit_screenshake.dm b/modular_citadel/cit_screenshake.dm index 818f363902..5bb1f82c10 100644 --- a/modular_citadel/cit_screenshake.dm +++ b/modular_citadel/cit_screenshake.dm @@ -46,17 +46,17 @@ /obj/item/attack(mob/living/M, mob/living/user) . = ..() - if(force && force >=15) + if(force >= 15) shake_camera(user, ((force - 10) * 0.01 + 1), ((force - 10) * 0.01)) if(M.client) switch (M.client.prefs.damagescreenshake) if (1) shake_camera(M, ((force - 10) * 0.015 + 1), ((force - 10) * 0.015)) if (2) - if (M.IsKnockdown()) + if (!M.canmove) shake_camera(M, ((force - 10) * 0.015 + 1), ((force - 10) * 0.015)) /obj/item/attack_obj(obj/O, mob/living/user) . = ..() - if(force && force >= 20) + if(force >= 20) shake_camera(user, ((force - 15) * 0.01 + 1), ((force - 15) * 0.01)) diff --git a/modular_citadel/cit_turfs.dm b/modular_citadel/cit_turfs.dm index 76b9a8f178..582552b83b 100644 --- a/modular_citadel/cit_turfs.dm +++ b/modular_citadel/cit_turfs.dm @@ -72,11 +72,6 @@ GLOBAL_LIST_INIT(turf_footstep_sounds, list( . = ..() CitDirtify(obj, oldloc)*/ -/mob/living/Move(atom/newloc, direct) - . = ..() - if(. && makesfootstepsounds) - CitFootstep(newloc) - //Baystation-styled tile dirtification. /turf/open/floor/proc/CitDirtify(atom/obj, atom/oldloc) if(prob(50)) diff --git a/modular_citadel/code/__HELPERS/list2list.dm b/modular_citadel/code/__HELPERS/list2list.dm new file mode 100644 index 0000000000..e812b3a1e9 --- /dev/null +++ b/modular_citadel/code/__HELPERS/list2list.dm @@ -0,0 +1,12 @@ +/proc/tg_ui_icon_to_cit_ui(ui_style) + switch(ui_style) + if('icons/mob/screen_plasmafire.dmi') + return 'modular_citadel/icons/ui/screen_plasmafire.dmi' + if('icons/mob/screen_slimecore.dmi') + return 'modular_citadel/icons/ui/screen_slimecore.dmi' + if('icons/mob/screen_operative.dmi') + return 'modular_citadel/icons/ui/screen_operative.dmi' + if('icons/mob/screen_clockwork.dmi') + return 'modular_citadel/icons/ui/screen_clockwork.dmi' + else + return 'modular_citadel/icons/ui/screen_midnight.dmi' diff --git a/modular_citadel/code/_onclick/click.dm b/modular_citadel/code/_onclick/click.dm new file mode 100644 index 0000000000..4746231c59 --- /dev/null +++ b/modular_citadel/code/_onclick/click.dm @@ -0,0 +1,74 @@ +/mob/proc/RightClickOn(atom/A, params) //mostly a copy-paste from ClickOn() + var/list/modifiers = params2list(params) + if(incapacitated(ignore_restraints = 1)) + return + + face_atom(A) + + if(next_move > world.time) // in the year 2000... + return + + if(!modifiers["catcher"] && A.IsObscured()) + return + + if(ismecha(loc)) + var/obj/mecha/M = loc + return M.click_action(A,src,params) + + if(restrained()) + changeNext_move(CLICK_CD_HANDCUFFED) //Doing shit in cuffs shall be vey slow + RestrainedClickOn(A) + return + + if(in_throw_mode) + throw_item(A)//todo: make it plausible to lightly toss items via right-click + return + + var/obj/item/W = get_active_held_item() + + if(W == A) + if(!W.rightclick_attack_self(src)) + W.attack_self(src) + update_inv_hands() + return + + //These are always reachable. + //User itself, current loc, and user inventory + if(DirectAccess(A)) + if(W) + W.rightclick_melee_attack_chain(src, A, params) + else + if(ismob(A)) + changeNext_move(CLICK_CD_MELEE) + if(!AltUnarmedAttack(A)) + UnarmedAttack(A) + return + + //Can't reach anything else in lockers or other weirdness + if(!loc.AllowClick()) + return + + //Standard reach turf to turf or reaching inside storage + if(CanReach(A,W)) + if(W) + W.rightclick_melee_attack_chain(src, A, params) + else + if(ismob(A)) + changeNext_move(CLICK_CD_MELEE) + if(!AltUnarmedAttack(A,1)) + UnarmedAttack(A,1) + else + if(W) + if(!W.altafterattack(A, src, FALSE, params)) + W.afterattack(A, src, FALSE, params) + else + if(!AltRangedAttack(A,params)) + RangedAttack(A,params) + +/mob/proc/AltUnarmedAttack(atom/A, proximity_flag) + if(ismob(A)) + changeNext_move(CLICK_CD_MELEE) + return FALSE + +/mob/proc/AltRangedAttack(atom/A, params) + return FALSE diff --git a/modular_citadel/code/_onclick/hud/screen_objects.dm b/modular_citadel/code/_onclick/hud/screen_objects.dm new file mode 100644 index 0000000000..5a193335f3 --- /dev/null +++ b/modular_citadel/code/_onclick/hud/screen_objects.dm @@ -0,0 +1,49 @@ +/obj/screen/mov_intent + icon = 'modular_citadel/icons/ui/screen_midnight.dmi' + +/obj/screen/sprintbutton + name = "toggle sprint" + icon = 'modular_citadel/icons/ui/screen_midnight.dmi' + icon_state = "act_sprint" + layer = ABOVE_HUD_LAYER - 0.1 + +/obj/screen/sprintbutton/Click() + if(ishuman(usr)) + var/mob/living/carbon/human/H = usr + H.togglesprint() + +/obj/screen/sprintbutton/proc/insert_witty_toggle_joke_here(mob/living/carbon/human/H) + if(!H) + return + if(H.sprinting) + icon_state = "act_sprint_on" + else + icon_state = "act_sprint" + +/obj/screen/restbutton + name = "rest" + icon = 'modular_citadel/icons/ui/screen_midnight.dmi' + icon_state = "rest" + +/obj/screen/restbutton/Click() + if(isliving(usr)) + var/mob/living/theuser = usr + theuser.lay_down() + +/obj/screen/combattoggle + name = "toggle combat mode" + icon = 'modular_citadel/icons/ui/screen_midnight.dmi' + icon_state = "combat_off" + +/obj/screen/combattoggle/Click() + if(iscarbon(usr)) + var/mob/living/carbon/C = usr + C.toggle_combat_mode() + +/obj/screen/combattoggle/proc/rebasetointerbay(mob/living/carbon/C) + if(!C) + return + if(C.combatmode) + icon_state = "combat" + else + icon_state = "combat_off" diff --git a/modular_citadel/code/_onclick/hud/stamina.dm b/modular_citadel/code/_onclick/hud/stamina.dm new file mode 100644 index 0000000000..72cd260f8a --- /dev/null +++ b/modular_citadel/code/_onclick/hud/stamina.dm @@ -0,0 +1,73 @@ +/datum/hud/var/obj/screen/staminas/staminas +/datum/hud/var/obj/screen/staminabuffer/staminabuffer + +/obj/screen/staminas + icon = 'modular_citadel/icons/ui/screen_gen.dmi' + name = "stamina" + icon_state = "stamina0" + screen_loc = ui_stamina + mouse_opacity = 0 + +/mob/living/carbon/human/proc/staminahudamount() + if(stat == DEAD || recoveringstam) + return "staminacrit" + else + switch(hal_screwyhud) + if(1 to 2) + return "staminacrit" + if(5) + return "stamina0" + else + switch(100 - staminaloss) + if(100 to INFINITY) + return "stamina0" + if(80 to 100) + return "stamina1" + if(60 to 80) + return "stamina2" + if(40 to 60) + return "stamina3" + if(20 to 40) + return "stamina4" + if(0 to 20) + return "stamina5" + else + return "stamina6" + +//stam buffer +/obj/screen/staminabuffer + icon = 'modular_citadel/icons/ui/screen_gen.dmi' + name = "stamina buffer" + icon_state = "stambuffer0" + screen_loc = ui_stamina + layer = ABOVE_HUD_LAYER + 0.1 + mouse_opacity = 0 + +/mob/living/carbon/human/proc/staminabufferhudamount() + if(stat == DEAD || recoveringstam) + return "stambuffer7" + else + switch(hal_screwyhud) + if(1 to 2) + return "stambuffer7" + if(5) + return "stambuffer0" + else + var/percentmult = 100/stambuffer + switch(stambuffer*percentmult - bufferedstam*percentmult) + if(95 to INFINITY) + return "stambuffer0" + if(90 to 95) + return "stambuffer1" + if(80 to 90) + return "stambuffer2" + if(60 to 80) + return "stambuffer3" + if(40 to 60) + return "stambuffer4" + if(20 to 40) + return "stambuffer5" + if(5 to 20) + return "stambuffer6" + else + return "stambuffer7" diff --git a/modular_citadel/code/_onclick/item_attack.dm b/modular_citadel/code/_onclick/item_attack.dm new file mode 100644 index 0000000000..b86ddc51be --- /dev/null +++ b/modular_citadel/code/_onclick/item_attack.dm @@ -0,0 +1,25 @@ +/obj/item/proc/rightclick_melee_attack_chain(mob/user, atom/target, params) + if(!pre_altattackby(target, user, params)) //Hey, does this item have special behavior that should override all normal right-click functionality? + if(!target.altattackby(src, user, params)) //Does the target do anything special when we right-click on it? + melee_attack_chain(user, target, params) //Ugh. Lame! I'm filing a legal complaint about the discrimination against the right mouse button! + else + altafterattack(target, user, TRUE, params) + return + +/obj/item/proc/pre_altattackby(atom/A, mob/living/user, params) + return FALSE //return something other than false if you wanna override attacking completely + +/atom/proc/altattackby(obj/item/W, mob/user, params) + return FALSE //return something other than false if you wanna add special right-click behavior to objects. + +/obj/item/proc/rightclick_attack_self(mob/user) + return FALSE + +/obj/item/proc/altafterattack(atom/target, mob/user, proximity_flag, click_parameters) + return FALSE + +/obj/item/proc/getweight() + if(total_mass) + return total_mass + else + return w_class*1.25 diff --git a/modular_citadel/code/_onclick/other_mobs.dm b/modular_citadel/code/_onclick/other_mobs.dm new file mode 100644 index 0000000000..51a5c6c5c3 --- /dev/null +++ b/modular_citadel/code/_onclick/other_mobs.dm @@ -0,0 +1,29 @@ +/mob/living/carbon/human/AltUnarmedAttack(atom/A, proximity) + if(!has_active_hand()) + to_chat(src, "You look at the state of the universe and sigh.") //lets face it, people rarely ever see this message in its intended condition. + return TRUE + + if(!A.alt_attack_hand(src)) + A.attack_hand(src) + return TRUE + return TRUE + +/mob/living/carbon/human/AltRangedAttack(atom/A, params) + if(!has_active_hand()) + to_chat(src, "You ponder your life choices and sigh.") + return TRUE + + if(!incapacitated()) + switch(a_intent) + if(INTENT_HELP) + visible_message("[src] waves to [A].", "You wave to [A].") + if(INTENT_DISARM) + visible_message("[src] shoos away [A].", "You shoo away [A].") + if(INTENT_GRAB) + visible_message("[src] beckons [A] to come.", "You beckon [A] to come.") //This sounds lewder than it actually is. Fuck. + if(INTENT_HARM) + visible_message("[src] shakes [p_their()] fist at [A].", "You shake your fist at [A].") + return TRUE + +/atom/proc/alt_attack_hand(mob/user) + return FALSE diff --git a/modular_citadel/code/datums/status_effects/debuffs.dm b/modular_citadel/code/datums/status_effects/debuffs.dm new file mode 100644 index 0000000000..37669fe94c --- /dev/null +++ b/modular_citadel/code/datums/status_effects/debuffs.dm @@ -0,0 +1,13 @@ +/datum/status_effect/incapacitating/knockdown/on_creation(mob/living/new_owner, set_duration, updating_canmove) + if(iscarbon(new_owner) && isnum(set_duration)) + new_owner.resting = TRUE + new_owner.adjustStaminaLoss(set_duration*0.25) + if(set_duration > 80) + set_duration = set_duration*0.15 + . = ..() + return + else if(updating_canmove) + new_owner.update_canmove() + qdel(src) + else + . = ..() diff --git a/modular_citadel/code/game/machinery/firealarm.dm b/modular_citadel/code/game/machinery/firealarm.dm new file mode 100644 index 0000000000..f4da844706 --- /dev/null +++ b/modular_citadel/code/game/machinery/firealarm.dm @@ -0,0 +1,10 @@ +/obj/machinery/firealarm/alt_attack_hand(mob/user) + if(is_interactable() && !user.stat) + var/area/A = get_area(src) + if(istype(A)) + if(A.fire) + reset() + else + alarm() + return TRUE + return FALSE diff --git a/modular_citadel/code/game/objects/items.dm b/modular_citadel/code/game/objects/items.dm new file mode 100644 index 0000000000..6f44d4b005 --- /dev/null +++ b/modular_citadel/code/game/objects/items.dm @@ -0,0 +1,2 @@ +/obj/item + var/total_mass diff --git a/modular_citadel/code/game/objects/structures/beds_chairs/chair.dm b/modular_citadel/code/game/objects/structures/beds_chairs/chair.dm new file mode 100644 index 0000000000..2023c6f326 --- /dev/null +++ b/modular_citadel/code/game/objects/structures/beds_chairs/chair.dm @@ -0,0 +1,21 @@ +/obj/structure/chair/alt_attack_hand(mob/living/user) + if(Adjacent(user) && istype(user)) + if(!item_chair || !user.can_hold_items() || !has_buckled_mobs() || buckled_mobs.len > 1 || dir != user.dir || flags_1 & NODECONSTRUCT_1) + return TRUE + if(!user.canUseTopic(src, BE_CLOSE, ismonkey(user))) + to_chat(user, "You can't do that right now!") + return TRUE + if(user.staminaloss >= STAMINA_SOFTCRIT) + to_chat(user, "You're too exhausted for that.") + return TRUE + var/mob/living/poordude = buckled_mobs[1] + if(!istype(poordude)) + return TRUE + user.visible_message("[user] pulls [src] out from under [poordude].", "You pull [src] out from under [poordude].") + var/C = new item_chair(loc) + user.put_in_hands(C) + poordude.Knockdown(20)//rip in peace + user.adjustStaminaLoss(5) + unbuckle_all_mobs(TRUE) + qdel(src) + return TRUE diff --git a/modular_citadel/code/modules/client/client_procs.dm b/modular_citadel/code/modules/client/client_procs.dm index 5bb53ee0f2..511aac0738 100644 --- a/modular_citadel/code/modules/client/client_procs.dm +++ b/modular_citadel/code/modules/client/client_procs.dm @@ -12,3 +12,11 @@ /client/proc/is_mentor() // admins are mentors too. if(mentor_datum || check_rights_for(src, R_ADMIN,0)) return TRUE + +/client/verb/togglerightclickstuff() + set category = "OOC" + set name = "Toggle Rightclick" + set desc = "Did the context menu get stuck on or off? Press this button." + + show_popup_menus = !show_popup_menus + to_chat(src, "The right-click context menu is now [show_popup_menus ? "enabled" : "disabled"].") diff --git a/modular_citadel/code/modules/client/preferences.dm b/modular_citadel/code/modules/client/preferences.dm index 1e12ae5c86..4d1fc880d7 100644 --- a/modular_citadel/code/modules/client/preferences.dm +++ b/modular_citadel/code/modules/client/preferences.dm @@ -11,6 +11,7 @@ var/damagescreenshake = 2 var/arousable = TRUE var/widescreenpref = TRUE + var/autostand = TRUE /datum/preferences/New(client/C) ..() diff --git a/modular_citadel/code/modules/keybindings/bindings_carbon.dm b/modular_citadel/code/modules/keybindings/bindings_carbon.dm new file mode 100644 index 0000000000..d49cbcf452 --- /dev/null +++ b/modular_citadel/code/modules/keybindings/bindings_carbon.dm @@ -0,0 +1,6 @@ +/mob/living/carbon/key_down(_key, client/user) + switch(_key) + if("C") + toggle_combat_mode() + return + return ..() diff --git a/modular_citadel/code/modules/keybindings/bindings_human.dm b/modular_citadel/code/modules/keybindings/bindings_human.dm new file mode 100644 index 0000000000..963e71d709 --- /dev/null +++ b/modular_citadel/code/modules/keybindings/bindings_human.dm @@ -0,0 +1,13 @@ +/mob/living/carbon/human/key_down(_key, client/user) + switch(_key) + if("Shift") + togglesprint() + return + return ..() + +/mob/living/carbon/human/key_up(_key, client/user) + switch(_key) + if("Shift") + togglesprint() + return + return ..() diff --git a/modular_citadel/code/modules/mob/living/carbon/carbon.dm b/modular_citadel/code/modules/mob/living/carbon/carbon.dm new file mode 100644 index 0000000000..87a496b48b --- /dev/null +++ b/modular_citadel/code/modules/mob/living/carbon/carbon.dm @@ -0,0 +1,17 @@ +/mob/living/carbon + var/combatmode = FALSE //literally lifeweb + +/mob/living/carbon/proc/toggle_combat_mode() + if(recoveringstam) + return TRUE + combatmode = !combatmode + if(combatmode) + playsound_local(src, 'modular_citadel/sound/misc/ui_toggle.ogg', 50, FALSE, pressure_affected = FALSE) //Sound from interbay! + else + playsound_local(src, 'modular_citadel/sound/misc/ui_toggleoff.ogg', 50, FALSE, pressure_affected = FALSE) //Slightly modified version of the above! + if(client) + client.show_popup_menus = !combatmode // So we can right-click for alternate actions and all that other good shit. Also moves examine to shift+rightclick to make it possible to attack while sprinting + if(hud_used && hud_used.static_inventory) + for(var/obj/screen/combattoggle/selector in hud_used.static_inventory) + selector.rebasetointerbay(src) + return TRUE diff --git a/modular_citadel/code/modules/mob/living/carbon/damage_procs.dm b/modular_citadel/code/modules/mob/living/carbon/damage_procs.dm new file mode 100644 index 0000000000..208d4769bb --- /dev/null +++ b/modular_citadel/code/modules/mob/living/carbon/damage_procs.dm @@ -0,0 +1,10 @@ +/mob/living/carbon/adjustStaminaLossBuffered(amount, updating_stamina = 1) + if(status_flags & GODMODE) + return 0 + var/directstamloss = (bufferedstam + amount) - stambuffer + if(directstamloss > 0) + adjustStaminaLoss(directstamloss) + bufferedstam = CLAMP(bufferedstam + amount, 0, stambuffer) + stambufferregentime = world.time + 2 SECONDS + if(updating_stamina) + update_health_hud() diff --git a/modular_citadel/code/modules/mob/living/carbon/human/human.dm b/modular_citadel/code/modules/mob/living/carbon/human/human.dm new file mode 100644 index 0000000000..e69de29bb2 diff --git a/modular_citadel/code/modules/mob/living/carbon/human/human_defense.dm b/modular_citadel/code/modules/mob/living/carbon/human/human_defense.dm index 1952b3a3b8..c1fc6623de 100644 --- a/modular_citadel/code/modules/mob/living/carbon/human/human_defense.dm +++ b/modular_citadel/code/modules/mob/living/carbon/human/human_defense.dm @@ -2,4 +2,13 @@ if(user == src && pulling && !pulling.anchored && grab_state >= GRAB_AGGRESSIVE && isliving(pulling)) vore_attack(user, pulling) else - ..() \ No newline at end of file + ..() + +/mob/living/carbon/human/alt_attack_hand(mob/user) + if(..()) + return + if(ishuman(user)) + var/mob/living/carbon/human/H = user + if(!dna.species.alt_spec_attack_hand(H, src)) + dna.species.spec_attack_hand(H, src) + return TRUE diff --git a/modular_citadel/code/modules/mob/living/carbon/human/human_movement.dm b/modular_citadel/code/modules/mob/living/carbon/human/human_movement.dm new file mode 100644 index 0000000000..8463abe66d --- /dev/null +++ b/modular_citadel/code/modules/mob/living/carbon/human/human_movement.dm @@ -0,0 +1,31 @@ +/mob/living/carbon/human + var/sprinting = FALSE + +/mob/living/carbon/human/Move(NewLoc, direct) + var/oldpseudoheight = pseudo_z_axis + . = ..() + if(. && sprinting && !resting && m_intent == MOVE_INTENT_RUN) + adjustStaminaLossBuffered(0.3) + if((oldpseudoheight - pseudo_z_axis) >= 8) + to_chat(src, "You trip off of the elevated surface!") + for(var/obj/item/I in held_items) + accident(I) + Knockdown(80) + +/mob/living/carbon/human/movement_delay() + . = 0 + if(!resting && m_intent == MOVE_INTENT_RUN && !sprinting) + . += 1 + . += ..() + +/mob/living/carbon/human/proc/togglesprint() // If you call this proc outside of hotkeys or clicking the HUD button, I'll be disappointed in you. + sprinting = !sprinting + if(!resting && m_intent == MOVE_INTENT_RUN && canmove) + if(sprinting) + playsound_local(src, 'modular_citadel/sound/misc/sprintactivate.ogg', 50, FALSE, pressure_affected = FALSE) + else + playsound_local(src, 'modular_citadel/sound/misc/sprintdeactivate.ogg', 50, FALSE, pressure_affected = FALSE) + if(hud_used && hud_used.static_inventory) + for(var/obj/screen/sprintbutton/selector in hud_used.static_inventory) + selector.insert_witty_toggle_joke_here(src) + return TRUE diff --git a/modular_citadel/code/modules/mob/living/carbon/human/life.dm b/modular_citadel/code/modules/mob/living/carbon/human/life.dm index 1f7c39a5ff..a3730a312f 100644 --- a/modular_citadel/code/modules/mob/living/carbon/human/life.dm +++ b/modular_citadel/code/modules/mob/living/carbon/human/life.dm @@ -3,10 +3,19 @@ if(stat != DEAD) handle_arousal() . = ..() - + /mob/living/carbon/human/calculate_affecting_pressure(pressure) if(ismob(loc)) return ONE_ATMOSPHERE if(istype(loc, /obj/item/device/dogborg/sleeper)) return ONE_ATMOSPHERE - . = ..() \ No newline at end of file + . = ..() + +/mob/living/carbon/human/update_health_hud(shown_health_amount) + . = ..() + if(!client || !hud_used) + return + if(hud_used.staminas) + hud_used.staminas.icon_state = staminahudamount() + if(hud_used.staminabuffer) + hud_used.staminabuffer.icon_state = staminabufferhudamount() diff --git a/modular_citadel/code/modules/mob/living/carbon/human/species.dm b/modular_citadel/code/modules/mob/living/carbon/human/species.dm new file mode 100644 index 0000000000..007194e9f1 --- /dev/null +++ b/modular_citadel/code/modules/mob/living/carbon/human/species.dm @@ -0,0 +1,57 @@ +/datum/species/proc/alt_spec_attack_hand(mob/living/carbon/human/M, mob/living/carbon/human/H, datum/martial_art/attacker_style) + if(!istype(M)) + return TRUE + CHECK_DNA_AND_SPECIES(M) + CHECK_DNA_AND_SPECIES(H) + + if(!istype(M)) //sanity check for drones. + return TRUE + if(M.mind) + attacker_style = M.mind.martial_art + if((M != H) && M.a_intent != INTENT_HELP && H.check_shields(M, 0, M.name, attack_type = UNARMED_ATTACK)) + add_logs(M, H, "attempted to touch") + H.visible_message("[M] attempted to touch [H]!") + return TRUE + switch(M.a_intent) + if("disarm") + altdisarm(M, H, attacker_style) + return TRUE + return FALSE + +/datum/species/proc/altdisarm(mob/living/carbon/human/user, mob/living/carbon/human/target, datum/martial_art/attacker_style) + if(user.staminaloss >= STAMINA_SOFTCRIT) + to_chat(user, "You're too exhausted.") + return FALSE + else if(target.check_block()) + target.visible_message("[target] blocks [user]'s disarm attempt!") + return 0 + if(attacker_style && attacker_style.disarm_act(user,target)) + return 1 + else + user.do_attack_animation(target, ATTACK_EFFECT_DISARM) + + user.adjustStaminaLossBuffered(4) //CITADEL CHANGE - makes disarmspam cause staminaloss + + if(target.w_uniform) + target.w_uniform.add_fingerprint(user) + var/randomized_zone = ran_zone(user.zone_selected) + target.SendSignal(COMSIG_HUMAN_DISARM_HIT, user, user.zone_selected) + var/obj/item/bodypart/affecting = target.get_bodypart(randomized_zone) + var/randn = rand(1, 100) + if(user.resting) + randn += 20 //Makes it plausible, but unlikely, to push someone over while resting + if(!user.combatmode) + randn += 25 //Makes it impossible to push actually push someone outside of combat mode + + if(randn <= 25) + playsound(target, 'sound/weapons/thudswoosh.ogg', 50, 1, -1) + target.visible_message("[user] has pushed [target]!", + "[user] has pushed [target]!", null, COMBAT_MESSAGE_RANGE) + target.apply_effect(40, KNOCKDOWN, target.run_armor_check(affecting, "melee", "Your armor prevents your fall!", "Your armor softens your fall!")) + target.forcesay(GLOB.hit_appends) + add_logs(user, target, "disarmed", " pushing them to the ground") + return + + playsound(target, 'sound/weapons/punchmiss.ogg', 25, 1, -1) + target.visible_message("[user] attempted to push [target]!", \ + "[user] attemped to push [target]!", null, COMBAT_MESSAGE_RANGE) diff --git a/modular_citadel/code/modules/mob/living/damage_procs.dm b/modular_citadel/code/modules/mob/living/damage_procs.dm new file mode 100644 index 0000000000..8323386eff --- /dev/null +++ b/modular_citadel/code/modules/mob/living/damage_procs.dm @@ -0,0 +1,2 @@ +/mob/living/proc/adjustStaminaLossBuffered(amount, updating_stamina = TRUE, forced = FALSE) + return diff --git a/modular_citadel/code/modules/mob/living/living.dm b/modular_citadel/code/modules/mob/living/living.dm new file mode 100644 index 0000000000..16376a4a58 --- /dev/null +++ b/modular_citadel/code/modules/mob/living/living.dm @@ -0,0 +1,122 @@ +/mob/living + var/recoveringstam = FALSE + var/bufferedstam = 0 + var/stambuffer = 20 + var/stambufferregentime + var/aimingdownsights = FALSE + var/attemptingstandup = FALSE + var/intentionalresting = FALSE + +/mob/living/movement_delay(ignorewalk = 0) + . = ..() + if(resting) + . += 6 + +/atom + var/pseudo_z_axis + +/atom/proc/get_fake_z() + return pseudo_z_axis + +/obj/structure/table + pseudo_z_axis = 8 + +/turf/open/get_fake_z() + var/objschecked + for(var/obj/structure/structurestocheck in contents) + objschecked++ + if(structurestocheck.pseudo_z_axis) + return structurestocheck.pseudo_z_axis + if(objschecked >= 25) + break + return pseudo_z_axis + +/mob/living/Move(atom/newloc, direct) + . = ..() + if(.) + if(makesfootstepsounds) + CitFootstep(newloc) + pseudo_z_axis = newloc.get_fake_z() + pixel_z = pseudo_z_axis + if(aimingdownsights) + aimingdownsights = FALSE + to_chat(src, "You are no longer aiming down your weapon's sights.") + +/mob/living/proc/lay_down() + set name = "Rest" + set category = "IC" + + if(client && client.prefs && client.prefs.autostand) + intentionalresting = !intentionalresting + to_chat(src, "You are now attempting to [intentionalresting ? "[!resting ? "lay down and ": ""]stay down" : "[resting ? "get up and ": ""]stay up"].") + if(intentionalresting && !resting) + resting = TRUE + update_canmove() + else + resist_a_rest() + else + if(!resting) + resting = TRUE + to_chat(src, "You are now laying down.") + update_canmove() + else + resist_a_rest() + +/mob/living/proc/resist_a_rest(automatic = FALSE, ignoretimer = FALSE) //Lets mobs resist out of resting. Major QOL change with combat reworks. + if(!resting || stat || attemptingstandup) + return FALSE + if(ignoretimer) + resting = FALSE + update_canmove() + return TRUE + else + var/totaldelay = 3 //A little bit less than half of a second as a baseline for getting up from a rest + if(staminaloss >= STAMINA_SOFTCRIT) + to_chat(src, "You're too exhausted to get up!") + return FALSE + attemptingstandup = TRUE + var/health_deficiency = max((maxHealth - (health - staminaloss))*0.5, 0) + if(!has_gravity()) + health_deficiency = health_deficiency*0.2 + totaldelay += health_deficiency + var/standupwarning = "[src] and everyone around them should probably yell at the dev team" + switch(health_deficiency) + if(-INFINITY to 10) + standupwarning = "[src] stands right up!" + if(10 to 35) + standupwarning = "[src] tries to stand up." + if(35 to 60) + standupwarning = "[src] slowly pushes [p_them()]self upright." + if(60 to 80) + standupwarning = "[src] weakly attempts to stand up." + if(80 to INFINITY) + standupwarning = "[src] struggles to stand up." + var/usernotice = automatic ? "You are now getting up. (Auto)" : "You are now getting up." + visible_message("[standupwarning]", usernotice, vision_distance = 5) + if(do_after(src, totaldelay, target = src)) + resting = FALSE + attemptingstandup = FALSE + update_canmove() + return TRUE + else + visible_message("[src] falls right back down.", "You fall right back down.") + attemptingstandup = FALSE + if(has_gravity()) + playsound(src, "bodyfall", 20, 1) + return FALSE + +/mob/living/carbon/proc/update_stamina() + var/total_health = (min(health*2,100) - staminaloss) + if(staminaloss) + if(!recoveringstam && total_health <= STAMINA_CRIT_TRADITIONAL && !stat) + to_chat(src, "You're too exhausted to keep going...") + resting = TRUE + if(combatmode) + toggle_combat_mode() + recoveringstam = TRUE + update_canmove() + if(recoveringstam && total_health >= STAMINA_SOFTCRIT_TRADITIONAL) + to_chat(src, "You don't feel nearly as exhausted anymore.") + recoveringstam = FALSE + update_canmove() + update_health_hud() diff --git a/modular_citadel/code/modules/mob/living/silicon/robot/dogborg_equipment.dm b/modular_citadel/code/modules/mob/living/silicon/robot/dogborg_equipment.dm index dceaf9d1c5..b15dac4a15 100644 --- a/modular_citadel/code/modules/mob/living/silicon/robot/dogborg_equipment.dm +++ b/modular_citadel/code/modules/mob/living/silicon/robot/dogborg_equipment.dm @@ -379,7 +379,7 @@ SLEEPER CODE IS IN game/objects/items/devices/dogborg_sleeper.dm ! blocked = 1 if(!blocked) L.visible_message("[src] pounces on [L]!", "[src] pounces on you!") - L.Knockdown(45) + L.Knockdown(iscarbon(L) ? 450 : 45) // Temporary. If someone could rework how dogborg pounces work to accomodate for combat changes, that'd be nice. playsound(src, 'sound/weapons/Egloves.ogg', 50, 1) sleep(2)//Runtime prevention (infinite bump() calls on hulks) step_towards(src,L) diff --git a/modular_citadel/code/modules/mob/mob.dm b/modular_citadel/code/modules/mob/mob.dm new file mode 100644 index 0000000000..bb48e5103f --- /dev/null +++ b/modular_citadel/code/modules/mob/mob.dm @@ -0,0 +1,2 @@ +/mob/proc/use_that_empty_hand() //currently unused proc so i can implement 2-handing any item a lot easier in the future. + return diff --git a/modular_citadel/code/modules/projectiles/gun.dm b/modular_citadel/code/modules/projectiles/gun.dm new file mode 100644 index 0000000000..27411c7e0a --- /dev/null +++ b/modular_citadel/code/modules/projectiles/gun.dm @@ -0,0 +1,36 @@ +/obj/item/gun/pre_altattackby(atom/A, mob/living/user, params) + altafterattack(A, user, TRUE, params) + return TRUE + +/obj/item/gun/altafterattack(atom/target, mob/living/carbon/user, proximity_flag, click_parameters) + if(istype(user)) + if(!user.aimingdownsights) + user.visible_message("[user] brings [src]'s sights up to [user.p_their()] eyes, aiming directly at [target].", "You bring [src]'s sights up to your eyes, aiming directly at [target].") + user.adjustStaminaLossBuffered(1) + else + user.visible_message("[user] lowers [src].", "You lower [src].") + user.aimingdownsights = !user.aimingdownsights + return TRUE + +/obj/item/gun/dropped(mob/living/user) + . = ..() + if(istype(user)) + user.aimingdownsights = FALSE + +/obj/item/gun/proc/getstamcost(mob/living/carbon/user) + if(user && user.has_gravity()) + return recoil + else + return recoil*5 + +/obj/item/gun/energy/kinetic_accelerator/getstamcost(mob/living/carbon/user) + if(user && !lavaland_equipment_pressure_check(get_turf(user))) + return 0 + else + return ..() + +/obj/item/gun/proc/getinaccuracy(mob/living/user) + if(!iscarbon(user) || user.aimingdownsights) + return 0 + else + return weapon_weight * 25 diff --git a/modular_citadel/code/modules/projectiles/projectile/energy.dm b/modular_citadel/code/modules/projectiles/projectile/energy.dm new file mode 100644 index 0000000000..8c5725a8a3 --- /dev/null +++ b/modular_citadel/code/modules/projectiles/projectile/energy.dm @@ -0,0 +1,2 @@ +/obj/item/projectile/energy/electrode + stamina = 30 diff --git a/modular_citadel/code/modules/recycling/disposal/bin.dm b/modular_citadel/code/modules/recycling/disposal/bin.dm new file mode 100644 index 0000000000..226c56d226 --- /dev/null +++ b/modular_citadel/code/modules/recycling/disposal/bin.dm @@ -0,0 +1,6 @@ +/obj/machinery/disposal/bin/alt_attack_hand(mob/user) + if(is_interactable() && !user.stat) + flush = !flush + update_icon() + return TRUE + return FALSE diff --git a/modular_citadel/icons/ui/screen_clockwork.dmi b/modular_citadel/icons/ui/screen_clockwork.dmi new file mode 100644 index 0000000000000000000000000000000000000000..499d2663b6c60590f8baeba0c18835cf7459760d GIT binary patch literal 3074 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 CSpQ%E literal 0 HcmV?d00001 diff --git a/modular_citadel/icons/ui/screen_gen.dmi b/modular_citadel/icons/ui/screen_gen.dmi new file mode 100644 index 0000000000000000000000000000000000000000..d006185a3c78ab430d1e3a40d2f904e13de9f07d GIT binary patch literal 5328 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 literal 0 HcmV?d00001 diff --git a/modular_citadel/icons/ui/screen_midnight.dmi b/modular_citadel/icons/ui/screen_midnight.dmi new file mode 100644 index 0000000000000000000000000000000000000000..38d96b86d1564fffe07da6fb46ec6dbf3f9bddfb GIT binary patch literal 5406 zcmbVQ^;;9(_um){kWn&m2nd1_5~CypB$Y-)5s)qcY2M_BA&ee98tD?HrE7Ew6OfQD z3F)5HXMX>L?++)Qd(J)g+~=I<+~>Z+wKSC|Z{52E001aelohoJ()1sZfeCy$#Z#Oh z(hzU-+!U?;vv9R_cC&SI1OU7;5{FuDbqGL1mLwV?6q+KDcJ#J!kR3kM6vubD^uGQd z^Q{WlAB(3g`};M{o8<_UBkpjA%OWCsv3W+Va%l(%&4|_}4pm#coysSvg^L}WRTgBo z(sGXNNH8**HnHRs#jC(>ayYt6GDi{BCu1Gzhpnn&7xfl~CDF!$*Uo&$7Nm38YorEo z7U@{)$W#CTDx;z(_r@z@=aY9V(@(!%nLYQBhNfS3r}1w`Z~d2=G8QlADxl01U+)&6 z5*s&IruP|D578;B;^}AMFIuiwmJc+Fc23-OMOWB!c8$KHm!Bf~k1SSBsD}y6sE7OT zWA}9EgQvA;^fTk@jm=C8YmZ4%VS{epFNK8*5t0oD8A95tyGG%DPG)k2+5YMdQ&niCTE6MLZTWVhn9X;yJj%(i*|`lfxg<1 zjX@(Z!K9qZ9JBTf69G`A-ui8G%I^UN5rBJEIGIx|uA^wRn?WN3m}ZeSjGZ$QZ0@u( zt*djzQ|n-?2NHDtvnY@GQW_=HTX3^h#s|?gm*qQ#!$1VrFS`+3U4-foWB`daiQF86 zu2NJ*b`Nk*>D)oK^h>}Qk6Uq+%yny1%$G*mTQDs<pOELL^G+ANiN1n+ zN<#wxKHYdVzh8bNRq_(`&k|gpIXe}SZ9%xYzCyzEyy2Oods9c=)W>_LR~w+KCi0%c zRvNhfX#efVwW~#U@Twpj3`LNCWCMFWl8j3aJI9wb0pEK8C|+61-aj&zmAI+vMVa#M zagt6J8E;6Q`7Q<*3$w;}3ufbPJ_)QGzZ!~Y<@3b%8rzl&oBGq3w5}r-SWFz5wEAy$ zatx;;4IUq9ZN(sEEQVdM_Sbu^F7Fe(2?3}V05zw*Z6-@id4GoMe_^dGam`!gg zpVLYv7!_h7-YR^iF@HxvvLN{S^YMg?m`>@5u7dTWjf)t*h?LLcYlFI_Pl*@xCVWb? zw)i*a{dXHqw85G4NM7@Fg0)jA`aa_2o#gC4dC6tTLi-{qDgotwYc@KRF6%PJTbe4y z^;Sm>gct}N)u`=Ze-1AvyWHnofu8mqF81I|zg_v9IOb=r$2!H=7r;-+Mu?^Fx+!o( z>OxaJoJEBTMZ=X?7fItd-#6P9n0vIg{MR*+nwp9dP)6(az>=7?sXEIm*|N->_2X~1 z6eta_r_(kAFXc|jr%p!x_=N9)aBGy1Nb9`V!MRpEw)7V%?6@#@{2daautg*8x~T1V@F z6js`pi!(TCfnw`&mL80(FW=~jHxR>Dt<^co-(>kCWLi^)2I086C5}-z^Lj>%Q|IMw zr?OG6FP?<|Z_|jtd8Z%m)nI8#c?%h~JL}3$^KwzC`D9_iy1U5HV)c)YEq>^4F6!&- zslM@a(--9%Zv&6>DvH|e#l!=nj5^!UHX{6a&{j6E8c%Lc6a5bMa6M*bHi@* zMBhiFW?G1uHnz7}ZHp=$>ikuT4$D$=<0^iB#rGC1zzTKAOgKCHihC;21@HSFm)hTdBxk~( zmo;^wV`5yd?pv$#BiIE+V{^NZK6n$z!BHe`y;9`8v*@`2?$L}H1B+xfQ8B?785Ovn zQwzj@QjD^SV^fFYPM7|85uB8xGT#sMpM!1e`c>ycy37SJ+Rq`*yy*wl_erz8PwrgTeANH_iDI3(qw*M%>KRipf#vb>#Jl^D z;=|cvfW|OG1q=c)*dCc@8wlQ>a-8ejs4CoOLNj*&=tpYunWSG{K&_{$wYv(E?!wj`paPIr`? z2MHN-yAndTOsrxARbM`hI>$CN@0%NU~ly&%ieO3*!JS&g-0$X_ljLWL`3I}g&0e8!bap@*dWSDde`N8%r1V9+#L2jDFNLlWNL`X2 zlq)2~o}oc*f@IC@%O}nWd)z4cxbyiW^giS36~arjXiucpBfodok$Ga*++bI+eXymig9}uOgPj#f^-l!lS_05Xss6+}(OhnTJ)}C|GX@Uo9 z=YYR>gYqI;vU6|84hB?2nEDkbM~Tgb&;*83Uj}@>Ya%CVliG&X16u)_6E?aXv5(-Sz!jv8PH0<^`0HiJxSYmw-thCvJ zg?szlj3G1u%JuiqRQq@r4G_u5 z^)mT4*?`P4m`Y;LtCD)fp&;O1!L>{X@LF6>F=ZSi<#SB_)&xPKJ+`@x7A$ywuNit| z9sngWO3qJb7YQB4)(SCs|1H}1$l96I-sZc{bltG_&T-aDnDlR(l7}xQEN*%Ir4*`c zlQ{4}&-lZ!A|cC~WySBI|91)oXuL@+@oI=ap$B*C>sNz4$pJIVuJbVgERP>0n|w)8 zy89o;!^uiX><9}T7gX2S8x$ks5rBMpN-PO)L65c5yJ@UP3{I|aoo_yf++9@Z8G7Sl zBt;6Ex4S}efl#P`!XJf7us`pHe(KH$+`lzeTZMA^TsMD%ka;>7#O< ziEzudC%j~N|J~|Oz3UDoSAo~oXQhAIWfKi6>qC*UdS7WGPZ96$A?XtJHy7%y=R%u- z@q&z?lAIfAs{jm+l}&sdzS0;a#@^?nrlh2#!Z6KX&l9T8uy`W%3-oGoVA2sx8vP7O z%m-UO;G{O!ryr<{8|6#3o1|~H%3JKWrly0S^zlni{EehGp%3lp!EY393?chHz=&m} zhH5U~t08CTM+2^CDZdo0Z{e~d({99?cxiZwcT9(itUd@9@)1MB5%J%(P}$j6bO(@W zEml)w1>LM7`bmCF#2?YOnno!W6xhomvys$gLs#p1u~^2!rKw%uY+n~6_3s`?Q83wq z*oKg|@8s;IBNGO3T(91oxr!RP(5&?Ba29L+g9WV2J?jew=1Huh<#ue_+WC&R;S zA@|4?@5RdJG6k=QcbV^?bbgHls6vX9u2mr$8)$s1uV0+$=FhsL;nq1z=c~&oA@#>J zvbXfA5zH^8FSzWURYkKaQ6H_o4#gb<=8Ty0mDy3Oim_Jdb^k3}Q=4jVRj~!-K|g<< zhGmmi3CVX>tr04^i?^e^G1!$F}4!A1hAaRYxdvwA8tKOxNJmnetzx9 zNE`L$1IYDJwoc5V#7A8}uO}l+lJc%YSfT1~?^Z5X3Ek@PwBOB>J=#?|zVQwR4m`G) zB*nzBlDGTBK`>WH+LKZ1(N%Q~ke1dAUpUhqQeA#!S*8Y7@L`diBuQw$otfiLCt?yu9x*r1-2k`~%^RgaP#1PhT(l{?))qJWIy&%p zoVeD({Jn4n!Y>w0l7R3JV1G!wL$*{VY-?+)#N9ov$JAR}5xQVGUeW)dyMKwpt3TJan(>3&+z-g$|2q)E5Rp%A&9Fw zNc@Ym2R*HR@OM5aS*~Rv(*;fK&T0W!GC5D(yL^b0u}_f=TU(5CAv^s+mZRK5XqEL% zK@Q0@GD#}jV%?U!JW3!zo-N;W>)XYC^bV`!+X_7v_D5BYd)OQ{5MeHt5P^PK;6)d^ zEU2ANdtSOO_cry5K4A@J9li6A@4tk%9iIkj92f_OM(>NIpr71!HjJs_D3}4;yUhf= zNF(#Gc7CIP7nP-psEi}eI7+TGTj3MGMI}>p*X~?n=()6bZ8xq$PSx^qLMoXmpCjz4 z84)wH<7ao??blA(zmnMs9?p*jUd=4T(KFbSB2w^F3|Py=W2M|EtCN^$=yBlfz#OM* z&gflHEF~Md;h0F&(2uS*&uhE#%JMsJt<|!g@E9Q*3WS(vjJ}VYyfV=}x6Gf9*&u^oUBt0$mr4$Jv8(lKql;;h9K%k3Vb z#x1G6_vc>zUUf==X@aN@zdl#i5XuZouq@0n86$pmhmFS0(}#6nY0eBZL#w#rG9)~# zC~>P(pyC^3E)hoP&!t-sE@pCy*%AqL*q6M?mj+v1Jm{E0TCP=n>j$Xflv-CVNh+;@ zf>7;S!s!n<7*lM**@8_wD&@B%4j8&w6 zg+{$s{Ui{2+0)y4@t>PfK>?-sZjp$zW$oNE5WJyqR}^kGj0(8sCAx1aj{+_`l%( z@-R!7ujblxEcqESyYR1F)L+u{59mhV|DXO|1E0L`y9v0L*NT*l5?uFG_{iY1Ouw68 zaIQ1!TIE`d6cdTjU%-UU-Y0tW&j3RZFedU38kRf#3{|SdNXe%$-hL8duc}yNms$by zq%9YlOB!%(l0)c3!e*|Jzz_q1QJGh8#rRux|{)0KnMG3GG z!^Xm=848Zyp)LOQvxVsnJ%@qLf$xR#VB<~TWi(Hgyja6=s3wC0FCsFPQMNC156m!1+_=W3I z#{611>D=3Ea^I-+i*Ox1*x|K{EnMiB(MBx}642!)JSU3MUZBYmlF=VU4$NwZaXRR` zBYRRTEU;GgJde*c8E=cAeO38mehtUtJx>q1v?MND?98hYEX8izg^uh<<_cFyUMAV) zU>xJJ007$WnktHhKDj%2{_cj8f&KDpxX#Pbm(%TppmPJFdnt2z6*NEZyN&hlUDlc5g9PubwgZIo zr-Rjo%evflEJen~l`rS>4X)|iC&>U}Y>W%WL4j|7<*qw1F_S!3a~HVvdh4!x&2s9@) z*0(g+lBuxRmD|7gGXPf3+75?Q3=VZyt5s-GIDRiLM)?sp=8ZJmP+(*qhCB~Uxdzau z0Su))BmyDRT6XrTx><2RM~0lzfioDP@c)f+6Mwaq_l8-b@9XSX8cAT=Z(t_rL{gt zOW+sEW!HPxEM|QK6tzA|*>=vsvvo)bWk53;zR1gk65}wMz5@0JWrcE{gcoG}%iI2E zZ!)ANvH5Z@UXr8!`Ig|*!yI>5(5G2azUx$PWdK%$nVUW4l9^#7B(1dc!)(M*GG3nq zhK1s(ILhA5xH$bPH$sKHx^|CO8m9>sr316emGjsd9X)2wlE(NCj+DK+_ejY0B=-?bMT){DhvT^pnqji1+g!kz;dL++a z^;?YkT}x)=C>al)-E26 z=nbj=3p!K3%LF3T%bL_@NNXr5o6~0V8s2qg{fR7FlVK!t%q{Q}n&SLI=sY+W^8REp zpZ?BD+5|GcSp-o6IEOxK7p62Dw8Vx_09T5fF_!`S|2WT_B-0$(N3(y#vI;5V z#CFZ|gIq!hq{KLZ>!J9_5$!I(mVRN*ka#a5SvQkZkL=BXNA|+xlp2fQmP5R<{AI=G zKh)%e5dxp@Q6hKG&l34NHr9LW&4U)i3ia8~LwzV!n27odb$fDqAq2~Pqhe!?fwsa& zLypmb>{>Lm&NmNP2t=RQzt29rmYp>Kb$frnpTgO1yMFo1Aa;eDebt)@I|No<^TsZ^ z$tq_d54>lsJjWLJl{(BScO3)Bk1{HTUlOAaOyzxteqUc z7zk_BVhCv*R|?^GP9n}U-psD_9bbhvzll+GxlWwp4#?&rdbdi_?D-wo{yUQvs(30t=xHKI)ZHSAT}-?jTZ|BkdL9og+zw> zbQ(~U8tpq`0dlV7W<}VaVG3)_Oc+LV#}4nn!g*Gzz!=hEJdncb=0kk3C4?Z@8?fu| zJQ^*tRQjVT8@wcFHSZ@e!Wx(-A`y`5GcPI9h;@4NuiC6vW7IO_qL}ltr#_7d9#YBr z>&IW>fceSQvQuF+3F1;1?GHBzHt-7BoeQ9q@A7)jn#8{pxO`vuicGjNDjR*Ok^?47-o_T82KjGF(j zluvqLL*CSU_y!qSvvu|K=|O`~L9@Iqjm6}-;?(eI$;y)8AL_Q65_OLCyLp?c6o5Dl z3!y&)8Q{ul)ia2BJ8567`vS!l_=#f6D|Wvj4jH#0r6XdBXu%rAv%)IZyGltaRn@;Z z+X92-4yl=$I2Y|(H(9AIHuIpKax2q+s+s0X#Qc9>uCyXt+zJ{MLM{*#oMP`Mhv&~`bd7=j`RtX|EJPFUl|N7+HE0bMq=-%~5WkL4q)KV9$pzVB7 z=W7m~;B}xVVB2!|<2T&1QJHratqp8%)Kjd`7&&< z%c*mQ8}ktSYFk*s3@0lN43wGy?E6IPU7ZuT{X27JEn4zW0ob!F4b!~SxyN`NLWnPl z*tODL6XGACjRBkswIRLUqp@EY39L|!hg?KwJ5DrzMRjVu_6R>^=*)~fX}XO!Z+ekq zaJ_qt`@SCe>L@It&Q4h&JY>1#xgULWxwJ1!7KeV=ebP{vV5v=cTb-Go;`+oy#2PLpT;BHcs+-Ot&Itj0yQH87}smR7F9R zD$3OFf*i6jRTpo6OY|_mR1mz7RHK_;W1$2{S*n6~SIhtuFC%kAFL{t}J*T7JCT~3z#k(2Fkp?yxC zFZV7M&7r835~gnZ?8GS5LvA9R6b@_DIT#W`b4ILWW$3 zfN6bE9?D&U_+&f#wD6><hI$Zv!vZFRg}$Iyiu2w( za2u&RZeZRg@beabxbV2S_2ng2Od*66{+d0!aFa8k=e8ptJ*0S4N=#+Ejhp3-@%f1b z+gg@M4!pZ8EY$n%Ps<=?oo8fKqR#QjjI4?YOiY%N?TopO*Jg`8!6>$1l;-y}JEiHx zZ>iv|txE$j%zoDa_;{_>W4@D$H(L%;pA21k{pfj*$u73HHZkw-0KvMYvG%pVz5R2; znFvGCYlhL+NkQ2ia(NeXq{y1)Uou6hSf$oX!@$iW|%9G@H0M^1_8 z!V9{a1KbDFq7c13%mgUt?TQeNoFv!OIm7wYe{wM`&_*ACbM(xYL;WQDLDv&!Y)2+XL!aeWH((PNMTpXw-*CvGpzNMoM9(9m{(-CY}^qCnDu zdMc77J;J)N(*W|TzfI5GYv35Dfw-y1{)1&~GDL(GT z_FoscEsP5AoG+#8Sd&3Zdz4>F92{x$NYRshdEHZKL4U<>%FwIhC<}44RbUJt*D|_$ z6IxAbL?Bq|fK`6O8ACKt@ULu#R>Dq~3yw7$eiSv|8&$ZIFK^ekD6d}yC)MUCd(W+y zxNh2INW5}_k=;sE+5RbVr!W;X_4bCJBts~2pU9NqjRUFGtx-hrUY}5oq*rOy&grMM z_g~!(t!g{Np>!M+_aN%a&HJ%e+s<1>8+O_#wI$J4QHpl<_8`z}{;FJsyCKMqcUQ29 zme5pwO*n*D)@QQcceCjg?n4B!d?ovV%9)YMmQnf(XnGk3QOD636HU3Ml^&aU!I2Us z{z0bRHBgLqOg~N=i$F!qIrV(xTt?<%SR_Un(InppEd$H4APgcbPX_LxKPzV^J6g$V z-df8~*wZwb0-0=2v$akN+#Gj{9}c4KGD`4HdR*z5CK`rAN2|2KohQ`n1vkI_ETv|j z*4lv4g40hLVuO8;VUrWWoU-@PomzLnM@7bwA&Q8f;g+0=J@umk)tG{ox0J)^Ad9Ga zu#8Mi5fS~JMoI`(42)Rsw}{H|B{I(ha5m^Daqx4|pm&I?I|!9!tIF=mO=e=qPK=i* z{EMU#Eopa8*YFn0r|QrxTE?$tj1amRpbAQ@&~V9M+t~a?GP{AT#*b2mU*jHW59Fdd z##RUYO;0*BP~R?2zg3=)AQcjmdKC^%szhJG-kjb^ZuMtBpP;@2>=!?oNJrIPO1H~1 zsIiLKc+oVpQ-6kqfbS58Jkv&s3elwh2uaPgcoB*H16103oyPWzp-0dN8{AdU+2oKZ zC-+E90c_R?{@j*HKa_Dc-7JGizFPY={xnl_=~Z$~Bz;8G(t@^3s0>P%ckW1&`9 zvGYy$sIpcJ0auyoY;vQ7V16=!Sc0OU*pK%KmVHM^}QLY7l5xij$YCKbqQzS5VqB z2EmZ=#gveSfm^lGs>^)krM!aR{h@W@ojbgvII?t=RATJx*wAFNI7BDKip>S;YRV-T z$HmZTQjw}dzhHo6)nB|mneBvZm@1qZF$h~d{n$;#&UJe-ruky`Qw4{swFX5@qn$lO zojCQp$e)gkag4*7hYItbEo* zsUMYW-0cCLymwLz{$j<6;{gNUOd3JHjjc`9`wXZHt%>F-5s}zFThUkg_4a=M-P7Fw zkTYj=J%lR5zoWj>+lhPs&_n?>0EHm1^^i+R1ua3oFOAVTPug1Zq`KtBETJY$*e8jkQjKhs;C}b77A<%x+e>o-91X@ z^&64uzkughikYp2MJSk?FqywNAQ(t*xT$C&Sk^e(a1-7?4fcMNp{2D`mjnyxLfJAk&3;}k9CgoTuo4(39_{CvPKNOwa0{So;k$qJK1kQ?vQ8Cr?J0&~Re>`}l* zy)$oz1nhm*d~RGPaQ3&{Tg0DrTtZR%8?UQ3d}N+n$_$#rdwTmlIi7NZVFcIP903%*0a4)!2dGI!BLu-7*y)63<6~0aIN7u-6A9S!+SN(Cd4XGTd7?WYX$O# zH^7cSuyUpMvB^d5>5tN5yP6~KLr)ut8e-7kod#FnJ0nA-Y29Bqt)-g;O0$xs)9H9Z zpliHY6Tt^>fzIpkC~4s_Q*<($RGMsx;63~w-^SPlKr42iQ$T;NOqGB6?ZT zlIWeVJim9&`}h5E@0@$SnYrhiIWy%`o^A0b{;nFj&7cgt}Xz8Z%)Q=J6X2?-MbZ7bL_L$xDe!B#}tYkXygnRRw288 zV0;PltaBW9+P=Tv;P$7=KhkCFaEHexHXqkEuUWG)45Z6R)CEOp;_iHaO6iOx4=tz( za@gs(C3mNpo6lO>a*JK4Gu{+%eJ@8(_}88M=+-*KXoz2awJ|GCv=F>@gC5%uFXpck zo2J-gciP8&003yZ)s+CVpRy3e=w(l=N#%2L7Diqt$4Oe=Ua!sm1!(8_?@jHrR4uokwO_il|9G*`aN+-Y z9|G*Sk3$SC%A6_W5Mo}(P@>R^qqSCYv zf!qGaV2Eos^x@8vovWD4kZ;V7m0^9s|B6<8T{G9udS_bM6!hY>_2Q^>bSqT|qbv6w z)nM)e%w289(C{8%hZoAz^IQp6>Z?GVYQ`!%7(d^ZiZaS33=01|PnuAeRTLDiV$~}B z?q%@RndWt|ZfEL!t6-m7qI}b|y$>;Eg4Y{nO-&M<(8T_& zI(gD|4gVt`l5+S!ix(_i+cH_3_%Lf)1=yFQr*xE=yA?AXwGeQ5NLxW0!z}0WHD$;) zMb7cAH57Z~dwFqBr#krvUcruJ()1V{X=om?o*4w_RDoa_`h&p`+{v^BA3WN5uE|$% zy~<=pwE3eeUq6z;((LdmvXmW>N}-^m z+4~bm%Y{|kt|0TF+7BS{{mc%yUR!NiShSf=#~lDVjt*Q6=-w8*8#n59W#mT$Oy6wetdRpxZwkI6r#mz;scjsJeS>r{B>PPs{5Q*T2h97OHF(>w z2W~Mlf%rJ>P1lgqTGEt`zvY&MU`~l#x#xL%hdhO217fVnUTlYF0P<=w8b8viEEm6Y zuZeRgYXRpK9~HXg|$J?tWWbvJN9+~!}#AVBWPOECd{T%Vf04(-wSy|YoS2~}! zB%Pflom)nZ9VHzE>>EceHvbHNsCY*GYIKSX)Fi_a!8-iDK-i{aEmzjueoiF!gYcuh z9GE01-?==n1byQx_=?l4#q(q$r`C#bqFlx+nPu%`fK2&9-RA+x>_Eq#-wz>9@eJeb zETR?{it;+(06HC3VW(=OdH9x?szO)+kPsAjWb>xK3l|#ZsJ^uFgNVbix;vB%QW5L1 zGhN7NPeGLC&KPbDVN9chPEm17ig%Q-a0 zSVN*)Gk48yZ_Ntw<}^W(C3uB`q0W*#V{;`Dq$^wxYTb??Hcpq>5(!vIvCz;Db)Kn? z7eRdIJrHZ@2L2IIQyY*f85tuJe-EmXz!2NqW=mx(#xaPNuE_Z=Rkj9P|I&1)(%1t= zj4_ZV?tde@JJkojnz2th3H33wKtES5&h@)HC+wA>f@p;*uJY~CDsTF;vN5aOo zu9$1waF6h*l8SP9U(5uu#*;saBrcmDUqrZjSV#Tcnwo(aMF*PO&RD5LJprd~W~dduG}6vcb!C#d>l zc|1)W)8F?mRvdk{phrJOH>N+}fJ&}&(jwQY>b$zw*-FKD#>@(eBnU4dF_YObp{~Bf ze#}vywRIO;(c!R!U6YHA1Vbt|s1sHMj9%;!-1p9FixqyXwkcIWVxMX!g{U2<0&%+1 zJ*VmV`J_a%Zqz5d+DeaMzIC2Sd*0ZvhCXqKASlz4bjdr&_SQVuij7rAOl~Nm zqdC2x{y6+KV-_*Vn(;IpO{A!=f1j1?zR?4v@bI`zi~dqeU-U;p*IMhBPdk{J!#rO_ zhqC9LPZmXyAO&ntBZxsRWI|2!8{_=t!zT(PuwxNr&! z*Q8AtBBTRaJ+!ttsAW z(VTj1_1TwCHV*s`+Hpr|i3eWFVm1L)1cgw@*nS5ApG_L313z$S0S z7hwR=p)Z4w8(IWL{%pE33I1uNFxA5%%A{o?eXYp-i4UZ&a2u{XlOLpH(ua$na>qjP z`RICrZbcwPQJ(PQxSYrLb+H8a%)OrTuE0SUa)ZIJ-#h5IkR$LgQ(5}J4I;i&53qt$ zl!BXr3nGrE&-U@V-YP;DBL;Tx?poHg7sz>UdWgdhFMaTmAvXyz7!-MR@IJZ5H%MOl z)wD%2!e>ut0yc9pm{E+WA%6bW5)JRAhqgL?BBTe9|EM27F|1GD@s{T#KQ<4}PPb%8 z%`?x7rEQht^0>}q4h~mn*1{Z=fUl0jK;l(UOsryg=GKa^|3m2C-oz zN4%EfQna24K{EuT^}iDm@Ve~6CaK2M#)qgDb$e&+(^El_SSiqLuI1Jt$M=;)NJKj;N4bqLu-Fem zYNfW4Y+3p`PeCA0nK#kz9^ZYjkcI30`2aEJg!dOG#1s9=d2Sqm0A(&S*iE-cXkH5r z?o$`nQd1bB2pwps;@!fzPbknpDl-YLoz3ZD!p`CKB4mxb}?^Xk1gqBK{=o zc;dH!x=e9VHy5nW^+2D#D0{>ucD_2ZU!_(I25q;>bWOPSGHQ3>5KItiKk~96)rVpE zzphah-(HE3b2y&kkwiDSTdc^_)Vj6v5+0q>F0UQZ5!aN}g(rl`BV8lQUT%_($%A)O zP1gCwTrXH<+>|0X?-y-fmLG=}&`~5Qav^mXbg3C)0+B1nj*M7%{3~beoOgYRN=yUC zY#_cl>W_j1lr%HV{9UODFaJfw^RloaHjc&MCAVdJ1~UxuXL~P}f3rd(d+_Hi0(CWn zUo2M95-QR1Y7;DRE@!9wmFuHY!&l@^x7LOo*Ov$}ysy_Sgu#zYxp+V9AQQD7sONW& zr!e{*`Ys>IXvA zdS}~jl~>3l?K`%$X6MjZFK4`bPEsB#3?>YJa>6g`rO6EmYK`jipJQU&RYs%*WXF@d zfT%%BJ?PeFMd^jus_iwP*_riIIp7z^s?Aox1ovURCA9*r@&9$G!Hy)I$ogx@sLXcb z&iF1kM+2>d@GvQ2CV0|N!8}+=xPX0@sm$xFJ3Xewk0>H(rhZB2wt58$_-Fk{_^V(8 zd+}${$h9*|rero#y}CrlE_&#jRFfHeuU+I{`S+a;jzw3QkaZ7*^3ca@FBcknU%8`p z_$L($1Lt`Q`U&|=6Q9x02LGFA6%@zc8LIvBCGP0FhRW%_H-*y0zSJ5TCFdGjxB8vO zM9&-553$r-PCItx6iJVOLh9-Crlao2Ks!(v4#pjVydzD_D}7BrvR) zsARB?4^2(#g7(Ad82gh##6$?r3};a1lOdP@#kCLzW>eZls=|G^{_QK;AlwIOZRJsk zV*=V9(IyF7Nf@dywalx%{5przmRyG)lzxRxUj*%;WSuVp{rHz(7?zEqz!wJ78 z+h-C5pU0yJ0#%*^Ws6Dxc`x-s|6f>2?$&e!vd`3TL>Sm>awATsG1_y2rorKj7ToLI z%kZuaK!Y2pdm5wEp}&L)ay)=-flGA+g9WF{=$kT!SP5cw-JKS?&ju^pQbK!?b~Ks zcgjp~dk&RsF%M=byPXSf6MO{QYFbpl5|S}aGYdHAiBw8?`Be#3+5xuEQc_wPkw$WW(lG&% zlo%=d&d(q4{o&s8obx)bd(MsLJmXvg7^{#064}lT&?190F zr4Eg*i4}bN!9j!jR&`)Fdi-$rj(zm|m9}}^n$>S4j5+a!WN&m==rcu?48{|O7vPe- zjt1_D-N{x~vrioaWzV%)2>AlNWqFf?6vdiW{8>^VZRP2!XTw} zzK6vCneI6ZVcTrcN(I`ZYga`~N@UOVra zJAMfjB6wuQFU!&$lHh|e;Tt(YW$8qp+&Z3virQm>ckPaf&X}->VDiU+uWHqdi47UB z;h`4ynZUb)wYQ%5Cv>Z-yr3@TBHhReu@-utEeOL6vv$TAqL zjUE+BOf|P|wqLKxMpI{?t^*h%M;tj4^@>@pK3Cs?WDm>V&OBbj1TaOa%g`P$g>jvZ z1l;`q5#E!L$6E&UzMLD-`XZs_@^Ztal*DMc7FrZ7B-} zf)A9qLTWxB*?ylYU)gCU0d>5X4HO7g+9pC2))}@HDKX6~k_8msQW(TjHuoM2P*_Kn zQT!xYQikdXbqf1+`X^~41^Rwt|E$8`JL&u)4LjY+fvXMcduAsX`cex)61<5MH~Bd^G3}6}HV^=9P``TB z{5RL02OO(&IP-&SuDe^C!$TAphVF>ul{RA>elv)|Zdl+1pItmhZKDPuI%0QjB1Ft{ZHY=Vjgr{fXXV znK-dEh}Or0tJ;n(nEHwD>&P_i8zo^vBMfRyIor4Y%Q{O*|9J!iSa}pk$5T)j3m;g+ zIgX7Cqz-hx+)>*S9bF^_2p1}y1&HzawM&oo-$daU2f;C82gvXk1tyfvv^ij9x;DD73nT)-{ zlJIZM09a_gz@s5`ZQlM=<4{V_I+C_yxhJdS$T{qkO99kXCRi`d)Tl+v3HrC2M{nZn^zwY{~41jJ-x0A*(Y65`C~A%&o;Dj)OMc&3iZi=S*d zaoK}PvlV%HnIam050-Du2g(Yz5;MRO5dabOI>i#k#uFs8G?aJ~fT|=7f{#|Bn zYG4^{qKL&3CfQdqOaR7G@8ioOkt80wy2M#r+0Mx{jd8HmWltu_CLh)Ug{9r+#1zWR zQEBm%U^MTl7?VWYO1v*7i&hB$EiJ8ab1XuN@>GP^NyK|9KaDo_a+~FB@C`MM z0?5lV5R5s@9L}8SXHFY7Rw)ql~%XHwoa%w-@HSfl`PUEh8)NT^&_(|2SFpX;a#rsh>WaZZ6$?++EGC$q3sv68q zcGJ20;w!nx`~5-iuc?RBCwOchJ-K~qKfq%oNcX!)v+Tu8wwkm3A4gs$;Zx_edaF%l%^5Qz41zuDk?d%)VZ<-4qS<3<73NBLq2{L z%4W+`&leGg3e_xtI6A3E8D(833${5Ut4#8HQdFM^$3cJ^VfNENn>i25Rbx0@{b6Bz zWqZkN8&Yzs=1=q{Q$Z}##fbhN7QS$(aNN{moD?@13}mQ9wuR)Q`hKrw(*E&T8w=F` z@htT-6>|7GkA%cRV4o>I^p&k;)Je8 zoTM}wab%XGYK1@FMUVivf*#iU}sG+bq&-B(#2#1%uKo?F^3f z3He0FP1Z^XU}s*Uf>5HafB&TX&$>RN=fS&`ND$3a4jkUiRTK4aY^+HVA0M%bSb;?` zjk>%FJ~D+pYDa(W+Ffp;z$_Aufdy`vEYCS)dU4Uj;y12iPxZ=|r;wDit$kCbFbJ@^MvQ>L^>&tatYHSa+IWj2z`VqtMf5IQ9ME-@iH(=h$fP62y zkibN>BEVTcgRErXV7>NMzU>s$a_hx91hs#zQivCUQ>LrfQ8fCRwc3(aw;#}31lnEw z%^JggU()ZQK3rD{W)_vH{vqx@_=R@z-jgZjF^7LA6lx@9m_cTI6IYI?@%?HAXlvQM zuXt&mv`cQHC|>|9KEYI^?Ls*@8z?IhBc|xN$zHth^~B9Bug=hHPnZ+;q_WUrtCA3v z4vB?)dVYS$xeV1Itz>Fi3}IH;a*f@SlURrfjW%wCcAl4*Vzjo++0dCQ_)A$vN8LBC zUq|v++*^`m!UjTpH|QoSW2+T=TilkSAa9#aJ6=;$S}%8y_Iq@Z2(?G<&$P~L?s13z zJh2j|qk3@GosJ$o>1D~c>@BV%uHF6`zXmY4-w9N=x57NxC4;emxM#oD-7Hrf_+gwZ zqPP%>@?T1OWHzBfg~QZR5gQD6(W6(2Y*m+$)yqwE+-)%&E-Bk@qf1H^TtRzMnVmt6ct4-CQ{&;64OfsVJF1^(S&hTTq0H}nNIJV5}97y(12 zf(<;QEiYti-M$Mi)T2ekWYLq3i~DX4n`+k-xP5X7;{{Z(P|b+MGeugU(Z*l(`(Pyc zc^|-i+a0Kp`Gz@Dy^r4`7+7Q}kfu=o4!s6bhAv+E?C7W@)RV=G`FWNVfu-!YX$*7< zQh4U3UQ1{+lb8Ox#wJ;rKq(Ghz4pvv{Fu3XlOyB7;Z=8KKP5F!%1W^hYIgqUo?KOX zZjg%7Y%9*Oklz^<%TqeomiRG$H~&Tt0UaqRi1B7X?%uQARHK&ZCDr5ZdWg00f3%?F zw$nQyl(PN7C2s0%wd$w5r+;?>*8b7~eZ@!T8(5sbWL{uPZvekHOw6rUn)>17X?Zut zxE(*dcdKxDb$tl7w>YVf5R6m~R3O!V2W_VPszI;x9;8U?lgVtc-%-OX#o_RD41qR3 z^?}x1KF!;_T9H7EzX%zhdb_e9#f)68Pq~@El`k%(70$*sB>Y}$)Ge*%BAuXy&P9(qAUxygpdV6rBw6~km82W|Y|74J zgFY=^O&}ThQCkZOkzIvBSi^eXE$GB)4;hK=y{M+*t(NT0o{n~vAKKX}oiFLiWih$l zNSA%6eDr8PJ76o0DZ@KBM8Snqy$rz6Xr)D>=th$369gJo`nmR&EmyP1bth%y5BRkQ z%+~N@0u*y|siIdWx$Rj_OB#9oj22<0FL8e?7LSuq$gw#bF*n>0EF`7Vl1&(&TI2be$8(t{Kia&d z3UV2b{N-AvhrdE4Ifg#C3U!94amuKl-5( zd0xr#OZZS0E?)t{zVc?88N}MsjDq_lu^tJ!)2mCrKcR8tDF!>Ujk!j5qiUIk^33Hv zN*n5s2TLgb6}fYHTb<74yy&Jp7uy5WNC;s*rv9CCU(ICfT%HJ9oE=N@{pM5`($8ob zk5M3f|Mb)r;+wrh%N3uYPQ^5Ciq@CmlVD_jiE7*ORUSo39|?fFFi|A(Ne5sBOFX7LOqmRvh>YI(K_HXMfDb-Xmj(6XX^Jak_Hz;Ytl6H8XES1s`dgTP7N@365hb z$9`@Xw<3SlCz(sF>e)Qenr$(LB~c(Nlj!Htf(E*-pZS&%G@aAWy20*X?Sy(Y*sm-~ zfR=@RK5dL;NLn1nIuj{;9$=C510^Ar@cxnfGZrDex5r@^ZL_aTi;{(`cgvvg~ zLN}T*-rZBUPtVn^oq^|$9*1QLyx<{orHlYj`p0KvQL~+PurrVOrpupS`RXRtgE

B8)fT0i0}`@?rc3_IuTLWd;(M9j>1r1LKsewv(S`fo_|qeUj$k z%zc_ut}|-FHq@Ma*WXkT`=|Sj(32c?5PPR_jMx2VHZ$g7<5EK<8fcHb&HY`mCS?_S z3&-CE)~fTkCGF1MVeH~a2wz;Kny?Hu`Y?0lk|O)s^Juu^@G|Z z#+b3vyIoF3Oe<1lR0piaH_l?qfd4Q2`niJN#3t#W8U_itRGR9!Z z_M8fivgPh1Of!YmISO76lD<*5JRLG z!N(SmNKg?_u!(efdDU@r|rzLw(ioqq6FS7H`2ib{GWZy&{Shk?D z@c*9MDoRdk!Gd5`a_l-^P7KUuF@hBQVNclFifnCVZDj+S`z9o^k~vH+Gm%GB1IzWm z&)sbs&CMYoDK#+)c8iW?M)J5{fN3XhXS$Dr4~rWKyRdi>QA{=*z>DCqk`iIAVr?{w z&E%rNN>`^qHwPeNqds^E^bGU{+>$x0L>}xE$z!EO@R(W%KU$z?K%j$jEGsV28@#*t z`uMnQ3k+}wOiGG}6PVz{@l2R(1t+i)Q+Z4-oD>a5v!bHdti%{Nf};@0N`#$Kqaq?% zyuC0l2~LOrJ9x1yE^4vT0z_w*AQYqlxRbr%uFRnlIs{=LXtxPbr!?A=C=yhg?=2U2 zAfqm;{Bl8l7cR1pEd8T{ZKHq+s!*mmy0~`6Gj5O)gEK4UR8d&lHa5WO1^!bM^vz$t zh)k?+t&dL}B${eyhb)GGe;qvtIanIfG4cqxIM5x&b9x936`Um&r>hPvvF?Ghyse+r zm2R_tcDlCM{<(SUkh3PKb(rc+9u10YzM>YM&K;!8R($Hv3O!(O7H2iXD2%fP!ak2! zU(Nxnlxo3HCQuV{KZf-@kL^2;AGmAc`-`Q&p50v=w}3z&I(SmUx2G}3(o)CLGD6C8 z!Y*ZmT*?U>&k3K;iNNK4YHu?p=aHsR9Y#S_Yba&Y#2VujH9t^lRI+oM7C}*nNnkYJ zn8>g7tdEXsW}R%0J=31h*J9b%qNP{@u&Iii2C8BS>;J1ohm^;#{bz(@!9rV-^ijnz_BF1sj%0qBQu^IzQs3(-J;vLl~ts?gj>sA#NZ>2V7 z`Oyr`M7%=^&0z@2#wbwyN2h?Y62*1=0*hYr3;ou8mPprhYtUYP?iR*Hiwsa~X$MeT z)HZX9+f4C@7q!Vk*NOx*Dp912DBx5$s>DgnP!S}#<(yt(1Bi;x9rv@zonp(0?AqOmf&m#kKqg&~UY0fWSDe0IOn(~7JiCvymbucN@v+1xhD4Z@f~Q^_WG zN^QNcre1n(cd*PcJ)g1Twga|y{(;@*}RadT5|%h@x{Y&oDdpBA@R zip7>^TAJRAE#>W}#hsGgmUAbY&&bhGg01|(%+tduN6PPYSDM|TyM)udFT4pRDwS}^^qWadOOe~Vb`8hVe>gH37f7- z-uD6q!*3~flJFg1+l53UFeiPrc1y&@Vo{6`oK!41DLx}_NnCrYN$%`V&j>%xocuC8 zWO?G`m&IXYMK$8*ofdspfgtijX%haj6+ZmI20*B6k!WT__ROR2#6OUxytkizlUjRL z3*CJbU;~9|9)|WDt_viq5xCo^U3h^XHI5*-XCZ|H zi#>ZPN_DBRM8Pmky;|f)jjtBSXz}Ok?=gOa>kOzYl3+MAu2Fg~v~XD@#(K6cYS0rc zYDEZu)ofLrjx$wMhxMY8g8BiFYlodY8tZfeJR92pD^Z<+7nR(O4ND};@L)%sZkQ)g ziVa90Nrh{qFkp2X5w4K&v|IpKoyg)-sgmP-T7N|;!YZqn>Pc+pQ@z2dsMPa0v`{u# zRzYLifl~oid@7qH4Gr^dOT~n0Do!P73yP1ENP%!u5zdQxzRe&$kvy}4%90?$8@mj` zih=Nec)NO896|_7aF7YPREg{!tq2ez6RwO3_r3f>b4DCVDq~0x;TGqQ^MUZ0`=Nyt z!7u}`;?oMjjxcsdeOVkJ2x&*!X6|#@c5m*5HX$;+z!!phwBy$xkaaRuAjeEJvkFNe zNZ2~%(FQ$P7*0RM0`1&SF>B;_I}?fYekTpnwm}M!*d?QAn2HR%EJ$5J@kAoff&}Ug zMcAtO)V#2AZkz%L?fB(N=xtK)287&+)P~;I)s6-ud#MJ`1lo$-7pE8HH1(^|_tz#jr z$kK7v&QBJ=rGQJ0P4N!EYOJr!w7*!eFlR$qKJnO1hgd(WRVOiqI3RH+(XBz zK+aqQ?L~4Xm7-oP*h-Yb0zM6h11dFgw1Dlpf)Iir^aTu{!M01o09Z*wU8s_-;P_^O zNXBTg8v`J2n-RuS0U>^%1A-ndR)@~17`bgQ!=Wu~qZCSH!oZA$kZs~ntI zZDn>Yajq^KxTo5MN-;MDC?OI7d_Y7CLa8UXG@6B}s0>LR_d=;8z+2r^B%{RvDfSwo z)_aJkaVHO=NEUj81VWAqUKxdUxiqk(Yn;(Ut{bL-_{2pvfdC4P2S<-55!+;p!Zu)k zkRfD@BX+V-O=v1H8OroHmy&zD?!wKxQwm=bK(Xztur_irpaEZ0A!s4EQUR(Ej1aPc z8}QqG0)U!Tt`qn+iT3WeSA~JFSdsYWrEvb z%6OcdDC>c{DzeMGvP(D^#=2#+0*d>2riWn{Zd5=PVFPIKa}|t2f8WYTD*0BEAc$&y z?9ec$sV%J^+>Buj$O=QSIp~PO;(CCfY*ivub?*8Qd55a%6J6^iT1&dKxx*|K2$S8T zbu2GfOIJ^Pu!dm|1@GA1qn@c%RMdJzbI$tu;_!#5a5k(;$m>F3OER_^4+vsp!R(|e*ZxVLzazc5p ze7v47Pt}@!s0X2h`}VcEt+?~zWAxd%0#)Iqdp|FPvkkJMPCkBiw&AxYcJs->BhxiE zO~XL4fOme_bRg@vjuY38 z{k-L;DXWo)w>lr^uyYG{(#X42wt%Y#?gOUAGa>ESgl2QF-2L0>%+%q@iU zNAw=j-khj^3bs46ekjdf5BYaOxA@?NySpkW4#xX5)frd&w@g2qc*g%%eM^5-z5RJo zuJOCJUs+a{2pZ^Vdd_Y?qa8mU)_o8qdpByHo<3-V9X6`Fw5PMcIQ{7RZA02KA28_| zhhJ0~-KTDGZ*HiY_BO-Gj8)~5$7-i~qJCf4G_59en;VE6B!l!wBQWFX6_QBaFAwCeZtsojq%v-ptgvU&1PsZr^4q^kFIHM9lC7mS4JTG;OC#hW3|0$ zv6UGOsIBUF{bGUm?O|4Oru%}E#4Ne`#keMJ?Q%Qh&!xR)!6w}YwEGx5*A4iUkM0<~ zXv}K*^@sE9^}!9#j&3t3*0IZ5H?-%W|#i?&qZ!BCG?}8@`-lCvP zzd$z;4y1!1DRo7B+!ppXCw!%6Gjjw zn}r|t6npzFeII;eZ|drjFQa?Cqp+R)TZd~lKF)simh~{{cRfOrFyN5Nv*4P|2`K?l z5YKn%E8@k_ZMW9kZtd9MPMXTqcoVqB?1O7?e>&=8v}Nz)_?p%uv#3?_R|j*W7qRGy z;1|3f|9EEUkV8_(>ZFXu3HAGNULIG5%hL7azwa`8WAB=?f#h=Q%A@*6BQJ-JEMC9P zy7#c=nGrSaz{qR;o`$2NhEGJqvqgBVal=gSS+@uq$p{&`8vXE41Ebn%b!!$Trddbk z;ZceK5eS{W!CiN)_0)$wHV^n$&TZni?uyN)d~pBjtW8$hS%Ess!0SAtvOZ2&-+Q3@ zp&ciW6L8Y*C%twYgX&lhP?7EC5YQcmv_88oFBNcZ=Ji-?t`7z zUZQ@we0h`}WAwV#7Q*OP~>>!GX6^j&51ZV ol72#Sev@}}S^L7fGvm?fyZfvLZk((N{)KI7&N;Ctm#3ohAG28Cwg3PC literal 0 HcmV?d00001 diff --git a/modular_citadel/sound/misc/sprintdeactivate.ogg b/modular_citadel/sound/misc/sprintdeactivate.ogg new file mode 100644 index 0000000000000000000000000000000000000000..c22587ace0006d105bf8aa6174102c1d0b3d117d GIT binary patch literal 5156 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 literal 0 HcmV?d00001 diff --git a/modular_citadel/sound/misc/ui_toggle.ogg b/modular_citadel/sound/misc/ui_toggle.ogg new file mode 100644 index 0000000000000000000000000000000000000000..7336b9cf0e13c24c841a65a297ada9706f533336 GIT binary patch literal 6537 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 literal 0 HcmV?d00001 diff --git a/modular_citadel/sound/misc/ui_toggleoff.ogg b/modular_citadel/sound/misc/ui_toggleoff.ogg new file mode 100644 index 0000000000000000000000000000000000000000..98df1726e987aeac5c8bf926842af8bd0109cf4f GIT binary patch literal 6934 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