mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-24 05:30:05 +01:00
Dumbfire changes (#43843)
* Dumbfire changes * Unifies dumbfire and projectile. * Also fixes this while i'm at it.
This commit is contained in:
@@ -137,7 +137,7 @@
|
||||
mob_size = MOB_SIZE_LARGE
|
||||
force_threshold = 10
|
||||
construct_spells = list(/obj/effect/proc_holder/spell/targeted/forcewall/cult,
|
||||
/obj/effect/proc_holder/spell/dumbfire/juggernaut)
|
||||
/obj/effect/proc_holder/spell/targeted/projectile/dumbfire/juggernaut)
|
||||
runetype = /datum/action/innate/cult/create_rune/wall
|
||||
playstyle_string = "<b>You are a Juggernaut. Though slow, your shell can withstand heavy punishment, \
|
||||
create shield walls, rip apart enemies and walls alike, and even deflect energy weapons.</b>"
|
||||
|
||||
@@ -146,11 +146,14 @@
|
||||
clothes_req = FALSE
|
||||
invocation = "none"
|
||||
invocation_type = "none"
|
||||
proj_lifespan = 10
|
||||
max_targets = 6
|
||||
action_icon_state = "magicm"
|
||||
action_background_icon_state = "bg_demon"
|
||||
proj_type = /obj/item/projectile/magic/spell/magic_missile/lesser
|
||||
|
||||
/obj/item/projectile/magic/spell/magic_missile/lesser
|
||||
color = "red" //Looks more culty this way
|
||||
range = 10
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/smoke/disable
|
||||
name = "Paralysing Smoke"
|
||||
@@ -282,37 +285,37 @@
|
||||
jaunt_out_type = /obj/effect/temp_visual/dir_setting/cult/phase/out
|
||||
|
||||
|
||||
/obj/effect/proc_holder/spell/dumbfire/juggernaut
|
||||
/obj/effect/proc_holder/spell/targeted/projectile/dumbfire/juggernaut
|
||||
name = "Gauntlet Echo"
|
||||
desc = "Channels energy into your gauntlet - firing its essence forward in a slow moving, yet devastating, attack."
|
||||
proj_icon_state = "cultfist"
|
||||
proj_name = "gauntlet echo"
|
||||
proj_type = "/obj/effect/proc_holder/spell/targeted/inflict_handler/juggernaut" //IMPORTANT use only subtypes of this
|
||||
proj_lifespan = 15
|
||||
proj_step_delay = 7
|
||||
proj_type = /obj/item/projectile/magic/spell/juggernaut
|
||||
charge_max = 350
|
||||
clothes_req = FALSE
|
||||
action_icon = 'icons/mob/actions/actions_cult.dmi'
|
||||
action_icon_state = "cultfist"
|
||||
action_background_icon_state = "bg_demon"
|
||||
sound = 'sound/weapons/resonator_blast.ogg'
|
||||
proj_trigger_range = 0
|
||||
ignore_factions = list("cult")
|
||||
check_holy = TRUE
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/inflict_handler/juggernaut
|
||||
/obj/item/projectile/magic/spell/juggernaut
|
||||
name = "Gauntlet Echo"
|
||||
icon_state = "cultfist"
|
||||
alpha = 180
|
||||
amt_dam_brute = 30
|
||||
amt_knockdown = 50
|
||||
sound = 'sound/weapons/punch3.ogg'
|
||||
damage = 30
|
||||
damage_type = BRUTE
|
||||
knockdown = 50
|
||||
hitsound = 'sound/weapons/punch3.ogg'
|
||||
trigger_range = 0
|
||||
check_holy = TRUE
|
||||
ignored_factions = list("cult")
|
||||
range = 15
|
||||
speed = 7
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/inflict_handler/juggernaut/cast(list/targets,mob/user = usr)
|
||||
/obj/item/projectile/magic/spell/juggernaut/on_hit(atom/target, blocked)
|
||||
. = ..()
|
||||
var/turf/T = get_turf(src)
|
||||
playsound(T, 'sound/weapons/resonator_blast.ogg', 100, FALSE)
|
||||
new /obj/effect/temp_visual/cult/sac(T)
|
||||
for(var/obj/O in range(src,1))
|
||||
if(O.density && !istype(O, /obj/structure/destructible/cult))
|
||||
O.take_damage(90, BRUTE, "melee", 0)
|
||||
new /obj/effect/temp_visual/cult/turf/floor
|
||||
..()
|
||||
new /obj/effect/temp_visual/cult/turf/floor(get_turf(O))
|
||||
|
||||
@@ -1,114 +0,0 @@
|
||||
|
||||
//NEEDS MAJOR CODE CLEANUP
|
||||
|
||||
/obj/effect/proc_holder/spell/dumbfire
|
||||
|
||||
var/projectile_type = ""
|
||||
var/activate_on_collision = 1
|
||||
|
||||
var/proj_icon = 'icons/obj/projectiles.dmi'
|
||||
var/proj_icon_state = "spell"
|
||||
var/proj_name = "a spell projectile"
|
||||
|
||||
var/proj_trail = 0 //if it leaves a trail
|
||||
var/proj_trail_lifespan = 0 //deciseconds
|
||||
var/proj_trail_icon = 'icons/obj/wizard.dmi'
|
||||
var/proj_trail_icon_state = "trail"
|
||||
|
||||
var/proj_type = "/obj/effect/proc_holder/spell" //IMPORTANT use only subtypes of this
|
||||
|
||||
var/proj_insubstantial = 0 //if it can pass through dense objects or not
|
||||
var/proj_trigger_range = 1 //the range from target at which the projectile triggers cast(target)
|
||||
|
||||
var/proj_lifespan = 100 //in deciseconds * proj_step_delay
|
||||
var/proj_step_delay = 1 //lower = faster
|
||||
var/list/ignore_factions = list() //Faction types that will be ignored
|
||||
|
||||
var/check_antimagic = TRUE
|
||||
var/check_holy = FALSE
|
||||
|
||||
/obj/effect/proc_holder/spell/dumbfire/choose_targets(mob/user = usr)
|
||||
|
||||
var/turf/T = get_turf(user)
|
||||
for(var/i = 1; i < range; i++)
|
||||
var/turf/new_turf = get_step(T, user.dir)
|
||||
if(new_turf.density)
|
||||
break
|
||||
T = new_turf
|
||||
perform(list(T),user = user)
|
||||
|
||||
/obj/effect/proc_holder/spell/dumbfire/cast(list/targets, mob/user = usr)
|
||||
playMagSound()
|
||||
for(var/turf/target in targets)
|
||||
launch_at(target, user)
|
||||
|
||||
/obj/effect/proc_holder/spell/dumbfire/proc/launch_at(turf/target, mob/user)
|
||||
set waitfor = FALSE
|
||||
var/obj/effect/proc_holder/spell/targeted/projectile
|
||||
if(istext(proj_type))
|
||||
var/projectile_type = text2path(proj_type)
|
||||
projectile = new projectile_type(user)
|
||||
else if(istype(proj_type, /obj/effect/proc_holder/spell))
|
||||
projectile = new /obj/effect/proc_holder/spell/targeted/trigger(user)
|
||||
var/obj/effect/proc_holder/spell/targeted/trigger/T = projectile
|
||||
T.linked_spells += proj_type
|
||||
else
|
||||
projectile = new proj_type(user)
|
||||
projectile.icon = proj_icon
|
||||
projectile.icon_state = proj_icon_state
|
||||
projectile.setDir(get_dir(projectile, target))
|
||||
projectile.name = proj_name
|
||||
|
||||
var/current_loc = user.loc
|
||||
|
||||
projectile.forceMove(current_loc)
|
||||
|
||||
for(var/i = 0,i < proj_lifespan,i++)
|
||||
if(!projectile)
|
||||
break
|
||||
|
||||
if(proj_insubstantial)
|
||||
projectile.forceMove(get_step(projectile, projectile.dir))
|
||||
else
|
||||
step(projectile, projectile.dir)
|
||||
|
||||
if(projectile.loc == current_loc || i == proj_lifespan)
|
||||
projectile.cast(current_loc,user=user)
|
||||
break
|
||||
|
||||
var/mob/living/L = locate(/mob/living) in range(projectile, proj_trigger_range) - user
|
||||
if(L && L.stat != DEAD && L.anti_magic_check(check_antimagic, check_holy))
|
||||
if(!ignore_factions.len)
|
||||
projectile.cast(L.loc,user=user)
|
||||
break
|
||||
else
|
||||
var/faction_check = FALSE
|
||||
for(var/faction in L.faction)
|
||||
if(ignore_factions.Find(faction))
|
||||
faction_check = TRUE
|
||||
break
|
||||
if(!faction_check)
|
||||
projectile.cast(L.loc,user=user)
|
||||
break
|
||||
|
||||
if(proj_trail && projectile)
|
||||
proj_trail(projectile)
|
||||
|
||||
current_loc = projectile.loc
|
||||
var/matrix/M = new
|
||||
M.Turn(dir2angle(projectile.dir))
|
||||
projectile.transform = M
|
||||
|
||||
sleep(proj_step_delay)
|
||||
|
||||
if(projectile)
|
||||
qdel(projectile)
|
||||
|
||||
/obj/effect/proc_holder/spell/dumbfire/proc/proj_trail(obj/effect/proc_holder/spell/targeted/projectile)
|
||||
set waitfor = FALSE
|
||||
if(projectile)
|
||||
var/obj/effect/overlay/trail = new /obj/effect/overlay(projectile.loc)
|
||||
trail.icon = proj_trail_icon
|
||||
trail.icon_state = proj_trail_icon_state
|
||||
trail.density = FALSE
|
||||
QDEL_IN(trail, proj_trail_lifespan)
|
||||
@@ -1,96 +1,130 @@
|
||||
|
||||
|
||||
/obj/item/projectile/magic/spell
|
||||
name = "custom spell projectile"
|
||||
var/list/ignored_factions //Do not hit these
|
||||
var/check_holy = FALSE
|
||||
var/check_antimagic = FALSE
|
||||
var/trigger_range = 0 //How far we do we need to be to hit
|
||||
var/linger = FALSE //Can't hit anything but the intended target
|
||||
|
||||
var/trail = FALSE //if it leaves a trail
|
||||
var/trail_lifespan = 0 //deciseconds
|
||||
var/trail_icon = 'icons/obj/wizard.dmi'
|
||||
var/trail_icon_state = "trail"
|
||||
|
||||
//todo unify this and magic/aoe under common path
|
||||
/obj/item/projectile/magic/spell/Range()
|
||||
if(trigger_range > 1)
|
||||
for(var/mob/living/L in range(trigger_range, get_turf(src)))
|
||||
if(can_hit_target(L, ignore_loc = TRUE))
|
||||
return Bump(L)
|
||||
. = ..()
|
||||
|
||||
/obj/item/projectile/magic/spell/Moved(atom/OldLoc, Dir)
|
||||
. = ..()
|
||||
if(trail)
|
||||
create_trail()
|
||||
|
||||
/obj/item/projectile/magic/spell/proc/create_trail()
|
||||
if(!trajectory)
|
||||
return
|
||||
var/datum/point/vector/previous = trajectory.return_vector_after_increments(1,-1)
|
||||
var/obj/effect/overlay/trail = new /obj/effect/overlay(previous.return_turf())
|
||||
trail.pixel_x = previous.return_px()
|
||||
trail.pixel_y = previous.return_py()
|
||||
trail.icon = trail_icon
|
||||
trail.icon_state = trail_icon_state
|
||||
//might be changed to temp overlay
|
||||
trail.density = FALSE
|
||||
trail.mouse_opacity = MOUSE_OPACITY_TRANSPARENT
|
||||
QDEL_IN(trail, trail_lifespan)
|
||||
|
||||
/obj/item/projectile/magic/spell/can_hit_target(atom/target, list/passthrough, direct_target = FALSE, ignore_loc = FALSE)
|
||||
. = ..()
|
||||
if(linger && target != original)
|
||||
return FALSE
|
||||
if(ismob(target) && !direct_target) //Unsure about the direct target, i guess it could always skip these.
|
||||
var/mob/M = target
|
||||
if(M.anti_magic_check(check_antimagic, check_holy))
|
||||
return FALSE
|
||||
if(ignored_factions && ignored_factions.len && faction_check(M.faction,ignored_factions))
|
||||
return FALSE
|
||||
|
||||
|
||||
//NEEDS MAJOR CODE CLEANUP.
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/projectile
|
||||
name = "Projectile"
|
||||
desc = "This spell summons projectiles which try to hit the targets."
|
||||
|
||||
|
||||
|
||||
var/proj_type = /obj/item/projectile/magic/spell //IMPORTANT use only subtypes of this
|
||||
|
||||
|
||||
var/update_projectile = FALSE //So you want to admin abuse magic bullets ? This is for you
|
||||
//Below only apply if update_projectile is true
|
||||
var/proj_icon = 'icons/obj/projectiles.dmi'
|
||||
var/proj_icon_state = "spell"
|
||||
var/proj_name = "a spell projectile"
|
||||
|
||||
var/proj_trail = FALSE //if it leaves a trail
|
||||
var/proj_trail_lifespan = 0 //deciseconds
|
||||
var/proj_trail_icon = 'icons/obj/wizard.dmi'
|
||||
var/proj_trail_icon_state = "trail"
|
||||
|
||||
|
||||
var/proj_type = "/obj/effect/proc_holder/spell/targeted" //IMPORTANT use only subtypes of this
|
||||
|
||||
var/proj_lingering = FALSE //if it lingers or disappears upon hitting an obstacle
|
||||
var/proj_homing = TRUE //if it follows the target
|
||||
var/proj_insubstantial = FALSE //if it can pass through dense objects or not
|
||||
var/proj_trigger_range = FALSE //the range from target at which the projectile triggers cast(target)
|
||||
|
||||
var/proj_trigger_range = 0 //the range from target at which the projectile triggers cast(target)
|
||||
var/proj_lifespan = 15 //in deciseconds * proj_step_delay
|
||||
var/proj_step_delay = 1 //lower = faster
|
||||
var/list/ignore_factions = list() //Faction types that will be ignored
|
||||
var/check_antimagic = TRUE
|
||||
var/check_holy = FALSE
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/projectile/proc/fire_projectile(atom/target, mob/user)
|
||||
var/obj/item/projectile/magic/spell/projectile = new proj_type()
|
||||
|
||||
if(update_projectile)
|
||||
//Generally these should already be set on the projectile, this is mostly here for varedited spells.
|
||||
projectile.icon = proj_icon
|
||||
projectile.icon_state = proj_icon_state
|
||||
projectile.name = proj_name
|
||||
if(proj_insubstantial)
|
||||
projectile.movement_type |= UNSTOPPABLE
|
||||
if(proj_homing)
|
||||
projectile.homing = TRUE
|
||||
projectile.homing_turn_speed = 360 //Perfect tracking
|
||||
if(proj_lingering)
|
||||
projectile.linger = TRUE
|
||||
projectile.trigger_range = proj_trigger_range
|
||||
projectile.ignored_factions = ignore_factions
|
||||
projectile.range = proj_lifespan
|
||||
projectile.speed = proj_step_delay
|
||||
projectile.trail = proj_trail
|
||||
projectile.trail_lifespan = proj_trail_lifespan
|
||||
projectile.trail_icon = proj_trail_icon
|
||||
projectile.trail_icon_state = proj_trail_icon_state
|
||||
|
||||
projectile.preparePixelProjectile(target,user)
|
||||
if(projectile.homing)
|
||||
projectile.set_homing_target(target)
|
||||
projectile.fire()
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/projectile/cast(list/targets, mob/user = usr)
|
||||
playMagSound()
|
||||
for(var/mob/living/target in targets)
|
||||
launch(target, user)
|
||||
for(var/atom/target in targets)
|
||||
fire_projectile(target, user)
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/projectile/proc/launch(mob/living/target, mob/user)
|
||||
set waitfor = FALSE
|
||||
var/obj/effect/proc_holder/spell/targeted/projectile
|
||||
if(istext(proj_type))
|
||||
var/projectile_type = text2path(proj_type)
|
||||
projectile = new projectile_type(user)
|
||||
if(istype(proj_type, /obj/effect/proc_holder/spell))
|
||||
projectile = new /obj/effect/proc_holder/spell/targeted/trigger(user)
|
||||
var/obj/effect/proc_holder/spell/targeted/trigger/T = projectile
|
||||
T.linked_spells += proj_type
|
||||
projectile.icon = proj_icon
|
||||
projectile.icon_state = proj_icon_state
|
||||
projectile.setDir(get_dir(target,projectile))
|
||||
projectile.name = proj_name
|
||||
//This one just pops one projectile in direction user is facing, irrelevant of max_targets etc
|
||||
/obj/effect/proc_holder/spell/targeted/projectile/dumbfire
|
||||
name = "Dumbfire projectile"
|
||||
|
||||
var/current_loc = user.loc
|
||||
|
||||
projectile.forceMove(current_loc)
|
||||
|
||||
for(var/i = 0,i < proj_lifespan,i++)
|
||||
if(!projectile)
|
||||
/obj/effect/proc_holder/spell/targeted/projectile/dumbfire/choose_targets(mob/user = usr)
|
||||
var/turf/T = get_turf(user)
|
||||
for(var/i = 1; i < range; i++)
|
||||
var/turf/new_turf = get_step(T, user.dir)
|
||||
if(new_turf.density)
|
||||
break
|
||||
|
||||
if(proj_homing)
|
||||
if(proj_insubstantial)
|
||||
projectile.setDir(get_dir(projectile,target))
|
||||
projectile.forceMove(get_step_to(projectile,target))
|
||||
else
|
||||
step_to(projectile,target)
|
||||
else
|
||||
if(proj_insubstantial)
|
||||
projectile.forceMove(get_step(projectile,dir))
|
||||
else
|
||||
step(projectile,dir)
|
||||
|
||||
if(!projectile) // step and step_to sleeps so we'll have to check again.
|
||||
break
|
||||
|
||||
if(!target || (!proj_lingering && projectile.loc == current_loc)) //if it didn't move since last time
|
||||
qdel(projectile)
|
||||
break
|
||||
|
||||
if(proj_trail && projectile)
|
||||
spawntrail(projectile)
|
||||
|
||||
if(projectile.loc in range(target.loc,proj_trigger_range))
|
||||
projectile.perform(list(target),user=user)
|
||||
break
|
||||
|
||||
current_loc = projectile.loc
|
||||
|
||||
sleep(proj_step_delay)
|
||||
|
||||
if(projectile)
|
||||
qdel(projectile)
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/projectile/proc/spawntrail(obj/effect/proc_holder/spell/targeted/projectile)
|
||||
set waitfor = FALSE
|
||||
if(projectile)
|
||||
var/obj/effect/overlay/trail = new /obj/effect/overlay(projectile.loc)
|
||||
trail.icon = proj_trail_icon
|
||||
trail.icon_state = proj_trail_icon_state
|
||||
trail.density = FALSE
|
||||
QDEL_IN(trail, proj_trail_lifespan)
|
||||
T = new_turf
|
||||
perform(list(T),user = user)
|
||||
@@ -9,27 +9,24 @@
|
||||
invocation_type = "shout"
|
||||
range = 7
|
||||
cooldown_min = 60 //35 deciseconds reduction per rank
|
||||
|
||||
max_targets = 0
|
||||
|
||||
proj_icon_state = "magicm"
|
||||
proj_name = "a magic missile"
|
||||
proj_lingering = 1
|
||||
proj_type = "/obj/effect/proc_holder/spell/targeted/inflict_handler/magic_missile"
|
||||
|
||||
proj_lifespan = 20
|
||||
proj_step_delay = 5
|
||||
|
||||
proj_trail = TRUE
|
||||
proj_trail_lifespan = 5
|
||||
proj_trail_icon_state = "magicmd"
|
||||
|
||||
proj_type = /obj/item/projectile/magic/spell/magic_missile
|
||||
action_icon_state = "magicm"
|
||||
sound = 'sound/magic/magic_missile.ogg'
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/inflict_handler/magic_missile
|
||||
amt_knockdown = 60
|
||||
sound = 'sound/magic/mm_hit.ogg'
|
||||
/obj/item/projectile/magic/spell/magic_missile
|
||||
name = "a magic missile"
|
||||
icon_state = "magicm"
|
||||
range = 20
|
||||
speed = 5
|
||||
trigger_range = 0
|
||||
linger = TRUE
|
||||
knockdown = 60
|
||||
hitsound = 'sound/magic/mm_hit.ogg'
|
||||
|
||||
trail = TRUE
|
||||
trail_lifespan = 5
|
||||
trail_icon_state = "magicmd"
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/genetic/mutate
|
||||
name = "Mutate"
|
||||
|
||||
@@ -2643,7 +2643,6 @@
|
||||
#include "code\modules\spells\spell_types\curse.dm"
|
||||
#include "code\modules\spells\spell_types\devil.dm"
|
||||
#include "code\modules\spells\spell_types\devil_boons.dm"
|
||||
#include "code\modules\spells\spell_types\dumbfire.dm"
|
||||
#include "code\modules\spells\spell_types\emplosion.dm"
|
||||
#include "code\modules\spells\spell_types\ethereal_jaunt.dm"
|
||||
#include "code\modules\spells\spell_types\explosion.dm"
|
||||
|
||||
Reference in New Issue
Block a user