Skip to content

Commit

Permalink
Gun rework (#1601)
Browse files Browse the repository at this point in the history
<!-- Write **BELOW** The Headers and **ABOVE** The comments else it may
not be viewable. -->
<!-- You can view Contributing.MD for a detailed description of the pull
request process. -->

## About The Pull Request
WIP.

if it wasn't obvious, very based off tgmc 

this reworks how guns work, by making them 4x more lethal without
touching a single damage value

its a bit difficult to put into words what this does, so i think these 3
gunfights i did with a good friend explains it better than i ever could

https://streamable.com/09in19
https://streamable.com/yel56o
https://streamable.com/x2a0he

if you didnt watch these videos:
- New guns sounds, TGMC as usual. but some racking sounds are from CEV
eris
- guns now can be wielded, if unwielded, they may cause recoil which not
only makes your shots less accurate, but 'scrolls' your screen
- new suppression effects
- getting hit hard enough scrolls your screen
- anything getting hit shakes you as feedback, not just bullets
- bullets can ricochet naturally upon hitting a surface at a step angle.
does not auto aim at your target, so be careful. ricochet sfx taken from
CEV eris
- new effects for bullet impacts. sound effects were taken from TGMC and
Skyrat-SS13/Skyrat-tg#11697
- adds the cattleman revolver and Himehabu 22lr pistol. sprites by yours
truely

big problem is, in order for all of this to work, a certain key needs to
be binded to rack the gun. by default this is SPACE, but moost already
have it binded to 'hold throw mode', which is an issue. for one, not
only you need to ask everyone to rebind their controls to a very
important key, but also a key dedicated to just racking the gun can
cause issues. im up for any solutions

- [x] I affirm that I have tested all of my proposed changes and that
any issues found during tested have been addressed.

## Why It's Good For The Game

people dont fear gunfights. they think its just a way to pvp. people
should be afraid of gunfights, feel the pain OOCly when their blorbo
gets hit

## Changelog

:cl:
add: 22lr and cattleman revolver
add: many gun sounds
balance: guns reworked
/:cl:

<!-- Both :cl:'s are required for the changelog to work! You can put
your name to the right of the first :cl: if you want to overwrite your
GitHub username as author ingame. -->
<!-- You can use multiple of the same prefix (they're only used for the
icon ingame) and delete the unneeded ones. Despite some of the tags,
changelogs should generally represent how a player might be affected by
the changes rather than a summary of the PR's contents. -->

---------

Co-authored-by: retlaw34 <[email protected]>
  • Loading branch information
rye-rice and retlaw34 authored Oct 29, 2023
1 parent f423b0d commit bf4671f
Show file tree
Hide file tree
Showing 193 changed files with 1,039 additions and 147 deletions.
3 changes: 3 additions & 0 deletions code/__DEFINES/combat.dm
Original file line number Diff line number Diff line change
Expand Up @@ -134,8 +134,11 @@ GLOBAL_LIST_INIT(shove_disarming_types, typecacheof(list(/obj/item/gun)))
#define EMBED_POINTY_SUPERIOR list("embed_chance" = 100, "ignore_throwspeed_threshold" = TRUE)

//Gun weapon weight
/// Allows you to dual wield this gun and your offhand gun
#define WEAPON_LIGHT 1
/// Does not allow you to dual wield with this gun and your offhand gun
#define WEAPON_MEDIUM 2
/// You must wield the gun to fire this gun
#define WEAPON_HEAVY 3
//Gun trigger guards
#define TRIGGER_GUARD_ALLOW_ALL -1
Expand Down
1 change: 1 addition & 0 deletions code/__DEFINES/keybinding.dm
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
//Human
#define COMSIG_KB_HUMAN_QUICKEQUIP_DOWN "keybinding_human_quickequip_down"
#define COMSIG_KB_HUMAN_QUICKEQUIPBELT_DOWN "keybinding_human_quickequipbelt_down"
#define COMSIG_KB_HUMAN_UNIQUEACTION "keybinding_uniqueaction"
#define COMSIG_KB_HUMAN_BAGEQUIP_DOWN "keybinding_human_bagequip_down"
#define COMSIG_KB_HUMAN_EQUIPMENTSWAP_DOWN "keybinding_human_equipmentswap_down"
#define COMSIG_KB_HUMAN_SUITEQUIP_DOWN "keybinding_human_suitequip_down"
Expand Down
10 changes: 10 additions & 0 deletions code/__DEFINES/obj_flags.dm
Original file line number Diff line number Diff line change
Expand Up @@ -64,3 +64,13 @@
/// Flags for the pod_flags var on /obj/structure/closet/supplypod

#define FIRST_SOUNDS (1<<0) // If it shouldn't play sounds the first time it lands, used for reverse mode


// Bullet hit sounds
#define PROJECTILE_HITSOUND_FLESH (1<<0)
#define PROJECTILE_HITSOUND_NON_LIVING (1<<1)
#define PROJECTILE_HITSOUND_GLASS (1<<2)
#define PROJECTILE_HITSOUND_STONE (1<<3)
#define PROJECTILE_HITSOUND_METAL (1<<4)
#define PROJECTILE_HITSOUND_WOOD (1<<5)
#define PROJECTILE_HITSOUND_SNOW (1<<6)
9 changes: 7 additions & 2 deletions code/__HELPERS/mobs.dm
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@ GLOBAL_LIST_EMPTY(species_list)
return "unknown"

///Timed action involving two mobs, the user and the target.
/proc/do_mob(mob/user , mob/target, time = 3 SECONDS, uninterruptible = FALSE, progress = TRUE, datum/callback/extra_checks = null)
/proc/do_mob(mob/user , mob/target, time = 3 SECONDS, uninterruptible = FALSE, progress = TRUE, datum/callback/extra_checks = null, ignore_loc_change = FALSE)
if(!user || !target)
return FALSE

Expand Down Expand Up @@ -284,7 +284,12 @@ GLOBAL_LIST_EMPTY(species_list)
drifting = FALSE
user_loc = user.loc

if((!drifting && user.loc != user_loc) || target.loc != target_loc || user.get_active_held_item() != holding || user.incapacitated() || (extra_checks && !extra_checks.Invoke()))

if(!ignore_loc_change && ((!drifting && user.loc != user_loc) || target.loc != target_loc))
. = FALSE
break

if(user.get_active_held_item() != holding || user.incapacitated() || (extra_checks && !extra_checks.Invoke()))
. = FALSE
break
if(!QDELETED(progbar))
Expand Down
21 changes: 21 additions & 0 deletions code/__HELPERS/unsorted.dm
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,27 @@
else if(dx<0)
.+=360


////Tile coordinates (x, y) to absolute coordinates (in number of pixels). Center of a tile is generally assumed to be (16,16), but can be offset.
#define ABS_COOR(c) (((c - 1) * 32) + 16)
#define ABS_COOR_OFFSET(c, o) (((c - 1) * 32) + o)

/proc/get_angle_with_scatter(atom/start, atom/end, scatter, x_offset = 16, y_offset = 16)
var/end_apx
var/end_apy
if(isliving(end)) //Center mass.
end_apx = ABS_COOR(end.x)
end_apy = ABS_COOR(end.y)
else //Exact pixel.
end_apx = ABS_COOR_OFFSET(end.x, x_offset)
end_apy = ABS_COOR_OFFSET(end.y, y_offset)
scatter = ((rand(0, min(scatter, 45))) * (prob(50) ? 1 : -1)) //Up to 45 degrees deviation to either side.
. = round((90 - ATAN2(end_apx - ABS_COOR(start.x), end_apy - ABS_COOR(start.y))), 1) + scatter
if(. < 0)
. += 360
else if(. >= 360)
. -= 360

/proc/Get_Pixel_Angle(y, x)//for getting the angle when animating something's pixel_x and pixel_y
if(!y)
return (x>=0)?90:270
Expand Down
8 changes: 5 additions & 3 deletions code/datums/components/fullauto.dm
Original file line number Diff line number Diff line change
Expand Up @@ -243,9 +243,8 @@
if(!can_shoot())
shoot_with_empty_chamber(shooter)
return FALSE
var/obj/item/bodypart/other_hand = shooter.has_hand_for_held_index(shooter.get_inactive_hand_index())
if(weapon_weight == WEAPON_HEAVY && (shooter.get_inactive_held_item() || !other_hand))
to_chat(shooter, "<span class='warning'>You need two hands to fire [src]!</span>")
if(weapon_weight == WEAPON_HEAVY && (!wielded))
to_chat(shooter, "<span class='warning'>You need a more secure grip to fire [src]!</span>")
return FALSE
return TRUE

Expand All @@ -260,6 +259,9 @@
SIGNAL_HANDLER
if(semicd || shooter.incapacitated())
return NONE
if(weapon_weight == WEAPON_HEAVY && (!wielded))
to_chat(shooter, "<span class='warning'>You need a more secure grip to fire [src]!</span>")
return NONE
if(!can_shoot())
shoot_with_empty_chamber(shooter)
return NONE
Expand Down
2 changes: 1 addition & 1 deletion code/datums/keybinding/carbon.dm
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
return TRUE

/datum/keybinding/carbon/hold_throw_mode
hotkey_keys = list("Space")
// hotkey_keys = list("Space")
name = "hold_throw_mode"
full_name = "Hold throw mode"
description = "Hold this to turn on throw mode, and release it to turn off throw mode"
Expand Down
16 changes: 16 additions & 0 deletions code/datums/keybinding/human.dm
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,22 @@
H.quick_equip()
return TRUE

/datum/keybinding/human/unique_action
hotkey_keys = list("Space")
name = "unique_action"
full_name = "Perform unique action"
description = ""
keybind_signal = COMSIG_KB_HUMAN_UNIQUEACTION


/datum/keybinding/human/unique_action/down(client/user)
. = ..()
if(.)
return
var/mob/living/carbon/human/current_human = user.mob
current_human.do_unique_action()
return TRUE

/datum/keybinding/human/quick_equip_belt
hotkey_keys = list("ShiftE")
name = "quick_equip_belt"
Expand Down
31 changes: 31 additions & 0 deletions code/game/atoms.dm
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,10 @@
///Default Y pixel offset
var/base_pixel_y

///Wanted sound when hit by a projectile
var/hitsound_type = PROJECTILE_HITSOUND_NON_LIVING
///volume wanted for being hit
var/hitsound_volume = 50
/**
* Called when an atom is created in byond (built in engine proc)
*
Expand Down Expand Up @@ -587,6 +591,33 @@
SEND_SIGNAL(src, COMSIG_ATOM_BULLET_ACT, P, def_zone)
. = P.on_hit(src, 0, def_zone, piercing_hit)

/atom/proc/bullet_hit_sfx(obj/projectile/hitting_projectile)
var/selected_sound = ""

if(!hitsound_volume)
return FALSE
if(!hitsound_volume)
return FALSE

switch(hitsound_type)
if(PROJECTILE_HITSOUND_FLESH)
selected_sound = hitting_projectile.hitsound
if(PROJECTILE_HITSOUND_NON_LIVING)
selected_sound = hitting_projectile.hitsound_non_living
if(PROJECTILE_HITSOUND_GLASS)
selected_sound = hitting_projectile.hitsound_glass
if(PROJECTILE_HITSOUND_STONE)
selected_sound = hitting_projectile.hitsound_stone
if(PROJECTILE_HITSOUND_METAL)
selected_sound = hitting_projectile.hitsound_metal
if(PROJECTILE_HITSOUND_WOOD)
selected_sound = hitting_projectile.hitsound_wood
if(PROJECTILE_HITSOUND_SNOW)
selected_sound = hitting_projectile.hitsound_snow

playsound(src, selected_sound, hitsound_volume, TRUE)
return TRUE

///Return true if we're inside the passed in atom
/atom/proc/in_contents_of(container)//can take class or object instance as argument
if(ispath(container))
Expand Down
2 changes: 2 additions & 0 deletions code/game/machinery/_machinery.dm
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,8 @@ Class Procs:
anchored = TRUE
interaction_flags_atom = INTERACT_ATOM_ATTACK_HAND | INTERACT_ATOM_UI_INTERACT

hitsound_type = PROJECTILE_HITSOUND_METAL

var/machine_stat = NONE
var/use_power = IDLE_POWER_USE
//0 = dont run the auto
Expand Down
2 changes: 2 additions & 0 deletions code/game/machinery/computer/_computer.dm
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
///Does this computer have a unique icon_state? Prevents the changing of icons from alternative computer construction
var/unique_icon = FALSE

hitsound_type = PROJECTILE_HITSOUND_GLASS

/obj/machinery/computer/Initialize(mapload, obj/item/circuitboard/C)
. = ..()
power_change()
Expand Down
2 changes: 2 additions & 0 deletions code/game/machinery/doors/windowdoor.dm
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
var/cable = 1
var/list/debris = list()

hitsound_type = PROJECTILE_HITSOUND_GLASS

/obj/machinery/door/window/Initialize(mapload, set_dir)
. = ..()
flags_1 &= ~PREVENT_CLICK_UNDER_1
Expand Down
13 changes: 13 additions & 0 deletions code/game/objects/effects/temporary_visuals/miscellaneous.dm
Original file line number Diff line number Diff line change
Expand Up @@ -544,3 +544,16 @@

/obj/effect/constructing_effect/proc/end()
qdel(src)

/obj/effect/muzzle_flash
icon = 'icons/obj/projectiles.dmi'
icon_state = "muzzle_flash"
layer = ABOVE_MOB_LAYER
plane = GAME_PLANE
appearance_flags = KEEP_APART|TILE_BOUND
var/applied = FALSE

/obj/effect/muzzle_flash/Initialize(mapload, new_icon_state)
. = ..()
if(new_icon_state)
icon_state = new_icon_state
13 changes: 5 additions & 8 deletions code/game/objects/items.dm
Original file line number Diff line number Diff line change
Expand Up @@ -453,14 +453,7 @@ GLOBAL_VAR_INIT(embedpocalypse, FALSE) // if true, all items will be able to emb
SEND_SIGNAL(src, COMSIG_ITEM_HIT_REACT, args)
if((prob(final_block_chance) && COOLDOWN_FINISHED(src, block_cooldown)) || (prob(final_block_chance) && istype(src, /obj/item/shield)))
owner.visible_message("<span class='danger'>[owner] blocks [attack_text] with [src]!</span>")
var/rand_ricochet = pick(list(
'sound/weapons/effects/ric1.ogg',
'sound/weapons/effects/ric2.ogg',
'sound/weapons/effects/ric3.ogg',
'sound/weapons/effects/ric4.ogg',
'sound/weapons/effects/ric5.ogg'
))
playsound(src, rand_ricochet, 100)
playsound(src, 'sound/weapons/effects/deflect.ogg', 100)
if(!istype(src, /obj/item/shield))
COOLDOWN_START(src, block_cooldown, block_cooldown_time)
return 1
Expand Down Expand Up @@ -1099,6 +1092,10 @@ GLOBAL_VAR_INIT(embedpocalypse, FALSE) // if true, all items will be able to emb
if(SEND_SIGNAL(src, COMSIG_ITEM_OFFER_TAKEN, offerer, taker) & COMPONENT_OFFER_INTERRUPT)
return TRUE

///Intended for interactions with guns, like racking
/obj/item/proc/unique_action(mob/living/user)
return

/**
* Returns null if this object cannot be used to interact with physical writing mediums such as paper.
* Returns a list of key attributes for this object interacting with paper otherwise.
Expand Down
10 changes: 5 additions & 5 deletions code/game/objects/obj_defense.dm
Original file line number Diff line number Diff line change
Expand Up @@ -68,13 +68,13 @@
if(3)
take_damage(rand(10, 90), BRUTE, "bomb", 0)

/obj/bullet_act(obj/projectile/P)
/obj/bullet_act(obj/projectile/hitting_projectile)
. = ..()
playsound(src, P.hitsound, 50, TRUE)
if(P.suppressed != SUPPRESSED_VERY)
visible_message("<span class='danger'>[src] is hit by \a [P]!</span>", null, null, COMBAT_MESSAGE_RANGE)
bullet_hit_sfx(hitting_projectile)
if(hitting_projectile.suppressed != SUPPRESSED_VERY)
visible_message("<span class='danger'>[src] is hit by \a [hitting_projectile]!</span>", null, null, COMBAT_MESSAGE_RANGE)
if(!QDELETED(src)) //Bullet on_hit effect might have already destroyed this object
take_damage(P.damage, P.damage_type, P.flag, 0, turn(P.dir, 180), P.armour_penetration)
take_damage(hitting_projectile.damage, hitting_projectile.damage_type, hitting_projectile.flag, 0, turn(hitting_projectile.dir, 180), hitting_projectile.armour_penetration)

///Called to get the damage that hulks will deal to the obj.
/obj/proc/hulk_damage()
Expand Down
2 changes: 2 additions & 0 deletions code/game/objects/structures.dm
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
flags_ricochet = RICOCHET_HARD
ricochet_chance_mod = 0.5

hitsound_type = PROJECTILE_HITSOUND_METAL

var/climb_time = 20
var/climbable = FALSE
var/mob/living/structureclimber
Expand Down
2 changes: 2 additions & 0 deletions code/game/objects/structures/beds_chairs/pew.dm
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
buildstackamount = 3
item_chair = null

hitsound_type = PROJECTILE_HITSOUND_WOOD

/obj/structure/chair/pew/left
name = "left wooden pew end"
icon_state = "pewend_left"
Expand Down
2 changes: 2 additions & 0 deletions code/game/objects/structures/dresser.dm
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
density = TRUE
anchored = TRUE

hitsound_type = PROJECTILE_HITSOUND_WOOD

/obj/structure/dresser/attackby(obj/item/I, mob/user, params)
if(I.tool_behaviour == TOOL_WRENCH)
to_chat(user, "<span class='notice'>You begin to [anchored ? "unwrench" : "wrench"] [src].</span>")
Expand Down
10 changes: 10 additions & 0 deletions code/game/objects/structures/flora.dm
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
max_integrity = 40
anchored = TRUE

hitsound_type = PROJECTILE_HITSOUND_NON_LIVING

/obj/structure/flora/play_attack_sound(damage_amount, damage_type = BRUTE, damage_flag = 0)
switch(damage_type)
if(BRUTE)
Expand All @@ -22,6 +24,8 @@
layer = FLY_LAYER
var/log_amount = 10

hitsound_type = PROJECTILE_HITSOUND_WOOD

/obj/structure/flora/tree/ComponentInitialize()
. = ..()
AddComponent(/datum/component/largetransparency)
Expand Down Expand Up @@ -52,6 +56,8 @@
density = FALSE
pixel_x = -16

hitsound_type = PROJECTILE_HITSOUND_WOOD

/obj/structure/flora/tree/pine
name = "pine tree"
desc = "A coniferous pine tree."
Expand Down Expand Up @@ -370,6 +376,8 @@
icon_state = "random_plant"
var/list/static/states

hitsound_type = PROJECTILE_HITSOUND_STONE

/obj/item/kirbyplants/random/Initialize()
. = ..()
icon = 'icons/obj/flora/plants.dmi'
Expand Down Expand Up @@ -424,6 +432,8 @@
max_integrity = 100
var/obj/item/stack/mineResult = /obj/item/stack/ore/glass/basalt

hitsound_type = PROJECTILE_HITSOUND_STONE

/obj/structure/flora/rock/Initialize()
. = ..()
icon_state = "[base_icon_state][rand(1,3)]"
Expand Down
2 changes: 2 additions & 0 deletions code/game/objects/structures/lavaland/necropolis_tendril.dm
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
anchored = TRUE
resistance_flags = FIRE_PROOF | LAVA_PROOF

hitsound_type = PROJECTILE_HITSOUND_FLESH

var/gps = null
var/obj/effect/light_emitter/tendril/emitted_light

Expand Down
6 changes: 6 additions & 0 deletions code/game/objects/structures/tables_racks.dm
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,8 @@
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 100)
var/list/debris = list()

hitsound_type = PROJECTILE_HITSOUND_GLASS

/obj/structure/table/glass/Initialize()
. = ..()
debris += new frame
Expand Down Expand Up @@ -424,6 +426,8 @@
smoothing_groups = list(SMOOTH_GROUP_WOOD_TABLES) //Don't smooth with SMOOTH_GROUP_TABLES
canSmoothWith = list(SMOOTH_GROUP_WOOD_TABLES)

hitsound_type = PROJECTILE_HITSOUND_WOOD

/obj/structure/table/wood/narsie_act(total_override = TRUE)
if(!total_override)
..()
Expand Down Expand Up @@ -776,6 +780,8 @@
armor = list("melee" = 10, "bullet" = 30, "laser" = 30, "energy" = 100, "bomb" = 20, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 70) //trolld
can_flip = FALSE //same as reinforced and theres no sprites for it

hitsound_type = PROJECTILE_HITSOUND_WOOD

/obj/structure/table/wood/reinforced/deconstruction_hints(mob/user)
if(deconstruction_ready)
return "<span class='notice'>The top cover has been <i>pried</i> loose and the main frame's <b>bolts</b> are exposed.</span>"
Expand Down
2 changes: 2 additions & 0 deletions code/game/objects/structures/window.dm
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@
flags_ricochet = RICOCHET_HARD
ricochet_chance_mod = 0.4

hitsound_type = PROJECTILE_HITSOUND_GLASS

/obj/structure/window/examine(mob/user)
. = ..()
if(flags_1 & NODECONSTRUCT_1)
Expand Down
Loading

0 comments on commit bf4671f

Please sign in to comment.