mirror of
https://github.com/Aurorastation/Aurora.3.git
synced 2026-08-30 08:29:57 +01:00
Projectile refactoring madness (#19878)
Refactored the projectile code, mostly in line with TG's now. Refactored various procs that are used or depends on it. Projectiles can now ricochet if enabled to. Damage falloffs with distance. Homing projectiles can now have accuracy falloff with distance. Projectiles have a maximum range. Muzzle flash is configurable per projectile. Impact effect of the projectile is configurable per projectile. Accuracy decreases with distance. Projectiles work with signals and emits them, for easy hooking up from other parts of the code. Meatshielding is now less effective . Impact sound is now configurable per projectile. High risk.
This commit is contained in:
@@ -428,12 +428,13 @@
|
||||
var/disp = dispersion[min(i, dispersion.len)]
|
||||
|
||||
P.accuracy = accuracy + acc
|
||||
P.dispersion = disp
|
||||
P.spread += disp
|
||||
|
||||
P.shot_from = src.name
|
||||
P.suppressed = suppressed
|
||||
|
||||
P.launch_projectile(target)
|
||||
P.preparePixelProjectile(target, get_turf(src))
|
||||
P.fired_from = src
|
||||
P.fire()
|
||||
|
||||
handle_post_fire() // should be safe to not include arguments here, as there are failsafes in effect (?)
|
||||
|
||||
@@ -539,7 +540,7 @@
|
||||
|
||||
//Accuracy modifiers
|
||||
P.accuracy = accuracy + acc_mod
|
||||
P.dispersion = dispersion
|
||||
P.spread += dispersion
|
||||
|
||||
//Increasing accuracy across the board, ever so slightly
|
||||
P.accuracy += 1
|
||||
@@ -556,7 +557,7 @@
|
||||
F = firemodes[sel_mode]
|
||||
if(one_hand_fa_penalty > 2 && !wielded && F?.name == "full auto") // todo: make firemode names defines
|
||||
P.accuracy -= one_hand_fa_penalty * 0.5
|
||||
P.dispersion -= one_hand_fa_penalty * 0.5
|
||||
P.spread -= one_hand_fa_penalty * 0.5
|
||||
|
||||
//does the actual launching of the projectile
|
||||
/obj/item/gun/proc/process_projectile(obj/projectile, mob/user, atom/target, target_zone, params)
|
||||
@@ -573,7 +574,12 @@
|
||||
else if(mob.shock_stage > 70)
|
||||
added_spread = 15
|
||||
|
||||
return !P.launch_from_gun(target, target_zone, user, params, null, added_spread, src)
|
||||
P.preparePixelProjectile(target, src, deviation = added_spread)
|
||||
P.firer = user
|
||||
P.fired_from = src
|
||||
P.def_zone = target_zone
|
||||
|
||||
return !P.fire()
|
||||
|
||||
//Suicide handling.
|
||||
/obj/item/gun/var/mouthshoot = FALSE //To stop people from suiciding twice... >.>
|
||||
|
||||
@@ -80,19 +80,18 @@
|
||||
muzzle_type = /obj/effect/projectile/muzzle/plasma_cutter
|
||||
tracer_type = /obj/effect/projectile/tracer/plasma_cutter
|
||||
impact_type = /obj/effect/projectile/impact/plasma_cutter
|
||||
maiming = TRUE
|
||||
maim_rate = 1
|
||||
|
||||
/obj/projectile/beam/plasmacutter/proc/pass_check(var/turf/simulated/mineral/mine_turf)
|
||||
if(mineral_passes <= 0)
|
||||
return list(null, FALSE) // the projectile stops
|
||||
mineral_passes--
|
||||
var/mineral_destroyed = on_impact(mine_turf)
|
||||
return list(PROJECTILE_CONTINUE, mineral_destroyed) // the projectile tunnels deeper
|
||||
var/mineral_destroyed = on_hit(mine_turf)
|
||||
return list(BULLET_ACT_HIT, mineral_destroyed) // the projectile tunnels deeper
|
||||
|
||||
/obj/projectile/beam/plasmacutter/on_impact(var/atom/A)
|
||||
if(istype(A, /turf/simulated/mineral))
|
||||
var/turf/simulated/mineral/M = A
|
||||
/obj/projectile/beam/plasmacutter/on_hit(atom/target, blocked, def_zone)
|
||||
if(istype(target, /turf/simulated/mineral))
|
||||
var/turf/simulated/mineral/M = target
|
||||
if(prob(33))
|
||||
M.GetDrilled(1)
|
||||
return TRUE
|
||||
|
||||
@@ -13,7 +13,8 @@
|
||||
reagents = new/datum/reagents(reagent_amount)
|
||||
reagents.my_atom = src
|
||||
|
||||
/obj/projectile/bullet/chemdart/on_hit(var/atom/target, var/blocked = 0, var/def_zone = null)
|
||||
/obj/projectile/bullet/chemdart/on_hit(atom/target, blocked, def_zone)
|
||||
. = ..()
|
||||
if(blocked < 100 && ishuman(target))
|
||||
var/mob/living/carbon/human/H = target
|
||||
if(H.can_inject(target_zone=def_zone))
|
||||
|
||||
@@ -300,8 +300,8 @@
|
||||
if(default_parry_check(user, attacker, damage_source) && prob(20))
|
||||
user.visible_message(SPAN_DANGER("\The [user] parries [attack_text] with \the [src]!"))
|
||||
playsound(user.loc, "punchmiss", 50, 1)
|
||||
return PROJECTILE_STOPPED
|
||||
return FALSE
|
||||
return BULLET_ACT_BLOCK
|
||||
return BULLET_ACT_HIT
|
||||
|
||||
/obj/item/gun/projectile/revolver/konyang/pirate
|
||||
name = "reclaimed revolver"
|
||||
|
||||
+1062
-596
File diff suppressed because it is too large
Load Diff
@@ -3,7 +3,6 @@
|
||||
icon_state = "ice_1"
|
||||
damage = 0
|
||||
damage_type = DAMAGE_BURN
|
||||
nodamage = 1
|
||||
check_armor = "energy"
|
||||
|
||||
/obj/projectile/animate/Collide(atom/change)
|
||||
|
||||
@@ -130,10 +130,10 @@
|
||||
damage = 45
|
||||
armor_penetration = 40
|
||||
|
||||
/obj/projectile/beam/pulse/on_hit(var/atom/target, var/blocked = 0)
|
||||
/obj/projectile/beam/pulse/on_hit(atom/target, blocked, def_zone)
|
||||
if(isturf(target))
|
||||
target.ex_act(2)
|
||||
..()
|
||||
. = ..()
|
||||
|
||||
/obj/projectile/beam/pulse/heavy
|
||||
name = "heavy pulse laser"
|
||||
@@ -168,7 +168,8 @@
|
||||
tracer_type = /obj/effect/projectile/tracer/laser
|
||||
impact_type = /obj/effect/projectile/impact/laser
|
||||
|
||||
/obj/projectile/beam/laser_tag/on_hit(var/atom/target, var/blocked = 0)
|
||||
/obj/projectile/beam/laser_tag/on_hit(atom/target, blocked, def_zone)
|
||||
. = ..()
|
||||
if(ishuman(target))
|
||||
var/mob/living/carbon/human/H = target
|
||||
var/obj/item/clothing/suit/armor/riot/laser_tag/LT = H.wear_suit
|
||||
@@ -234,7 +235,7 @@
|
||||
tracer_type = /obj/effect/projectile/tracer/disabler
|
||||
impact_type = /obj/effect/projectile/impact/disabler
|
||||
|
||||
/obj/projectile/beam/disorient/on_hit(var/atom/target, var/blocked = 0)
|
||||
/obj/projectile/beam/disorient/on_hit(atom/target, blocked, def_zone)
|
||||
if(ishuman(target) && blocked < 100 && !issilicon(target) && !isipc(target)) //Make them trip
|
||||
var/mob/living/carbon/human/H = target
|
||||
H.druggy = min(H.druggy + 15, 75)
|
||||
@@ -268,9 +269,9 @@
|
||||
tracer_type = /obj/effect/projectile/tracer/stun
|
||||
impact_type = /obj/effect/projectile/impact/stun
|
||||
|
||||
/obj/projectile/beam/mousegun/on_impact(var/atom/A)
|
||||
mousepulse(A, 1)
|
||||
..()
|
||||
/obj/projectile/beam/mousegun/on_hit(atom/target, blocked, def_zone)
|
||||
mousepulse(target, 1)
|
||||
. = ..()
|
||||
|
||||
/obj/projectile/beam/mousegun/proc/mousepulse(turf/epicenter, range, log=0)
|
||||
if(!epicenter)
|
||||
@@ -309,8 +310,6 @@
|
||||
|
||||
/obj/projectile/beam/mousegun/emag
|
||||
name = "diffuse electrical arc"
|
||||
|
||||
nodamage = FALSE
|
||||
damage_type = DAMAGE_BURN
|
||||
damage = 15
|
||||
agony = 30
|
||||
@@ -349,7 +348,6 @@
|
||||
return TRUE
|
||||
|
||||
/obj/projectile/beam/mousegun/xenofauna
|
||||
nodamage = FALSE
|
||||
damage = 10
|
||||
|
||||
/obj/projectile/beam/mousegun/xenofauna/mousepulse(atom/target, range, log)
|
||||
@@ -376,22 +374,22 @@
|
||||
tracer_type = /obj/effect/projectile/tracer/solar
|
||||
impact_type = /obj/effect/projectile/impact/solar
|
||||
|
||||
/obj/projectile/beam/megaglaive/on_impact(var/atom/A)
|
||||
if(isturf(A))
|
||||
if(istype(A, /turf/simulated/mineral))
|
||||
/obj/projectile/beam/megaglaive/on_hit(atom/target, blocked, def_zone)
|
||||
if(isturf(target))
|
||||
if(istype(target, /turf/simulated/mineral))
|
||||
if(prob(75)) //likely because its a mining tool
|
||||
var/turf/simulated/mineral/M = A
|
||||
var/turf/simulated/mineral/M = target
|
||||
if(prob(10))
|
||||
M.GetDrilled(1)
|
||||
else if(!M.emitter_blasts_taken)
|
||||
M.emitter_blasts_taken += 1
|
||||
else if(prob(33))
|
||||
M.emitter_blasts_taken += 1
|
||||
if(ismob(A))
|
||||
var/mob/living/M = A
|
||||
if(ismob(target))
|
||||
var/mob/living/M = target
|
||||
M.apply_effect(1, INCINERATE, 0)
|
||||
explosion(A, -1, 0, 2)
|
||||
..()
|
||||
explosion(target, -1, 0, 2)
|
||||
. = ..()
|
||||
|
||||
/obj/projectile/beam/thermaldrill
|
||||
name = "thermal drill"
|
||||
@@ -402,9 +400,9 @@
|
||||
tracer_type = /obj/effect/projectile/tracer/solar
|
||||
impact_type = /obj/effect/projectile/impact/solar
|
||||
|
||||
/obj/projectile/beam/thermaldrill/on_impact(var/atom/hit_atom)
|
||||
if(istype(hit_atom, /turf/simulated/mineral))
|
||||
var/turf/simulated/mineral/mineral = hit_atom
|
||||
/obj/projectile/beam/thermaldrill/on_hit(atom/target, blocked, def_zone)
|
||||
if(istype(target, /turf/simulated/mineral))
|
||||
var/turf/simulated/mineral/mineral = target
|
||||
mineral.GetDrilled(TRUE)
|
||||
return ..()
|
||||
|
||||
@@ -426,11 +424,11 @@
|
||||
tracer_type = /obj/effect/projectile/tracer/cult
|
||||
impact_type = /obj/effect/projectile/impact/cult
|
||||
|
||||
/obj/projectile/beam/cult/attack_mob(var/mob/living/target_mob, var/distance, var/miss_modifier=0)
|
||||
/obj/projectile/beam/cult/on_hit(atom/target, blocked, def_zone)
|
||||
//Harmlessly passes through cultists and constructs
|
||||
if (target_mob == ignore)
|
||||
if (target == ignore)
|
||||
return 0
|
||||
if (iscultist(target_mob))
|
||||
if (iscultist(target))
|
||||
return 0
|
||||
|
||||
return ..()
|
||||
@@ -447,16 +445,16 @@
|
||||
/obj/projectile/beam/energy_net
|
||||
name = "energy net projection"
|
||||
icon_state = "xray"
|
||||
nodamage = 1
|
||||
damage = 0
|
||||
damage_type = DAMAGE_PAIN
|
||||
|
||||
muzzle_type = /obj/effect/projectile/muzzle/xray
|
||||
tracer_type = /obj/effect/projectile/tracer/xray
|
||||
impact_type = /obj/effect/projectile/impact/xray
|
||||
|
||||
/obj/projectile/beam/energy_net/on_hit(var/atom/netted)
|
||||
do_net(netted)
|
||||
..()
|
||||
/obj/projectile/beam/energy_net/on_hit(atom/target, blocked, def_zone)
|
||||
do_net(target)
|
||||
. = ..()
|
||||
|
||||
/obj/projectile/beam/energy_net/proc/do_net(var/mob/M)
|
||||
var/obj/item/energy_net/net = new (get_turf(M))
|
||||
@@ -468,10 +466,7 @@
|
||||
damage = 25
|
||||
armor_penetration = 65
|
||||
penetrating = 1
|
||||
maiming = 1
|
||||
maim_rate = 5
|
||||
clean_cut = 1
|
||||
maim_type = DROPLIMB_BURN
|
||||
|
||||
muzzle_type = /obj/effect/projectile/muzzle/tachyon
|
||||
tracer_type = /obj/effect/projectile/tracer/tachyon
|
||||
@@ -490,7 +485,7 @@
|
||||
tracer_type = /obj/effect/projectile/tracer/tesla
|
||||
impact_type = /obj/effect/projectile/impact/tesla
|
||||
|
||||
/obj/projectile/beam/tesla/on_impact(atom/target)
|
||||
/obj/projectile/beam/tesla/on_hit(atom/target, blocked, def_zone)
|
||||
. = ..()
|
||||
if(isliving(target))
|
||||
tesla_zap(target, 5, 5000)
|
||||
@@ -507,7 +502,7 @@
|
||||
tracer_type = /obj/effect/projectile/tracer/laser/blue
|
||||
impact_type = /obj/effect/projectile/impact/laser/blue
|
||||
|
||||
/obj/projectile/beam/freezer/on_impact(atom/target)
|
||||
/obj/projectile/beam/freezer/on_hit(atom/target, blocked, def_zone)
|
||||
. = ..()
|
||||
if(isliving(target))
|
||||
var/mob/living/L = target
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
damage = 60
|
||||
damage_type = DAMAGE_BRUTE
|
||||
impact_sounds = list(BULLET_IMPACT_MEAT = SOUNDS_BULLET_MEAT, BULLET_IMPACT_METAL = SOUNDS_BULLET_METAL)
|
||||
nodamage = FALSE
|
||||
check_armor = "bullet"
|
||||
embed = TRUE
|
||||
sharp = TRUE
|
||||
@@ -13,12 +12,11 @@
|
||||
|
||||
muzzle_type = /obj/effect/projectile/muzzle/bullet
|
||||
|
||||
/obj/projectile/bullet/on_hit(var/atom/target, var/blocked = 0, var/def_zone = null)
|
||||
if (..(target, blocked, def_zone))
|
||||
/obj/projectile/bullet/on_hit(atom/target, blocked, def_zone)
|
||||
if(isliving(target) && (..(target, blocked, def_zone) == BULLET_ACT_HIT))
|
||||
var/mob/living/L = target
|
||||
shake_camera(L, 3, 2)
|
||||
|
||||
/obj/projectile/bullet/attack_mob(var/mob/living/target_mob, var/distance, var/miss_modifier)
|
||||
if(penetrating > 0 && damage > 20 && prob(damage))
|
||||
mob_passthrough_check = 1
|
||||
else
|
||||
@@ -88,9 +86,16 @@
|
||||
var/pellet_loss = round((distance - 1)/range_step) //pellets lost due to distance
|
||||
return max(pellets - pellet_loss, 1)
|
||||
|
||||
/obj/projectile/bullet/pellet/attack_mob(var/mob/living/target_mob, var/distance, var/miss_modifier)
|
||||
/obj/projectile/bullet/pellet/on_hit(atom/target, blocked, def_zone)
|
||||
if(!isliving(target))
|
||||
return ..()
|
||||
|
||||
var/mob/living/living_target = target
|
||||
|
||||
if (pellets < 0)
|
||||
return TRUE
|
||||
return BULLET_ACT_BLOCK
|
||||
|
||||
var/distance = get_dist(src.starting, get_turf(living_target))
|
||||
|
||||
var/total_pellets = get_pellets(distance)
|
||||
var/spread = max(base_spread - (spread_step*distance), 0)
|
||||
@@ -102,7 +107,7 @@
|
||||
|
||||
var/hits = 0
|
||||
for (var/i in 1 to total_pellets)
|
||||
if(target_mob.lying && target_mob != original && prob(prone_chance))
|
||||
if(living_target.lying && living_target != original && prob(prone_chance))
|
||||
continue
|
||||
|
||||
// pellet hits spread out across different zones, but 'aim at' the targeted zone with higher probability
|
||||
@@ -112,20 +117,22 @@
|
||||
// relatively hacky way of basing a shotgun pellet's likelihood of hitting on the first pellet of the burst while not affecting shrapnel explosions.
|
||||
if (base_spread > 0)
|
||||
if (i == 1)
|
||||
if (..())
|
||||
if (..() == BULLET_ACT_HIT)
|
||||
hits++
|
||||
else
|
||||
return 0
|
||||
else if (..(target_mob, distance, -100))
|
||||
else if (..() == BULLET_ACT_HIT)
|
||||
hits++
|
||||
else if (..())
|
||||
else if (..() == BULLET_ACT_HIT)
|
||||
hits++
|
||||
def_zone = old_zone //restore the original zone the projectile was aimed at
|
||||
|
||||
pellets -= hits //each hit reduces the number of pellets left
|
||||
if (hits >= total_pellets || pellets <= 0)
|
||||
return TRUE
|
||||
return FALSE
|
||||
// if (hits >= total_pellets || pellets <= 0)
|
||||
// return TRUE
|
||||
if(hits)
|
||||
return BULLET_ACT_HIT //Technically not everything, but good enough
|
||||
return BULLET_ACT_BLOCK //Nothing hit
|
||||
|
||||
/obj/projectile/bullet/pellet/get_structure_damage()
|
||||
var/distance = get_dist(loc, starting)
|
||||
@@ -157,7 +164,13 @@
|
||||
var/ball_loss = round((distance - 1)/range_step)
|
||||
return max(balls - ball_loss, 1)
|
||||
|
||||
/obj/projectile/bullet/rubberball/attack_mob(var/mob/living/target_mob, var/distance, var/miss_modifier)
|
||||
/obj/projectile/bullet/rubberball/on_hit(atom/target, blocked, def_zone)
|
||||
if(!isliving(target))
|
||||
return ..()
|
||||
|
||||
var/mob/living/target_mob = target
|
||||
var/distance = get_dist(src.starting, get_turf(target_mob))
|
||||
|
||||
if (balls < 0)
|
||||
return TRUE
|
||||
|
||||
@@ -323,9 +336,7 @@
|
||||
penetrating = 5
|
||||
armor_penetration = 70
|
||||
hitscan = 1 //so the PTR isn't useless as a sniper weapon
|
||||
maiming = 1
|
||||
maim_rate = 3
|
||||
maim_type = DROPLIMB_BLUNT
|
||||
anti_materiel_potential = 2
|
||||
|
||||
/obj/projectile/rifle/kumar_super
|
||||
@@ -349,18 +360,15 @@
|
||||
weaken = 3
|
||||
penetrating = 5
|
||||
armor_penetration = 10
|
||||
maiming = TRUE
|
||||
maim_rate = 3
|
||||
maim_type = DROPLIMB_BLUNT
|
||||
anti_materiel_potential = 2
|
||||
|
||||
/obj/projectile/bullet/rifle/slugger/on_hit(var/atom/movable/target, var/blocked = 0)
|
||||
if(!istype(target))
|
||||
return FALSE
|
||||
var/throwdir = get_dir(firer, target)
|
||||
target.throw_at(get_edge_target_turf(target, throwdir), 3, 3)
|
||||
..()
|
||||
return TRUE
|
||||
/obj/projectile/bullet/rifle/slugger/on_hit(atom/target, blocked, def_zone)
|
||||
var/atom/movable/movable_target = target
|
||||
if(istype(movable_target))
|
||||
var/throwdir = get_dir(firer, movable_target)
|
||||
movable_target.throw_at(get_edge_target_turf(movable_target, throwdir), 3, 3)
|
||||
. = ..()
|
||||
|
||||
/obj/projectile/bullet/rifle/tranq
|
||||
name = "dart"
|
||||
@@ -448,7 +456,6 @@
|
||||
name = "cap"
|
||||
damage_type = DAMAGE_PAIN
|
||||
damage = 0
|
||||
nodamage = 1
|
||||
embed = 0
|
||||
sharp = 0
|
||||
|
||||
@@ -493,17 +500,13 @@
|
||||
damage = 10
|
||||
armor_penetration = 30
|
||||
|
||||
/obj/projectile/bullet/gauss/highex/on_impact(var/atom/A)
|
||||
explosion(A, -1, 0, 2)
|
||||
..()
|
||||
|
||||
/obj/projectile/bullet/gauss/highex/on_hit(var/atom/target, var/blocked = 0)
|
||||
/obj/projectile/bullet/gauss/highex/on_hit(atom/target, blocked, def_zone)
|
||||
. = ..()
|
||||
explosion(target, -1, 0, 2)
|
||||
if(ismovable(target))
|
||||
var/atom/movable/T = target
|
||||
var/throwdir = get_dir(firer,target)
|
||||
INVOKE_ASYNC(T, TYPE_PROC_REF(/atom/movable, throw_at), get_edge_target_turf(target, throwdir), 3, 3)
|
||||
return TRUE
|
||||
|
||||
/obj/projectile/bullet/cannonball
|
||||
name = "cannonball"
|
||||
@@ -519,9 +522,9 @@
|
||||
penetrating = 0
|
||||
armor_penetration = 5
|
||||
|
||||
/obj/projectile/bullet/cannonball/explosive/on_impact(var/atom/A)
|
||||
explosion(A, -1, 1, 2)
|
||||
..()
|
||||
/obj/projectile/bullet/cannonball/explosive/on_hit(atom/target, blocked, def_zone)
|
||||
explosion(target, -1, 1, 2)
|
||||
. = ..()
|
||||
|
||||
/obj/projectile/bullet/nuke
|
||||
name = "miniaturized nuclear warhead"
|
||||
@@ -529,15 +532,15 @@
|
||||
damage = 25
|
||||
anti_materiel_potential = 2
|
||||
|
||||
/obj/projectile/bullet/nuke/on_impact(var/atom/A)
|
||||
/obj/projectile/bullet/nuke/on_hit(atom/target, blocked, def_zone)
|
||||
for(var/mob/living/carbon/human/mob in GLOB.human_mob_list)
|
||||
var/turf/T = get_turf(mob)
|
||||
if(T && (loc.z == T.z))
|
||||
if(ishuman(mob))
|
||||
mob.apply_damage(250, DAMAGE_RADIATION, damage_flags = DAMAGE_FLAG_DISPERSED)
|
||||
new /obj/effect/temp_visual/nuke(A.loc)
|
||||
explosion(A,2,5,9)
|
||||
..()
|
||||
new /obj/effect/temp_visual/nuke(target.loc)
|
||||
explosion(target,2,5,9)
|
||||
. = ..()
|
||||
|
||||
/obj/projectile/bullet/shard
|
||||
name = "shard"
|
||||
@@ -559,9 +562,9 @@
|
||||
penetrating = FALSE
|
||||
var/heavy_impact_range = 1
|
||||
|
||||
/obj/projectile/bullet/recoilless_rifle/on_impact(var/atom/A)
|
||||
explosion(A, -1, heavy_impact_range, 2)
|
||||
..()
|
||||
/obj/projectile/bullet/recoilless_rifle/on_hit(atom/target, blocked, def_zone)
|
||||
explosion(target, -1, heavy_impact_range, 2)
|
||||
. = ..()
|
||||
|
||||
/obj/projectile/bullet/peac
|
||||
name = "anti-tank missile"
|
||||
@@ -581,8 +584,10 @@
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
/obj/projectile/bullet/peac/on_impact(var/atom/hit_atom)
|
||||
explosion(hit_atom, devastation_range, heavy_impact_range, light_impact_range)
|
||||
/obj/projectile/bullet/peac/on_hit(atom/target, blocked, def_zone)
|
||||
. = ..()
|
||||
|
||||
explosion(target, devastation_range, heavy_impact_range, light_impact_range)
|
||||
|
||||
/obj/projectile/bullet/peac/he
|
||||
name = "high-explosive missile"
|
||||
@@ -600,12 +605,13 @@
|
||||
|
||||
light_impact_range = 1
|
||||
|
||||
/obj/projectile/bullet/peac/shrapnel/preparePixelProjectile()
|
||||
/obj/projectile/bullet/peac/shrapnel/preparePixelProjectile(atom/target, atom/source, list/modifiers, deviation)
|
||||
. = ..()
|
||||
range = get_dist(firer, original)
|
||||
|
||||
/obj/projectile/bullet/peac/shrapnel/on_impact(var/atom/hit_atom)
|
||||
..()
|
||||
/obj/projectile/bullet/peac/shrapnel/on_hit(atom/target, blocked, def_zone)
|
||||
. = ..()
|
||||
|
||||
spawn_shrapnel(starting ? get_dir(starting, original) : dir)
|
||||
|
||||
/obj/projectile/bullet/peac/shrapnel/proc/spawn_shrapnel(var/shrapnel_dir)
|
||||
@@ -622,7 +628,9 @@
|
||||
P.damage = 30
|
||||
P.pellets = 4
|
||||
P.range_step = 3
|
||||
P.shot_from = src
|
||||
P.range = 15
|
||||
P.name = "shrapnel"
|
||||
P.launch_projectile(T)
|
||||
P.preparePixelProjectile(T, src)
|
||||
P.firer = src
|
||||
P.fired_from = src
|
||||
P.fire()
|
||||
|
||||
@@ -3,11 +3,11 @@
|
||||
icon_state = "ice_1"
|
||||
damage = 0
|
||||
damage_type = DAMAGE_BURN
|
||||
nodamage = 1
|
||||
check_armor = "energy"
|
||||
|
||||
/obj/projectile/change/on_hit(var/atom/change)
|
||||
wabbajack(change)
|
||||
/obj/projectile/change/on_hit(atom/target, blocked, def_zone)
|
||||
. = ..()
|
||||
wabbajack(target)
|
||||
|
||||
/obj/projectile/change/proc/wabbajack(var/mob/M)
|
||||
if(istype(M, /mob/living) && M.stat != DEAD)
|
||||
|
||||
@@ -16,8 +16,10 @@
|
||||
var/brightness = 7
|
||||
var/light_duration = 5
|
||||
|
||||
/obj/projectile/energy/flash/on_impact(var/atom/A, affected_limb)
|
||||
var/turf/T = flash_range ? src.loc : get_turf(A)
|
||||
/obj/projectile/energy/flash/on_hit(atom/target, blocked, def_zone)
|
||||
. = ..()
|
||||
|
||||
var/turf/T = flash_range ? src.loc : get_turf(target)
|
||||
if(!istype(T))
|
||||
return
|
||||
|
||||
@@ -25,8 +27,6 @@
|
||||
for(var/mob/living/M in viewers(T, flash_range))
|
||||
if(M.flash_act(ignore_inherent = TRUE))
|
||||
M.confused = rand(5, 15)
|
||||
else if(affected_limb && M == A)
|
||||
M.confused = rand(2, 7)
|
||||
|
||||
//snap pop
|
||||
playsound(src, 'sound/effects/snap.ogg', 50, 1)
|
||||
@@ -111,12 +111,12 @@
|
||||
light_range = 4
|
||||
light_color = "#b5ff5b"
|
||||
|
||||
/obj/projectile/energy/bfg/on_impact(var/atom/A)
|
||||
if(ismob(A))
|
||||
var/mob/M = A
|
||||
/obj/projectile/energy/bfg/on_hit(atom/target, blocked, def_zone)
|
||||
if(ismob(target))
|
||||
var/mob/M = target
|
||||
M.gib()
|
||||
explosion(A, -1, 0, 5)
|
||||
..()
|
||||
explosion(target, -1, 0, 5)
|
||||
. = ..()
|
||||
|
||||
/obj/projectile/energy/bfg/New()
|
||||
var/matrix/M = matrix()
|
||||
@@ -124,21 +124,21 @@
|
||||
src.transform = M
|
||||
..()
|
||||
|
||||
/obj/projectile/energy/bfg/after_move()
|
||||
for(var/a in range(1, src))
|
||||
if(isliving(a) && a != firer)
|
||||
var/mob/living/M = a
|
||||
if(M.stat == DEAD)
|
||||
M.gib()
|
||||
else
|
||||
M.apply_damage(60, DAMAGE_BRUTE, BP_HEAD)
|
||||
playsound(src, 'sound/magic/LightningShock.ogg', 75, 1)
|
||||
else if(isturf(a) || isobj(a))
|
||||
var/atom/A = a
|
||||
if(!A.density)
|
||||
continue
|
||||
A.ex_act(2)
|
||||
playsound(src, 'sound/magic/LightningShock.ogg', 75, 1)
|
||||
// /obj/projectile/energy/bfg/after_move()
|
||||
// for(var/a in range(1, src))
|
||||
// if(isliving(a) && a != firer)
|
||||
// var/mob/living/M = a
|
||||
// if(M.stat == DEAD)
|
||||
// M.gib()
|
||||
// else
|
||||
// M.apply_damage(60, DAMAGE_BRUTE, BP_HEAD)
|
||||
// playsound(src, 'sound/magic/LightningShock.ogg', 75, 1)
|
||||
// else if(isturf(a) || isobj(a))
|
||||
// var/atom/A = a
|
||||
// if(!A.density)
|
||||
// continue
|
||||
// A.ex_act(2)
|
||||
// playsound(src, 'sound/magic/LightningShock.ogg', 75, 1)
|
||||
|
||||
/obj/projectile/energy/gravitydisabler
|
||||
name = "gravity disabler"
|
||||
@@ -153,7 +153,7 @@
|
||||
light_range = 4
|
||||
light_color = "#b5ff5b"
|
||||
|
||||
/obj/projectile/energy/gravitydisabler/on_impact(atom/target)
|
||||
/obj/projectile/energy/gravitydisabler/on_hit(atom/target, blocked, def_zone)
|
||||
. = ..()
|
||||
var/area/A = get_area(target)
|
||||
if(A && A.has_gravity())
|
||||
@@ -176,7 +176,7 @@
|
||||
damage_flags = DAMAGE_FLAG_LASER
|
||||
pass_flags = PASSTABLE | PASSGLASS | PASSGRILLE | PASSRAILING
|
||||
muzzle_type = /obj/effect/projectile/muzzle/bolt
|
||||
hit_effect = /obj/effect/temp_visual/blaster_effect
|
||||
impact_effect_type = /obj/effect/temp_visual/blaster_effect
|
||||
|
||||
/obj/projectile/energy/blaster/disruptor
|
||||
damage = 20
|
||||
|
||||
@@ -10,13 +10,15 @@
|
||||
name = "force bolt"
|
||||
icon_state = "bluespace"
|
||||
|
||||
/obj/projectile/forcebolt/on_hit(var/atom/movable/target, var/blocked = 0)
|
||||
if(istype(target))
|
||||
/obj/projectile/forcebolt/on_hit(atom/target, blocked, def_zone)
|
||||
. = ..()
|
||||
if(ismovable(target))
|
||||
var/atom/movable/M = target
|
||||
var/throwdir = get_dir(firer,target)
|
||||
target.throw_at(get_edge_target_turf(target, throwdir),10,10)
|
||||
return 1
|
||||
M.throw_at(get_edge_target_turf(target, throwdir),10,10)
|
||||
return BULLET_ACT_HIT
|
||||
|
||||
/obj/projectile/forcebolt/strong/on_hit(var/atom/target, var/blocked = 0)
|
||||
/obj/projectile/forcebolt/strong/on_hit(atom/target, blocked, def_zone)
|
||||
for(var/mob/M in hearers(2, src))
|
||||
if(M.loc != src.loc)
|
||||
var/throwdir = get_dir(firer,target)
|
||||
|
||||
@@ -7,12 +7,16 @@
|
||||
check_armor = "energy"
|
||||
var/pulse_range = 1
|
||||
|
||||
/obj/projectile/ion/on_impact(var/atom/A)
|
||||
empulse(A, pulse_range, pulse_range)
|
||||
/obj/projectile/ion/on_hit(atom/target, blocked, def_zone)
|
||||
. = ..()
|
||||
|
||||
/obj/projectile/ion/stun/on_impact(var/atom/A)
|
||||
if(isipc(A))
|
||||
var/mob/living/carbon/human/H = A
|
||||
empulse(target, pulse_range, pulse_range)
|
||||
|
||||
/obj/projectile/ion/stun/on_hit(atom/target, blocked, def_zone)
|
||||
. = ..()
|
||||
|
||||
if(isipc(target))
|
||||
var/mob/living/carbon/human/H = target
|
||||
var/obj/item/organ/internal/surge/s = H.internal_organs_by_name["surge"]
|
||||
if(!isnull(s))
|
||||
if(s.surge_left >= 0.5)
|
||||
@@ -28,8 +32,8 @@
|
||||
return
|
||||
else
|
||||
to_chat(src, SPAN_DANGER("Warning: EMP detected, integrated surge prevention module is fried and unable to protect from EMP. Replacement recommended."))
|
||||
if (isrobot(A))
|
||||
var/mob/living/silicon/robot/R = A
|
||||
if (isrobot(target))
|
||||
var/mob/living/silicon/robot/R = target
|
||||
var/datum/robot_component/surge/C = R.components["surge"]
|
||||
if(C && C.installed)
|
||||
if(C.surge_left >= 0.5)
|
||||
@@ -48,7 +52,7 @@
|
||||
|
||||
R.emp_act(EMP_LIGHT) // Borgs emp_act is 1-2
|
||||
else
|
||||
A.emp_act(EMP_LIGHT)
|
||||
target.emp_act(EMP_LIGHT)
|
||||
return
|
||||
|
||||
/obj/projectile/ion/small
|
||||
@@ -71,16 +75,18 @@
|
||||
sharp = 1
|
||||
edge = TRUE
|
||||
|
||||
/obj/projectile/bullet/gyro/on_impact(var/atom/A)
|
||||
explosion(A, -1, 0, 2)
|
||||
..()
|
||||
/obj/projectile/bullet/gyro/on_hit(atom/target, blocked, def_zone)
|
||||
explosion(target, -1, 0, 2)
|
||||
. = ..()
|
||||
|
||||
/obj/projectile/bullet/gyro/law
|
||||
name ="high-ex round"
|
||||
icon_state= "bolter"
|
||||
damage = 15
|
||||
|
||||
/obj/projectile/bullet/gyro/law/on_hit(var/atom/target, var/blocked = 0)
|
||||
/obj/projectile/bullet/gyro/law/on_hit(atom/target, blocked, def_zone)
|
||||
. = ..()
|
||||
|
||||
explosion(target, -1, 0, 2)
|
||||
var/obj/T = target
|
||||
var/throwdir = get_dir(firer,target)
|
||||
@@ -92,12 +98,12 @@
|
||||
icon_state = "ice_2"
|
||||
damage = 0
|
||||
damage_type = DAMAGE_BURN
|
||||
nodamage = 1
|
||||
check_armor = "energy"
|
||||
//var/temperature = 300
|
||||
|
||||
|
||||
/obj/projectile/temp/on_hit(var/atom/target, var/blocked = 0)//These two could likely check temp protection on the mob
|
||||
/obj/projectile/temp/on_hit(atom/target, blocked, def_zone)//These two could likely check temp protection on the mob
|
||||
. = ..()
|
||||
if(istype(target, /mob/living))
|
||||
var/mob/M = target
|
||||
M.bodytemperature = -273
|
||||
@@ -109,7 +115,6 @@
|
||||
icon_state = "small1"
|
||||
damage = 0
|
||||
damage_type = DAMAGE_BRUTE
|
||||
nodamage = 1
|
||||
check_armor = "bullet"
|
||||
|
||||
/obj/projectile/meteor/Collide(atom/A)
|
||||
@@ -136,7 +141,6 @@
|
||||
icon_state = "energy"
|
||||
damage = 0
|
||||
damage_type = DAMAGE_TOXIN
|
||||
nodamage = 1
|
||||
check_armor = "energy"
|
||||
|
||||
/obj/projectile/energy/floramut/gene
|
||||
@@ -144,10 +148,10 @@
|
||||
icon_state = "energy2"
|
||||
damage = 0
|
||||
damage_type = DAMAGE_TOXIN
|
||||
nodamage = TRUE
|
||||
var/singleton/plantgene/gene = null
|
||||
|
||||
/obj/projectile/energy/floramut/on_hit(var/atom/target, var/blocked = 0)
|
||||
/obj/projectile/energy/floramut/on_hit(atom/target, blocked, def_zone)
|
||||
. = ..()
|
||||
var/mob/living/M = target
|
||||
if(ishuman(target))
|
||||
var/mob/living/carbon/human/H = M
|
||||
@@ -177,10 +181,10 @@
|
||||
icon_state = "energy2"
|
||||
damage = 0
|
||||
damage_type = DAMAGE_TOXIN
|
||||
nodamage = 1
|
||||
check_armor = "energy"
|
||||
|
||||
/obj/projectile/energy/florayield/on_hit(var/atom/target, var/blocked = 0)
|
||||
/obj/projectile/energy/florayield/on_hit(atom/target, blocked, def_zone)
|
||||
. = ..()
|
||||
var/mob/M = target
|
||||
if(ishuman(target)) //These rays make plantmen fat.
|
||||
var/mob/living/carbon/human/H = M
|
||||
@@ -195,7 +199,8 @@
|
||||
/obj/projectile/beam/mindflayer
|
||||
name = "flayer ray"
|
||||
|
||||
/obj/projectile/beam/mindflayer/on_hit(var/atom/target, var/blocked = 0)
|
||||
/obj/projectile/beam/mindflayer/on_hit(atom/target, blocked, def_zone)
|
||||
. = ..()
|
||||
if(ishuman(target))
|
||||
var/mob/living/carbon/human/M = target
|
||||
M.adjustBrainLoss(5)
|
||||
@@ -209,16 +214,15 @@
|
||||
sharp = 1
|
||||
edge = TRUE
|
||||
|
||||
/obj/projectile/bullet/trod/on_impact(var/atom/A)
|
||||
explosion(A, 0, 0, 4)
|
||||
..()
|
||||
/obj/projectile/bullet/trod/on_hit(atom/target, blocked, def_zone)
|
||||
explosion(target, 0, 0, 4)
|
||||
. = ..()
|
||||
|
||||
/obj/projectile/chameleon
|
||||
name = "bullet"
|
||||
icon_state = "bullet"
|
||||
damage = 1 // stop trying to murderbone with a fake gun dumbass!!!
|
||||
damage = 0 // stop trying to murderbone with a fake gun dumbass!!!
|
||||
embed = 0 // nope
|
||||
nodamage = 1
|
||||
damage_type = DAMAGE_PAIN
|
||||
muzzle_type = /obj/effect/projectile/muzzle/bullet
|
||||
|
||||
@@ -230,9 +234,9 @@
|
||||
armor_penetration = 80
|
||||
penetrating = 1
|
||||
|
||||
/obj/projectile/bullet/cannon/on_impact(var/atom/A)
|
||||
explosion(A, 1, 2, 3, 3)
|
||||
..()
|
||||
/obj/projectile/bullet/cannon/on_hit(atom/target, blocked, def_zone)
|
||||
explosion(target, 1, 2, 3, 3)
|
||||
. = ..()
|
||||
|
||||
//magic
|
||||
|
||||
@@ -251,9 +255,9 @@
|
||||
damage = 20
|
||||
damage_type = DAMAGE_BURN
|
||||
|
||||
/obj/projectile/magic/fireball/on_impact(var/atom/A)
|
||||
explosion(A, 0, 0, 4)
|
||||
..()
|
||||
/obj/projectile/magic/fireball/on_hit(atom/target, blocked, def_zone)
|
||||
explosion(target, 0, 0, 4)
|
||||
. = ..()
|
||||
|
||||
/obj/projectile/magic/teleport //literaly bluespace crystal code, because i am lazy and it seems to work
|
||||
name = "bolt of teleportation"
|
||||
@@ -261,12 +265,12 @@
|
||||
icon_state = "energy2"
|
||||
var/blink_range = 8
|
||||
|
||||
/obj/projectile/magic/teleport/on_hit(var/atom/hit_atom)
|
||||
var/turf/T = get_turf(hit_atom)
|
||||
/obj/projectile/magic/teleport/on_hit(atom/target, blocked, def_zone)
|
||||
var/turf/T = get_turf(target)
|
||||
single_spark(T)
|
||||
playsound(src.loc, /singleton/sound_category/spark_sound, 50, 1)
|
||||
if(isliving(hit_atom))
|
||||
blink_mob(hit_atom)
|
||||
if(isliving(target))
|
||||
blink_mob(target)
|
||||
return ..()
|
||||
|
||||
/obj/projectile/magic/teleport/proc/blink_mob(mob/living/L)
|
||||
@@ -316,7 +320,6 @@
|
||||
damage = 35
|
||||
damage_type = DAMAGE_BRUTE
|
||||
impact_sounds = list(BULLET_IMPACT_MEAT = SOUNDS_BULLET_MEAT, BULLET_IMPACT_METAL = SOUNDS_BULLET_METAL)
|
||||
nodamage = FALSE
|
||||
check_armor = "melee"
|
||||
embed = TRUE
|
||||
sharp = TRUE
|
||||
|
||||
@@ -10,16 +10,16 @@
|
||||
trace.obj_flags = obj_flags
|
||||
trace.pass_flags = pass_flags
|
||||
|
||||
return trace.launch_projectile(target) //Test it!
|
||||
trace.preparePixelProjectile(target, firer)
|
||||
trace.firer = firer
|
||||
|
||||
/obj/projectile/proc/_check_fire(atom/target as mob, mob/living/user as mob) //Checks if you can hit them or not.
|
||||
check_trajectory(target, user, pass_flags, obj_flags)
|
||||
return trace.fire()
|
||||
|
||||
//"Tracing" projectile
|
||||
/obj/projectile/test //Used to see if you can hit them.
|
||||
invisibility = 101 //Nope! Can't see me!
|
||||
invisibility = INVISIBILITY_ABSTRACT //Nope! Can't see me!
|
||||
hitscan = TRUE
|
||||
nodamage = TRUE
|
||||
do_not_log = TRUE
|
||||
damage = 0
|
||||
var/list/hit = list()
|
||||
|
||||
@@ -34,5 +34,6 @@
|
||||
hit |= A
|
||||
return ..()
|
||||
|
||||
/obj/projectile/test/attack_mob()
|
||||
/obj/projectile/test/on_hit(atom/target, blocked, def_zone)
|
||||
SHOULD_CALL_PARENT(FALSE)
|
||||
return
|
||||
|
||||
Reference in New Issue
Block a user