• 🏆 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!

Ancient Burning Swords

This bundle is marked as useful / simple. Simplicity is bliss, low effort and/or may contain minor bugs.
Credit to shamanyouranus for sword model

Reason why i posted the spell: coz somebody liked the old version http://www.hiveworkshop.com/forums/2074454-post5.html

How to implentate:

1. Open the map
2. Copy the ability (or make your ability what is unit targeted ability) to your map
3. Export sword model then import the model to your map
4. Copy The Sword dummy unit to your map, and check if at model path its show the imported sword path
5. Copy the trigger
6. Change the ability ID (it is 'A000' in trigger) in trigger (if u dont know the raw code then check the ,,display raw value'' in object editor)
7. Change the unit type id in trigger (in trigger is 'h000'), you can check if unit what u copied got same raw code, if no then replace h000 to your unit type id

Thats all

Ability description:
Summon 5 sword, same time lift up the target and paralyze him (pause), then caster lifted up the air and start 5 rush to target direction and at last rush he deal 2x damage

Notice: TSA with lower amount just used just for make a short trigger pause, if somebody want then can use timer but i dont know if needed, since dont must be acurated anyway

JASS:
function Trig_Untitled_Trigger_003_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == 'A000'
endfunction

function Trig_Untitled_Trigger_003_Actions takes nothing returns nothing
    local unit uc = GetTriggerUnit()
    local unit ut = GetSpellTargetUnit()
    local unit array u
    local integer a = 1
    local integer b = 1
    local integer h1 = 330
    local integer h2 = 320
    local integer d = 10
    local integer rnd
    local integer e = 0
    local real xt = GetUnitX(ut)
    local real yt = GetUnitY(ut)
    local real g = (3.14159 / 180)
    local real array x
    local real array y
    local real spd = GetUnitMoveSpeed(ut)
    local real spd1 = GetUnitMoveSpeed(uc)
    local real sp = 100
    local real hp = GetWidgetLife(ut)
    local real hp1 = GetWidgetLife(uc)
    local real dmg = GetHeroLevel(uc) * GetUnitAbilityLevel(uc,'A000' )
    local real t1
    local real dist
    local real dist1
    local lightning array l
    local lightning l1 = null
    local lightning l2 = null
    local lightning l3 = null
    local lightning l4 = null
    local lightning l5 = null
    local lightning l6 = null
    local lightning l7 = null
    local lightning l8 = null
    local lightning l9 = null
    local lightning l10 = null
    local player p = GetTriggerPlayer()
    local string array s
    
    local effect f1
    local effect f2
    local effect array f
    set s[0] = "Abilities\\Spells\\Items\\StaffOfSanctuary\\Staff_Sanctuary_Target.mdl"
    set s[1] = "Abilities\\Spells\\NightElf\\Blink\\BlinkCaster.mdl"
    set s[2] = "Objects\\Spawnmodels\\Human\\HumanBlood\\HumanBloodPeasant.mdl"
    set s[3] = "Abilities\\Spells\\NightElf\\Blink\\BlinkTarget.mdl"
    set s[4] = "Abilities\\Spells\\Other\\Doom\\DoomDeath.mdl"
    set s[5] = "Abilities\\Spells\\Human\\FlameStrike\\FlameStrikeEmbers.mdl"
    set f1 = AddSpecialEffectTarget(s[0], ut, "chest")
    loop
        exitwhen a > 5
        set t1 = g * (a - 1) * 72
        set x[a] = xt + 300 * Cos(t1)
        set y[a] = yt + 300 * Sin(t1)
        set x[a + 5] = xt + 400 * Cos(t1)
        set y[a + 5] = yt + 400 * Sin(t1)
        set x[a + 10] = xt - 400 * Cos(t1)
        set y[a + 10] = yt - 400 * Sin(t1)
        set u[a] = CreateUnit (p, 'h000', x[a] , y[a], 0)
        call UnitAddAbility(u[a], 'Amrf' )
        call UnitRemoveAbility(u[a], 'Amrf' )
        call SetUnitFlyHeight( u[a], h1, sp * 4 )
        set a = a + 1
    endloop
    call PauseUnit( uc, true )
    call SetUnitPathing (uc, true)
    call SetUnitMoveSpeed (uc, 400)
    call PauseUnit( ut, true )
    call UnitAddAbility(uc, 'Abun' )
    call UnitAddAbility(ut, 'Amrf' )
    call UnitRemoveAbility(ut, 'Amrf' )
    call SetUnitFlyHeight( ut, h2, sp )
    call SetUnitInvulnerable( ut, true )
    call TriggerSleepAction(3.2)
    call UnitAddAbility(uc, 'Aloc' )
    call SetUnitVertexColor(uc, 255, 255, 255, 200)
    call DestroyEffect(f1)
    set f[1] = AddSpecialEffectTarget(s[5], uc, "foot left")
    set f[2] = AddSpecialEffectTarget(s[5], uc, "foot right")
    set f[3] = AddSpecialEffectTarget(s[5], uc, "hand left")
    set f[4] = AddSpecialEffectTarget(s[5], uc, "hand right")
    set f[5] = AddSpecialEffectTarget(s[5], uc, "chest")
    set a = 1
    loop
        exitwhen a > 5
        set l[a] = AddLightningEx("DRAL", true, x[a], y[a], 320, xt, yt, 320)
        call SetLightningColor(l[a], 1, 0, 0, 1)
        set a = a + 1
    endloop

    set a = 0
    set l[6] = AddLightningEx("LEAS", true, x[1], y[1], 320, x[5], y[5], 320)
    call SetLightningColor(l[6], 0, 0, 1, 1)
    call TriggerSleepAction(0.01)
    set l[7] = AddLightningEx("LEAS", true, x[2], y[2], 320, x[1], y[1], 320)
    call SetLightningColor(l[7], 0, 0, 1, 1)
    call TriggerSleepAction(0.01)
    set l[8] = AddLightningEx("LEAS", true, x[3], y[3], 320, x[2], y[2], 320)
    call SetLightningColor(l[8], 0, 0, 1, 1)
    call TriggerSleepAction(0.01)
    set l[9] = AddLightningEx("LEAS", true, x[4], y[4], 320, x[3], y[3], 320)
    call SetLightningColor(l[9], 0, 0, 1, 1)
    call TriggerSleepAction(0.01)
    set l[10] = AddLightningEx("LEAS", true, x[5], y[5], 320, x[4], y[4], 320)
    call SetLightningColor(l[10], 0, 0, 1, 1)
    call PauseUnit( uc, false )
    call SetUnitInvulnerable( ut, false )

    call SetUnitLookAt( ut, "bone_chest", uc, 0, 0, 50 )
    loop
        set hp = GetWidgetLife(ut)
        set hp1 = GetWidgetLife(uc)
        exitwhen b > 5 or hp < 0.4 or hp1 < 0.4
        call DestroyEffect(AddSpecialEffectTarget(s[1], uc, "origin"))
        call SetUnitPosition(uc, x[b + 5], y[b + 5])
        call DestroyEffect(AddSpecialEffectTarget(s[3], uc, "origin"))
        call UnitAddAbility(uc, 'Amrf' )
        call UnitRemoveAbility(uc, 'Amrf' )
        call SetUnitFlyHeight( uc, h1, 10000 )
        call DestroyEffect(AddSpecialEffectTarget(s[1], uc, "origin"))
        call IssuePointOrder (uc, "move", x[b + 10], y[b + 10])
        loop
            set dist = SquareRoot((x[b + 10] - GetUnitX(uc)) * (x[b + 10] - GetUnitX(uc)) + (y[b + 10] - GetUnitY(uc)) * (y[b + 10] - GetUnitY(uc)))
            exitwhen dist < 120
            set dist1 = SquareRoot((GetUnitX(ut) - GetUnitX(uc)) * (GetUnitX(ut) - GetUnitX(uc)) + (GetUnitY(ut) - GetUnitY(uc)) * (GetUnitY(ut) - GetUnitY(uc)))
            if dist1 < 75 and b != e then
                call UnitDamageTarget(uc, ut, dmg, true, false, ATTACK_TYPE_HERO, DAMAGE_TYPE_NORMAL, WEAPON_TYPE_WHOKNOWS)
                call DestroyEffect(AddSpecialEffectTarget(s[2], ut, "origin"))
                call DestroyEffect(AddSpecialEffectTarget(s[4], ut, "origin"))
                if b == 5 then
                    call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Human\\MarkOfChaos\\MarkOfChaosTarget.mdl", ut, "origin"))
                    call DestroyEffect(AddSpecialEffectTarget("Units\\NightElf\\Wisp\\WispExplode.mdl", ut, "origin"))
                    call UnitDamageTarget(uc, ut, dmg * 2, true, false, ATTACK_TYPE_HERO, DAMAGE_TYPE_NORMAL, WEAPON_TYPE_WHOKNOWS)
                endif
                set e = b
            endif
            call TriggerSleepAction(0.1)
        endloop
        set b = b + 1
    endloop
    call SetUnitMoveSpeed (uc, 0)
    call IssueTargetOrder( uc, "smart", ut )
    call TriggerSleepAction(0.3)
    call SetUnitAnimation( uc, "stand victory" )
    call SetUnitInvulnerable( ut, true )
    call TriggerSleepAction(1)
    call DestroyEffect(AddSpecialEffectTarget(s[1], uc, "origin"))
    call TriggerSleepAction(0.3)
    call ResetUnitLookAt( ut )
    call SetUnitFlyHeight( uc, 0, 2000 )
    call SetUnitPathing (uc, false)

    set f1 = AddSpecialEffectTarget(s[0], ut, "chest")
    set a = 1
    loop
        exitwhen a > 10
        call DestroyLightning(l[a])
        set l[a] = null
        set a = a + 1
    endloop
    set a = 1
    loop
        exitwhen a > 5
        call UnitApplyTimedLife( u[a], 'BUan', 5 )
        call SetUnitFlyHeight( u[a], 2500, sp * 4 )
        set u[a] = null
        set a = a + 1
    endloop


    if (GetLocalPlayer() == p) then
        call ClearSelection()
        call SelectUnit(uc, true)
    endif
    call UnitAddAbility(ut, 'Amrf' )
    call UnitRemoveAbility(ut, 'Amrf' )
    call SetUnitMoveSpeed (uc, spd1)
    call SetUnitVertexColor(uc, 255, 255, 255, 255)
    call UnitRemoveAbility (uc, 'Aloc' )
    call ShowUnit(uc, false)
    call ShowUnit(uc, true)

    set hp = GetWidgetLife(ut)
    if hp < 0.4 then
        call DestroyEffect(f1)
        call SetUnitFlyHeight( ut, 0, sp * 4 )
    else
        call SetUnitFlyHeight( ut, 0, sp )
    endif

    set hp = GetWidgetLife(uc)
    set a = 1
    if hp < 0.4 then
        loop
            exitwhen a > 5
            call DestroyEffect(f[a])
            set a = a + 1
        endloop
    endif

    call TriggerSleepAction(3)
    call SetUnitInvulnerable( ut, false )
    call UnitRemoveAbility(uc, 'Abun' )
    call PauseUnit( ut, false )

    if f1 != null then
        call DestroyEffect(f1)
    endif
    set a = 1
    if f[1] != null then
        loop
            exitwhen a > 5
            call DestroyEffect(f[a])
            set s[a] = null
            set a = a + 1
        endloop
    endif
    call DestroyEffect(f2)

    set ut = null
    set p = null
    set f1 = null
    set f2 = null
    set s[0] = null

