mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-25 06:00:16 +01:00
## About The Pull Request It was removed in https://github.com/tgstation/tgstation/pull/27799 because the spear was broken and the Flans' AI sucked with not-great sprites and was all just one big reference. Original addition: https://github.com/tgstation/tgstation/pull/22270 This re-adds it, updates the map (now using airless turfs) with extra ambiance, using ash whelps (lavaland variation of ice whelps) instead of Flans, re-adds the spear, and adds armor as well this time around. The spear gives you a jump ability to crash down upon a player below you, rather than teleporting to wherever you throw the spear at. You can't attack while mid-air, you can go through tables but not walls/doors, and you also can't un-dualwield or drop the spear mid-jump. Landing on a mob deals double damage to them (36 to unarmored people), while landing on objects deals 150 damage to them (taken from savannah's jump ability, which was in turn taken from hulk's punching) It's also got some extra throw force (24 compared to default spear's 20) The armor has basic security-level armor but covers your whole body. Does not include space protection, and can be worn by Ian. Video demonstration https://github.com/user-attachments/assets/a77c3a0d-17d2-4e8d-88b6-cdbca8b1f2c3 New sprites demonstration https://github.com/user-attachments/assets/0e465351-5484-406f-8adc-ffa1ac180daf Armor demonstration https://github.com/user-attachments/assets/abdfcac6-65bf-443c-bde2-27d157ee3a80 Map  With the changes in https://github.com/tgstation/tgstation/pull/90771 I had to mess with ash whelp abilities a bit, I decided to make them use cold fire instead of hardcoding blue color on top of the fire sprites, and it now acts accordingly too https://github.com/user-attachments/assets/cfca0d70-d13d-4c73-996d-2d4a7519866d The jump was taken from Savannah Ivanov, and Goof's bunny jumping. ##### Code bounty by Ezel/Improvedname ## Why It's Good For The Game This Re-implements a old spear that got removed for its buggyness/bad mapping and on the authors request as well not wanting to deal with it. Re-introduces the SkyBulge as a space ruin, referencing Dragoons from Final Fantasy. this just like any normal spear, but using the savannah jump mechanic, this allows you to close distances with the spear avoiding ranged projectiles in the jump, and if you directly land on your target you will do double the damage. ##### -Ezel/Improvedname ## Changelog 🆑 Ezel/Improvedname, Toriate, JohnFulpWillard add: Re-added the Dragoon Tomb lair, now has a Skybulge spear and Drachen armor. balance: Ice whelps now spit out cold fire. /🆑 --------- Co-authored-by: Jacquerel <hnevard@gmail.com>
129 lines
5.2 KiB
Plaintext
129 lines
5.2 KiB
Plaintext
/datum/action/cooldown/mob_cooldown/fire_breath
|
|
name = "Fire Breath"
|
|
button_icon = 'icons/effects/magic.dmi'
|
|
button_icon_state = "fireball"
|
|
desc = "Breathe a line of flames towards the target."
|
|
cooldown_time = 3 SECONDS
|
|
/// The range of the fire
|
|
var/fire_range = 15
|
|
/// The sound played when you use this ability
|
|
var/fire_sound = 'sound/effects/magic/fireball.ogg'
|
|
/// Time to wait between spawning each fire turf
|
|
var/fire_delay = 1.5 DECISECONDS
|
|
/// How hot is our fire
|
|
var/fire_temperature = DRAKE_FIRE_TEMP
|
|
/// 'How much' fire do we expose the turf to?
|
|
var/fire_volume = DRAKE_FIRE_EXPOSURE
|
|
/// How much damage do you take when engulfed?
|
|
var/fire_damage = 20
|
|
/// How much damage to mechs take when engulfed?
|
|
var/mech_damage = 45
|
|
|
|
/datum/action/cooldown/mob_cooldown/fire_breath/Activate(atom/target_atom)
|
|
disable_cooldown_actions()
|
|
attack_sequence(target_atom)
|
|
StartCooldown()
|
|
enable_cooldown_actions()
|
|
return TRUE
|
|
|
|
/// Apply our specific fire breathing shape, in proc form so we can override it in subtypes
|
|
/datum/action/cooldown/mob_cooldown/fire_breath/proc/attack_sequence(atom/target)
|
|
playsound(owner.loc, fire_sound, 200, TRUE)
|
|
fire_line(target)
|
|
|
|
/// Breathe fire in a line towards the target, optionally rotated at an offset from the target
|
|
/datum/action/cooldown/mob_cooldown/fire_breath/proc/fire_line(atom/target, offset)
|
|
if (isnull(target))
|
|
return
|
|
var/turf/target_turf = get_ranged_target_turf_direct(owner, target, fire_range, offset)
|
|
var/list/turfs = get_line(owner, target_turf) - get_turf(owner)
|
|
INVOKE_ASYNC(src, PROC_REF(progressive_fire_line), turfs)
|
|
|
|
/// Creates fire with a delay on the list of targeted turfs
|
|
/datum/action/cooldown/mob_cooldown/fire_breath/proc/progressive_fire_line(list/burn_turfs)
|
|
if (QDELETED(owner) || owner.stat == DEAD)
|
|
return
|
|
// Guys we have already hit, no double dipping
|
|
var/list/hit_list = list(owner) // also don't burn ourselves
|
|
for(var/turf/target_turf in burn_turfs)
|
|
if (target_turf.is_blocked_turf(exclude_mobs = TRUE))
|
|
return
|
|
burn_turf(target_turf, hit_list, owner)
|
|
sleep(fire_delay)
|
|
|
|
/// Finally spawn the actual fire, spawns the fire hotspot in case you want to recolour it or something
|
|
/datum/action/cooldown/mob_cooldown/fire_breath/proc/burn_turf(turf/fire_turf, list/hit_list, mob/living/source)
|
|
var/obj/effect/hotspot/fire_hotspot = new /obj/effect/hotspot(fire_turf, fire_volume, fire_temperature)
|
|
fire_turf.hotspot_expose(fire_temperature, fire_volume, TRUE)
|
|
|
|
for(var/mob/living/barbecued in fire_turf.contents)
|
|
if(barbecued in hit_list)
|
|
continue
|
|
hit_list |= barbecued
|
|
on_burn_mob(barbecued, source)
|
|
|
|
for(var/obj/vehicle/sealed/mecha/robotron in fire_turf.contents)
|
|
if(robotron in hit_list)
|
|
continue
|
|
hit_list |= robotron
|
|
robotron.take_damage(mech_damage, BURN, FIRE)
|
|
|
|
return fire_hotspot
|
|
|
|
/// Do something unpleasant to someone we set on fire
|
|
/datum/action/cooldown/mob_cooldown/fire_breath/proc/on_burn_mob(mob/living/barbecued, mob/living/source)
|
|
if(fire_temperature <= TCMB)
|
|
barbecued.apply_status_effect(/datum/status_effect/ice_block_talisman, 2 SECONDS)
|
|
to_chat(barbecued, span_userdanger("You're frozen solid by [source]'s icy breath!"))
|
|
else
|
|
to_chat(barbecued, span_userdanger("You are burned by [source]'s fire breath!"))
|
|
barbecued.adjustFireLoss(fire_damage)
|
|
|
|
/// Shoot three lines of fire in a sort of fork pattern approximating a cone
|
|
/datum/action/cooldown/mob_cooldown/fire_breath/cone
|
|
name = "Fire Cone"
|
|
desc = "Breathe several lines of fire directed at a target."
|
|
/// The angles relative to the target that shoot lines of fire
|
|
var/list/angles = list(-40, 0, 40)
|
|
|
|
/datum/action/cooldown/mob_cooldown/fire_breath/cone/attack_sequence(atom/target)
|
|
playsound(owner.loc, fire_sound, 200, TRUE)
|
|
for(var/offset in angles)
|
|
fire_line(target, offset)
|
|
|
|
/// Shoot fire in a whole bunch of directions
|
|
/datum/action/cooldown/mob_cooldown/fire_breath/mass_fire
|
|
name = "Mass Fire"
|
|
button_icon = 'icons/effects/fire.dmi'
|
|
button_icon_state = "light"
|
|
desc = "Breathe flames in all directions."
|
|
cooldown_time = 10.5 SECONDS
|
|
click_to_activate = FALSE
|
|
/// How many fire lines do we produce to turn a full circle?
|
|
var/sectors = 12
|
|
/// How long do we wait between each spin?
|
|
var/breath_delay = 2.5 SECONDS
|
|
/// How many full circles do we perform?
|
|
var/total_spins = 3
|
|
|
|
/datum/action/cooldown/mob_cooldown/fire_breath/mass_fire/Activate(atom/target_atom)
|
|
target_atom = get_step(owner, owner.dir) // Just shoot it forwards, we don't need to click on someone for this one
|
|
return ..()
|
|
|
|
/datum/action/cooldown/mob_cooldown/fire_breath/mass_fire/attack_sequence(atom/target)
|
|
var/queued_spins = 0
|
|
for (var/i in 1 to total_spins)
|
|
var/delay = queued_spins * breath_delay
|
|
queued_spins++
|
|
addtimer(CALLBACK(src, PROC_REF(fire_spin), target, queued_spins), delay)
|
|
|
|
/// Breathe fire in a circle, with a slight angle offset based on which of our several circles it is
|
|
/datum/action/cooldown/mob_cooldown/fire_breath/mass_fire/proc/fire_spin(target, spin_count)
|
|
if (QDELETED(owner) || owner.stat == DEAD)
|
|
return // Too dead to spin
|
|
playsound(owner.loc, fire_sound, 200, TRUE)
|
|
var/angle_increment = 360 / sectors
|
|
var/additional_offset = spin_count * angle_increment / 2
|
|
for (var/i in 1 to sectors)
|
|
fire_line(target, (angle_increment * i) + (additional_offset))
|