• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

[Spell] Shadow Fury ability of the dark templar in Starcraft II: Legacy of the Void

Status
Not open for further replies.
Level 24
Joined
Jun 26, 2020
Messages
1,852
Hello I wanna create the Shadow Fury ability of the dark templar in Starcraft II: Legacy of the Void, if you don't what it is, here is an example:
My main problem is I'm not sure about how to determine where the caster should be positioned during the casting, because I never played it, but saw gameplays, can you help me please?
 
Maybe this can help you
 
Level 24
Joined
Jun 26, 2020
Messages
1,852
The thing is that ability has multiple targets and area damage (I'm not sure if the latter is true, but I wanna my spell has it), and I wanna know how can I know how to position my caster with every slash, I mean it has to move where there is the most concentration of units, and in the next slash should move to another place, but I'm not sure where exactly.
 
here
 
Level 24
Joined
Jun 26, 2020
Messages
1,852
here
Yeah, I think Omnislash is closer of what I want, because I also wanna each slash causes area damage and not just to the target, and also make the most of that area damage, I mean if 2 units are too close then the caster positionate in the middle of them and do the area damage, and also 2 times in 2 different places because is 1 slash for each target.
But I think I know what I have to do, thanks.
 
Level 24
Joined
Jun 26, 2020
Messages
1,852
@Uncle, thanks, but my problem was more where I should positioned the caster to have the most value possible of the damage area in each slash, at the end this is what I did:
Wurst:
function unit.slashDamage(real damage)
    this.setAnimation("attack")
    flashEffect(Imports.cullingSlashRed, this.getPos())
    forUnitsInRange(this.getPos(), AREA_DMG, u -> begin
        if u.isEnemyOf(this.getOwner()) and not u.isType(UNIT_TYPE_STRUCTURE)
            this.damageTarget(u, damage, ATTACK_TYPE_HERO, DAMAGE_TYPE_ENHANCED)
    end)

function unit.resetSlash(vec2 pos)
    this.setXY(pos)
    this.pause(false)
    this.setInvulnerable(false)

registerPlayerUnitEvent(EVENT_PLAYER_UNIT_SPELL_EFFECT, () -> begin
    let data = abilityCond(SLASH_FURY_NL, SLASH_FURY_L, SLASH_FURY_S)
    if data.check
        let caster = EventData.getSpellAbilityUnit()
        let target = EventData.getAbilityTargetPos()
        let owner = caster.getOwner()

        real damage
        if data.isNL
            damage = DMG_NL
        else
            damage = DMG_L[data.lvl]
      
        let vase = CreateGroup()
        forUnitsInRange(target, AREA, u -> begin
            if u.isEnemyOf(owner) and not u.isType(UNIT_TYPE_STRUCTURE) and u.ignoreLocust()
                vase.add(u)
        end)

        // Only 3 max targets, but prioritizes heros
        let final = CreateGroup()

        var i = 0
        for u in vase
            if i < MAX_TARGETS
                if u.isType(UNIT_TYPE_HERO)
                    final.add(u)
                    vase.remove(u)
                    i++
            else
                break
      
        if i < MAX_TARGETS
            for u in vase
                if i < MAX_TARGETS
                    final.add(u)
                    i++
                else
                    break
      
        vase.clear()

        let pos = caster.getPos()
        caster.pause(true)
        caster.setInvulnerable(true)

        switch i
            case 1
                caster.setXY(final.next().getPos().polarOffset(GetRandomDirectionDeg().asAngleDegrees(), DIST))
                caster.slashDamage(damage)
                doAfter(INTERVAL) ->
                    caster.resetSlash(pos)
            case 2
                let target0 = final.next()
                let target1 = final.next()
                let angl = target0.getPos().angleTo(target1.getPos())

                caster.setFacing(angl)
                caster.setXY(target0.getPos().polarOffset(angl + 35..asAngleDegrees(), DIST))
                caster.slashDamage(damage)

                doAfter(INTERVAL) ->
                    let angl2 = target1.getPos().angleTo(target0.getPos())
                    caster.setFacing(angl2)
                    caster.setXY(target1.getPos().polarOffset(angl2 + 35..asAngleDegrees(), DIST))
                    caster.slashDamage(damage)
                    doAfter(INTERVAL) ->
                        caster.resetSlash(pos)
            default
                vase.add(final)

                RecursiveClosure rc = rc2 -> begin
                    if vase.hasNext()
                        let u = vase.next()
                        let vase2 = final.iterator()..remove(u)
                        var nearest = vase2.next()
                        var near = nearest.getPos().distanceToSq(u.getPos())
                        for u2 from vase2
                            let dist = u2.getPos().distanceToSq(u.getPos())
                            if dist < near
                                near = dist
                                nearest = u2
                        vase2.destr()

                        caster.setFacing(caster.getPos().angleTo(nearest.getPos()))
                        caster.setXY(u.getPos().moveTowards(nearest.getPos(), DIST))
                        caster.slashDamage(damage)

                        doAfter(INTERVAL, () -> rc2.call(rc2))
                    else
                        caster.resetSlash(pos)
                        vase.close()
                        destroy rc2
                end
                rc.call(rc)
end)
 
Last edited:
Status
Not open for further replies.
Top