endfunction

//===========================================================================
function InitTrig_Magical_sword takes nothing returns nothing
    set gg_trg_Magical_sword = CreateTrigger( )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Magical_sword, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( gg_trg_Magical_sword, Condition( function Trig_Untitled_Trigger_003_Conditions ) )
    call TriggerAddAction( gg_trg_Magical_sword, function Trig_Untitled_Trigger_003_Actions )
endfunction

Keywords:
magic sword flying ultimate flame paladin special effect
Contents

Just another Warcraft III map (Map)

Reviews
12th Dec 2015 IcemanBo: Too long as NeedsFix. Rejected. Required changes: Add importing instructions into the map file Add learn hotkey List hotkey in tooltips Improve tooltips When you declare local lightning variables, you don't have to...

Moderator

M

Moderator

12th Dec 2015
IcemanBo: Too long as NeedsFix. Rejected.

Reviewed by Maker, Ancient Burning Swords, 11th Jan 2012

Required changes:
  • Add importing instructions into the map file
  • Add learn hotkey
  • List hotkey in tooltips
  • Improve tooltips
  • When you declare local lightning variables, you don't have to set them to null
  • Change the learned icon position
  • The hero should be added to selection when the spell ends
  • TriggerSleepAction is not accurate. In single player, a 0.01 second wait is either 0.011, 0.126, 0.151, 0.176 or 0.201 seconds, chosen randomly
  • Only remove 'Armf' if the unit didn't have it before adding it
  • For what do you need a lightning array and 9 non-array lightning variables?
  • 0.405 health is the limit of dead/alive unit

