mirror of
https://github.com/goonstation/goonstation-2020.git
synced 2026-07-12 07:32:20 +01:00
735 lines
18 KiB
Plaintext
735 lines
18 KiB
Plaintext
// Not all that crazy shit
|
|
|
|
/datum/projectile/special
|
|
name = "special"
|
|
icon = 'icons/obj/projectiles.dmi'
|
|
icon_state = "laser"
|
|
power = 15
|
|
cost = 25
|
|
dissipation_rate = 1
|
|
dissipation_delay = 0
|
|
ks_ratio = 1.0
|
|
sname = "laser"
|
|
shot_sound = 'sound/weapons/Taser.ogg'
|
|
shot_number = 1
|
|
damage_type = D_SPECIAL
|
|
hit_ground_chance = 50
|
|
window_pass = 0
|
|
|
|
on_hit(atom/hit, direction, projectile)
|
|
return
|
|
|
|
/datum/projectile/special/kiss
|
|
name = "kiss"
|
|
icon_state = "kiss"
|
|
power = 0
|
|
sname = "kiss"
|
|
shot_sound = 'sound/voice/gasps/gasp.ogg'
|
|
|
|
on_hit(atom/hit, direction, var/obj/projectile/projectile)
|
|
if(istype(hit, /mob/living/carbon/human))
|
|
var/mob/living/carbon/human/H = hit
|
|
boutput(H, "<span style=\"color:red\"><B>You catch the kiss and save it for later.</B></span>")
|
|
|
|
/datum/projectile/special/acid
|
|
name = "acid"
|
|
icon_state = "radbolt"
|
|
power = 45
|
|
dissipation_rate = 30
|
|
dissipation_delay = 10
|
|
sname = "acid"
|
|
|
|
on_hit(atom/hit, direction, var/obj/projectile/projectile)
|
|
var/power = projectile.power
|
|
hit.damage_corrosive(power)
|
|
|
|
potent
|
|
power = 100
|
|
|
|
weak
|
|
power = 15
|
|
|
|
/datum/projectile/special/acidspit
|
|
name = "acid splash"
|
|
icon_state = "cbbolt"
|
|
power = 0.8
|
|
dissipation_rate = 20
|
|
dissipation_delay = 10
|
|
sname = "acid"
|
|
damage_type = D_TOXIC
|
|
hit_mob_sound = 'sound/impact_sounds/burn_sizzle.ogg'
|
|
hit_object_sound = 'sound/impact_sounds/burn_sizzle.ogg'
|
|
shot_sound = null
|
|
|
|
on_hit(atom/hit, direction, var/obj/projectile/projectile)
|
|
..()
|
|
var/power = projectile.power
|
|
hit.damage_corrosive(power)
|
|
|
|
|
|
/datum/projectile/special/ice
|
|
name = "ice"
|
|
icon_state = "ice"
|
|
power = 120
|
|
dissipation_rate = 10
|
|
dissipation_delay = 3
|
|
sname = "ice"
|
|
|
|
on_hit(atom/hit, direction, var/obj/projectile/projectile)
|
|
hit.damage_cold(projectile.power / 10)
|
|
if (ishuman(hit))
|
|
var/mob/living/L = hit
|
|
L.bodytemperature -= projectile.power
|
|
|
|
/datum/projectile/special/material_changer
|
|
name = "transmutation bolt"
|
|
icon_state = "ice"
|
|
power = 1
|
|
dissipation_rate = 1
|
|
dissipation_delay = 25
|
|
sname = "ice"
|
|
color_icon = "#aaff00"
|
|
var/material_to_make = "gold"
|
|
|
|
tick(var/obj/projectile/P)
|
|
var/turf/T = get_turf(P)
|
|
if (T)
|
|
T.setMaterial(getMaterial("gold"))
|
|
|
|
on_hit(var/atom/A)
|
|
A.setMaterial(getMaterial("gold"))
|
|
|
|
/datum/projectile/special/piercing
|
|
name = "focused beam"
|
|
sname = "focused beam"
|
|
icon_state = "laser_white"
|
|
window_pass = 1
|
|
power = 30
|
|
dissipation_rate = 1
|
|
dissipation_delay = 3
|
|
damage_type = D_ENERGY
|
|
pierces = -1
|
|
ticks_between_mob_hits = 10
|
|
|
|
/datum/projectile/special/wallhax
|
|
name = "phased beam"
|
|
sname = "phased beam"
|
|
icon_state = "crescent_white"
|
|
window_pass = 1
|
|
power = 30
|
|
dissipation_rate = 1
|
|
dissipation_delay = 3
|
|
damage_type = D_ENERGY
|
|
goes_through_walls = 1
|
|
|
|
// Mildly crazy shit
|
|
|
|
/datum/projectile/special/spreader
|
|
name = "spread shot"
|
|
sname = "spread shot"
|
|
shot_sound = 'sound/weapons/grenade.ogg'
|
|
var/pellets_to_fire = 15
|
|
var/spread_projectile_type = /datum/projectile/bullet/flak_chunk
|
|
var/split_type = 0
|
|
// 0 = on spawn
|
|
// 1 = on impact
|
|
|
|
on_launch(var/obj/projectile/P)
|
|
if(split_type == 0)
|
|
split(P)
|
|
|
|
on_hit(var/atom/A,var/obj/projectile/P)
|
|
if(split_type == 1)
|
|
split(P)
|
|
|
|
proc/new_pellet(var/obj/projectile/P, var/turf/PT, var/datum/projectile/F)
|
|
return
|
|
|
|
proc/split(var/obj/projectile/P)
|
|
var/datum/projectile/F = new spread_projectile_type()
|
|
var/turf/PT = get_turf(P)
|
|
var/pellets = pellets_to_fire
|
|
while (pellets > 0)
|
|
pellets--
|
|
new_pellet(P,PT,F)
|
|
P.die()
|
|
|
|
/datum/projectile/special/spreader/uniform_burst
|
|
name = "uniform spread"
|
|
sname = "uniform spread"
|
|
var/spread_angle = 45
|
|
var/current_angle = 0
|
|
var/angle_adjust_per_pellet = 0
|
|
var/initial_angle_offset_mult = 0.5
|
|
|
|
on_launch(var/obj/projectile/P)
|
|
angle_adjust_per_pellet = ((spread_angle * 2) / pellets_to_fire)
|
|
current_angle = (0 - spread_angle) + (angle_adjust_per_pellet * initial_angle_offset_mult)
|
|
..()
|
|
|
|
new_pellet(var/obj/projectile/P, var/turf/PT, var/datum/projectile/F)
|
|
var/obj/projectile/FC = initialize_projectile(PT, F, P.xo, P.yo, P.shooter)
|
|
FC.rotateDirection(current_angle)
|
|
FC.launch()
|
|
current_angle += angle_adjust_per_pellet
|
|
|
|
/datum/projectile/special/spreader/buckshot_burst
|
|
name = "buckshot"
|
|
sname = "buckshot"
|
|
cost = 1
|
|
pellets_to_fire = 10
|
|
spread_projectile_type = /datum/projectile/bullet/buckshot
|
|
var/speed_max = 5
|
|
var/speed_min = 60
|
|
var/spread_angle_variance = 5
|
|
var/dissipation_variance = 1
|
|
|
|
new_pellet(var/obj/projectile/P, var/turf/PT, var/datum/projectile/F)
|
|
var/obj/projectile/FC = initialize_projectile(PT, F, P.xo, P.yo, P.shooter)
|
|
FC.rotateDirection(rand(0-spread_angle_variance,spread_angle_variance))
|
|
FC.internal_speed = rand(speed_min,speed_max)
|
|
FC.dissipation_ticker = rand(0,dissipation_variance)
|
|
FC.launch()
|
|
|
|
/datum/projectile/special/spreader/uniform_burst/circle
|
|
name = "circular spread"
|
|
sname = "circular spread"
|
|
spread_angle = 360
|
|
pellets_to_fire = 20
|
|
|
|
/datum/projectile/special/spreader/uniform_burst/blaster
|
|
name = "blaster wave"
|
|
sname = "wave fire"
|
|
spread_angle = 33
|
|
cost = 200
|
|
pellets_to_fire = 5
|
|
spread_projectile_type = /datum/projectile/laser/blaster/blast
|
|
shot_sound = 'sound/weapons/laser_f.ogg'
|
|
|
|
// Really crazy shit
|
|
|
|
/datum/projectile/special/shock_orb
|
|
name = "ball lightning"
|
|
sname = "ball lightning"
|
|
icon_state = "elecorb"
|
|
shot_sound = 'sound/weapons/energy/LightningCannon.ogg'
|
|
power = 75
|
|
cost = 75
|
|
damage_type = D_ENERGY
|
|
dissipation_delay = 15
|
|
color_red = 0.1
|
|
color_green = 0.3
|
|
color_blue = 1
|
|
ks_ratio = 0.8
|
|
|
|
var/arc_chance_per_tick = 33
|
|
var/max_arcs_per_tick = 3
|
|
var/min_arcs_per_tick = 1
|
|
var/arcs_on_hit = 8
|
|
var/shock_range = 3
|
|
var/wattage = 5000
|
|
|
|
tick(var/obj/projectile/P)
|
|
if (prob(arc_chance_per_tick))
|
|
var/list/sfloors = list()
|
|
for (var/turf/T in view(shock_range, P))
|
|
if (!T.density)
|
|
sfloors += T
|
|
var/shocks = rand(min_arcs_per_tick, max_arcs_per_tick)
|
|
while (shocks > 0 && sfloors.len)
|
|
shocks--
|
|
var/turf/Q = pick(sfloors)
|
|
arcFlashTurf(P, Q, wattage)
|
|
sfloors -= Q
|
|
|
|
on_hit(var/atom/A)
|
|
playsound(A, "sound/weapons/energy/LightningCannonImpact.ogg", 50, 1)
|
|
var/list/sfloors = list()
|
|
for (var/turf/T in view(shock_range, A))
|
|
if (!T.density)
|
|
sfloors += T
|
|
var/arcs = arcs_on_hit
|
|
while (arcs > 0 && sfloors.len)
|
|
arcs--
|
|
var/turf/Q = pick(sfloors)
|
|
arcFlashTurf(A, Q, wattage)
|
|
sfloors -= Q
|
|
|
|
always_mob
|
|
|
|
tick(var/obj/projectile/P)
|
|
if (prob(arc_chance_per_tick))
|
|
var/list/smobs = list()
|
|
for (var/mob/M in view(shock_range, P))
|
|
smobs += M
|
|
var/shocks = rand(min_arcs_per_tick, max_arcs_per_tick)
|
|
while (shocks > 0 && smobs.len)
|
|
shocks--
|
|
var/mob/Q = pick(smobs)
|
|
arcFlash(P, Q, wattage)
|
|
smobs -= Q
|
|
|
|
/datum/projectile/special/inferno
|
|
name = "inferno bomb"
|
|
sname = "inferno bomb"
|
|
icon_state = "fusionorb"
|
|
shot_sound = 'sound/weapons/energy/InfernoCannon.ogg'
|
|
power = 75
|
|
cost = 75
|
|
damage_type = D_BURNING
|
|
dissipation_delay = 15
|
|
ks_ratio = 0.8
|
|
|
|
var/burn_range = 1
|
|
var/blast_size = 3
|
|
var/temperature = 800
|
|
|
|
tick(var/obj/projectile/P)
|
|
fireflash_sm(get_turf(P), burn_range, temperature)
|
|
|
|
on_hit(var/atom/A)
|
|
playsound(A, "sound/effects/ExplosionFirey.ogg", 100, 1)
|
|
fireflash_sm(get_turf(A), blast_size, temperature)
|
|
|
|
|
|
/datum/projectile/special/howitzer
|
|
name = "plasma howitzer"
|
|
sname = "plasma howitzer"
|
|
icon = 'icons/obj/32x96.dmi'
|
|
icon_state = "howitzer-shot"
|
|
shot_sound = 'sound/weapons/energy/howitzer_shot.ogg'
|
|
power = 10000 // blam = INF
|
|
cost = 2500
|
|
damage_type = D_BURNING
|
|
dissipation_delay = 75
|
|
dissipation_rate = 300
|
|
ks_ratio = 0.8
|
|
brightness = 2
|
|
projectile_speed = 28
|
|
impact_range = 32
|
|
caliber = 40
|
|
pierces = -1
|
|
goes_through_walls = 1
|
|
color_red = 1
|
|
color_green = 1
|
|
color_blue = 0
|
|
var/burn_range = 1
|
|
var/blast_size = 2
|
|
var/temperature = 5000
|
|
var/impacted = 0
|
|
|
|
tick(var/obj/projectile/P)
|
|
var/T1 = get_turf(P)
|
|
if((!istype(T1,/turf/space))) // so uh yeah this will be pretty mean
|
|
fireflash_sm(T1, burn_range, temperature)
|
|
new /obj/effects/explosion/dangerous(get_step(P.loc,P.dir))
|
|
|
|
|
|
|
|
on_launch(var/obj/projectile/P)
|
|
for(var/mob/M in range(P.loc, 6))
|
|
shake_camera(M, 3, 1)
|
|
|
|
|
|
on_hit(var/atom/A)
|
|
var/turf/T = get_turf(A)
|
|
playsound(A, "sound/effects/ExplosionFirey.ogg", 60, 1)
|
|
if(!src.impacted)
|
|
world << sound('sound/weapons/energy/howitzer_impact.ogg', volume = 70)
|
|
src.impacted = 1
|
|
SPAWN_DBG(1 DECI SECOND)
|
|
for(var/mob/living/M in mobs)
|
|
shake_camera(M, 2, 1)
|
|
|
|
SPAWN_DBG(0)
|
|
explosion_new(null, T, 30, 1)
|
|
if(prob(50))
|
|
world << sound('sound/effects/creaking_metal1.ogg', volume = 60)
|
|
|
|
|
|
|
|
|
|
|
|
/datum/projectile/special/spewer
|
|
name = "volatile bolt"
|
|
sname = "volatile bolt"
|
|
icon_state = "orb_white"
|
|
shot_sound = 'sound/weapons/laserultra.ogg'
|
|
power = 100
|
|
cost = 75
|
|
damage_type = D_BURNING
|
|
dissipation_delay = 0
|
|
dissipation_rate = 5
|
|
ks_ratio = 0.8
|
|
|
|
var/bolt_type = /datum/projectile/laser/spewer_bolt
|
|
var/datum/projectile/bolt_instance = null
|
|
var/bolt_chance_per_tick = 50
|
|
|
|
on_launch(var/obj/projectile/P)
|
|
bolt_instance = new bolt_type()
|
|
|
|
tick(var/obj/projectile/P)
|
|
if (prob(bolt_chance_per_tick) && istype(bolt_instance))
|
|
var/list/sfloors = list()
|
|
for (var/turf/T in view(7, P))
|
|
if (!T.density)
|
|
sfloors += T
|
|
new_bolt(P, get_turf(P), bolt_instance)
|
|
|
|
proc/new_bolt(var/obj/projectile/P, var/turf/PT, var/datum/projectile/F)
|
|
var/obj/projectile/FC = initialize_projectile(PT, F, rand(-projectile_speed,projectile_speed), rand(-projectile_speed,projectile_speed), P.shooter)
|
|
FC.launch()
|
|
|
|
/datum/projectile/laser/spewer_bolt
|
|
name = "volatile bolt fragment"
|
|
sname = "volatile bolt fragment"
|
|
icon_state = "ball_white"
|
|
shot_sound = 'sound/weapons/blaster_a.ogg'
|
|
power = 5
|
|
dissipation_delay = 15
|
|
dissipation_rate = 1
|
|
|
|
/datum/projectile/laser/punch // yep :I
|
|
name = "punch"
|
|
window_pass = 0
|
|
icon_state = "punch"
|
|
damage_type = D_KINETIC
|
|
power = 0
|
|
cost = 1
|
|
brightness = 0
|
|
sname = "punch"
|
|
shot_sound = 'sound/impact_sounds/Generic_Swing_1.ogg'
|
|
dissipation_delay = 1
|
|
dissipation_rate = 35
|
|
icon_turf_hit = null
|
|
|
|
on_hit(atom/hit)
|
|
if (usr && hit)
|
|
hit.attack_hand(usr)
|
|
|
|
//mbc : hey i know homing projectiles exist already as 'seeker', but i like mine better
|
|
/datum/projectile/special/homing
|
|
name = "homing"
|
|
icon = 'icons/obj/projectiles.dmi'
|
|
icon_state = "laser"
|
|
power = 1
|
|
cost = 1
|
|
dissipation_rate = 0
|
|
dissipation_delay = 0
|
|
shot_sound = 'sound/weapons/Taser.ogg'
|
|
shot_number = 1
|
|
damage_type = D_SPECIAL
|
|
hit_ground_chance = 100
|
|
window_pass = 0
|
|
|
|
precalculated = 0
|
|
|
|
var/min_speed = 0
|
|
var/max_speed = 23
|
|
var/start_speed = 6
|
|
var/easemult = 0.1
|
|
|
|
var/auto_find_targets = 1
|
|
|
|
var/desired_x = 0
|
|
var/desired_y = 0
|
|
|
|
var/rotate_proj = 1
|
|
var/face_desired_dir = 0
|
|
|
|
goes_through_walls = 1
|
|
|
|
on_launch(var/obj/projectile/P)
|
|
..()
|
|
P.internal_speed = start_speed
|
|
|
|
if (auto_find_targets)
|
|
P.targets = list()
|
|
for(var/mob/M in view(P,15))
|
|
P.targets += M
|
|
|
|
on_hit(atom/hit, direction, projectile)
|
|
return
|
|
|
|
proc/calc_desired_x_y(var/obj/projectile/P)
|
|
.= 0
|
|
|
|
//if (auto_find_targets) //prob expensive
|
|
// P.targets = list()
|
|
// for(var/mob/M in view(P,6))
|
|
// P.targets += M
|
|
|
|
if (P.targets && P.targets.len && P.targets[1])
|
|
|
|
var/atom/closest = P.targets[1]
|
|
|
|
for (var/atom in P.targets)
|
|
var/atom/A = atom
|
|
if (A == P.shooter) continue
|
|
if (get_dist(P,A) < get_dist(P,closest))
|
|
closest = A
|
|
|
|
desired_x = closest.x - P.x
|
|
desired_y = closest.y - P.y
|
|
|
|
.= 1
|
|
|
|
tick(var/obj/projectile/P)
|
|
if (!P)
|
|
return
|
|
|
|
desired_x = 0
|
|
desired_y = 0
|
|
if (calc_desired_x_y(P))
|
|
var/magnitude = vector_magnitude(desired_x,desired_y)
|
|
if (magnitude != 0)
|
|
desired_x /= magnitude
|
|
desired_y /= magnitude
|
|
|
|
desired_x *= max_speed
|
|
desired_y *= max_speed
|
|
|
|
var/xchanged = P.xo + ((desired_x - P.xo) * easemult)
|
|
var/ychanged = P.yo + ((desired_y - P.yo) * easemult)
|
|
|
|
var/setangle = 0
|
|
if (face_desired_dir)
|
|
setangle = atan2(desired_y,desired_x)
|
|
|
|
P.setDirection(xchanged,ychanged, do_turn = rotate_proj, angle_override = setangle)
|
|
P.internal_speed = ( max(min_speed, min(max_speed, magnitude)) )
|
|
|
|
desired_x = 0
|
|
desired_y = 0
|
|
|
|
..()
|
|
|
|
/datum/projectile/special/homing/slow
|
|
max_speed = 1
|
|
|
|
/datum/projectile/special/homing/vamp_blood
|
|
name = "blood glob"
|
|
icon_state = "bloodproj"
|
|
start_speed = 9
|
|
goes_through_walls = 1
|
|
goes_through_mobs = 1
|
|
auto_find_targets = 0
|
|
silentshot = 1
|
|
|
|
shot_sound = "sound/impact_sounds/Flesh_Tear_1.ogg"
|
|
|
|
on_launch(var/obj/projectile/P)
|
|
if (!("victim" in P.special_data))
|
|
P.die()
|
|
return
|
|
|
|
if (!("vamp" in P.special_data))
|
|
P.die()
|
|
return
|
|
P.layer = EFFECTS_LAYER_BASE
|
|
flick("bloodproj",P)
|
|
..()
|
|
|
|
on_hit(atom/hit, direction, var/obj/projectile/P)
|
|
if (("vamp" in P.special_data))
|
|
var/datum/abilityHolder/vampire/vampire = P.special_data["vamp"]
|
|
if (vampire.owner == hit)
|
|
P.die()
|
|
..()
|
|
|
|
on_end(var/obj/projectile/P)
|
|
if (("vamp" in P.special_data) && ("victim" in P.special_data))
|
|
var/datum/abilityHolder/vampire/vampire = P.special_data["vamp"]
|
|
var/mob/living/victim = P.special_data["victim"]
|
|
|
|
if (vampire && victim)
|
|
if (vampire.can_bite(victim,is_pointblank = 0))
|
|
vampire.do_bite(victim, mult = 0.3333)
|
|
|
|
vampire.owner.add_stamina(20)
|
|
victim.remove_stamina(4)
|
|
|
|
..()
|
|
|
|
|
|
//vamp bail out travel
|
|
/datum/projectile/special/homing/travel
|
|
name = "mysterious mystery mist"
|
|
icon_state = "vamp_travel"
|
|
auto_find_targets = 0
|
|
max_speed = 2
|
|
start_speed = 0.1
|
|
|
|
|
|
shot_sound = "sound/effects/mag_phase.ogg"
|
|
goes_through_walls = 1
|
|
goes_through_mobs = 1
|
|
|
|
silentshot = 1
|
|
|
|
|
|
on_hit(atom/hit, direction, var/obj/projectile/P)
|
|
..()
|
|
if (istype(hit, /obj/storage/closet/coffin/vampire))
|
|
P.special_data["insert_owner"] = hit
|
|
P.die()
|
|
|
|
on_launch(var/obj/projectile/P)
|
|
..()
|
|
if (!("owner" in P.special_data))
|
|
P.die()
|
|
return
|
|
var/mob/carryme = P.special_data["owner"]
|
|
carryme.set_loc(P)
|
|
|
|
tick(var/obj/projectile/P)
|
|
..()
|
|
|
|
if (!(P.targets && P.targets.len && P.targets[1]))
|
|
P.die()
|
|
|
|
on_end(var/obj/projectile/P)
|
|
if (("owner" in P.special_data) && P.proj_data == src)
|
|
var/mob/dropme = P.special_data["owner"]
|
|
|
|
if (("insert_owner" in P.special_data) && P.special_data["insert_owner"])
|
|
dropme.set_loc(P.special_data["insert_owner"])
|
|
else
|
|
if (dropme.loc == P)
|
|
dropme.set_loc(get_turf(P))
|
|
boutput(dropme, __red("Your coffin was lost or destroyed! Oh no!!!"))
|
|
..()
|
|
|
|
/datum/projectile/special/homing/orbiter
|
|
icon_state = "bloodproj"
|
|
easemult = 0.3
|
|
|
|
rotate_proj = 1
|
|
face_desired_dir = 1
|
|
|
|
goes_through_walls = 1
|
|
|
|
var/radius = 1.4
|
|
var/ang_inc = 15
|
|
|
|
|
|
on_launch(var/obj/projectile/P)
|
|
..()
|
|
P.special_data["orbit_angle"] = 0
|
|
P.special_data["diss_count"] = 0
|
|
|
|
|
|
calc_desired_x_y(var/obj/projectile/P)
|
|
.= 0
|
|
|
|
if (P.targets && P.targets.len && P.targets[1])
|
|
P.special_data["orbit_angle"] += ang_inc
|
|
if (P.special_data["orbit_angle"] > 360)
|
|
P.special_data["orbit_angle"] -= 360
|
|
|
|
var/atom/target = P.targets[1]
|
|
|
|
//var/ang_between = get_angle(target,P)
|
|
var/tx = target.x + cos(P.special_data["orbit_angle"])
|
|
var/ty = target.y + sin(P.special_data["orbit_angle"])
|
|
|
|
desired_x = (tx - P.x)
|
|
desired_y = (ty - P.y)
|
|
|
|
.= 1
|
|
else
|
|
P.special_data["diss_count"] += 1
|
|
if (P.special_data["diss_count"] > 40)
|
|
P.die()
|
|
|
|
|
|
/datum/projectile/special/homing/orbiter/spiritbat
|
|
name = "frost bat"
|
|
icon = 'icons/misc/critter.dmi'
|
|
icon_state = "spiritbat"
|
|
rotate_proj = 0
|
|
face_desired_dir = 1
|
|
goes_through_walls = 1
|
|
|
|
shot_sound = 0
|
|
hit_mob_sound = 'sound/effects/mag_iceburstimpact_high.ogg'
|
|
hit_object_sound = 'sound/effects/mag_iceburstimpact_high.ogg'
|
|
|
|
var/temp_reduc = 80
|
|
|
|
on_launch(var/obj/projectile/P)
|
|
..()
|
|
P.collide_with_other_projectiles = 1
|
|
//P.transform = matrix()
|
|
|
|
on_hit(atom/hit, direction, var/obj/projectile/P)
|
|
..()
|
|
|
|
if (istype(hit, /obj/projectile))
|
|
var/obj/projectile/pass_proj = hit
|
|
if (pass_proj.proj_data.hit_object_sound)
|
|
playsound(pass_proj.loc, pass_proj.proj_data.hit_object_sound, 60, 0.5)
|
|
if (pass_proj.proj_data.name != src.name)
|
|
pass_proj.die()
|
|
return
|
|
|
|
hit.damage_cold(temp_reduc / 10)
|
|
if (isliving(hit))
|
|
var/mob/living/L = hit
|
|
L.bodytemperature -= temp_reduc
|
|
L.TakeDamage("All", 3, 1, 0, 0)
|
|
|
|
var/atom/targetTurf = 0
|
|
if (P.shooter)
|
|
var/dir = get_dir(P.shooter, P.dir)
|
|
targetTurf = get_edge_target_turf(hit, dir ? dir : P.dir)
|
|
else
|
|
targetTurf = get_edge_target_turf(hit, P.dir)
|
|
|
|
SPAWN_DBG(0)
|
|
L.changeStatus("weakened", 2 SECONDS)
|
|
L.force_laydown_standup()
|
|
L.throw_at(targetTurf, rand(5,7), rand(1,2), throw_type = THROW_GUNIMPACT)
|
|
|
|
on_canpass(var/obj/projectile/P, atom/movable/passing_thing)
|
|
if (P != passing_thing)
|
|
if (istype(passing_thing, /obj/projectile))
|
|
var/obj/projectile/pass_proj = passing_thing
|
|
return (istype(pass_proj.proj_data, src.type) || pass_proj.goes_through_walls)
|
|
|
|
if (isitem(passing_thing))
|
|
var/obj/item/I = passing_thing
|
|
if (I.throwing)
|
|
return 0
|
|
.= 1
|
|
|
|
//place coffin. then, we travel to it in prjoectile form and it heals us while people can beat it
|
|
//cofin is anchored, rises outta ground at spot
|
|
|
|
/datum/projectile/special/spreader/tasershotgunspread //Used in Azungar's taser shotgun.
|
|
name = "energy bolt"
|
|
sname = "shotgun spread"
|
|
shot_number = 0
|
|
cost = 37.5
|
|
power = 80
|
|
pellets_to_fire = 3
|
|
spread_projectile_type = /datum/projectile/energy_bolt/tasershotgun
|
|
split_type = 0
|
|
shot_sound = 'sound/weapons/Taser.ogg'
|
|
hit_mob_sound = 'sound/effects/sparks6.ogg'
|
|
var/spread_angle = 30
|
|
var/current_angle = 0
|
|
var/angle_adjust_per_pellet = 0
|
|
var/initial_angle_offset_mult = 0
|
|
|
|
on_launch(var/obj/projectile/P)
|
|
angle_adjust_per_pellet = ((spread_angle *3) / pellets_to_fire)
|
|
current_angle = (0 - spread_angle) + (angle_adjust_per_pellet * initial_angle_offset_mult)
|
|
..()
|
|
|
|
new_pellet(var/obj/projectile/P, var/turf/PT, var/datum/projectile/F)
|
|
var/obj/projectile/FC = initialize_projectile(PT, F, P.xo, P.yo, P.shooter)
|
|
FC.rotateDirection(current_angle)
|
|
FC.launch()
|
|
current_angle += angle_adjust_per_pellet |