Revert "?"

This reverts commit c6b5bac0d8.
This commit is contained in:
EmeraldSundisk
2020-07-04 21:39:23 -07:00
parent c6b5bac0d8
commit 45a14f16d4
871 changed files with 96125 additions and 411183 deletions
+12 -8
View File
@@ -1,17 +1,21 @@
/obj/item/ammo_casing/proc/fire_casing(atom/target, mob/living/user, params, distro, quiet, zone_override, spread, atom/fired_from)
distro += variance
for (var/i = max(1, pellets), i > 0, i--)
var/targloc = get_turf(target)
ready_proj(target, user, quiet, zone_override, fired_from)
var/targloc = get_turf(target)
ready_proj(target, user, quiet, zone_override, fired_from)
if(pellets == 1)
if(distro) //We have to spread a pixel-precision bullet. throw_proj was called before so angles should exist by now...
if(randomspread)
spread = round((rand() - 0.5) * distro)
else //Smart spread
spread = round((i / pellets - 0.5) * distro)
spread = round(1 - 0.5) * distro
if(!throw_proj(target, targloc, user, params, spread))
return 0
if(i > 1)
newshot()
return FALSE
else
if(isnull(BB))
return FALSE
AddComponent(/datum/component/pellet_cloud, projectile_type, pellets)
SEND_SIGNAL(src, COMSIG_PELLET_CLOUD_INIT, target, user, fired_from, randomspread, spread, zone_override, params, distro)
if(click_cooldown_override)
user.changeNext_move(click_cooldown_override)
else
@@ -31,7 +35,7 @@
else
BB.def_zone = user.zone_selected
BB.suppressed = quiet
if(isgun(fired_from))
var/obj/item/gun/G = fired_from
BB.damage *= G.projectile_damage_multiplier
@@ -21,3 +21,16 @@
name = "1.95x129mm incendiary bullet casing"
desc = "A 1.95x129mm bullet casing designed with a chemical-filled capsule on the tip that when bursted, reacts with the atmosphere to produce a fireball, engulfing the target in flames."
projectile_type = /obj/item/projectile/bullet/incendiary/mm195x129
/obj/item/ammo_casing/mm712x82/match
name = "7.12x82mm match bullet casing"
desc = "A 7.12x82mm bullet casing manufactured to unfailingly high standards, you could pull off some cool trickshots with this."
projectile_type = /obj/item/projectile/bullet/mm712x82_match
/obj/item/projectile/bullet/mm712x82_match
name = "7.12x82mm match bullet"
damage = 40
ricochets_max = 2
ricochet_chance = 60
ricochet_auto_aim_range = 4
ricochet_incidence_leeway = 35
@@ -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
@@ -52,4 +51,3 @@
desc = "A .50AE bullet casing."
caliber = ".50"
projectile_type = /obj/item/projectile/bullet/a50AE
@@ -11,6 +11,12 @@
desc = "A .357 armor-piercing bullet casing."
projectile_type = /obj/item/projectile/bullet/a357/ap
/obj/item/ammo_casing/a357/match
name = ".357 match bullet casing"
desc = "A .357 bullet casing, manufactured to exceedingly high standards."
caliber = "357"
projectile_type = /obj/item/projectile/bullet/a357/match
// 7.62x38mmR (Nagant Revolver)
/obj/item/ammo_casing/n762
@@ -47,4 +53,19 @@
name = ".38 Iceblox bullet casing"
desc = "A .38 Iceblox bullet casing."
caliber = "38"
projectile_type = /obj/item/projectile/bullet/c38/iceblox
projectile_type = /obj/item/projectile/bullet/c38/iceblox
/obj/item/ammo_casing/c38/match
name = ".38 Match bullet casing"
desc = "A .38 bullet casing, manufactured to exceedingly high standards."
projectile_type = /obj/item/projectile/bullet/c38/match
/obj/item/ammo_casing/c38/match/bouncy
name = ".38 Rubber bullet casing"
desc = "A .38 rubber bullet casing, manufactured to exceedingly high standards."
projectile_type = /obj/item/projectile/bullet/c38/match/bouncy
/obj/item/ammo_casing/c38/dumdum
name = ".38 DumDum bullet casing"
desc = "A .38 DumDum bullet casing."
projectile_type = /obj/item/projectile/bullet/c38/dumdum
@@ -143,3 +143,12 @@
reagents.add_reagent(/datum/reagent/toxin/acid/fluacid, 5) //this and the acid equal about 25ish burn, not counting the minute toxin damage dealt by their metabolism, this makes each dart about as lethal as a stechkin shot in upfront damage
reagents.add_reagent(/datum/reagent/toxin/acid, 5)
reagents.add_reagent(/datum/reagent/consumable/frostoil, 10) //tempgun slowdown goes both ways and adds to the burn
/obj/item/ammo_casing/shotgun/incapacitate
name = "custom incapacitating shot"
desc = "A shotgun casing filled with... something. used to incapacitate targets."
icon_state = "bountyshell"
projectile_type = /obj/item/projectile/bullet/pellet/shotgun_incapacitate
pellets = 12//double the pellets, but half the stun power of each, which makes this best for just dumping right in someone's face.
variance = 25
custom_materials = list(/datum/material/iron=4000)
@@ -114,11 +114,13 @@
/obj/item/ammo_box/update_icon()
. = ..()
desc = "[initial(desc)] There [stored_ammo.len == 1 ? "is" : "are"] [stored_ammo.len] shell\s left!"
for (var/material in bullet_cost)
var/material_amount = bullet_cost[material]
material_amount = (material_amount*stored_ammo.len) + base_cost[material]
custom_materials[material] = material_amount
set_custom_materials(custom_materials)//make sure we setup the correct properties again
if(length(bullet_cost))
var/temp_materials = custom_materials.Copy()
for (var/material in bullet_cost)
var/material_amount = bullet_cost[material]
material_amount = (material_amount*stored_ammo.len) + base_cost[material]
temp_materials[material] = material_amount
set_custom_materials(temp_materials)
/obj/item/ammo_box/update_icon_state()
switch(multiple_sprites)
@@ -7,6 +7,11 @@
max_ammo = 7
multiple_sprites = 1
/obj/item/ammo_box/a357/match
name = "speed loader (.357 Match)"
desc = "Designed to quickly reload revolvers. These rounds are manufactured within extremely tight tolerances, making them easy to show off trickshots with."
ammo_type = /obj/item/ammo_casing/a357/match
/obj/item/ammo_box/a357/ap
name = "speed loader (.357 AP)"
ammo_type = /obj/item/ammo_casing/a357/ap
@@ -40,6 +45,16 @@
desc = "Designed to quickly reload revolvers. Iceblox bullets contain a cryogenic payload."
ammo_type = /obj/item/ammo_casing/c38/iceblox
/obj/item/ammo_box/c38/dumdum
name = "speed loader (.38 DumDum)"
desc = "Designed to quickly reload revolvers. DumDum bullets shatter on impact and shred the target's innards, likely getting caught inside."
ammo_type = /obj/item/ammo_casing/c38/dumdum
/obj/item/ammo_box/c38/match
name = "speed loader (.38 Match)"
desc = "Designed to quickly reload revolvers. These rounds are manufactured within extremely tight tolerances, making them easy to show off trickshots with."
ammo_type = /obj/item/ammo_casing/c38/match
/obj/item/ammo_box/c9mm
name = "ammo box (9mm)"
icon_state = "9mmbox"
@@ -20,3 +20,7 @@
/obj/item/ammo_box/magazine/mm195x129/update_icon()
..()
icon_state = "a762-[round(ammo_count(),10)]"
/obj/item/ammo_box/magazine/mm712x82/match
name = "box magazine (Match 7.12x82mm)"
ammo_type = /obj/item/ammo_casing/mm712x82/match
@@ -50,3 +50,8 @@
name = "riot shotgun internal magazine"
ammo_type = /obj/item/ammo_casing/shotgun/rubbershot
max_ammo = 6
/obj/item/ammo_box/magazine/internal/shot/bounty
name = "triple-barrel shotgun internal magazine"
ammo_type = /obj/item/ammo_casing/shotgun/incapacitate
max_ammo = 3
@@ -59,7 +59,7 @@
/obj/item/gun/ballistic/bow/pipe
name = "pipe bow"
desc = "Some sort of pipe made projectile weapon made of a durathread string and lots of bending. Used to fire arrows."
desc = "Some sort of pipe-based projectile weapon made of string and lots of bending. Used to fire arrows."
icon_state = "pipebow"
item_state = "pipebow"
force = 0
force = 2
@@ -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)
@@ -144,13 +144,13 @@
user.visible_message("<span class='warning'>[user] aims [src] at the ground! It looks like [user.p_theyre()] performing a sick rocket jump!</span>", \
"<span class='userdanger'>You aim [src] at the ground to perform a bisnasty rocket jump...</span>")
if(can_shoot())
user.notransform = TRUE
user.mob_transforming = TRUE
playsound(src, 'sound/vehicles/rocketlaunch.ogg', 80, 1, 5)
animate(user, pixel_z = 300, time = 30, easing = LINEAR_EASING)
sleep(70)
animate(user, pixel_z = 0, time = 5, easing = LINEAR_EASING)
sleep(5)
user.notransform = FALSE
user.mob_transforming = FALSE
process_fire(user, user, TRUE)
if(!QDELETED(user)) //if they weren't gibbed by the explosion, take care of them for good.
user.gib()
@@ -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>")
@@ -319,24 +319,23 @@
/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."
desc = "A shoddy break-action breechloaded shotgun. Its lacklustre construction shows in its lesser effectiveness."
icon_state = "ishotgun"
item_state = "shotgun"
w_class = WEIGHT_CLASS_BULKY
weapon_weight = WEAPON_MEDIUM
weapon_weight = WEAPON_MEDIUM // prevents shooting 2 at once, but doesn't require 2 hands
force = 10
slot_flags = null
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
/obj/item/gun/ballistic/revolver/doublebarrel/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))
if(A.use_tool(src, user, 0, 10, skill_gain_mult = EASY_USE_TOOL_MULT))
slot_flags = ITEM_SLOT_BACK
to_chat(user, "<span class='notice'>You tie the lengths of cable to the shotgun, making a sling.</span>")
slung = TRUE
@@ -358,7 +357,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 wont want to shoot two of these at once if you value your 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, skill_gain_mult = EASY_USE_TOOL_MULT))
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."
@@ -303,3 +320,18 @@
return TRUE
// DOUBLE BARRELED SHOTGUN and IMPROVISED SHOTGUN are in revolver.dm
/obj/item/gun/ballistic/shotgun/doublebarrel/hook
name = "hook modified sawn-off shotgun"
desc = "Range isn't an issue when you can bring your victim to you."
icon_state = "hookshotgun"
item_state = "shotgun"
mag_type = /obj/item/ammo_box/magazine/internal/shot/bounty
w_class = WEIGHT_CLASS_BULKY
weapon_weight = WEAPON_MEDIUM
force = 16 //it has a hook on it
attack_verb = list("slashed", "hooked", "stabbed")
hitsound = 'sound/weapons/bladeslice.ogg'
//our hook gun!
var/obj/item/gun/magic/hook/bounty/hook
var/toggled = FALSE
@@ -34,13 +34,6 @@
righthand_file = 'icons/mob/inhands/weapons/guns_righthand.dmi'
ammo_type = list(/obj/item/ammo_casing/energy/kinetic/premium)
/obj/item/gun/energy/kinetic_accelerator/premiumka/dropped(mob/user)
. = ..()
if(!QDELING(src) && !holds_charge)
// Put it on a delay because moving item from slot to hand
// calls dropped().
addtimer(CALLBACK(src, .proc/empty_if_not_held), 1.60)
/obj/item/ammo_casing/energy/kinetic/premium
projectile_type = /obj/item/projectile/kinetic/premium
@@ -151,7 +144,7 @@
addtimer(CALLBACK(src, .proc/empty_if_not_held), 2)
/obj/item/gun/energy/kinetic_accelerator/proc/empty_if_not_held()
if(!ismob(loc))
if(!ismob(loc) && !istype(loc, /obj/item/integrated_circuit))
empty()
/obj/item/gun/energy/kinetic_accelerator/proc/empty()
+1 -1
View File
@@ -9,7 +9,7 @@
fire_sound = 'sound/weapons/emitter.ogg'
flags_1 = CONDUCT_1
w_class = WEIGHT_CLASS_HUGE
var/checks_antimagic = FALSE
var/checks_antimagic = TRUE
var/max_charges = 6
var/charges = 0
var/recharge_rate = 4
+99 -23
View File
@@ -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,9 +58,25 @@
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
var/ricochets_max = 2
var/ricochet_chance = 30
/// 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
//Hitscan
var/hitscan = FALSE //Whether this is hitscan. If it is, speed is basically ignored.
@@ -131,6 +149,11 @@
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()
@@ -146,6 +169,7 @@
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
@@ -165,6 +189,14 @@
/obj/item/projectile/proc/on_hit(atom/target, blocked = FALSE)
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
@@ -207,7 +239,7 @@
else
if(ishuman(target))
var/mob/living/carbon/human/H = target
new /obj/effect/temp_visual/dir_setting/bloodsplatter(target_loca, splatter_dir, bloodtype_to_color(H.dna.blood_type))
new /obj/effect/temp_visual/dir_setting/bloodsplatter(target_loca, splatter_dir, H.dna.species.exotic_blood_color)
else
new /obj/effect/temp_visual/dir_setting/bloodsplatter(target_loca, splatter_dir, bloodtype_to_color())
@@ -216,10 +248,13 @@
new impact_effect_type(target_loca, hitx, hity)
var/organ_hit_text = ""
var/limb_hit = L.check_limb_hit(def_zone)//to get the correct message info.
var/limb_hit = hit_limb
if(limb_hit)
organ_hit_text = " in \the [parse_zone(limb_hit)]"
if(suppressed)
if(suppressed==SUPPRESSED_VERY)
playsound(loc, hitsound, 5, TRUE, -1)
else 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
@@ -250,7 +285,23 @@
return 50 //if the projectile doesn't do damage, play its hitsound at 50% volume
/obj/item/projectile/proc/on_ricochet(atom/A)
return
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
@@ -258,18 +309,19 @@
beam_segments[beam_index] = null
/obj/item/projectile/Bump(atom/A)
if(!trajectory)
return
var/turf/T = get_turf(A)
if(trajectory && check_ricochet(A) && check_ricochet_flag(A) && ricochets < ricochets_max)
if(check_ricochet(A) && A.handle_ricochet(src)) //if you can ricochet, attempt to ricochet off the object
on_ricochet(A) //if allowed, use autoaim to ricochet into someone, otherwise default to ricocheting off the object from above
var/datum/point/pcache = trajectory.copy_to()
ricochets++
if(A.handle_ricochet(src))
on_ricochet(A)
ignore_source_check = TRUE
decayedRange = max(0, decayedRange - reflect_range_decrease)
range = decayedRange
if(hitscan)
store_hitscan_collision(pcache)
return TRUE
if(hitscan)
store_hitscan_collision(pcache)
decayedRange = max(0, decayedRange - reflect_range_decrease)
ricochet_chance *= ricochet_decay_chance
damage *= ricochet_decay_damage
range = decayedRange
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)
@@ -344,13 +396,30 @@
return T
//Returns null if nothing at all was found.
/obj/item/projectile/proc/check_ricochet()
if(prob(ricochet_chance))
return TRUE
return 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)
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
else
CRASH("Invalid return value for projectile ricochet check from [A].")
/obj/item/projectile/proc/check_ricochet_flag(atom/A)
if(A.flags_1 & CHECK_RICOCHET_1)
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
@@ -391,6 +460,8 @@
/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)
@@ -431,6 +502,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)
@@ -457,6 +529,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)
@@ -505,7 +578,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)
@@ -515,6 +588,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
@@ -550,7 +624,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)
@@ -47,4 +47,4 @@
if(L.getStaminaLoss() >= 60)
L.Sleeping(300)
else
L.adjustStaminaLoss(25)
L.adjustStaminaLoss(25)
@@ -15,6 +15,38 @@
/obj/item/projectile/bullet/c38
name = ".38 bullet"
damage = 25
ricochets_max = 2
ricochet_chance = 50
ricochet_auto_aim_angle = 10
ricochet_auto_aim_range = 3
/obj/item/projectile/bullet/c38/match
name = ".38 Match bullet"
ricochets_max = 4
ricochet_chance = 100
ricochet_auto_aim_angle = 40
ricochet_auto_aim_range = 5
ricochet_incidence_leeway = 50
ricochet_decay_chance = 1
ricochet_decay_damage = 1
/obj/item/projectile/bullet/c38/match/bouncy
name = ".38 Rubber bullet"
damage = 10
stamina = 30
armour_penetration = -30
ricochets_max = 6
ricochet_incidence_leeway = 70
ricochet_chance = 130
ricochet_decay_damage = 0.8
shrapnel_type = NONE
/obj/item/projectile/bullet/c38/dumdum
name = ".38 DumDum bullet"
damage = 15
armour_penetration = -30
ricochets_max = 0
shrapnel_type = /obj/item/shrapnel/bullet/c38/dumdum
/obj/item/projectile/bullet/c38/rubber
name = ".38 rubber bullet"
@@ -24,6 +56,7 @@
/obj/item/projectile/bullet/c38/trac
name = ".38 TRAC bullet"
damage = 10
ricochets_max = 0
/obj/item/projectile/bullet/c38/trac/on_hit(atom/target, blocked = FALSE)
. = ..()
@@ -39,6 +72,7 @@
/obj/item/projectile/bullet/c38/hotshot //similar to incendiary bullets, but do not leave a flaming trail
name = ".38 Hot Shot bullet"
damage = 20
ricochets_max = 0
/obj/item/projectile/bullet/c38/hotshot/on_hit(atom/target, blocked = FALSE)
. = ..()
@@ -51,6 +85,7 @@
name = ".38 Iceblox bullet"
damage = 20
var/temperature = 100
ricochets_max = 0
/obj/item/projectile/bullet/c38/iceblox/on_hit(atom/target, blocked = FALSE)
. = ..()
@@ -68,4 +103,14 @@
/obj/item/projectile/bullet/a357/ap
name = ".357 armor-piercing bullet"
damage = 45
armour_penetration = 45
armour_penetration = 45
// admin only really, for ocelot memes
/obj/item/projectile/bullet/a357/match
name = ".357 match bullet"
ricochets_max = 5
ricochet_chance = 140
ricochet_auto_aim_angle = 50
ricochet_auto_aim_range = 6
ricochet_incidence_leeway = 80
ricochet_decay_chance = 1
@@ -112,3 +112,8 @@
/obj/item/projectile/bullet/seed
damage = 4
stamina = 1
/obj/item/projectile/bullet/pellet/shotgun_incapacitate
name = "incapacitating pellet"
damage = 1
stamina = 6
+2 -2
View File
@@ -121,10 +121,10 @@
qdel(src)
/proc/wabbajack(mob/living/M)
if(!istype(M) || M.stat == DEAD || M.notransform || (GODMODE & M.status_flags))
if(!istype(M) || M.stat == DEAD || M.mob_transforming || (GODMODE & M.status_flags))
return
M.notransform = TRUE
M.mob_transforming = TRUE
M.Paralyze(INFINITY)
M.icon = null
M.cut_overlays()