From 4a5901e2ee1a643f0f3102a7d80ace026655859f Mon Sep 17 00:00:00 2001 From: simb11 <84613249+simb11@users.noreply.github.com> Date: Fri, 16 Aug 2024 21:01:19 +0200 Subject: [PATCH 1/9] bbra --- code/__DEFINES/combat.dm | 13 + code/__DEFINES/dcs/signals.dm | 8 + code/__DEFINES/subsystem.dm | 1 + code/__HELPERS/unsorted.dm | 20 ++ code/__HELPERS/view.dm | 2 + code/_onclick/click.dm | 21 ++ code/controllers/subsystem/fullauto.dm | 5 + code/datums/components/_component.dm | 4 + code/datums/components/fullauto.dm | 297 ++++++++++++++++++ .../modes_gameplays/families/outfit.dm | 2 +- code/game/objects/random/random_guns.dm | 4 +- code/modules/client/client_defines.dm | 8 + code/modules/projectiles/firing.dm | 1 + code/modules/projectiles/gun.dm | 41 +-- .../modules/projectiles/guns/plasma/plasma.dm | 4 + .../projectiles/guns/projectile/automatic.dm | 64 ++++ .../projectiles/guns/projectile/pistol.dm | 5 + code/modules/research/designs.dm | 2 +- icons/hud/weapon_pointer.dmi | Bin 0 -> 234 bytes maps/centcom/centcom.dmm | 2 +- .../space_structures/old_station.dmm | 2 +- taucetistation.dme | 2 + 22 files changed, 483 insertions(+), 25 deletions(-) create mode 100644 code/controllers/subsystem/fullauto.dm create mode 100644 code/datums/components/fullauto.dm create mode 100644 icons/hud/weapon_pointer.dmi diff --git a/code/__DEFINES/combat.dm b/code/__DEFINES/combat.dm index 6c593f9a140b..b848b5560faa 100644 --- a/code/__DEFINES/combat.dm +++ b/code/__DEFINES/combat.dm @@ -111,3 +111,16 @@ #define MOVESET_TYPE "moveset_type" #define MOVESET_ROLES "moveset_role" #define MOVESET_QUALITY "moveset_quality" + +//Autofire component +/// Compatible firemode is in the gun. Wait until it's held in the user hands. +#define AUTOFIRE_STAT_IDLE (1<<0) +/// Gun is active and in the user hands. Wait until user does a valid click. +#define AUTOFIRE_STAT_ALERT (1<<1) +/// Gun is shooting. +#define AUTOFIRE_STAT_FIRING (1<<2) + +#define COMSIG_AUTOFIRE_ONMOUSEDOWN "autofire_onmousedown" + #define COMPONENT_AUTOFIRE_ONMOUSEDOWN_BYPASS (1<<0) +#define COMSIG_AUTOFIRE_SHOT "autofire_shot" + #define COMPONENT_AUTOFIRE_SHOT_SUCCESS (1<<0) diff --git a/code/__DEFINES/dcs/signals.dm b/code/__DEFINES/dcs/signals.dm index e6be0a84a9cf..7aeae642e3e5 100644 --- a/code/__DEFINES/dcs/signals.dm +++ b/code/__DEFINES/dcs/signals.dm @@ -424,3 +424,11 @@ #define COMSIG_REMOVE_GENE_DISABILITY "remove_gene_disability" // send this signal to handle disabilities in life for mob/living/carbon/human #define COMSIG_HANDLE_DISABILITIES "handle_disabilities" + +//from base of client/MouseDown(): (/client, object, location, control, params) +#define COMSIG_CLIENT_MOUSEDOWN "client_mousedown" +//from base of client/MouseUp(): (/client, object, location, control, params) +#define COMSIG_CLIENT_MOUSEUP "client_mouseup" + #define COMPONENT_CLIENT_MOUSEUP_INTERCEPT (1<<0) +//from base of client/MouseUp(): (/client, object, location, control, params) +#define COMSIG_CLIENT_MOUSEDRAG "client_mousedrag" diff --git a/code/__DEFINES/subsystem.dm b/code/__DEFINES/subsystem.dm index f9b91ad1fdd6..30133b79d53c 100644 --- a/code/__DEFINES/subsystem.dm +++ b/code/__DEFINES/subsystem.dm @@ -81,6 +81,7 @@ #define SS_PRIORITY_LOW 1 +#define SS_WAIT_FULLAUTO 1 #define SS_WAIT_EXPLOSION 1 #define SS_WAIT_INPUT 1 #define SS_WAIT_DEMO 1 diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm index 0c3785628578..41209e09c563 100644 --- a/code/__HELPERS/unsorted.dm +++ b/code/__HELPERS/unsorted.dm @@ -1662,3 +1662,23 @@ var/global/list/WALLITEMS = typecacheof(list( location = location.loc if(location && include_turf) //At this point, only the turf is left, provided it exists. . += location + +/proc/parse_caught_click_modifiers(list/modifiers, turf/origin, client/viewing_client) + if(!modifiers) + return null + + var/screen_loc = splittext(LAZYACCESS(modifiers, SCREEN_LOC), ",") + var/list/actual_view = getviewsize(viewing_client ? viewing_client.view : world.view) + var/click_turf_x = splittext(screen_loc[1], ":") + var/click_turf_y = splittext(screen_loc[2], ":") + var/click_turf_z = origin.z + + var/click_turf_px = text2num(click_turf_x[2]) + var/click_turf_py = text2num(click_turf_y[2]) + click_turf_x = origin.x + text2num(click_turf_x[1]) - round(actual_view[1] / 2) - 1 + click_turf_y = origin.y + text2num(click_turf_y[1]) - round(actual_view[2] / 2) - 1 + + var/turf/click_turf = locate(clamp(click_turf_x, 1, world.maxx), clamp(click_turf_y, 1, world.maxy), click_turf_z) + LAZYSET(modifiers, ICON_X, "[(click_turf_px - click_turf.pixel_x) + ((click_turf_x - click_turf.x) * world.icon_size)]") + LAZYSET(modifiers, ICON_Y, "[(click_turf_py - click_turf.pixel_y) + ((click_turf_y - click_turf.y) * world.icon_size)]") + return click_turf diff --git a/code/__HELPERS/view.dm b/code/__HELPERS/view.dm index 22637d252b9e..6b1ce1b34a25 100644 --- a/code/__HELPERS/view.dm +++ b/code/__HELPERS/view.dm @@ -10,3 +10,5 @@ viewX = text2num(viewrangelist[1]) viewY = text2num(viewrangelist[2]) return list(viewX, viewY) + +#define CAN_THEY_SEE(target, source) ((source in viewers(7, target)) || in_range(target, source)) diff --git a/code/_onclick/click.dm b/code/_onclick/click.dm index 79e3368daacf..1008b1608f09 100644 --- a/code/_onclick/click.dm +++ b/code/_onclick/click.dm @@ -53,6 +53,11 @@ * mob/RangedAttack(atom,params) - used only ranged, only used for tk and laser eyes but could be changed */ /mob/proc/ClickOn( atom/A, params ) + if(client.click_intercept_time) + if(client.click_intercept_time >= world.time) + client.click_intercept_time = 0 //Reset and return. Next click should work, but not this one. + return + client.click_intercept_time = 0 //Just reset. Let's not keep re-checking forever. if(world.time <= next_click) return next_click = world.time + 1 @@ -160,6 +165,22 @@ else RangedAttack(A, params) +/client/MouseDown(datum/object, location, control, params) + SEND_SIGNAL(src, COMSIG_CLIENT_MOUSEDOWN, object, location, control, params) + if(mouse_down_icon) + mouse_pointer_icon = mouse_down_icon + ..() + +/client/MouseUp(object, location, control, params) + if(SEND_SIGNAL(src, COMSIG_CLIENT_MOUSEUP, object, location, control, params) & COMPONENT_CLIENT_MOUSEUP_INTERCEPT) + click_intercept_time = world.time + if(mouse_up_icon) + mouse_pointer_icon = mouse_up_icon + +/client/MouseDrag(src_object,atom/over_object,src_location,over_location,src_control,over_control,params) + SEND_SIGNAL(src, COMSIG_CLIENT_MOUSEDRAG, src_object, over_object, src_location, over_location, src_control, over_control, params) + ..() + // Default behavior: ignore double clicks (don't add normal clicks, as it will do three clicks instead of two with double). /mob/proc/DblClickOn(atom/A, params) return diff --git a/code/controllers/subsystem/fullauto.dm b/code/controllers/subsystem/fullauto.dm new file mode 100644 index 000000000000..856bc49f8e9d --- /dev/null +++ b/code/controllers/subsystem/fullauto.dm @@ -0,0 +1,5 @@ +PROCESSING_SUBSYSTEM_DEF(fullauto) + name = "Fullauto" + flags = SS_NO_INIT | SS_BACKGROUND + priority = SS_PRIORITY_LOW + wait = SS_WAIT_FULLAUTO diff --git a/code/datums/components/_component.dm b/code/datums/components/_component.dm index 2fe896c8820e..52928242093f 100644 --- a/code/datums/components/_component.dm +++ b/code/datums/components/_component.dm @@ -151,6 +151,10 @@ if(!length(signal_procs[target])) signal_procs -= target +/datum/proc/RegisterSignals(datum/target, list/signal_types, proctype, override = FALSE) + for (var/signal_type in signal_types) + RegisterSignal(target, signal_type, proctype, override) + /datum/component/proc/InheritComponent(datum/component/C, i_am_original) return diff --git a/code/datums/components/fullauto.dm b/code/datums/components/fullauto.dm new file mode 100644 index 000000000000..e7f687caaab0 --- /dev/null +++ b/code/datums/components/fullauto.dm @@ -0,0 +1,297 @@ +#define AUTOFIRE_MOUSEUP 0 +#define AUTOFIRE_MOUSEDOWN 1 + +/datum/component/automatic_fire + var/client/clicker + var/mob/living/shooter + var/atom/target + var/turf/target_loc //For dealing with locking on targets due to BYOND engine limitations (the mouse input only happening when mouse moves). + var/autofire_stat = AUTOFIRE_STAT_IDLE + var/mouse_parameters + /// Time between individual shots. + var/autofire_shot_delay = 0.3 SECONDS + /// This seems hacky but there can be two MouseDown() without a MouseUp() in between if the user holds click and uses alt+tab, printscreen or similar. + var/mouse_status = AUTOFIRE_MOUSEUP + + ///windup autofire vars + ///Whether the delay between shots increases over time, simulating a spooling weapon + var/windup_autofire = FALSE + ///the reduction to shot delay for windup + var/current_windup_reduction = 0 + ///the percentage of autfire_shot_delay that is added to current_windup_reduction + var/windup_autofire_reduction_multiplier = 0.3 + ///How high of a reduction that current_windup_reduction can reach + var/windup_autofire_cap = 0.3 + ///How long it takes for weapons that have spooled-up to reset back to the original firing speed + var/windup_spindown = 3 SECONDS + ///Timer for tracking the spindown reset timings + var/timerid + COOLDOWN_DECLARE(next_shot_cd) + +/datum/component/automatic_fire/Initialize(autofire_shot_delay, windup_autofire, windup_autofire_reduction_multiplier, windup_autofire_cap, windup_spindown) + . = ..() + if(!istype(parent, /obj/item/weapon/gun)) + return COMPONENT_NOT_ATTACHED + var/obj/item/weapon/gun/gun = parent + RegisterSignal(parent, COMSIG_ITEM_EQUIPPED, PROC_REF(wake_up)) + if(autofire_shot_delay) + src.autofire_shot_delay = autofire_shot_delay + if(windup_autofire) + src.windup_autofire = windup_autofire + src.windup_autofire_reduction_multiplier = windup_autofire_reduction_multiplier + src.windup_autofire_cap = windup_autofire_cap + src.windup_spindown = windup_spindown + if(autofire_stat == AUTOFIRE_STAT_IDLE && ismob(gun.loc)) + var/mob/user = gun.loc + wake_up(src, user) + + +/datum/component/automatic_fire/Destroy() + autofire_off() + return ..() + +/datum/component/automatic_fire/process(seconds_per_tick) + if(autofire_stat != AUTOFIRE_STAT_FIRING) + STOP_PROCESSING(SSfullauto, src) + return + process_shot() + +/datum/component/automatic_fire/proc/wake_up(datum/source, mob/user, slot) + SIGNAL_HANDLER + + if(autofire_stat == AUTOFIRE_STAT_ALERT) + return //We've updated the firemode. No need for more. + if(autofire_stat == AUTOFIRE_STAT_FIRING) + stop_autofiring() //Let's stop shooting to avoid issues. + return + if(user.get_active_hand() == parent) + autofire_on(user.client) + +// There is a gun and there is a user wielding it. The component now waits for the mouse click. +/datum/component/automatic_fire/proc/autofire_on(client/usercli) + SIGNAL_HANDLER + + if(autofire_stat != AUTOFIRE_STAT_IDLE) + return + autofire_stat = AUTOFIRE_STAT_ALERT + if(!QDELETED(usercli)) + clicker = usercli + shooter = clicker.mob + RegisterSignal(clicker, COMSIG_CLIENT_MOUSEDOWN, PROC_REF(on_mouse_down)) + if(!QDELETED(shooter)) + RegisterSignal(shooter, COMSIG_LOGOUT, PROC_REF(autofire_off)) + UnregisterSignal(shooter, COMSIG_LOGIN) + RegisterSignals(parent, list(COMSIG_PARENT_QDELETING, COMSIG_ITEM_DROPPED), PROC_REF(autofire_off)) + parent.RegisterSignal(src, COMSIG_AUTOFIRE_ONMOUSEDOWN, TYPE_PROC_REF(/obj/item/weapon/gun/, autofire_bypass_check)) + parent.RegisterSignal(parent, COMSIG_AUTOFIRE_SHOT, TYPE_PROC_REF(/obj/item/weapon/gun/, do_autofire)) + + + +/datum/component/automatic_fire/proc/autofire_off(datum/source) + SIGNAL_HANDLER + if(autofire_stat == AUTOFIRE_STAT_IDLE) + return + if(autofire_stat == AUTOFIRE_STAT_FIRING) + stop_autofiring() + + autofire_stat = AUTOFIRE_STAT_IDLE + + if(!QDELETED(clicker)) + UnregisterSignal(clicker, list(COMSIG_CLIENT_MOUSEDOWN, COMSIG_CLIENT_MOUSEUP, COMSIG_CLIENT_MOUSEDRAG)) + mouse_status = AUTOFIRE_MOUSEUP //In regards to the component there's no click anymore to care about. + clicker = null + if(!QDELETED(shooter)) + RegisterSignal(shooter, COMSIG_LOGIN, PROC_REF(on_client_login)) + UnregisterSignal(shooter, COMSIG_LOGOUT) + UnregisterSignal(parent, list(COMSIG_PARENT_QDELETING, COMSIG_ITEM_DROPPED)) + shooter = null + parent.UnregisterSignal(parent, COMSIG_AUTOFIRE_SHOT) + parent.UnregisterSignal(src, COMSIG_AUTOFIRE_ONMOUSEDOWN) + +/datum/component/automatic_fire/proc/on_client_login(mob/source) + SIGNAL_HANDLER + if(!source.client) + return + if(source.get_active_hand() == src) + autofire_on(source.client) + +/datum/component/automatic_fire/proc/on_mouse_down(client/source, atom/_target, turf/location, control, params) + SIGNAL_HANDLER + var/list/modifiers = params2list(params) //If they're shift+clicking, for example, let's not have them accidentally shoot. + + if(modifiers[SHIFT_CLICK] || modifiers[MIDDLE_CLICK] || modifiers[RIGHT_CLICK] || modifiers[ALT_CLICK]) + return + if(source.mob.in_throw_mode) + return + if(!isturf(source.mob.loc)) //No firing inside lockers and stuff. + return + if(get_dist(source.mob, _target) < 2) //Adjacent clicking. + return + + if(isnull(location) || istype(_target, /atom/movable/screen)) //Clicking on a screen object. + if(_target.plane != CLICKCATCHER_PLANE) //The clickcatcher is a special case. We want the click to trigger then, under it. + return //If we click and drag on our worn backpack, for example, we want it to open instead. + _target = parse_caught_click_modifiers(modifiers, get_turf(source.eye), source) + params = list2params(modifiers) + if(!_target) + CRASH("Failed to get the turf under clickcatcher") + + if(SEND_SIGNAL(src, COMSIG_AUTOFIRE_ONMOUSEDOWN, source, _target, location, control, params) & COMPONENT_AUTOFIRE_ONMOUSEDOWN_BYPASS) + return + + source.click_intercept_time = world.time //From this point onwards Click() will no longer be triggered. + + if(autofire_stat == (AUTOFIRE_STAT_IDLE)) + CRASH("on_mouse_down() called with [autofire_stat] autofire_stat") + if(autofire_stat == AUTOFIRE_STAT_FIRING) + stop_autofiring() //This can happen if we click and hold and then alt+tab, printscreen or other such action. MouseUp won't be called then and it will keep autofiring. + + target = _target + target_loc = get_turf(target) + mouse_parameters = params + INVOKE_ASYNC(src, PROC_REF(start_autofiring)) + +/datum/component/automatic_fire/proc/start_autofiring() + if(autofire_stat == AUTOFIRE_STAT_FIRING) + return + autofire_stat = AUTOFIRE_STAT_FIRING + + clicker.mouse_override_icon = 'icons/hud/weapon_pointer.dmi' + clicker.mouse_pointer_icon = clicker.mouse_override_icon + + if(mouse_status == AUTOFIRE_MOUSEUP) //See mouse_status definition for the reason for this. + RegisterSignal(clicker, COMSIG_CLIENT_MOUSEUP, PROC_REF(on_mouse_up)) + mouse_status = AUTOFIRE_MOUSEDOWN + + RegisterSignal(shooter, COMSIG_MOB_SWAP_HANDS, PROC_REF(stop_autofiring)) + + if(!istype(parent, /obj/item/weapon/gun)) + var/obj/item/weapon/gun/shoota = parent + if(!shoota.on_autofire_start(shooter)) //This is needed because the minigun has a do_after before firing and signals are async. + stop_autofiring() + return + if(autofire_stat != AUTOFIRE_STAT_FIRING) + return //Things may have changed while on_autofire_start() was being processed, due to do_after's sleep. + + if(!process_shot()) //First shot is processed instantly. + return //If it fails, such as when the gun is empty, then there's no need to schedule a second shot. + + START_PROCESSING(SSfullauto, src) + RegisterSignal(clicker, COMSIG_CLIENT_MOUSEDRAG, PROC_REF(on_mouse_drag)) + + +/datum/component/automatic_fire/proc/on_mouse_up(datum/source, atom/object, turf/location, control, params) + SIGNAL_HANDLER + UnregisterSignal(clicker, COMSIG_CLIENT_MOUSEUP) + mouse_status = AUTOFIRE_MOUSEUP + if(autofire_stat == AUTOFIRE_STAT_FIRING) + stop_autofiring() + return COMPONENT_CLIENT_MOUSEUP_INTERCEPT + + +/datum/component/automatic_fire/proc/stop_autofiring(datum/source, atom/object, turf/location, control, params) + SIGNAL_HANDLER + if(autofire_stat != AUTOFIRE_STAT_FIRING) + return + STOP_PROCESSING(SSfullauto, src) + autofire_stat = AUTOFIRE_STAT_ALERT + if(clicker) + clicker.mouse_override_icon = null + clicker.mouse_pointer_icon = clicker.mouse_override_icon + UnregisterSignal(clicker, COMSIG_CLIENT_MOUSEDRAG) + if(!QDELETED(shooter)) + UnregisterSignal(shooter, COMSIG_MOB_SWAP_HANDS) + target = null + target_loc = null + mouse_parameters = null + +/datum/component/automatic_fire/proc/on_mouse_drag(client/source, atom/src_object, atom/over_object, turf/src_location, turf/over_location, src_control, over_control, params) + SIGNAL_HANDLER + if(!over_location) //This happens when the mouse is over an inventory or screen object, or on entering deep darkness, for example. + var/list/modifiers = params2list(params) + var/new_target = parse_caught_click_modifiers(modifiers, get_turf(source.eye), source) + params = list2params(modifiers) + mouse_parameters = params + if(!new_target) + if(QDELETED(target)) //No new target acquired, and old one was deleted, get us out of here. + stop_autofiring() + CRASH("on_mouse_drag failed to get the turf under screen object [over_object.type]. Old target was incidentally QDELETED.") + target = get_turf(target) //If previous target wasn't a turf, let's turn it into one to avoid locking onto a potentially moving target. + target_loc = target + CRASH("on_mouse_drag failed to get the turf under screen object [over_object.type]") + target = new_target + target_loc = new_target + return + target = over_object + target_loc = get_turf(over_object) + mouse_parameters = params + + +/datum/component/automatic_fire/proc/process_shot() + if(autofire_stat != AUTOFIRE_STAT_FIRING) + return FALSE + if(!COOLDOWN_FINISHED(src, next_shot_cd)) + return TRUE + if(QDELETED(target) || get_turf(target) != target_loc) //Target moved or got destroyed since we last aimed. + target = target_loc //So we keep firing on the emptied tile until we move our mouse and find a new target. + if(get_dist(shooter, target) <= 0) + target = get_step(shooter, shooter.dir) //Shoot in the direction faced if the mouse is on the same tile as we are. + target_loc = target + //else if(!CAN_THEY_SEE(target, shooter)) + // stop_autofiring() //Elvis has left the building. + // return FALSE + shooter.face_atom(target) + var/next_delay = autofire_shot_delay + if(windup_autofire) + next_delay = clamp(next_delay - current_windup_reduction, round(autofire_shot_delay * windup_autofire_cap), autofire_shot_delay) + current_windup_reduction = (current_windup_reduction + round(autofire_shot_delay * windup_autofire_reduction_multiplier)) + timerid = addtimer(CALLBACK(src, PROC_REF(windup_reset), FALSE), windup_spindown, TIMER_UNIQUE|TIMER_OVERRIDE|TIMER_STOPPABLE) + COOLDOWN_START(src, next_shot_cd, next_delay) + if(SEND_SIGNAL(parent, COMSIG_AUTOFIRE_SHOT, target, shooter, mouse_parameters) & COMPONENT_AUTOFIRE_SHOT_SUCCESS) + return TRUE + stop_autofiring() + return FALSE + +/// Reset for our windup, resetting everything back to initial values after a variable set amount of time (determined by var/windup_spindown). +/datum/component/automatic_fire/proc/windup_reset(deltimer) + current_windup_reduction = initial(current_windup_reduction) + if(deltimer && timerid) + deltimer(timerid) + +// Gun procs. + +/obj/item/weapon/gun/proc/on_autofire_start(mob/living/shooter) + if(!ready_to_fire() || shooter.incapacitated()) + return FALSE + if(!can_fire()) + shoot_with_empty_chamber(shooter) + return FALSE + //var/obj/item/bodypart/other_hand = shooter.has_hand_for_held_index(shooter.get_inactive_hand_index()) + //if(weapon_weight == WEAPON_HEAVY && (shooter.get_inactive_held_item() || !other_hand)) + // balloon_alert(shooter, "use both hands!") + // return FALSE + return TRUE + + +/obj/item/weapon/gun/proc/autofire_bypass_check(datum/source, client/clicker, atom/target, turf/location, control, params) + SIGNAL_HANDLER + if(clicker.mob.get_active_hand() != src) + return COMPONENT_AUTOFIRE_ONMOUSEDOWN_BYPASS + + +/obj/item/weapon/gun/proc/do_autofire(datum/source, atom/target, mob/living/shooter, params) + SIGNAL_HANDLER + if(!ready_to_fire() || shooter.incapacitated()) + return NONE + if(!can_fire()) + shoot_with_empty_chamber(shooter) + return NONE + INVOKE_ASYNC(src, PROC_REF(do_autofire_shot), source, target, shooter, params) + return COMPONENT_AUTOFIRE_SHOT_SUCCESS //All is well, we can continue shooting. + + +/obj/item/weapon/gun/proc/do_autofire_shot(datum/source, atom/target, mob/living/shooter, params) + afterattack(target, shooter, FALSE) + +#undef AUTOFIRE_MOUSEUP +#undef AUTOFIRE_MOUSEDOWN diff --git a/code/game/gamemodes/modes_gameplays/families/outfit.dm b/code/game/gamemodes/modes_gameplays/families/outfit.dm index 0ade42619f2a..e3b2ed643949 100644 --- a/code/game/gamemodes/modes_gameplays/families/outfit.dm +++ b/code/game/gamemodes/modes_gameplays/families/outfit.dm @@ -65,7 +65,7 @@ head = /obj/item/clothing/head/helmet/laserproof/police shoes = /obj/item/clothing/shoes/boots/combat gloves = /obj/item/clothing/gloves/combat/police - suit_store = /obj/item/weapon/gun/projectile/automatic + suit_store = /obj/item/weapon/gun/projectile/automatic/saber backpack_contents = list( /obj/item/weapon/storage/box/handcuffs = 1, /obj/item/ammo_box/magazine/smg = 3, diff --git a/code/game/objects/random/random_guns.dm b/code/game/objects/random/random_guns.dm index 7742f2589511..af5342398ecb 100644 --- a/code/game/objects/random/random_guns.dm +++ b/code/game/objects/random/random_guns.dm @@ -92,7 +92,7 @@ return pick(\ prob(15);/obj/item/weapon/gun/projectile/shotgun/bolt_action,\ prob(15);/obj/item/weapon/gun/projectile/shotgun/repeater,\ - prob(15);/obj/item/weapon/gun/projectile/automatic,\ + prob(15);/obj/item/weapon/gun/projectile/automatic/saber,\ prob(14);/obj/item/weapon/gun/projectile/automatic/c20r,\ prob(12);/obj/item/weapon/gun/projectile/automatic/mini_uzi,\ prob(10);/obj/item/weapon/gun/projectile/automatic/bar,\ @@ -188,7 +188,7 @@ /obj/item/weapon/gun/projectile/revolver/doublebarrel/dungeon/sawn_off,\ /obj/item/weapon/gun/projectile/revolver,\ /obj/item/weapon/gun/projectile/revolver/detective,\ - /obj/item/weapon/gun/projectile/automatic,\ + /obj/item/weapon/gun/projectile/automatic/saber,\ /obj/item/weapon/gun/projectile/automatic/mini_uzi,\ /obj/item/weapon/gun/projectile/automatic/c20r,\ /obj/item/weapon/gun/projectile/automatic/l13,\ diff --git a/code/modules/client/client_defines.dm b/code/modules/client/client_defines.dm index 6b470e732a73..10076c751169 100644 --- a/code/modules/client/client_defines.dm +++ b/code/modules/client/client_defines.dm @@ -75,6 +75,8 @@ var/last_asset_job = 0 var/last_completed_asset_job = 0 + ///Time when the click was intercepted + var/click_intercept_time = 0 ///Amount of keydowns in the last keysend checking interval var/client_keysend_amount = 0 @@ -118,3 +120,9 @@ COOLDOWN_DECLARE(say_slowmode) var/is_in_spawner = FALSE + ///used to make a special mouse cursor, this one for mouse up icon + var/mouse_up_icon = null + ///used to make a special mouse cursor, this one for mouse up icon + var/mouse_down_icon = null + ///used to override the mouse cursor so it doesnt get reset + var/mouse_override_icon = null diff --git a/code/modules/projectiles/firing.dm b/code/modules/projectiles/firing.dm index c71ca8829f6d..85549bad2870 100644 --- a/code/modules/projectiles/firing.dm +++ b/code/modules/projectiles/firing.dm @@ -50,6 +50,7 @@ qdel(BB) BB = null return 1 + BB.dispersion += weapon.spread BB.loc = get_turf(src) BB.starting = get_turf(src) BB.current = curloc diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm index ed31e7d13761..be765e617cd6 100644 --- a/code/modules/projectiles/gun.dm +++ b/code/modules/projectiles/gun.dm @@ -39,6 +39,9 @@ var/fire_delay = 6 var/last_fired = 0 var/two_hand_weapon = FALSE + var/burst = 1 //burst size + var/burst_delay = 1 //cooldown between burst shots + var/spread = 0 lefthand_file = 'icons/mob/inhands/guns_lefthand.dmi' righthand_file = 'icons/mob/inhands/guns_righthand.dmi' @@ -173,26 +176,26 @@ if(!special_check(user, target)) return - if (!ready_to_fire()) - if (world.time % 3) //to prevent spam - to_chat(user, "[src] is not ready to fire again!") - return - if(chambered) - if(point_blank) - if(!chambered.BB.fake) - user.visible_message(" \The [user] fires \the [src] point blank at [target]!") - chambered.BB.damage *= 1.3 - if(!chambered.fire(src, target, user, params, , silenced)) - shoot_with_empty_chamber(user) + user.next_click = world.time + (burst - 1) * burst_delay + for(var/i in 1 to burst) + if(chambered) + if(point_blank) + if(!chambered.BB.fake) + user.visible_message(" \The [user] fires \the [src] point blank at [target]!") + chambered.BB.damage *= 1.3 + if(!chambered.fire(src, target, user, params, , silenced)) + shoot_with_empty_chamber(user) + break + else + shoot_live_shot(user) + user.newtonian_move(get_dir(target, user)) else - shoot_live_shot(user) - user.newtonian_move(get_dir(target, user)) - else - shoot_with_empty_chamber(user) - process_chamber() - update_icon() - update_inv_mob() - + shoot_with_empty_chamber(user) + break + sleep(burst_delay) + process_chamber() + update_icon() + update_inv_mob() /obj/item/weapon/gun/proc/can_fire() return diff --git a/code/modules/projectiles/guns/plasma/plasma.dm b/code/modules/projectiles/guns/plasma/plasma.dm index 0a7761add0a0..6b0dacc31dcd 100644 --- a/code/modules/projectiles/guns/plasma/plasma.dm +++ b/code/modules/projectiles/guns/plasma/plasma.dm @@ -21,6 +21,7 @@ fire_sound = 'sound/weapons/guns/plasma10_shot.ogg' recoil = FALSE can_be_holstered = FALSE + var/fullauto = TRUE var/overcharge_fire_sound = 'sound/weapons/guns/plasma10_overcharge_shot.ogg' @@ -40,6 +41,7 @@ icon_state = "plasma104_stg" item_state = "plasma104_stg" origin_tech = "combat=4;magnets=3" + fullauto = FALSE overcharge_fire_sound = 'sound/weapons/guns/plasma10_overcharge_massive_shot.ogg' @@ -55,6 +57,8 @@ /obj/item/weapon/gun/plasma/atom_init() . = ..() + if(fullauto) + AddComponent(/datum/component/automatic_fire, fire_delay) magazine = new initial_mag(src) for(var/i in ammo_type) var/path = ammo_type[i] diff --git a/code/modules/projectiles/guns/projectile/automatic.dm b/code/modules/projectiles/guns/projectile/automatic.dm index be0134592d26..25183b6853dc 100644 --- a/code/modules/projectiles/guns/projectile/automatic.dm +++ b/code/modules/projectiles/guns/projectile/automatic.dm @@ -46,6 +46,15 @@ return install_silencer(I, user, params) return ..() +/obj/item/weapon/gun/projectile/automatic/saber + spread = 1 + fire_delay = 2 + +/obj/item/weapon/gun/projectile/automatic/saber/atom_init() + . = ..() + AddComponent(/datum/component/automatic_fire, fire_delay) + + /obj/item/weapon/gun/projectile/automatic/mini_uzi name = "Mac-10" desc = "Легкий и скорострельный пистолет-пулемёт для тех случаев, когда нужно кого-то быстро убить. Использует патроны калибра 9мм." @@ -56,6 +65,12 @@ origin_tech = "combat=5;materials=2;syndicate=8" initial_mag = /obj/item/ammo_box/magazine/mac10 can_be_silenced = TRUE + fire_delay = 1 + spread = 1.5 + +/obj/item/weapon/gun/projectile/automatic/mini_uzi/atom_init() + . = ..() + AddComponent(/datum/component/automatic_fire, fire_delay) /obj/item/weapon/gun/projectile/automatic/c20r name = "C-20r SMG" @@ -70,6 +85,12 @@ should_alarm_when_empty = TRUE can_be_silenced = TRUE has_ammo_counter = TRUE + fire_delay = 2 + spread = 1 + +/obj/item/weapon/gun/projectile/automatic/c20r/atom_init() + . = ..() + AddComponent(/datum/component/automatic_fire, fire_delay) /obj/item/weapon/gun/projectile/automatic/l6_saw name = "L6 SAW" @@ -83,6 +104,12 @@ has_cover = TRUE two_hand_weapon = ONLY_TWOHAND has_ammo_counter = TRUE + fire_delay = 2.5 + spread = 1.5 + +/obj/item/weapon/gun/projectile/automatic/l6_saw/atom_init() + . = ..() + AddComponent(/datum/component/automatic_fire, fire_delay) /obj/item/weapon/gun/projectile/automatic/l6_saw/update_icon() icon_state = "l6[cover_open ? "open" : "closed"][magazine ? CEIL(get_ammo(0) / 12.5) * 25 : "-empty"]" @@ -136,6 +163,12 @@ suitable_mags = list(/obj/item/ammo_box/magazine/l13, /obj/item/ammo_box/magazine/l13/lethal) fire_sound = 'sound/weapons/guns/gunshot_l13.ogg' can_be_silenced = TRUE + fire_delay = 2 + spread = 1 + +/obj/item/weapon/gun/projectile/automatic/l13/atom_init() + . = ..() + AddComponent(/datum/component/automatic_fire, fire_delay) /obj/item/weapon/gun/projectile/automatic/tommygun name = "tommy gun" @@ -149,6 +182,12 @@ initial_mag = /obj/item/ammo_box/magazine/tommygun fire_sound = 'sound/weapons/guns/gunshot_light.ogg' can_be_silenced = TRUE + fire_delay = 1.5 + spread = 1.5 + +/obj/item/weapon/gun/projectile/automatic/tommygun/atom_init() + . = ..() + AddComponent(/datum/component/automatic_fire, fire_delay) /obj/item/weapon/gun/projectile/automatic/bar name = "Browning M1918" @@ -161,12 +200,19 @@ initial_mag = /obj/item/ammo_box/magazine/bar fire_sound = 'sound/weapons/guns/Gunshot2.ogg' +/obj/item/weapon/gun/projectile/automatic/bar/atom_init() + . = ..() + AddComponent(/datum/component/automatic_fire, fire_delay) + /obj/item/weapon/gun/projectile/automatic/borg name = "Robot SMG" icon_state = "borg_smg" initial_mag = /obj/item/ammo_box/magazine/borg45 fire_sound = 'sound/weapons/guns/gunshot_medium.ogg' has_ammo_counter = TRUE + spread = 1 + burst = 3 + burst_delay = 2 /obj/item/weapon/gun/projectile/automatic/borg/update_icon() return @@ -205,6 +251,12 @@ initial_mag = /obj/item/ammo_box/magazine/a28 suitable_mags = list(/obj/item/ammo_box/magazine/a28, /obj/item/ammo_box/magazine/a28/nonlethal, /obj/item/ammo_box/magazine/a28/incendiary) fire_sound = 'sound/weapons/guns/gunshot_medium.ogg' + fire_delay = 2.5 + spread = 1 + +/obj/item/weapon/gun/projectile/automatic/a28/atom_init() + . = ..() + AddComponent(/datum/component/automatic_fire, fire_delay) /obj/item/weapon/gun/projectile/automatic/a74 name = "A74 assault rifle" @@ -217,6 +269,12 @@ item_state = "a74" origin_tech = "combat=5;materials=4;syndicate=6" fire_sound = 'sound/weapons/guns/gunshot_ak74.ogg' + fire_delay = 2.5 + spread = 1 + +/obj/item/weapon/gun/projectile/automatic/a74/atom_init() + . = ..() + AddComponent(/datum/component/automatic_fire, fire_delay) /obj/item/weapon/gun/projectile/automatic/a74/krinkov name = "Krinkov" @@ -300,6 +358,8 @@ w_class = SIZE_SMALL two_hand_weapon = DESIRABLE_TWOHAND fire_delay = 1 + burst = 3 + spread = 1.5 /obj/item/weapon/gun/projectile/automatic/m41a/process_chamber() return ..(1, 1, 1) @@ -325,10 +385,14 @@ /obj/item/weapon/gun/projectile/automatic/m41a/launcher/proc/toggle_gl(mob/user) using_gl = !using_gl if(using_gl) + spread = 0 + burst = 1 user.visible_message("[user] presses a button, activating their [launcher]!",\ "You activate your [launcher].",\ "You hear an ominous click.") else + spread = 1.5 + burst = 3 user.visible_message("[user] presses a button, deciding to stop the bombings.",\ "You deactivate your [launcher].",\ "You hear a click.") diff --git a/code/modules/projectiles/guns/projectile/pistol.dm b/code/modules/projectiles/guns/projectile/pistol.dm index a883e0d71aa7..9800d30a0320 100644 --- a/code/modules/projectiles/guns/projectile/pistol.dm +++ b/code/modules/projectiles/guns/projectile/pistol.dm @@ -65,6 +65,11 @@ initial_mag = /obj/item/ammo_box/magazine/stechkin suitable_mags = list(/obj/item/ammo_box/magazine/stechkin, /obj/item/ammo_box/magazine/stechkin/extended) can_be_silenced = TRUE + fire_delay = 3 + +/obj/item/weapon/gun/projectile/automatic/pistol/stechkin/atom_init() + . = ..() + AddComponent(/datum/component/automatic_fire, fire_delay) /obj/item/weapon/gun/projectile/automatic/pistol/colt1911 desc = "Дешевая марсианская подделка Colt M1911. Использует менее смертоносные патроны 45-го калибра." diff --git a/code/modules/research/designs.dm b/code/modules/research/designs.dm index ede37b37c08d..d07c41f77cb3 100644 --- a/code/modules/research/designs.dm +++ b/code/modules/research/designs.dm @@ -2083,7 +2083,7 @@ other types of metals and chemistry for reagents). id = "smg" build_type = PROTOLATHE materials = list(MAT_METAL = 8000, MAT_SILVER = 2000, MAT_DIAMOND = 1000) - build_path = /obj/item/weapon/gun/projectile/automatic + build_path = /obj/item/weapon/gun/projectile/automatic/saber category = list("Weapons") /datum/design/msmg9mm diff --git a/icons/hud/weapon_pointer.dmi b/icons/hud/weapon_pointer.dmi new file mode 100644 index 0000000000000000000000000000000000000000..b5070062c0bb6c7a06e95dc52b8cc1631daada63 GIT binary patch literal 234 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0P3?wHke>@jRu?6^qxE?rg;HIQuav+;EP=v80 z$S;_|;n|HeASb;lB%;J6wK%ybv!En1KaYW-Voq>aK~d@VFTn*Lzdq6O*3~+9=6vvm zP=kxc4<6~9_t8AbP;|y;hlO#F@nvH#g*lHV9hnrO5Ugpa?%vsLth#xH#0ldkk9@Sf z&iJ-&m?|3cH|9Va6T?pyNk5zFnyWx7-Lo_BPCrEHL{A4JVaAEj;xc$FCk^t+A d7ta`37=%BFn=Y<3a|bGA@O1TaS?83{1OTnfQ!4-f literal 0 HcmV?d00001 diff --git a/maps/centcom/centcom.dmm b/maps/centcom/centcom.dmm index bafdb389eceb..12d3b3f88391 100644 --- a/maps/centcom/centcom.dmm +++ b/maps/centcom/centcom.dmm @@ -14439,7 +14439,7 @@ /obj/item/weapon/gun/projectile/automatic{ pixel_y = 3 }, -/obj/item/weapon/gun/projectile/automatic, +/obj/item/weapon/gun/projectile/automatic/saber, /obj/machinery/camera{ c_tag = "Spec. Ops. Armory North"; network = list("ERT") diff --git a/maps/templates/space_structures/old_station.dmm b/maps/templates/space_structures/old_station.dmm index 72dc11c50b6f..3abc5fe6f605 100644 --- a/maps/templates/space_structures/old_station.dmm +++ b/maps/templates/space_structures/old_station.dmm @@ -6967,7 +6967,7 @@ /area/space_structures/old_station/central) "OZ" = ( /obj/structure/rack, -/obj/item/weapon/gun/projectile/automatic, +/obj/item/weapon/gun/projectile/automatic/saber, /obj/effect/decal/turf_decal/alpha/yellow{ icon_state = "bot" }, diff --git a/taucetistation.dme b/taucetistation.dme index 7ba48840835b..49602c417ba5 100644 --- a/taucetistation.dme +++ b/taucetistation.dme @@ -240,6 +240,7 @@ #include "code\controllers\subsystem\environment.dm" #include "code\controllers\subsystem\events.dm" #include "code\controllers\subsystem\explosions.dm" +#include "code\controllers\subsystem\fullauto.dm" #include "code\controllers\subsystem\garbage.dm" #include "code\controllers\subsystem\holiday.dm" #include "code\controllers\subsystem\holomaps.dm" @@ -342,6 +343,7 @@ #include "code\datums\components\fishing.dm" #include "code\datums\components\footstep.dm" #include "code\datums\components\forcefield.dm" +#include "code\datums\components\fullauto.dm" #include "code\datums\components\gnawing.dm" #include "code\datums\components\logout_spawner.dm" #include "code\datums\components\magic_item.dm" From ed38c08c63a9a9d801490cec73848e497b521eb3 Mon Sep 17 00:00:00 2001 From: simb11 <84613249+simb11@users.noreply.github.com> Date: Fri, 16 Aug 2024 21:04:25 +0200 Subject: [PATCH 2/9] l6 saw --- code/datums/uplinks_items.dm | 4 ++-- .../projectiles/ammunition/magazines.dm | 4 ++-- .../projectiles/guns/projectile/automatic.dm | 3 +-- .../modules/projectiles/projectile/bullets.dm | 2 +- icons/obj/ammo/magazines.dmi | Bin 16720 -> 16722 bytes 5 files changed, 6 insertions(+), 7 deletions(-) diff --git a/code/datums/uplinks_items.dm b/code/datums/uplinks_items.dm index a1fe5f67feb1..63c8e898c5d6 100644 --- a/code/datums/uplinks_items.dm +++ b/code/datums/uplinks_items.dm @@ -242,7 +242,7 @@ /datum/uplink_item/dangerous/machinegun name = "L6 Squad Automatic Weapon" - desc = "A traditionally constructed machine gun made by AA-2531. This deadly weapon has a massive 50-round magazine of 7.62x51mm ammunition." + desc = "A traditionally constructed machine gun made by AA-2531. This deadly weapon has a massive 100-round magazine of 7.62x51mm ammunition." item = /obj/item/weapon/gun/projectile/automatic/l6_saw cost = 30 uplink_types = list("nuclear") @@ -522,7 +522,7 @@ /datum/uplink_item/ammo/machinegun name = "Ammo-7.62x51mm" - desc = "A 50-round magazine of 7.62x51mm ammunition for use in the L6 SAW machinegun. By the time you need to use this, you'll already be on a pile of corpses." + desc = "A 100-round magazine of 7.62x51mm ammunition for use in the L6 SAW machinegun. By the time you need to use this, you'll already be on a pile of corpses." item = /obj/item/ammo_box/magazine/saw cost = 10 uplink_types = list("nuclear") diff --git a/code/modules/projectiles/ammunition/magazines.dm b/code/modules/projectiles/ammunition/magazines.dm index 258b30de1a90..29a1406dc079 100644 --- a/code/modules/projectiles/ammunition/magazines.dm +++ b/code/modules/projectiles/ammunition/magazines.dm @@ -331,11 +331,11 @@ origin_tech = "combat=2" ammo_type = /obj/item/ammo_casing/a762 caliber = "a762" - max_ammo = 50 + max_ammo = 100 /obj/item/ammo_box/magazine/saw/update_icon() ..() - icon_state = "[initial(icon_state)]-[round(ammo_count(),10)]" + icon_state = "[initial(icon_state)]-[round(ammo_count(),20)]" /obj/item/ammo_box/magazine/chameleon name = "magazine (.45)" diff --git a/code/modules/projectiles/guns/projectile/automatic.dm b/code/modules/projectiles/guns/projectile/automatic.dm index 25183b6853dc..fdd66049f050 100644 --- a/code/modules/projectiles/guns/projectile/automatic.dm +++ b/code/modules/projectiles/guns/projectile/automatic.dm @@ -54,7 +54,6 @@ . = ..() AddComponent(/datum/component/automatic_fire, fire_delay) - /obj/item/weapon/gun/projectile/automatic/mini_uzi name = "Mac-10" desc = "Легкий и скорострельный пистолет-пулемёт для тех случаев, когда нужно кого-то быстро убить. Использует патроны калибра 9мм." @@ -112,7 +111,7 @@ AddComponent(/datum/component/automatic_fire, fire_delay) /obj/item/weapon/gun/projectile/automatic/l6_saw/update_icon() - icon_state = "l6[cover_open ? "open" : "closed"][magazine ? CEIL(get_ammo(0) / 12.5) * 25 : "-empty"]" + icon_state = "l6[cover_open ? "open" : "closed"][magazine ? CEIL(get_ammo(0) / 25) * 25 : "-empty"]" item_state = "l6[cover_open ? "open" : "closed"][magazine ? "mag" : "nomag"]" /obj/item/weapon/gun/projectile/automatic/l6_saw/afterattack(atom/target, mob/user, proximity, params) //what I tried to do here is just add a check to see if the cover is open or not and add an icon_state change because I can't figure out how c-20rs do it with overlays diff --git a/code/modules/projectiles/projectile/bullets.dm b/code/modules/projectiles/projectile/bullets.dm index d525b3d9ee53..bc0a2dc55f1a 100644 --- a/code/modules/projectiles/projectile/bullets.dm +++ b/code/modules/projectiles/projectile/bullets.dm @@ -233,7 +233,7 @@ proj_act_sound = SOUNDIN_WEAKBULLETACT /obj/item/projectile/bullet/a762 - damage = 50 + damage = 30 embed = 0 /obj/item/projectile/bullet/incendiary diff --git a/icons/obj/ammo/magazines.dmi b/icons/obj/ammo/magazines.dmi index 7ee6f6754b0eaa14e71812195915e269dc676052..d965f790a280e2fc2fd9efd4aaf5856c8f2c687f 100644 GIT binary patch delta 236 zcmVC-6mR*%(J}aCC~J!2M2#!X#aPC4q)gvPRCC zO4i6}M#&mECMj7X=PxB|{4SbtwC3GQ@RLR<{F5DSjy3ez4JXXvX%Ww2e zS`bFSBZDvk3 Date: Fri, 16 Aug 2024 21:07:49 +0200 Subject: [PATCH 3/9] smg crate --- code/modules/cargo/packs.dm | 40 +++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/code/modules/cargo/packs.dm b/code/modules/cargo/packs.dm index 2dc16fb89866..b0b4b6c306f1 100644 --- a/code/modules/cargo/packs.dm +++ b/code/modules/cargo/packs.dm @@ -174,6 +174,46 @@ var/global/list/all_supply_groups = list("Operations","Security","Hospitality"," access = access_brig group = "Security" +/datum/supply_pack/ballistic/smg + name = ".38 SMG crate" + contains = list(/obj/item/weapon/gun/projectile/automatic/l13, + /obj/item/weapon/gun/projectile/automatic/l13, + /obj/item/weapon/gun/projectile/automatic/l13) + additional_costs = 2300 + crate_type = /obj/structure/closet/crate/secure/weapon + crate_name = ".38 SMG crate" + access = access_brig + group = "Security" + +/datum/supply_pack/ballistic/smg_magazine + name = ".38 magazine" + contains = list(/obj/item/ammo_box/magazine/l13/lethal, + /obj/item/ammo_box/magazine/l13/lethal, + /obj/item/ammo_box/magazine/l13/lethal, + /obj/item/ammo_box/magazine/l13/lethal, + /obj/item/ammo_box/magazine/l13/lethal, + /obj/item/ammo_box/magazine/l13/lethal) + additional_costs = 500 + crate_type = /obj/structure/closet/crate/secure + crate_name = ".38 magazine" + access = access_armory + group = "Security" + +/datum/supply_pack/ballistic/smg_magazine_rubber + name = ".38 magazine (rubber)" + contains = list(/obj/item/ammo_box/magazine/l13, + /obj/item/ammo_box/magazine/l13, + /obj/item/ammo_box/magazine/l13, + /obj/item/ammo_box/magazine/l13, + /obj/item/ammo_box/magazine/l13, + /obj/item/ammo_box/magazine/l13) + additional_costs = 400 + crate_type = /obj/structure/closet/crate/secure + crate_name = ".38 magazine (rubber)" + access = access_brig + group = "Security" + + /datum/supply_pack/ballistic/pistol name = "9mm pistol crate" contains = list(/obj/item/weapon/gun/projectile/automatic/pistol/glock, From 4b74e9e4fef129c7a6c4641b367565b3221571ad Mon Sep 17 00:00:00 2001 From: simb11 <84613249+simb11@users.noreply.github.com> Date: Fri, 16 Aug 2024 21:21:10 +0200 Subject: [PATCH 4/9] Update fullauto.dm --- code/datums/components/fullauto.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/datums/components/fullauto.dm b/code/datums/components/fullauto.dm index e7f687caaab0..e77171b95a36 100644 --- a/code/datums/components/fullauto.dm +++ b/code/datums/components/fullauto.dm @@ -82,8 +82,8 @@ RegisterSignal(shooter, COMSIG_LOGOUT, PROC_REF(autofire_off)) UnregisterSignal(shooter, COMSIG_LOGIN) RegisterSignals(parent, list(COMSIG_PARENT_QDELETING, COMSIG_ITEM_DROPPED), PROC_REF(autofire_off)) - parent.RegisterSignal(src, COMSIG_AUTOFIRE_ONMOUSEDOWN, TYPE_PROC_REF(/obj/item/weapon/gun/, autofire_bypass_check)) - parent.RegisterSignal(parent, COMSIG_AUTOFIRE_SHOT, TYPE_PROC_REF(/obj/item/weapon/gun/, do_autofire)) + parent.RegisterSignal(src, COMSIG_AUTOFIRE_ONMOUSEDOWN, TYPE_PROC_REF(/obj/item/weapon/gun, autofire_bypass_check)) + parent.RegisterSignal(parent, COMSIG_AUTOFIRE_SHOT, TYPE_PROC_REF(/obj/item/weapon/gun, do_autofire)) From 5bd05a7df359edf7a3ed950cba5ee7e5a9ff227d Mon Sep 17 00:00:00 2001 From: simb11 <84613249+simb11@users.noreply.github.com> Date: Fri, 16 Aug 2024 22:47:51 +0200 Subject: [PATCH 5/9] del musor --- code/datums/components/fullauto.dm | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/code/datums/components/fullauto.dm b/code/datums/components/fullauto.dm index e77171b95a36..283f17fdf703 100644 --- a/code/datums/components/fullauto.dm +++ b/code/datums/components/fullauto.dm @@ -237,9 +237,9 @@ if(get_dist(shooter, target) <= 0) target = get_step(shooter, shooter.dir) //Shoot in the direction faced if the mouse is on the same tile as we are. target_loc = target - //else if(!CAN_THEY_SEE(target, shooter)) - // stop_autofiring() //Elvis has left the building. - // return FALSE + else if(!CAN_THEY_SEE(target, shooter)) + stop_autofiring() //Elvis has left the building. + return FALSE shooter.face_atom(target) var/next_delay = autofire_shot_delay if(windup_autofire) @@ -266,13 +266,8 @@ if(!can_fire()) shoot_with_empty_chamber(shooter) return FALSE - //var/obj/item/bodypart/other_hand = shooter.has_hand_for_held_index(shooter.get_inactive_hand_index()) - //if(weapon_weight == WEAPON_HEAVY && (shooter.get_inactive_held_item() || !other_hand)) - // balloon_alert(shooter, "use both hands!") - // return FALSE return TRUE - /obj/item/weapon/gun/proc/autofire_bypass_check(datum/source, client/clicker, atom/target, turf/location, control, params) SIGNAL_HANDLER if(clicker.mob.get_active_hand() != src) @@ -289,7 +284,6 @@ INVOKE_ASYNC(src, PROC_REF(do_autofire_shot), source, target, shooter, params) return COMPONENT_AUTOFIRE_SHOT_SUCCESS //All is well, we can continue shooting. - /obj/item/weapon/gun/proc/do_autofire_shot(datum/source, atom/target, mob/living/shooter, params) afterattack(target, shooter, FALSE) From a2f75704ecf66636998fb4406a04843b64de2384 Mon Sep 17 00:00:00 2001 From: simb11 <84613249+simb11@users.noreply.github.com> Date: Mon, 19 Aug 2024 13:35:42 +0200 Subject: [PATCH 6/9] be --- code/modules/projectiles/gun.dm | 3 ++ .../modules/projectiles/guns/plasma/plasma.dm | 4 +- .../projectiles/guns/projectile/automatic.dm | 37 +++++++++--------- .../projectiles/guns/projectile/pistol.dm | 4 +- code/modules/research/prototipify.dm | 2 - icons/obj/ammo/magazines.dmi | Bin 16722 -> 16690 bytes 6 files changed, 26 insertions(+), 24 deletions(-) diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm index be765e617cd6..0176156ce1a5 100644 --- a/code/modules/projectiles/gun.dm +++ b/code/modules/projectiles/gun.dm @@ -176,6 +176,9 @@ if(!special_check(user, target)) return + if (!ready_to_fire()) + return + user.next_click = world.time + (burst - 1) * burst_delay for(var/i in 1 to burst) if(chambered) diff --git a/code/modules/projectiles/guns/plasma/plasma.dm b/code/modules/projectiles/guns/plasma/plasma.dm index 6b0dacc31dcd..283a954344ce 100644 --- a/code/modules/projectiles/guns/plasma/plasma.dm +++ b/code/modules/projectiles/guns/plasma/plasma.dm @@ -16,7 +16,7 @@ desc = "Стандартный плазменный карабин типа булл-пап обладающий высокой скорострельностью." icon_state = "plasma10_car" item_state = "plasma10_car" - fire_delay = 2 + fire_delay = 0 origin_tech = "combat=3;magnets=2" fire_sound = 'sound/weapons/guns/plasma10_shot.ogg' recoil = FALSE @@ -58,7 +58,7 @@ /obj/item/weapon/gun/plasma/atom_init() . = ..() if(fullauto) - AddComponent(/datum/component/automatic_fire, fire_delay) + AddComponent(/datum/component/automatic_fire, 0.2 SECONDS) magazine = new initial_mag(src) for(var/i in ammo_type) var/path = ammo_type[i] diff --git a/code/modules/projectiles/guns/projectile/automatic.dm b/code/modules/projectiles/guns/projectile/automatic.dm index fdd66049f050..7444bbabd241 100644 --- a/code/modules/projectiles/guns/projectile/automatic.dm +++ b/code/modules/projectiles/guns/projectile/automatic.dm @@ -48,11 +48,11 @@ /obj/item/weapon/gun/projectile/automatic/saber spread = 1 - fire_delay = 2 + fire_delay = 0 /obj/item/weapon/gun/projectile/automatic/saber/atom_init() . = ..() - AddComponent(/datum/component/automatic_fire, fire_delay) + AddComponent(/datum/component/automatic_fire, 0.2 SECONDS) /obj/item/weapon/gun/projectile/automatic/mini_uzi name = "Mac-10" @@ -64,12 +64,12 @@ origin_tech = "combat=5;materials=2;syndicate=8" initial_mag = /obj/item/ammo_box/magazine/mac10 can_be_silenced = TRUE - fire_delay = 1 + fire_delay = 0 spread = 1.5 /obj/item/weapon/gun/projectile/automatic/mini_uzi/atom_init() . = ..() - AddComponent(/datum/component/automatic_fire, fire_delay) + AddComponent(/datum/component/automatic_fire, 0.1 SECONDS) /obj/item/weapon/gun/projectile/automatic/c20r name = "C-20r SMG" @@ -84,12 +84,12 @@ should_alarm_when_empty = TRUE can_be_silenced = TRUE has_ammo_counter = TRUE - fire_delay = 2 + fire_delay = 0 spread = 1 /obj/item/weapon/gun/projectile/automatic/c20r/atom_init() . = ..() - AddComponent(/datum/component/automatic_fire, fire_delay) + AddComponent(/datum/component/automatic_fire, 0.2 SECONDS) /obj/item/weapon/gun/projectile/automatic/l6_saw name = "L6 SAW" @@ -103,12 +103,12 @@ has_cover = TRUE two_hand_weapon = ONLY_TWOHAND has_ammo_counter = TRUE - fire_delay = 2.5 + fire_delay = 0 spread = 1.5 /obj/item/weapon/gun/projectile/automatic/l6_saw/atom_init() . = ..() - AddComponent(/datum/component/automatic_fire, fire_delay) + AddComponent(/datum/component/automatic_fire, 0.25 SECONDS) /obj/item/weapon/gun/projectile/automatic/l6_saw/update_icon() icon_state = "l6[cover_open ? "open" : "closed"][magazine ? CEIL(get_ammo(0) / 25) * 25 : "-empty"]" @@ -162,12 +162,12 @@ suitable_mags = list(/obj/item/ammo_box/magazine/l13, /obj/item/ammo_box/magazine/l13/lethal) fire_sound = 'sound/weapons/guns/gunshot_l13.ogg' can_be_silenced = TRUE - fire_delay = 2 + fire_delay = 0 spread = 1 /obj/item/weapon/gun/projectile/automatic/l13/atom_init() . = ..() - AddComponent(/datum/component/automatic_fire, fire_delay) + AddComponent(/datum/component/automatic_fire, 0.2 SECONDS) /obj/item/weapon/gun/projectile/automatic/tommygun name = "tommy gun" @@ -181,12 +181,12 @@ initial_mag = /obj/item/ammo_box/magazine/tommygun fire_sound = 'sound/weapons/guns/gunshot_light.ogg' can_be_silenced = TRUE - fire_delay = 1.5 + fire_delay = 0 spread = 1.5 /obj/item/weapon/gun/projectile/automatic/tommygun/atom_init() . = ..() - AddComponent(/datum/component/automatic_fire, fire_delay) + AddComponent(/datum/component/automatic_fire, 0.15 SECONDS) /obj/item/weapon/gun/projectile/automatic/bar name = "Browning M1918" @@ -198,10 +198,11 @@ origin_tech = "combat=5;materials=2" initial_mag = /obj/item/ammo_box/magazine/bar fire_sound = 'sound/weapons/guns/Gunshot2.ogg' + fire_delay = 0 /obj/item/weapon/gun/projectile/automatic/bar/atom_init() . = ..() - AddComponent(/datum/component/automatic_fire, fire_delay) + AddComponent(/datum/component/automatic_fire, 0.4 SECONDS) /obj/item/weapon/gun/projectile/automatic/borg name = "Robot SMG" @@ -250,12 +251,12 @@ initial_mag = /obj/item/ammo_box/magazine/a28 suitable_mags = list(/obj/item/ammo_box/magazine/a28, /obj/item/ammo_box/magazine/a28/nonlethal, /obj/item/ammo_box/magazine/a28/incendiary) fire_sound = 'sound/weapons/guns/gunshot_medium.ogg' - fire_delay = 2.5 + fire_delay = 0 spread = 1 /obj/item/weapon/gun/projectile/automatic/a28/atom_init() . = ..() - AddComponent(/datum/component/automatic_fire, fire_delay) + AddComponent(/datum/component/automatic_fire, 0.25 SECONDS) /obj/item/weapon/gun/projectile/automatic/a74 name = "A74 assault rifle" @@ -268,12 +269,12 @@ item_state = "a74" origin_tech = "combat=5;materials=4;syndicate=6" fire_sound = 'sound/weapons/guns/gunshot_ak74.ogg' - fire_delay = 2.5 + fire_delay = 0 spread = 1 /obj/item/weapon/gun/projectile/automatic/a74/atom_init() . = ..() - AddComponent(/datum/component/automatic_fire, fire_delay) + AddComponent(/datum/component/automatic_fire, 0.25 SECONDS) /obj/item/weapon/gun/projectile/automatic/a74/krinkov name = "Krinkov" @@ -356,7 +357,7 @@ initial_mag = /obj/item/ammo_box/magazine/m41a w_class = SIZE_SMALL two_hand_weapon = DESIRABLE_TWOHAND - fire_delay = 1 + fire_delay = 3 burst = 3 spread = 1.5 diff --git a/code/modules/projectiles/guns/projectile/pistol.dm b/code/modules/projectiles/guns/projectile/pistol.dm index 9800d30a0320..b012d2b2528d 100644 --- a/code/modules/projectiles/guns/projectile/pistol.dm +++ b/code/modules/projectiles/guns/projectile/pistol.dm @@ -65,11 +65,11 @@ initial_mag = /obj/item/ammo_box/magazine/stechkin suitable_mags = list(/obj/item/ammo_box/magazine/stechkin, /obj/item/ammo_box/magazine/stechkin/extended) can_be_silenced = TRUE - fire_delay = 3 + fire_delay = 0 /obj/item/weapon/gun/projectile/automatic/pistol/stechkin/atom_init() . = ..() - AddComponent(/datum/component/automatic_fire, fire_delay) + AddComponent(/datum/component/automatic_fire, 0.3 SECONDS) /obj/item/weapon/gun/projectile/automatic/pistol/colt1911 desc = "Дешевая марсианская подделка Colt M1911. Использует менее смертоносные патроны 45-го калибра." diff --git a/code/modules/research/prototipify.dm b/code/modules/research/prototipify.dm index 1983ceecae52..4ffc28fd3b01 100644 --- a/code/modules/research/prototipify.dm +++ b/code/modules/research/prototipify.dm @@ -95,9 +95,7 @@ /obj/item/weapon/gun/projectile/automatic/set_prototype_qualities(rel_val=100, mark=0) if(mark) recoil = max(recoil / mark, 0.5) - fire_delay = max(fire_delay / mark, 2) if(!prob(reliability)) - fire_delay *= 2 recoil += 1 /obj/item/weapon/gun/plasma/set_prototype_qualities(rel_val=100, mark=0) diff --git a/icons/obj/ammo/magazines.dmi b/icons/obj/ammo/magazines.dmi index d965f790a280e2fc2fd9efd4aaf5856c8f2c687f..4582c3c2f36dbf8821ef873dfe2b2fce4de746f9 100644 GIT binary patch delta 13319 zcmZX5c{r49*#2XXt!!l}yF}>~l4PBUN?NE8WetU7DQjY$NtU!wO$ae4yO1SY8fz+K z&u&8Y-3(^NEZ;r7@Av)w_;no5(KK^E_j+CDbzbLn*B!=I62?}%!VbH<+9ULIZ?QcT z=fktJysWU7uTZ5+6KQQ-kFy=&zH;Z?sJx1OPFdKU<^((Ut4}<|%IIAQAC_-jIJJAK zB;%V)IcCrn!|n7qT-FB-@9g-~=AxLW?faA1)<(RKx4(aL`ohr_jhVOFIAUn3@6XBg zZMtl@prPL+qE7?GEf)^wVA#%b%bhwejsahnh5!4HZXGC_94~Gja(-tY@g%pL0=-hL z3l5^N;nZ&&Tm9wb*f1M2=lo>-5_0i$LW+i%Droski-xqCPz)D*m8u|#L8&cbB8m7% zf5c213zb68m_|D!3tEJ#r48Y8%Ko{%Q5(>H?$E-?5Ew06xpR~J34+#J#BRhqC@PyO z`hin!#SOzJMi@P=+h!*qEiL|*=_yD}a^My^Q`oCRp+LoiB(-F8n)|DccnABXO*K{Aobc|x0C!a!4h1nc?$ic?KF@g6D>oc3)k;5?c4wHu~Z5aFXzOSo) z61v?VcJ?9EZYfa%Ox7ZqGlky_P;0hl1VO((4-CEzX_^lAZ6_!1YeWZ^O!0fYm~*9co7;#FBlezC1WCE;+=zR5^=@43{kB>=%$QEK z*z44}Y#f^ExoX3Uf~+@EtkyamyvnF6@TUxU4zalSz4qP@OCGWP+X_om^4lB!0>RCP z|Gt~=a#d}$xlO?ZCr&BVIBf%y3ioC%{c8D(C@RJ}Z)1Wcsqo{VGO2J^s^IKc}M?~tSPkxEHmLohMZt8}B*Hx?%VT#ACiG#rV1^dY7F(7t6IXYRoY~MN zL+3=9574*57%Ht(@J8s|axAK5$*df_+@S{BvK=gCcEtSn=PFS#-@uStF6{l0M^G3Y zF7cx66XJEpGq&nXjqj}t%gw7;;1+H=; z%2Sep4_8_Wg~NwZ)EfCM1pBWzuIK`wz|JbJ7Yur$MW`j96Fok z9x8gUF;;Nq^61uCB;AzKQ!N1YocrUsA+3kP;GL_E*p~{j*j2$@;MoC3Z(ns&MgG=M ze6}29kabXCA=L|lMmAp))@)v>D62fxS(bqg?eAV-P%O7CRbj)k(=RV^p2#|=O2Rsv z*tPo%`|dMbfu^SIX?u$*WEYJ)`+g3Z`Y~yF^t=S5oI>g28pO!R3CZMy;6A;4%OH)D}5*fs9GqQ~zXA5o( zTAxRM8M-#{Kz2b_oI>&bN&G#nC%_;uYn7I0@yaOmeMS8?m>)}hZ}dK18se^J^$OFh z&2xBGf7k2mlsMjdR|%$%gFSIt`!w#eqC;4rwZ^ht2m^0nE+5WRwJ*n4<$g5B*Yw-S zPU#BLiMTBp{iv0!MC3ALTXQSZkd{Uw(q25A`(jh~wn~(i{cTneI zxrV(XKb$}C;t2zlCi)Qdq2&1$F8n;JQCLQ-Z9d4OcYPgX?a6VR1MuecirqV8<=nr$$@ttkNo#N) z*m&RZ?aO02eq6xI#{rGG_WBLiNB4XpYj&liF&1$7mEVMF2m;SB^lG++HS5q zzImZxNLZidL_Vx>v?bG={;xB@x;G%<^En0x%O$J(9E+QOoW@43-RN1SWD8qZS+#b8 z)n37;s6i$Tf7_Tv?En2^DJAf@7227DPVyM9;M*ZaZ$8Wj&u^d6 z*krG4SP6`FkNzUY{=(XDLnv(-ZRnSoImHow1D6!;y`(3!j+@ zGVDRTkCH#76I{!oTP~j+rq-2mPs(0;ib^{^UoS|9Nv=tFuqR3Unh<25Z7q|>fWkSQ zdeV0&bjyIg$MlQ2ynYh>lE&~W+2oK_&a;(5$4>^wRPSvpO6+zIE?PV7gSVS1PC;wv zNIlF-a_EbRMN@BXCxC6(BN}7m@4u_0bUOlJ8lKACxVVTW|8Wd8v`m{SMKOCj!;^`y zUOJ&~3Wr$NpCL6rTM}KC)hkYhipN zSltl?gB=L3jXx{$tyT8%0gDx~|JLpdz7HQ%$cqCrZl0be0|M}!Wo+!!N%Gon(wERu zUAm_pAT;pYeRYGov8dm(RmB8s5q#v-O%F{`1!^Qu_eyDs_(<=Q>5kitXoo=Z!J(u) zwi6F@1xM-Og7OlVyUNSnqC7nK?)ef|sS8DH-1fp<0|T9N-jggJ8|mc+=uNUYPRifd zopIPV7WhNA#vHJuR$Rrg7~*I@`1XBZQtkf4&PIAPtkfV!XAX zr&*@EwpApkebi_j`4uDO7ye57sB>21VsUnaFN1D(?r?KDIy!IVl!B%XP=oGrES#{)!uQS1Kv* zZrZHXg3|nIFrQ(9W2YI6KY|ttLlyHLvkC{B#}g&v*mx~%qG2)b3GV@2XVz>&6wUr= z(r3P3c2NTJnG$1D3RAlmoMHWC_p_kS_lZTBW5G|+<>-u5H?c7*ucEJ!Gg{}WM5O7Y zd=mRFcGXwm?3Xt96VN-P<-!NpRKt}N+8+lr027oTF6vROShk(wqla?h%UfEKCmjLQ@GmLU267XYSR_9Z(r1oI)<4|aVcmkZ~Maka` z)Kcl8o5z!%6{%dQWQc6nB**8Xon+z>#s6W&BG;wZ-#@(FwQsDvZ5|iv@ZZpq8i^ia z_Vuf#F3c0)ePrD6Q2Iob7kG<@z-Li#r>Otw*RMMul$RGQjd%zF54f?>f%73{<&b&+ zWznIw{`iq`HF0Ysj&CJ%=|sq}6Q527FyxJ=y(eqD>f&?j^`3V@ z6IM}c*lnSG+<~bJy6DYSi*w}&Cd>fAor`V8}`g5R513_OZwr|u1N0<-RNis?T4wZL+@4L z6naIB_~7>y5>@Q2wyz?ovbI*AR9Rjwvb406j!HusOz_sR;5i~ z1K6#R9rG_R==1Wm396|Custy!suk4-Tre-znZH0}%U0(O@VT9}ZX~zCo`gVHvMJ_Oq)f zWl)kqu-%1MruV?OG^Ma^$plrYeJuke_o~s35=+PKBY^Do>L`I zVkXfaVOr7W0;znlW0Sq^VxPWrSq-gQEr~54lN_e0v8=`65$sm`JjL%#pSPXYQ3<8z zuRq<8X;<|HJF8p8Xn(8!;5do=RP~EbZ`>TC65-S1?cf)k@`dtE5sVI^XZp-EevmXQ z=2;`!v`E;lk5Z>UK$1J}GIyo&JG^JYJIqoi(ZqFp6Y;=pWEFQ*45v-W&41uNG?5xh zYPDy+L?=;3KvIo4n*Ne=dtW>4gw6KIvo>+eAy+ZH&Byui_P4r2jT@ zNBfG%vPNt#3Z}T^Z~D@~X1)CuMVo%pi; zH}mx0;QN`PJ5y#T0XJ+RL`M8)kl}r)C9%POQ$>Gbi*Is~%kuNwWRSVBa+SHATulf5 zLqirKa=<*#xy`uc^6vjt0sLBs>ZkAL$S8WBQ0QZv&P<8oxL)(MO75}KIPs!7RJQ^f z4MKI_8z6=7_fpPJbk5xD0C|F)8THv)VSJg?$J_XR8^O&GK%Ud(IUYI+{@^`%cXjQT zS6$2_LBJXnK9J3vg^#OxAG??vKCHpxah?RPvZE|dpC0h7P_jzZ<2`Dm7PQ*s*n0Bu z6!g!bLp+BYTU%Q*r9)@uV}H@)Ufku#8S>r|a?HqKfP|@foW`q93sy0Y&*|*H3 zSLF(MnR!`@9J}w7-gBK=bMg$g*I&xX=6IsGo%W>s(F+iN7RjogR}Cv|>pO0X!)M&8 zdrqd+$jpv_{`+=j40+E8rHNR;=sw1`DI6i28}iwHZBQ3wI;_jhal0|qf%05v{ST>e z1#Ub*W#cs6;;YuL0x8th>^YV!ur>MsZdggU1jWC8EiPs+PD@DDe~@8SWDj9JeLDVD z$6uMGWg3B5M#~0~`bT=j;SJ5b?Xr3F02wyLC-WUeLo%V1Sayg-eV3BrVmjDOq%tC8 zf8WuxuBsjSwDm+6YW|6L?MQ_%Z0tM2?Lp*dSetBNgR)Ii?kRBif!XLFf~jH)DVMs< z;2&g@d2kR`p);0xqyz~p8dr(v{7hWw%NHvtDd`*=iz$E$3OWfp#nm7H%+R6$+bI3z zz& zP&Biep0$z_Q<22p>+A?6Ok$iwkuz7)>km_l5_o1pQ@XoSYHF%b!}aIy-dyu^b2?|nAwkqZj#JG3L=D$FRR?VY@vsMqG9b~&+s zRKV}cmP23<&@r&IFb{9)zOQyuJjqu}XPl|#7`O46Kf6k>b4+&O&tf^;Y_isKj}?)P zYCh9#iJb)N6nHPydG`V%_G4C$8LUWYf2-{$tm!s?>^a(hz;5Gv1JFxU=u(IE`u`$0T;JEF;jGSss_4`wkQ-j=hG)(oEprgGv8{*-0R`v}N zQJeK^(gJ|Q-OG7;h~14UmiY4c%L(l<+&}-Rn_7*E|3~lu<04IQ zg?tU~smmGTAn!waFX>5g5;eh-l4 zM+`CruIdG}1^tOX36pwcw7?w7DuYbh_5+Qjf9)OWUsY?aq7moAIs0!;o08?=J1RaB zxI&NqV%N|KSRkN+cq#Pxi)p~YKG2dq|N9Ouu{PlI1HM%5sR%Hg(F8!KoRtugTqBX` z26d-1Z=NaRUj>4qQSN6)G#u^hS@)M!l6t%okhu#``yom0ULEQkmPOky|VJYLgc zi`iLJ0XJGcoy{hQPAs#xHElY8#UVp!|En6pEZL9^di$9>nbAfXz9;Hd{fU`X>fq1h zV`Tuz`IzY^*^;A_Zd@<}e7dt{v&?QW%FL*7Xko}uH#P;lhD3vDmwKLyKl7|yUcJ1S z<)F)S^k(aP{TVsVd&!@P1)>5&0C3&GBI0N=GTZ1gim@Kjl_69CN^FKb%QpYC@c(U?8^-oM_f1Pf}2apb80E=d6 ztV^U85ls8V=R6lHB>wmGhHg^_F z#{wZtefos0ms#OEuR0nfiha1P$f98>F}(Z$N!Mh)0A|C(h`p_Zw)a!lvRvcb=YV!U znraKTCF|z*kUR<{9&InzBFFdsO+m7e`m~SJ#_xGk|A+d$70abo^FR@ z{UieTdFaMbhJHKCMXBLIl0YOqHOirD&!15^cD6Sv{li~qjG={`o zIga>iG<|5G0o)0;JRPwvXj@*~yJ|OtMI1QJ9(%qRt9#%i?7Ma;-}^MnCcOulJ#qPE z#N=zB*&AQ1E{PV;cb+e!KH{1b#2^C-T81vocBD2oF`fpbX91=QzJKa=%JQ zcb|7If&}CO<22RD%6S4n9C$dZ%UnFE-$fYZn$-7%-qv!+nbYEvQO#n6 zkv;o&Q|GuEk~3W7142kWs>y|L0Ar=rcaOK$#uZV6x#@~Mn7nP7SyyH(>Ms^-xLzT@ z4@0IydzJ{(@0bALGAr;sgv<1t)#O+-%T2Wz7x-ijGvsQAKMl^ARU$4#FvR-Mn@kpT z9;N3B8syQ9f-5|Iw-%7K%cYD@6d<>iFpUWeF0f>WLKtb;U|dcZEn@nqe_;Ji-p!Bt z_ia+^TJ|~epxymzYsuLHD&pY@4!YGU*WeMhoN9V93nUzrVC4whn_E^>H~R!Q8og&? z*oXO37B%&+!GrEn3#gi5K-_wAFuI6*!}` zH1SqjzwbF(3}Me3G}V8z$gcDX)u4INibB!YHO%hQ*KnmV&|Q@*P*xBAD!6Wa``gZR zi?w9j@Dl9T|Gsnb!gkUyoO) zK&MM_+93g!nsu;j%aPO9$<2Bv+F_verxSpu{4L3~jIz$>);3Guezc>evB9;|Q45G+ zuZ6=(XrJD4l-|CPt3IO`I7?9x`1!RkZ-<_P#=hxkRJJwnY4PqFPa9=&`}oZJ?G-A6 z57b-K%hp;W(Ns$+TzxO@7dktE32Kja)2rVBr56LjWn(K0^GCec@ARGVp8ZldVVv$? z>1*hd>Qy^gdx;G8S36k#3Aaojp3zhEnVj)@m0fCl<~3|(`DoPJ1QfzF-0#OBBb@U$LuE1S3qt%Pgi z6dWk?Y>OkA?Pin!v{OZ#qf0W;oiUwt2J}R>Uzt&#Oh_1_{32z)#OGxgRuLpQNUa;K zV~nHP94ee?0~BLE{MMNElZs?G_z)j1MVJ4Mu3t$%>B1&pa=!B)=FHfUT@oV04q1_o z4Qy^>l>X3PxN)UHft(d)*JuYrHAC2P7*>pQG-MO^oN?H?21nvJVC4@pW=8P0Hs zW#HXhu5*8t!q_d*9MDU%$0Kp242wDV%91NnjIOh78Om&Pxx)Pw7Qy5N0_NGCvkZPy zI^}w0YCBxc`4AP}y=2OAY%XGRH_J`bwiRrPs5snFLIl(i4oCppw zyw99waskgS`dT!xO%RzDO!5y@hy3LR9(=VjME85tPVm;h`L{XYnH!S}vlsvQSOL53 zC&JQq82ANMgkl-OtT74~gl@`_OWUVTkQj5}MryaAyfF&MTf$%X8TxZG0;YKTqaV3u zME(|ddftiZd=(RAx|uWFGpa^_%Dp0$0A`8 zsRVA>klBMu;Ikd&9e)(5vs$yzlJ7kH+(_xcMJ@xv@y((0*{vgByx23o=KGV9_gUt! zP^O)}Rsv$kLZWNybAZq43(HP-g3#|?-xcP>+f_9jNYaaHtK`OcdM$OY06|uraN*fq zt@nY+uTt_u0Fl=CIv>2iF+0_g4x;CoL=n zK6!I74cu7JiRehH_d3)#oE?VDZd!RVLXkeSW#aMVox=yDsBvuQKB~|uGzIJ-gCu(k zDzq!@zR8a(DEKF&YbXr)ndW*(?){KJTF=kG3zt(#f@uyZNYRap{x^^>LxO*UN>|Sc z)S*XwCWl^xgYZYp!i3m)ekSYkg;H;^V@QG)b6UQwk4iu0=dtAlG=K_(@x9-4GhI3h z{(oYz*hkgXI=wWnyvxLz+%sc@kgu<$4JKb2OPd7YJD0Ad@l7XGDpy!d#teI15jM=D zhs_(6+9?PA?Pzl4$chLx-2uroKU}zzo>K=q+d{E-AAV|uTYoNmyg9Q$9?vH^eP>1(p3Ds#By%Olo<8znzDag~kNBI?C$ylk8y$_iEvmw`ftg4muER_=u1ZB+YI z8Cat#bLM5`%+I^5=Nv8D6k)XE=DR5kO$V;NR)_1H2QNvnmSVxpmO{^Mu=4E~FY)Gp zXZt${rCKlaJ5ie`&E&rYOVx73o*aI;KJ>$R!Ol?}FKZ;mW8B#(qgw*Kc=s^)d`t5!s)Z6E8 z8<74UvByu$FtEes!!Zun;&z9>{OHSba_=AD-rlj0VawkvMf4081#g>!byxGI3-uE+ zk8!x#24u&}<#>qaqWonZgAol5QU|$m-~z;+H%2*x{uu;!WM`ETK0!LHnZjqtKuW2C zj}x1A1x-iAh$*TTl5ELzWo5Nehtr&f@I2Yl5~CZi2tm)b(GeaaTZe6TB~a|nDWmFH zu-<}0bNWXStVF|-am>T>F`CM|PNq#t$5*F{XYB5Z!K8fI6_@BH0!$umHEiBwk|$$p znqs9^Ty6ZA+mV@tn`UFN`@)dcA^DR^Sv0?PME}o@vB&$untkyq8=u^Fp45M=hlsBt zvguesfD7*K8^%iw0Hu+)epiP#hoIzmy{Uu3N5f0;glF0uCbuqa^xNI&aNc$8vS*^aYm zws&a5=G}A!-)PrMmy}vgzGE?tfXTBEqFzvPV5YKUm2!Db;|yPtI2ur(j0tN9QK!)n zFQMFMT#f@d-~5EzU;Q-qNz!>T4?v%0P;!zBcjLjnQAc4@MY&+xoZubYCO1Xn;!jIK zWgw>_k#((bb^c%OLYP3hCb=aF?LE9|!-8F3MtGD_@N}Z9p+=cwJz{QhvC9m9ftk^L z)EUI-lq^s-+W}cvTAZTe+mm6>*3Vrm$EB!PVzjlj2R=GS#lhvA<3*HF3wFp$#^d)w z0=qekKDPJp)dHW8?6Y`#^x930-Q2yA(lz>3tkPbGbLb%!*7U9`^>I)i$J+s(!JCzr!Cpm?{WhI*d=+1|1b0@AaY5wqq=;@h)4)l#uzI`( z!mM=QR7c@^-7dC4EpZUWK;X*}0y7TbIMNJ3Tgh=iI1zKVW6RrIxWd*Yqj25)+3&d} zxXuaMO3@3SmTUZoDuJg~7~w~uK$w&$jJ(Z1xf3(yeRYDEbp|?c52nw|q;DmZ-%vUW z%9vIP{(GAyW0A|jVB&Vl4N(k7PQUGez|~R-IQEc!$k+X`dcqse4pFhL>rD;CgqQ!M z2608&t~81|s6XLfN?2CiX0%t%N3J+^)E+oT6Ax5B@_F*yTSha2v{%RSIrF=BE)j=| z!eSL0m%e8rFVYHNsAr(ahBK>MHO9bMDniGOEnp_F8nO6u#gFsNI)h03ZNYg8ufYgs zFD@+P2j>X&lIpu~I%ttlj50k#Kz?63ui)ku+t*0}ON`b4flE9VX~8yjH*+Zz<380= z(M#^=Xf(0C^FYQ{ar+uuxA)!@WfUe9b7+(+r-n(>gWuc8yuFR=Kx864=|>Nvh}T@F z%}Y2=zxS0vF?Y-tr>N#YFFGX*%fv=jIeJ84Wp4l1I|BZLly??JjD&+pv zg5~CTu_vYV;g64tez}rwhu$5<0jV*VRX-Mvl$D#~0m`FTvEBSPEy=S{LO`mmgv`-%5JCs04_(O=-_^3OqV zQBMS)Xq`Tzx_Uk()&jK%Ss^!bUUeK9hTp>@uFnqrXgnV!)9^rd3xYQLmwJA{AZD)- ztqM7z&lSG0N0}QD{cMmlwZ1!?7H=GmW0e@(0atU|SOUB9frfw|5=2xuLdy*ra|Hoi zxnX4at;uO_J?i;hjaw77DGy$^;qKtMWgzi2B;T6!^bL6QOXug=-}tHeK^Vd$iWM~o zF!l6FNf+SI4G-&khcEe)bv~QZk3}Bm&ZvGk;)1_V*m63PUHZxSx^_Fp&4#7HCti=EV=E-plGJ)rHH>?Kx}kY(IU!C@g*tN@+BU zkeLP6cB8%Cl-#c`1#}5All+HIy;1ctJYJjkcmr<9= z$KCt7l3K;@UHkqgvukPrlNSNT5kelWJGPZyi1FL9X+C%0U`%+kiKwQgcewqqLxq5s z8UHOXmdAmE%BJu~B88aGvP3U|%b9`t&>F;HlDu%Dd)JxK@o$*Oqt@?6F(T+2_Ng((m^rGBtA*6J|OPo=l%Ee&;hN!c7Nc z^aJ9VDB5&HSmmhCTW(q6Pvf_DmGcKRFEf8B4%kO`<0wD?IC0-e4oC$%lNE{f&p^`K zEn}iMwnw+5<1RdE;ND&cxL#vNm+b7NY$VT7b+UZ)qVF*?uD7`cKv0V$Tmcm8k7i&N zq9h;ywCw4C6q@9xp|;-N`xUU`k5|JLcp770kic#Bv%+dLZW9Mk|FI4qH$EHOh<&KJ zTj)E1?={e`_TW0QgGC=3TC-uh1P@4lJOK3<5nKRvADR~TG<`P&ij)fUvpTGAu@kyx zYzXX8J!QBtD(3Z-=v-2^(>KQanD)8DLW4jQfiCq0?deC?7WJk$Dw9_d6WJkdi2jHsCBa!IE&wf(D>aX)>X5|>rQt_2_BvsxzQInt98zmRlf|~l^a~&83?Gg<-(L(e zIsCP|`%uOQrca&CAw6AX#{iJeI)!`3Ei?FEug>7gCiELyDgx;=%nTK6SuO+L5gJB9 zBLOX4#n9EMglo}xo7gsaaKjbM?Opz=kVIxqQybH@V?5)WGdKL$#q9R%PSk zz55Tcl}}|7a?f2VfQ1Zd^7cW{#`Ajr(53!uNt)14Uo{_3u>9M- zLLsy#uERK?2%E33#0wnZQ-6ry`ezz;ME{J|KMb|`GvbuYw|>>U+Y6gFHk@M>%Qdbp z#kzn`)t|gVc_72MENp1lOB|kAC)p@zfLbN;&tb0_$gur`y>B1~e<^HT6&er$(ry^g z^7!q1fELOE?zSXN!b`ztG#UVp477bsqpCf=C(f;GL%=T_cMb_XzD4GWv{kxXTlq%aJ2^0%1u;#g0+DHd5MwfEcuSn2mc!UCH4*HE=6?{wMiUHtmyV z2pDl=0oK|((Mlfssm}s{$*&jLpvPHV(^>lmD%Y+JKhheS!TD9QD*Pd1L9~}~vXG>X z_QA@5Xyu8K;$mrPP}3<$zJ+Y;HZq1vyRz;$B4j6=X_wQ$Q1Op8@x>F~Kfu>pdw zOwl{i#z=4U9|TmuWoWu$<5s&wvH!yP6QS$2Zqz!4*JsA%!&LNG*YvW*RA#sL^e}-s zZT9Pf&6a9*M|nipa`SouBhw6T0KMhGFB>qQ?bTv7nL5Zb;QT8!4D)(;f)2BjlUk}$ zU}aGDJy=Tz_b9?fOV4*dKC%s+#wECIN`M2ueS3_%_6wNyNUG!={p(O2*Got}xMsYeyJ7bpbo__!Ld%yR1zmDTMj+*DW_v1L-uPL?|5t^YZkA6G;yj5UW%bOdC6NJOF5ay zbNNI8L+dp15{IT3eaObXweJbL6SB>%$sXx;w&@-FTR$ab?c)4!iZiWyuU9r+dk7{H zRv1OXINluP%}qyWphS?D7~)?X;)dh;5DMSQ8v4ChP1F4S?i zeI48qdK?=5rGQL*MOTZmOx;VkUU4zL__J7-&nI>sk;4m?8I)K-EVSy+QlBm@aaz`9 ziC#(7hc5cLG!hzCeaF6<$y())j%9Aa4dMA*sB<65;{3rbI%lTa(t7QQ7y6&q1?`OD zW`~Y{J4(S-9ovV#dGM*jpx@f1y~B?E3eH9=t}YI&`y=BWUKVT{GmN1vmi&-qxj3(5 z|NB;7c%C*>+X`|{$F^%8)2D|4WeKoH*aH#NkGum}0<2~pBZpPUkz3jhb2&IHajv}1 z^%R7#?DeturU_Se&EtojJ>xLbH?j4tX86f=VD|4vI&eF#^FD_Lv#=EDgpSmusqJ}f z=aO>~Jf2_mL&5%@kNd*r2D&(Sk&WJ=#1b3PeS`B${`MlP`bJ1FpS$qb=EDryU^!?% z{L~3uDEfSe(%lbh{_3<7zJW-(PKG1moKUviT{>TgBX@*qyPnSNO-2?^ElH?oz)eLk zJVMUzhfnNHx*%^&QSg_naKgY!T7rV}`lyK~4K-wVqA8v`RXM7i_WqRJW54j`kF{L* zF5w%ny$cv0{QMTq9@~OQD!i3}+-Bg?cseRJ%$U?phLMuviOgE?CNFf$YKOo=l$TEI z-+5PsMlO9u_kyIwE;9D$&U zrBnFHaxqhVlS5v^Xz2EpxBcXeg6#qeN?2^GXeP7UO+AZQalG4+6Hy0FM6oTuex0H& zYvHQ?J0_zb?PJ<3WzS&WKpNJ#YRl=vP?6_OFLzpACy!nRskYkmwtPStllH*HAxaS{ zin2fYasEGFLrE8XUbvf5cd}|uWHH}jfZz99_+n2NxW#!l3eeo;7^65Vy~A18Whp0L zY}S(O6*M{T53iKjYhM4?z{BCdbq1(TLjMXXZyO_PYnEfr$lf>3$WCe9{T7eD7r%z$ zJER(Tm~A^Z{`TYiZEAmE3LDk$3A@mfcwr_%mm004QMuYrA7SDQdIjyzMz|#l z4R3p;kryY=)AKt~XFelS@f&*os=r$oe&9bkzOAp|wZx*O|3pMf!zdQDt)B7h;w1 zj9{`iC5*1PAj^$US%g@%t^9l$s}>}iv5bW>Q_nSiQKSRr{AfwOq3<2n)yuH3Zlqd< z;lP!=M;I^KN9tX_@~rT4IRxfc$l|J+!#OdHb1RFy9jU2DXnrDak^44qT3fXdGNfyu z$GM$~CGvl;tVAwK(A)4w^ayQ63aPcX<0!&iDF}F@+csX7r4jzDIwpG}YS~vc`y~5T z1Lmdo{>5I(gGr}C^N+VvJBkL2{P%{K=wf5f+t3Ww9Xo!0(ZAd7&&%C+OJVx^)uW-s zGm+O@Sd*2ldU2RC%+`82%K_nQhkLa$^2zxz!SWZPYqO`OPbIhooUn3^5X7D(CGaIr zcIQz@;C&(9O1 zoNiOw?aHZ=__J|XV%h2t16{0G)VwHIbl7Zb_wkmfUNl_aJH5fTk1!kGscQUmi4cjn zDwRn@>H45WzI1m#MBYf0lBFQjE(XKqrEu#5dqu0cYF_~Wjj^9B=i=@kfc{KRk7K@D z#Pl~=#0(FAE$-(M8E2Lm0AHvXTElRp$IW=fIgT8hU+!^#7)rzmMMA>FnHhg6G%w+tdEvq7oii%Kg?}d|6 z{E51#6a2vwtQ9{#j(#0Q(j&_vYRv1;%U`&+_LHt!o9Ep4VAzuJiY;wqQNnN!tOdqT{z2*3Y5t zG4(2AX$GL-=*Xg~yschn}Q2ZBp zw*%ID;m5g7ADTih5oFYfL7%xFrJ8h+?mGWoSzr^oY<<%?h z2hPswE-r!=F!=&hcjMTRqeqp<&ML-*5b(kAtwUkhmM7RUtcK@QWLnV}Q5tF0bHG9u zb@dBps0$?#yZ>gPP?C7c|v}5knBLdB=BNK zgy+W>?t|pbg4M{Mg{}mr^Kx=w$l{U`M9{u%R$1Bc%z5^!$DjfU3ElHv4qyvsjTXe` z-2xse8<5XQhk(m(0ISFFEF<#LCf(=HpBv4|h->s26>PV96?8WXwz$0jPszL?Gn)fr zc=0H8VPl3A$@;#&S78n8#p6=C?pEFgmmkNaou$o2HD3JCL^`bRQ_2nIvmP1Dt$tYX zqMj6i>59ter@8*yuGN?ECTKmKPb@2vfZ zsVyu6#@(c$5b*Sa=D>{`1rG;@y%l+(H7?P9B^!q|z*f2Kk+HoSYT$Oh8ZKVP5g)6} z8_#j_2zVIb8;A%a`mF+7&>(T|5=!43@!>38V0}_~_2lBs>K;G(p8MLw`dmKFU7o{e1J{L|Oa z=P>*zr-644#@EHqR1m(Bq_+bj26fKVXIj_2a^h>jlo7sCM9HQ7@LOw1l5H znzgz(&E7!j?x#+FmBBA=;Va)U^ag3s9q8PxByAOS!{6kuSZy#0J=vRrsT=jAbA9l6 z{j{fXrzjPvYTxu?e|L(W#ZNbO#SFL>BIyIrySga^GX@lG#Ek+A8%jRejA}-GVM8Rw zBpQ>gH?_nwmFu29hfsnHpFh1;yV1e~)^ZSvE(-h$9_HjwkC}GG51mc8)oL{cpOL*C ztFoNMEWy8TM@VbK(~`*n*7MWgUI_z{rcwjKJ>LDo$@oqw3HX|ZXg#;aQ-}Y_{H6|u zpC>b_PR2zBJicXWM5Mmm<4y1uw88BnF4Q z<)K>Ltk0f$p8a36ke`a`7yG(*&-(W#lL#!7o1cpcSl<5gGhR#G7IlCfd&Ef*RmvZH z{P=OJ`@VjDmA|ss&B)}kiq_vD)Qz(H1>%eT&EgP+n`|5+U2Cl(S=3i4CvJmA7Ym86aRe-MxhuA6bU(>{PPM9um42B4z1(_dqE$*vWb z&>6LJSaqN(Y)rS$pC_j*G>z2+tmy2LxtMF?;KY^hP*pD z8t|k(YId11R10pq^;{1V-^Kc7&~=B?@=Y#{C3huK6`)!Wy!92{o!eE3{Uu_8Lbe+| z0>O}TKv4yq?jk8*dyxq`EMuuQTlW6F6h9iv54p|%I;Ewd=7Y~D5Y5PeOGcTFlQ(ms zaBpEj2@RU+Koc&`&h11~Ji3rtCei~)r`afMFI^C51E*lfR=)TrBY=}} z#69!mdDvBd_O4;jOmF9;8k}*6WjgUU%okQkIAT0`1UmAa6ovp6LgC#sx|Dc4u&jaHBim;izs7{sYI!-yeDBGf!G@}sf!b-!3sK| zXIbf-ot>?21x>hr%C7zVS?=(YpoCA$*f=Ftm%%>!L9g(bHy`qj1aFihyGC@*J+evF zY_khFfGm6EitKV`Ft)H*R`Qr;)lO65QR>AAryvnw8fu$xnxaS3tH^q<9hTdf)JVXE z_O98!aKdB=kYPCZ@rlj{cB;1b?~5oaSM@k*XV4gCce0HnS~;SC>C@M*!v?o+-+Nk> z_NlDQ%TJ_Yq&H@n;;ZW??@OFBS`y#3{C+p3gt+^@ru+^WRzv!PMzDrVevi?r=1IDv z3`8HbnESookgnLyF0vXnNH4a(5TKfkW_Su8!fKBSD<@OX!gT>5&p4pagy;wB zvaED=?XQ{0&wGh+|(Lmu(Im4!~I6|LO_aC^%Xq%hr_aG=~f60o6d#GhHGE{fSp~bZO+y%=rvc7 zftW<>8^Bab$en~YH7BfRimK2@@J8|NMXFa%_pvq3v1Si+)xomcmlKCs?Q^k= zag|;F&TADNAWhyB4||tt1yoYHPB)5AEUDi9_tx8vAE(xoYdHQk#uk+e&u?CScmGKg z$9dQ#1M$6ycYOO)Q1L{Gb(3g0EBppWskpXlk@4-D$2~#Bmy4CrLJZwB?$)D&7odbm zs{Jp(*j(azLR0>L{I|4f>VO2Qm-7_C>Cu0Fi~qKMH>03tBi~sTNDrIhSA=y7Xt8$= zT9(ALg*XGC_l;MuPP*~o>r)IH@C|-PI>3_u_E$x^X3qFPdt5D}uZtbbA#YmVNPTmm zoHC~a5n~W;8RhrKrr?)stScyKu_WHgw zxleb5s)-+^95g!p28T6$TE#BIJp_Y^Q#RNBOIU3-82}BZBlg9T3I{DBBWDh$%8>`VvY>y@ zVXnMK$Ow{?zi{IGh|9mSWeymoo^FB*XoJbneteyja{P+aLGUoZjTiajEEniht?Or_ zXIz&KZ12j60u-CB*illIIR?Ti0HIOFMIV65GB^V}%3E5nSwCCXMUyTQ1x^_B;e!cy zHXA8e-F@wK?#B3L@m24AZZ2B07uuR<;gZN~_8J)Ec{XoD~aGo)k~T z{W7~g_ z?iIu7W?Cb`dmAydYcnrwNS4X*#;i}=ue($vmP&u_6+Zb|%g37? z5Y=gTf>V6FI1qEU9g!l`BjPbRZLtd}B(@hAQhN`1?l2X^3aNodJdoKpKU&6b ziF*lTR5CNuJG_$$2DVWkOq|*mop}tL#7EGhGe4KIxG6r&==)3d;->Ft`dl!hug}$w z%EIpv{6PtZqtRGmPd5gH-oH2VpD~}J(42oLKJxTOx?^7vto0?ou0fE1@wH3p`tf*C zq4;^xo)gPxj+9s6L>ht;Zp$J6+EgzMIh_1KsJ+f%R#yCL)x0}?QcR9+C$c1-|F}9V zYm?Ml4%`al8y2Z^KMe-=+TNQOJG53d3;1JO9(^n+$VYVaM?G1Iv)J?rnS!LKYXhB= zak$N5qTDN>0T6rlfI@J)2~0HK8yoU_PiPbqt}IU9L9W<}-qBEobN0u&M+ny2ivvtd zml@r9M=d8_QFo=H)02aLF7?93GWbg-jOPJP2@P{54hQ9UQhzTLzQcqNqWorX7jwl; zqSNZj63w5oQ^XaHGRELu98#T|FV{!-19d@Emj|Q>dWr_6C7@m`PcI`ddbQ0ocsnC~ zc4hg|TDlz6ZV?)L3fpokV^E}@HAiNhqE8Y z@K8HPorl0_njx|^sF4n6fGGf1lPUTrp;VJ6yIXX1t3#EOwVyS`18(W`;dB{t9ru<0qW?`;;)#$YW-1|yP`FAb zbv|UikD^WU6X_n@GdRd4m^>cOj0G8+{N>=k{)3yN(0U=<4R&Y~M!FYO1y=v| zaf}P4g0b;AKiOCgY#N%Zv?pXz-c;sbbvQ5cSfJ_ zo~Yq{aO`Pn5;FGT&ciek4cEfIf92cQdd-EOlxF~&kwykNwwE5 zg+k{HOrE9S(5oZoG*23krf0nOg+?x%+VpK9GXnHFz4^6Zb zV|8+4L)x5@i+})KU4{Kwih)o6>R9+h=!4FOcMQ8%odsI14~OwS1&uVP>Q$Uj!ce+m!t+j0`1wV@>e{Y zk2b2k=Y!8zUS=U`h@6(rCC>3lV8X-%%`?}T(4CxE?L8lZ3%|*)fLF`Mzp^{EwGbV( zC7tqcrY-F;ST;hYk9O5d2k7c- z`s~#C>J;1fyW5d^qz~G906iw_C z1dfG4Ct2!n&Jy1T)yP_~~6A-oFZQRQ$=^rJp=!y8bA7HeKFzy5pFL1*zJYJ==eA>E$8`ga<&nSa1C} z1^BJx1ybwq-R-Aqz0&Po3oGZKkZ2CwvWt&*FUgAZ+>8`dn)Eg5Ycw>ch_`h zG1ocZB$%!CM9MD~P#Az0kXxE9(b0@qfK%t|EtFR&IiHv5|FYFPjZR2&eUrXZfd>wH z-{2cn}49 z5Xou*_bx2f0UfNZOgMYluUj*i7S8;V?|n?Zv_2QYO}hx`R5n^=pX|aVljJWdOjlUN z6hH=ea}Fp<-I}`Z2(72t+nc~La|fAviu#0_Lw3+ho0?!aWgTs8w)y#a-HoceD{U*; zNBrOozB~TAQCfn2V&i0ua=VZ-|HH%cwpsGo+r0CJ|912oU-jN-HXKVP>3pa-x0wYa zW84ucO$>u)sBOwc->1|1C$);O?5?l3stn&7zi`7@nSb?bTvyXl-vxvm9dV>$TPPmjH*elLi=nk;K6!Nu8bQqoYWNn zIkZrHW`sF8j{{Vd*iSN?{4#MHCN0rjNbKn@>cf*56DQM^zmJ3G)EZ8SiB;g`^H&|e z0tNJ?VSAnoH7}3>XSppx@421BjA^?Vegn@*%EX}Ij#0I3HM#-1UMHa0f&Aq!X59=W zkO*bS*HrU?C1@k<4l(kc{1EK9jkj1k{?kxUW8kOebyAKt@-&RAd}&|_+V$f%|GS-V z0x7RsYEEq05eMyQ)ozCG-#1d*EHI}+x<>u(1CQgFbvw;bBNtuEx;aQWw*v~f=c4tQ zMMn1j*kln=#$`C3q)}||5Uvz_XMlSCm2&2th{9yIav7_-dBatP{Cze3eS;nKt`1dL z?LJRNEx!i2MwM4hCahh6SiQ+1)sEp|H1^I)B#04`b4MvlwS9vZ3{ft= zSkd4y6uUR^SOiaKDap1~)y*hSkgICQQbc z{R*DHk1T2|7BQOWsb0_&ReG9gs@#T7P_>Q{P+({{Fm-Q|kRG=zo_s^)QK*t4+Yyju zSu8)Qh2%gz8LL(Op76MX_VK5Th;c2Hh?qn)gD|85ctYm6Kz$IMguOizeSlVJ6PKS` z83v>slpZTkOf{ayPfH#8PlQN|5@`<$-26D-E;v@-R?q(KFN7M%BLXGeV~fdb<|rfN z+mCq!`_ArsK8U|ebH^DSUxl}J>3%29YqA`YidAhFByYBC(v;S}bx{6O+YXQ#sDSxJ z9Ri8D&#gzn<*@RaaGN11KK_w_vbXV`ktqiyg>dTvG`3xGpa#n)15e>jSbuxQ6TR}! zTz`vnjgu`hWU$j3C=#F;W!CS#G>{E@a3++uDQfU;gU}I3#_6}r@!neCymXNFdG?0T z8@v^U@4>n3GtoOV)L2eSV~l!eoa)!MI8Sg4no_aZdE+>B$(o=@tvY~NSqsoKWVi%w z^WF7Z;68vspaH7Bl!C_lb_Abg_U}Uw+T^3|7b@WjTcd$|ATP8^-rIP$ucMt3#j;Yt z1$EBU^-t~NZ$nW>k&qky?lm;o{Y4*7h6DZ#4+mNO&4q8M^ic|<)B!g_v*rUqB_xa3 zz7b_v=Omrmju!6JTGq5oJ2XqSJ+A8NK(BiY?uW60{_x$S-l6p5O`prR6V+8HyOV`9 zBYk%)aF*Rrtvn`(5nZ*mlhoZ{r?UP-RIelH4cZSV%B=eW%@Ywmma|)`PTM?Lvz^#E zO6dwAs=#IU%=WP9o5mP-O}B9Yqlr!FLm3^#c@88U?2R-kN#*tH^L*g$CfiTg!3;@F z*bxbt1g!fe-@?gXbIirc_#PfhA8d|f?aLh;jxk3r2XHUX7M?UZJ}wiLQCq1lFg0@99#ITk@hE z!&Ur!&wL26jmY*C%2=jsY{0QDL2mhE6_%HjPg^bTp*Fj;WS!ebhc zUkDj@?5ewTP62sA+}mXaTFuv6Nl;OF9>|GI zaO1HW6Wn;g);BL$L*wdv9V8}p?Qm$=TX9x34X0p{TUz}xdC{E++O?=?>HSKN(~ShZBSV(8sbgi6(E(XD8NS{8IKG$b^gt1qetY|z%`37|^sMD2*)UI_X@_NCj#=!bDOocRuxcb%+OY`L0%Z)`;KO}GU7Kwl~6f_n`S3X&p)>DFa5xT-!rQ!m22L%V!7)8a$ zp9sfJSEWSl6`rtnt^-LHD|Bfl#uYDY*g4>r7luMZNoTFI->I@!4G@Dnj4KqRKXL0X z5isTKvbL?PkBdiY9*l4FEsr_26z1NBml+}P{XcIWMMvMa0?9xO`_F*Mh4~kibz&?17Y#BAr5ZAW?T!4ZYHs35`)dcZ zh#?bOu3voMTy$$YhshU`RaU`jvW!W!5QP0Waeg!p+kX~*zZwtE#T>%k6U2J=eD0(+ zPL>bTAGtRi+u0C*7^z2YX0D^H_G03a(Os`jS3IFvRx#e0%bff>tMFZmklZDR`L&D7 zKM6D2DeO@ZlQrYWH{mgUss_7l31dRqo|_Q^Q`FhgWVPP<&dndIcjg!&PBz)_uZQ}? z?Q*CwI%gV_-oRgT$HiNO`0DQoHrA=z;B1WE1~KFg7JWfxqP>9MUzM{oLT~3fw!BJ2 z)V{bb%2l$#nK=YoMt2$Pj%>e_4N4!`%QASQwr<5gCseuH5KA}9kCh;)Y3)KNM>g+z z{PNuIaq$M~cX7;9K5PWBrv|CNWXF(SPGB~aRQC{q$6lS54%b$ILPZoD`vR>eo9vtk z%Z=?b*+=nAkXwgYxcQ7Er+9<31->WY!CPupOCO?&w}};w_`vwIhjU5W8xcw0q~FqBYt7n9O1&CT-@-5dl42r6r2z*we|>U!?* zv$PHzhO7hCatB1d4a3loy33d%FMWH3@m{!2_CD^n>96~{-xll`lBThS8FNMmWZ#*W z_?4O}vuTOWrDpY8ZAU?e8nCEFXZv-xE$f&s%gJa0Fu@bSmOTqktr92Olq|dFB)->6 z3sS@K$CAUfpSb4}alcu{nt7Grt>(Eum?!yfNzIIwz}6Z@F@5)zsKn31j`6cb^G4=g zdE2HU1Kd`&Z7Hr57Zo44D1|;hiaU6bkt4-+sP&ldt^O!J*(|v#mpsMLp~aWSXW`W? z(WJ8#a_8G3WVHRL%Y(WeQsjueyNGVwKgot6gYM&Bddju9GkKRP)5dvWKV;|wZvlB1 z=HOLZBXOeOcl*un|?@Ak0?uURfNQKq#A*WXVqgf8u@}&J|x=Qn0ikORDKi< ziGLVKz!LB8DjuPSLBd1*!~u-hi=gP~xnS8|aX^ArfjX%1^y_rHzFJ>9P-pKG`GUiY z8~KBij|7In>+gVA7Xm} zAzT_)Qzka{^gEDxC`nrVuSq>528!(C14WMVf2JR!;W|e(a`cwO0o}uj2?T>* z;v1B85UlasDiW~h6Z13gxbDp9e2XRbR(rfOJXT6R76@hJubnI;`(yHy>-1L%va*a2 zN3K#T7dAN|$pPKWD#ehY7zpHf1awBxO?h;vl5s~WX~Fk+b~oO0ub~MTNRB>=GC!(# zW$sVpyA^tay%=yO3@s}#3m;a6iYF)gI={}2VJiG#*7Sfq6w<&>b0ec$`Xkq!CGlj< zdc@(=f%63zT3}1E{bmmdBqVW*WOhr}vqQG6Ny%J6(Z>R9{;OAT(}2Rjc0*_ug>%G@ z8dVbJu3vJZLT*C>S`A3!1dQ$R{6U>_kri}qbL-*H3+uImJ~&X@EbqzO8NW^g8}dLWVK*SfIDT1qhly`e=bTShQoX%s6Iz{N5-fBzg(^ zJN9Dc>YedKgNXd?_*St(=%0iRt;7%UQ5VIT&n`Z6D%unNGeC^5zIa9c3`J)C%Hh3t zuRXso?=Ngy0f#zKCTqA9V?%ST&rW`PkVZmwd{F2M9G+Us-vAJIb%SjwUP)C5aVFkG zRRsQA*s{v`n@1G{jQ}Ls%-y6lbY<@So=UplSR*QOcyDh+w*NBut9Ll&E6v#-EC|h_ z&A_9(n=igeyW!U6W|Ac3&?VD@kQ6yFms(Tj?mmOlm-v*)NvS= zQSQ_U`Eg{&qX*TmD(&$F`}fdt1S6C#n$6d^js~ALwP>1)pV8=H-1eE=iZSWh*@%|& z$&rvwz{(ORee!Ur%g7g4HK_3PKc3RB@T86);ud1;=C0Syo?UCjp13!WYmMrdFt~+d zrf{#oLbd%W?MtLP15~2c+!8$gn0GPVJno9;0OLvG*GnG>z~ZyAr=NE&fa9%OYOZ^g z#Q-f5b`AEeOWY?v7EWi2rlk)FVArtN9HO9sG}Uumxnv^;^8sh0%Im%LW^YllYZ0Wh z!1g{bwndkVGn%FZ4>_eP_EHK#F=iE9pekI_fd&BIuO#=Vp!T?VdlbtO^ex;$d z>F2NfebZ<1`8^o^T>6NS*fq!^ZU9-O9UHgT=*89g{_e)Xa`Bv=Cnr)yUyp(_{r5eb zP4wf68f^?ZlsjLnw`BBuz5{4D$+LFQ{HJJQoKi4j6Un Date: Sun, 8 Sep 2024 12:01:48 +0200 Subject: [PATCH 7/9] small fix --- code/__HELPERS/view.dm | 2 -- code/datums/components/fullauto.dm | 3 -- code/modules/projectiles/gun.dm | 17 ++++++++++ .../projectiles/guns/projectile/automatic.dm | 31 ++++++++++++------- .../projectiles/guns/projectile/pistol.dm | 2 ++ 5 files changed, 39 insertions(+), 16 deletions(-) diff --git a/code/__HELPERS/view.dm b/code/__HELPERS/view.dm index 6b1ce1b34a25..22637d252b9e 100644 --- a/code/__HELPERS/view.dm +++ b/code/__HELPERS/view.dm @@ -10,5 +10,3 @@ viewX = text2num(viewrangelist[1]) viewY = text2num(viewrangelist[2]) return list(viewX, viewY) - -#define CAN_THEY_SEE(target, source) ((source in viewers(7, target)) || in_range(target, source)) diff --git a/code/datums/components/fullauto.dm b/code/datums/components/fullauto.dm index 283f17fdf703..081ab7842681 100644 --- a/code/datums/components/fullauto.dm +++ b/code/datums/components/fullauto.dm @@ -237,9 +237,6 @@ if(get_dist(shooter, target) <= 0) target = get_step(shooter, shooter.dir) //Shoot in the direction faced if the mouse is on the same tile as we are. target_loc = target - else if(!CAN_THEY_SEE(target, shooter)) - stop_autofiring() //Elvis has left the building. - return FALSE shooter.face_atom(target) var/next_delay = autofire_shot_delay if(windup_autofire) diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm index 0176156ce1a5..121f87fe482a 100644 --- a/code/modules/projectiles/gun.dm +++ b/code/modules/projectiles/gun.dm @@ -41,6 +41,8 @@ var/two_hand_weapon = FALSE var/burst = 1 //burst size var/burst_delay = 1 //cooldown between burst shots + var/spread_increase = 0 // per shot + var/spread_max = 0 var/spread = 0 lefthand_file = 'icons/mob/inhands/guns_lefthand.dmi' @@ -49,6 +51,12 @@ /datum/action/item_action/hands_free/switch_gun name = "Switch Gun" +/obj/item/weapon/gun/process() + if(spread == 0) + STOP_PROCESSING(SSfastprocess, src) + else + spread = clamp(spread - 0.1, 0, spread_max) + /obj/item/weapon/gun/examine(mob/user) ..() if(two_hand_weapon) @@ -83,12 +91,21 @@ var/skill_recoil_duration = max(DEFAULT_DURATION_RECOIL, apply_skill_bonus(user, recoil, list(/datum/skill/firearms = SKILL_LEVEL_TRAINED), multiplier = -0.5)) if(two_hand_weapon != DESIRABLE_TWOHAND) shake_camera(user, skill_recoil_duration, OPTIMAL_POWER_RECOIL) + if(spread_increase) + spread = clamp(spread + spread_increase, 0, spread_max) + START_PROCESSING(SSfastprocess, src) if(two_hand_weapon == DESIRABLE_TWOHAND) //No OPTIMAL_POWER_RECOIL only for increasing user's motivation to drop other hand if(user.get_inactive_hand()) shake_camera(user, recoil + 2, recoil + 1) + if(spread_increase) + spread = clamp(spread + spread_increase + 1, 0, spread_max) + START_PROCESSING(SSfastprocess, src) else shake_camera(user, skill_recoil_duration, OPTIMAL_POWER_RECOIL) + if(spread_increase) + spread = clamp(spread + spread_increase, 0, spread_max) + START_PROCESSING(SSfastprocess, src) if(silenced) playsound(user, fire_sound, VOL_EFFECTS_MASTER, 30, FALSE, null, -4) diff --git a/code/modules/projectiles/guns/projectile/automatic.dm b/code/modules/projectiles/guns/projectile/automatic.dm index 7444bbabd241..1b021982a875 100644 --- a/code/modules/projectiles/guns/projectile/automatic.dm +++ b/code/modules/projectiles/guns/projectile/automatic.dm @@ -47,7 +47,8 @@ return ..() /obj/item/weapon/gun/projectile/automatic/saber - spread = 1 + spread_increase = 0.5 + spread_max = 1.5 fire_delay = 0 /obj/item/weapon/gun/projectile/automatic/saber/atom_init() @@ -65,7 +66,8 @@ initial_mag = /obj/item/ammo_box/magazine/mac10 can_be_silenced = TRUE fire_delay = 0 - spread = 1.5 + spread_increase = 0.25 + spread_max = 2 /obj/item/weapon/gun/projectile/automatic/mini_uzi/atom_init() . = ..() @@ -85,7 +87,8 @@ can_be_silenced = TRUE has_ammo_counter = TRUE fire_delay = 0 - spread = 1 + spread_increase = 0.25 + spread_max = 1.5 /obj/item/weapon/gun/projectile/automatic/c20r/atom_init() . = ..() @@ -104,7 +107,8 @@ two_hand_weapon = ONLY_TWOHAND has_ammo_counter = TRUE fire_delay = 0 - spread = 1.5 + spread_increase = 0.5 + spread_max = 2 /obj/item/weapon/gun/projectile/automatic/l6_saw/atom_init() . = ..() @@ -163,7 +167,8 @@ fire_sound = 'sound/weapons/guns/gunshot_l13.ogg' can_be_silenced = TRUE fire_delay = 0 - spread = 1 + spread_increase = 0.25 + spread_max = 1.5 /obj/item/weapon/gun/projectile/automatic/l13/atom_init() . = ..() @@ -182,7 +187,8 @@ fire_sound = 'sound/weapons/guns/gunshot_light.ogg' can_be_silenced = TRUE fire_delay = 0 - spread = 1.5 + spread_increase = 0.25 + spread_max = 2 /obj/item/weapon/gun/projectile/automatic/tommygun/atom_init() . = ..() @@ -199,6 +205,8 @@ initial_mag = /obj/item/ammo_box/magazine/bar fire_sound = 'sound/weapons/guns/Gunshot2.ogg' fire_delay = 0 + spread_increase = 0.5 + spread_max = 1 /obj/item/weapon/gun/projectile/automatic/bar/atom_init() . = ..() @@ -210,7 +218,6 @@ initial_mag = /obj/item/ammo_box/magazine/borg45 fire_sound = 'sound/weapons/guns/gunshot_medium.ogg' has_ammo_counter = TRUE - spread = 1 burst = 3 burst_delay = 2 @@ -252,7 +259,8 @@ suitable_mags = list(/obj/item/ammo_box/magazine/a28, /obj/item/ammo_box/magazine/a28/nonlethal, /obj/item/ammo_box/magazine/a28/incendiary) fire_sound = 'sound/weapons/guns/gunshot_medium.ogg' fire_delay = 0 - spread = 1 + spread_increase = 0.5 + spread_max = 1.5 /obj/item/weapon/gun/projectile/automatic/a28/atom_init() . = ..() @@ -270,7 +278,8 @@ origin_tech = "combat=5;materials=4;syndicate=6" fire_sound = 'sound/weapons/guns/gunshot_ak74.ogg' fire_delay = 0 - spread = 1 + spread_increase = 0.5 + spread_max = 1.5 /obj/item/weapon/gun/projectile/automatic/a74/atom_init() . = ..() @@ -359,7 +368,8 @@ two_hand_weapon = DESIRABLE_TWOHAND fire_delay = 3 burst = 3 - spread = 1.5 + spread_increase = 0.5 + spread_max = 1.5 /obj/item/weapon/gun/projectile/automatic/m41a/process_chamber() return ..(1, 1, 1) @@ -391,7 +401,6 @@ "You activate your [launcher].",\ "You hear an ominous click.") else - spread = 1.5 burst = 3 user.visible_message("[user] presses a button, deciding to stop the bombings.",\ "You deactivate your [launcher].",\ diff --git a/code/modules/projectiles/guns/projectile/pistol.dm b/code/modules/projectiles/guns/projectile/pistol.dm index b012d2b2528d..46c69c3fc04d 100644 --- a/code/modules/projectiles/guns/projectile/pistol.dm +++ b/code/modules/projectiles/guns/projectile/pistol.dm @@ -66,6 +66,8 @@ suitable_mags = list(/obj/item/ammo_box/magazine/stechkin, /obj/item/ammo_box/magazine/stechkin/extended) can_be_silenced = TRUE fire_delay = 0 + spread_increase = 0.5 + spread_max = 1.5 /obj/item/weapon/gun/projectile/automatic/pistol/stechkin/atom_init() . = ..() From b372a0be3f01c2f30d5d17e4b3cb4aafc500d8ba Mon Sep 17 00:00:00 2001 From: simb11 <84613249+simb11@users.noreply.github.com> Date: Mon, 16 Sep 2024 17:59:37 +0200 Subject: [PATCH 8/9] 321 --- code/__DEFINES/traits.dm | 1 + code/_onclick/click.dm | 4 ---- code/datums/components/fullauto.dm | 2 ++ code/modules/client/client_defines.dm | 4 ---- code/modules/mining/mine_items.dm | 4 ++-- code/modules/mob/living/carbon/human/human_movement.dm | 3 +++ code/modules/projectiles/guns/plasma/plasma.dm | 2 +- code/modules/projectiles/guns/projectile/automatic.dm | 8 +++++--- maps/centcom/centcom.dmm | 4 ++-- 9 files changed, 16 insertions(+), 16 deletions(-) diff --git a/code/__DEFINES/traits.dm b/code/__DEFINES/traits.dm index f5254f82ecef..dbbc836fccaf 100644 --- a/code/__DEFINES/traits.dm +++ b/code/__DEFINES/traits.dm @@ -197,6 +197,7 @@ #define TRAIT_MIMING "miming" #define TRAIT_WILLPOWER_IMPLANT "willpower_implant" #define TRAIT_CAN_LEAP "can_leap" +#define TRAIT_AUTOFIRE_SHOOTS "autofire_shoots" /* * Used for movables that need to be updated, via COMSIG_ENTER_AREA and COMSIG_EXIT_AREA, when transitioning areas. diff --git a/code/_onclick/click.dm b/code/_onclick/click.dm index 1008b1608f09..7d0761e32eaa 100644 --- a/code/_onclick/click.dm +++ b/code/_onclick/click.dm @@ -167,15 +167,11 @@ /client/MouseDown(datum/object, location, control, params) SEND_SIGNAL(src, COMSIG_CLIENT_MOUSEDOWN, object, location, control, params) - if(mouse_down_icon) - mouse_pointer_icon = mouse_down_icon ..() /client/MouseUp(object, location, control, params) if(SEND_SIGNAL(src, COMSIG_CLIENT_MOUSEUP, object, location, control, params) & COMPONENT_CLIENT_MOUSEUP_INTERCEPT) click_intercept_time = world.time - if(mouse_up_icon) - mouse_pointer_icon = mouse_up_icon /client/MouseDrag(src_object,atom/over_object,src_location,over_location,src_control,over_control,params) SEND_SIGNAL(src, COMSIG_CLIENT_MOUSEDRAG, src_object, over_object, src_location, over_location, src_control, over_control, params) diff --git a/code/datums/components/fullauto.dm b/code/datums/components/fullauto.dm index 081ab7842681..3bd03c5351e2 100644 --- a/code/datums/components/fullauto.dm +++ b/code/datums/components/fullauto.dm @@ -176,6 +176,7 @@ if(!process_shot()) //First shot is processed instantly. return //If it fails, such as when the gun is empty, then there's no need to schedule a second shot. + ADD_TRAIT(shooter, TRAIT_AUTOFIRE_SHOOTS, GENERIC_TRAIT) START_PROCESSING(SSfullauto, src) RegisterSignal(clicker, COMSIG_CLIENT_MOUSEDRAG, PROC_REF(on_mouse_drag)) @@ -201,6 +202,7 @@ UnregisterSignal(clicker, COMSIG_CLIENT_MOUSEDRAG) if(!QDELETED(shooter)) UnregisterSignal(shooter, COMSIG_MOB_SWAP_HANDS) + REMOVE_TRAIT(shooter, TRAIT_AUTOFIRE_SHOOTS, GENERIC_TRAIT) target = null target_loc = null mouse_parameters = null diff --git a/code/modules/client/client_defines.dm b/code/modules/client/client_defines.dm index 10076c751169..8e35c5318c0c 100644 --- a/code/modules/client/client_defines.dm +++ b/code/modules/client/client_defines.dm @@ -120,9 +120,5 @@ COOLDOWN_DECLARE(say_slowmode) var/is_in_spawner = FALSE - ///used to make a special mouse cursor, this one for mouse up icon - var/mouse_up_icon = null - ///used to make a special mouse cursor, this one for mouse up icon - var/mouse_down_icon = null ///used to override the mouse cursor so it doesnt get reset var/mouse_override_icon = null diff --git a/code/modules/mining/mine_items.dm b/code/modules/mining/mine_items.dm index ddd9358ab0c7..aa6b432be1cb 100644 --- a/code/modules/mining/mine_items.dm +++ b/code/modules/mining/mine_items.dm @@ -667,7 +667,7 @@ var/global/mining_shuttle_location = 0 // 0 = station 13, 1 = mining station damtype = BURN hitsound = list('sound/weapons/sear.ogg') ammo_type = list(/obj/item/ammo_casing/energy/laser/cutter) - fire_delay = 3 + fire_delay = 0 w_class = SIZE_SMALL //it is smaller than the pickaxe origin_tech = "materials=4;phorontech=3;engineering=3" desc = "The latest self-rechargeable low-power cutter using bursts of hot plasma. You could use it to cut limbs off of xenos! Or, you know, mine stuff." @@ -701,12 +701,12 @@ var/global/mining_shuttle_location = 0 // 0 = station 13, 1 = mining station /obj/item/weapon/gun/energy/laser/cutter/atom_init() . = ..() power_supply.AddComponent(/datum/component/cell_selfrecharge, 50) + AddComponent(/datum/component/automatic_fire, 0.4 SECONDS) /obj/item/weapon/gun/energy/laser/cutter/emag_act(mob/user) if(emagged) return FALSE ammo_type += new /obj/item/ammo_casing/energy/laser/cutter/emagged(src) - fire_delay = 5 origin_tech += ";syndicate=1" emagged = TRUE to_chat(user, "Ошибка: Обнаружен несовместимый модуль. Ошибкаошибкаошибка.") diff --git a/code/modules/mob/living/carbon/human/human_movement.dm b/code/modules/mob/living/carbon/human/human_movement.dm index a5d8a7bf3f34..a186e529b11d 100644 --- a/code/modules/mob/living/carbon/human/human_movement.dm +++ b/code/modules/mob/living/carbon/human/human_movement.dm @@ -136,6 +136,9 @@ if(get_species() == UNATHI && bodytemperature > species.body_temperature) tally -= min((bodytemperature - species.body_temperature) / 10, 1) //will be on the border of heat_level_1 + if(HAS_TRAIT(src, TRAIT_AUTOFIRE_SHOOTS)) // so that you can’t run at full speed and shoot everyone and everything + tally += 0.75 + return (tally + config.human_delay) /mob/living/carbon/human/Process_Spacemove(movement_dir = 0) diff --git a/code/modules/projectiles/guns/plasma/plasma.dm b/code/modules/projectiles/guns/plasma/plasma.dm index 283a954344ce..a7e256a658e8 100644 --- a/code/modules/projectiles/guns/plasma/plasma.dm +++ b/code/modules/projectiles/guns/plasma/plasma.dm @@ -89,7 +89,7 @@ fire_sound = initial(fire_sound) else shot = ammo_type[PLASMAGUN_OVERCHARGE_TYPE] - fire_delay = 1 + fire_delay = 0 fire_sound = overcharge_fire_sound max_projectile_per_fire = 1 diff --git a/code/modules/projectiles/guns/projectile/automatic.dm b/code/modules/projectiles/guns/projectile/automatic.dm index 1b021982a875..48b983faa04e 100644 --- a/code/modules/projectiles/guns/projectile/automatic.dm +++ b/code/modules/projectiles/guns/projectile/automatic.dm @@ -1,6 +1,6 @@ -/obj/item/weapon/gun/projectile/automatic //Hopefully someone will find a way to make these fire in bursts or something. --Superxpdude - name = "submachine gun" - desc = "Легкий, скорострельный пистолет-пулемёт. Использует патроны калибра 9мм." +/obj/item/weapon/gun/projectile/automatic + name = "generic automatic gun" + desc = "О боже, вы не должны были видеть это!" icon_state = "saber" item_state = null w_class = SIZE_SMALL @@ -47,6 +47,8 @@ return ..() /obj/item/weapon/gun/projectile/automatic/saber + name = "submachine gun" + desc = "Легкий, скорострельный пистолет-пулемёт. Использует патроны калибра 9мм." spread_increase = 0.5 spread_max = 1.5 fire_delay = 0 diff --git a/maps/centcom/centcom.dmm b/maps/centcom/centcom.dmm index be4149c678d9..2c6d0b6e89eb 100644 --- a/maps/centcom/centcom.dmm +++ b/maps/centcom/centcom.dmm @@ -14441,10 +14441,10 @@ /area/custom/wizard_station) "aGr" = ( /obj/structure/rack, -/obj/item/weapon/gun/projectile/automatic{ +/obj/item/weapon/gun/projectile/automatic/saber{ pixel_y = 6 }, -/obj/item/weapon/gun/projectile/automatic{ +/obj/item/weapon/gun/projectile/automatic/saber{ pixel_y = 3 }, /obj/item/weapon/gun/projectile/automatic/saber, From 29f580f8921bb5986ce267b31e5b376163b595ee Mon Sep 17 00:00:00 2001 From: simb11 <84613249+simb11@users.noreply.github.com> Date: Sat, 21 Sep 2024 15:32:54 +0200 Subject: [PATCH 9/9] rnd plasma cutter fix --- code/modules/mining/mine_items.dm | 1 - code/modules/research/prototipify.dm | 7 +++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/code/modules/mining/mine_items.dm b/code/modules/mining/mine_items.dm index aa6b432be1cb..d1e52bba2bea 100644 --- a/code/modules/mining/mine_items.dm +++ b/code/modules/mining/mine_items.dm @@ -697,7 +697,6 @@ var/global/mining_shuttle_location = 0 // 0 = station 13, 1 = mining station if((iswallturf(target)) && (prob(destruction_chance))) target.ex_act(EXPLODE_HEAVY) - /obj/item/weapon/gun/energy/laser/cutter/atom_init() . = ..() power_supply.AddComponent(/datum/component/cell_selfrecharge, 50) diff --git a/code/modules/research/prototipify.dm b/code/modules/research/prototipify.dm index 4ffc28fd3b01..d712c0f0ed61 100644 --- a/code/modules/research/prototipify.dm +++ b/code/modules/research/prototipify.dm @@ -92,6 +92,13 @@ power_supply.maxcharge /= 2 power_supply.charge = power_supply.maxcharge +/obj/item/weapon/gun/energy/laser/cutter/set_prototype_qualities(rel_val=100, mark=0) + if(mark) + power_supply.maxcharge += (mark - 1) * 200 + if(!prob(reliability)) + power_supply.maxcharge /= 2 + power_supply.charge = power_supply.maxcharge + /obj/item/weapon/gun/projectile/automatic/set_prototype_qualities(rel_val=100, mark=0) if(mark) recoil = max(recoil / mark, 0.5)