Suggested changes:
  • When you create the swords, you could set Cos(t1) and Sin(t1) into variables since now you're calculating them thrice
  • I'd like you not to set the paths for effects every time the spell is cast
  • In my opinion, you could speed up the spell a bit
  • You could increase Art - Follow through time so the caster's cast anim doesn't stop so quickly
 
- You should use functions to make things (like the special effects configurable:
Example:
JASS:
function Spell_GetEffect takes nothing returns string
    return "Abilities\\Spells\\Items\\StaffOfSanctuary\\Staff_Sanctuary_Target.mdl"
endfunction

- Don't use TriggerSleepAction, timers are much better to use.
Also, 0.01 second TSA waits 0.27 seconds in reality.
And instead of Actions, you should use Conditions.

You'd just have to get rid of the TSA's and put all your code in the Conditions function then return false at the end (use an if/then/endif block to check if the right spell was casted)

JASS:
    set hp = GetWidgetLife(ut)
    if hp < 0.4 then
        call DestroyEffect(f1)
        call SetUnitFlyHeight( ut, 0, sp * 4 )
    else
        call SetUnitFlyHeight( ut, 0, sp )
    endif

    set hp = GetWidgetLife(uc)
    set a = 1
    if hp < 0.4 then
        loop
            exitwhen a > 5
            call DestroyEffect(f[a])
            set a = a + 1
        endloop
    endif

Why are you using the ho real if you're only using the variable once?
Do this instead:

JASS:
                if GetWidgetLife(ut) <= 0.405 then
                    call DestroyEffect(f1)
                    call SetUnitFlyHeight( ut, 0, sp * 4 )
                else
                    call SetUnitFlyHeight( ut, 0, sp )
                endif

                set a = 1
                if GetWidgetLife(uc) <= 0.405 then
                    loop
                        exitwhen a > 5
                        call DestroyEffect(f[a])
                        set a = a + 1
                    endloop
                endif

Still, this is bad. To check if a unit is dead, do this: "IsUnitType(unit, UNIT_TYPE_DEAD)"

- call SetUnitFlyHeight( uc, h1, 10000 )
Use 0 instead of 10000. 0 makes the unit move instantly.

- In the loop, instead of using the SquareRoot function, you could simply compare the distance with 14400 (120*120)

- WEAPON_TYPE_WHOKNOWS -> null
They're the same thing

- Don't use local arrays, they have very bad performance.

- Again, please make more things configurable and use timers for the spell.
The lightning types should be configurable, the height, the damage the effects, the distance, the durations, everything.

This needs to be improved .. a lot.

Oh and the local variable g is useless. We have bj_RADTODEG and bj_DEGTORAD.
JASS:
constant real bj_RADTODEG = 180./bj_PI
constant real bj_DEGTORAD = bj_PI/180.
 
Level 17
Joined
Nov 13, 2006
Messages
1,814
1 - You should use functions to make things (like the special effects configurable:
Example:
JASS:
function Spell_GetEffect takes nothing returns string
    return "Abilities\\Spells\\Items\\StaffOfSanctuary\\Staff_Sanctuary_Target.mdl"
endfunction

2 - Don't use TriggerSleepAction, timers are much better to use.
Also, 0.01 second TSA waits 0.27 seconds in reality.
And instead of Actions, you should use Conditions.

3-You'd just have to get rid of the TSA's and put all your code in the Conditions function then return false at the end (use an if/then/endif block to check if the right spell was casted)

JASS:
    set hp = GetWidgetLife(ut)
    if hp < 0.4 then
        call DestroyEffect(f1)
        call SetUnitFlyHeight( ut, 0, sp * 4 )
    else
        call SetUnitFlyHeight( ut, 0, sp )
    endif

    set hp = GetWidgetLife(uc)
    set a = 1
    if hp < 0.4 then
        loop
            exitwhen a > 5
            call DestroyEffect(f[a])
            set a = a + 1
        endloop
    endif

4 - Why are you using the ho real if you're only using the variable once?
Do this instead:

JASS:
                if GetWidgetLife(ut) <= 0.405 then
                    call DestroyEffect(f1)
                    call SetUnitFlyHeight( ut, 0, sp * 4 )
                else
                    call SetUnitFlyHeight( ut, 0, sp )
                endif

                set a = 1
                if GetWidgetLife(uc) <= 0.405 then
                    loop
                        exitwhen a > 5
                        call DestroyEffect(f[a])
                        set a = a + 1
                    endloop
                endif

5-Still, this is bad. To check if a unit is dead, do this: "IsUnitType(unit, UNIT_TYPE_DEAD)"

6- call SetUnitFlyHeight( uc, h1, 10000 )
Use 0 instead of 10000. 0 makes the unit move instantly.

7- In the loop, instead of using the SquareRoot function, you could simply compare the distance with 14400 (120*120)

8- WEAPON_TYPE_WHOKNOWS -> null
They're the same thing

9- Don't use local arrays, they have very bad performance.

10- Again, please make more things configurable and use timers for the spell.
The lightning types should be configurable, the height, the damage the effects, the distance, the durations, everything.

This needs to be improved .. a lot.

11-Oh and the local variable g is useless. We have bj_RADTODEG and bj_DEGTORAD.
JASS:
constant real bj_RADTODEG = 180./bj_PI
constant real bj_DEGTORAD = bj_PI/180.


1. but why more configurable than all string local at begining of trigger in same place?
2. there enough 0.5 value too just i put lower
3. then i declared locals without sense since i must put local declaretion before if else give error to me
4. done
5. done
6. done
7. done
8. ok
9. but harshtable also slower than global variables, so i must use global variable arrays? local arrays slower than harshtable?
10. Timer i understand but lightning height no, coz i tryed move upper and down and both way i think it was ugly or too unrealistic really, anyway i replaced with h2 so its configurable with other object heights, about damage effect i like that also got no ideea how could improve, distance and duration i think also useless because idk if somebody have who want half map ability
11. its shorter if few case, i mean just 1 letter :D
 
Level 29
Joined
Mar 10, 2009
Messages
5,016
- You should use functions to make things (like the special effects configurable:
globals are better

JASS:
function SetSfx takes nothing retuns nothing
   set udg_s[0] = "Abilities\\Spells\\Items\\StaffOfSanctuary\\Staff_Sanctuary_Target.mdl"
   set udg_ss[1] = "Abilities\\Spells\\NightElf\\Blink\\BlinkCaster.mdl"
   set udg_ss[2] = "Objects\\Spawnmodels\\Human\\HumanBlood\\HumanBloodPeasant.mdl"
   set udg_ss[3] = "Abilities\\Spells\\NightElf\\Blink\\BlinkTarget.mdl"
   set udg_ss[4] = "Abilities\\Spells\\Other\\Doom\\DoomDeath.mdl"
   set udg_ss[5] = "Abilities\\Spells\\Human\\FlameStrike\\FlameStrikeEmbers.mdl"
endfunction

function InitTrig_Magical_sword takes nothing returns nothing
    set gg_trg_Magical_sword = CreateTrigger( )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Magical_sword, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( gg_trg_Magical_sword, Condition( function Trig_Untitled_Trigger_003_Conditions ) )
    call TriggerAddAction( gg_trg_Magical_sword, function Trig_Untitled_Trigger_003_Actions )
   call SetSfx()
endfunction

and you really need to rename this Trig_Untitled_Trigger_003_Actions and a-like coz it's really bad for eyes ;)...
 
Yes, globals are better but I was assuming this is a strictly jass resource :>

Hashtables are slower than global and local arrays, but that doesn't mean local arrays are any good. Use a hashtable or use dynamic indexing or even a stack.
Go with dynamic indexing. (I'd recommend it)

The configurables are needed in the form of functions or globals because creating the same constant locals everytime is really inefficient. Putting all the configurables at the top of the code is much better because it gives your code structure and organisation.
 
Level 17
Joined
Nov 13, 2006
Messages
1,814
Yes, globals are better but I was assuming this is a strictly jass resource :>

Hashtables are slower than global and local arrays, but that doesn't mean local arrays are any good. Use a hashtable or use dynamic indexing or even a stack.
Go with dynamic indexing. (I'd recommend it)

The configurables are needed in the form of functions or globals because creating the same constant locals everytime is really inefficient. Putting all the configurables at the top of the code is much better because it gives your code structure and organisation.

if i understand well the only problem with local arrays, is u cant pass the data to another function until global variable+indexing system or harshtable can, right?

ok now i understand that thing about strings, and similiar things what i use often but declare every time.

have anyway to kill TSA, since i use 0,1 value but its indifferent what value i give just must be lower than 0.8, because it is use for loop dont make problem when i run damn much time till target arrive to a location (so exitwhen from loop if a real lower than x), since it is used for slowdown the loop cycle not because i need wait, the only way is the timer? i ask this since really its not like a trigger when need to do something in fixed time, like dot, regen, missile etc
 
Level 29
Joined
Mar 10, 2009
Messages
5,016
Yes, globals are better but I was assuming this is a strictly jass resource :>
Mag you should know better that "udg_" is a jass resource ;)...

EDIT:
the problem with locals also is you cant use it in a timer loop (delay purposes) to recall it's
value, so you might as well use hashtable or UnitIndexer, I wont recommend Hanky's indexing
system in Jass coz Unit indexer is way better and easier...
 
Last edited:
Top