From ad11a9a70315f0ad4eb45454e7e23c5abcc1ca4a Mon Sep 17 00:00:00 2001 From: Doubleumc Date: Sat, 28 Oct 2023 02:24:37 -0400 Subject: [PATCH 01/21] first test --- code/modules/vehicles/hardpoints/hardpoint.dm | 376 +++++++++++++++++- .../hardpoints/primary/dual_cannon.dm | 32 +- .../vehicles/hardpoints/secondary/cupola.dm | 2 +- .../hardpoints/secondary/frontal_cannon.dm | 2 +- .../hardpoints/special/firing_port_weapon.dm | 2 +- code/modules/vehicles/multitile/multitile.dm | 1 + .../multitile/multitile_interaction.dm | 60 +++ 7 files changed, 446 insertions(+), 29 deletions(-) diff --git a/code/modules/vehicles/hardpoints/hardpoint.dm b/code/modules/vehicles/hardpoints/hardpoint.dm index ee49ebc0ab57..85b7984cb71a 100644 --- a/code/modules/vehicles/hardpoints/hardpoint.dm +++ b/code/modules/vehicles/hardpoints/hardpoint.dm @@ -98,17 +98,91 @@ //maximum amount of spare mags var/max_clips = 0 - /// An assoc list in the format list(/datum/element/bullet_trait_to_give = list(...args)) - /// that will be given to a projectile fired from the hardpoint + + /**How the bullet will behave once it leaves the gun, also used for basic bullet damage and effects, etc. + Ammo will be replaced on New() for things that do not use mags.**/ + //var/datum/ammo/ammo = null + ///What is currently in the chamber. Most guns will want something in the chamber upon creation. + //var/obj/projectile/in_chamber = null + /*Ammo mags may or may not be internal, though the difference is a few additional variables. If they are not internal, don't call + on those unique vars. This is done for quicker pathing. Just keep in mind most mags aren't internal, though some are. + This is also the default magazine path loaded into a projectile weapon for reverse lookups on New(). Leave this null to do your own thing.*/ + //var/obj/item/ammo_magazine/internal/current_mag = null + + ///How much the bullet scatters when fired. + var/scatter = 0 + ///Multiplier. Increases or decreases how much bonus scatter is added with each bullet during burst fire (wielded only). + var/burst_scatter_mult = 4 + + ///What minimum range the weapon deals full damage, builds up the closer you get. 0 for no minimum. + var/effective_range_min = 0 + ///What maximum range the weapon deals full damage, tapers off using damage_falloff after hitting this value. 0 for no maximum. + var/effective_range_max = 0 + + ///For regular shots, how long to wait before firing again. Use modify_fire_delay and set_fire_delay instead of modifying this on the fly + VAR_PROTECTED/fire_delay = 0 + ///When it was last fired, related to world.time. + var/last_fired = 0 + + //Burst fire. + ///How many shots can the weapon shoot in burst? Anything less than 2 and you cannot toggle burst. Use modify_burst_amount and set_burst_amount instead of modifying this + VAR_PROTECTED/burst_amount = 1 + ///The delay in between shots. Lower = less delay = faster. Use modify_burst_delay and set_burst_delay instead of modifying this + VAR_PROTECTED/burst_delay = 1 + ///When burst-firing, this number is extra time before the weapon can fire again. Depends on number of rounds fired. + var/extra_delay = 0 + + // Full auto + ///Whether or not the gun is firing full-auto + var/fa_firing = FALSE + ///How many full-auto shots to get to max scatter? + var/fa_scatter_peak = 4 + ///How bad does the scatter get on full auto? + var/fa_max_scatter = 6.5 + + var/flags_gun_features = GUN_AMMO_COUNTER + + /** An assoc list in the format list(/datum/element/bullet_trait_to_give = list(...args)) + that will be given to a projectile with the current ammo datum**/ var/list/list/traits_to_give + ///Current selected firemode of the gun. + var/gun_firemode = GUN_FIREMODE_SEMIAUTO + ///List of allowed firemodes. + var/list/gun_firemode_list = list() + ///How many bullets the gun fired while bursting/auto firing + var/shots_fired = 0 + /// Currently selected target to fire at. Set with set_target() + VAR_PRIVATE/atom/target + /// Current operator (crew) of the hardpoint. + VAR_PRIVATE/mob/hp_operator + /// If this gun should spawn with semi-automatic fire. Protected due to it never needing to be edited. + VAR_PROTECTED/start_semiauto = TRUE + /// If this gun should spawn with automatic fire. Protected due to it never needing to be edited. + VAR_PROTECTED/start_automatic = FALSE + /// The type of projectile that this gun should shoot + var/projectile_type = /obj/projectile + /// The multiplier for how much slower this should fire in automatic mode. 1 is normal, 1.2 is 20% slower, 2 is 100% slower, etc. Protected due to it never needing to be edited. + VAR_PROTECTED/autofire_slow_mult = 1 + + /// Semi auto cooldown + COOLDOWN_DECLARE(semiauto_fire_cooldown) + /// How long between semi-auto shots this should wait, to reduce possible spam + var/semiauto_cooldown_time = 0.2 SECONDS + var/empty_alarm = 'sound/weapons/hmg_eject_mag.ogg' + //----------------------------- //------GENERAL PROCS---------- //----------------------------- /obj/item/hardpoint/Initialize() . = ..() + + //set_gun_config_values() set_bullet_traits() + //setup_firemodes() + //gun_firemode = gun_firemode_list[1] || GUN_FIREMODE_SEMIAUTO + AddComponent(/datum/component/automatedfire/autofire, fire_delay, burst_delay, burst_amount, gun_firemode, autofire_slow_mult, CALLBACK(src, PROC_REF(set_bursting)), CALLBACK(src, PROC_REF(reset_fire)), CALLBACK(src, PROC_REF(fire_wrapper)), CALLBACK(src, PROC_REF(display_ammo)), CALLBACK(src, PROC_REF(set_auto_firing))) //This should go after handle_starting_attachment() and setup_firemodes() to get the proper values set. /obj/item/hardpoint/Destroy() if(owner) @@ -117,6 +191,9 @@ owner = null QDEL_NULL_LIST(backup_clips) QDEL_NULL(ammo) + ammo = null + target = null + hp_operator = null return ..() @@ -278,14 +355,14 @@ continue // Make sure we can pass object from all directions - if(!(O.pass_flags.flags_can_pass_all & PASS_OVER_THROW_ITEM)) - if(!(O.flags_atom & ON_BORDER)) + if(!CHECK_BITFIELD(O.pass_flags.flags_can_pass_all, PASS_OVER_THROW_ITEM)) + if(!CHECK_BITFIELD(O.flags_atom, ON_BORDER)) return FALSE //If we're behind the object, check the behind pass flags - else if(dir == O.dir && !(O.pass_flags.flags_can_pass_behind & PASS_OVER_THROW_ITEM)) + else if(dir == O.dir && !CHECK_BITFIELD(O.pass_flags.flags_can_pass_behind, PASS_OVER_THROW_ITEM)) return FALSE //If we're in front, check front pass flags - else if(dir == turn(O.dir, 180) && !(O.pass_flags.flags_can_pass_front & PASS_OVER_THROW_ITEM)) + else if(dir == turn(O.dir, 180) && !CHECK_BITFIELD(O.pass_flags.flags_can_pass_front, PASS_OVER_THROW_ITEM)) return FALSE // Trace back towards the vehicle @@ -561,6 +638,293 @@ ammo.current_rounds-- +/* +/obj/item/hardpoint/proc/setup_firemodes() + var/old_firemode = gun_firemode + gun_firemode_list.len = 0 + + if(start_automatic) + gun_firemode_list |= GUN_FIREMODE_AUTOMATIC + + if(start_semiauto) + gun_firemode_list |= GUN_FIREMODE_SEMIAUTO + + if(burst_amount > BURST_AMOUNT_TIER_1) + gun_firemode_list |= GUN_FIREMODE_BURSTFIRE + + if(!length(gun_firemode_list)) + CRASH("[src] called setup_firemodes() with an empty gun_firemode_list") + + else if(old_firemode in gun_firemode_list) + gun_firemode = old_firemode + + else + gun_firemode = gun_firemode_list[1] +*/ + +/// Setter proc to toggle burst firing +/obj/item/hardpoint/proc/set_bursting(bursting = FALSE) + if(bursting) + ENABLE_BITFIELD(flags_gun_features, GUN_BURST_FIRING) + else + DISABLE_BITFIELD(flags_gun_features, GUN_BURST_FIRING) + +///Clean all references +/obj/item/hardpoint/proc/reset_fire() + shots_fired = 0//Let's clean everything + set_target(null) + set_auto_firing(FALSE) + +///Set the target and take care of hard delete +/obj/item/hardpoint/proc/set_target(atom/object) + if(object == target || object == loc) + return + if(target) + UnregisterSignal(target, COMSIG_PARENT_QDELETING) + target = object + if(target) + RegisterSignal(target, COMSIG_PARENT_QDELETING, PROC_REF(clean_target)) + +///Set the target to its turf, so we keep shooting even when it was qdeled +/obj/item/hardpoint/proc/clean_target() + SIGNAL_HANDLER + target = get_turf(target) + +/// Setter proc for fa_firing +/obj/item/hardpoint/proc/set_auto_firing(auto = FALSE) + fa_firing = auto + +/obj/item/hardpoint/proc/display_ammo(mob/user) + if(!user) + user = hp_operator + + if(CHECK_BITFIELD(flags_gun_features, GUN_AMMO_COUNTER) && ammo) + //var/chambered = in_chamber ? TRUE : FALSE + to_chat(user, SPAN_DANGER("[ammo.current_rounds] / [ammo.max_rounds] ROUNDS REMAINING")) + +/* +/obj/item/hardpoint/proc/try_fire() + if(!ammo?.current_rounds) + to_chat(hp_operator, SPAN_WARNING("*click*")) + playsound(src, 'sound/weapons/gun_empty.ogg', 25, 1, 5) + return + + return fire_shot() + +/obj/item/hardpoint/proc/fire_shot() //Bang Bang + var/atom/T = target + + var/turf/origin_turf = get_turf(src) + origin_turf = locate(origin_turf.x + origins[1], origin_turf.y + origins[2], origin_turf.z) + + var/obj/projectile/P = generate_bullet(hp_operator, origin_turf) + SEND_SIGNAL(P, COMSIG_BULLET_USER_EFFECTS, hp_operator) + P.fire_at(T, hp_operator, src, P.ammo.max_range, P.ammo.shell_speed) + + if(LAZYLEN(activation_sounds)) + playsound(get_turf(src), pick(activation_sounds), 60, 1) + + if(use_muzzle_flash) + muzzle_flash(Get_Angle(origin_turf, T)) + + ammo.current_rounds-- + if(!ammo.current_rounds) + handle_ammo_out() + + return AUTOFIRE_CONTINUE +*/ + +/obj/item/hardpoint/proc/handle_ammo_out(mob/user) + visible_message(SPAN_NOTICE("[icon2html(src, viewers(src))] [src] beeps steadily and its ammo light blinks red.")) + playsound(loc, empty_alarm, 25, 1) + +/obj/item/hardpoint/proc/crew_mouseup(datum/source, atom/object, turf/location, control, params) + if(!target) + return + + if(gun_firemode == GUN_FIREMODE_AUTOMATIC) + reset_fire() + display_ammo() + SEND_SIGNAL(src, COMSIG_GUN_STOP_FIRE) + +///Update the target if you draged your mouse +/obj/item/hardpoint/proc/crew_mousedrag(datum/source, atom/src_object, atom/over_object, turf/src_location, turf/over_location, src_control, over_control, params) + set_target(get_turf_on_clickcatcher(over_object, hp_operator, params)) + +///Check if the gun can fire and add it to bucket auto_fire system if needed, or just fire the gun if not +/obj/item/hardpoint/proc/crew_mousedown(datum/source, atom/object, turf/location, control, params) + //hp_operator = owner.get_seat_mob(allowed_seat) + hp_operator = source + + if (CHECK_BITFIELD(flags_gun_features, GUN_BURST_FIRING)) + return + + var/list/modifiers = params2list(params) + if(modifiers["shift"] || modifiers["middle"] || modifiers["right"]) + return + + if(istype(object, /atom/movable/screen)) + return + + if(QDELETED(object)) + return + + set_target(get_turf_on_clickcatcher(object, hp_operator, params)) + if(gun_firemode == GUN_FIREMODE_SEMIAUTO && COOLDOWN_FINISHED(src, semiauto_fire_cooldown)) + COOLDOWN_START(src, semiauto_fire_cooldown, semiauto_cooldown_time) + //try_fire(object, hp_operator, modifiers) + fire_wrapper(object, hp_operator, modifiers) + reset_fire() + display_ammo() + return + else + SEND_SIGNAL(src, COMSIG_GUN_FIRE) + +/// Wrapper proc for the autofire subsystem to ensure the important args aren't null +/obj/item/hardpoint/proc/fire_wrapper(atom/target, mob/living/user, params) + SHOULD_NOT_OVERRIDE(TRUE) + if(!target) + target = src.target + if(!user) + user = hp_operator + if(!target || !user) + return NONE + return Fire(target, user, params) + +/obj/item/hardpoint/proc/Fire(atom/target, mob/living/user, params) + set waitfor = FALSE + + if(!able_to_fire(user) || !target || !get_turf(user) || !get_turf(target)) + return NONE + + /* + This is where burst is established for the proceeding section. Which just means the proc loops around that many times. + If burst = 1, you must null it if you ever RETURN during the for() cycle. If for whatever reason burst is left on while + the gun is not firing, it will break a lot of stuff. BREAK is fine, as it will null it. + */ + if((gun_firemode == GUN_FIREMODE_BURSTFIRE) && burst_amount > BURST_AMOUNT_TIER_1) + ENABLE_BITFIELD(flags_gun_features, GUN_BURST_FIRING) + + var/fire_return = handle_fire(target, user, params) + if(!fire_return) + return fire_return + + DISABLE_BITFIELD(flags_gun_features, GUN_BURST_FIRING) // We always want to turn off bursting when we're done, mainly for when we break early mid-burstfire. + return AUTOFIRE_CONTINUE + +/obj/item/hardpoint/proc/able_to_fire(mob/user) + if(CHECK_BITFIELD(flags_gun_features, GUN_BURST_FIRING)) + return TRUE + + // The rest is delay-related. If we're firing full-auto it doesn't matter + if(fa_firing) + return TRUE + + var/next_shot = last_fired + fire_delay + + if(world.time >= next_shot + extra_delay) //check the last time it was fired. + extra_delay = 0 + + return TRUE + +/obj/item/hardpoint/proc/handle_fire(atom/target, mob/living/user, params) + var/turf/curloc = get_turf(src) //In case the target or we are expired. + var/turf/targloc = get_turf(target) + + var/atom/original_target = target //This is for burst mode, in case the target changes per scatter chance in between fired bullets. + + //The gun should return the bullet that it already loaded from the end cycle of the last Fire(). + //var/obj/projectile/projectile_to_fire = load_into_chamber(user) //Load a bullet in or check for existing one. + var/obj/projectile/projectile_to_fire = generate_bullet(user, curloc) + if(!projectile_to_fire) //If there is nothing to fire, click. + click_empty(user) + DISABLE_BITFIELD(flags_gun_features, GUN_BURST_FIRING) + return NONE + + /* + apply_bullet_effects(projectile_to_fire, user) //User can be passed as null. + SEND_SIGNAL(projectile_to_fire, COMSIG_BULLET_USER_EFFECTS, user) + */ + + if(QDELETED(original_target)) //If the target's destroyed, shoot at where it was last. + target = targloc + else + target = original_target + targloc = get_turf(target) + + projectile_to_fire.original = target + + /* + // turf-targeted projectiles are fired without scatter, because proc would raytrace them further away + var/ammo_flags = projectile_to_fire.ammo.flags_ammo_behavior | projectile_to_fire.projectile_override_flags + if(!CHECK_BITFIELD(ammo_flags, AMMO_HITS_TARGET_TURF)) + target = simulate_scatter(projectile_to_fire, target, curloc, targloc, user) + + var/bullet_velocity = projectile_to_fire?.ammo?.shell_speed + velocity_add + */ + + /* + if(params) // Apply relative clicked position from the mouse info to offset projectile + if(!params["click_catcher"]) + if(params["vis-x"]) + projectile_to_fire.p_x = text2num(params["vis-x"]) + else if(params["icon-x"]) + projectile_to_fire.p_x = text2num(params["icon-x"]) + if(params["vis-y"]) + projectile_to_fire.p_y = text2num(params["vis-y"]) + else if(params["icon-y"]) + projectile_to_fire.p_y = text2num(params["icon-y"]) + var/atom/movable/clicked_target = original_target + if(istype(clicked_target)) + projectile_to_fire.p_x -= clicked_target.bound_width / 2 + projectile_to_fire.p_y -= clicked_target.bound_height / 2 + else + projectile_to_fire.p_x -= world.icon_size / 2 + projectile_to_fire.p_y -= world.icon_size / 2 + else + projectile_to_fire.p_x -= world.icon_size / 2 + projectile_to_fire.p_y -= world.icon_size / 2 + */ + + play_firing_sounds(projectile_to_fire, user) + + if(targloc != curloc) + //This is where the projectile leaves the barrel and deals with projectile code only. + //vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + //in_chamber = null // It's not in the gun anymore + INVOKE_ASYNC(projectile_to_fire, TYPE_PROC_REF(/obj/projectile, fire_at), target, user, src, projectile_to_fire?.ammo?.max_range, projectile_to_fire?.ammo?.shell_speed, original_target) + projectile_to_fire = null // Important: firing might have made projectile collide early and ALREADY have deleted it. We clear it too. + //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + . = TRUE + + shots_fired++ + else + return TRUE + + //>>POST PROCESSING AND CLEANUP BEGIN HERE.<< + var/angle = round(Get_Angle(user, target)) //Let's do a muzzle flash. + muzzle_flash(angle,user) + + //This is where we load the next bullet in the chamber. + //if(!reload_into_chamber(user)) // It has to return a bullet, otherwise it's empty. + if(!ammo.current_rounds) + click_empty(user) + return TRUE //Nothing else to do here, time to cancel out. + return TRUE + +/obj/item/hardpoint/proc/click_empty(mob/user) + if(user) + to_chat(user, SPAN_WARNING("*click*")) + playsound(user, 'sound/weapons/gun_empty.ogg', 25, 1, 5) //5 tile range + else + playsound(src, 'sound/weapons/gun_empty.ogg', 25, 1, 5) + +/obj/item/hardpoint/proc/play_firing_sounds(obj/projectile/projectile_to_fire, mob/user) + if(LAZYLEN(activation_sounds)) + playsound(get_turf(src), pick(activation_sounds), 60, 1) + + //----------------------------- //------ICON PROCS---------- //----------------------------- diff --git a/code/modules/vehicles/hardpoints/primary/dual_cannon.dm b/code/modules/vehicles/hardpoints/primary/dual_cannon.dm index 763bfb69842d..78e19d8b1329 100644 --- a/code/modules/vehicles/hardpoints/primary/dual_cannon.dm +++ b/code/modules/vehicles/hardpoints/primary/dual_cannon.dm @@ -15,7 +15,7 @@ cooldown = 7 accuracy = 0.98 firing_arc = 60 - var/burst_amount = 2 + //var/burst_amount = 2 origins = list(0, -2) @@ -33,27 +33,19 @@ "8" = list(14, 9) ) + //fire_delay = 0.6 SECONDS + burst_amount = 2 + burst_delay = 0.3 SECONDS + //extra_delay = 0.7 SECONDS + gun_firemode = GUN_FIREMODE_BURSTFIRE + gun_firemode_list = list( + GUN_FIREMODE_BURSTFIRE, + //GUN_FIREMODE_AUTOMATIC, + ) + start_semiauto = FALSE + /obj/item/hardpoint/primary/dualcannon/set_bullet_traits() ..() LAZYADD(traits_to_give, list( BULLET_TRAIT_ENTRY(/datum/element/bullet_trait_iff) )) - -/obj/item/hardpoint/primary/dualcannon/fire(mob/user, atom/A) - if(ammo.current_rounds <= 0) - return - - next_use = world.time + cooldown * owner.misc_multipliers["cooldown"] - - for(var/bullets_fired = 1, bullets_fired <= burst_amount, bullets_fired++) - var/atom/T = A - if(!prob((accuracy * 100) / owner.misc_multipliers["accuracy"])) - T = get_step(get_turf(A), pick(cardinal)) - if(LAZYLEN(activation_sounds)) - playsound(get_turf(src), pick(activation_sounds), 60, 1) - fire_projectile(user, T) - if(ammo.current_rounds <= 0) - break - if(bullets_fired < burst_amount) //we need to sleep only if there are more bullets to shoot in the burst - sleep(3) - to_chat(user, SPAN_WARNING("[src] Ammo: [SPAN_HELPFUL(ammo ? ammo.current_rounds : 0)]/[SPAN_HELPFUL(ammo ? ammo.max_rounds : 0)] | Mags: [SPAN_HELPFUL(LAZYLEN(backup_clips))]/[SPAN_HELPFUL(max_clips)]")) diff --git a/code/modules/vehicles/hardpoints/secondary/cupola.dm b/code/modules/vehicles/hardpoints/secondary/cupola.dm index f1f8f23435c2..712e6c7763e3 100644 --- a/code/modules/vehicles/hardpoints/secondary/cupola.dm +++ b/code/modules/vehicles/hardpoints/secondary/cupola.dm @@ -11,7 +11,7 @@ cooldown = 15 accuracy = 0.9 firing_arc = 120 - var/burst_amount = 3 + //var/burst_amount = 3 origins = list(0, -2) diff --git a/code/modules/vehicles/hardpoints/secondary/frontal_cannon.dm b/code/modules/vehicles/hardpoints/secondary/frontal_cannon.dm index 4d454bed12a4..0f28be062ba2 100644 --- a/code/modules/vehicles/hardpoints/secondary/frontal_cannon.dm +++ b/code/modules/vehicles/hardpoints/secondary/frontal_cannon.dm @@ -14,7 +14,7 @@ cooldown = 16 accuracy = 0.8 firing_arc = 120 - var/burst_amount = 4 + //var/burst_amount = 4 origins = list(0, -2) diff --git a/code/modules/vehicles/hardpoints/special/firing_port_weapon.dm b/code/modules/vehicles/hardpoints/special/firing_port_weapon.dm index 9310556ee94f..369513078387 100644 --- a/code/modules/vehicles/hardpoints/special/firing_port_weapon.dm +++ b/code/modules/vehicles/hardpoints/special/firing_port_weapon.dm @@ -13,7 +13,7 @@ cooldown = 10 accuracy = 0.9 firing_arc = 120 - var/burst_amount = 3 + //var/burst_amount = 3 //FPWs reload automatically var/reloading = FALSE var/reload_time = 10 SECONDS diff --git a/code/modules/vehicles/multitile/multitile.dm b/code/modules/vehicles/multitile/multitile.dm index c8138c5b8f86..6e238ae2ebe1 100644 --- a/code/modules/vehicles/multitile/multitile.dm +++ b/code/modules/vehicles/multitile/multitile.dm @@ -323,6 +323,7 @@ return /obj/vehicle/multitile/set_seated_mob(seat, mob/living/M) + to_chat(M, "multitile set_seated_mob") // Give/remove verbs if(QDELETED(M)) var/mob/living/L = seats[seat] diff --git a/code/modules/vehicles/multitile/multitile_interaction.dm b/code/modules/vehicles/multitile/multitile_interaction.dm index 42b141327bd8..d00a30a90ec5 100644 --- a/code/modules/vehicles/multitile/multitile_interaction.dm +++ b/code/modules/vehicles/multitile/multitile_interaction.dm @@ -330,6 +330,65 @@ healthcheck() +/obj/vehicle/multitile/on_set_interaction(mob/user) + to_chat(user, "multitile on_set_interaction") + RegisterSignal(user, COMSIG_MOB_MOUSEDOWN, PROC_REF(crew_mousedown)) + RegisterSignal(user, COMSIG_MOB_MOUSEDRAG, PROC_REF(crew_mousedrag)) + RegisterSignal(user, COMSIG_MOB_MOUSEUP, PROC_REF(crew_mouseup)) + +/obj/vehicle/multitile/on_unset_interaction(mob/user) + to_chat(user, "multitile on_unset_interaction") + UnregisterSignal(user, list(COMSIG_MOB_MOUSEUP, COMSIG_MOB_MOUSEDOWN, COMSIG_MOB_MOUSEDRAG)) + +/obj/vehicle/multitile/proc/crew_mouseup(datum/source, atom/object, turf/location, control, params) + SIGNAL_HANDLER + //to_chat(source, "multitile crew_mouseup [source] [object] [location] [control] [params]") + var/seat = get_mob_seat(source) + if(!seat) + return + + var/obj/item/hardpoint/HP = active_hp[seat] + if(!HP) + to_chat(source, SPAN_WARNING("Please select an active hardpoint first.")) + return + + HP.crew_mouseup(source, object, location, control, params) + +/obj/vehicle/multitile/proc/crew_mousedrag(datum/source, atom/src_object, atom/over_object, turf/src_location, turf/over_location, src_control, over_control, params) + SIGNAL_HANDLER + //to_chat(source, "multitile crew_mousedrag [source] [src_object] [over_object] [src_location] [over_location] [src_control] [over_control] [params]") + + var/seat = get_mob_seat(source) + if(!seat) + return + + var/obj/item/hardpoint/HP = active_hp[seat] + if(!HP) + to_chat(source, SPAN_WARNING("Please select an active hardpoint first.")) + return + + HP.crew_mousedrag(source, src_object, over_object, src_location, over_location, src_control, over_control, params) + +/obj/vehicle/multitile/proc/crew_mousedown(datum/source, atom/object, turf/location, control, params) + SIGNAL_HANDLER + //to_chat(source, "multitile crew_mousedown [source] [object] [location] [control] [params]") + + var/seat = get_mob_seat(source) + if(!seat) + return + + var/obj/item/hardpoint/HP = active_hp[seat] + if(!HP) + to_chat(source, SPAN_WARNING("Please select an active hardpoint first.")) + return + + if(!HP.can_activate(source, object)) + return + + //HP.activate(source, object) + HP.crew_mousedown(source, object, location, control, params) + +/* /obj/vehicle/multitile/handle_click(mob/living/user, atom/A, list/mods) var/seat @@ -404,6 +463,7 @@ return HP.activate(user, A) +*/ /obj/vehicle/multitile/proc/handle_player_entrance(mob/M) if(!M || M.client == null) return From cd0719cfc0e9a94c3d0be5149348a85b9f33612b Mon Sep 17 00:00:00 2001 From: Doubleumc Date: Sat, 28 Oct 2023 20:49:24 -0400 Subject: [PATCH 02/21] APC working --- code/modules/vehicles/hardpoints/hardpoint.dm | 374 ++++++------------ .../hardpoints/primary/dual_cannon.dm | 12 +- .../hardpoints/secondary/frontal_cannon.dm | 34 +- .../hardpoints/special/firing_port_weapon.dm | 36 +- .../vehicles/hardpoints/support/flare.dm | 12 +- .../vehicles/multitile/multitile_verbs.dm | 27 ++ 6 files changed, 201 insertions(+), 294 deletions(-) diff --git a/code/modules/vehicles/hardpoints/hardpoint.dm b/code/modules/vehicles/hardpoints/hardpoint.dm index 85b7984cb71a..a5e5671fe295 100644 --- a/code/modules/vehicles/hardpoints/hardpoint.dm +++ b/code/modules/vehicles/hardpoints/hardpoint.dm @@ -98,31 +98,23 @@ //maximum amount of spare mags var/max_clips = 0 + /** An assoc list in the format list(/datum/element/bullet_trait_to_give = list(...args)) + that will be given to a projectile with the current ammo datum**/ + var/list/list/traits_to_give - /**How the bullet will behave once it leaves the gun, also used for basic bullet damage and effects, etc. - Ammo will be replaced on New() for things that do not use mags.**/ - //var/datum/ammo/ammo = null - ///What is currently in the chamber. Most guns will want something in the chamber upon creation. - //var/obj/projectile/in_chamber = null - /*Ammo mags may or may not be internal, though the difference is a few additional variables. If they are not internal, don't call - on those unique vars. This is done for quicker pathing. Just keep in mind most mags aren't internal, though some are. - This is also the default magazine path loaded into a projectile weapon for reverse lookups on New(). Leave this null to do your own thing.*/ - //var/obj/item/ammo_magazine/internal/current_mag = null - - ///How much the bullet scatters when fired. - var/scatter = 0 - ///Multiplier. Increases or decreases how much bonus scatter is added with each bullet during burst fire (wielded only). - var/burst_scatter_mult = 4 - - ///What minimum range the weapon deals full damage, builds up the closer you get. 0 for no minimum. - var/effective_range_min = 0 - ///What maximum range the weapon deals full damage, tapers off using damage_falloff after hitting this value. 0 for no maximum. - var/effective_range_max = 0 + //Firemodes. + ///Current selected firemode of the gun. + var/gun_firemode = GUN_FIREMODE_SEMIAUTO + ///List of allowed firemodes. + var/list/gun_firemode_list = list() + //Semi-auto and full-auto. ///For regular shots, how long to wait before firing again. Use modify_fire_delay and set_fire_delay instead of modifying this on the fly VAR_PROTECTED/fire_delay = 0 - ///When it was last fired, related to world.time. - var/last_fired = 0 + /// The multiplier for how much slower this should fire in automatic mode. 1 is normal, 1.2 is 20% slower, 2 is 100% slower, etc. Protected due to it never needing to be edited. + VAR_PROTECTED/autofire_slow_mult = 1 + ///If the gun is currently auto firing. + VAR_PROTECTED/auto_firing = FALSE //Burst fire. ///How many shots can the weapon shoot in burst? Anything less than 2 and you cannot toggle burst. Use modify_burst_amount and set_burst_amount instead of modifying this @@ -131,44 +123,20 @@ VAR_PROTECTED/burst_delay = 1 ///When burst-firing, this number is extra time before the weapon can fire again. Depends on number of rounds fired. var/extra_delay = 0 + ///If the gun is currently burst firing. + VAR_PROTECTED/burst_firing = FALSE - // Full auto - ///Whether or not the gun is firing full-auto - var/fa_firing = FALSE - ///How many full-auto shots to get to max scatter? - var/fa_scatter_peak = 4 - ///How bad does the scatter get on full auto? - var/fa_max_scatter = 6.5 - - var/flags_gun_features = GUN_AMMO_COUNTER - - /** An assoc list in the format list(/datum/element/bullet_trait_to_give = list(...args)) - that will be given to a projectile with the current ammo datum**/ - var/list/list/traits_to_give + //Firing cooldown. + ///When it was last fired, related to world.time. + var/last_fired = 0 + ///Fire delay of last firemode used. + var/last_delay = 0 - ///Current selected firemode of the gun. - var/gun_firemode = GUN_FIREMODE_SEMIAUTO - ///List of allowed firemodes. - var/list/gun_firemode_list = list() - ///How many bullets the gun fired while bursting/auto firing - var/shots_fired = 0 /// Currently selected target to fire at. Set with set_target() VAR_PRIVATE/atom/target /// Current operator (crew) of the hardpoint. VAR_PRIVATE/mob/hp_operator - /// If this gun should spawn with semi-automatic fire. Protected due to it never needing to be edited. - VAR_PROTECTED/start_semiauto = TRUE - /// If this gun should spawn with automatic fire. Protected due to it never needing to be edited. - VAR_PROTECTED/start_automatic = FALSE - /// The type of projectile that this gun should shoot - var/projectile_type = /obj/projectile - /// The multiplier for how much slower this should fire in automatic mode. 1 is normal, 1.2 is 20% slower, 2 is 100% slower, etc. Protected due to it never needing to be edited. - VAR_PROTECTED/autofire_slow_mult = 1 - /// Semi auto cooldown - COOLDOWN_DECLARE(semiauto_fire_cooldown) - /// How long between semi-auto shots this should wait, to reduce possible spam - var/semiauto_cooldown_time = 0.2 SECONDS var/empty_alarm = 'sound/weapons/hmg_eject_mag.ogg' //----------------------------- @@ -177,12 +145,8 @@ /obj/item/hardpoint/Initialize() . = ..() - - //set_gun_config_values() set_bullet_traits() - //setup_firemodes() - //gun_firemode = gun_firemode_list[1] || GUN_FIREMODE_SEMIAUTO - AddComponent(/datum/component/automatedfire/autofire, fire_delay, burst_delay, burst_amount, gun_firemode, autofire_slow_mult, CALLBACK(src, PROC_REF(set_bursting)), CALLBACK(src, PROC_REF(reset_fire)), CALLBACK(src, PROC_REF(fire_wrapper)), CALLBACK(src, PROC_REF(display_ammo)), CALLBACK(src, PROC_REF(set_auto_firing))) //This should go after handle_starting_attachment() and setup_firemodes() to get the proper values set. + AddComponent(/datum/component/automatedfire/autofire, fire_delay, burst_delay, burst_amount, gun_firemode, autofire_slow_mult, CALLBACK(src, PROC_REF(set_burst_firing)), CALLBACK(src, PROC_REF(reset_fire)), CALLBACK(src, PROC_REF(continue_fire)), CALLBACK(src, PROC_REF(display_ammo)), CALLBACK(src, PROC_REF(set_auto_firing))) //This should go after handle_starting_attachment() and setup_firemodes() to get the proper values set. /obj/item/hardpoint/Destroy() if(owner) @@ -638,42 +602,14 @@ ammo.current_rounds-- -/* -/obj/item/hardpoint/proc/setup_firemodes() - var/old_firemode = gun_firemode - gun_firemode_list.len = 0 - - if(start_automatic) - gun_firemode_list |= GUN_FIREMODE_AUTOMATIC - - if(start_semiauto) - gun_firemode_list |= GUN_FIREMODE_SEMIAUTO - - if(burst_amount > BURST_AMOUNT_TIER_1) - gun_firemode_list |= GUN_FIREMODE_BURSTFIRE - - if(!length(gun_firemode_list)) - CRASH("[src] called setup_firemodes() with an empty gun_firemode_list") - - else if(old_firemode in gun_firemode_list) - gun_firemode = old_firemode - - else - gun_firemode = gun_firemode_list[1] -*/ - /// Setter proc to toggle burst firing -/obj/item/hardpoint/proc/set_bursting(bursting = FALSE) - if(bursting) - ENABLE_BITFIELD(flags_gun_features, GUN_BURST_FIRING) - else - DISABLE_BITFIELD(flags_gun_features, GUN_BURST_FIRING) +/obj/item/hardpoint/proc/set_burst_firing(burst = FALSE) + burst_firing = burst ///Clean all references /obj/item/hardpoint/proc/reset_fire() - shots_fired = 0//Let's clean everything - set_target(null) set_auto_firing(FALSE) + set_target(null) ///Set the target and take care of hard delete /obj/item/hardpoint/proc/set_target(atom/object) @@ -690,79 +626,53 @@ SIGNAL_HANDLER target = get_turf(target) -/// Setter proc for fa_firing +/// Setter proc for auto_firing /obj/item/hardpoint/proc/set_auto_firing(auto = FALSE) - fa_firing = auto + auto_firing = auto /obj/item/hardpoint/proc/display_ammo(mob/user) if(!user) user = hp_operator - if(CHECK_BITFIELD(flags_gun_features, GUN_AMMO_COUNTER) && ammo) - //var/chambered = in_chamber ? TRUE : FALSE - to_chat(user, SPAN_DANGER("[ammo.current_rounds] / [ammo.max_rounds] ROUNDS REMAINING")) - -/* -/obj/item/hardpoint/proc/try_fire() - if(!ammo?.current_rounds) - to_chat(hp_operator, SPAN_WARNING("*click*")) - playsound(src, 'sound/weapons/gun_empty.ogg', 25, 1, 5) - return - - return fire_shot() - -/obj/item/hardpoint/proc/fire_shot() //Bang Bang - var/atom/T = target - - var/turf/origin_turf = get_turf(src) - origin_turf = locate(origin_turf.x + origins[1], origin_turf.y + origins[2], origin_turf.z) - - var/obj/projectile/P = generate_bullet(hp_operator, origin_turf) - SEND_SIGNAL(P, COMSIG_BULLET_USER_EFFECTS, hp_operator) - P.fire_at(T, hp_operator, src, P.ammo.max_range, P.ammo.shell_speed) - - if(LAZYLEN(activation_sounds)) - playsound(get_turf(src), pick(activation_sounds), 60, 1) - - if(use_muzzle_flash) - muzzle_flash(Get_Angle(origin_turf, T)) - - ammo.current_rounds-- - if(!ammo.current_rounds) - handle_ammo_out() - - return AUTOFIRE_CONTINUE -*/ + if( ammo) + //to_chat(user, SPAN_DANGER("[ammo.current_rounds] / [ammo.max_rounds] ROUNDS REMAINING")) + to_chat(user, SPAN_WARNING("[name] Ammo: [SPAN_HELPFUL(ammo ? ammo.current_rounds : 0)]/[SPAN_HELPFUL(ammo ? ammo.max_rounds : 0)] | Mags: [SPAN_HELPFUL(LAZYLEN(backup_clips))]/[SPAN_HELPFUL(max_clips)]")) /obj/item/hardpoint/proc/handle_ammo_out(mob/user) visible_message(SPAN_NOTICE("[icon2html(src, viewers(src))] [src] beeps steadily and its ammo light blinks red.")) playsound(loc, empty_alarm, 25, 1) /obj/item/hardpoint/proc/crew_mouseup(datum/source, atom/object, turf/location, control, params) - if(!target) - return - - if(gun_firemode == GUN_FIREMODE_AUTOMATIC) - reset_fire() - display_ammo() - SEND_SIGNAL(src, COMSIG_GUN_STOP_FIRE) + if(auto_firing || burst_firing) + SEND_SIGNAL(src, COMSIG_GUN_STOP_FIRE) + //autofire component resets on burst completion, have to do it ourselves for automatic + if(auto_firing) + reset_fire() + display_ammo() ///Update the target if you draged your mouse -/obj/item/hardpoint/proc/crew_mousedrag(datum/source, atom/src_object, atom/over_object, turf/src_location, turf/over_location, src_control, over_control, params) - set_target(get_turf_on_clickcatcher(over_object, hp_operator, params)) +/obj/item/hardpoint/proc/crew_mousedrag(mob/source, atom/src_object, atom/over_object, turf/src_location, turf/over_location, src_control, over_control, params) + set_target(get_turf_on_clickcatcher(over_object, hp_operator, params)) //stops when dragging over UI + /* + if(istype(over_object, /atom/movable/screen)) //doesn't stop when dragging over UI, no side effects? + var/list/modifiers = params2list(params) + var/turf/turf = params2turf(modifiers["screen-loc"], get_turf(source.client.eye), source.client) + if (turf) + set_target(turf) + else + set_target(over_object) + */ + ///Check if the gun can fire and add it to bucket auto_fire system if needed, or just fire the gun if not /obj/item/hardpoint/proc/crew_mousedown(datum/source, atom/object, turf/location, control, params) - //hp_operator = owner.get_seat_mob(allowed_seat) hp_operator = source - if (CHECK_BITFIELD(flags_gun_features, GUN_BURST_FIRING)) - return - var/list/modifiers = params2list(params) if(modifiers["shift"] || modifiers["middle"] || modifiers["right"]) return + //don't click on UI if(istype(object, /atom/movable/screen)) return @@ -770,18 +680,24 @@ return set_target(get_turf_on_clickcatcher(object, hp_operator, params)) - if(gun_firemode == GUN_FIREMODE_SEMIAUTO && COOLDOWN_FINISHED(src, semiauto_fire_cooldown)) - COOLDOWN_START(src, semiauto_fire_cooldown, semiauto_cooldown_time) - //try_fire(object, hp_operator, modifiers) - fire_wrapper(object, hp_operator, modifiers) - reset_fire() - display_ammo() - return - else - SEND_SIGNAL(src, COMSIG_GUN_FIRE) + + initiate_fire(object, hp_operator, modifiers) + +/obj/item/hardpoint/proc/initiate_fire(atom/target, mob/living/user, params) + //still actively firing + if(auto_firing || burst_firing || world.time < last_fired + last_delay) + return NONE + + switch(gun_firemode) + if(GUN_FIREMODE_SEMIAUTO) + try_fire(target, user, params) + if(GUN_FIREMODE_BURSTFIRE) + SEND_SIGNAL(src, COMSIG_GUN_FIRE) + if(GUN_FIREMODE_AUTOMATIC) + SEND_SIGNAL(src, COMSIG_GUN_FIRE) /// Wrapper proc for the autofire subsystem to ensure the important args aren't null -/obj/item/hardpoint/proc/fire_wrapper(atom/target, mob/living/user, params) +/obj/item/hardpoint/proc/continue_fire(atom/target, mob/living/user, params) SHOULD_NOT_OVERRIDE(TRUE) if(!target) target = src.target @@ -789,129 +705,88 @@ user = hp_operator if(!target || !user) return NONE - return Fire(target, user, params) -/obj/item/hardpoint/proc/Fire(atom/target, mob/living/user, params) - set waitfor = FALSE + return try_fire(target, user, params) - if(!able_to_fire(user) || !target || !get_turf(user) || !get_turf(target)) +/obj/item/hardpoint/proc/try_fire(atom/target, mob/living/user, params) + if(health <= 0) + to_chat(user, SPAN_WARNING("\The [name] is broken!")) return NONE - /* - This is where burst is established for the proceeding section. Which just means the proc loops around that many times. - If burst = 1, you must null it if you ever RETURN during the for() cycle. If for whatever reason burst is left on while - the gun is not firing, it will break a lot of stuff. BREAK is fine, as it will null it. - */ - if((gun_firemode == GUN_FIREMODE_BURSTFIRE) && burst_amount > BURST_AMOUNT_TIER_1) - ENABLE_BITFIELD(flags_gun_features, GUN_BURST_FIRING) - - var/fire_return = handle_fire(target, user, params) - if(!fire_return) - return fire_return - - DISABLE_BITFIELD(flags_gun_features, GUN_BURST_FIRING) // We always want to turn off bursting when we're done, mainly for when we break early mid-burstfire. - return AUTOFIRE_CONTINUE - -/obj/item/hardpoint/proc/able_to_fire(mob/user) - if(CHECK_BITFIELD(flags_gun_features, GUN_BURST_FIRING)) - return TRUE - - // The rest is delay-related. If we're firing full-auto it doesn't matter - if(fa_firing) - return TRUE - - var/next_shot = last_fired + fire_delay - - if(world.time >= next_shot + extra_delay) //check the last time it was fired. - extra_delay = 0 - - return TRUE + if(!ammo || ammo.current_rounds <= 0) + click_empty(user) + return NONE -/obj/item/hardpoint/proc/handle_fire(atom/target, mob/living/user, params) - var/turf/curloc = get_turf(src) //In case the target or we are expired. - var/turf/targloc = get_turf(target) + if(!in_firing_arc(target)) + to_chat(user, SPAN_WARNING("The target is not within your firing arc!")) + return NONE - var/atom/original_target = target //This is for burst mode, in case the target changes per scatter chance in between fired bullets. + return fire_shot(target, user, params) - //The gun should return the bullet that it already loaded from the end cycle of the last Fire(). - //var/obj/projectile/projectile_to_fire = load_into_chamber(user) //Load a bullet in or check for existing one. - var/obj/projectile/projectile_to_fire = generate_bullet(user, curloc) - if(!projectile_to_fire) //If there is nothing to fire, click. - click_empty(user) - DISABLE_BITFIELD(flags_gun_features, GUN_BURST_FIRING) - return NONE +/obj/item/hardpoint/proc/fire_shot(atom/target, mob/living/user, params) + //offset fire origin from lower-left corner + var/turf/origin_turf = get_turf(src) + origin_turf = locate(origin_turf.x + origins[1], origin_turf.y + origins[2], origin_turf.z) - /* - apply_bullet_effects(projectile_to_fire, user) //User can be passed as null. + var/obj/projectile/projectile_to_fire = generate_bullet(user, origin_turf) SEND_SIGNAL(projectile_to_fire, COMSIG_BULLET_USER_EFFECTS, user) - */ - if(QDELETED(original_target)) //If the target's destroyed, shoot at where it was last. - target = targloc - else - target = original_target - targloc = get_turf(target) + play_firing_sounds(projectile_to_fire, user) - projectile_to_fire.original = target + INVOKE_ASYNC(projectile_to_fire, TYPE_PROC_REF(/obj/projectile, fire_at), target, user, src, projectile_to_fire.ammo.max_range, projectile_to_fire.ammo.shell_speed) + projectile_to_fire = null - /* - // turf-targeted projectiles are fired without scatter, because proc would raytrace them further away - var/ammo_flags = projectile_to_fire.ammo.flags_ammo_behavior | projectile_to_fire.projectile_override_flags - if(!CHECK_BITFIELD(ammo_flags, AMMO_HITS_TARGET_TURF)) - target = simulate_scatter(projectile_to_fire, target, curloc, targloc, user) + if(use_muzzle_flash) + muzzle_flash(Get_Angle(origin_turf, target)) - var/bullet_velocity = projectile_to_fire?.ammo?.shell_speed + velocity_add - */ + ammo.current_rounds-- + //just ran out + if(ammo.current_rounds <= 0) + playsound(get_turf(src), empty_alarm, 70, 1) + + //cooldown to respect intended ROF + last_fired = world.time + switch(gun_firemode) + if(GUN_FIREMODE_SEMIAUTO) + last_delay = fire_delay + reset_fire() + display_ammo() + if(GUN_FIREMODE_BURSTFIRE) + last_delay = burst_delay + extra_delay + if(GUN_FIREMODE_AUTOMATIC) + last_delay = fire_delay + + return AUTOFIRE_CONTINUE +/// Toggles the gun's firemode one down the list +/obj/item/hardpoint/proc/do_toggle_firemode(mob/user, new_firemode) /* - if(params) // Apply relative clicked position from the mouse info to offset projectile - if(!params["click_catcher"]) - if(params["vis-x"]) - projectile_to_fire.p_x = text2num(params["vis-x"]) - else if(params["icon-x"]) - projectile_to_fire.p_x = text2num(params["icon-x"]) - if(params["vis-y"]) - projectile_to_fire.p_y = text2num(params["vis-y"]) - else if(params["icon-y"]) - projectile_to_fire.p_y = text2num(params["icon-y"]) - var/atom/movable/clicked_target = original_target - if(istype(clicked_target)) - projectile_to_fire.p_x -= clicked_target.bound_width / 2 - projectile_to_fire.p_y -= clicked_target.bound_height / 2 - else - projectile_to_fire.p_x -= world.icon_size / 2 - projectile_to_fire.p_y -= world.icon_size / 2 - else - projectile_to_fire.p_x -= world.icon_size / 2 - projectile_to_fire.p_y -= world.icon_size / 2 + if(get_burst_firing())//can't toggle mid burst + return */ - play_firing_sounds(projectile_to_fire, user) - - if(targloc != curloc) - //This is where the projectile leaves the barrel and deals with projectile code only. - //vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv - //in_chamber = null // It's not in the gun anymore - INVOKE_ASYNC(projectile_to_fire, TYPE_PROC_REF(/obj/projectile, fire_at), target, user, src, projectile_to_fire?.ammo?.max_range, projectile_to_fire?.ammo?.shell_speed, original_target) - projectile_to_fire = null // Important: firing might have made projectile collide early and ALREADY have deleted it. We clear it too. - //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + if(!length(gun_firemode_list)) + CRASH("[src] called do_toggle_firemode() with an empty gun_firemodes") - . = TRUE + if(length(gun_firemode_list) == 1) + to_chat(user, SPAN_NOTICE("[icon2html(src, user)] This gun only has one firemode.")) + return - shots_fired++ + if(new_firemode) + if(!(new_firemode in gun_firemode_list)) + CRASH("[src] called do_toggle_firemode() with [new_firemode] new_firemode, not on gun_firemodes") + gun_firemode = new_firemode else - return TRUE + var/mode_index = gun_firemode_list.Find(gun_firemode) + if(++mode_index <= length(gun_firemode_list)) + gun_firemode = gun_firemode_list[mode_index] + else + gun_firemode = gun_firemode_list[1] - //>>POST PROCESSING AND CLEANUP BEGIN HERE.<< - var/angle = round(Get_Angle(user, target)) //Let's do a muzzle flash. - muzzle_flash(angle,user) + playsound(user, 'sound/weapons/handling/gun_burst_toggle.ogg', 15, 1) - //This is where we load the next bullet in the chamber. - //if(!reload_into_chamber(user)) // It has to return a bullet, otherwise it's empty. - if(!ammo.current_rounds) - click_empty(user) - return TRUE //Nothing else to do here, time to cancel out. - return TRUE + to_chat(user, SPAN_NOTICE("[icon2html(src, user)] You switch to [gun_firemode].")) + SEND_SIGNAL(src, COMSIG_GUN_FIRE_MODE_TOGGLE, gun_firemode) /obj/item/hardpoint/proc/click_empty(mob/user) if(user) @@ -924,7 +799,6 @@ if(LAZYLEN(activation_sounds)) playsound(get_turf(src), pick(activation_sounds), 60, 1) - //----------------------------- //------ICON PROCS---------- //----------------------------- diff --git a/code/modules/vehicles/hardpoints/primary/dual_cannon.dm b/code/modules/vehicles/hardpoints/primary/dual_cannon.dm index 78e19d8b1329..6b76312bc5a5 100644 --- a/code/modules/vehicles/hardpoints/primary/dual_cannon.dm +++ b/code/modules/vehicles/hardpoints/primary/dual_cannon.dm @@ -12,8 +12,8 @@ damage_multiplier = 0.2 health = 500 - cooldown = 7 - accuracy = 0.98 + //cooldown = 7 + //accuracy = 0.98 firing_arc = 60 //var/burst_amount = 2 @@ -33,16 +33,16 @@ "8" = list(14, 9) ) - //fire_delay = 0.6 SECONDS + fire_delay = 0.5 SECONDS burst_amount = 2 burst_delay = 0.3 SECONDS - //extra_delay = 0.7 SECONDS + extra_delay = 0.4 SECONDS gun_firemode = GUN_FIREMODE_BURSTFIRE gun_firemode_list = list( + GUN_FIREMODE_SEMIAUTO, GUN_FIREMODE_BURSTFIRE, - //GUN_FIREMODE_AUTOMATIC, + GUN_FIREMODE_AUTOMATIC, ) - start_semiauto = FALSE /obj/item/hardpoint/primary/dualcannon/set_bullet_traits() ..() diff --git a/code/modules/vehicles/hardpoints/secondary/frontal_cannon.dm b/code/modules/vehicles/hardpoints/secondary/frontal_cannon.dm index 0f28be062ba2..597d3a174042 100644 --- a/code/modules/vehicles/hardpoints/secondary/frontal_cannon.dm +++ b/code/modules/vehicles/hardpoints/secondary/frontal_cannon.dm @@ -11,8 +11,8 @@ damage_multiplier = 0.11 health = 350 - cooldown = 16 - accuracy = 0.8 + //cooldown = 16 + //accuracy = 0.8 firing_arc = 120 //var/burst_amount = 4 @@ -32,27 +32,19 @@ "8" = list(-62, -26) ) + fire_delay = 0.5 SECONDS + burst_amount = 4 + burst_delay = 0.3 SECONDS + extra_delay = 0.4 SECONDS + gun_firemode = GUN_FIREMODE_BURSTFIRE + gun_firemode_list = list( + GUN_FIREMODE_SEMIAUTO, + GUN_FIREMODE_BURSTFIRE, + GUN_FIREMODE_AUTOMATIC, + ) + /obj/item/hardpoint/secondary/frontalcannon/set_bullet_traits() ..() LAZYADD(traits_to_give, list( BULLET_TRAIT_ENTRY(/datum/element/bullet_trait_iff) )) - -/obj/item/hardpoint/secondary/frontalcannon/fire(mob/user, atom/A) - if(ammo.current_rounds <= 0) - return - - next_use = world.time + cooldown * owner.misc_multipliers["cooldown"] - - for(var/bullets_fired = 1, bullets_fired <= burst_amount, bullets_fired++) - var/atom/T = A - if(!prob((accuracy * 100) / owner.misc_multipliers["accuracy"])) - T = get_step(get_turf(A), pick(cardinal)) - if(LAZYLEN(activation_sounds)) - playsound(get_turf(src), pick(activation_sounds), 60, 1) - fire_projectile(user, T) - if(ammo.current_rounds <= 0) - break - if(bullets_fired < burst_amount) //we need to sleep only if there are more bullets to shoot in the burst - sleep(3) - to_chat(user, SPAN_WARNING("[src] Ammo: [SPAN_HELPFUL(ammo ? ammo.current_rounds : 0)]/[SPAN_HELPFUL(ammo ? ammo.max_rounds : 0)] | Mags: [SPAN_HELPFUL(LAZYLEN(backup_clips))]/[SPAN_HELPFUL(max_clips)]")) diff --git a/code/modules/vehicles/hardpoints/special/firing_port_weapon.dm b/code/modules/vehicles/hardpoints/special/firing_port_weapon.dm index 369513078387..f6ae86f7267c 100644 --- a/code/modules/vehicles/hardpoints/special/firing_port_weapon.dm +++ b/code/modules/vehicles/hardpoints/special/firing_port_weapon.dm @@ -30,6 +30,17 @@ underlayer_north_muzzleflash = TRUE + fire_delay = 0.4 SECONDS + burst_amount = 3 + burst_delay = 0.3 SECONDS + extra_delay = -0.2 SECONDS + gun_firemode = GUN_FIREMODE_BURSTFIRE + gun_firemode_list = list( + GUN_FIREMODE_SEMIAUTO, + GUN_FIREMODE_BURSTFIRE, + GUN_FIREMODE_AUTOMATIC, + ) + /obj/item/hardpoint/special/firing_port_weapon/set_bullet_traits() ..() LAZYADD(traits_to_give, list( @@ -116,8 +127,12 @@ to_chat(user, SPAN_NOTICE("\The [name] reloads automatically.")) return FALSE +/obj/item/hardpoint/special/firing_port_weapon/try_fire(atom/target, mob/living/user, params) + //FPW stop working at 50% hull + if(owner.health < initial(owner.health) * 0.5) + to_chat(user, SPAN_WARNING("\The [owner]'s hull is too damaged!")) + return FALSE -/obj/item/hardpoint/special/firing_port_weapon/fire(mob/user, atom/A) if(user.get_active_hand()) to_chat(user, SPAN_WARNING("You need a free hand to use \the [name].")) return @@ -126,17 +141,8 @@ start_auto_reload(user) return - next_use = world.time + cooldown * owner.misc_multipliers["cooldown"] - - for(var/bullets_fired = 1, bullets_fired <= burst_amount, bullets_fired++) - var/atom/T = A - if(!prob((accuracy * 100) / owner.misc_multipliers["accuracy"])) - T = get_step(get_turf(A), pick(cardinal)) - if(LAZYLEN(activation_sounds)) - playsound(get_turf(src), pick(activation_sounds), 60, 1) - fire_projectile(user, T) - if(ammo.current_rounds <= 0) - break - if(bullets_fired < burst_amount) //we need to sleep only if there are more bullets to shoot in the burst - sleep(3) - to_chat(user, SPAN_WARNING("[src] Ammo: [SPAN_HELPFUL(ammo ? ammo.current_rounds : 0)]/[SPAN_HELPFUL(ammo ? ammo.max_rounds : 0)]")) + if(reloading) + to_chat(user, SPAN_NOTICE("\The [name] is reloading. Wait [SPAN_HELPFUL("[((reload_time_started + reload_time - world.time) / 10)]")] seconds.")) + return FALSE + + return ..() diff --git a/code/modules/vehicles/hardpoints/support/flare.dm b/code/modules/vehicles/hardpoints/support/flare.dm index 00dcd3ac1886..d9aa720a7e86 100644 --- a/code/modules/vehicles/hardpoints/support/flare.dm +++ b/code/modules/vehicles/hardpoints/support/flare.dm @@ -13,8 +13,8 @@ activatable = TRUE health = 500 - cooldown = 30 - accuracy = 0.7 + //cooldown = 30 + //accuracy = 0.7 firing_arc = 120 origins = list(0, -2) @@ -33,6 +33,14 @@ "8" = list(14, -6) ) + fire_delay = 3.0 SECONDS + gun_firemode = GUN_FIREMODE_BURSTFIRE + gun_firemode_list = list( + GUN_FIREMODE_SEMIAUTO, + GUN_FIREMODE_BURSTFIRE, + GUN_FIREMODE_AUTOMATIC, + ) + /obj/item/hardpoint/support/flare_launcher/set_bullet_traits() ..() LAZYADD(traits_to_give, list( diff --git a/code/modules/vehicles/multitile/multitile_verbs.dm b/code/modules/vehicles/multitile/multitile_verbs.dm index c7dd29bbf0a9..fc79a6a3b717 100644 --- a/code/modules/vehicles/multitile/multitile_verbs.dm +++ b/code/modules/vehicles/multitile/multitile_verbs.dm @@ -376,3 +376,30 @@ return to_chat(user, SPAN_WARNING("Warning. No FPW for [seat] found, tell a dev!")) + +/obj/vehicle/multitile/proc/cycle_firemode() + set name = "Cycle Firemode" + set desc = "Cycles through your gun's firemodes." + set category = "Vehicle" + + var/mob/user = usr + if(!user || !istype(user)) + return + + var/obj/vehicle/multitile/vehicle = user.interactee + if(!istype(vehicle)) + return + + var/seat + for(var/vehicle_seat in vehicle.seats) + if(vehicle.seats[vehicle_seat] == user) + seat = vehicle_seat + break + if(!seat) + return + + var/obj/item/hardpoint/hardpoint = vehicle.active_hp[seat] + if(!hardpoint) + return + + hardpoint.do_toggle_firemode(usr) From c4cfe8e6debc2b17a844f901170c27e43b386315 Mon Sep 17 00:00:00 2001 From: Doubleumc Date: Sat, 28 Oct 2023 21:04:57 -0400 Subject: [PATCH 03/21] minor cleanup --- code/modules/vehicles/hardpoints/hardpoint.dm | 14 +++++++------- .../vehicles/hardpoints/primary/dual_cannon.dm | 5 ++--- .../hardpoints/secondary/frontal_cannon.dm | 6 ++---- .../hardpoints/special/firing_port_weapon.dm | 2 -- code/modules/vehicles/hardpoints/support/flare.dm | 8 +++----- code/modules/vehicles/multitile/multitile.dm | 1 - .../vehicles/multitile/multitile_interaction.dm | 5 ----- 7 files changed, 14 insertions(+), 27 deletions(-) diff --git a/code/modules/vehicles/hardpoints/hardpoint.dm b/code/modules/vehicles/hardpoints/hardpoint.dm index a5e5671fe295..66a4b6d79a9c 100644 --- a/code/modules/vehicles/hardpoints/hardpoint.dm +++ b/code/modules/vehicles/hardpoints/hardpoint.dm @@ -98,8 +98,8 @@ //maximum amount of spare mags var/max_clips = 0 - /** An assoc list in the format list(/datum/element/bullet_trait_to_give = list(...args)) - that will be given to a projectile with the current ammo datum**/ + /// An assoc list in the format list(/datum/element/bullet_trait_to_give = list(...args)) + /// that will be given to a projectile fired from the hardpoint var/list/list/traits_to_give //Firemodes. @@ -146,7 +146,7 @@ /obj/item/hardpoint/Initialize() . = ..() set_bullet_traits() - AddComponent(/datum/component/automatedfire/autofire, fire_delay, burst_delay, burst_amount, gun_firemode, autofire_slow_mult, CALLBACK(src, PROC_REF(set_burst_firing)), CALLBACK(src, PROC_REF(reset_fire)), CALLBACK(src, PROC_REF(continue_fire)), CALLBACK(src, PROC_REF(display_ammo)), CALLBACK(src, PROC_REF(set_auto_firing))) //This should go after handle_starting_attachment() and setup_firemodes() to get the proper values set. + AddComponent(/datum/component/automatedfire/autofire, fire_delay, burst_delay, burst_amount, gun_firemode, autofire_slow_mult, CALLBACK(src, PROC_REF(set_burst_firing)), CALLBACK(src, PROC_REF(reset_fire)), CALLBACK(src, PROC_REF(continue_fire)), CALLBACK(src, PROC_REF(display_ammo)), CALLBACK(src, PROC_REF(set_auto_firing))) /obj/item/hardpoint/Destroy() if(owner) @@ -319,14 +319,14 @@ continue // Make sure we can pass object from all directions - if(!CHECK_BITFIELD(O.pass_flags.flags_can_pass_all, PASS_OVER_THROW_ITEM)) - if(!CHECK_BITFIELD(O.flags_atom, ON_BORDER)) + if(!(O.pass_flags.flags_can_pass_all & PASS_OVER_THROW_ITEM)) + if(!(O.flags_atom & ON_BORDER)) return FALSE //If we're behind the object, check the behind pass flags - else if(dir == O.dir && !CHECK_BITFIELD(O.pass_flags.flags_can_pass_behind, PASS_OVER_THROW_ITEM)) + else if(dir == O.dir && !(O.pass_flags.flags_can_pass_behind & PASS_OVER_THROW_ITEM)) return FALSE //If we're in front, check front pass flags - else if(dir == turn(O.dir, 180) && !CHECK_BITFIELD(O.pass_flags.flags_can_pass_front, PASS_OVER_THROW_ITEM)) + else if(dir == turn(O.dir, 180) && !(O.pass_flags.flags_can_pass_front & PASS_OVER_THROW_ITEM)) return FALSE // Trace back towards the vehicle diff --git a/code/modules/vehicles/hardpoints/primary/dual_cannon.dm b/code/modules/vehicles/hardpoints/primary/dual_cannon.dm index 6b76312bc5a5..d128860f4874 100644 --- a/code/modules/vehicles/hardpoints/primary/dual_cannon.dm +++ b/code/modules/vehicles/hardpoints/primary/dual_cannon.dm @@ -12,10 +12,9 @@ damage_multiplier = 0.2 health = 500 - //cooldown = 7 - //accuracy = 0.98 + cooldown = 7 + accuracy = 0.98 firing_arc = 60 - //var/burst_amount = 2 origins = list(0, -2) diff --git a/code/modules/vehicles/hardpoints/secondary/frontal_cannon.dm b/code/modules/vehicles/hardpoints/secondary/frontal_cannon.dm index 597d3a174042..31260bff4601 100644 --- a/code/modules/vehicles/hardpoints/secondary/frontal_cannon.dm +++ b/code/modules/vehicles/hardpoints/secondary/frontal_cannon.dm @@ -11,10 +11,9 @@ damage_multiplier = 0.11 health = 350 - //cooldown = 16 - //accuracy = 0.8 + cooldown = 16 + accuracy = 0.8 firing_arc = 120 - //var/burst_amount = 4 origins = list(0, -2) @@ -38,7 +37,6 @@ extra_delay = 0.4 SECONDS gun_firemode = GUN_FIREMODE_BURSTFIRE gun_firemode_list = list( - GUN_FIREMODE_SEMIAUTO, GUN_FIREMODE_BURSTFIRE, GUN_FIREMODE_AUTOMATIC, ) diff --git a/code/modules/vehicles/hardpoints/special/firing_port_weapon.dm b/code/modules/vehicles/hardpoints/special/firing_port_weapon.dm index f6ae86f7267c..015b0b215164 100644 --- a/code/modules/vehicles/hardpoints/special/firing_port_weapon.dm +++ b/code/modules/vehicles/hardpoints/special/firing_port_weapon.dm @@ -13,7 +13,6 @@ cooldown = 10 accuracy = 0.9 firing_arc = 120 - //var/burst_amount = 3 //FPWs reload automatically var/reloading = FALSE var/reload_time = 10 SECONDS @@ -36,7 +35,6 @@ extra_delay = -0.2 SECONDS gun_firemode = GUN_FIREMODE_BURSTFIRE gun_firemode_list = list( - GUN_FIREMODE_SEMIAUTO, GUN_FIREMODE_BURSTFIRE, GUN_FIREMODE_AUTOMATIC, ) diff --git a/code/modules/vehicles/hardpoints/support/flare.dm b/code/modules/vehicles/hardpoints/support/flare.dm index d9aa720a7e86..184c148197b1 100644 --- a/code/modules/vehicles/hardpoints/support/flare.dm +++ b/code/modules/vehicles/hardpoints/support/flare.dm @@ -13,8 +13,8 @@ activatable = TRUE health = 500 - //cooldown = 30 - //accuracy = 0.7 + cooldown = 30 + accuracy = 0.7 firing_arc = 120 origins = list(0, -2) @@ -34,11 +34,9 @@ ) fire_delay = 3.0 SECONDS - gun_firemode = GUN_FIREMODE_BURSTFIRE + gun_firemode = GUN_FIREMODE_SEMIAUTO gun_firemode_list = list( GUN_FIREMODE_SEMIAUTO, - GUN_FIREMODE_BURSTFIRE, - GUN_FIREMODE_AUTOMATIC, ) /obj/item/hardpoint/support/flare_launcher/set_bullet_traits() diff --git a/code/modules/vehicles/multitile/multitile.dm b/code/modules/vehicles/multitile/multitile.dm index 6e238ae2ebe1..c8138c5b8f86 100644 --- a/code/modules/vehicles/multitile/multitile.dm +++ b/code/modules/vehicles/multitile/multitile.dm @@ -323,7 +323,6 @@ return /obj/vehicle/multitile/set_seated_mob(seat, mob/living/M) - to_chat(M, "multitile set_seated_mob") // Give/remove verbs if(QDELETED(M)) var/mob/living/L = seats[seat] diff --git a/code/modules/vehicles/multitile/multitile_interaction.dm b/code/modules/vehicles/multitile/multitile_interaction.dm index d00a30a90ec5..909b396d4c0f 100644 --- a/code/modules/vehicles/multitile/multitile_interaction.dm +++ b/code/modules/vehicles/multitile/multitile_interaction.dm @@ -342,7 +342,6 @@ /obj/vehicle/multitile/proc/crew_mouseup(datum/source, atom/object, turf/location, control, params) SIGNAL_HANDLER - //to_chat(source, "multitile crew_mouseup [source] [object] [location] [control] [params]") var/seat = get_mob_seat(source) if(!seat) return @@ -356,8 +355,6 @@ /obj/vehicle/multitile/proc/crew_mousedrag(datum/source, atom/src_object, atom/over_object, turf/src_location, turf/over_location, src_control, over_control, params) SIGNAL_HANDLER - //to_chat(source, "multitile crew_mousedrag [source] [src_object] [over_object] [src_location] [over_location] [src_control] [over_control] [params]") - var/seat = get_mob_seat(source) if(!seat) return @@ -371,8 +368,6 @@ /obj/vehicle/multitile/proc/crew_mousedown(datum/source, atom/object, turf/location, control, params) SIGNAL_HANDLER - //to_chat(source, "multitile crew_mousedown [source] [object] [location] [control] [params]") - var/seat = get_mob_seat(source) if(!seat) return From bd7a829a1d18071af657982c3a77de9c31db1032 Mon Sep 17 00:00:00 2001 From: Doubleumc Date: Fri, 3 Nov 2023 16:27:30 -0400 Subject: [PATCH 04/21] remove some debug messages --- code/modules/vehicles/multitile/multitile_interaction.dm | 2 -- 1 file changed, 2 deletions(-) diff --git a/code/modules/vehicles/multitile/multitile_interaction.dm b/code/modules/vehicles/multitile/multitile_interaction.dm index 909b396d4c0f..0bd9f3c130d0 100644 --- a/code/modules/vehicles/multitile/multitile_interaction.dm +++ b/code/modules/vehicles/multitile/multitile_interaction.dm @@ -331,13 +331,11 @@ healthcheck() /obj/vehicle/multitile/on_set_interaction(mob/user) - to_chat(user, "multitile on_set_interaction") RegisterSignal(user, COMSIG_MOB_MOUSEDOWN, PROC_REF(crew_mousedown)) RegisterSignal(user, COMSIG_MOB_MOUSEDRAG, PROC_REF(crew_mousedrag)) RegisterSignal(user, COMSIG_MOB_MOUSEUP, PROC_REF(crew_mouseup)) /obj/vehicle/multitile/on_unset_interaction(mob/user) - to_chat(user, "multitile on_unset_interaction") UnregisterSignal(user, list(COMSIG_MOB_MOUSEUP, COMSIG_MOB_MOUSEDOWN, COMSIG_MOB_MOUSEDRAG)) /obj/vehicle/multitile/proc/crew_mouseup(datum/source, atom/object, turf/location, control, params) From 9599633d7f4948d294789db396cd7e230bbac737 Mon Sep 17 00:00:00 2001 From: Doubleumc Date: Sat, 4 Nov 2023 04:22:17 -0400 Subject: [PATCH 05/21] tank mostly functional --- code/modules/vehicles/hardpoints/hardpoint.dm | 83 ++++++++++++++----- .../vehicles/hardpoints/holder/tank_turret.dm | 39 +++++++++ .../vehicles/hardpoints/primary/autocannon.dm | 6 ++ .../hardpoints/primary/dual_cannon.dm | 2 +- .../vehicles/hardpoints/primary/flamer.dm | 23 +---- .../vehicles/hardpoints/primary/ltb.dm | 6 ++ .../vehicles/hardpoints/primary/minigun.dm | 12 +++ .../vehicles/hardpoints/secondary/cupola.dm | 27 ++---- .../vehicles/hardpoints/secondary/flamer.dm | 41 ++++----- .../hardpoints/secondary/grenade_launcher.dm | 29 ++----- .../vehicles/hardpoints/secondary/tow.dm | 7 ++ .../vehicles/hardpoints/support/artillery.dm | 3 +- .../multitile/multitile_hardpoints.dm | 4 + 13 files changed, 169 insertions(+), 113 deletions(-) diff --git a/code/modules/vehicles/hardpoints/hardpoint.dm b/code/modules/vehicles/hardpoints/hardpoint.dm index 66a4b6d79a9c..ed124ed438c0 100644 --- a/code/modules/vehicles/hardpoints/hardpoint.dm +++ b/code/modules/vehicles/hardpoints/hardpoint.dm @@ -106,7 +106,9 @@ ///Current selected firemode of the gun. var/gun_firemode = GUN_FIREMODE_SEMIAUTO ///List of allowed firemodes. - var/list/gun_firemode_list = list() + var/list/gun_firemode_list = list( + GUN_FIREMODE_SEMIAUTO, + ) //Semi-auto and full-auto. ///For regular shots, how long to wait before firing again. Use modify_fire_delay and set_fire_delay instead of modifying this on the fly @@ -128,9 +130,10 @@ //Firing cooldown. ///When it was last fired, related to world.time. - var/last_fired = 0 + //var/last_fired = 0 ///Fire delay of last firemode used. - var/last_delay = 0 + //var/last_delay = 0 + COOLDOWN_DECLARE(fire_cooldown) /// Currently selected target to fire at. Set with set_target() VAR_PRIVATE/atom/target @@ -138,6 +141,7 @@ VAR_PRIVATE/mob/hp_operator var/empty_alarm = 'sound/weapons/hmg_eject_mag.ogg' + var/shots_fired = 0 //----------------------------- //------GENERAL PROCS---------- @@ -355,10 +359,12 @@ to_chat(user, SPAN_WARNING("\The [name] is broken!")) return FALSE + /* done in initiate_fire instead, as don't want to block continue_fire if(world.time < next_use) if(cooldown >= 20) //filter out guns with high firerate to prevent message spam. to_chat(user, SPAN_WARNING("You need to wait [SPAN_HELPFUL((next_use - world.time) / 10)] seconds before [name] can be used again.")) return FALSE + */ if(ammo && ammo.current_rounds <= 0) to_chat(user, SPAN_WARNING("\The [name] is out of ammo! Magazines: [SPAN_HELPFUL(LAZYLEN(backup_clips))]/[SPAN_HELPFUL(max_clips)]")) @@ -374,10 +380,12 @@ return TRUE +/* //Called when you want to activate the hardpoint, by default firing a gun //This can also be used for some type of temporary buff or toggling mode, up to you /obj/item/hardpoint/proc/activate(mob/user, atom/A) fire(user, A) +*/ /obj/item/hardpoint/proc/deactivate() return @@ -531,6 +539,7 @@ user.visible_message(SPAN_NOTICE("[user] stops repairing \the [name]."), SPAN_NOTICE("You stop repairing \the [name]. The integrity of the module is at [SPAN_HELPFUL(round(get_integrity_percent()))]%.")) return +/* allowed northwest firing when facing east, undesirable //determines whether something is in firing arc of a hardpoint /obj/item/hardpoint/proc/in_firing_arc(atom/A) if(!owner) @@ -567,7 +576,9 @@ angle += 180 return abs(angle) <= (firing_arc/2) +*/ +/* //doing last preparation before actually firing gun /obj/item/hardpoint/proc/fire(mob/user, atom/A) if(!ammo) //Prevents a runtime @@ -585,7 +596,9 @@ fire_projectile(user, A) to_chat(user, SPAN_WARNING("[name] Ammo: [SPAN_HELPFUL(ammo ? ammo.current_rounds : 0)]/[SPAN_HELPFUL(ammo ? ammo.max_rounds : 0)] | Mags: [SPAN_HELPFUL(LAZYLEN(backup_clips))]/[SPAN_HELPFUL(max_clips)]")) +*/ +/* //finally firing the gun /obj/item/hardpoint/proc/fire_projectile(mob/user, atom/A) set waitfor = 0 @@ -601,6 +614,7 @@ muzzle_flash(Get_Angle(origin_turf, A)) ammo.current_rounds-- +*/ /// Setter proc to toggle burst firing /obj/item/hardpoint/proc/set_burst_firing(burst = FALSE) @@ -608,6 +622,7 @@ ///Clean all references /obj/item/hardpoint/proc/reset_fire() + shots_fired = 0 set_auto_firing(FALSE) set_target(null) @@ -638,10 +653,6 @@ //to_chat(user, SPAN_DANGER("[ammo.current_rounds] / [ammo.max_rounds] ROUNDS REMAINING")) to_chat(user, SPAN_WARNING("[name] Ammo: [SPAN_HELPFUL(ammo ? ammo.current_rounds : 0)]/[SPAN_HELPFUL(ammo ? ammo.max_rounds : 0)] | Mags: [SPAN_HELPFUL(LAZYLEN(backup_clips))]/[SPAN_HELPFUL(max_clips)]")) -/obj/item/hardpoint/proc/handle_ammo_out(mob/user) - visible_message(SPAN_NOTICE("[icon2html(src, viewers(src))] [src] beeps steadily and its ammo light blinks red.")) - playsound(loc, empty_alarm, 25, 1) - /obj/item/hardpoint/proc/crew_mouseup(datum/source, atom/object, turf/location, control, params) if(auto_firing || burst_firing) SEND_SIGNAL(src, COMSIG_GUN_STOP_FIRE) @@ -685,7 +696,12 @@ /obj/item/hardpoint/proc/initiate_fire(atom/target, mob/living/user, params) //still actively firing - if(auto_firing || burst_firing || world.time < last_fired + last_delay) + if(auto_firing || burst_firing) + return NONE + + if(!COOLDOWN_FINISHED(src, fire_cooldown)) + if(max(fire_delay, burst_delay + extra_delay) >= 2.0 SECONDS) //filter out guns with high firerate to prevent message spam. + to_chat(user, SPAN_WARNING("You need to wait [SPAN_HELPFUL(COOLDOWN_SECONDSLEFT(src, fire_cooldown))] seconds before [name] can be used again.")) return NONE switch(gun_firemode) @@ -706,9 +722,13 @@ if(!target || !user) return NONE + if(!can_activate(user, target)) //since it doesn't follow the multitile_interaction -> can_activate() pathway have to do it here + return NONE + return try_fire(target, user, params) /obj/item/hardpoint/proc/try_fire(atom/target, mob/living/user, params) + /* currently checked by multitile_interaction doing can_activate() first if(health <= 0) to_chat(user, SPAN_WARNING("\The [name] is broken!")) return NONE @@ -720,44 +740,44 @@ if(!in_firing_arc(target)) to_chat(user, SPAN_WARNING("The target is not within your firing arc!")) return NONE + */ return fire_shot(target, user, params) /obj/item/hardpoint/proc/fire_shot(atom/target, mob/living/user, params) - //offset fire origin from lower-left corner - var/turf/origin_turf = get_turf(src) - origin_turf = locate(origin_turf.x + origins[1], origin_turf.y + origins[2], origin_turf.z) + var/turf/origin_turf = get_origin_turf() var/obj/projectile/projectile_to_fire = generate_bullet(user, origin_turf) SEND_SIGNAL(projectile_to_fire, COMSIG_BULLET_USER_EFFECTS, user) - play_firing_sounds(projectile_to_fire, user) - INVOKE_ASYNC(projectile_to_fire, TYPE_PROC_REF(/obj/projectile, fire_at), target, user, src, projectile_to_fire.ammo.max_range, projectile_to_fire.ammo.shell_speed) projectile_to_fire = null + ammo.current_rounds-- + shots_fired++ + play_firing_sounds() if(use_muzzle_flash) muzzle_flash(Get_Angle(origin_turf, target)) - ammo.current_rounds-- - //just ran out - if(ammo.current_rounds <= 0) - playsound(get_turf(src), empty_alarm, 70, 1) - //cooldown to respect intended ROF - last_fired = world.time + var/cooldown_time = 0 switch(gun_firemode) if(GUN_FIREMODE_SEMIAUTO) - last_delay = fire_delay + cooldown_time = fire_delay reset_fire() display_ammo() if(GUN_FIREMODE_BURSTFIRE) - last_delay = burst_delay + extra_delay + cooldown_time = burst_delay + extra_delay if(GUN_FIREMODE_AUTOMATIC) - last_delay = fire_delay + cooldown_time = fire_delay + COOLDOWN_START(src, fire_cooldown, cooldown_time) return AUTOFIRE_CONTINUE +/// Get turf at hardpoint origin position, used as the muzzle. +/obj/item/hardpoint/proc/get_origin_turf() + return get_offset_target_turf(get_turf(src), origins[1], origins[2]) + /// Toggles the gun's firemode one down the list /obj/item/hardpoint/proc/do_toggle_firemode(mob/user, new_firemode) /* @@ -795,10 +815,27 @@ else playsound(src, 'sound/weapons/gun_empty.ogg', 25, 1, 5) -/obj/item/hardpoint/proc/play_firing_sounds(obj/projectile/projectile_to_fire, mob/user) +/obj/item/hardpoint/proc/play_firing_sounds() if(LAZYLEN(activation_sounds)) playsound(get_turf(src), pick(activation_sounds), 60, 1) +/// Determines whether something is in firing arc of a hardpoint. +/obj/item/hardpoint/proc/in_firing_arc(atom/target) + if(!firing_arc || !ISINRANGE_EX(firing_arc, 0, 360)) + return TRUE + + var/turf/muzzle_turf = get_origin_turf() + var/turf/target_turf = get_turf(target) + + var/angle_diff = SIMPLIFY_DEGREES(dir2angle(dir) - get_angle(muzzle_turf, target_turf)) + if(angle_diff < -180) + angle_diff += 360 + else if(angle_diff > 180) + angle_diff -= 360 + //debug_msg("Get_Angle: [Get_Angle(muzzle_turf, target_turf)] get_angle: [get_angle(muzzle_turf, target_turf)] dir2angle: [dir2angle(dir)] angle_diff: [angle_diff]") + + return abs(angle_diff) <= (firing_arc * 0.5) + //----------------------------- //------ICON PROCS---------- //----------------------------- diff --git a/code/modules/vehicles/hardpoints/holder/tank_turret.dm b/code/modules/vehicles/hardpoints/holder/tank_turret.dm index 27ab6c95404c..49e40e62c9c4 100644 --- a/code/modules/vehicles/hardpoints/holder/tank_turret.dm +++ b/code/modules/vehicles/hardpoints/holder/tank_turret.dm @@ -60,6 +60,14 @@ // Used during the windup var/rotating = FALSE + burst_amount = 2 + burst_delay = 1.0 SECONDS + extra_delay = 13.0 SECONDS + gun_firemode = GUN_FIREMODE_BURSTFIRE + gun_firemode_list = list( + GUN_FIREMODE_BURSTFIRE, + ) + /obj/item/hardpoint/holder/tank_turret/update_icon() var/broken = (health <= 0) icon_state = "tank_turret_[broken]" @@ -182,6 +190,34 @@ user.client.pixel_x = -1 * AM.view_tile_offset * 32 user.client.pixel_y = 0 +/obj/item/hardpoint/holder/tank_turret/try_fire(atom/target, mob/living/user, params) + var/turf/L + var/turf/R + switch(owner.dir) + if(NORTH) + L = locate(owner.x - 2, owner.y + 4, owner.z) + R = locate(owner.x + 2, owner.y + 4, owner.z) + if(SOUTH) + L = locate(owner.x + 2, owner.y - 4, owner.z) + R = locate(owner.x - 2, owner.y - 4, owner.z) + if(EAST) + L = locate(owner.x + 4, owner.y + 2, owner.z) + R = locate(owner.x + 4, owner.y - 2, owner.z) + else + L = locate(owner.x - 4, owner.y + 2, owner.z) + R = locate(owner.x - 4, owner.y - 2, owner.z) + + if(shots_fired) + L = R + + return fire_shot(L, user, params) + +/obj/item/hardpoint/holder/tank_turret/get_origin_turf() + var/origin_turf = get_offset_target_turf(get_turf(src), origins[1], origins[2]) + origin_turf = get_step(get_step(origin_turf, owner.dir), owner.dir) //this should get us tile in front of tank to prevent grenade being stuck under us. + return origin_turf + +/* /obj/item/hardpoint/holder/tank_turret/fire(mob/user, atom/A) if(ammo.current_rounds <= 0) return @@ -215,7 +251,9 @@ fire_projectile(user, R) to_chat(user, SPAN_WARNING("Smoke Screen uses left: [SPAN_HELPFUL(ammo ? ammo.current_rounds / 2 : 0)]/[SPAN_HELPFUL(ammo ? ammo.max_rounds / 2 : 0)] | Mags: [SPAN_HELPFUL(LAZYLEN(backup_clips))]/[SPAN_HELPFUL(max_clips)]")) +*/ +/* /obj/item/hardpoint/holder/tank_turret/fire_projectile(mob/user, atom/A) set waitfor = 0 @@ -227,3 +265,4 @@ SEND_SIGNAL(P, COMSIG_BULLET_USER_EFFECTS, owner.seats[VEHICLE_GUNNER]) P.fire_at(A, owner.seats[VEHICLE_GUNNER], src, get_dist(origin_turf, A) + 1, P.ammo.shell_speed) ammo.current_rounds-- +*/ diff --git a/code/modules/vehicles/hardpoints/primary/autocannon.dm b/code/modules/vehicles/hardpoints/primary/autocannon.dm index df9224011b32..54b34f78f726 100644 --- a/code/modules/vehicles/hardpoints/primary/autocannon.dm +++ b/code/modules/vehicles/hardpoints/primary/autocannon.dm @@ -23,3 +23,9 @@ "4" = list(32, 0), "8" = list(-32, 0) ) + + fire_delay = 0.7 SECONDS + gun_firemode = GUN_FIREMODE_AUTOMATIC + gun_firemode_list = list( + GUN_FIREMODE_AUTOMATIC, + ) diff --git a/code/modules/vehicles/hardpoints/primary/dual_cannon.dm b/code/modules/vehicles/hardpoints/primary/dual_cannon.dm index d128860f4874..6f5136cc03d5 100644 --- a/code/modules/vehicles/hardpoints/primary/dual_cannon.dm +++ b/code/modules/vehicles/hardpoints/primary/dual_cannon.dm @@ -35,7 +35,7 @@ fire_delay = 0.5 SECONDS burst_amount = 2 burst_delay = 0.3 SECONDS - extra_delay = 0.4 SECONDS + extra_delay = 0.1 SECONDS gun_firemode = GUN_FIREMODE_BURSTFIRE gun_firemode_list = list( GUN_FIREMODE_SEMIAUTO, diff --git a/code/modules/vehicles/hardpoints/primary/flamer.dm b/code/modules/vehicles/hardpoints/primary/flamer.dm index 929842df2307..e64cc2aa3448 100644 --- a/code/modules/vehicles/hardpoints/primary/flamer.dm +++ b/code/modules/vehicles/hardpoints/primary/flamer.dm @@ -26,6 +26,8 @@ use_muzzle_flash = FALSE + fire_delay = 2.0 SECONDS + /obj/item/hardpoint/primary/flamer/set_bullet_traits() ..() LAZYADD(traits_to_give, list( @@ -36,26 +38,9 @@ if(!..()) return FALSE - var/turf/origin_turf = get_turf(src) - origin_turf = locate(origin_turf.x + origins[1], origin_turf.y + origins[2], origin_turf.z) + var/turf/origin_turf = get_origin_turf() if(origin_turf == get_turf(A)) + to_chat(user, SPAN_WARNING("The target is too close.")) return FALSE return TRUE - -/obj/item/hardpoint/primary/flamer/fire_projectile(mob/user, atom/A) - set waitfor = 0 - - var/turf/origin_turf = get_turf(src) - origin_turf = locate(origin_turf.x + origins[1], origin_turf.y + origins[2], origin_turf.z) - - var/range = get_dist(origin_turf, A) + 1 - - var/obj/projectile/P = generate_bullet(user, origin_turf) - SEND_SIGNAL(P, COMSIG_BULLET_USER_EFFECTS, owner.seats[VEHICLE_GUNNER]) - P.fire_at(A, owner.seats[VEHICLE_GUNNER], src, range < P.ammo.max_range ? range : P.ammo.max_range, P.ammo.shell_speed) - - if(use_muzzle_flash) - muzzle_flash(Get_Angle(owner, A)) - - ammo.current_rounds-- diff --git a/code/modules/vehicles/hardpoints/primary/ltb.dm b/code/modules/vehicles/hardpoints/primary/ltb.dm index 7c663dc27fbc..0f67aceecff8 100644 --- a/code/modules/vehicles/hardpoints/primary/ltb.dm +++ b/code/modules/vehicles/hardpoints/primary/ltb.dm @@ -30,3 +30,9 @@ "4" = list(89, -4), "8" = list(-89, -4) ) + + fire_delay = 20.0 SECONDS + gun_firemode = GUN_FIREMODE_SEMIAUTO + gun_firemode_list = list( + GUN_FIREMODE_SEMIAUTO, + ) diff --git a/code/modules/vehicles/hardpoints/primary/minigun.dm b/code/modules/vehicles/hardpoints/primary/minigun.dm index c6158f1a3b2c..b924810d5d1f 100644 --- a/code/modules/vehicles/hardpoints/primary/minigun.dm +++ b/code/modules/vehicles/hardpoints/primary/minigun.dm @@ -37,7 +37,18 @@ var/last_shot_time = 0 //when was last shot fired, after 3 seconds we stop barrel var/list/chain_bursts = list(1, 1, 2, 2, 3, 3, 3, 4, 4, 4) //how many shots per click we do + fire_delay = 0.2 SECONDS + gun_firemode = GUN_FIREMODE_AUTOMATIC + gun_firemode_list = list( + GUN_FIREMODE_AUTOMATIC, + ) + + var/start_sound = 'sound/weapons/vehicles/minigun_start.ogg' + var/loop_sound = 'sound/weapons/vehicles/minigun_loop.ogg' + var/stop_sound = 'sound/weapons/vehicles/minigun_stop.ogg' + activation_sounds = list('sound/weapons/gun_minigun.ogg') +/* /obj/item/hardpoint/primary/minigun/fire(mob/user, atom/A) var/S = 'sound/weapons/vehicles/minigun_stop.ogg' @@ -73,3 +84,4 @@ playsound(get_turf(src), S, 40, 1) last_shot_time = world.time +*/ diff --git a/code/modules/vehicles/hardpoints/secondary/cupola.dm b/code/modules/vehicles/hardpoints/secondary/cupola.dm index 712e6c7763e3..4fd119664169 100644 --- a/code/modules/vehicles/hardpoints/secondary/cupola.dm +++ b/code/modules/vehicles/hardpoints/secondary/cupola.dm @@ -25,27 +25,16 @@ "8" = list(-5, 7) ) + burst_amount = 3 + burst_delay = 0.3 SECONDS + extra_delay = 0.6 SECONDS + gun_firemode = GUN_FIREMODE_BURSTFIRE + gun_firemode_list = list( + GUN_FIREMODE_BURSTFIRE, + ) + /obj/item/hardpoint/secondary/m56cupola/set_bullet_traits() ..() LAZYADD(traits_to_give, list( BULLET_TRAIT_ENTRY(/datum/element/bullet_trait_iff) )) - -/obj/item/hardpoint/secondary/m56cupola/fire(mob/user, atom/A) - if(ammo.current_rounds <= 0) - return - - next_use = world.time + cooldown * owner.misc_multipliers["cooldown"] - - for(var/bullets_fired = 1, bullets_fired <= burst_amount, bullets_fired++) - var/atom/T = A - if(!prob((accuracy * 100) / owner.misc_multipliers["accuracy"])) - T = get_step(get_turf(A), pick(cardinal)) - if(LAZYLEN(activation_sounds)) - playsound(get_turf(src), pick(activation_sounds), 60, 1) - fire_projectile(user, T) - if(ammo.current_rounds <= 0) - break - if(bullets_fired < burst_amount) //we need to sleep only if there are more bullets to shoot in the burst - sleep(3) - to_chat(user, SPAN_WARNING("[src] Ammo: [SPAN_HELPFUL(ammo ? ammo.current_rounds : 0)]/[SPAN_HELPFUL(ammo ? ammo.max_rounds : 0)] | Mags: [SPAN_HELPFUL(LAZYLEN(backup_clips))]/[SPAN_HELPFUL(max_clips)]")) diff --git a/code/modules/vehicles/hardpoints/secondary/flamer.dm b/code/modules/vehicles/hardpoints/secondary/flamer.dm index 10f7453d8c95..770018f6d591 100644 --- a/code/modules/vehicles/hardpoints/secondary/flamer.dm +++ b/code/modules/vehicles/hardpoints/secondary/flamer.dm @@ -28,31 +28,20 @@ "8" = list(-3, 18) ) -/obj/item/hardpoint/secondary/small_flamer/fire_projectile(mob/user, atom/A) - set waitfor = 0 + fire_delay = 3.0 SECONDS +/obj/item/hardpoint/secondary/small_flamer/fire_shot(atom/target, mob/living/user, params) + //offset fire origin from lower-left corner var/turf/origin_turf = get_turf(src) - origin_turf = locate(origin_turf.x + origins[1], origin_turf.y + origins[2], origin_turf.z) - var/list/turf/turfs = getline2(origin_turf, A) - var/distance = 0 - var/turf/prev_T - - for(var/turf/T in turfs) - if(T == loc) - prev_T = T - continue - if(!ammo.current_rounds) break - if(distance >= max_range) break - if(prev_T && LinkBlocked(prev_T, T)) - break - ammo.current_rounds-- - flame_turf(T, user) - distance++ - prev_T = T - sleep(1) - -/obj/item/hardpoint/secondary/small_flamer/proc/flame_turf(turf/T, mob/user) - if(!istype(T)) return - - if(!locate(/obj/flamer_fire) in T) // No stacking flames! - new/obj/flamer_fire(T, create_cause_data(initial(name), user)) + origin_turf = get_offset_target_turf(origin_turf, origins[1], origins[2]) + + var/distance = get_dist(origin_turf, get_turf(target)) + var/fire_amount = min(ammo.current_rounds, distance+1, max_range) + + new /obj/flamer_fire(origin_turf, create_cause_data(initial(name), user), null, fire_amount, null, FLAMESHAPE_LINE, target, CALLBACK(src, PROC_REF(display_ammo), user)) + + ammo.current_rounds -= fire_amount + play_firing_sounds() + + COOLDOWN_START(src, fire_cooldown, fire_delay) + return AUTOFIRE_CONTINUE diff --git a/code/modules/vehicles/hardpoints/secondary/grenade_launcher.dm b/code/modules/vehicles/hardpoints/secondary/grenade_launcher.dm index 8151a1ee50c1..7e5a9298d1b9 100644 --- a/code/modules/vehicles/hardpoints/secondary/grenade_launcher.dm +++ b/code/modules/vehicles/hardpoints/secondary/grenade_launcher.dm @@ -27,6 +27,8 @@ "8" = list(-6, 17) ) + fire_delay = 3.0 SECONDS + /obj/item/hardpoint/secondary/grenade_launcher/set_bullet_traits() ..() LAZYADD(traits_to_give, list( @@ -37,30 +39,9 @@ if(!..()) return FALSE - var/turf/origin_turf = get_turf(src) - origin_turf = locate(origin_turf.x + origins[1], origin_turf.y + origins[2], origin_turf.z) - if(get_dist(origin_turf, A) < 1) - to_chat(usr, SPAN_WARNING("The target is too close.")) + var/turf/origin_turf = get_origin_turf() + if(origin_turf == get_turf(A)) + to_chat(user, SPAN_WARNING("The target is too close.")) return FALSE return TRUE - -/obj/item/hardpoint/secondary/grenade_launcher/fire_projectile(mob/user, atom/A) - set waitfor = 0 - - var/turf/origin_turf = get_turf(src) - origin_turf = locate(origin_turf.x + origins[1], origin_turf.y + origins[2], origin_turf.z) - - //getting distance between supposed target and tank center. - var/range = get_dist(origin_turf, A) + 1 //otherwise nade falls one tile shorter - if(range > max_range) - range = max_range - - var/obj/projectile/P = generate_bullet(user, origin_turf) - SEND_SIGNAL(P, COMSIG_BULLET_USER_EFFECTS, owner.seats[VEHICLE_GUNNER]) - P.fire_at(A, owner.seats[VEHICLE_GUNNER], src, P.ammo.max_range, P.ammo.shell_speed) - - if(use_muzzle_flash) - muzzle_flash(Get_Angle(owner, A)) - - ammo.current_rounds-- diff --git a/code/modules/vehicles/hardpoints/secondary/tow.dm b/code/modules/vehicles/hardpoints/secondary/tow.dm index 4bdbc6f417fb..00a492566de7 100644 --- a/code/modules/vehicles/hardpoints/secondary/tow.dm +++ b/code/modules/vehicles/hardpoints/secondary/tow.dm @@ -29,3 +29,10 @@ "4" = list(5, -8), "8" = list(-5, 10) ) + + fire_delay = 15.0 SECONDS + gun_firemode = GUN_FIREMODE_SEMIAUTO + gun_firemode_list = list( + GUN_FIREMODE_SEMIAUTO, + ) + diff --git a/code/modules/vehicles/hardpoints/support/artillery.dm b/code/modules/vehicles/hardpoints/support/artillery.dm index 441817107e7c..033004852a2f 100644 --- a/code/modules/vehicles/hardpoints/support/artillery.dm +++ b/code/modules/vehicles/hardpoints/support/artillery.dm @@ -14,7 +14,8 @@ var/view_buff = 10 //This way you can VV for more or less fun var/view_tile_offset = 7 -/obj/item/hardpoint/support/artillery_module/activate(mob/user, atom/A) +// /obj/item/hardpoint/support/artillery_module/activate(mob/user, atom/A) +/obj/item/hardpoint/support/artillery_module/crew_mousedown(mob/user, atom/A) if(!user.client) return diff --git a/code/modules/vehicles/multitile/multitile_hardpoints.dm b/code/modules/vehicles/multitile/multitile_hardpoints.dm index 2c5a343b802a..7274e4b24d58 100644 --- a/code/modules/vehicles/multitile/multitile_hardpoints.dm +++ b/code/modules/vehicles/multitile/multitile_hardpoints.dm @@ -231,6 +231,7 @@ update_icon() +/* //proc that fires non selected weaponry /obj/vehicle/multitile/proc/shoot_other_weapon(mob/living/carbon/human/M, seat, atom/A) @@ -252,7 +253,9 @@ HP.activate(M, A) break return +*/ +/* //proc that activates support module if it can be activated and you meet requirements /obj/vehicle/multitile/proc/activate_support_module(mob/living/carbon/human/M, seat, atom/A) @@ -274,3 +277,4 @@ HP.activate(M, A) break return +*/ From 2aba617d1a9df27663c7345697a1a0bd0c2e3e73 Mon Sep 17 00:00:00 2001 From: Doubleumc Date: Sun, 5 Nov 2023 02:17:54 -0500 Subject: [PATCH 06/21] scatter and tank weapons working --- code/modules/vehicles/hardpoints/hardpoint.dm | 270 +++++------------- .../vehicles/hardpoints/holder/tank_turret.dm | 6 +- .../vehicles/hardpoints/primary/autocannon.dm | 4 +- .../hardpoints/primary/dual_cannon.dm | 13 +- .../vehicles/hardpoints/primary/flamer.dm | 15 +- .../vehicles/hardpoints/primary/ltb.dm | 4 +- .../vehicles/hardpoints/primary/minigun.dm | 90 +++--- .../vehicles/hardpoints/secondary/cupola.dm | 5 +- .../vehicles/hardpoints/secondary/flamer.dm | 13 +- .../hardpoints/secondary/frontal_cannon.dm | 12 +- .../hardpoints/secondary/grenade_launcher.dm | 13 +- .../vehicles/hardpoints/secondary/tow.dm | 4 +- .../hardpoints/special/firing_port_weapon.dm | 74 ++--- .../vehicles/hardpoints/support/artillery.dm | 10 +- .../vehicles/hardpoints/support/flare.dm | 4 +- .../multitile/multitile_interaction.dm | 24 +- .../vehicles/multitile/multitile_verbs.dm | 2 + 17 files changed, 190 insertions(+), 373 deletions(-) diff --git a/code/modules/vehicles/hardpoints/hardpoint.dm b/code/modules/vehicles/hardpoints/hardpoint.dm index ed124ed438c0..c48a9f8178b0 100644 --- a/code/modules/vehicles/hardpoints/hardpoint.dm +++ b/code/modules/vehicles/hardpoints/hardpoint.dm @@ -102,6 +102,11 @@ /// that will be given to a projectile fired from the hardpoint var/list/list/traits_to_give + ///How much the bullet scatters when fired. + var/scatter = 0 + ///How many bullets the gun fired while burst firing/auto firing. + var/shots_fired = 0 + //Firemodes. ///Current selected firemode of the gun. var/gun_firemode = GUN_FIREMODE_SEMIAUTO @@ -123,16 +128,12 @@ VAR_PROTECTED/burst_amount = 1 ///The delay in between shots. Lower = less delay = faster. Use modify_burst_delay and set_burst_delay instead of modifying this VAR_PROTECTED/burst_delay = 1 - ///When burst-firing, this number is extra time before the weapon can fire again. Depends on number of rounds fired. + ///When burst-firing, this number is extra time before the weapon can fire again. var/extra_delay = 0 ///If the gun is currently burst firing. VAR_PROTECTED/burst_firing = FALSE - //Firing cooldown. - ///When it was last fired, related to world.time. - //var/last_fired = 0 - ///Fire delay of last firemode used. - //var/last_delay = 0 + ///Delay before fire can resume. COOLDOWN_DECLARE(fire_cooldown) /// Currently selected target to fire at. Set with set_target() @@ -140,9 +141,6 @@ /// Current operator (crew) of the hardpoint. VAR_PRIVATE/mob/hp_operator - var/empty_alarm = 'sound/weapons/hmg_eject_mag.ogg' - var/shots_fired = 0 - //----------------------------- //------GENERAL PROCS---------- //----------------------------- @@ -150,7 +148,7 @@ /obj/item/hardpoint/Initialize() . = ..() set_bullet_traits() - AddComponent(/datum/component/automatedfire/autofire, fire_delay, burst_delay, burst_amount, gun_firemode, autofire_slow_mult, CALLBACK(src, PROC_REF(set_burst_firing)), CALLBACK(src, PROC_REF(reset_fire)), CALLBACK(src, PROC_REF(continue_fire)), CALLBACK(src, PROC_REF(display_ammo)), CALLBACK(src, PROC_REF(set_auto_firing))) + AddComponent(/datum/component/automatedfire/autofire, fire_delay, burst_delay, burst_amount, gun_firemode, autofire_slow_mult, CALLBACK(src, PROC_REF(set_burst_firing)), CALLBACK(src, PROC_REF(reset_fire)), CALLBACK(src, PROC_REF(fire_wrapper)), CALLBACK(src, PROC_REF(display_ammo)), CALLBACK(src, PROC_REF(set_auto_firing))) /obj/item/hardpoint/Destroy() if(owner) @@ -298,6 +296,7 @@ return data +/* // Traces backwards from the gun origin to the vehicle to check for obstacles between the vehicle and the muzzle /obj/item/hardpoint/proc/clear_los(atom/A) @@ -337,56 +336,12 @@ checking_turf = get_step(checking_turf, turn(dir,180)) return TRUE +*/ //----------------------------- //------INTERACTION PROCS---------- //----------------------------- -//If the hardpoint can be activated by current user -/obj/item/hardpoint/proc/can_activate(mob/user, atom/A) - if(!owner) - return - - var/seat = owner.get_mob_seat(user) - if(!seat) - return - - if(seat != allowed_seat) - to_chat(user, SPAN_WARNING("Only [allowed_seat] can use [name].")) - return - - if(health <= 0) - to_chat(user, SPAN_WARNING("\The [name] is broken!")) - return FALSE - - /* done in initiate_fire instead, as don't want to block continue_fire - if(world.time < next_use) - if(cooldown >= 20) //filter out guns with high firerate to prevent message spam. - to_chat(user, SPAN_WARNING("You need to wait [SPAN_HELPFUL((next_use - world.time) / 10)] seconds before [name] can be used again.")) - return FALSE - */ - - if(ammo && ammo.current_rounds <= 0) - to_chat(user, SPAN_WARNING("\The [name] is out of ammo! Magazines: [SPAN_HELPFUL(LAZYLEN(backup_clips))]/[SPAN_HELPFUL(max_clips)]")) - return FALSE - - if(!in_firing_arc(A)) - to_chat(user, SPAN_WARNING("The target is not within your firing arc!")) - return FALSE - - if(!clear_los(A)) - to_chat(user, SPAN_WARNING("You don't have a clear line of sight to the target!")) - return FALSE - - return TRUE - -/* -//Called when you want to activate the hardpoint, by default firing a gun -//This can also be used for some type of temporary buff or toggling mode, up to you -/obj/item/hardpoint/proc/activate(mob/user, atom/A) - fire(user, A) -*/ - /obj/item/hardpoint/proc/deactivate() return @@ -539,94 +494,17 @@ user.visible_message(SPAN_NOTICE("[user] stops repairing \the [name]."), SPAN_NOTICE("You stop repairing \the [name]. The integrity of the module is at [SPAN_HELPFUL(round(get_integrity_percent()))]%.")) return -/* allowed northwest firing when facing east, undesirable -//determines whether something is in firing arc of a hardpoint -/obj/item/hardpoint/proc/in_firing_arc(atom/A) - if(!owner) - return FALSE - - if(!firing_arc) - return TRUE - - var/turf/T = get_turf(A) - if(!T) - return FALSE - - var/dx = T.x - (owner.x + origins[1]/2) - var/dy = T.y - (owner.y + origins[2]/2) - - var/deg = 0 - switch(dir) - if(EAST) - deg = 0 - if(NORTH) - deg = -90 - if(WEST) - deg = 180 - if(SOUTH) - deg = 90 - - var/nx = dx * cos(deg) - dy * sin(deg) - var/ny = dx * sin(deg) + dy * cos(deg) - if(nx == 0) - return firing_arc >= 90 - - var/angle = arctan(ny/nx) - if(nx < 0) - angle += 180 - - return abs(angle) <= (firing_arc/2) -*/ - -/* -//doing last preparation before actually firing gun -/obj/item/hardpoint/proc/fire(mob/user, atom/A) - if(!ammo) //Prevents a runtime - return - if(ammo.current_rounds <= 0) - return - - next_use = world.time + cooldown * owner.misc_multipliers["cooldown"] - if(!prob((accuracy * 100) / owner.misc_multipliers["accuracy"])) - A = get_step(get_turf(A), pick(cardinal)) - - if(LAZYLEN(activation_sounds)) - playsound(get_turf(src), pick(activation_sounds), 60, 1) - - fire_projectile(user, A) - - to_chat(user, SPAN_WARNING("[name] Ammo: [SPAN_HELPFUL(ammo ? ammo.current_rounds : 0)]/[SPAN_HELPFUL(ammo ? ammo.max_rounds : 0)] | Mags: [SPAN_HELPFUL(LAZYLEN(backup_clips))]/[SPAN_HELPFUL(max_clips)]")) -*/ - -/* -//finally firing the gun -/obj/item/hardpoint/proc/fire_projectile(mob/user, atom/A) - set waitfor = 0 - - var/turf/origin_turf = get_turf(src) - origin_turf = locate(origin_turf.x + origins[1], origin_turf.y + origins[2], origin_turf.z) - - var/obj/projectile/P = generate_bullet(user, origin_turf) - SEND_SIGNAL(P, COMSIG_BULLET_USER_EFFECTS, user) - P.fire_at(A, user, src, P.ammo.max_range, P.ammo.shell_speed) - - if(use_muzzle_flash) - muzzle_flash(Get_Angle(origin_turf, A)) - - ammo.current_rounds-- -*/ - -/// Setter proc to toggle burst firing +/// Setter proc for the burst firing flag. /obj/item/hardpoint/proc/set_burst_firing(burst = FALSE) burst_firing = burst -///Clean all references +/// Clean all firing references. /obj/item/hardpoint/proc/reset_fire() shots_fired = 0 - set_auto_firing(FALSE) set_target(null) + set_auto_firing(FALSE) //autofire automatic exit -///Set the target and take care of hard delete +/// Set the target and take care of hard delete. /obj/item/hardpoint/proc/set_target(atom/object) if(object == target || object == loc) return @@ -636,84 +514,64 @@ if(target) RegisterSignal(target, COMSIG_PARENT_QDELETING, PROC_REF(clean_target)) -///Set the target to its turf, so we keep shooting even when it was qdeled +/// Set the target to its turf, so we keep shooting even when it was qdeled. /obj/item/hardpoint/proc/clean_target() SIGNAL_HANDLER target = get_turf(target) -/// Setter proc for auto_firing +/// Setter proc for the automatic firing flag. /obj/item/hardpoint/proc/set_auto_firing(auto = FALSE) auto_firing = auto +/// Print how much ammo is left to chat. /obj/item/hardpoint/proc/display_ammo(mob/user) if(!user) user = hp_operator - if( ammo) + if(ammo) //to_chat(user, SPAN_DANGER("[ammo.current_rounds] / [ammo.max_rounds] ROUNDS REMAINING")) to_chat(user, SPAN_WARNING("[name] Ammo: [SPAN_HELPFUL(ammo ? ammo.current_rounds : 0)]/[SPAN_HELPFUL(ammo ? ammo.max_rounds : 0)] | Mags: [SPAN_HELPFUL(LAZYLEN(backup_clips))]/[SPAN_HELPFUL(max_clips)]")) -/obj/item/hardpoint/proc/crew_mouseup(datum/source, atom/object, turf/location, control, params) +/// Reset variables used in firing and remove the gun from the autofire system. +/obj/item/hardpoint/proc/stop_fire(datum/source, atom/object, turf/location, control, params) if(auto_firing || burst_firing) SEND_SIGNAL(src, COMSIG_GUN_STOP_FIRE) - //autofire component resets on burst completion, have to do it ourselves for automatic if(auto_firing) + //manual automatic exit reset_fire() display_ammo() -///Update the target if you draged your mouse -/obj/item/hardpoint/proc/crew_mousedrag(mob/source, atom/src_object, atom/over_object, turf/src_location, turf/over_location, src_control, over_control, params) - set_target(get_turf_on_clickcatcher(over_object, hp_operator, params)) //stops when dragging over UI - /* - if(istype(over_object, /atom/movable/screen)) //doesn't stop when dragging over UI, no side effects? - var/list/modifiers = params2list(params) - var/turf/turf = params2turf(modifiers["screen-loc"], get_turf(source.client.eye), source.client) - if (turf) - set_target(turf) - else - set_target(over_object) - */ - - -///Check if the gun can fire and add it to bucket auto_fire system if needed, or just fire the gun if not -/obj/item/hardpoint/proc/crew_mousedown(datum/source, atom/object, turf/location, control, params) - hp_operator = source +/// Update the target if you dragged your mouse. +/obj/item/hardpoint/proc/change_target(mob/source, atom/src_object, atom/over_object, turf/src_location, turf/over_location, src_control, over_control, params) + set_target(get_turf_on_clickcatcher(over_object, hp_operator, params)) +/// Check if the gun can fire and add it to bucket autofire system if needed, or just fire the gun if not. +/obj/item/hardpoint/proc/start_fire(datum/source, atom/object, turf/location, control, params) var/list/modifiers = params2list(params) if(modifiers["shift"] || modifiers["middle"] || modifiers["right"]) return - //don't click on UI - if(istype(object, /atom/movable/screen)) + if(istype(object, /atom/movable/screen)) //don't click on UI return if(QDELETED(object)) return - set_target(get_turf_on_clickcatcher(object, hp_operator, params)) - - initiate_fire(object, hp_operator, modifiers) - -/obj/item/hardpoint/proc/initiate_fire(atom/target, mob/living/user, params) - //still actively firing - if(auto_firing || burst_firing) - return NONE - if(!COOLDOWN_FINISHED(src, fire_cooldown)) if(max(fire_delay, burst_delay + extra_delay) >= 2.0 SECONDS) //filter out guns with high firerate to prevent message spam. to_chat(user, SPAN_WARNING("You need to wait [SPAN_HELPFUL(COOLDOWN_SECONDSLEFT(src, fire_cooldown))] seconds before [name] can be used again.")) - return NONE + return - switch(gun_firemode) - if(GUN_FIREMODE_SEMIAUTO) - try_fire(target, user, params) - if(GUN_FIREMODE_BURSTFIRE) - SEND_SIGNAL(src, COMSIG_GUN_FIRE) - if(GUN_FIREMODE_AUTOMATIC) - SEND_SIGNAL(src, COMSIG_GUN_FIRE) + hp_operator = source + set_target(get_turf_on_clickcatcher(object, hp_operator, params)) + + if(gun_firemode == GUN_FIREMODE_SEMIAUTO) + try_fire(object, source, params) + else + SEND_SIGNAL(src, COMSIG_GUN_FIRE) -/// Wrapper proc for the autofire subsystem to ensure the important args aren't null -/obj/item/hardpoint/proc/continue_fire(atom/target, mob/living/user, params) +/// Wrapper proc for the autofire system to ensure the important args aren't null. +/obj/item/hardpoint/proc/fire_wrapper(atom/target, mob/living/user, params) SHOULD_NOT_OVERRIDE(TRUE) if(!target) target = src.target @@ -722,48 +580,55 @@ if(!target || !user) return NONE - if(!can_activate(user, target)) //since it doesn't follow the multitile_interaction -> can_activate() pathway have to do it here - return NONE - return try_fire(target, user, params) +/// Tests if firing should be interrupted, otherwise fires. /obj/item/hardpoint/proc/try_fire(atom/target, mob/living/user, params) - /* currently checked by multitile_interaction doing can_activate() first if(health <= 0) to_chat(user, SPAN_WARNING("\The [name] is broken!")) return NONE - if(!ammo || ammo.current_rounds <= 0) - click_empty(user) + if(ammo && ammo.current_rounds <= 0) + click_empty() return NONE if(!in_firing_arc(target)) to_chat(user, SPAN_WARNING("The target is not within your firing arc!")) return NONE - */ - return fire_shot(target, user, params) + return handle_fire(target, user, params) -/obj/item/hardpoint/proc/fire_shot(atom/target, mob/living/user, params) +/// Actually fires the gun, sets up the projectile and fires it. +/obj/item/hardpoint/proc/handle_fire(atom/target, mob/living/user, params) var/turf/origin_turf = get_origin_turf() var/obj/projectile/projectile_to_fire = generate_bullet(user, origin_turf) + ammo.current_rounds-- SEND_SIGNAL(projectile_to_fire, COMSIG_BULLET_USER_EFFECTS, user) + // turf-targeted projectiles are fired without scatter, because proc would raytrace them further away + var/ammo_flags = projectile_to_fire.ammo.flags_ammo_behavior | projectile_to_fire.projectile_override_flags + if(!HAS_FLAG(ammo_flags, AMMO_HITS_TARGET_TURF) && !HAS_FLAG(ammo_flags, AMMO_EXPLOSIVE)) + projectile_to_fire.scatter = scatter + target = simulate_scatter(projectile_to_fire, target, origin_turf, get_turf(target), user) + INVOKE_ASYNC(projectile_to_fire, TYPE_PROC_REF(/obj/projectile, fire_at), target, user, src, projectile_to_fire.ammo.max_range, projectile_to_fire.ammo.shell_speed) projectile_to_fire = null - ammo.current_rounds-- shots_fired++ play_firing_sounds() if(use_muzzle_flash) muzzle_flash(Get_Angle(origin_turf, target)) + if(ammo && ammo.current_rounds <= 0) + click_empty() + //cooldown to respect intended ROF var/cooldown_time = 0 switch(gun_firemode) if(GUN_FIREMODE_SEMIAUTO) cooldown_time = fire_delay + //manual semiauto exit reset_fire() display_ammo() if(GUN_FIREMODE_BURSTFIRE) @@ -774,22 +639,31 @@ return AUTOFIRE_CONTINUE -/// Get turf at hardpoint origin position, used as the muzzle. +/obj/item/hardpoint/proc/simulate_scatter(obj/projectile/projectile_to_fire, atom/target, turf/curloc, turf/targloc) + var/fire_angle = Get_Angle(curloc, targloc) + var/total_scatter_angle = projectile_to_fire.scatter + + //Not if the gun doesn't scatter at all, or negative scatter. + if(total_scatter_angle > 0) + fire_angle += rand(-total_scatter_angle, total_scatter_angle) + target = get_angle_target_turf(curloc, fire_angle, 30) + + return target + +/// Get turf at hardpoint origin offset, used as the muzzle. /obj/item/hardpoint/proc/get_origin_turf() return get_offset_target_turf(get_turf(src), origins[1], origins[2]) -/// Toggles the gun's firemode one down the list +/// Toggles the gun's firemode one down the list. /obj/item/hardpoint/proc/do_toggle_firemode(mob/user, new_firemode) - /* - if(get_burst_firing())//can't toggle mid burst + if(burst_firing) //can't toggle mid burst return - */ if(!length(gun_firemode_list)) CRASH("[src] called do_toggle_firemode() with an empty gun_firemodes") if(length(gun_firemode_list) == 1) - to_chat(user, SPAN_NOTICE("[icon2html(src, user)] This gun only has one firemode.")) + to_chat(user, SPAN_NOTICE("[icon2html(src, user)] This hardpoint only has one firemode.")) return if(new_firemode) @@ -805,7 +679,7 @@ playsound(user, 'sound/weapons/handling/gun_burst_toggle.ogg', 15, 1) - to_chat(user, SPAN_NOTICE("[icon2html(src, user)] You switch to [gun_firemode].")) + to_chat(user, SPAN_NOTICE("[icon2html(src, user)] You switch the hardpoint to [gun_firemode].")) SEND_SIGNAL(src, COMSIG_GUN_FIRE_MODE_TOGGLE, gun_firemode) /obj/item/hardpoint/proc/click_empty(mob/user) @@ -827,6 +701,10 @@ var/turf/muzzle_turf = get_origin_turf() var/turf/target_turf = get_turf(target) + //same tile angle returns EAST, returning FALSE to ensure consistency + if(muzzle_turf == target_turf) + return FALSE + var/angle_diff = SIMPLIFY_DEGREES(dir2angle(dir) - get_angle(muzzle_turf, target_turf)) if(angle_diff < -180) angle_diff += 360 diff --git a/code/modules/vehicles/hardpoints/holder/tank_turret.dm b/code/modules/vehicles/hardpoints/holder/tank_turret.dm index 49e40e62c9c4..78fc259a2e26 100644 --- a/code/modules/vehicles/hardpoints/holder/tank_turret.dm +++ b/code/modules/vehicles/hardpoints/holder/tank_turret.dm @@ -13,8 +13,7 @@ density = TRUE //come on, it's huge activatable = TRUE - cooldown = 150 - accuracy = 0.8 + //accuracy = 0.8 ammo = new /obj/item/ammo_magazine/hardpoint/turret_smoke max_clips = 2 @@ -67,6 +66,7 @@ gun_firemode_list = list( GUN_FIREMODE_BURSTFIRE, ) + scatter = 4 /obj/item/hardpoint/holder/tank_turret/update_icon() var/broken = (health <= 0) @@ -210,7 +210,7 @@ if(shots_fired) L = R - return fire_shot(L, user, params) + return handle_fire(L, user, params) /obj/item/hardpoint/holder/tank_turret/get_origin_turf() var/origin_turf = get_offset_target_turf(get_turf(src), origins[1], origins[2]) diff --git a/code/modules/vehicles/hardpoints/primary/autocannon.dm b/code/modules/vehicles/hardpoints/primary/autocannon.dm index 54b34f78f726..2e74533e7ade 100644 --- a/code/modules/vehicles/hardpoints/primary/autocannon.dm +++ b/code/modules/vehicles/hardpoints/primary/autocannon.dm @@ -8,8 +8,7 @@ activation_sounds = list('sound/weapons/vehicles/autocannon_fire.ogg') health = 500 - cooldown = 7 - accuracy = 0.98 + //accuracy = 0.98 firing_arc = 60 origins = list(0, -3) @@ -29,3 +28,4 @@ gun_firemode_list = list( GUN_FIREMODE_AUTOMATIC, ) + scatter = 1 diff --git a/code/modules/vehicles/hardpoints/primary/dual_cannon.dm b/code/modules/vehicles/hardpoints/primary/dual_cannon.dm index 6f5136cc03d5..523742df3e67 100644 --- a/code/modules/vehicles/hardpoints/primary/dual_cannon.dm +++ b/code/modules/vehicles/hardpoints/primary/dual_cannon.dm @@ -12,8 +12,7 @@ damage_multiplier = 0.2 health = 500 - cooldown = 7 - accuracy = 0.98 + //accuracy = 0.98 firing_arc = 60 origins = list(0, -2) @@ -32,16 +31,12 @@ "8" = list(14, 9) ) - fire_delay = 0.5 SECONDS - burst_amount = 2 - burst_delay = 0.3 SECONDS - extra_delay = 0.1 SECONDS - gun_firemode = GUN_FIREMODE_BURSTFIRE + fire_delay = 0.3 SECONDS + gun_firemode = GUN_FIREMODE_AUTOMATIC gun_firemode_list = list( - GUN_FIREMODE_SEMIAUTO, - GUN_FIREMODE_BURSTFIRE, GUN_FIREMODE_AUTOMATIC, ) + scatter = 1 /obj/item/hardpoint/primary/dualcannon/set_bullet_traits() ..() diff --git a/code/modules/vehicles/hardpoints/primary/flamer.dm b/code/modules/vehicles/hardpoints/primary/flamer.dm index e64cc2aa3448..6475a331ffb1 100644 --- a/code/modules/vehicles/hardpoints/primary/flamer.dm +++ b/code/modules/vehicles/hardpoints/primary/flamer.dm @@ -8,8 +8,7 @@ activation_sounds = list('sound/weapons/vehicles/flamethrower.ogg') health = 400 - cooldown = 20 - accuracy = 0.75 + //accuracy = 0.75 firing_arc = 90 origins = list(0, -3) @@ -27,6 +26,7 @@ use_muzzle_flash = FALSE fire_delay = 2.0 SECONDS + scatter = 5 /obj/item/hardpoint/primary/flamer/set_bullet_traits() ..() @@ -34,13 +34,10 @@ BULLET_TRAIT_ENTRY(/datum/element/bullet_trait_iff) )) -/obj/item/hardpoint/primary/flamer/can_activate(mob/user, atom/A) - if(!..()) - return FALSE - +/obj/item/hardpoint/primary/flamer/try_fire(target, user, params) var/turf/origin_turf = get_origin_turf() - if(origin_turf == get_turf(A)) + if(origin_turf == get_turf(target)) to_chat(user, SPAN_WARNING("The target is too close.")) - return FALSE + return NONE - return TRUE + return ..() diff --git a/code/modules/vehicles/hardpoints/primary/ltb.dm b/code/modules/vehicles/hardpoints/primary/ltb.dm index 0f67aceecff8..b31fe533d29b 100644 --- a/code/modules/vehicles/hardpoints/primary/ltb.dm +++ b/code/modules/vehicles/hardpoints/primary/ltb.dm @@ -8,8 +8,7 @@ activation_sounds = list('sound/weapons/vehicles/cannon_fire1.ogg', 'sound/weapons/vehicles/cannon_fire2.ogg') health = 500 - cooldown = 200 - accuracy = 0.97 + //accuracy = 0.97 firing_arc = 60 origins = list(0, -3) @@ -36,3 +35,4 @@ gun_firemode_list = list( GUN_FIREMODE_SEMIAUTO, ) + scatter = 2 diff --git a/code/modules/vehicles/hardpoints/primary/minigun.dm b/code/modules/vehicles/hardpoints/primary/minigun.dm index b924810d5d1f..05ba44d7c6f2 100644 --- a/code/modules/vehicles/hardpoints/primary/minigun.dm +++ b/code/modules/vehicles/hardpoints/primary/minigun.dm @@ -7,8 +7,7 @@ disp_icon_state = "ltaaap_minigun" health = 350 - cooldown = 8 - accuracy = 0.6 + //accuracy = 0.6 firing_arc = 90 origins = list(0, -3) @@ -30,58 +29,53 @@ "8" = list(-77, 0) ) - //changed minigun mechanic so instead of having lowered cooldown with each shot it now has increased burst size. - //While it's still spammy, user doesn't have to click as fast as possible anymore and has margin of 2 seconds before minigun will start slowing down - - var/chained_shots = 1 //how many quick succession shots we've fired, 1 by default - var/last_shot_time = 0 //when was last shot fired, after 3 seconds we stop barrel - var/list/chain_bursts = list(1, 1, 2, 2, 3, 3, 3, 4, 4, 4) //how many shots per click we do - - fire_delay = 0.2 SECONDS + fire_delay = 0.8 SECONDS gun_firemode = GUN_FIREMODE_AUTOMATIC gun_firemode_list = list( GUN_FIREMODE_AUTOMATIC, ) + scatter = 7 var/start_sound = 'sound/weapons/vehicles/minigun_start.ogg' var/loop_sound = 'sound/weapons/vehicles/minigun_loop.ogg' var/stop_sound = 'sound/weapons/vehicles/minigun_stop.ogg' activation_sounds = list('sound/weapons/gun_minigun.ogg') - -/* -/obj/item/hardpoint/primary/minigun/fire(mob/user, atom/A) - - var/S = 'sound/weapons/vehicles/minigun_stop.ogg' - //check how much time since last shot. 2 seconds are grace period before minigun starts to lose rotation momentum - var/t = world.time - last_shot_time - 2 SECONDS - t = round(t / 10) - if(t > 0) - chained_shots = max(chained_shots - t * 3, 1) //we lose 3 chained_shots per second - else - if(chained_shots < 11) - chained_shots++ - S = 'sound/weapons/vehicles/minigun_loop.ogg' - - if(chained_shots == 1) - playsound(get_turf(src), 'sound/weapons/vehicles/minigun_start.ogg', 40, 1) - - next_use = world.time + cooldown * owner.misc_multipliers["cooldown"] - - //how many rounds we will shoot in this burst - if(chained_shots > LAZYLEN(chain_bursts)) //5 shots at maximum rotation - t = 5 - else - t = LAZYACCESS(chain_bursts, chained_shots) - for(var/i = 1; i <= t; i++) - var/atom/T = A - if(!prob((accuracy * 100) / owner.misc_multipliers["accuracy"])) - T = get_step(get_turf(T), pick(cardinal)) - fire_projectile(user, T) - if(ammo.current_rounds <= 0) - break - sleep(2) - to_chat(user, SPAN_WARNING("[src] Ammo: [SPAN_HELPFUL(ammo ? ammo.current_rounds : 0)]/[SPAN_HELPFUL(ammo ? ammo.max_rounds : 0)] | Mags: [SPAN_HELPFUL(LAZYLEN(backup_clips))]/[SPAN_HELPFUL(max_clips)]")) - - playsound(get_turf(src), S, 40, 1) - last_shot_time = world.time -*/ + /// Active firing time to reach max spin_stage + var/spinup_time = 8 SECONDS + /// Cooldown time to reach min spin_stage + var/spindown_time = 3 SECONDS + /// Index of stage_rate + var/spin_stage = 1 + /// Shots fired per fire_delay at a particular spin_stage + var/list/stage_rate = list(1, 1, 2, 2, 3, 3, 3, 4, 4, 4, 5) + /// Fire delay for current spin_stage + var/stage_delay = 0.8 SECONDS + +/obj/item/hardpoint/primary/minigun/process(delta_time) + var/stage_rate_len = stage_rate.len + var/delta_stage = (delta_time SECONDS) * (stage_rate_len - 1) + + var/old_spin_stage = spin_stage + if(auto_firing || burst_firing) //spinup if firing + spin_stage += delta_stage / spinup_time + else //spindown if not firing + spin_stage -= delta_stage / spindown_time + spin_stage = Clamp(spin_stage, 1, stage_rate_len) + + var/old_stage_rate = stage_rate[Floor(old_spin_stage)] + var/new_stage_rate = stage_rate[Floor(spin_stage)] + + if(old_stage_rate != new_stage_rate) + stage_delay = fire_delay / new_stage_rate + SEND_SIGNAL(src, COMSIG_GUN_AUTOFIREDELAY_MODIFIED, stage_delay) + + if(spin_stage <= 1) + spin_stage = 1 + STOP_PROCESSING(SSobj, src) + +/obj/item/hardpoint/primary/minigun/handle_fire() + . = ..() + + if((. & AUTOFIRE_CONTINUE)) + COOLDOWN_START(src, fire_cooldown, stage_delay) + START_PROCESSING(SSobj, src) diff --git a/code/modules/vehicles/hardpoints/secondary/cupola.dm b/code/modules/vehicles/hardpoints/secondary/cupola.dm index 4fd119664169..9fbc6b379d3c 100644 --- a/code/modules/vehicles/hardpoints/secondary/cupola.dm +++ b/code/modules/vehicles/hardpoints/secondary/cupola.dm @@ -8,10 +8,8 @@ activation_sounds = list('sound/weapons/gun_smartgun1.ogg', 'sound/weapons/gun_smartgun2.ogg', 'sound/weapons/gun_smartgun3.ogg', 'sound/weapons/gun_smartgun4.ogg') health = 350 - cooldown = 15 - accuracy = 0.9 + //accuracy = 0.9 firing_arc = 120 - //var/burst_amount = 3 origins = list(0, -2) @@ -32,6 +30,7 @@ gun_firemode_list = list( GUN_FIREMODE_BURSTFIRE, ) + scatter = 3 /obj/item/hardpoint/secondary/m56cupola/set_bullet_traits() ..() diff --git a/code/modules/vehicles/hardpoints/secondary/flamer.dm b/code/modules/vehicles/hardpoints/secondary/flamer.dm index 770018f6d591..1bc9f52b1e22 100644 --- a/code/modules/vehicles/hardpoints/secondary/flamer.dm +++ b/code/modules/vehicles/hardpoints/secondary/flamer.dm @@ -8,8 +8,7 @@ activation_sounds = list('sound/weapons/vehicles/flamethrower.ogg') health = 300 - cooldown = 30 - accuracy = 0.68 + //accuracy = 0.68 firing_arc = 120 origins = list(0, -2) @@ -27,21 +26,21 @@ "4" = list(3, 0), "8" = list(-3, 18) ) + scatter = 6 fire_delay = 3.0 SECONDS -/obj/item/hardpoint/secondary/small_flamer/fire_shot(atom/target, mob/living/user, params) - //offset fire origin from lower-left corner - var/turf/origin_turf = get_turf(src) - origin_turf = get_offset_target_turf(origin_turf, origins[1], origins[2]) +/obj/item/hardpoint/secondary/small_flamer/handle_fire(atom/target, mob/living/user, params) + var/turf/origin_turf = get_origin_turf() var/distance = get_dist(origin_turf, get_turf(target)) var/fire_amount = min(ammo.current_rounds, distance+1, max_range) + ammo.current_rounds -= fire_amount new /obj/flamer_fire(origin_turf, create_cause_data(initial(name), user), null, fire_amount, null, FLAMESHAPE_LINE, target, CALLBACK(src, PROC_REF(display_ammo), user)) - ammo.current_rounds -= fire_amount play_firing_sounds() COOLDOWN_START(src, fire_cooldown, fire_delay) + return AUTOFIRE_CONTINUE diff --git a/code/modules/vehicles/hardpoints/secondary/frontal_cannon.dm b/code/modules/vehicles/hardpoints/secondary/frontal_cannon.dm index 31260bff4601..5e16eb76e46d 100644 --- a/code/modules/vehicles/hardpoints/secondary/frontal_cannon.dm +++ b/code/modules/vehicles/hardpoints/secondary/frontal_cannon.dm @@ -11,8 +11,7 @@ damage_multiplier = 0.11 health = 350 - cooldown = 16 - accuracy = 0.8 + //accuracy = 0.8 firing_arc = 120 origins = list(0, -2) @@ -31,15 +30,12 @@ "8" = list(-62, -26) ) - fire_delay = 0.5 SECONDS - burst_amount = 4 - burst_delay = 0.3 SECONDS - extra_delay = 0.4 SECONDS - gun_firemode = GUN_FIREMODE_BURSTFIRE + fire_delay = 0.3 SECONDS + gun_firemode = GUN_FIREMODE_AUTOMATIC gun_firemode_list = list( - GUN_FIREMODE_BURSTFIRE, GUN_FIREMODE_AUTOMATIC, ) + scatter = 4 /obj/item/hardpoint/secondary/frontalcannon/set_bullet_traits() ..() diff --git a/code/modules/vehicles/hardpoints/secondary/grenade_launcher.dm b/code/modules/vehicles/hardpoints/secondary/grenade_launcher.dm index 7e5a9298d1b9..ca4915a40dcc 100644 --- a/code/modules/vehicles/hardpoints/secondary/grenade_launcher.dm +++ b/code/modules/vehicles/hardpoints/secondary/grenade_launcher.dm @@ -8,8 +8,7 @@ activation_sounds = list('sound/weapons/gun_m92_attachable.ogg') health = 500 - cooldown = 30 - accuracy = 0.4 + //accuracy = 0.4 firing_arc = 90 var/max_range = 7 @@ -26,6 +25,7 @@ "4" = list(6, 0), "8" = list(-6, 17) ) + scatter = 10 fire_delay = 3.0 SECONDS @@ -35,13 +35,10 @@ BULLET_TRAIT_ENTRY(/datum/element/bullet_trait_iff) )) -/obj/item/hardpoint/secondary/grenade_launcher/can_activate(mob/user, atom/A) - if(!..()) - return FALSE - +/obj/item/hardpoint/secondary/grenade_launcher/try_fire(mob/user, atom/A) var/turf/origin_turf = get_origin_turf() if(origin_turf == get_turf(A)) to_chat(user, SPAN_WARNING("The target is too close.")) - return FALSE + return NONE - return TRUE + return ..() diff --git a/code/modules/vehicles/hardpoints/secondary/tow.dm b/code/modules/vehicles/hardpoints/secondary/tow.dm index 00a492566de7..f9697b94043e 100644 --- a/code/modules/vehicles/hardpoints/secondary/tow.dm +++ b/code/modules/vehicles/hardpoints/secondary/tow.dm @@ -7,8 +7,7 @@ disp_icon_state = "towlauncher" health = 500 - cooldown = 150 - accuracy = 0.8 + //accuracy = 0.8 firing_arc = 60 origins = list(0, -2) @@ -35,4 +34,5 @@ gun_firemode_list = list( GUN_FIREMODE_SEMIAUTO, ) + scatter = 4 diff --git a/code/modules/vehicles/hardpoints/special/firing_port_weapon.dm b/code/modules/vehicles/hardpoints/special/firing_port_weapon.dm index 015b0b215164..76917580bb9f 100644 --- a/code/modules/vehicles/hardpoints/special/firing_port_weapon.dm +++ b/code/modules/vehicles/hardpoints/special/firing_port_weapon.dm @@ -10,8 +10,7 @@ activation_sounds = list('sound/weapons/gun_smartgun1.ogg', 'sound/weapons/gun_smartgun2.ogg', 'sound/weapons/gun_smartgun3.ogg', 'sound/weapons/gun_smartgun4.ogg') health = 100 - cooldown = 10 - accuracy = 0.9 + //accuracy = 0.9 firing_arc = 120 //FPWs reload automatically var/reloading = FALSE @@ -29,15 +28,12 @@ underlayer_north_muzzleflash = TRUE - fire_delay = 0.4 SECONDS - burst_amount = 3 - burst_delay = 0.3 SECONDS - extra_delay = -0.2 SECONDS - gun_firemode = GUN_FIREMODE_BURSTFIRE + fire_delay = 0.3 SECONDS + gun_firemode = GUN_FIREMODE_AUTOMATIC gun_firemode_list = list( - GUN_FIREMODE_BURSTFIRE, GUN_FIREMODE_AUTOMATIC, ) + scatter = 3 /obj/item/hardpoint/special/firing_port_weapon/set_bullet_traits() ..() @@ -58,46 +54,6 @@ return data - -/obj/item/hardpoint/special/firing_port_weapon/can_activate(mob/user, atom/A) - if(!owner) - return FALSE - - var/seat = owner.get_mob_seat(user) - if(!seat) - return FALSE - - if(seat != allowed_seat) - to_chat(user, SPAN_WARNING("Only [allowed_seat] can use [name].")) - return FALSE - - //FPW stop working at 50% hull - if(owner.health < initial(owner.health) * 0.5) - to_chat(user, SPAN_WARNING("\The [owner]'s hull is too damaged!")) - return FALSE - - if(world.time < next_use) - if(cooldown >= 20) //filter out guns with high firerate to prevent message spam. - to_chat(user, SPAN_WARNING("You need to wait [SPAN_HELPFUL((next_use - world.time) / 10)] seconds before [name] can be used again.")) - return FALSE - - if(reloading) - to_chat(user, SPAN_NOTICE("\The [name] is reloading. Wait [SPAN_HELPFUL("[((reload_time_started + reload_time - world.time) / 10)]")] seconds.")) - return FALSE - - if(ammo && ammo.current_rounds <= 0) - if(reloading) - to_chat(user, SPAN_WARNING("\The [name] is out of ammo! You have to wait [(reload_time_started + reload_time - world.time) / 10] seconds before it reloads!")) - else - start_auto_reload(user) - return FALSE - - if(!in_firing_arc(A)) - to_chat(user, SPAN_WARNING("The target is not within your firing arc!")) - return FALSE - - return TRUE - /obj/item/hardpoint/special/firing_port_weapon/reload(mob/user) if(!ammo) ammo = new /obj/item/ammo_magazine/hardpoint/firing_port_weapon @@ -126,6 +82,9 @@ return FALSE /obj/item/hardpoint/special/firing_port_weapon/try_fire(atom/target, mob/living/user, params) + if(!owner) + return NONE + //FPW stop working at 50% hull if(owner.health < initial(owner.health) * 0.5) to_chat(user, SPAN_WARNING("\The [owner]'s hull is too damaged!")) @@ -135,12 +94,19 @@ to_chat(user, SPAN_WARNING("You need a free hand to use \the [name].")) return - if(ammo.current_rounds <= 0) - start_auto_reload(user) - return - if(reloading) to_chat(user, SPAN_NOTICE("\The [name] is reloading. Wait [SPAN_HELPFUL("[((reload_time_started + reload_time - world.time) / 10)]")] seconds.")) - return FALSE + return NONE + + if(ammo && ammo.current_rounds <= 0) + if(reloading) + to_chat(user, SPAN_WARNING("\The [name] is out of ammo! You have to wait [(reload_time_started + reload_time - world.time) / 10] seconds before it reloads!")) + else + start_auto_reload(user) + return NONE + + if(!in_firing_arc(target)) + to_chat(user, SPAN_WARNING("The target is not within your firing arc!")) + return NONE - return ..() + return handle_fire(target, user, params) diff --git a/code/modules/vehicles/hardpoints/support/artillery.dm b/code/modules/vehicles/hardpoints/support/artillery.dm index 033004852a2f..62f977ad3288 100644 --- a/code/modules/vehicles/hardpoints/support/artillery.dm +++ b/code/modules/vehicles/hardpoints/support/artillery.dm @@ -14,8 +14,7 @@ var/view_buff = 10 //This way you can VV for more or less fun var/view_tile_offset = 7 -// /obj/item/hardpoint/support/artillery_module/activate(mob/user, atom/A) -/obj/item/hardpoint/support/artillery_module/crew_mousedown(mob/user, atom/A) +/obj/item/hardpoint/support/artillery_module/handle_fire(atom/target, mob/living/user, params) if(!user.client) return @@ -63,8 +62,9 @@ user.client.pixel_y = 0 is_active = FALSE -/obj/item/hardpoint/support/artillery_module/can_activate() +/obj/item/hardpoint/support/artillery_module/try_fire(target, user, params) if(health <= 0) to_chat(usr, SPAN_WARNING("\The [src] is broken!")) - return FALSE - return TRUE + return NONE + + return handle_fire(target, user, params) diff --git a/code/modules/vehicles/hardpoints/support/flare.dm b/code/modules/vehicles/hardpoints/support/flare.dm index 184c148197b1..28d341ac9cb3 100644 --- a/code/modules/vehicles/hardpoints/support/flare.dm +++ b/code/modules/vehicles/hardpoints/support/flare.dm @@ -13,8 +13,7 @@ activatable = TRUE health = 500 - cooldown = 30 - accuracy = 0.7 + //accuracy = 0.7 firing_arc = 120 origins = list(0, -2) @@ -38,6 +37,7 @@ gun_firemode_list = list( GUN_FIREMODE_SEMIAUTO, ) + scatter = 6 /obj/item/hardpoint/support/flare_launcher/set_bullet_traits() ..() diff --git a/code/modules/vehicles/multitile/multitile_interaction.dm b/code/modules/vehicles/multitile/multitile_interaction.dm index 0bd9f3c130d0..4b48c8e32948 100644 --- a/code/modules/vehicles/multitile/multitile_interaction.dm +++ b/code/modules/vehicles/multitile/multitile_interaction.dm @@ -344,12 +344,11 @@ if(!seat) return - var/obj/item/hardpoint/HP = active_hp[seat] - if(!HP) - to_chat(source, SPAN_WARNING("Please select an active hardpoint first.")) + var/obj/item/hardpoint/hardpoint = active_hp[seat] + if(!hardpoint) return - HP.crew_mouseup(source, object, location, control, params) + hardpoint.stop_fire(source, object, location, control, params) /obj/vehicle/multitile/proc/crew_mousedrag(datum/source, atom/src_object, atom/over_object, turf/src_location, turf/over_location, src_control, over_control, params) SIGNAL_HANDLER @@ -357,12 +356,11 @@ if(!seat) return - var/obj/item/hardpoint/HP = active_hp[seat] - if(!HP) - to_chat(source, SPAN_WARNING("Please select an active hardpoint first.")) + var/obj/item/hardpoint/hardpoint = active_hp[seat] + if(!hardpoint) return - HP.crew_mousedrag(source, src_object, over_object, src_location, over_location, src_control, over_control, params) + hardpoint.change_target(source, src_object, over_object, src_location, over_location, src_control, over_control, params) /obj/vehicle/multitile/proc/crew_mousedown(datum/source, atom/object, turf/location, control, params) SIGNAL_HANDLER @@ -370,16 +368,12 @@ if(!seat) return - var/obj/item/hardpoint/HP = active_hp[seat] - if(!HP) + var/obj/item/hardpoint/hardpoint = active_hp[seat] + if(!hardpoint) to_chat(source, SPAN_WARNING("Please select an active hardpoint first.")) return - if(!HP.can_activate(source, object)) - return - - //HP.activate(source, object) - HP.crew_mousedown(source, object, location, control, params) + hardpoint.start_fire(source, object, location, control, params) /* /obj/vehicle/multitile/handle_click(mob/living/user, atom/A, list/mods) diff --git a/code/modules/vehicles/multitile/multitile_verbs.dm b/code/modules/vehicles/multitile/multitile_verbs.dm index fc79a6a3b717..aba9ee03ca68 100644 --- a/code/modules/vehicles/multitile/multitile_verbs.dm +++ b/code/modules/vehicles/multitile/multitile_verbs.dm @@ -377,6 +377,7 @@ to_chat(user, SPAN_WARNING("Warning. No FPW for [seat] found, tell a dev!")) +/* /obj/vehicle/multitile/proc/cycle_firemode() set name = "Cycle Firemode" set desc = "Cycles through your gun's firemodes." @@ -403,3 +404,4 @@ return hardpoint.do_toggle_firemode(usr) +*/ From 8711e8552f84573c4ebd2793bec5d0ffd73bbc99 Mon Sep 17 00:00:00 2001 From: Doubleumc Date: Mon, 6 Nov 2023 23:56:08 -0500 Subject: [PATCH 07/21] stop fire when switching hps & unbuckling --- code/modules/vehicles/hardpoints/hardpoint.dm | 88 +++++++++++-------- .../vehicles/hardpoints/holder/tank_turret.dm | 8 +- .../vehicles/hardpoints/primary/minigun.dm | 31 ++++--- .../hardpoints/special/firing_port_weapon.dm | 4 +- .../vehicles/interior/interactable/seats.dm | 6 +- code/modules/vehicles/multitile/multitile.dm | 7 ++ .../multitile/multitile_interaction.dm | 59 ++++++++++--- .../vehicles/multitile/multitile_verbs.dm | 8 ++ 8 files changed, 146 insertions(+), 65 deletions(-) diff --git a/code/modules/vehicles/hardpoints/hardpoint.dm b/code/modules/vehicles/hardpoints/hardpoint.dm index c48a9f8178b0..1fbaf44f3743 100644 --- a/code/modules/vehicles/hardpoints/hardpoint.dm +++ b/code/modules/vehicles/hardpoints/hardpoint.dm @@ -64,9 +64,11 @@ //which seat can use this module var/allowed_seat = VEHICLE_GUNNER + /* //Cooldown on use of the hardpoint var/cooldown = 100 var/next_use = 0 + */ //whether hardpoint has activatable ability like shooting or zooming var/activatable = 0 @@ -74,11 +76,13 @@ //used to prevent welder click spam var/being_repaired = FALSE + /* //current user. We can have only one user at a time. Better never change that var/user //Accuracy of the hardpoint. (which is, in fact, a scatter. Need to change this system) var/accuracy = 1 + */ // The firing arc of this hardpoint var/firing_arc = 0 //in degrees. 0 skips whole arc of fire check @@ -117,29 +121,29 @@ //Semi-auto and full-auto. ///For regular shots, how long to wait before firing again. Use modify_fire_delay and set_fire_delay instead of modifying this on the fly - VAR_PROTECTED/fire_delay = 0 + var/fire_delay = 0 /// The multiplier for how much slower this should fire in automatic mode. 1 is normal, 1.2 is 20% slower, 2 is 100% slower, etc. Protected due to it never needing to be edited. - VAR_PROTECTED/autofire_slow_mult = 1 + var/autofire_slow_mult = 1 ///If the gun is currently auto firing. - VAR_PROTECTED/auto_firing = FALSE + var/auto_firing = FALSE //Burst fire. ///How many shots can the weapon shoot in burst? Anything less than 2 and you cannot toggle burst. Use modify_burst_amount and set_burst_amount instead of modifying this - VAR_PROTECTED/burst_amount = 1 + var/burst_amount = 1 ///The delay in between shots. Lower = less delay = faster. Use modify_burst_delay and set_burst_delay instead of modifying this - VAR_PROTECTED/burst_delay = 1 + var/burst_delay = 1 ///When burst-firing, this number is extra time before the weapon can fire again. var/extra_delay = 0 ///If the gun is currently burst firing. - VAR_PROTECTED/burst_firing = FALSE + var/burst_firing = FALSE ///Delay before fire can resume. COOLDOWN_DECLARE(fire_cooldown) /// Currently selected target to fire at. Set with set_target() - VAR_PRIVATE/atom/target + var/atom/target /// Current operator (crew) of the hardpoint. - VAR_PRIVATE/mob/hp_operator + var/mob/hp_operator //----------------------------- //------GENERAL PROCS---------- @@ -148,7 +152,7 @@ /obj/item/hardpoint/Initialize() . = ..() set_bullet_traits() - AddComponent(/datum/component/automatedfire/autofire, fire_delay, burst_delay, burst_amount, gun_firemode, autofire_slow_mult, CALLBACK(src, PROC_REF(set_burst_firing)), CALLBACK(src, PROC_REF(reset_fire)), CALLBACK(src, PROC_REF(fire_wrapper)), CALLBACK(src, PROC_REF(display_ammo)), CALLBACK(src, PROC_REF(set_auto_firing))) + AddComponent(/datum/component/automatedfire/autofire, fire_delay, burst_delay, burst_amount, gun_firemode, autofire_slow_mult, CALLBACK(src, PROC_REF(set_burst_firing)), CALLBACK(src, PROC_REF(reset_fire)), CALLBACK(src, PROC_REF(fire_wrapper)), null, CALLBACK(src, PROC_REF(set_auto_firing))) /obj/item/hardpoint/Destroy() if(owner) @@ -158,7 +162,7 @@ QDEL_NULL_LIST(backup_clips) QDEL_NULL(ammo) ammo = null - target = null + set_target(null) hp_operator = null return ..() @@ -494,15 +498,27 @@ user.visible_message(SPAN_NOTICE("[user] stops repairing \the [name]."), SPAN_NOTICE("You stop repairing \the [name]. The integrity of the module is at [SPAN_HELPFUL(round(get_integrity_percent()))]%.")) return +/// Setter proc for the automatic firing flag. +/obj/item/hardpoint/proc/set_auto_firing(auto = FALSE) + if(auto_firing != auto) + auto_firing = auto + if(!auto_firing) //just stopped auto firing + display_ammo() + hp_operator = null + /// Setter proc for the burst firing flag. /obj/item/hardpoint/proc/set_burst_firing(burst = FALSE) - burst_firing = burst + if(burst_firing != burst) + burst_firing = burst + if(!burst_firing) //just stopped burst firing + display_ammo() + hp_operator = null /// Clean all firing references. -/obj/item/hardpoint/proc/reset_fire() +/obj/item/hardpoint/proc/reset_fire() //automatic reset shots_fired = 0 set_target(null) - set_auto_firing(FALSE) //autofire automatic exit + set_auto_firing(FALSE) /// Set the target and take care of hard delete. /obj/item/hardpoint/proc/set_target(atom/object) @@ -519,10 +535,6 @@ SIGNAL_HANDLER target = get_turf(target) -/// Setter proc for the automatic firing flag. -/obj/item/hardpoint/proc/set_auto_firing(auto = FALSE) - auto_firing = auto - /// Print how much ammo is left to chat. /obj/item/hardpoint/proc/display_ammo(mob/user) if(!user) @@ -537,9 +549,7 @@ if(auto_firing || burst_firing) SEND_SIGNAL(src, COMSIG_GUN_STOP_FIRE) if(auto_firing) - //manual automatic exit - reset_fire() - display_ammo() + reset_fire() //automatic end-of-fire /// Update the target if you dragged your mouse. /obj/item/hardpoint/proc/change_target(mob/source, atom/src_object, atom/over_object, turf/src_location, turf/over_location, src_control, over_control, params) @@ -547,26 +557,32 @@ /// Check if the gun can fire and add it to bucket autofire system if needed, or just fire the gun if not. /obj/item/hardpoint/proc/start_fire(datum/source, atom/object, turf/location, control, params) + /* var/list/modifiers = params2list(params) - if(modifiers["shift"] || modifiers["middle"] || modifiers["right"]) + if(modifiers["shift"] || modifiers["ctrl"] || modifiers["alt"] || modifiers["middle"] || modifiers["right"]) return + */ - if(istype(object, /atom/movable/screen)) //don't click on UI + if(istype(object, /atom/movable/screen)) return if(QDELETED(object)) return - if(!COOLDOWN_FINISHED(src, fire_cooldown)) + if(!auto_firing && !burst_firing && !COOLDOWN_FINISHED(src, fire_cooldown)) if(max(fire_delay, burst_delay + extra_delay) >= 2.0 SECONDS) //filter out guns with high firerate to prevent message spam. - to_chat(user, SPAN_WARNING("You need to wait [SPAN_HELPFUL(COOLDOWN_SECONDSLEFT(src, fire_cooldown))] seconds before [name] can be used again.")) + to_chat(source, SPAN_WARNING("You need to wait [SPAN_HELPFUL(COOLDOWN_SECONDSLEFT(src, fire_cooldown))] seconds before [name] can be used again.")) return hp_operator = source - set_target(get_turf_on_clickcatcher(object, hp_operator, params)) + set_target(get_turf_on_clickcatcher(object, source, params)) if(gun_firemode == GUN_FIREMODE_SEMIAUTO) - try_fire(object, source, params) + var/fire_return = try_fire(object, source, params) + if(fire_return == AUTOFIRE_CONTINUE) + reset_fire() //semiauto end-of-fire + display_ammo() + hp_operator = null else SEND_SIGNAL(src, COMSIG_GUN_FIRE) @@ -620,25 +636,23 @@ if(use_muzzle_flash) muzzle_flash(Get_Angle(origin_turf, target)) - if(ammo && ammo.current_rounds <= 0) - click_empty() + set_fire_cooldown(gun_firemode) + + return AUTOFIRE_CONTINUE - //cooldown to respect intended ROF +/// Start cooldown to respect delay of firemode. +/obj/item/hardpoint/proc/set_fire_cooldown(firemode) var/cooldown_time = 0 - switch(gun_firemode) + switch(firemode) if(GUN_FIREMODE_SEMIAUTO) cooldown_time = fire_delay - //manual semiauto exit - reset_fire() - display_ammo() if(GUN_FIREMODE_BURSTFIRE) cooldown_time = burst_delay + extra_delay if(GUN_FIREMODE_AUTOMATIC) cooldown_time = fire_delay COOLDOWN_START(src, fire_cooldown, cooldown_time) - return AUTOFIRE_CONTINUE - +/// Adjust target based on random scatter angle. /obj/item/hardpoint/proc/simulate_scatter(obj/projectile/projectile_to_fire, atom/target, turf/curloc, turf/targloc) var/fire_angle = Get_Angle(curloc, targloc) var/total_scatter_angle = projectile_to_fire.scatter @@ -654,6 +668,7 @@ /obj/item/hardpoint/proc/get_origin_turf() return get_offset_target_turf(get_turf(src), origins[1], origins[2]) +/* /// Toggles the gun's firemode one down the list. /obj/item/hardpoint/proc/do_toggle_firemode(mob/user, new_firemode) if(burst_firing) //can't toggle mid burst @@ -681,7 +696,9 @@ to_chat(user, SPAN_NOTICE("[icon2html(src, user)] You switch the hardpoint to [gun_firemode].")) SEND_SIGNAL(src, COMSIG_GUN_FIRE_MODE_TOGGLE, gun_firemode) +*/ +/// Plays 'click' noise and announced to chat. Usually called when weapon empty. /obj/item/hardpoint/proc/click_empty(mob/user) if(user) to_chat(user, SPAN_WARNING("*click*")) @@ -689,6 +706,7 @@ else playsound(src, 'sound/weapons/gun_empty.ogg', 25, 1, 5) +/// Selects and plays a firing sound from the list. /obj/item/hardpoint/proc/play_firing_sounds() if(LAZYLEN(activation_sounds)) playsound(get_turf(src), pick(activation_sounds), 60, 1) diff --git a/code/modules/vehicles/hardpoints/holder/tank_turret.dm b/code/modules/vehicles/hardpoints/holder/tank_turret.dm index 78fc259a2e26..75118562e75c 100644 --- a/code/modules/vehicles/hardpoints/holder/tank_turret.dm +++ b/code/modules/vehicles/hardpoints/holder/tank_turret.dm @@ -208,12 +208,14 @@ R = locate(owner.x - 4, owner.y - 2, owner.z) if(shots_fired) - L = R + target = R + else + target = L - return handle_fire(L, user, params) + return ..() /obj/item/hardpoint/holder/tank_turret/get_origin_turf() - var/origin_turf = get_offset_target_turf(get_turf(src), origins[1], origins[2]) + var/origin_turf = ..() origin_turf = get_step(get_step(origin_turf, owner.dir), owner.dir) //this should get us tile in front of tank to prevent grenade being stuck under us. return origin_turf diff --git a/code/modules/vehicles/hardpoints/primary/minigun.dm b/code/modules/vehicles/hardpoints/primary/minigun.dm index 05ba44d7c6f2..5d89aea545dd 100644 --- a/code/modules/vehicles/hardpoints/primary/minigun.dm +++ b/code/modules/vehicles/hardpoints/primary/minigun.dm @@ -36,21 +36,29 @@ ) scatter = 7 - var/start_sound = 'sound/weapons/vehicles/minigun_start.ogg' - var/loop_sound = 'sound/weapons/vehicles/minigun_loop.ogg' - var/stop_sound = 'sound/weapons/vehicles/minigun_stop.ogg' + //var/start_sound = 'sound/weapons/vehicles/minigun_start.ogg' + //var/loop_sound = 'sound/weapons/vehicles/minigun_loop.ogg' + //var/stop_sound = 'sound/weapons/vehicles/minigun_stop.ogg' activation_sounds = list('sound/weapons/gun_minigun.ogg') - /// Active firing time to reach max spin_stage + /// Active firing time to reach max spin_stage. var/spinup_time = 8 SECONDS - /// Cooldown time to reach min spin_stage + /// Grace period before losing spin_stage. + var/spindown_grace_time = 2 SECONDS + COOLDOWN_DECLARE(spindown_grace_cooldown) + /// Cooldown time to reach min spin_stage. var/spindown_time = 3 SECONDS - /// Index of stage_rate + /// Index of stage_rate. var/spin_stage = 1 - /// Shots fired per fire_delay at a particular spin_stage + /// Shots fired per fire_delay at a particular spin_stage. var/list/stage_rate = list(1, 1, 2, 2, 3, 3, 3, 4, 4, 4, 5) - /// Fire delay for current spin_stage + /// Fire delay for current spin_stage. var/stage_delay = 0.8 SECONDS +/obj/item/hardpoint/primary/minigun/Destroy() + STOP_PROCESSING(SSobj, src) + + return ..() + /obj/item/hardpoint/primary/minigun/process(delta_time) var/stage_rate_len = stage_rate.len var/delta_stage = (delta_time SECONDS) * (stage_rate_len - 1) @@ -58,7 +66,7 @@ var/old_spin_stage = spin_stage if(auto_firing || burst_firing) //spinup if firing spin_stage += delta_stage / spinup_time - else //spindown if not firing + else if(COOLDOWN_FINISHED(src, spindown_grace_cooldown)) //spindown if not firing and after grace spin_stage -= delta_stage / spindown_time spin_stage = Clamp(spin_stage, 1, stage_rate_len) @@ -77,5 +85,8 @@ . = ..() if((. & AUTOFIRE_CONTINUE)) - COOLDOWN_START(src, fire_cooldown, stage_delay) START_PROCESSING(SSobj, src) + +/obj/item/hardpoint/primary/minigun/set_fire_cooldown() + COOLDOWN_START(src, fire_cooldown, stage_delay) + COOLDOWN_START(src, spindown_grace_cooldown, spindown_grace_time) diff --git a/code/modules/vehicles/hardpoints/special/firing_port_weapon.dm b/code/modules/vehicles/hardpoints/special/firing_port_weapon.dm index 76917580bb9f..4e333869bf9a 100644 --- a/code/modules/vehicles/hardpoints/special/firing_port_weapon.dm +++ b/code/modules/vehicles/hardpoints/special/firing_port_weapon.dm @@ -88,11 +88,11 @@ //FPW stop working at 50% hull if(owner.health < initial(owner.health) * 0.5) to_chat(user, SPAN_WARNING("\The [owner]'s hull is too damaged!")) - return FALSE + return NONE if(user.get_active_hand()) to_chat(user, SPAN_WARNING("You need a free hand to use \the [name].")) - return + return NONE if(reloading) to_chat(user, SPAN_NOTICE("\The [name] is reloading. Wait [SPAN_HELPFUL("[((reload_time_started + reload_time - world.time) / 10)]")] seconds.")) diff --git a/code/modules/vehicles/interior/interactable/seats.dm b/code/modules/vehicles/interior/interactable/seats.dm index 3f3058d0572f..c3960576e494 100644 --- a/code/modules/vehicles/interior/interactable/seats.dm +++ b/code/modules/vehicles/interior/interactable/seats.dm @@ -40,8 +40,8 @@ return if(QDELETED(buckled_mob)) - vehicle.set_seated_mob(seat, null) M.unset_interaction() + vehicle.set_seated_mob(seat, null) if(M.client) M.client.change_view(world_view_size, vehicle) M.client.pixel_x = 0 @@ -174,8 +174,8 @@ return if(QDELETED(buckled_mob)) - vehicle.set_seated_mob(seat, null) M.unset_interaction() + vehicle.set_seated_mob(seat, null) if(M.client) M.client.change_view(world_view_size, vehicle) M.client.pixel_x = 0 @@ -252,8 +252,8 @@ return if(QDELETED(buckled_mob)) - vehicle.set_seated_mob(seat, null) M.unset_interaction() + vehicle.set_seated_mob(seat, null) if(M.client) M.client.change_view(world_view_size, vehicle) M.client.pixel_x = 0 diff --git a/code/modules/vehicles/multitile/multitile.dm b/code/modules/vehicles/multitile/multitile.dm index c8138c5b8f86..4da772daec86 100644 --- a/code/modules/vehicles/multitile/multitile.dm +++ b/code/modules/vehicles/multitile/multitile.dm @@ -349,6 +349,13 @@ return seat return null +/// Get active hardpoint (if any) from crew. +/obj/vehicle/multitile/proc/get_mob_hp(mob/crew) + var/seat = get_mob_seat(crew) + if(seat) + return active_hp[seat] + return null + /obj/vehicle/multitile/proc/get_passengers() if(interior) return interior.get_passengers() diff --git a/code/modules/vehicles/multitile/multitile_interaction.dm b/code/modules/vehicles/multitile/multitile_interaction.dm index 4b48c8e32948..d10d4832f6b0 100644 --- a/code/modules/vehicles/multitile/multitile_interaction.dm +++ b/code/modules/vehicles/multitile/multitile_interaction.dm @@ -338,13 +338,13 @@ /obj/vehicle/multitile/on_unset_interaction(mob/user) UnregisterSignal(user, list(COMSIG_MOB_MOUSEUP, COMSIG_MOB_MOUSEDOWN, COMSIG_MOB_MOUSEDRAG)) + var/obj/item/hardpoint/hardpoint = get_mob_hp(user) + if(hardpoint) + SEND_SIGNAL(hardpoint, COMSIG_GUN_INTERRUPT_FIRE) //stop fire when crew leaves + /obj/vehicle/multitile/proc/crew_mouseup(datum/source, atom/object, turf/location, control, params) SIGNAL_HANDLER - var/seat = get_mob_seat(source) - if(!seat) - return - - var/obj/item/hardpoint/hardpoint = active_hp[seat] + var/obj/item/hardpoint/hardpoint = get_mob_hp(source) if(!hardpoint) return @@ -352,11 +352,7 @@ /obj/vehicle/multitile/proc/crew_mousedrag(datum/source, atom/src_object, atom/over_object, turf/src_location, turf/over_location, src_control, over_control, params) SIGNAL_HANDLER - var/seat = get_mob_seat(source) - if(!seat) - return - - var/obj/item/hardpoint/hardpoint = active_hp[seat] + var/obj/item/hardpoint/hardpoint = get_mob_hp(source) if(!hardpoint) return @@ -364,11 +360,50 @@ /obj/vehicle/multitile/proc/crew_mousedown(datum/source, atom/object, turf/location, control, params) SIGNAL_HANDLER + + var/list/modifiers = params2list(params) + var/seat = get_mob_seat(source) - if(!seat) + switch(seat) + if(VEHICLE_DRIVER) + if(modifiers["shift"] && !modifiers["alt"]) + //object.examine(source) + return + if(modifiers["ctrl"] && !modifiers["alt"]) + activate_horn() + return + if(VEHICLE_GUNNER) + if(modifiers["shift"] && !modifiers["middle"]) + /* + if(HAS_FLAG(vehicle_flags, VEHICLE_TOGGLE_SHIFT_CLICK_GUNNER)) + shoot_other_weapon(source, seat, object) + else + object.examine(source) + */ + return + if(modifiers["middle"] && !modifiers["shift"]) + /* + if(!HAS_FLAG(vehicle_flags, VEHICLE_TOGGLE_SHIFT_CLICK_GUNNER)) + shoot_other_weapon(source, seat, object) + */ + return + if(modifiers["alt"]) + //toggle_gyrostabilizer() + return + if(modifiers["ctrl"]) + //activate_support_module(source, seat, object) + return + if(VEHICLE_SUPPORT_GUNNER_ONE, VEHICLE_SUPPORT_GUNNER_TWO) + if(modifiers["shift"]) + //object.examine(source) + return + if(modifiers["middle"] || modifiers["alt"] || modifiers["ctrl"]) + return + + if(modifiers["shift"] || modifiers["middle"] || modifiers["right"]) return - var/obj/item/hardpoint/hardpoint = active_hp[seat] + var/obj/item/hardpoint/hardpoint = get_mob_hp(source) if(!hardpoint) to_chat(source, SPAN_WARNING("Please select an active hardpoint first.")) return diff --git a/code/modules/vehicles/multitile/multitile_verbs.dm b/code/modules/vehicles/multitile/multitile_verbs.dm index aba9ee03ca68..66a3db0bfbe6 100644 --- a/code/modules/vehicles/multitile/multitile_verbs.dm +++ b/code/modules/vehicles/multitile/multitile_verbs.dm @@ -30,6 +30,10 @@ if(!HP) return + var/obj/item/hardpoint/old_HP = V.active_hp[seat] + if(old_HP) + SEND_SIGNAL(old_HP, COMSIG_GUN_INTERRUPT_FIRE) //stop fire when switching away from HP + V.active_hp[seat] = HP var/msg = "You select \the [HP]." if(HP.ammo) @@ -66,6 +70,10 @@ if(!HP) return + var/obj/item/hardpoint/old_HP = V.active_hp[seat] + if(old_HP) + SEND_SIGNAL(old_HP, COMSIG_GUN_INTERRUPT_FIRE) //stop fire when switching away from HP + V.active_hp[seat] = HP var/msg = "You select \the [HP]." if(HP.ammo) From 1645ce50b57b866b0af089c0c582324193cc725e Mon Sep 17 00:00:00 2001 From: Doubleumc Date: Wed, 8 Nov 2023 00:42:15 -0500 Subject: [PATCH 08/21] always clears operator at end-of-fire --- code/modules/vehicles/hardpoints/hardpoint.dm | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/code/modules/vehicles/hardpoints/hardpoint.dm b/code/modules/vehicles/hardpoints/hardpoint.dm index 1fbaf44f3743..d23d43f34395 100644 --- a/code/modules/vehicles/hardpoints/hardpoint.dm +++ b/code/modules/vehicles/hardpoints/hardpoint.dm @@ -519,6 +519,7 @@ shots_fired = 0 set_target(null) set_auto_firing(FALSE) + hp_operator = null /// Set the target and take care of hard delete. /obj/item/hardpoint/proc/set_target(atom/object) @@ -582,7 +583,7 @@ if(fire_return == AUTOFIRE_CONTINUE) reset_fire() //semiauto end-of-fire display_ammo() - hp_operator = null + hp_operator = null else SEND_SIGNAL(src, COMSIG_GUN_FIRE) From 75a295e434d69c12a687327648188ac536959d4e Mon Sep 17 00:00:00 2001 From: Doubleumc Date: Wed, 8 Nov 2023 01:06:27 -0500 Subject: [PATCH 09/21] re-introduces muzzle los check --- code/modules/vehicles/hardpoints/hardpoint.dm | 27 ++++++++++--------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/code/modules/vehicles/hardpoints/hardpoint.dm b/code/modules/vehicles/hardpoints/hardpoint.dm index d23d43f34395..2a7ca1115197 100644 --- a/code/modules/vehicles/hardpoints/hardpoint.dm +++ b/code/modules/vehicles/hardpoints/hardpoint.dm @@ -300,14 +300,12 @@ return data -/* -// Traces backwards from the gun origin to the vehicle to check for obstacles between the vehicle and the muzzle -/obj/item/hardpoint/proc/clear_los(atom/A) - +/// Traces backwards from the gun origin to the vehicle to check for obstacles between the vehicle and the muzzle. +/obj/item/hardpoint/proc/clear_los() if(origins[1] == 0 && origins[2] == 0) //skipping check for modules we don't need this return TRUE - var/turf/muzzle_turf = locate(owner.x + origins[1], owner.y + origins[2], owner.z) + var/turf/muzzle_turf = get_origin_turf() var/turf/checking_turf = muzzle_turf while(!(owner in checking_turf)) @@ -316,31 +314,30 @@ return FALSE // Ensure that we can pass over all objects in the turf - for(var/obj/O in checking_turf) + for(var/obj/object in checking_turf) // Since vehicles are multitile the - if(O == owner) + if(object == owner) continue // Non-dense objects are irrelevant - if(!O.density) + if(!object.density) continue // Make sure we can pass object from all directions - if(!(O.pass_flags.flags_can_pass_all & PASS_OVER_THROW_ITEM)) - if(!(O.flags_atom & ON_BORDER)) + if(!HAS_FLAG(object.pass_flags.flags_can_pass_all, PASS_OVER_THROW_ITEM)) + if(!HAS_FLAG(object.flags_atom, ON_BORDER)) return FALSE //If we're behind the object, check the behind pass flags - else if(dir == O.dir && !(O.pass_flags.flags_can_pass_behind & PASS_OVER_THROW_ITEM)) + else if(dir == object.dir && !HAS_FLAG(object.pass_flags.flags_can_pass_behind, PASS_OVER_THROW_ITEM)) return FALSE //If we're in front, check front pass flags - else if(dir == turn(O.dir, 180) && !(O.pass_flags.flags_can_pass_front & PASS_OVER_THROW_ITEM)) + else if(dir == turn(object.dir, 180) && !HAS_FLAG(object.pass_flags.flags_can_pass_front, PASS_OVER_THROW_ITEM)) return FALSE // Trace back towards the vehicle checking_turf = get_step(checking_turf, turn(dir,180)) return TRUE -*/ //----------------------------- //------INTERACTION PROCS---------- @@ -613,6 +610,10 @@ to_chat(user, SPAN_WARNING("The target is not within your firing arc!")) return NONE + if(!clear_los()) + to_chat(user, SPAN_WARNING("The muzzle is obstructed!")) + return NONE + return handle_fire(target, user, params) /// Actually fires the gun, sets up the projectile and fires it. From 39a67a2078ad784dd49aace7baae8617493994cb Mon Sep 17 00:00:00 2001 From: Doubleumc Date: Wed, 8 Nov 2023 03:54:29 -0500 Subject: [PATCH 10/21] some more documentation --- code/modules/vehicles/hardpoints/hardpoint.dm | 106 ++++++++---------- code/modules/vehicles/multitile/multitile.dm | 4 +- .../multitile/multitile_interaction.dm | 5 +- 3 files changed, 51 insertions(+), 64 deletions(-) diff --git a/code/modules/vehicles/hardpoints/hardpoint.dm b/code/modules/vehicles/hardpoints/hardpoint.dm index 2a7ca1115197..877cda9df2aa 100644 --- a/code/modules/vehicles/hardpoints/hardpoint.dm +++ b/code/modules/vehicles/hardpoints/hardpoint.dm @@ -1,22 +1,20 @@ -/* - Hardpoints are any items that attach to a base vehicle, such as wheels/treads, support systems and guns -*/ - +/** + * Hardpoints are any items that attach to a base vehicle, such as wheels/treads, support systems and guns + */ /obj/item/hardpoint //------MAIN VARS---------- - // Which slot is this hardpoint in - // Purely to check for conflicting hardpoints + /// Which slot is this hardpoint in. Purely to check for conflicting hardpoints. var/slot - // The vehicle this hardpoint is installed on + /// The vehicle this hardpoint is installed on. var/obj/vehicle/multitile/owner health = 100 w_class = SIZE_LARGE - // Determines how much of any incoming damage is actually taken + /// Determines how much of any incoming damage is actually taken. var/damage_multiplier = 1 - // Origin coords of the hardpoint relative to the vehicle + /// Origin coords of the hardpoint relative to the vehicle. var/list/origins = list(0, 0) var/list/buff_multipliers @@ -32,13 +30,13 @@ var/disp_icon //This also differentiates tank vs apc vs other var/disp_icon_state - // List of pixel offsets for each direction + /// List of pixel offsets for each direction. var/list/px_offsets - //visual layer of hardpoint when on vehicle + /// Visual layer of hardpoint when on vehicle. var/hdpt_layer = HDPT_LAYER_WHEELS - // List of offsets for where to place the muzzle flash for each direction + /// List of offsets for where to place the muzzle flash for each direction. var/list/muzzle_flash_pos = list( "1" = list(0, 0), "2" = list(0, 0), @@ -54,37 +52,23 @@ var/const_mz_offset_y = 0 //------SOUNDS VARS---------- - // Sounds to play when the module activated/fired + /// Sounds to play when the module activated/fired. var/list/activation_sounds //------INTERACTION VARS---------- - //which seat can use this module + /// Which seat can use this module. var/allowed_seat = VEHICLE_GUNNER - /* - //Cooldown on use of the hardpoint - var/cooldown = 100 - var/next_use = 0 - */ - - //whether hardpoint has activatable ability like shooting or zooming + /// Whether hardpoint has activatable ability like shooting or zooming. var/activatable = 0 - //used to prevent welder click spam + /// Used to prevent welder click spam. var/being_repaired = FALSE - /* - //current user. We can have only one user at a time. Better never change that - var/user - - //Accuracy of the hardpoint. (which is, in fact, a scatter. Need to change this system) - var/accuracy = 1 - */ - - // The firing arc of this hardpoint + /// The firing arc of this hardpoint. var/firing_arc = 0 //in degrees. 0 skips whole arc of fire check // Muzzleflash @@ -95,52 +79,51 @@ //------AMMUNITION VARS---------- - //Currently loaded ammo that we shoot from + /// Currently loaded ammo that we shoot from. var/obj/item/ammo_magazine/hardpoint/ammo - //spare magazines that we can reload from + /// Spare magazines that we can reload from. var/list/backup_clips - //maximum amount of spare mags + /// Maximum amount of spare mags. var/max_clips = 0 /// An assoc list in the format list(/datum/element/bullet_trait_to_give = list(...args)) - /// that will be given to a projectile fired from the hardpoint + /// that will be given to a projectile fired from the hardpoint. var/list/list/traits_to_give - ///How much the bullet scatters when fired. + /// How much the bullet scatters when fired, in degrees. var/scatter = 0 - ///How many bullets the gun fired while burst firing/auto firing. + /// How many bullets the gun fired while burst firing/auto firing. var/shots_fired = 0 + /// Delay before a new firing sequence can start. + COOLDOWN_DECLARE(fire_cooldown) - //Firemodes. - ///Current selected firemode of the gun. + // Firemodes. + /// Current selected firemode of the gun. var/gun_firemode = GUN_FIREMODE_SEMIAUTO - ///List of allowed firemodes. + /// List of allowed firemodes. var/list/gun_firemode_list = list( GUN_FIREMODE_SEMIAUTO, ) - //Semi-auto and full-auto. - ///For regular shots, how long to wait before firing again. Use modify_fire_delay and set_fire_delay instead of modifying this on the fly + // Semi-auto and full-auto. + /// For regular shots, how long to wait before firing again. Use modify_fire_delay and set_fire_delay instead of modifying this on the fly var/fire_delay = 0 /// The multiplier for how much slower this should fire in automatic mode. 1 is normal, 1.2 is 20% slower, 2 is 100% slower, etc. Protected due to it never needing to be edited. var/autofire_slow_mult = 1 - ///If the gun is currently auto firing. + /// If the gun is currently auto firing. var/auto_firing = FALSE - //Burst fire. - ///How many shots can the weapon shoot in burst? Anything less than 2 and you cannot toggle burst. Use modify_burst_amount and set_burst_amount instead of modifying this + // Burst fire. + /// How many shots can the weapon shoot in burst? Anything less than 2 and you cannot toggle burst. Use modify_burst_amount and set_burst_amount instead of modifying this var/burst_amount = 1 - ///The delay in between shots. Lower = less delay = faster. Use modify_burst_delay and set_burst_delay instead of modifying this + /// The delay in between shots. Lower = less delay = faster. Use modify_burst_delay and set_burst_delay instead of modifying this var/burst_delay = 1 - ///When burst-firing, this number is extra time before the weapon can fire again. + /// When burst-firing, this number is extra time before the weapon can fire again. var/extra_delay = 0 - ///If the gun is currently burst firing. + /// If the gun is currently burst firing. var/burst_firing = FALSE - ///Delay before fire can resume. - COOLDOWN_DECLARE(fire_cooldown) - - /// Currently selected target to fire at. Set with set_target() + /// Currently selected target to fire at. Set with set_target(). var/atom/target /// Current operator (crew) of the hardpoint. var/mob/hp_operator @@ -161,10 +144,8 @@ owner = null QDEL_NULL_LIST(backup_clips) QDEL_NULL(ammo) - ammo = null set_target(null) hp_operator = null - return ..() /obj/item/hardpoint/ex_act(severity) @@ -499,7 +480,7 @@ /obj/item/hardpoint/proc/set_auto_firing(auto = FALSE) if(auto_firing != auto) auto_firing = auto - if(!auto_firing) //just stopped auto firing + if(!auto_firing) //end-of-fire, show changed ammo and clear firer display_ammo() hp_operator = null @@ -507,16 +488,16 @@ /obj/item/hardpoint/proc/set_burst_firing(burst = FALSE) if(burst_firing != burst) burst_firing = burst - if(!burst_firing) //just stopped burst firing + if(!burst_firing) //end-of-fire, show changed ammo and clear firer display_ammo() hp_operator = null /// Clean all firing references. -/obj/item/hardpoint/proc/reset_fire() //automatic reset +/obj/item/hardpoint/proc/reset_fire() shots_fired = 0 set_target(null) - set_auto_firing(FALSE) - hp_operator = null + set_auto_firing(FALSE) //on abnormal exits automatic fire doesn't call set_auto_firing() + hp_operator = null //clear 'firer' when autofire exits before first shot /// Set the target and take care of hard delete. /obj/item/hardpoint/proc/set_target(atom/object) @@ -547,7 +528,7 @@ if(auto_firing || burst_firing) SEND_SIGNAL(src, COMSIG_GUN_STOP_FIRE) if(auto_firing) - reset_fire() //automatic end-of-fire + reset_fire() //automatic fire doesn't reset itself from COMSIG_GUN_STOP_FIRE /// Update the target if you dragged your mouse. /obj/item/hardpoint/proc/change_target(mob/source, atom/src_object, atom/over_object, turf/src_location, turf/over_location, src_control, over_control, params) @@ -577,8 +558,9 @@ if(gun_firemode == GUN_FIREMODE_SEMIAUTO) var/fire_return = try_fire(object, source, params) + //end-of-fire, show ammo (if changed) and clear firer if(fire_return == AUTOFIRE_CONTINUE) - reset_fire() //semiauto end-of-fire + reset_fire() display_ammo() hp_operator = null else @@ -626,7 +608,7 @@ // turf-targeted projectiles are fired without scatter, because proc would raytrace them further away var/ammo_flags = projectile_to_fire.ammo.flags_ammo_behavior | projectile_to_fire.projectile_override_flags - if(!HAS_FLAG(ammo_flags, AMMO_HITS_TARGET_TURF) && !HAS_FLAG(ammo_flags, AMMO_EXPLOSIVE)) + if(!HAS_FLAG(ammo_flags, AMMO_HITS_TARGET_TURF) && !HAS_FLAG(ammo_flags, AMMO_EXPLOSIVE)) //AMMO_EXPLOSIVE is also a turf-targeted projectile projectile_to_fire.scatter = scatter target = simulate_scatter(projectile_to_fire, target, origin_turf, get_turf(target), user) diff --git a/code/modules/vehicles/multitile/multitile.dm b/code/modules/vehicles/multitile/multitile.dm index 4da772daec86..f3b7be510b08 100644 --- a/code/modules/vehicles/multitile/multitile.dm +++ b/code/modules/vehicles/multitile/multitile.dm @@ -340,16 +340,18 @@ M.reset_view(src) give_action(M, /datum/action/human_action/vehicle_unbuckle) +/// Get crewmember of seat. /obj/vehicle/multitile/proc/get_seat_mob(seat) return seats[seat] +/// Get seat of crewmember. /obj/vehicle/multitile/proc/get_mob_seat(mob/M) for(var/seat in seats) if(seats[seat] == M) return seat return null -/// Get active hardpoint (if any) from crew. +/// Get active hardpoint of crewmember. /obj/vehicle/multitile/proc/get_mob_hp(mob/crew) var/seat = get_mob_seat(crew) if(seat) diff --git a/code/modules/vehicles/multitile/multitile_interaction.dm b/code/modules/vehicles/multitile/multitile_interaction.dm index d10d4832f6b0..496267bc33ad 100644 --- a/code/modules/vehicles/multitile/multitile_interaction.dm +++ b/code/modules/vehicles/multitile/multitile_interaction.dm @@ -340,8 +340,9 @@ var/obj/item/hardpoint/hardpoint = get_mob_hp(user) if(hardpoint) - SEND_SIGNAL(hardpoint, COMSIG_GUN_INTERRUPT_FIRE) //stop fire when crew leaves + SEND_SIGNAL(hardpoint, COMSIG_GUN_INTERRUPT_FIRE) //abort fire when crew leaves +/// Relays crew mouse release to active hardpoint. /obj/vehicle/multitile/proc/crew_mouseup(datum/source, atom/object, turf/location, control, params) SIGNAL_HANDLER var/obj/item/hardpoint/hardpoint = get_mob_hp(source) @@ -350,6 +351,7 @@ hardpoint.stop_fire(source, object, location, control, params) +/// Relays crew mouse movement to active hardpoint. /obj/vehicle/multitile/proc/crew_mousedrag(datum/source, atom/src_object, atom/over_object, turf/src_location, turf/over_location, src_control, over_control, params) SIGNAL_HANDLER var/obj/item/hardpoint/hardpoint = get_mob_hp(source) @@ -358,6 +360,7 @@ hardpoint.change_target(source, src_object, over_object, src_location, over_location, src_control, over_control, params) +/// Checks for special control keybinds, else relays crew mouse press to active hardpoint. /obj/vehicle/multitile/proc/crew_mousedown(datum/source, atom/object, turf/location, control, params) SIGNAL_HANDLER From e06a9c7d8eb8952f5daecb52e2cc563e0acf233d Mon Sep 17 00:00:00 2001 From: Doubleumc Date: Wed, 8 Nov 2023 05:58:44 -0500 Subject: [PATCH 11/21] minor reorganization --- .../vehicles/hardpoints/holder/tank_turret.dm | 59 ++----------------- .../vehicles/hardpoints/primary/autocannon.dm | 5 +- .../hardpoints/primary/dual_cannon.dm | 5 +- .../vehicles/hardpoints/primary/flamer.dm | 3 +- .../vehicles/hardpoints/primary/ltb.dm | 7 +-- .../vehicles/hardpoints/primary/minigun.dm | 5 +- .../vehicles/hardpoints/secondary/cupola.dm | 9 ++- .../vehicles/hardpoints/secondary/flamer.dm | 3 +- .../hardpoints/secondary/frontal_cannon.dm | 5 +- .../hardpoints/secondary/grenade_launcher.dm | 3 +- .../vehicles/hardpoints/secondary/tow.dm | 7 +-- .../hardpoints/special/firing_port_weapon.dm | 5 +- .../vehicles/hardpoints/support/flare.dm | 7 +-- 13 files changed, 24 insertions(+), 99 deletions(-) diff --git a/code/modules/vehicles/hardpoints/holder/tank_turret.dm b/code/modules/vehicles/hardpoints/holder/tank_turret.dm index 75118562e75c..896628e609bb 100644 --- a/code/modules/vehicles/hardpoints/holder/tank_turret.dm +++ b/code/modules/vehicles/hardpoints/holder/tank_turret.dm @@ -13,7 +13,6 @@ density = TRUE //come on, it's huge activatable = TRUE - //accuracy = 0.8 ammo = new /obj/item/ammo_magazine/hardpoint/turret_smoke max_clips = 2 @@ -59,14 +58,14 @@ // Used during the windup var/rotating = FALSE - burst_amount = 2 - burst_delay = 1.0 SECONDS - extra_delay = 13.0 SECONDS + scatter = 4 gun_firemode = GUN_FIREMODE_BURSTFIRE gun_firemode_list = list( GUN_FIREMODE_BURSTFIRE, ) - scatter = 4 + burst_amount = 2 + burst_delay = 1.0 SECONDS + extra_delay = 13.0 SECONDS /obj/item/hardpoint/holder/tank_turret/update_icon() var/broken = (health <= 0) @@ -218,53 +217,3 @@ var/origin_turf = ..() origin_turf = get_step(get_step(origin_turf, owner.dir), owner.dir) //this should get us tile in front of tank to prevent grenade being stuck under us. return origin_turf - -/* -/obj/item/hardpoint/holder/tank_turret/fire(mob/user, atom/A) - if(ammo.current_rounds <= 0) - return - - next_use = world.time + cooldown - - var/turf/L - var/turf/R - switch(owner.dir) - if(NORTH) - L = locate(owner.x - 2, owner.y + 4, owner.z) - R = locate(owner.x + 2, owner.y + 4, owner.z) - if(SOUTH) - L = locate(owner.x + 2, owner.y - 4, owner.z) - R = locate(owner.x - 2, owner.y - 4, owner.z) - if(EAST) - L = locate(owner.x + 4, owner.y + 2, owner.z) - R = locate(owner.x + 4, owner.y - 2, owner.z) - else - L = locate(owner.x - 4, owner.y + 2, owner.z) - R = locate(owner.x - 4, owner.y - 2, owner.z) - - if(LAZYLEN(activation_sounds)) - playsound(get_turf(src), pick(activation_sounds), 60, 1) - fire_projectile(user, L) - - sleep(10) - - if(LAZYLEN(activation_sounds)) - playsound(get_turf(src), pick(activation_sounds), 60, 1) - fire_projectile(user, R) - - to_chat(user, SPAN_WARNING("Smoke Screen uses left: [SPAN_HELPFUL(ammo ? ammo.current_rounds / 2 : 0)]/[SPAN_HELPFUL(ammo ? ammo.max_rounds / 2 : 0)] | Mags: [SPAN_HELPFUL(LAZYLEN(backup_clips))]/[SPAN_HELPFUL(max_clips)]")) -*/ - -/* -/obj/item/hardpoint/holder/tank_turret/fire_projectile(mob/user, atom/A) - set waitfor = 0 - - var/turf/origin_turf = get_turf(src) - origin_turf = locate(origin_turf.x + origins[1], origin_turf.y + origins[2], origin_turf.z) - origin_turf = get_step(get_step(origin_turf, owner.dir), owner.dir) //this should get us tile in front of tank to prevent grenade being stuck under us. - - var/obj/projectile/P = generate_bullet(user, origin_turf) - SEND_SIGNAL(P, COMSIG_BULLET_USER_EFFECTS, owner.seats[VEHICLE_GUNNER]) - P.fire_at(A, owner.seats[VEHICLE_GUNNER], src, get_dist(origin_turf, A) + 1, P.ammo.shell_speed) - ammo.current_rounds-- -*/ diff --git a/code/modules/vehicles/hardpoints/primary/autocannon.dm b/code/modules/vehicles/hardpoints/primary/autocannon.dm index 2e74533e7ade..b6dc2cedc674 100644 --- a/code/modules/vehicles/hardpoints/primary/autocannon.dm +++ b/code/modules/vehicles/hardpoints/primary/autocannon.dm @@ -8,7 +8,6 @@ activation_sounds = list('sound/weapons/vehicles/autocannon_fire.ogg') health = 500 - //accuracy = 0.98 firing_arc = 60 origins = list(0, -3) @@ -23,9 +22,9 @@ "8" = list(-32, 0) ) - fire_delay = 0.7 SECONDS + scatter = 1 gun_firemode = GUN_FIREMODE_AUTOMATIC gun_firemode_list = list( GUN_FIREMODE_AUTOMATIC, ) - scatter = 1 + fire_delay = 0.7 SECONDS diff --git a/code/modules/vehicles/hardpoints/primary/dual_cannon.dm b/code/modules/vehicles/hardpoints/primary/dual_cannon.dm index 523742df3e67..4033a4bffb2a 100644 --- a/code/modules/vehicles/hardpoints/primary/dual_cannon.dm +++ b/code/modules/vehicles/hardpoints/primary/dual_cannon.dm @@ -12,7 +12,6 @@ damage_multiplier = 0.2 health = 500 - //accuracy = 0.98 firing_arc = 60 origins = list(0, -2) @@ -31,12 +30,12 @@ "8" = list(14, 9) ) - fire_delay = 0.3 SECONDS + scatter = 1 gun_firemode = GUN_FIREMODE_AUTOMATIC gun_firemode_list = list( GUN_FIREMODE_AUTOMATIC, ) - scatter = 1 + fire_delay = 0.3 SECONDS /obj/item/hardpoint/primary/dualcannon/set_bullet_traits() ..() diff --git a/code/modules/vehicles/hardpoints/primary/flamer.dm b/code/modules/vehicles/hardpoints/primary/flamer.dm index 6475a331ffb1..13beee9dd2c2 100644 --- a/code/modules/vehicles/hardpoints/primary/flamer.dm +++ b/code/modules/vehicles/hardpoints/primary/flamer.dm @@ -8,7 +8,6 @@ activation_sounds = list('sound/weapons/vehicles/flamethrower.ogg') health = 400 - //accuracy = 0.75 firing_arc = 90 origins = list(0, -3) @@ -25,8 +24,8 @@ use_muzzle_flash = FALSE - fire_delay = 2.0 SECONDS scatter = 5 + fire_delay = 2.0 SECONDS /obj/item/hardpoint/primary/flamer/set_bullet_traits() ..() diff --git a/code/modules/vehicles/hardpoints/primary/ltb.dm b/code/modules/vehicles/hardpoints/primary/ltb.dm index b31fe533d29b..19b5c7e7b9b4 100644 --- a/code/modules/vehicles/hardpoints/primary/ltb.dm +++ b/code/modules/vehicles/hardpoints/primary/ltb.dm @@ -8,7 +8,6 @@ activation_sounds = list('sound/weapons/vehicles/cannon_fire1.ogg', 'sound/weapons/vehicles/cannon_fire2.ogg') health = 500 - //accuracy = 0.97 firing_arc = 60 origins = list(0, -3) @@ -30,9 +29,5 @@ "8" = list(-89, -4) ) - fire_delay = 20.0 SECONDS - gun_firemode = GUN_FIREMODE_SEMIAUTO - gun_firemode_list = list( - GUN_FIREMODE_SEMIAUTO, - ) scatter = 2 + fire_delay = 20.0 SECONDS diff --git a/code/modules/vehicles/hardpoints/primary/minigun.dm b/code/modules/vehicles/hardpoints/primary/minigun.dm index 5d89aea545dd..b4d4de4cf200 100644 --- a/code/modules/vehicles/hardpoints/primary/minigun.dm +++ b/code/modules/vehicles/hardpoints/primary/minigun.dm @@ -7,7 +7,6 @@ disp_icon_state = "ltaaap_minigun" health = 350 - //accuracy = 0.6 firing_arc = 90 origins = list(0, -3) @@ -29,12 +28,12 @@ "8" = list(-77, 0) ) - fire_delay = 0.8 SECONDS + scatter = 7 gun_firemode = GUN_FIREMODE_AUTOMATIC gun_firemode_list = list( GUN_FIREMODE_AUTOMATIC, ) - scatter = 7 + fire_delay = 0.8 SECONDS //var/start_sound = 'sound/weapons/vehicles/minigun_start.ogg' //var/loop_sound = 'sound/weapons/vehicles/minigun_loop.ogg' diff --git a/code/modules/vehicles/hardpoints/secondary/cupola.dm b/code/modules/vehicles/hardpoints/secondary/cupola.dm index 9fbc6b379d3c..f259d6ea2623 100644 --- a/code/modules/vehicles/hardpoints/secondary/cupola.dm +++ b/code/modules/vehicles/hardpoints/secondary/cupola.dm @@ -8,7 +8,6 @@ activation_sounds = list('sound/weapons/gun_smartgun1.ogg', 'sound/weapons/gun_smartgun2.ogg', 'sound/weapons/gun_smartgun3.ogg', 'sound/weapons/gun_smartgun4.ogg') health = 350 - //accuracy = 0.9 firing_arc = 120 origins = list(0, -2) @@ -23,14 +22,14 @@ "8" = list(-5, 7) ) - burst_amount = 3 - burst_delay = 0.3 SECONDS - extra_delay = 0.6 SECONDS + scatter = 3 gun_firemode = GUN_FIREMODE_BURSTFIRE gun_firemode_list = list( GUN_FIREMODE_BURSTFIRE, ) - scatter = 3 + burst_amount = 3 + burst_delay = 0.3 SECONDS + extra_delay = 0.6 SECONDS /obj/item/hardpoint/secondary/m56cupola/set_bullet_traits() ..() diff --git a/code/modules/vehicles/hardpoints/secondary/flamer.dm b/code/modules/vehicles/hardpoints/secondary/flamer.dm index 1bc9f52b1e22..5557cfb24e17 100644 --- a/code/modules/vehicles/hardpoints/secondary/flamer.dm +++ b/code/modules/vehicles/hardpoints/secondary/flamer.dm @@ -8,7 +8,6 @@ activation_sounds = list('sound/weapons/vehicles/flamethrower.ogg') health = 300 - //accuracy = 0.68 firing_arc = 120 origins = list(0, -2) @@ -26,8 +25,8 @@ "4" = list(3, 0), "8" = list(-3, 18) ) - scatter = 6 + scatter = 6 fire_delay = 3.0 SECONDS /obj/item/hardpoint/secondary/small_flamer/handle_fire(atom/target, mob/living/user, params) diff --git a/code/modules/vehicles/hardpoints/secondary/frontal_cannon.dm b/code/modules/vehicles/hardpoints/secondary/frontal_cannon.dm index 5e16eb76e46d..536b5742cfcd 100644 --- a/code/modules/vehicles/hardpoints/secondary/frontal_cannon.dm +++ b/code/modules/vehicles/hardpoints/secondary/frontal_cannon.dm @@ -11,7 +11,6 @@ damage_multiplier = 0.11 health = 350 - //accuracy = 0.8 firing_arc = 120 origins = list(0, -2) @@ -30,12 +29,12 @@ "8" = list(-62, -26) ) - fire_delay = 0.3 SECONDS + scatter = 4 gun_firemode = GUN_FIREMODE_AUTOMATIC gun_firemode_list = list( GUN_FIREMODE_AUTOMATIC, ) - scatter = 4 + fire_delay = 0.3 SECONDS /obj/item/hardpoint/secondary/frontalcannon/set_bullet_traits() ..() diff --git a/code/modules/vehicles/hardpoints/secondary/grenade_launcher.dm b/code/modules/vehicles/hardpoints/secondary/grenade_launcher.dm index ca4915a40dcc..efd151e93cb3 100644 --- a/code/modules/vehicles/hardpoints/secondary/grenade_launcher.dm +++ b/code/modules/vehicles/hardpoints/secondary/grenade_launcher.dm @@ -8,7 +8,6 @@ activation_sounds = list('sound/weapons/gun_m92_attachable.ogg') health = 500 - //accuracy = 0.4 firing_arc = 90 var/max_range = 7 @@ -25,8 +24,8 @@ "4" = list(6, 0), "8" = list(-6, 17) ) - scatter = 10 + scatter = 10 fire_delay = 3.0 SECONDS /obj/item/hardpoint/secondary/grenade_launcher/set_bullet_traits() diff --git a/code/modules/vehicles/hardpoints/secondary/tow.dm b/code/modules/vehicles/hardpoints/secondary/tow.dm index f9697b94043e..7c58f7970c7b 100644 --- a/code/modules/vehicles/hardpoints/secondary/tow.dm +++ b/code/modules/vehicles/hardpoints/secondary/tow.dm @@ -7,7 +7,6 @@ disp_icon_state = "towlauncher" health = 500 - //accuracy = 0.8 firing_arc = 60 origins = list(0, -2) @@ -29,10 +28,6 @@ "8" = list(-5, 10) ) - fire_delay = 15.0 SECONDS - gun_firemode = GUN_FIREMODE_SEMIAUTO - gun_firemode_list = list( - GUN_FIREMODE_SEMIAUTO, - ) scatter = 4 + fire_delay = 15.0 SECONDS diff --git a/code/modules/vehicles/hardpoints/special/firing_port_weapon.dm b/code/modules/vehicles/hardpoints/special/firing_port_weapon.dm index 4e333869bf9a..780c195f00be 100644 --- a/code/modules/vehicles/hardpoints/special/firing_port_weapon.dm +++ b/code/modules/vehicles/hardpoints/special/firing_port_weapon.dm @@ -10,7 +10,6 @@ activation_sounds = list('sound/weapons/gun_smartgun1.ogg', 'sound/weapons/gun_smartgun2.ogg', 'sound/weapons/gun_smartgun3.ogg', 'sound/weapons/gun_smartgun4.ogg') health = 100 - //accuracy = 0.9 firing_arc = 120 //FPWs reload automatically var/reloading = FALSE @@ -28,12 +27,12 @@ underlayer_north_muzzleflash = TRUE - fire_delay = 0.3 SECONDS + scatter = 3 gun_firemode = GUN_FIREMODE_AUTOMATIC gun_firemode_list = list( GUN_FIREMODE_AUTOMATIC, ) - scatter = 3 + fire_delay = 0.3 SECONDS /obj/item/hardpoint/special/firing_port_weapon/set_bullet_traits() ..() diff --git a/code/modules/vehicles/hardpoints/support/flare.dm b/code/modules/vehicles/hardpoints/support/flare.dm index 28d341ac9cb3..432c9636dadd 100644 --- a/code/modules/vehicles/hardpoints/support/flare.dm +++ b/code/modules/vehicles/hardpoints/support/flare.dm @@ -13,7 +13,6 @@ activatable = TRUE health = 500 - //accuracy = 0.7 firing_arc = 120 origins = list(0, -2) @@ -32,12 +31,8 @@ "8" = list(14, -6) ) - fire_delay = 3.0 SECONDS - gun_firemode = GUN_FIREMODE_SEMIAUTO - gun_firemode_list = list( - GUN_FIREMODE_SEMIAUTO, - ) scatter = 6 + fire_delay = 3.0 SECONDS /obj/item/hardpoint/support/flare_launcher/set_bullet_traits() ..() From 0628839f1569ad9463dc168386d7a43af1eacf0f Mon Sep 17 00:00:00 2001 From: Doubleumc Date: Wed, 8 Nov 2023 21:16:19 -0500 Subject: [PATCH 12/21] use defines for click modifiers --- code/modules/vehicles/hardpoints/hardpoint.dm | 2 +- .../multitile/multitile_interaction.dm | 18 +++++++++--------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/code/modules/vehicles/hardpoints/hardpoint.dm b/code/modules/vehicles/hardpoints/hardpoint.dm index 877cda9df2aa..455e13b007fa 100644 --- a/code/modules/vehicles/hardpoints/hardpoint.dm +++ b/code/modules/vehicles/hardpoints/hardpoint.dm @@ -538,7 +538,7 @@ /obj/item/hardpoint/proc/start_fire(datum/source, atom/object, turf/location, control, params) /* var/list/modifiers = params2list(params) - if(modifiers["shift"] || modifiers["ctrl"] || modifiers["alt"] || modifiers["middle"] || modifiers["right"]) + if(modifiers[SHIFT_CLICK] || modifiers[CTRL_CLICK] || modifiers[ALT_CLICK] || modifiers[MIDDLE_CLICK] || modifiers[RIGHT_CLICK]) return */ diff --git a/code/modules/vehicles/multitile/multitile_interaction.dm b/code/modules/vehicles/multitile/multitile_interaction.dm index 496267bc33ad..708e624543ef 100644 --- a/code/modules/vehicles/multitile/multitile_interaction.dm +++ b/code/modules/vehicles/multitile/multitile_interaction.dm @@ -369,14 +369,14 @@ var/seat = get_mob_seat(source) switch(seat) if(VEHICLE_DRIVER) - if(modifiers["shift"] && !modifiers["alt"]) + if(modifiers[SHIFT_CLICK] && !modifiers[ALT_CLICK]) //object.examine(source) return - if(modifiers["ctrl"] && !modifiers["alt"]) + if(modifiers[CTRL_CLICK] && !modifiers[ALT_CLICK]) activate_horn() return if(VEHICLE_GUNNER) - if(modifiers["shift"] && !modifiers["middle"]) + if(modifiers[SHIFT_CLICK] && !modifiers[MIDDLE_CLICK]) /* if(HAS_FLAG(vehicle_flags, VEHICLE_TOGGLE_SHIFT_CLICK_GUNNER)) shoot_other_weapon(source, seat, object) @@ -384,26 +384,26 @@ object.examine(source) */ return - if(modifiers["middle"] && !modifiers["shift"]) + if(modifiers[MIDDLE_CLICK] && !modifiers[SHIFT_CLICK]) /* if(!HAS_FLAG(vehicle_flags, VEHICLE_TOGGLE_SHIFT_CLICK_GUNNER)) shoot_other_weapon(source, seat, object) */ return - if(modifiers["alt"]) + if(modifiers[ALT_CLICK]) //toggle_gyrostabilizer() return - if(modifiers["ctrl"]) + if(modifiers[CTRL_CLICK]) //activate_support_module(source, seat, object) return if(VEHICLE_SUPPORT_GUNNER_ONE, VEHICLE_SUPPORT_GUNNER_TWO) - if(modifiers["shift"]) + if(modifiers[SHIFT_CLICK]) //object.examine(source) return - if(modifiers["middle"] || modifiers["alt"] || modifiers["ctrl"]) + if(modifiers[MIDDLE_CLICK] || modifiers[ALT_CLICK] || modifiers[CTRL_CLICK]) return - if(modifiers["shift"] || modifiers["middle"] || modifiers["right"]) + if(modifiers[SHIFT_CLICK] || modifiers[MIDDLE_CLICK] || modifiers[RIGHT_CLICK]) return var/obj/item/hardpoint/hardpoint = get_mob_hp(source) From 16ae7082aa9949912369183d47d926b63f97f1ce Mon Sep 17 00:00:00 2001 From: Doubleumc Date: Thu, 9 Nov 2023 03:42:55 -0500 Subject: [PATCH 13/21] vehicle buffs for scatter, fire delay --- code/modules/vehicles/hardpoints/hardpoint.dm | 48 ++++++++++++++----- .../vehicles/hardpoints/holder/holder.dm | 5 +- .../vehicles/hardpoints/primary/minigun.dm | 16 ++++--- .../multitile/multitile_hardpoints.dm | 6 +++ 4 files changed, 55 insertions(+), 20 deletions(-) diff --git a/code/modules/vehicles/hardpoints/hardpoint.dm b/code/modules/vehicles/hardpoints/hardpoint.dm index 455e13b007fa..512805b8e8ab 100644 --- a/code/modules/vehicles/hardpoints/hardpoint.dm +++ b/code/modules/vehicles/hardpoints/hardpoint.dm @@ -194,37 +194,61 @@ /obj/item/hardpoint/proc/get_integrity_percent() return 100.0*health/initial(health) -/obj/item/hardpoint/proc/on_install(obj/vehicle/multitile/V) - apply_buff(V) +/// Apply hardpoint effects to vehicle and self. +/obj/item/hardpoint/proc/on_install(obj/vehicle/multitile/vehicle) + apply_buff(vehicle) + recalculate_hardpoint_bonuses() return -/obj/item/hardpoint/proc/on_uninstall(obj/vehicle/multitile/V) - remove_buff(V) +/// Remove hardpoint effects from vehicle and self. +/obj/item/hardpoint/proc/on_uninstall(obj/vehicle/multitile/vehicle) + remove_buff(vehicle) + recalculate_hardpoint_bonuses() return -//applying passive buffs like damage type resistance, speed, accuracy, cooldowns -/obj/item/hardpoint/proc/apply_buff(obj/vehicle/multitile/V) +/// Applying passive buffs like damage type resistance, speed, accuracy, cooldowns. +/obj/item/hardpoint/proc/apply_buff(obj/vehicle/multitile/vehicle) if(buff_applied) return if(LAZYLEN(type_multipliers)) for(var/type in type_multipliers) - V.dmg_multipliers[type] *= LAZYACCESS(type_multipliers, type) + vehicle.dmg_multipliers[type] *= LAZYACCESS(type_multipliers, type) if(LAZYLEN(buff_multipliers)) for(var/type in buff_multipliers) - V.misc_multipliers[type] *= LAZYACCESS(buff_multipliers, type) + vehicle.misc_multipliers[type] *= LAZYACCESS(buff_multipliers, type) buff_applied = TRUE + vehicle.on_modifiers_change() //check if I need to do this? currently only "accuracy" and "cooldown" need it -//removing buffs -/obj/item/hardpoint/proc/remove_buff(obj/vehicle/multitile/V) +/// Removing passive buffs like damage type resistance, speed, accuracy, cooldowns. +/obj/item/hardpoint/proc/remove_buff(obj/vehicle/multitile/vehicle) if(!buff_applied) return if(LAZYLEN(type_multipliers)) for(var/type in type_multipliers) - V.dmg_multipliers[type] *= 1 / LAZYACCESS(type_multipliers, type) + vehicle.dmg_multipliers[type] *= 1 / LAZYACCESS(type_multipliers, type) if(LAZYLEN(buff_multipliers)) for(var/type in buff_multipliers) - V.misc_multipliers[type] *= 1 / LAZYACCESS(buff_multipliers, type) + vehicle.misc_multipliers[type] *= 1 / LAZYACCESS(buff_multipliers, type) buff_applied = FALSE + vehicle.on_modifiers_change() //check if I need to do this? currently only "accuracy" and "cooldown" need it + +/// Recalculates hardpoint values based on vehicle modifiers. +/obj/item/hardpoint/proc/recalculate_hardpoint_bonuses() + scatter = initial(scatter) / owner.misc_multipliers["accuracy"] + var/cooldown_mult = owner.misc_multipliers["cooldown"] + set_fire_delay(initial(fire_delay) * cooldown_mult) + set_burst_delay(initial(burst_delay) * cooldown_mult) + extra_delay = initial(extra_delay) * cooldown_mult + +/// Setter for fire_delay. +/obj/item/hardpoint/proc/set_fire_delay(value) + fire_delay = value + SEND_SIGNAL(src, COMSIG_GUN_AUTOFIREDELAY_MODIFIED, fire_delay) + +/// Setter for burst_delay. +/obj/item/hardpoint/proc/set_burst_delay(value) + burst_delay = value + SEND_SIGNAL(src, COMSIG_GUN_BURST_SHOT_DELAY_MODIFIED, burst_delay) //this proc called on each move of vehicle /obj/item/hardpoint/proc/on_move(turf/old, turf/new_turf, move_dir) diff --git a/code/modules/vehicles/hardpoints/holder/holder.dm b/code/modules/vehicles/hardpoints/holder/holder.dm index b14e078a3997..619bb649f556 100644 --- a/code/modules/vehicles/hardpoints/holder/holder.dm +++ b/code/modules/vehicles/hardpoints/holder/holder.dm @@ -121,16 +121,17 @@ H.forceMove(src) LAZYADD(hardpoints, H) + H.on_install(owner) H.rotate(turning_angle(H.dir, dir)) /obj/item/hardpoint/holder/proc/remove_hardpoint(obj/item/hardpoint/H, turf/uninstall_to) if(!hardpoints) return - hardpoints -= H H.forceMove(uninstall_to ? uninstall_to : get_turf(src)) + H.on_uninstall(owner) H.reset_rotation() - + hardpoints -= H H.owner = null if(H.health <= 0) diff --git a/code/modules/vehicles/hardpoints/primary/minigun.dm b/code/modules/vehicles/hardpoints/primary/minigun.dm index b4d4de4cf200..c7511a63f240 100644 --- a/code/modules/vehicles/hardpoints/primary/minigun.dm +++ b/code/modules/vehicles/hardpoints/primary/minigun.dm @@ -33,7 +33,7 @@ gun_firemode_list = list( GUN_FIREMODE_AUTOMATIC, ) - fire_delay = 0.8 SECONDS + fire_delay = 0.8 SECONDS //base fire rate, modified by stage_delay_mult //var/start_sound = 'sound/weapons/vehicles/minigun_start.ogg' //var/loop_sound = 'sound/weapons/vehicles/minigun_loop.ogg' @@ -50,8 +50,8 @@ var/spin_stage = 1 /// Shots fired per fire_delay at a particular spin_stage. var/list/stage_rate = list(1, 1, 2, 2, 3, 3, 3, 4, 4, 4, 5) - /// Fire delay for current spin_stage. - var/stage_delay = 0.8 SECONDS + /// Fire delay multiplier for current spin_stage. + var/stage_delay_mult = 1 /obj/item/hardpoint/primary/minigun/Destroy() STOP_PROCESSING(SSobj, src) @@ -73,13 +73,17 @@ var/new_stage_rate = stage_rate[Floor(spin_stage)] if(old_stage_rate != new_stage_rate) - stage_delay = fire_delay / new_stage_rate - SEND_SIGNAL(src, COMSIG_GUN_AUTOFIREDELAY_MODIFIED, stage_delay) + stage_delay_mult = 1 / new_stage_rate + SEND_SIGNAL(src, COMSIG_GUN_AUTOFIREDELAY_MODIFIED, fire_delay * stage_delay_mult) if(spin_stage <= 1) spin_stage = 1 STOP_PROCESSING(SSobj, src) +/obj/item/hardpoint/primary/minigun/set_fire_delay(value) + fire_delay = value + SEND_SIGNAL(src, COMSIG_GUN_AUTOFIREDELAY_MODIFIED, fire_delay * stage_delay_mult) + /obj/item/hardpoint/primary/minigun/handle_fire() . = ..() @@ -87,5 +91,5 @@ START_PROCESSING(SSobj, src) /obj/item/hardpoint/primary/minigun/set_fire_cooldown() - COOLDOWN_START(src, fire_cooldown, stage_delay) + COOLDOWN_START(src, fire_cooldown, fire_delay * stage_delay_mult) COOLDOWN_START(src, spindown_grace_cooldown, spindown_grace_time) diff --git a/code/modules/vehicles/multitile/multitile_hardpoints.dm b/code/modules/vehicles/multitile/multitile_hardpoints.dm index 7274e4b24d58..6efbd1efb70e 100644 --- a/code/modules/vehicles/multitile/multitile_hardpoints.dm +++ b/code/modules/vehicles/multitile/multitile_hardpoints.dm @@ -231,6 +231,12 @@ update_icon() +/// Trigger vehicle hardpoints to update values based on new modifiers. +/obj/vehicle/multitile/proc/on_modifiers_change() //should this be a signal? + var/list/hardpoints = get_hardpoints_copy() //could be more selective with get_hardpoints_with_ammo(), as only autofire weapons need it + for(var/obj/item/hardpoint/hardpoint in hardpoints) + hardpoint.recalculate_hardpoint_bonuses() + /* //proc that fires non selected weaponry /obj/vehicle/multitile/proc/shoot_other_weapon(mob/living/carbon/human/M, seat, atom/A) From cdd8a38f00696dd743da4de4ce652a9174b9586c Mon Sep 17 00:00:00 2001 From: Doubleumc Date: Fri, 10 Nov 2023 02:22:21 -0500 Subject: [PATCH 14/21] can't find good solution for nonselected firing --- code/modules/vehicles/multitile/multitile_interaction.dm | 5 +---- code/modules/vehicles/multitile/multitile_verbs.dm | 5 +---- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/code/modules/vehicles/multitile/multitile_interaction.dm b/code/modules/vehicles/multitile/multitile_interaction.dm index 708e624543ef..504f0ad5d4c4 100644 --- a/code/modules/vehicles/multitile/multitile_interaction.dm +++ b/code/modules/vehicles/multitile/multitile_interaction.dm @@ -391,7 +391,7 @@ */ return if(modifiers[ALT_CLICK]) - //toggle_gyrostabilizer() + toggle_gyrostabilizer() return if(modifiers[CTRL_CLICK]) //activate_support_module(source, seat, object) @@ -403,9 +403,6 @@ if(modifiers[MIDDLE_CLICK] || modifiers[ALT_CLICK] || modifiers[CTRL_CLICK]) return - if(modifiers[SHIFT_CLICK] || modifiers[MIDDLE_CLICK] || modifiers[RIGHT_CLICK]) - return - var/obj/item/hardpoint/hardpoint = get_mob_hp(source) if(!hardpoint) to_chat(source, SPAN_WARNING("Please select an active hardpoint first.")) diff --git a/code/modules/vehicles/multitile/multitile_verbs.dm b/code/modules/vehicles/multitile/multitile_verbs.dm index 66a3db0bfbe6..6d685bc16817 100644 --- a/code/modules/vehicles/multitile/multitile_verbs.dm +++ b/code/modules/vehicles/multitile/multitile_verbs.dm @@ -233,10 +233,7 @@ 3. \"G: Toggle Turret Gyrostabilizer\" - toggles Turret Gyrostabilizer allowing it to keep current direction ignoring hull turning. (Exists only on vehicles with rotating turret, e.g. M34A2 Longstreet Light Tank)
\ Support Gunner verbs:
1. \"Reload Firing Port Weapon\" - initiates automated reloading process for M56 FPW. Requires a confirmation.
\ Driver shortcuts:
1. \"CTRL + Click\" - activates vehicle horn.
\ - Gunner shortcuts:
1. \"ALT + Click\" - toggles Turret Gyrostabilizer. (Exists only on vehicles with rotating turret, e.g. M34A2 Longstreet Light Tank)
\ - 2. \"CTRL + Click\" - activates not destroyed activatable support module.
\ - 3. \"Middle Mouse Button Click (MMB)\" - default shortcut to shoot currently not selected weapon if possible. Won't work if SHIFT + Click firing is toggled ON.
\ - 4. \"SHIFT + Click\" - examines target as usual, unless \"G: Toggle Middle/Shift Clicking\" verb was used to toggle SHIFT + Click firing ON. In this case, it will fire currently not selected weapon if possible.
" + Gunner shortcuts:
1. \"ALT + Click\" - toggles Turret Gyrostabilizer. (Exists only on vehicles with rotating turret, e.g. M34A2 Longstreet Light Tank)
" show_browser(user, dat, "Vehicle Controls Guide", "vehicle_help", "size=900x500") onclose(user, "vehicle_help") From 7d0a91546977d4b16345978f2d3a218509cb67ce Mon Sep 17 00:00:00 2001 From: Doubleumc Date: Fri, 10 Nov 2023 02:38:01 -0500 Subject: [PATCH 15/21] cleanup --- code/modules/vehicles/hardpoints/hardpoint.dm | 47 +---------- .../multitile/multitile_hardpoints.dm | 48 ------------ .../multitile/multitile_interaction.dm | 77 ------------------- .../vehicles/multitile/multitile_verbs.dm | 29 ------- 4 files changed, 4 insertions(+), 197 deletions(-) diff --git a/code/modules/vehicles/hardpoints/hardpoint.dm b/code/modules/vehicles/hardpoints/hardpoint.dm index 512805b8e8ab..7c913db8e1ef 100644 --- a/code/modules/vehicles/hardpoints/hardpoint.dm +++ b/code/modules/vehicles/hardpoints/hardpoint.dm @@ -544,28 +544,20 @@ user = hp_operator if(ammo) - //to_chat(user, SPAN_DANGER("[ammo.current_rounds] / [ammo.max_rounds] ROUNDS REMAINING")) to_chat(user, SPAN_WARNING("[name] Ammo: [SPAN_HELPFUL(ammo ? ammo.current_rounds : 0)]/[SPAN_HELPFUL(ammo ? ammo.max_rounds : 0)] | Mags: [SPAN_HELPFUL(LAZYLEN(backup_clips))]/[SPAN_HELPFUL(max_clips)]")) /// Reset variables used in firing and remove the gun from the autofire system. /obj/item/hardpoint/proc/stop_fire(datum/source, atom/object, turf/location, control, params) - if(auto_firing || burst_firing) - SEND_SIGNAL(src, COMSIG_GUN_STOP_FIRE) - if(auto_firing) - reset_fire() //automatic fire doesn't reset itself from COMSIG_GUN_STOP_FIRE + SEND_SIGNAL(src, COMSIG_GUN_STOP_FIRE) + if(auto_firing) + reset_fire() //automatic fire doesn't reset itself from COMSIG_GUN_STOP_FIRE /// Update the target if you dragged your mouse. -/obj/item/hardpoint/proc/change_target(mob/source, atom/src_object, atom/over_object, turf/src_location, turf/over_location, src_control, over_control, params) +/obj/item/hardpoint/proc/change_target(datum/source, atom/src_object, atom/over_object, turf/src_location, turf/over_location, src_control, over_control, params) set_target(get_turf_on_clickcatcher(over_object, hp_operator, params)) /// Check if the gun can fire and add it to bucket autofire system if needed, or just fire the gun if not. /obj/item/hardpoint/proc/start_fire(datum/source, atom/object, turf/location, control, params) - /* - var/list/modifiers = params2list(params) - if(modifiers[SHIFT_CLICK] || modifiers[CTRL_CLICK] || modifiers[ALT_CLICK] || modifiers[MIDDLE_CLICK] || modifiers[RIGHT_CLICK]) - return - */ - if(istype(object, /atom/movable/screen)) return @@ -676,36 +668,6 @@ /obj/item/hardpoint/proc/get_origin_turf() return get_offset_target_turf(get_turf(src), origins[1], origins[2]) -/* -/// Toggles the gun's firemode one down the list. -/obj/item/hardpoint/proc/do_toggle_firemode(mob/user, new_firemode) - if(burst_firing) //can't toggle mid burst - return - - if(!length(gun_firemode_list)) - CRASH("[src] called do_toggle_firemode() with an empty gun_firemodes") - - if(length(gun_firemode_list) == 1) - to_chat(user, SPAN_NOTICE("[icon2html(src, user)] This hardpoint only has one firemode.")) - return - - if(new_firemode) - if(!(new_firemode in gun_firemode_list)) - CRASH("[src] called do_toggle_firemode() with [new_firemode] new_firemode, not on gun_firemodes") - gun_firemode = new_firemode - else - var/mode_index = gun_firemode_list.Find(gun_firemode) - if(++mode_index <= length(gun_firemode_list)) - gun_firemode = gun_firemode_list[mode_index] - else - gun_firemode = gun_firemode_list[1] - - playsound(user, 'sound/weapons/handling/gun_burst_toggle.ogg', 15, 1) - - to_chat(user, SPAN_NOTICE("[icon2html(src, user)] You switch the hardpoint to [gun_firemode].")) - SEND_SIGNAL(src, COMSIG_GUN_FIRE_MODE_TOGGLE, gun_firemode) -*/ - /// Plays 'click' noise and announced to chat. Usually called when weapon empty. /obj/item/hardpoint/proc/click_empty(mob/user) if(user) @@ -736,7 +698,6 @@ angle_diff += 360 else if(angle_diff > 180) angle_diff -= 360 - //debug_msg("Get_Angle: [Get_Angle(muzzle_turf, target_turf)] get_angle: [get_angle(muzzle_turf, target_turf)] dir2angle: [dir2angle(dir)] angle_diff: [angle_diff]") return abs(angle_diff) <= (firing_arc * 0.5) diff --git a/code/modules/vehicles/multitile/multitile_hardpoints.dm b/code/modules/vehicles/multitile/multitile_hardpoints.dm index 6efbd1efb70e..ca03ec6dfd15 100644 --- a/code/modules/vehicles/multitile/multitile_hardpoints.dm +++ b/code/modules/vehicles/multitile/multitile_hardpoints.dm @@ -236,51 +236,3 @@ var/list/hardpoints = get_hardpoints_copy() //could be more selective with get_hardpoints_with_ammo(), as only autofire weapons need it for(var/obj/item/hardpoint/hardpoint in hardpoints) hardpoint.recalculate_hardpoint_bonuses() - -/* -//proc that fires non selected weaponry -/obj/vehicle/multitile/proc/shoot_other_weapon(mob/living/carbon/human/M, seat, atom/A) - - if(!istype(M)) - return - - var/list/usable_hps = get_hardpoints_with_ammo(seat) - for(var/obj/item/hardpoint/HP in usable_hps) - if(HP == active_hp[seat] || HP.slot != HDPT_PRIMARY && HP.slot != HDPT_SECONDARY) - usable_hps.Remove(HP) - - if(!LAZYLEN(usable_hps)) - to_chat(M, SPAN_WARNING("No other working weapons detected.")) - return - - for(var/obj/item/hardpoint/HP in usable_hps) - if(!HP.can_activate(M, A)) - return - HP.activate(M, A) - break - return -*/ - -/* -//proc that activates support module if it can be activated and you meet requirements -/obj/vehicle/multitile/proc/activate_support_module(mob/living/carbon/human/M, seat, atom/A) - - if(!istype(M)) - return - - var/list/usable_hps = get_activatable_hardpoints(seat) - for(var/obj/item/hardpoint/HP in usable_hps) - if(HP.slot != HDPT_SUPPORT) - usable_hps.Remove(HP) - - if(!LAZYLEN(usable_hps)) - to_chat(M, SPAN_WARNING("No activatable support modules detected.")) - return - - for(var/obj/item/hardpoint/HP in usable_hps) - if(!HP.can_activate(M, A)) - return - HP.activate(M, A) - break - return -*/ diff --git a/code/modules/vehicles/multitile/multitile_interaction.dm b/code/modules/vehicles/multitile/multitile_interaction.dm index 504f0ad5d4c4..4d06925a612e 100644 --- a/code/modules/vehicles/multitile/multitile_interaction.dm +++ b/code/modules/vehicles/multitile/multitile_interaction.dm @@ -410,83 +410,6 @@ hardpoint.start_fire(source, object, location, control, params) -/* -/obj/vehicle/multitile/handle_click(mob/living/user, atom/A, list/mods) - - var/seat - for(var/vehicle_seat in seats) - if(seats[vehicle_seat] == user) - seat = vehicle_seat - break - - if(istype(A, /atom/movable/screen) || !seat) - return - - if(seat == VEHICLE_DRIVER) - if(mods["shift"] && !mods["alt"]) - A.examine(user) - return - - if(mods["ctrl"] && !mods["alt"]) - activate_horn() - return - - var/obj/item/hardpoint/HP = active_hp[seat] - if(!HP) - to_chat(user, SPAN_WARNING("Please select an active hardpoint first.")) - return - - if(!HP.can_activate(user, A)) - return - - HP.activate(user, A) - - if(seat == VEHICLE_GUNNER) - if(mods["shift"] && !mods["middle"]) - if(vehicle_flags & VEHICLE_TOGGLE_SHIFT_CLICK_GUNNER) - shoot_other_weapon(user, seat, A) - else - A.examine(user) - return - if(mods["middle"] && !mods["shift"]) - if(!(vehicle_flags & VEHICLE_TOGGLE_SHIFT_CLICK_GUNNER)) - shoot_other_weapon(user, seat, A) - return - if(mods["alt"]) - toggle_gyrostabilizer() - return - if(mods["ctrl"]) - activate_support_module(user, seat, A) - return - - var/obj/item/hardpoint/HP = active_hp[seat] - if(!HP) - to_chat(user, SPAN_WARNING("Please select an active hardpoint first.")) - return - - if(!HP.can_activate(user, A)) - return - - HP.activate(user, A) - - if(seat == VEHICLE_SUPPORT_GUNNER_ONE || seat == VEHICLE_SUPPORT_GUNNER_TWO) - if(mods["shift"]) - A.examine(user) - return - if(mods["middle"] || mods["alt"] || mods["ctrl"]) - return - - var/obj/item/hardpoint/HP = active_hp[seat] - if(!HP) - to_chat(user, SPAN_WARNING("Please select an active hardpoint first.")) - return - - if(!HP.can_activate(user, A)) - return - - HP.activate(user, A) -*/ - /obj/vehicle/multitile/proc/handle_player_entrance(mob/M) if(!M || M.client == null) return diff --git a/code/modules/vehicles/multitile/multitile_verbs.dm b/code/modules/vehicles/multitile/multitile_verbs.dm index 6d685bc16817..3801cd2e176c 100644 --- a/code/modules/vehicles/multitile/multitile_verbs.dm +++ b/code/modules/vehicles/multitile/multitile_verbs.dm @@ -381,32 +381,3 @@ return to_chat(user, SPAN_WARNING("Warning. No FPW for [seat] found, tell a dev!")) - -/* -/obj/vehicle/multitile/proc/cycle_firemode() - set name = "Cycle Firemode" - set desc = "Cycles through your gun's firemodes." - set category = "Vehicle" - - var/mob/user = usr - if(!user || !istype(user)) - return - - var/obj/vehicle/multitile/vehicle = user.interactee - if(!istype(vehicle)) - return - - var/seat - for(var/vehicle_seat in vehicle.seats) - if(vehicle.seats[vehicle_seat] == user) - seat = vehicle_seat - break - if(!seat) - return - - var/obj/item/hardpoint/hardpoint = vehicle.active_hp[seat] - if(!hardpoint) - return - - hardpoint.do_toggle_firemode(usr) -*/ From 4fe2f7327a2b08974a747034602116409908fcce Mon Sep 17 00:00:00 2001 From: Doubleumc Date: Fri, 10 Nov 2023 02:43:58 -0500 Subject: [PATCH 16/21] cleaned up control logic --- .../multitile/multitile_interaction.dm | 32 +++---------------- 1 file changed, 4 insertions(+), 28 deletions(-) diff --git a/code/modules/vehicles/multitile/multitile_interaction.dm b/code/modules/vehicles/multitile/multitile_interaction.dm index 4d06925a612e..aa2025d151b5 100644 --- a/code/modules/vehicles/multitile/multitile_interaction.dm +++ b/code/modules/vehicles/multitile/multitile_interaction.dm @@ -365,43 +365,19 @@ SIGNAL_HANDLER var/list/modifiers = params2list(params) + if(modifiers[SHIFT_CLICK] || modifiers[MIDDLE_CLICK] || modifiers[RIGHT_CLICK]) //don't step on examine, point, etc + return var/seat = get_mob_seat(source) switch(seat) if(VEHICLE_DRIVER) - if(modifiers[SHIFT_CLICK] && !modifiers[ALT_CLICK]) - //object.examine(source) - return - if(modifiers[CTRL_CLICK] && !modifiers[ALT_CLICK]) + if(modifiers[LEFT_CLICK] && modifiers[CTRL_CLICK]) activate_horn() return if(VEHICLE_GUNNER) - if(modifiers[SHIFT_CLICK] && !modifiers[MIDDLE_CLICK]) - /* - if(HAS_FLAG(vehicle_flags, VEHICLE_TOGGLE_SHIFT_CLICK_GUNNER)) - shoot_other_weapon(source, seat, object) - else - object.examine(source) - */ - return - if(modifiers[MIDDLE_CLICK] && !modifiers[SHIFT_CLICK]) - /* - if(!HAS_FLAG(vehicle_flags, VEHICLE_TOGGLE_SHIFT_CLICK_GUNNER)) - shoot_other_weapon(source, seat, object) - */ - return - if(modifiers[ALT_CLICK]) + if(modifiers[LEFT_CLICK] && modifiers[ALT_CLICK]) toggle_gyrostabilizer() return - if(modifiers[CTRL_CLICK]) - //activate_support_module(source, seat, object) - return - if(VEHICLE_SUPPORT_GUNNER_ONE, VEHICLE_SUPPORT_GUNNER_TWO) - if(modifiers[SHIFT_CLICK]) - //object.examine(source) - return - if(modifiers[MIDDLE_CLICK] || modifiers[ALT_CLICK] || modifiers[CTRL_CLICK]) - return var/obj/item/hardpoint/hardpoint = get_mob_hp(source) if(!hardpoint) From c082cf929386e7163a1c991aae04ed1a62b5d077 Mon Sep 17 00:00:00 2001 From: Doubleumc Date: Fri, 10 Nov 2023 18:58:01 -0500 Subject: [PATCH 17/21] click_empty() update, comment cleanup --- code/modules/vehicles/hardpoints/hardpoint.dm | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/code/modules/vehicles/hardpoints/hardpoint.dm b/code/modules/vehicles/hardpoints/hardpoint.dm index 7c913db8e1ef..07fbc33bbb27 100644 --- a/code/modules/vehicles/hardpoints/hardpoint.dm +++ b/code/modules/vehicles/hardpoints/hardpoint.dm @@ -217,7 +217,7 @@ for(var/type in buff_multipliers) vehicle.misc_multipliers[type] *= LAZYACCESS(buff_multipliers, type) buff_applied = TRUE - vehicle.on_modifiers_change() //check if I need to do this? currently only "accuracy" and "cooldown" need it + vehicle.on_modifiers_change() /// Removing passive buffs like damage type resistance, speed, accuracy, cooldowns. /obj/item/hardpoint/proc/remove_buff(obj/vehicle/multitile/vehicle) @@ -230,7 +230,7 @@ for(var/type in buff_multipliers) vehicle.misc_multipliers[type] *= 1 / LAZYACCESS(buff_multipliers, type) buff_applied = FALSE - vehicle.on_modifiers_change() //check if I need to do this? currently only "accuracy" and "cooldown" need it + vehicle.on_modifiers_change() /// Recalculates hardpoint values based on vehicle modifiers. /obj/item/hardpoint/proc/recalculate_hardpoint_bonuses() @@ -601,7 +601,7 @@ return NONE if(ammo && ammo.current_rounds <= 0) - click_empty() + click_empty(user) return NONE if(!in_firing_arc(target)) @@ -670,11 +670,9 @@ /// Plays 'click' noise and announced to chat. Usually called when weapon empty. /obj/item/hardpoint/proc/click_empty(mob/user) + playsound(src, 'sound/weapons/gun_empty.ogg', 25, 1, 5) if(user) to_chat(user, SPAN_WARNING("*click*")) - playsound(user, 'sound/weapons/gun_empty.ogg', 25, 1, 5) //5 tile range - else - playsound(src, 'sound/weapons/gun_empty.ogg', 25, 1, 5) /// Selects and plays a firing sound from the list. /obj/item/hardpoint/proc/play_firing_sounds() From 861c78661f66e7cfa4688f70fa48d02eed72519c Mon Sep 17 00:00:00 2001 From: Doubleumc Date: Sun, 12 Nov 2023 16:05:50 -0500 Subject: [PATCH 18/21] multitile-authoritative hardpoint user --- code/modules/vehicles/hardpoints/hardpoint.dm | 24 +++++++------------ 1 file changed, 9 insertions(+), 15 deletions(-) diff --git a/code/modules/vehicles/hardpoints/hardpoint.dm b/code/modules/vehicles/hardpoints/hardpoint.dm index 07fbc33bbb27..65a7ca79e065 100644 --- a/code/modules/vehicles/hardpoints/hardpoint.dm +++ b/code/modules/vehicles/hardpoints/hardpoint.dm @@ -125,8 +125,6 @@ /// Currently selected target to fire at. Set with set_target(). var/atom/target - /// Current operator (crew) of the hardpoint. - var/mob/hp_operator //----------------------------- //------GENERAL PROCS---------- @@ -145,7 +143,6 @@ QDEL_NULL_LIST(backup_clips) QDEL_NULL(ammo) set_target(null) - hp_operator = null return ..() /obj/item/hardpoint/ex_act(severity) @@ -504,24 +501,21 @@ /obj/item/hardpoint/proc/set_auto_firing(auto = FALSE) if(auto_firing != auto) auto_firing = auto - if(!auto_firing) //end-of-fire, show changed ammo and clear firer + if(!auto_firing) //end-of-fire, show changed ammo display_ammo() - hp_operator = null /// Setter proc for the burst firing flag. /obj/item/hardpoint/proc/set_burst_firing(burst = FALSE) if(burst_firing != burst) burst_firing = burst - if(!burst_firing) //end-of-fire, show changed ammo and clear firer + if(!burst_firing) //end-of-fire, show changed ammo display_ammo() - hp_operator = null /// Clean all firing references. /obj/item/hardpoint/proc/reset_fire() shots_fired = 0 set_target(null) set_auto_firing(FALSE) //on abnormal exits automatic fire doesn't call set_auto_firing() - hp_operator = null //clear 'firer' when autofire exits before first shot /// Set the target and take care of hard delete. /obj/item/hardpoint/proc/set_target(atom/object) @@ -541,7 +535,9 @@ /// Print how much ammo is left to chat. /obj/item/hardpoint/proc/display_ammo(mob/user) if(!user) - user = hp_operator + user = owner.get_seat_mob(allowed_seat) + if(!user) + return if(ammo) to_chat(user, SPAN_WARNING("[name] Ammo: [SPAN_HELPFUL(ammo ? ammo.current_rounds : 0)]/[SPAN_HELPFUL(ammo ? ammo.max_rounds : 0)] | Mags: [SPAN_HELPFUL(LAZYLEN(backup_clips))]/[SPAN_HELPFUL(max_clips)]")) @@ -554,7 +550,7 @@ /// Update the target if you dragged your mouse. /obj/item/hardpoint/proc/change_target(datum/source, atom/src_object, atom/over_object, turf/src_location, turf/over_location, src_control, over_control, params) - set_target(get_turf_on_clickcatcher(over_object, hp_operator, params)) + set_target(get_turf_on_clickcatcher(over_object, source, params)) /// Check if the gun can fire and add it to bucket autofire system if needed, or just fire the gun if not. /obj/item/hardpoint/proc/start_fire(datum/source, atom/object, turf/location, control, params) @@ -569,16 +565,14 @@ to_chat(source, SPAN_WARNING("You need to wait [SPAN_HELPFUL(COOLDOWN_SECONDSLEFT(src, fire_cooldown))] seconds before [name] can be used again.")) return - hp_operator = source set_target(get_turf_on_clickcatcher(object, source, params)) if(gun_firemode == GUN_FIREMODE_SEMIAUTO) var/fire_return = try_fire(object, source, params) - //end-of-fire, show ammo (if changed) and clear firer + //end-of-fire, show ammo (if changed) if(fire_return == AUTOFIRE_CONTINUE) reset_fire() - display_ammo() - hp_operator = null + display_ammo(source) else SEND_SIGNAL(src, COMSIG_GUN_FIRE) @@ -588,7 +582,7 @@ if(!target) target = src.target if(!user) - user = hp_operator + user = owner.get_seat_mob(allowed_seat) if(!target || !user) return NONE From 505887a04daf6cb1f1f390d10e2ea55111004c16 Mon Sep 17 00:00:00 2001 From: Doubleumc Date: Sun, 12 Nov 2023 16:49:43 -0500 Subject: [PATCH 19/21] no null args --- code/modules/vehicles/hardpoints/hardpoint.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/vehicles/hardpoints/hardpoint.dm b/code/modules/vehicles/hardpoints/hardpoint.dm index 65a7ca79e065..d9ca5bd38ac9 100644 --- a/code/modules/vehicles/hardpoints/hardpoint.dm +++ b/code/modules/vehicles/hardpoints/hardpoint.dm @@ -133,7 +133,7 @@ /obj/item/hardpoint/Initialize() . = ..() set_bullet_traits() - AddComponent(/datum/component/automatedfire/autofire, fire_delay, burst_delay, burst_amount, gun_firemode, autofire_slow_mult, CALLBACK(src, PROC_REF(set_burst_firing)), CALLBACK(src, PROC_REF(reset_fire)), CALLBACK(src, PROC_REF(fire_wrapper)), null, CALLBACK(src, PROC_REF(set_auto_firing))) + AddComponent(/datum/component/automatedfire/autofire, fire_delay, burst_delay, burst_amount, gun_firemode, autofire_slow_mult, CALLBACK(src, PROC_REF(set_burst_firing)), CALLBACK(src, PROC_REF(reset_fire)), CALLBACK(src, PROC_REF(fire_wrapper)), callback_set_firing = CALLBACK(src, PROC_REF(set_auto_firing))) /obj/item/hardpoint/Destroy() if(owner) From 45832b7c5fc5f7d2f07d0a1c15f462e4424df348 Mon Sep 17 00:00:00 2001 From: Doubleumc Date: Sun, 12 Nov 2023 18:15:36 -0500 Subject: [PATCH 20/21] changed minigun to not use PROCESSING --- .../vehicles/hardpoints/primary/minigun.dm | 46 ++++++++----------- 1 file changed, 18 insertions(+), 28 deletions(-) diff --git a/code/modules/vehicles/hardpoints/primary/minigun.dm b/code/modules/vehicles/hardpoints/primary/minigun.dm index c7511a63f240..3acf37eec268 100644 --- a/code/modules/vehicles/hardpoints/primary/minigun.dm +++ b/code/modules/vehicles/hardpoints/primary/minigun.dm @@ -35,9 +35,6 @@ ) fire_delay = 0.8 SECONDS //base fire rate, modified by stage_delay_mult - //var/start_sound = 'sound/weapons/vehicles/minigun_start.ogg' - //var/loop_sound = 'sound/weapons/vehicles/minigun_loop.ogg' - //var/stop_sound = 'sound/weapons/vehicles/minigun_stop.ogg' activation_sounds = list('sound/weapons/gun_minigun.ogg') /// Active firing time to reach max spin_stage. var/spinup_time = 8 SECONDS @@ -52,21 +49,32 @@ var/list/stage_rate = list(1, 1, 2, 2, 3, 3, 3, 4, 4, 4, 5) /// Fire delay multiplier for current spin_stage. var/stage_delay_mult = 1 + /// When it was last fired, related to world.time. + var/last_fired = 0 -/obj/item/hardpoint/primary/minigun/Destroy() - STOP_PROCESSING(SSobj, src) +/obj/item/hardpoint/primary/minigun/set_fire_delay(value) + fire_delay = value + SEND_SIGNAL(src, COMSIG_GUN_AUTOFIREDELAY_MODIFIED, fire_delay * stage_delay_mult) - return ..() +/obj/item/hardpoint/primary/minigun/set_fire_cooldown() + calculate_stage_delay_mult() //needs to check grace_cooldown before refreshed + last_fired = world.time + COOLDOWN_START(src, spindown_grace_cooldown, spindown_grace_time) + COOLDOWN_START(src, fire_cooldown, fire_delay * stage_delay_mult) -/obj/item/hardpoint/primary/minigun/process(delta_time) +/obj/item/hardpoint/primary/minigun/proc/calculate_stage_delay_mult() var/stage_rate_len = stage_rate.len - var/delta_stage = (delta_time SECONDS) * (stage_rate_len - 1) + var/delta_time = world.time - last_fired var/old_spin_stage = spin_stage - if(auto_firing || burst_firing) //spinup if firing + if(auto_firing || burst_firing) //spinup if continuing fire + var/delta_stage = delta_time * (stage_rate_len - 1) spin_stage += delta_stage / spinup_time - else if(COOLDOWN_FINISHED(src, spindown_grace_cooldown)) //spindown if not firing and after grace + else if(COOLDOWN_FINISHED(src, spindown_grace_cooldown)) //spindown if initiating fire after grace + var/delta_stage = (delta_time - spindown_grace_time) * (stage_rate_len - 1) spin_stage -= delta_stage / spindown_time + else + return spin_stage = Clamp(spin_stage, 1, stage_rate_len) var/old_stage_rate = stage_rate[Floor(old_spin_stage)] @@ -75,21 +83,3 @@ if(old_stage_rate != new_stage_rate) stage_delay_mult = 1 / new_stage_rate SEND_SIGNAL(src, COMSIG_GUN_AUTOFIREDELAY_MODIFIED, fire_delay * stage_delay_mult) - - if(spin_stage <= 1) - spin_stage = 1 - STOP_PROCESSING(SSobj, src) - -/obj/item/hardpoint/primary/minigun/set_fire_delay(value) - fire_delay = value - SEND_SIGNAL(src, COMSIG_GUN_AUTOFIREDELAY_MODIFIED, fire_delay * stage_delay_mult) - -/obj/item/hardpoint/primary/minigun/handle_fire() - . = ..() - - if((. & AUTOFIRE_CONTINUE)) - START_PROCESSING(SSobj, src) - -/obj/item/hardpoint/primary/minigun/set_fire_cooldown() - COOLDOWN_START(src, fire_cooldown, fire_delay * stage_delay_mult) - COOLDOWN_START(src, spindown_grace_cooldown, spindown_grace_time) From a907f7b79933533150c4b3e425d1ea0490c1cd20 Mon Sep 17 00:00:00 2001 From: Doubleumc Date: Mon, 13 Nov 2023 04:37:32 -0500 Subject: [PATCH 21/21] buffs are now SIGNALS, work with holders --- code/modules/vehicles/hardpoints/hardpoint.dm | 15 +++++++++------ .../vehicles/hardpoints/holder/holder.dm | 19 +++++++++++++++---- .../multitile/multitile_hardpoints.dm | 6 ------ 3 files changed, 24 insertions(+), 16 deletions(-) diff --git a/code/modules/vehicles/hardpoints/hardpoint.dm b/code/modules/vehicles/hardpoints/hardpoint.dm index d9ca5bd38ac9..acdefca18fd2 100644 --- a/code/modules/vehicles/hardpoints/hardpoint.dm +++ b/code/modules/vehicles/hardpoints/hardpoint.dm @@ -193,15 +193,18 @@ /// Apply hardpoint effects to vehicle and self. /obj/item/hardpoint/proc/on_install(obj/vehicle/multitile/vehicle) + if(!vehicle) //in loose holder + return + RegisterSignal(vehicle, COMSIG_GUN_RECALCULATE_ATTACHMENT_BONUSES, PROC_REF(recalculate_hardpoint_bonuses)) apply_buff(vehicle) - recalculate_hardpoint_bonuses() - return /// Remove hardpoint effects from vehicle and self. /obj/item/hardpoint/proc/on_uninstall(obj/vehicle/multitile/vehicle) + if(!vehicle) //in loose holder + return + UnregisterSignal(vehicle, COMSIG_GUN_RECALCULATE_ATTACHMENT_BONUSES) remove_buff(vehicle) - recalculate_hardpoint_bonuses() - return + //resetting values like set_gun_config_values() would be tidy, but unnecessary as it gets recalc'd on install anyway /// Applying passive buffs like damage type resistance, speed, accuracy, cooldowns. /obj/item/hardpoint/proc/apply_buff(obj/vehicle/multitile/vehicle) @@ -214,7 +217,7 @@ for(var/type in buff_multipliers) vehicle.misc_multipliers[type] *= LAZYACCESS(buff_multipliers, type) buff_applied = TRUE - vehicle.on_modifiers_change() + SEND_SIGNAL(vehicle, COMSIG_GUN_RECALCULATE_ATTACHMENT_BONUSES) /// Removing passive buffs like damage type resistance, speed, accuracy, cooldowns. /obj/item/hardpoint/proc/remove_buff(obj/vehicle/multitile/vehicle) @@ -227,7 +230,7 @@ for(var/type in buff_multipliers) vehicle.misc_multipliers[type] *= 1 / LAZYACCESS(buff_multipliers, type) buff_applied = FALSE - vehicle.on_modifiers_change() + SEND_SIGNAL(vehicle, COMSIG_GUN_RECALCULATE_ATTACHMENT_BONUSES) /// Recalculates hardpoint values based on vehicle modifiers. /obj/item/hardpoint/proc/recalculate_hardpoint_bonuses() diff --git a/code/modules/vehicles/hardpoints/holder/holder.dm b/code/modules/vehicles/hardpoints/holder/holder.dm index 619bb649f556..fc8e849d105c 100644 --- a/code/modules/vehicles/hardpoints/holder/holder.dm +++ b/code/modules/vehicles/hardpoints/holder/holder.dm @@ -43,10 +43,21 @@ for(var/obj/item/hardpoint/H in hardpoints) H.take_damage(damage) -/obj/item/hardpoint/holder/on_install(obj/vehicle/multitile/V) - for(var/obj/item/hardpoint/HP in hardpoints) - HP.owner = V - return +/obj/item/hardpoint/holder/on_install(obj/vehicle/multitile/vehicle) + ..() + if(!vehicle) //in loose holder + return + for(var/obj/item/hardpoint/hardpoint in hardpoints) + hardpoint.owner = vehicle + hardpoint.on_install(vehicle) + +/obj/item/hardpoint/holder/on_uninstall(obj/vehicle/multitile/vehicle) + if(!vehicle) //in loose holder + return + for(var/obj/item/hardpoint/hardpoint in hardpoints) + hardpoint.on_uninstall(vehicle) + hardpoint.owner = null + ..() /obj/item/hardpoint/holder/proc/can_install(obj/item/hardpoint/H) // Can only have 1 hardpoint of each slot type diff --git a/code/modules/vehicles/multitile/multitile_hardpoints.dm b/code/modules/vehicles/multitile/multitile_hardpoints.dm index ca03ec6dfd15..a6014c6cf2cd 100644 --- a/code/modules/vehicles/multitile/multitile_hardpoints.dm +++ b/code/modules/vehicles/multitile/multitile_hardpoints.dm @@ -230,9 +230,3 @@ qdel(old) update_icon() - -/// Trigger vehicle hardpoints to update values based on new modifiers. -/obj/vehicle/multitile/proc/on_modifiers_change() //should this be a signal? - var/list/hardpoints = get_hardpoints_copy() //could be more selective with get_hardpoints_with_ammo(), as only autofire weapons need it - for(var/obj/item/hardpoint/hardpoint in hardpoints) - hardpoint.recalculate_hardpoint_bonuses()