diff --git a/code/__DEFINES/traits/declarations.dm b/code/__DEFINES/traits/declarations.dm index 911cc9d1875..11b1e0d2b31 100644 --- a/code/__DEFINES/traits/declarations.dm +++ b/code/__DEFINES/traits/declarations.dm @@ -534,9 +534,6 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai /// Mobs with this trait cannot be hit by projectiles, meaning the projectiles will just go through. #define TRAIT_UNHITTABLE_BY_PROJECTILES "unhittable_by_projectiles" -/// Projectile with this trait will always hit the defined zone of a struck living mob. -#define TRAIT_ALWAYS_HIT_ZONE "always_hit_zone" - /// Mobs with this trait do care about a few grisly things, such as digging up graves. They also really do not like bringing people back to life or tending wounds, but love autopsies and amputations. #define TRAIT_MORBID "morbid" diff --git a/code/_globalvars/traits/_traits.dm b/code/_globalvars/traits/_traits.dm index 8332e806150..8a3697eaa4b 100644 --- a/code/_globalvars/traits/_traits.dm +++ b/code/_globalvars/traits/_traits.dm @@ -647,9 +647,6 @@ GLOBAL_LIST_INIT(traits_by_type, list( /obj/machinery/modular_computer = list( "TRAIT_MODPC_INTERACTING_WITH_FRAME" = TRAIT_MODPC_INTERACTING_WITH_FRAME, ), - /obj/projectile = list( - "TRAIT_ALWAYS_HIT_ZONE" = TRAIT_ALWAYS_HIT_ZONE, - ), /obj/structure = list( "TRAIT_RADSTORM_IMMUNE" = TRAIT_RADSTORM_IMMUNE, ), diff --git a/code/datums/actions/items/reload_rebar.dm b/code/datums/actions/items/reload_rebar.dm new file mode 100644 index 00000000000..a29b02f6b22 --- /dev/null +++ b/code/datums/actions/items/reload_rebar.dm @@ -0,0 +1,5 @@ +/datum/action/item_action/reload_rebar + name = "Reload Rebar" + desc = "Reloads a held crossbow" + button_icon = 'icons/mob/actions/actions_items.dmi' + button_icon_state = "bolts" diff --git a/code/game/objects/items/storage/bags.dm b/code/game/objects/items/storage/bags.dm index 996cd933647..05e1dff79cc 100644 --- a/code/game/objects/items/storage/bags.dm +++ b/code/game/objects/items/storage/bags.dm @@ -581,7 +581,7 @@ worn_icon_state = "rebar_quiver" inhand_icon_state = "rebar_quiver" desc = "A oxygen tank cut in half, used for holding sharpened rods for the rebar crossbow." - slot_flags = ITEM_SLOT_BACK|ITEM_SLOT_SUITSTORE + slot_flags = ITEM_SLOT_BACK|ITEM_SLOT_SUITSTORE|ITEM_SLOT_NECK resistance_flags = FLAMMABLE /obj/item/storage/bag/rebar_quiver/Initialize(mapload) @@ -598,4 +598,58 @@ /obj/item/ammo_casing/rebar/paperball, )) +/obj/item/storage/bag/rebar_quiver/syndicate + icon_state = "syndie_quiver_0" + worn_icon_state = "syndie_quiver_0" + inhand_icon_state = "holyquiver" + desc = "A specialized quiver meant to hold any kind of bolts intended for use with the rebar crossbow. \ + Clearly a better design than a cut up oxygen tank..." + slot_flags = ITEM_SLOT_NECK + resistance_flags = LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF + actions_types = list(/datum/action/item_action/reload_rebar) + +/obj/item/storage/bag/rebar_quiver/syndicate/Initialize(mapload) + . = ..() + atom_storage.max_slots = 20 + atom_storage.max_total_storage = 20 + update_appearance(UPDATE_OVERLAYS) + +/obj/item/storage/bag/rebar_quiver/syndicate/PopulateContents() + for(var/to_fill in 1 to 20) + new /obj/item/ammo_casing/rebar/syndie(src) + +/obj/item/storage/bag/rebar_quiver/syndicate/update_icon_state() + . = ..() + switch(contents.len) + if(0) + icon_state = "syndie_quiver_0" + if(1 to 7) + icon_state = "syndie_quiver_1" + if(8 to 13) + icon_state = "syndie_quiver_2" + if(14 to 20) + icon_state = "syndie_quiver_3" + +/obj/item/storage/bag/rebar_quiver/syndicate/ui_action_click(mob/user, actiontype) + if(istype(actiontype, /datum/action/item_action/reload_rebar)) + reload_held_rebar(user) + +/obj/item/storage/bag/rebar_quiver/syndicate/proc/reload_held_rebar(mob/user) + if(!contents.len) + user.balloon_alert(user, "no bolts left!") + return + var/obj/held_item = user.get_active_held_item() + if(!held_item || !istype(held_item, /obj/item/gun/ballistic/rifle/rebarxbow)) + user.balloon_alert(user, "no held crossbow!") + return + var/obj/item/gun/ballistic/rifle/rebarxbow/held_crossbow = held_item + if(held_crossbow.magazine.contents.len >= held_crossbow.magazine.max_ammo) + user.balloon_alert(user, "no more room!") + return + if(!do_after(user, 0.8 SECONDS, user, IGNORE_USER_LOC_CHANGE)) + return + + var/obj/item/ammo_casing/rebar/ammo_to_load = contents[1] + held_crossbow.attackby(ammo_to_load, user) + #undef ORE_BAG_BALOON_COOLDOWN diff --git a/code/game/objects/items/storage/uplink_kits.dm b/code/game/objects/items/storage/uplink_kits.dm index b54d4d30f3f..05b8a5a0e8a 100644 --- a/code/game/objects/items/storage/uplink_kits.dm +++ b/code/game/objects/items/storage/uplink_kits.dm @@ -346,6 +346,7 @@ /obj/item/storage/box/syndie_kit/rebarxbowsyndie/PopulateContents() new /obj/item/book/granter/crafting_recipe/dusting/rebarxbowsyndie_ammo(src) new /obj/item/gun/ballistic/rifle/rebarxbow/syndie(src) + new /obj/item/storage/bag/rebar_quiver/syndicate(src) /obj/item/storage/box/syndie_kit/origami_bundle name = "origami kit" diff --git a/code/modules/deathmatch/deathmatch_modifier.dm b/code/modules/deathmatch/deathmatch_modifier.dm index dadca49d70a..9faafa91a48 100644 --- a/code/modules/deathmatch/deathmatch_modifier.dm +++ b/code/modules/deathmatch/deathmatch_modifier.dm @@ -232,7 +232,7 @@ projectile.ricochets_max += 2 projectile.min_ricochets += 2 projectile.ricochet_incidence_leeway = 0 - ADD_TRAIT(projectile, TRAIT_ALWAYS_HIT_ZONE, DEATHMATCH_TRAIT) + projectile.accuracy_falloff = 0 /datum/deathmatch_modifier/stormtrooper name = "Stormtrooper Aim" diff --git a/code/modules/mod/modules/modules_security.dm b/code/modules/mod/modules/modules_security.dm index 752273fa074..5da8ff00241 100644 --- a/code/modules/mod/modules/modules_security.dm +++ b/code/modules/mod/modules/modules_security.dm @@ -568,7 +568,7 @@ projectile.ricochets_max += 1 projectile.min_ricochets += 1 projectile.ricochet_incidence_leeway = 0 //allows the projectile to bounce at any angle. - ADD_TRAIT(projectile, TRAIT_ALWAYS_HIT_ZONE, MOD_TRAIT) + projectile.accuracy_falloff = 0 #undef SHOOTING_ASSISTANT_OFF #undef STORMTROOPER_MODE diff --git a/code/modules/projectiles/boxes_magazines/internal/rifle.dm b/code/modules/projectiles/boxes_magazines/internal/rifle.dm index b092e207c10..b1f761831ee 100644 --- a/code/modules/projectiles/boxes_magazines/internal/rifle.dm +++ b/code/modules/projectiles/boxes_magazines/internal/rifle.dm @@ -60,5 +60,5 @@ /obj/item/ammo_box/magazine/internal/boltaction/rebarxbow/syndie max_ammo = 3 caliber = CALIBER_REBAR_SYNDIE - ammo_type = /obj/item/ammo_casing/rebar + ammo_type = /obj/item/ammo_casing/rebar/syndie diff --git a/code/modules/projectiles/guns/ballistic/rifle.dm b/code/modules/projectiles/guns/ballistic/rifle.dm index 024f8353ddb..a79d4db3082 100644 --- a/code/modules/projectiles/guns/ballistic/rifle.dm +++ b/code/modules/projectiles/guns/ballistic/rifle.dm @@ -201,10 +201,9 @@ inhand_icon_state = "rebarxbow" worn_icon_state = "rebarxbow" rack_sound = 'sound/weapons/gun/sniper/rack.ogg' - must_hold_to_load = TRUE mag_display = FALSE empty_indicator = TRUE - bolt_type = BOLT_TYPE_LOCKING + bolt_type = BOLT_TYPE_OPEN semi_auto = FALSE internal_magazine = TRUE can_modify_ammo = FALSE @@ -250,10 +249,22 @@ return FALSE return ..() +/obj/item/gun/ballistic/rifle/rebarxbow/shoot_with_empty_chamber(mob/living/user) + if(chambered || !magazine || !length(magazine.contents)) + return ..() + drop_bolt(user) + /obj/item/gun/ballistic/rifle/rebarxbow/examine(mob/user) . = ..() . += "The crossbow is [bolt_locked ? "not ready" : "ready"] to fire." +/obj/item/gun/ballistic/rifle/rebarxbow/update_overlays() + . = ..() + if(!magazine) + . += "[initial(icon_state)]" + "_empty" + if(!bolt_locked) + . += "[initial(icon_state)]" + "_bolt_locked" + /obj/item/gun/ballistic/rifle/rebarxbow/forced name = "Stressed Rebar Crossbow" desc = "Some idiot decided that they would risk shooting themselves in the face if it meant they could have a draw this crossbow a bit faster. Hopefully, it was worth it." diff --git a/code/modules/projectiles/projectile.dm b/code/modules/projectiles/projectile.dm index 8274217e1f7..5e06f115ace 100644 --- a/code/modules/projectiles/projectile.dm +++ b/code/modules/projectiles/projectile.dm @@ -209,6 +209,10 @@ var/wound_falloff_tile ///How much we want to drop the embed_chance value, if we can embed, per tile, for falloff purposes var/embed_falloff_tile + ///How much accuracy is lost for each tile travelled + var/accuracy_falloff = 7 + ///How much accuracy before falloff starts to matter. Formula is range - falloff * tiles travelled + var/accurate_range = 100 var/static/list/projectile_connections = list(COMSIG_ATOM_ENTERED = PROC_REF(on_entered)) /// If true directly targeted turfs can be hit var/can_hit_turfs = FALSE @@ -452,9 +456,8 @@ store_hitscan_collision(point_cache) return TRUE - if(!HAS_TRAIT(src, TRAIT_ALWAYS_HIT_ZONE)) - var/distance = get_dist(T, starting) // Get the distance between the turf shot from and the mob we hit and use that for the calculations. - def_zone = ran_zone(def_zone, max(100-(7*distance), 5)) //Lower accurancy/longer range tradeoff. 7 is a balanced number to use. + var/distance = get_dist(T, starting) // Get the distance between the turf shot from and the mob we hit and use that for the calculations. + def_zone = ran_zone(def_zone, clamp(accurate_range - (accuracy_falloff * distance), 5, 100)) //Lower accurancy/longer range tradeoff. 7 is a balanced number to use. return process_hit(T, select_target(T, A, A), A) // SELECT TARGET FIRST! diff --git a/code/modules/projectiles/projectile/bullets/rifle.dm b/code/modules/projectiles/projectile/bullets/rifle.dm index 6f14df2f4c8..2915e3e59bd 100644 --- a/code/modules/projectiles/projectile/bullets/rifle.dm +++ b/code/modules/projectiles/projectile/bullets/rifle.dm @@ -140,27 +140,38 @@ /obj/projectile/bullet/rebar/hydrogen name = "metallic hydrogen bolt" icon_state = "rebar_hydrogen" - damage = 40 + damage = 55 speed = 0.6 + projectile_piercing = PASSMOB|PASSVEHICLE + projectile_phasing = ~(PASSMOB|PASSVEHICLE) + phasing_ignore_direct_target = TRUE dismemberment = 0 //goes through clean. damage_type = BRUTE armour_penetration = 30 //very pointy. - projectile_piercing = PASSMOB //felt this might have been a nice compromise for the lower damage for the difficulty of getting it wound_bonus = -15 bare_wound_bonus = 10 + shrapnel_type = /obj/item/ammo_casing/rebar/hydrogen embed_type = /datum/embed_data/rebar_hydrogen embed_falloff_tile = -3 shrapnel_type = /obj/item/ammo_casing/rebar/hydrogen + accurate_range = 205 //15 tiles before falloff starts to kick in + +/obj/projectile/bullet/rebar/hydrogen/Impact(atom/A) + . = ..() + def_zone = ran_zone(def_zone, clamp(205-(7*get_dist(get_turf(A), starting)), 5, 100)) /datum/embed_data/rebar_hydrogen - embed_chance = 50 - fall_chance = 2 - jostle_chance = 3 - ignore_throwspeed_threshold = TRUE - pain_stam_pct = 0.6 - pain_mult = 4 - jostle_pain_mult = 2 - rip_time =18 + embed_chance = 0 + +/obj/projectile/bullet/rebar/hydrogen/on_hit(atom/target, blocked, pierce_hit) + if(isAI(target)) + return BULLET_ACT_FORCE_PIERCE + return ..() + +/obj/projectile/bullet/rebar/hydrogen/process_hit(turf/T, atom/target, atom/bumped, hit_something) + . = ..() + if(pierces >= 3) + qdel(src) /obj/projectile/bullet/rebar/healium name = "healium bolt" diff --git a/icons/mob/actions/actions_items.dmi b/icons/mob/actions/actions_items.dmi index 7aaeb9b36d2..3887804e55d 100644 Binary files a/icons/mob/actions/actions_items.dmi and b/icons/mob/actions/actions_items.dmi differ diff --git a/icons/mob/clothing/back.dmi b/icons/mob/clothing/back.dmi index 8c3748e8667..5bcaa41f5ed 100644 Binary files a/icons/mob/clothing/back.dmi and b/icons/mob/clothing/back.dmi differ diff --git a/icons/mob/clothing/neck.dmi b/icons/mob/clothing/neck.dmi index 3467f752ac3..bd57cb6eee9 100644 Binary files a/icons/mob/clothing/neck.dmi and b/icons/mob/clothing/neck.dmi differ diff --git a/icons/obj/weapons/bows/quivers.dmi b/icons/obj/weapons/bows/quivers.dmi index 615f96ee6af..86e6ffd2b92 100644 Binary files a/icons/obj/weapons/bows/quivers.dmi and b/icons/obj/weapons/bows/quivers.dmi differ diff --git a/icons/obj/weapons/guns/ammo.dmi b/icons/obj/weapons/guns/ammo.dmi index 4cd031af7ee..971bdaf4d20 100644 Binary files a/icons/obj/weapons/guns/ammo.dmi and b/icons/obj/weapons/guns/ammo.dmi differ diff --git a/icons/obj/weapons/guns/ballistic.dmi b/icons/obj/weapons/guns/ballistic.dmi index 824d8b7c0a0..4ebb17baec3 100644 Binary files a/icons/obj/weapons/guns/ballistic.dmi and b/icons/obj/weapons/guns/ballistic.dmi differ diff --git a/tgstation.dme b/tgstation.dme index ca400936f09..6e2024e5fa3 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -845,6 +845,7 @@ #include "code\datums\actions\items\cult_dagger.dm" #include "code\datums\actions\items\hands_free.dm" #include "code\datums\actions\items\organ_action.dm" +#include "code\datums\actions\items\reload_rebar.dm" #include "code\datums\actions\items\set_internals.dm" #include "code\datums\actions\items\stealth_box.dm" #include "code\datums\actions\items\summon_stickmen.dm"