diff --git a/code/__DEFINES/dcs/signals/signals_mob/signals_mob_main.dm b/code/__DEFINES/dcs/signals/signals_mob/signals_mob_main.dm index 8ada1c30be3..39fa037a264 100644 --- a/code/__DEFINES/dcs/signals/signals_mob/signals_mob_main.dm +++ b/code/__DEFINES/dcs/signals/signals_mob/signals_mob_main.dm @@ -205,7 +205,7 @@ ///Sent by pilot of mech in /obj/vehicle/sealed/mecha/on_mouseclick when using mech equipment : (/obj/vehicle/sealed/mecha/mech) #define COMSIG_MOB_USED_MECH_EQUIPMENT "mob_used_mech_equipment" ///Sent by pilot of mech in /obj/vehicle/sealed/mecha/on_mouseclick when triggering mech punch : (/obj/vehicle/sealed/mecha/mech) -#define COMSIG_MOB_USED_MECH_MELEE "mob_used_mech_melee" +#define COMSIG_MOB_USED_CLICK_MECH_MELEE "mob_used_click_mech_melee" ///from living/flash_act(), when a mob is successfully flashed. #define COMSIG_MOB_FLASHED "mob_flashed" diff --git a/code/datums/elements/relay_attackers.dm b/code/datums/elements/relay_attackers.dm index 5f5bf7ed589..fd87cb3bc2c 100644 --- a/code/datums/elements/relay_attackers.dm +++ b/code/datums/elements/relay_attackers.dm @@ -85,7 +85,7 @@ SIGNAL_HANDLER relay_attacker(target, attacker, ATTACKER_DAMAGING_ATTACK) -/datum/element/relay_attackers/proc/on_attack_mech(atom/target, obj/vehicle/sealed/mecha/mecha_attacker, mob/living/pilot) +/datum/element/relay_attackers/proc/on_attack_mech(atom/target, obj/vehicle/sealed/mecha/mecha_attacker, mob/living/pilot, mecha_attack_cooldown) SIGNAL_HANDLER relay_attacker(target, mecha_attacker, ATTACKER_DAMAGING_ATTACK) diff --git a/code/modules/mob/living/basic/lavaland/watcher/watcher_overwatch.dm b/code/modules/mob/living/basic/lavaland/watcher/watcher_overwatch.dm index 541a4ed9e1c..a61ea0743f9 100644 --- a/code/modules/mob/living/basic/lavaland/watcher/watcher_overwatch.dm +++ b/code/modules/mob/living/basic/lavaland/watcher/watcher_overwatch.dm @@ -76,7 +76,7 @@ COMSIG_MOB_ITEM_ATTACK, COMSIG_MOB_THROW, COMSIG_MOB_USED_MECH_EQUIPMENT, - COMSIG_MOB_USED_MECH_MELEE, + COMSIG_MOB_USED_CLICK_MECH_MELEE, COMSIG_MOVABLE_MOVED, ) diff --git a/code/modules/vehicles/mecha/_mecha.dm b/code/modules/vehicles/mecha/_mecha.dm index 1155e6293d2..ed1d7c1d94b 100644 --- a/code/modules/vehicles/mecha/_mecha.dm +++ b/code/modules/vehicles/mecha/_mecha.dm @@ -16,6 +16,7 @@ * Clicks are wither translated into mech_melee_attack (see mech_melee_attack.dm) * Or are used to call action() on equipped gear * Cooldown for gear is on the mech because exploits + * Cooldown for melee is on mech_melee_attack also because exploits */ /obj/vehicle/sealed/mecha name = "exosuit" @@ -28,7 +29,6 @@ movedelay = 1 SECONDS move_force = MOVE_FORCE_VERY_STRONG move_resist = MOVE_FORCE_EXTREMELY_STRONG - COOLDOWN_DECLARE(mecha_bump_smash) light_system = OVERLAY_LIGHT_DIRECTIONAL light_on = FALSE light_range = 6 @@ -139,7 +139,7 @@ var/turnsound = 'sound/mecha/mechturn.ogg' ///Cooldown duration between melee punches - var/melee_cooldown = 10 + var/melee_cooldown = CLICK_CD_SLOW ///TIme taken to leave the mech var/exit_delay = 2 SECONDS @@ -194,9 +194,6 @@ ///Wether we are strafing var/strafe = FALSE - ///Cooldown length between bumpsmashes - var/smashcooldown = 3 - ///Bool for whether this mech can only be used on lavaland var/lavaland_only = FALSE @@ -703,10 +700,9 @@ return use_energy(melee_energy_drain) - SEND_SIGNAL(user, COMSIG_MOB_USED_MECH_MELEE, src) - target.mech_melee_attack(src, user) - TIMER_COOLDOWN_START(src, COOLDOWN_MECHA_MELEE_ATTACK, melee_cooldown) - + SEND_SIGNAL(user, COMSIG_MOB_USED_CLICK_MECH_MELEE, src) + if(target.mech_melee_attack(src, user)) + TIMER_COOLDOWN_START(src, COOLDOWN_MECHA_MELEE_ATTACK, melee_cooldown) /// Driver alt clicks anything while in mech /obj/vehicle/sealed/mecha/proc/on_click_alt(mob/user, atom/target, params) diff --git a/code/modules/vehicles/mecha/equipment/weapons/weapons.dm b/code/modules/vehicles/mecha/equipment/weapons/weapons.dm index d13b90e5659..5b50ac93523 100644 --- a/code/modules/vehicles/mecha/equipment/weapons/weapons.dm +++ b/code/modules/vehicles/mecha/equipment/weapons/weapons.dm @@ -4,14 +4,22 @@ equipment_slot = MECHA_WEAPON destroy_sound = 'sound/mecha/weapdestr.ogg' mech_flags = EXOSUIT_MODULE_COMBAT + /// The type of bullet generated by the mecha weapon. var/projectile + /// The sound of the mecha weapon firing. var/fire_sound + /// How many shots are fired per action. var/projectiles_per_shot = 1 + /// The degrees by which each individual bullet fans out from a central point. A predictable spray of bullets. var/variance = 0 - var/randomspread = FALSE //use random spread for machineguns, instead of shotgun scatter + /// Whether our bullets go off trajectory while firing randomly. Used to replicate recoil and not a structured, predictable spray. + var/randomspread = FALSE + /// The amount in deciseconds that the weapon sleeps between shots to simulate a 'burst fire'. The delay stops another bullet from being fired while sleeping. var/projectile_delay = 0 - var/firing_effect_type = /obj/effect/temp_visual/dir_setting/firing_effect //the visual effect appearing when the weapon is fired. - var/kickback = TRUE //Will using this weapon in no grav push mecha back. + //the visual effect appearing when the weapon is fired. + var/firing_effect_type = /obj/effect/temp_visual/dir_setting/firing_effect + /// Will using this weapon in no grav push mecha back. + var/kickback = TRUE /obj/item/mecha_parts/mecha_equipment/weapon/special_attaching_interaction(attach_right = FALSE, obj/vehicle/sealed/mecha/mech, mob/user, checkonly = FALSE) var/obj/item/mecha_parts/mecha_equipment/concealed_weapon_bay/bay @@ -43,17 +51,19 @@ /obj/item/mecha_parts/mecha_equipment/weapon/action(mob/source, atom/target, list/modifiers) if(!action_checks(target)) return FALSE + + /// Find our mecha, find the opposite direction. Used for kickback while the mecha is drifting in zero-g to launch us in this direction. var/newtonian_target = REVERSE_DIR(chassis.dir) . = ..()//start the cooldown early because of sleeps - for(var/i in 1 to projectiles_per_shot) + for(var/projectiles_to_shoot in 1 to projectiles_per_shot) if(energy_drain && !chassis.has_charge(energy_drain))//in case we run out of energy mid-burst, such as emp break var/spread = 0 if(variance) if(randomspread) - spread = round((rand() - 0.5) * variance) + spread = round((rand(0 , 1) - 0.5) * variance, 1) else - spread = round((i / projectiles_per_shot - 0.5) * variance) + spread = round((projectiles_to_shoot / projectiles_per_shot - 0.5) * variance, 1) var/obj/projectile/projectile_obj = new projectile(get_turf(src)) projectile_obj.log_override = TRUE //we log being fired ourselves a little further down. diff --git a/code/modules/vehicles/mecha/mech_melee_attack.dm b/code/modules/vehicles/mecha/mech_melee_attack.dm index 08669ebdd0c..e5c7b0aac72 100644 --- a/code/modules/vehicles/mecha/mech_melee_attack.dm +++ b/code/modules/vehicles/mecha/mech_melee_attack.dm @@ -2,7 +2,7 @@ * ## Mech melee attack * Called when a mech melees a target with fists * Handles damaging the target & associated effects - * return value is number of damage dealt + * return value is number of damage dealt. returning a value puts our mech onto attack cooldown. * Arguments: * * mecha_attacker: Mech attacking this target * * user: mob that initiated the attack from inside the mech as a controller @@ -14,6 +14,9 @@ return 0 /turf/closed/wall/mech_melee_attack(obj/vehicle/sealed/mecha/mecha_attacker, mob/living/user) + if(!user.combat_mode) + return 0 + mecha_attacker.do_attack_animation(src) switch(mecha_attacker.damtype) if(BRUTE) @@ -31,7 +34,26 @@ ..() return 100 //this is an arbitrary "damage" number since the actual damage is rng dismantle -/obj/mech_melee_attack(obj/vehicle/sealed/mecha/mecha_attacker, mob/living/user) +/obj/structure/mech_melee_attack(obj/vehicle/sealed/mecha/mecha_attacker, mob/living/user) + if(!user.combat_mode) + return 0 + + mecha_attacker.do_attack_animation(src) + switch(mecha_attacker.damtype) + if(BRUTE) + playsound(src, 'sound/weapons/punch4.ogg', 50, TRUE) + if(BURN) + playsound(src, 'sound/items/welder.ogg', 50, TRUE) + else + return 0 + mecha_attacker.visible_message(span_danger("[mecha_attacker] hits [src]!"), span_danger("You hit [src]!"), null, COMBAT_MESSAGE_RANGE) + ..() + return take_damage(mecha_attacker.force * 3, mecha_attacker.damtype, "melee", FALSE, get_dir(src, mecha_attacker)) // multiplied by 3 so we can hit objs hard but not be overpowered against mobs. + +/obj/machinery/mech_melee_attack(obj/vehicle/sealed/mecha/mecha_attacker, mob/living/user) + if(!user.combat_mode) + return 0 + mecha_attacker.do_attack_animation(src) switch(mecha_attacker.damtype) if(BRUTE) diff --git a/code/modules/vehicles/mecha/mecha_movement.dm b/code/modules/vehicles/mecha/mecha_movement.dm index 53e61690aba..3c743bd7fb3 100644 --- a/code/modules/vehicles/mecha/mecha_movement.dm +++ b/code/modules/vehicles/mecha/mecha_movement.dm @@ -154,13 +154,17 @@ return if(.) //mech was thrown/door/whatever return - if(bumpsmash) //Need a pilot to push the PUNCH button. - if(COOLDOWN_FINISHED(src, mecha_bump_smash)) - var/list/mob/mobster = return_drivers() - obstacle.mech_melee_attack(src, mobster[1]) - COOLDOWN_START(src, mecha_bump_smash, smashcooldown) - if(!obstacle || obstacle.CanPass(src, get_dir(obstacle, src) || dir)) // The else is in case the obstacle is in the same turf. - step(src,dir) + + // Whether or not we're on our mecha melee cooldown + var/on_cooldown = TIMER_COOLDOWN_RUNNING(src, COOLDOWN_MECHA_MELEE_ATTACK) + + if(bumpsmash && !on_cooldown) + // Our pilot for this evening + var/list/mob/mobster = return_drivers() + if(obstacle.mech_melee_attack(src, mobster[1])) + TIMER_COOLDOWN_START(src, COOLDOWN_MECHA_MELEE_ATTACK, melee_cooldown * 0.3) + if(!obstacle || obstacle.CanPass(src, get_dir(obstacle, src) || dir)) // The else is in case the obstacle is in the same turf. + step(src,dir) if(isobj(obstacle)) var/obj/obj_obstacle = obstacle if(!obj_obstacle.anchored && obj_obstacle.move_resist <= move_force)