Merge remote-tracking branch 'upstream/master' into embed-changes
This commit is contained in:
@@ -44,7 +44,6 @@
|
||||
desc = "A 9mm incendiary bullet casing."
|
||||
projectile_type = /obj/item/projectile/bullet/incendiary/c9mm
|
||||
|
||||
|
||||
// .50AE (Desert Eagle)
|
||||
|
||||
/obj/item/ammo_casing/a50AE
|
||||
@@ -53,3 +52,16 @@
|
||||
caliber = ".50"
|
||||
projectile_type = /obj/item/projectile/bullet/a50AE
|
||||
|
||||
// .32 ACP (Improvised Pistol)
|
||||
|
||||
/obj/item/ammo_casing/c32acp
|
||||
name = ".32 bullet casing"
|
||||
desc = "A .32 bullet casing."
|
||||
caliber = "c32acp"
|
||||
projectile_type = /obj/item/projectile/bullet/c32acp
|
||||
|
||||
/obj/item/ammo_casing/r32acp
|
||||
name = ".32 rubber bullet casing"
|
||||
desc = "A .32 rubber bullet casing."
|
||||
caliber = "c32acp"
|
||||
projectile_type = /obj/item/projectile/bullet/r32acp
|
||||
|
||||
@@ -12,6 +12,15 @@
|
||||
e_cost = 200
|
||||
select_name = "kill"
|
||||
|
||||
/obj/item/ammo_casing/energy/lasergun/improvised
|
||||
projectile_type = /obj/item/projectile/beam/weak/improvised
|
||||
e_cost = 200
|
||||
select_name = "kill"
|
||||
|
||||
/obj/item/ammo_casing/energy/lasergun/improvised/upgraded
|
||||
projectile_type = /obj/item/projectile/beam/weak
|
||||
e_cost = 100
|
||||
|
||||
/obj/item/ammo_casing/energy/laser/hos
|
||||
e_cost = 100
|
||||
|
||||
|
||||
@@ -66,3 +66,15 @@
|
||||
caliber = ".50"
|
||||
max_ammo = 7
|
||||
multiple_sprites = 1
|
||||
|
||||
/obj/item/ammo_box/magazine/m32acp
|
||||
name = "pistol magazine (.32)"
|
||||
desc = "A crudely construction pistol magazine that holds .32 ACP rounds. It looks like it can only fit eight bullets."
|
||||
icon_state = "32acp"
|
||||
ammo_type = /obj/item/ammo_casing/c32acp
|
||||
caliber = "c32acp"
|
||||
max_ammo = 8
|
||||
multiple_sprites = 2
|
||||
|
||||
/obj/item/ammo_box/magazine/m32acp/empty
|
||||
start_empty = 1
|
||||
|
||||
@@ -53,6 +53,7 @@
|
||||
..()
|
||||
|
||||
/obj/item/minigunpack/dropped(mob/user)
|
||||
. = ..()
|
||||
if(armed)
|
||||
user.dropItemToGround(gun, TRUE)
|
||||
|
||||
@@ -125,6 +126,7 @@
|
||||
return
|
||||
|
||||
/obj/item/gun/ballistic/minigun/dropped(mob/user)
|
||||
. = ..()
|
||||
if(ammo_pack)
|
||||
ammo_pack.attach_gun(user)
|
||||
else
|
||||
@@ -144,4 +146,5 @@
|
||||
. = ..()
|
||||
|
||||
/obj/item/gun/ballistic/minigun/dropped(mob/living/user)
|
||||
. = ..()
|
||||
ammo_pack.attach_gun(user)
|
||||
|
||||
@@ -115,6 +115,7 @@
|
||||
icon_state = "flatgun"
|
||||
|
||||
/obj/item/gun/ballistic/automatic/pistol/stickman/pickup(mob/living/user)
|
||||
. = ..()
|
||||
to_chat(user, "<span class='notice'>As you try to pick up [src], it slips out of your grip..</span>")
|
||||
if(prob(50))
|
||||
to_chat(user, "<span class='notice'>..and vanishes from your vision! Where the hell did it go?</span>")
|
||||
@@ -155,3 +156,19 @@
|
||||
name = "Syndicate Anti Tank Pistol"
|
||||
desc = "A massively impractical and silly monstrosity of a pistol that fires .50 calliber rounds. The recoil is likely to dislocate a variety of joints without proper bracing."
|
||||
pin = /obj/item/firing_pin/implant/pindicate
|
||||
|
||||
////////////Improvised Pistol////////////
|
||||
|
||||
/obj/item/gun/ballistic/automatic/pistol/improvised
|
||||
name = "Improvised Pistol"
|
||||
desc = "An improvised pocket-sized pistol that fires .32 calibre rounds. It looks incredibly flimsy."
|
||||
icon_state = "ipistol"
|
||||
item_state = "pistol"
|
||||
mag_type = /obj/item/ammo_box/magazine/m32acp
|
||||
fire_delay = 7.5
|
||||
can_suppress = FALSE
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
spread = 15 // Keep the spread between 15 and 20. This hardlocks it into being a mid-range pistol, the magazine size means you're allowed to miss. Fills the mid-range niche that slugs/rifle and buckshot doesn't fill.
|
||||
|
||||
/obj/item/gun/ballistic/automatic/pistol/improvised/nomag
|
||||
spawnwithmagazine = FALSE // For crafting as you shouldn't get eight bullets for free otherwise people will reaper reload.
|
||||
|
||||
@@ -319,7 +319,6 @@
|
||||
|
||||
/obj/item/gun/ballistic/revolver/doublebarrel/improvised
|
||||
name = "improvised shotgun"
|
||||
desc = "Essentially a tube that aims shotgun shells."
|
||||
desc = "A shoddy break-action breechloaded shotgun. Its lacklustre construction will probably result in it hurting people less than a normal shotgun."
|
||||
icon_state = "ishotgun"
|
||||
item_state = "shotgun"
|
||||
@@ -330,8 +329,9 @@
|
||||
mag_type = /obj/item/ammo_box/magazine/internal/shot/improvised
|
||||
sawn_desc = "I'm just here for the gasoline."
|
||||
unique_reskin = null
|
||||
projectile_damage_multiplier = 0.8
|
||||
projectile_damage_multiplier = 0.9
|
||||
var/slung = FALSE
|
||||
weapon_weight = WEAPON_HEAVY
|
||||
|
||||
/obj/item/gun/ballistic/revolver/doublebarrel/improvised/attackby(obj/item/A, mob/user, params)
|
||||
..()
|
||||
@@ -358,7 +358,7 @@
|
||||
|
||||
/obj/item/gun/ballistic/revolver/doublebarrel/improvised/sawn
|
||||
name = "sawn-off improvised shotgun"
|
||||
desc = "A single-shot shotgun. Better not miss."
|
||||
desc = "The barrel and stock have been sawn and filed down; it can fit in backpacks. You still need two hands to fire this, if you value unbroken wrists."
|
||||
icon_state = "ishotgun"
|
||||
item_state = "gun"
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
|
||||
@@ -131,6 +131,7 @@
|
||||
desc = "A bolt-action breechloaded rifle that takes 7.62mm bullets."
|
||||
mag_type = /obj/item/ammo_box/magazine/internal/boltaction/improvised
|
||||
can_bayonet = FALSE
|
||||
var/slung = FALSE
|
||||
|
||||
/obj/item/gun/ballistic/shotgun/boltaction/pump(mob/M)
|
||||
playsound(M, 'sound/weapons/shotgunpump.ogg', 60, 1)
|
||||
@@ -152,6 +153,22 @@
|
||||
. = ..()
|
||||
. += "The bolt is [bolt_open ? "open" : "closed"]."
|
||||
|
||||
/obj/item/gun/ballistic/shotgun/boltaction/improvised/attackby(obj/item/A, mob/user, params)
|
||||
..()
|
||||
if(istype(A, /obj/item/stack/cable_coil) && !sawn_off)
|
||||
if(A.use_tool(src, user, 0, 10, max_level = JOB_SKILL_BASIC))
|
||||
slot_flags = ITEM_SLOT_BACK
|
||||
to_chat(user, "<span class='notice'>You tie the lengths of cable to the rifle, making a sling.</span>")
|
||||
slung = TRUE
|
||||
update_icon()
|
||||
else
|
||||
to_chat(user, "<span class='warning'>You need at least ten lengths of cable if you want to make a sling!</span>")
|
||||
|
||||
/obj/item/gun/ballistic/shotgun/boltaction/improvised/update_icon()
|
||||
..()
|
||||
if(slung)
|
||||
icon_state += "sling"
|
||||
|
||||
/obj/item/gun/ballistic/shotgun/boltaction/enchanted
|
||||
name = "enchanted bolt action rifle"
|
||||
desc = "Careful not to lose your head."
|
||||
|
||||
@@ -240,3 +240,20 @@
|
||||
chambered.BB.damage *= 5
|
||||
|
||||
process_fire(target, user, TRUE, params)
|
||||
|
||||
////////////////
|
||||
// IMPROVISED //
|
||||
////////////////
|
||||
|
||||
/obj/item/gun/energy/e_gun/old/improvised
|
||||
name = "improvised energy rifle"
|
||||
desc = "A crude imitation of an energy gun. It works, however the beams are poorly focused and most of the energy is wasted before it reaches the target. Welp, it still burns things."
|
||||
icon_state = "improvised"
|
||||
ammo_x_offset = 1
|
||||
shaded_charge = 1
|
||||
ammo_type = list(/obj/item/ammo_casing/energy/lasergun/improvised)
|
||||
|
||||
/obj/item/gun/energy/e_gun/old/improvised/upgraded
|
||||
name = "makeshift energy rifle"
|
||||
desc = "The new lens and upgraded parts gives this a higher capacity and more energy output, however, the shoddy construction still leaves it inferior to Nanotrasen's own energy weapons."
|
||||
ammo_type = list(/obj/item/ammo_casing/energy/lasergun/improvised/upgraded)
|
||||
|
||||
@@ -45,6 +45,8 @@
|
||||
var/pixels_range_leftover = 0
|
||||
/// "leftover" tick pixels and stuff yeah, so we don't round off things and introducing tracing inaccuracy.
|
||||
var/pixels_tick_leftover = 0
|
||||
/// Used to detect jumps in the middle of a pixel_move. Yes, this is ugly as sin code-wise but it works.
|
||||
var/pixel_move_interrupted = FALSE
|
||||
|
||||
/// Pixels moved per second.
|
||||
var/pixels_per_second = TILES_TO_PIXELS(12.5)
|
||||
@@ -56,25 +58,9 @@
|
||||
var/nondirectional_sprite = FALSE //Set TRUE to prevent projectiles from having their sprites rotated based on firing angle
|
||||
var/spread = 0 //amount (in degrees) of projectile spread
|
||||
animate_movement = 0 //Use SLIDE_STEPS in conjunction with legacy
|
||||
/// how many times we've ricochet'd so far (instance variable, not a stat)
|
||||
var/ricochets = 0
|
||||
/// how many times we can ricochet max
|
||||
var/ricochets_max = 0
|
||||
/// 0-100, the base chance of ricocheting, before being modified by the atom we shoot and our chance decay
|
||||
var/ricochet_chance = 0
|
||||
/// 0-1 (or more, I guess) multiplier, the ricochet_chance is modified by multiplying this after each ricochet
|
||||
var/ricochet_decay_chance = 0.7
|
||||
/// 0-1 (or more, I guess) multiplier, the projectile's damage is modified by multiplying this after each ricochet
|
||||
var/ricochet_decay_damage = 0.7
|
||||
/// On ricochet, if nonzero, we consider all mobs within this range of our projectile at the time of ricochet to home in on like Revolver Ocelot, as governed by ricochet_auto_aim_angle
|
||||
var/ricochet_auto_aim_range = 0
|
||||
/// On ricochet, if ricochet_auto_aim_range is nonzero, we'll consider any mobs within this range of the normal angle of incidence to home in on, higher = more auto aim
|
||||
var/ricochet_auto_aim_angle = 30
|
||||
/// the angle of impact must be within this many degrees of the struck surface, set to 0 to allow any angle
|
||||
var/ricochet_incidence_leeway = 40
|
||||
|
||||
///If the object being hit can pass ths damage on to something else, it should not do it for this bullet
|
||||
var/force_hit = FALSE
|
||||
var/ricochets_max = 2
|
||||
var/ricochet_chance = 30
|
||||
|
||||
//Hitscan
|
||||
var/hitscan = FALSE //Whether this is hitscan. If it is, speed is basically ignored.
|
||||
@@ -147,11 +133,6 @@
|
||||
|
||||
var/temporary_unstoppable_movement = FALSE
|
||||
|
||||
///If defined, on hit we create an item of this type then call hitby() on the hit target with this
|
||||
var/shrapnel_type
|
||||
///If TRUE, hit mobs even if they're on the floor and not our target
|
||||
var/hit_stunned_targets = FALSE
|
||||
|
||||
/obj/item/projectile/Initialize()
|
||||
. = ..()
|
||||
permutated = list()
|
||||
@@ -167,7 +148,6 @@
|
||||
on_range()
|
||||
|
||||
/obj/item/projectile/proc/on_range() //if we want there to be effects when they reach the end of their range
|
||||
SEND_SIGNAL(src, COMSIG_PROJECTILE_RANGE_OUT)
|
||||
qdel(src)
|
||||
|
||||
//to get the correct limb (if any) for the projectile hit message
|
||||
@@ -184,17 +164,17 @@
|
||||
/obj/item/projectile/proc/prehit(atom/target)
|
||||
return TRUE
|
||||
|
||||
/obj/item/projectile/proc/on_hit(atom/target, blocked = FALSE)
|
||||
/**
|
||||
* Called when we hit something.
|
||||
*
|
||||
* @params
|
||||
* * target - what we hit
|
||||
* * blocked - 0 to 100 percentage mitigation/block
|
||||
* * def zone - where we hit if we hit a mob.
|
||||
*/
|
||||
/obj/item/projectile/proc/on_hit(atom/target, blocked = 0, def_zone)
|
||||
if(fired_from)
|
||||
SEND_SIGNAL(fired_from, COMSIG_PROJECTILE_ON_HIT, firer, target, Angle)
|
||||
|
||||
// i know that this is probably more with wands and gun mods in mind, but it's a bit silly that the projectile on_hit signal doesn't ping the projectile itself.
|
||||
// maybe we care what the projectile thinks! See about combining these via args some time when it's not 5AM
|
||||
var/obj/item/bodypart/hit_limb
|
||||
if(isliving(target))
|
||||
var/mob/living/L = target
|
||||
hit_limb = L.check_limb_hit(def_zone)
|
||||
SEND_SIGNAL(src, COMSIG_PROJECTILE_SELF_ON_HIT, firer, target, Angle, hit_limb)
|
||||
var/turf/target_loca = get_turf(target)
|
||||
|
||||
var/hitx
|
||||
@@ -246,13 +226,10 @@
|
||||
new impact_effect_type(target_loca, hitx, hity)
|
||||
|
||||
var/organ_hit_text = ""
|
||||
var/limb_hit = hit_limb
|
||||
var/limb_hit = L.check_limb_hit(def_zone)//to get the correct message info.
|
||||
if(limb_hit)
|
||||
organ_hit_text = " in \the [parse_zone(limb_hit)]"
|
||||
|
||||
if(suppressed==SUPPRESSED_VERY)
|
||||
playsound(loc, hitsound, 5, TRUE, -1)
|
||||
else if(suppressed)
|
||||
if(suppressed)
|
||||
playsound(loc, hitsound, 5, 1, -1)
|
||||
to_chat(L, "<span class='userdanger'>You're shot by \a [src][organ_hit_text]!</span>")
|
||||
else
|
||||
@@ -282,45 +259,54 @@
|
||||
else
|
||||
return 50 //if the projectile doesn't do damage, play its hitsound at 50% volume
|
||||
|
||||
/obj/item/projectile/proc/on_ricochet(atom/A)
|
||||
if(!ricochet_auto_aim_angle || !ricochet_auto_aim_range)
|
||||
return
|
||||
|
||||
var/mob/living/unlucky_sob
|
||||
var/best_angle = ricochet_auto_aim_angle
|
||||
if(firer && HAS_TRAIT(firer, TRAIT_NICE_SHOT))
|
||||
best_angle += NICE_SHOT_RICOCHET_BONUS
|
||||
for(var/mob/living/L in range(ricochet_auto_aim_range, src.loc))
|
||||
if(L.stat == DEAD || !isInSight(src, L))
|
||||
continue
|
||||
var/our_angle = abs(closer_angle_difference(Angle, get_projectile_angle(src.loc, L.loc)))
|
||||
if(our_angle < best_angle)
|
||||
best_angle = our_angle
|
||||
unlucky_sob = L
|
||||
|
||||
if(unlucky_sob)
|
||||
setAngle(get_projectile_angle(src, unlucky_sob.loc))
|
||||
|
||||
/obj/item/projectile/proc/store_hitscan_collision(datum/point/pcache)
|
||||
beam_segments[beam_index] = pcache
|
||||
beam_index = pcache
|
||||
beam_segments[beam_index] = null
|
||||
|
||||
/obj/item/projectile/Bump(atom/A)
|
||||
var/datum/point/pcache = trajectory.copy_to()
|
||||
var/turf/T = get_turf(A)
|
||||
if(trajectory && ricochets < ricochets_max && check_ricochet_flag(A) && check_ricochet(A))
|
||||
ricochets++
|
||||
if(A.handle_ricochet(src))
|
||||
on_ricochet(A)
|
||||
ignore_source_check = TRUE
|
||||
decayedRange = max(0, decayedRange - reflect_range_decrease)
|
||||
ricochet_chance *= ricochet_decay_chance
|
||||
damage *= ricochet_decay_damage
|
||||
range = decayedRange
|
||||
if(hitscan)
|
||||
store_hitscan_collision(pcache)
|
||||
/**
|
||||
* Determines if we should ricochet off of something.
|
||||
* By default, asks the thing if we should ricochet off it, but because we're called first, we get final say.
|
||||
* Returns TRUE or FALSE.
|
||||
*/
|
||||
/obj/item/projectile/proc/check_ricochet(atom/A)
|
||||
if(ricochets > ricochets_max) //safety thing, we don't care about what the other thing says about this.
|
||||
return FALSE
|
||||
var/them = A.check_projectile_ricochet(src)
|
||||
switch(them)
|
||||
if(PROJECTILE_RICOCHET_PREVENT)
|
||||
return FALSE
|
||||
if(PROJECTILE_RICOCHET_FORCE)
|
||||
return TRUE
|
||||
if(PROJECTILE_RICOCHET_NO)
|
||||
return FALSE
|
||||
if(PROJECTILE_RICOCHET_YES)
|
||||
return prob(ricochet_chance)
|
||||
else
|
||||
CRASH("Invalid return value for projectile ricochet check from [A].")
|
||||
|
||||
/**
|
||||
* Handles ricocheting off of something.
|
||||
* By default, also asks the thing to handle it, but because we're called first, we get final say.
|
||||
*/
|
||||
/obj/item/projectile/proc/handle_ricochet(atom/A)
|
||||
ricochets++
|
||||
ignore_source_check = TRUE
|
||||
decayedRange = max(0, decayedRange - reflect_range_decrease)
|
||||
pixel_move_interrupted = TRUE
|
||||
range = decayedRange
|
||||
return A.handle_projectile_ricochet(src)
|
||||
|
||||
/obj/item/projectile/Bump(atom/A)
|
||||
if(!trajectory)
|
||||
return
|
||||
var/turf/T = get_turf(A)
|
||||
if(check_ricochet(A))
|
||||
var/datum/point/pcache = trajectory.copy_to()
|
||||
if(hitscan)
|
||||
store_hitscan_collision(pcache)
|
||||
handle_ricochet(A)
|
||||
return TRUE
|
||||
|
||||
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.
|
||||
if(def_zone && check_zone(def_zone) != BODY_ZONE_CHEST)
|
||||
@@ -395,21 +381,6 @@
|
||||
return T
|
||||
//Returns null if nothing at all was found.
|
||||
|
||||
/obj/item/projectile/proc/check_ricochet(atom/A)
|
||||
var/chance = ricochet_chance * A.ricochet_chance_mod
|
||||
if(firer && HAS_TRAIT(firer, TRAIT_NICE_SHOT))
|
||||
chance += NICE_SHOT_RICOCHET_BONUS
|
||||
if(prob(chance))
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/obj/item/projectile/proc/check_ricochet_flag(atom/A)
|
||||
if((flag in list("energy", "laser")) && (A.flags_ricochet & RICOCHET_SHINY))
|
||||
return TRUE
|
||||
if((flag in list("bomb", "bullet")) && (A.flags_ricochet & RICOCHET_HARD))
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/// one move is a tile.
|
||||
/obj/item/projectile/proc/return_predicted_turf_after_moves(moves, forced_angle) //I say predicted because there's no telling that the projectile won't change direction/location in flight.
|
||||
if(!trajectory && isnull(forced_angle) && isnull(Angle))
|
||||
@@ -447,8 +418,6 @@
|
||||
/obj/item/projectile/proc/fire(angle, atom/direct_target)
|
||||
if(fired_from)
|
||||
SEND_SIGNAL(fired_from, COMSIG_PROJECTILE_BEFORE_FIRE, src, original) //If no angle needs to resolve it from xo/yo!
|
||||
if(shrapnel_type)
|
||||
AddElement(/datum/element/embed, projectile_payload = shrapnel_type)
|
||||
if(!log_override && firer && original)
|
||||
log_combat(firer, original, "fired at", src, "from [get_area_name(src, TRUE)]")
|
||||
if(direct_target)
|
||||
@@ -489,6 +458,7 @@
|
||||
|
||||
/obj/item/projectile/proc/setAngle(new_angle, hitscan_store_segment = TRUE) //wrapper for overrides.
|
||||
Angle = new_angle
|
||||
pixel_move_interrupted = TRUE
|
||||
if(!nondirectional_sprite)
|
||||
var/matrix/M = new
|
||||
M.Turn(Angle)
|
||||
@@ -515,6 +485,7 @@
|
||||
trajectory.initialize_location(target.x, target.y, target.z, 0, 0)
|
||||
if(hitscan)
|
||||
record_hitscan_start(RETURN_PRECISE_POINT(src))
|
||||
pixel_move_interrupted = TRUE
|
||||
if(zc)
|
||||
after_z_change(old, target)
|
||||
|
||||
@@ -563,7 +534,7 @@
|
||||
* The proc to make the projectile go, using a simulated pixel movement line trace.
|
||||
* Note: deciseconds_equivalent is currently only used for homing, times is the number of times to move pixel_increment_amount.
|
||||
* Trajectory multiplier directly modifies the factor of pixel_increment_amount to go per time.
|
||||
* It's complicated, so probably just don'ot mess with this unless you know what you're doing.
|
||||
* It's complicated, so probably just don't mess with this unless you know what you're doing.
|
||||
*/
|
||||
/obj/item/projectile/proc/pixel_move(times, hitscanning = FALSE, deciseconds_equivalent = world.tick_lag, trajectory_multiplier = 1, allow_animation = TRUE)
|
||||
if(!loc || !trajectory)
|
||||
@@ -573,6 +544,7 @@
|
||||
M.Turn(Angle)
|
||||
transform = M
|
||||
var/forcemoved = FALSE
|
||||
pixel_move_interrupted = FALSE // reset that
|
||||
var/turf/oldloc = loc
|
||||
var/old_px = pixel_x
|
||||
var/old_py = pixel_y
|
||||
@@ -608,7 +580,9 @@
|
||||
if(!--safety)
|
||||
CRASH("[type] took too long (allowed: [CEILING(pixel_increment_amount/world.icon_size,1)*2] moves) to get to its location.")
|
||||
step_towards(src, T)
|
||||
if(QDELETED(src))
|
||||
if(QDELETED(src) || pixel_move_interrupted) // this doesn't take into account with pixel_move_interrupted the portion of the move cut off by any forcemoves, but we're opting to ignore that for now
|
||||
// the reason is the entire point of moving to pixel speed rather than tile speed is smoothness, which will be crucial when pixel movement is done in the future
|
||||
// reverting back to tile is more or less the only way of fixing this issue.
|
||||
return
|
||||
pixels_range_leftover += pixel_increment_amount
|
||||
if(pixels_range_leftover > world.icon_size)
|
||||
|
||||
@@ -39,6 +39,9 @@
|
||||
/obj/item/projectile/beam/weak
|
||||
damage = 15
|
||||
|
||||
/obj/item/projectile/beam/weak/improvised
|
||||
damage = 10
|
||||
|
||||
/obj/item/projectile/beam/weak/penetrator
|
||||
armour_penetration = 50
|
||||
|
||||
|
||||
@@ -47,4 +47,16 @@
|
||||
if(L.getStaminaLoss() >= 60)
|
||||
L.Sleeping(300)
|
||||
else
|
||||
L.adjustStaminaLoss(25)
|
||||
L.adjustStaminaLoss(25)
|
||||
|
||||
// .32 ACP (Improvised Pistol)
|
||||
|
||||
/obj/item/projectile/bullet/c32acp
|
||||
name = ".32 bullet"
|
||||
damage = 13
|
||||
|
||||
/obj/item/projectile/bullet/r32acp
|
||||
name = ".32 rubber bullet"
|
||||
damage = 3
|
||||
eyeblur = 1
|
||||
stamina = 20
|
||||
|
||||
Reference in New Issue
Block a user