mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2025-12-10 09:42:29 +00:00
* ONLY SKYRAT CHANGES * ACTUALLY SKYRAT CHANGES * yolo, revert later * Update alternate_byond_versions.txt Co-authored-by: AnturK <AnturK@users.noreply.github.com>
326 lines
13 KiB
Plaintext
326 lines
13 KiB
Plaintext
/datum/action/cooldown/mob_cooldown/projectile_attack
|
|
name = "Projectile Attack"
|
|
icon_icon = 'icons/mob/actions/actions_items.dmi'
|
|
button_icon_state = "sniper_zoom"
|
|
desc = "Fires a set of projectiles at a selected target."
|
|
cooldown_time = 1.5 SECONDS
|
|
/// The type of the projectile to be fired
|
|
var/projectile_type
|
|
/// The sound played when a projectile is fired
|
|
var/projectile_sound
|
|
/// If the projectile should home in on its target
|
|
var/has_homing = FALSE
|
|
/// The turning speed if there is homing
|
|
var/homing_turn_speed = 30
|
|
/// The variance in the projectiles direction
|
|
var/default_projectile_spread = 0
|
|
/// The multiplier to the projectiles speed (a value of 2 makes it twice as slow, 0.5 makes it twice as fast)
|
|
var/projectile_speed_multiplier = 1
|
|
|
|
/datum/action/cooldown/mob_cooldown/projectile_attack/Activate(atom/target_atom)
|
|
StartCooldown(360 SECONDS, 360 SECONDS)
|
|
attack_sequence(owner, target_atom)
|
|
StartCooldown()
|
|
return TRUE
|
|
|
|
/datum/action/cooldown/mob_cooldown/projectile_attack/proc/attack_sequence(mob/living/firer, atom/target)
|
|
shoot_projectile(firer, target, null, firer, rand(-default_projectile_spread, default_projectile_spread), null)
|
|
|
|
/datum/action/cooldown/mob_cooldown/projectile_attack/proc/shoot_projectile(atom/origin, atom/target, set_angle, mob/firer, projectile_spread, speed_multiplier, override_projectile_type, override_homing)
|
|
var/turf/startloc = get_turf(origin)
|
|
var/turf/endloc = get_turf(target)
|
|
if(!startloc || !endloc)
|
|
return
|
|
var/obj/projectile/our_projectile
|
|
if(override_projectile_type)
|
|
our_projectile = new override_projectile_type(startloc)
|
|
else
|
|
our_projectile = new projectile_type(startloc)
|
|
if(!isnum(speed_multiplier))
|
|
speed_multiplier = projectile_speed_multiplier
|
|
our_projectile.speed *= speed_multiplier
|
|
our_projectile.preparePixelProjectile(endloc, startloc, null, projectile_spread)
|
|
our_projectile.firer = firer
|
|
if(target)
|
|
our_projectile.original = target
|
|
if(override_homing == null && has_homing || override_homing)
|
|
our_projectile.homing_turn_speed = homing_turn_speed
|
|
our_projectile.set_homing_target(target)
|
|
if(isnum(set_angle))
|
|
our_projectile.fire(set_angle)
|
|
return
|
|
our_projectile.fire()
|
|
return our_projectile
|
|
|
|
/datum/action/cooldown/mob_cooldown/projectile_attack/rapid_fire
|
|
name = "Rapid Fire"
|
|
icon_icon = 'icons/obj/weapons/guns/energy.dmi'
|
|
button_icon_state = "kineticgun"
|
|
desc = "Fires projectiles repeatedly at a given target."
|
|
cooldown_time = 1.5 SECONDS
|
|
projectile_type = /obj/projectile/colossus/snowball
|
|
default_projectile_spread = 45
|
|
/// Total shot count
|
|
var/shot_count = 60
|
|
/// Delay between shots
|
|
var/shot_delay = 0.1 SECONDS
|
|
|
|
/datum/action/cooldown/mob_cooldown/projectile_attack/rapid_fire/attack_sequence(mob/living/firer, atom/target)
|
|
for(var/i in 1 to shot_count)
|
|
shoot_projectile(firer, target, null, firer, rand(-default_projectile_spread, default_projectile_spread), null)
|
|
SLEEP_CHECK_DEATH(shot_delay, src)
|
|
|
|
/datum/action/cooldown/mob_cooldown/projectile_attack/rapid_fire/direct
|
|
shot_count = 40
|
|
default_projectile_spread = 5
|
|
|
|
/datum/action/cooldown/mob_cooldown/projectile_attack/rapid_fire/shrapnel
|
|
name = "Shrapnel Fire"
|
|
icon_icon = 'icons/mob/actions/actions_items.dmi'
|
|
button_icon_state = "sniper_zoom"
|
|
desc = "Fires projectiles that will split into shrapnel after a period of time."
|
|
cooldown_time = 6 SECONDS
|
|
projectile_type = /obj/projectile/colossus/frost_orb
|
|
has_homing = TRUE
|
|
default_projectile_spread = 180
|
|
shot_count = 8
|
|
shot_delay = 1 SECONDS
|
|
var/shrapnel_projectile_type = /obj/projectile/colossus/ice_blast
|
|
var/shrapnel_angles = list(0, 60, 120, 180, 240, 300)
|
|
var/shrapnel_spread = 60
|
|
var/break_time = 2 SECONDS
|
|
|
|
/datum/action/cooldown/mob_cooldown/projectile_attack/rapid_fire/shrapnel/attack_sequence(mob/living/firer, atom/target)
|
|
for(var/i in 1 to shot_count)
|
|
var/obj/projectile/to_explode = shoot_projectile(firer, target, null, firer, rand(-default_projectile_spread, default_projectile_spread), null)
|
|
addtimer(CALLBACK(src, PROC_REF(explode_into_shrapnel), firer, target, to_explode), break_time)
|
|
SLEEP_CHECK_DEATH(shot_delay, src)
|
|
|
|
/datum/action/cooldown/mob_cooldown/projectile_attack/rapid_fire/shrapnel/proc/explode_into_shrapnel(mob/living/firer, atom/target, obj/projectile/to_explode)
|
|
if(!to_explode)
|
|
return
|
|
for(var/angle in shrapnel_angles)
|
|
// no speed multiplier for shrapnel
|
|
shoot_projectile(to_explode, target, angle + rand(-shrapnel_spread, shrapnel_spread), firer, null, 1, shrapnel_projectile_type, FALSE)
|
|
qdel(to_explode)
|
|
|
|
/datum/action/cooldown/mob_cooldown/projectile_attack/rapid_fire/shrapnel/strong
|
|
name = "Strong Shrapnel Fire"
|
|
shot_count = 16
|
|
shot_delay = 0.5 SECONDS
|
|
|
|
/datum/action/cooldown/mob_cooldown/projectile_attack/spiral_shots
|
|
name = "Spiral Shots"
|
|
icon_icon = 'icons/mob/actions/actions_items.dmi'
|
|
button_icon_state = "sniper_zoom"
|
|
desc = "Fires projectiles in a spiral pattern."
|
|
cooldown_time = 3 SECONDS
|
|
projectile_type = /obj/projectile/colossus
|
|
projectile_sound = 'sound/magic/clockwork/invoke_general.ogg'
|
|
/// Whether or not the attack is the enraged form
|
|
var/enraged = FALSE
|
|
|
|
/datum/action/cooldown/mob_cooldown/projectile_attack/spiral_shots/attack_sequence(mob/living/firer, atom/target)
|
|
if(enraged)
|
|
SLEEP_CHECK_DEATH(1 SECONDS, firer)
|
|
INVOKE_ASYNC(src, PROC_REF(create_spiral_attack), firer, target, TRUE)
|
|
create_spiral_attack(firer, target, FALSE)
|
|
return
|
|
create_spiral_attack(firer, target)
|
|
|
|
/datum/action/cooldown/mob_cooldown/projectile_attack/spiral_shots/proc/create_spiral_attack(mob/living/firer, atom/target, negative = pick(TRUE, FALSE))
|
|
var/counter = 8
|
|
for(var/i in 1 to 80)
|
|
if(negative)
|
|
counter--
|
|
else
|
|
counter++
|
|
if(counter > 16)
|
|
counter = 1
|
|
if(counter < 1)
|
|
counter = 16
|
|
shoot_projectile(firer, target, counter * 22.5, firer, null, null)
|
|
playsound(get_turf(firer), projectile_sound, 20, TRUE)
|
|
SLEEP_CHECK_DEATH(0.1 SECONDS, firer)
|
|
|
|
/datum/action/cooldown/mob_cooldown/projectile_attack/spiral_shots/colossus
|
|
cooldown_time = 1.5 SECONDS
|
|
|
|
/datum/action/cooldown/mob_cooldown/projectile_attack/spiral_shots/colossus/Activate(atom/target_atom)
|
|
SLEEP_CHECK_DEATH(1.5 SECONDS, owner)
|
|
return ..()
|
|
|
|
/datum/action/cooldown/mob_cooldown/projectile_attack/random_aoe
|
|
name = "All Directions"
|
|
icon_icon = 'icons/effects/effects.dmi'
|
|
button_icon_state = "at_shield2"
|
|
desc = "Fires projectiles in all directions."
|
|
cooldown_time = 3 SECONDS
|
|
projectile_type = /obj/projectile/colossus
|
|
projectile_sound = 'sound/magic/clockwork/invoke_general.ogg'
|
|
|
|
/datum/action/cooldown/mob_cooldown/projectile_attack/random_aoe/attack_sequence(mob/living/firer, atom/target)
|
|
var/turf/U = get_turf(firer)
|
|
playsound(U, projectile_sound, 300, TRUE, 5)
|
|
for(var/i in 1 to 32)
|
|
shoot_projectile(firer, target, rand(0, 360), firer, null, null)
|
|
|
|
/datum/action/cooldown/mob_cooldown/projectile_attack/random_aoe/colossus
|
|
cooldown_time = 1.5 SECONDS
|
|
|
|
/datum/action/cooldown/mob_cooldown/projectile_attack/random_aoe/colossus/Activate(atom/target_atom)
|
|
SLEEP_CHECK_DEATH(1.5 SECONDS, owner)
|
|
return ..()
|
|
|
|
/datum/action/cooldown/mob_cooldown/projectile_attack/shotgun_blast
|
|
name = "Shotgun Fire"
|
|
icon_icon = 'icons/obj/weapons/guns/ballistic.dmi'
|
|
button_icon_state = "shotgun"
|
|
desc = "Fires projectiles in a shotgun pattern."
|
|
cooldown_time = 2 SECONDS
|
|
projectile_type = /obj/projectile/colossus
|
|
projectile_sound = 'sound/magic/clockwork/invoke_general.ogg'
|
|
var/list/shot_angles = list(12.5, 7.5, 2.5, -2.5, -7.5, -12.5)
|
|
|
|
/datum/action/cooldown/mob_cooldown/projectile_attack/shotgun_blast/attack_sequence(mob/living/firer, atom/target)
|
|
fire_shotgun(firer, target, shot_angles)
|
|
|
|
/datum/action/cooldown/mob_cooldown/projectile_attack/shotgun_blast/proc/fire_shotgun(mob/living/firer, atom/target, list/chosen_angles)
|
|
playsound(firer, projectile_sound, 200, TRUE, 2)
|
|
for(var/spread in chosen_angles)
|
|
shoot_projectile(firer, target, null, firer, spread, null)
|
|
|
|
|
|
/datum/action/cooldown/mob_cooldown/projectile_attack/shotgun_blast/colossus
|
|
cooldown_time = 0.5 SECONDS
|
|
|
|
/datum/action/cooldown/mob_cooldown/projectile_attack/shotgun_blast/colossus/Activate(atom/target_atom)
|
|
SLEEP_CHECK_DEATH(1.5 SECONDS, owner)
|
|
return ..()
|
|
|
|
/datum/action/cooldown/mob_cooldown/projectile_attack/shotgun_blast/pattern
|
|
name = "Alternating Shotgun Fire"
|
|
desc = "Fires projectiles in an alternating shotgun pattern."
|
|
projectile_type = /obj/projectile/colossus/ice_blast
|
|
projectile_sound = null
|
|
shot_angles = list(list(-40, -20, 0, 20, 40), list(-30, -10, 10, 30))
|
|
var/shot_count = 5
|
|
|
|
/datum/action/cooldown/mob_cooldown/projectile_attack/shotgun_blast/pattern/attack_sequence(mob/living/firer, atom/target)
|
|
for(var/i in 1 to shot_count)
|
|
var/list/pattern = shot_angles[i % length(shot_angles) + 1] // changing patterns
|
|
fire_shotgun(firer, target, pattern)
|
|
SLEEP_CHECK_DEATH(0.8 SECONDS, firer)
|
|
|
|
/datum/action/cooldown/mob_cooldown/projectile_attack/shotgun_blast/pattern/circular
|
|
name = "Circular Shotgun Fire"
|
|
shot_angles = list(list(0, 30, 60, 90, 120, 150, 180, 210, 240, 270, 300, 330), list(-30, -15, 0, 15, 30))
|
|
|
|
/datum/action/cooldown/mob_cooldown/projectile_attack/shotgun_blast/pattern/circular/complete
|
|
shot_angles = list(list(-180, -140, -100, -60, -20, 20, 60, 100, 140), list(-160, -120, -80, -40, 0, 40, 80, 120, 160))
|
|
|
|
/datum/action/cooldown/mob_cooldown/projectile_attack/dir_shots
|
|
name = "Directional Shots"
|
|
icon_icon = 'icons/obj/weapons/guns/ballistic.dmi'
|
|
button_icon_state = "pistol"
|
|
desc = "Fires projectiles in specific directions."
|
|
cooldown_time = 4 SECONDS
|
|
projectile_type = /obj/projectile/colossus
|
|
projectile_sound = 'sound/magic/clockwork/invoke_general.ogg'
|
|
var/list/firing_directions
|
|
|
|
/datum/action/cooldown/mob_cooldown/projectile_attack/dir_shots/New(Target)
|
|
. = ..()
|
|
if(!firing_directions)
|
|
firing_directions = GLOB.alldirs.Copy()
|
|
|
|
/datum/action/cooldown/mob_cooldown/projectile_attack/dir_shots/attack_sequence(mob/living/firer, atom/target)
|
|
fire_in_directions(firer, target, firing_directions)
|
|
|
|
/datum/action/cooldown/mob_cooldown/projectile_attack/dir_shots/proc/fire_in_directions(mob/living/firer, atom/target, list/dirs)
|
|
if(!islist(dirs))
|
|
dirs = GLOB.alldirs.Copy()
|
|
playsound(firer, projectile_sound, 200, TRUE, 2)
|
|
for(var/dir in dirs)
|
|
shoot_projectile(firer, target, dir2angle(dir), firer)
|
|
|
|
/datum/action/cooldown/mob_cooldown/projectile_attack/dir_shots/alternating
|
|
name = "Alternating Shots"
|
|
desc = "Fires projectiles in alternating directions."
|
|
|
|
/datum/action/cooldown/mob_cooldown/projectile_attack/dir_shots/alternating/attack_sequence(mob/living/firer, atom/target)
|
|
fire_in_directions(firer, target, GLOB.diagonals)
|
|
SLEEP_CHECK_DEATH(1 SECONDS, firer)
|
|
fire_in_directions(firer, target, GLOB.cardinals)
|
|
SLEEP_CHECK_DEATH(1 SECONDS, firer)
|
|
fire_in_directions(firer, target, GLOB.diagonals)
|
|
SLEEP_CHECK_DEATH(1 SECONDS, firer)
|
|
fire_in_directions(firer, target, GLOB.cardinals)
|
|
|
|
/datum/action/cooldown/mob_cooldown/projectile_attack/dir_shots/alternating/colossus
|
|
cooldown_time = 2.5 SECONDS
|
|
|
|
/datum/action/cooldown/mob_cooldown/projectile_attack/dir_shots/alternating/colossus/Activate(atom/target_atom)
|
|
SLEEP_CHECK_DEATH(1.5 SECONDS, owner)
|
|
return ..()
|
|
|
|
/datum/action/cooldown/mob_cooldown/projectile_attack/kinetic_accelerator
|
|
name = "Fire Kinetic Accelerator"
|
|
icon_icon = 'icons/obj/weapons/guns/energy.dmi'
|
|
button_icon_state = "kineticgun"
|
|
desc = "Fires a kinetic accelerator projectile at the target."
|
|
cooldown_time = 1.5 SECONDS
|
|
projectile_type = /obj/projectile/kinetic/miner
|
|
projectile_sound = 'sound/weapons/kenetic_accel.ogg'
|
|
|
|
/datum/action/cooldown/mob_cooldown/projectile_attack/kinetic_accelerator/Activate(atom/target_atom)
|
|
. = ..()
|
|
playsound(owner, projectile_sound, 200, TRUE, 2)
|
|
owner.visible_message(span_danger("[owner] fires the proto-kinetic accelerator!"))
|
|
owner.face_atom(target_atom)
|
|
new /obj/effect/temp_visual/dir_setting/firing_effect(owner.loc, owner.dir)
|
|
|
|
/datum/action/cooldown/mob_cooldown/projectile_attack/colossus_final
|
|
name = "Titan's Finale"
|
|
desc = "A single-use ability that shoots a large amount of projectiles around you."
|
|
cooldown_time = 2.5 SECONDS
|
|
|
|
/datum/action/cooldown/mob_cooldown/projectile_attack/colossus_final/Activate(atom/target_atom)
|
|
. = ..()
|
|
Remove(owner)
|
|
|
|
/datum/action/cooldown/mob_cooldown/projectile_attack/colossus_final/attack_sequence(mob/living/firer, atom/target)
|
|
var/mob/living/simple_animal/hostile/megafauna/colossus/colossus
|
|
if(istype(firer, /mob/living/simple_animal/hostile/megafauna/colossus))
|
|
colossus = firer
|
|
colossus.say("Perish.", spans = list("colossus", "yell"))
|
|
|
|
var/finale_counter = 10
|
|
for(var/i in 1 to 20)
|
|
if(finale_counter > 4 && colossus)
|
|
colossus.telegraph()
|
|
colossus.shotgun_blast.attack_sequence(firer, target)
|
|
|
|
if(finale_counter > 1)
|
|
finale_counter -= 1
|
|
|
|
var/turf/start_turf = get_turf(firer)
|
|
for(var/turf/target_turf in RANGE_TURFS(12, start_turf))
|
|
if(prob(min(finale_counter, 2)) && target_turf != get_turf(firer))
|
|
shoot_projectile(firer, target_turf, null, firer, null, null)
|
|
|
|
SLEEP_CHECK_DEATH(finale_counter + 1, firer)
|
|
|
|
for(var/i in 1 to 3)
|
|
if(colossus)
|
|
colossus.telegraph()
|
|
colossus.random_shots.attack_sequence(firer, target)
|
|
finale_counter += 6
|
|
SLEEP_CHECK_DEATH(finale_counter, firer)
|
|
|
|
for(var/i in 1 to 3)
|
|
if(colossus)
|
|
colossus.telegraph()
|
|
colossus.dir_shots.attack_sequence(firer, target)
|
|
SLEEP_CHECK_DEATH(1 SECONDS, firer)
|