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

[vJass] Fiery Run v1.1b

  • Like
Reactions: Dark_Dragon
Created as an request by Zaraf
So... more or less credits for the idea go to him x)

Sets the Hero aflame that he will lite the ground when moving. Units standing on burning ground take damage and got reduced armour.
Rank 1 - 5 dps, -3 armour, lasts 8 sec, flames will stay for 4 sec
Rank 2 - 10 dps, -5 armour, lasts12 sec, flames will stay for 5 sec
Rank 3 - 15 dps, -8 armour, lasts 16 sec, flames will stay for 6 sec



Version 1.1
small script changes

Version 1.1b
- Made it 1.24 compatible


JASS:
//////////////////////////////////////Globals with important values////////////////////////////////////////
scope FireRun initializer Init 

globals
    private constant integer DummyID                   = 'h000'  // The Rawcode of teh dummy
    
    private constant integer Spell                     = 'A000'  // Your FieryRun Spell, must add a Buff (look line below)

    private constant integer Buff                      = 'B000'  // The Buff the unit has while its "burning" and the spell is active

    private constant integer PassiveEffect1            = 'A001'  // Effect the Flames got, in this case its an armour decreasing aura

    private constant integer PassiveEffect2            = 'A002'  // Another Effect the Flames got , in this case its Phoenixfire to deal damage

    private constant real    CreationRange             = 80.00   // Distance between Fire dummys / Minrange the unit has to move till another dummy is created

    private constant real    TimerPeriod               = 0.1     // The interval in which checks are made
    
    private constant real    MaxDistance               = 800     // The Maximum range which can be moved in each interval which will cause flames to be created (mention the Creationrange and Max movementspeed of 522
    
    private constant real    DelayedRemoval            = 1.5     // Delay between the death and the removal of the dummy unit (to show death animation)
    
    private timer   t                         = CreateTimer() // Do not modify
endglobals


private constant function Lasts takes integer level returns real
    return level + 3.0  
    // How Long each Flame will last
endfunction

private constant function SpellDuration takes integer level returns real
    return 4.0 + 4.0 * level 
    // Spell Duration, shoul be the same duration of the buff
endfunction

private function RunCondition takes nothing returns boolean
    return GetSpellAbilityId() == Spell
    //The condition if the spell is casted
endfunction


////////////////////////////////Main script// Do not edit unless you understand it////////////////////////////////


private function CreateFlame takes integer level, unit u, real x, real y, real angle returns nothing
    // Simply creating flames
    // Yes i know it uses TSA ...but due the duration is not really low and has not an insanely importance i decided to use waits after i got several bugs before which drove me crazy 
    local unit flame = CreateUnit(GetOwningPlayer(u),DummyID,x,y,bj_RADTODEG * angle)
    call UnitAddAbility(flame,PassiveEffect1)
    call SetUnitAbilityLevel(flame,PassiveEffect1,level)
    call UnitAddAbility(flame,PassiveEffect2)
    call SetUnitAbilityLevel(flame,PassiveEffect2,level)
    call TriggerSleepAction(Lasts(level))
    call KillUnit(flame)
    call TriggerSleepAction(DelayedRemoval)
    call RemoveUnit(flame)
    set flame = null
    return                 
endfunction

private function callback takes nothing returns nothing
    local integer i = 0
    // looping through all structs
    loop
        exitwhen i >= F.Index
        call F.Data[i].move()
        set i = i+1
    endloop
    if F.Data[F.Index-1].Index != 0 then
        call TimerStart(t, TimerPeriod, true, function callback)
    endif
endfunction
    
struct F
    static integer Index = 0
    static F array Data
    unit u                      // Caster
    integer in = 0              // Index of the struct
    integer dur = 0             // Duration left
    real lx = 0                 // Last x coordinated where a flame was created
    real ly = 0                 // Last y coordinated where a flame was created
    integer level               // Level of the spell
    
    static method create takes unit u, integer level returns F
        // Spell is cast and this sets most revelant values
        // Does not create the flames
        local F d = F.allocate()
        set F.Data[F.Index] = d
        set d.dur = R2I(SpellDuration(level) / TimerPeriod)
        set d.in = F.Index
        set d.u = u
        set d.level = level
        set d.Index = F.Index + 1
        set d.lx = GetUnitX(u)
        set d.ly = GetUnitY(u)
        if d.Data[d.Index-1].Index == 1 then
            call TimerStart(t, TimerPeriod, true, function callback)
        endif
        return d
    endmethod
    
    method move takes nothing returns nothing
        local integer ii = 0
        local real x = GetUnitX(this.u)
        local real y = GetUnitY(this.u)
        local real d
        local real a 
        
        //Checking if the duration is over and destroying the struct then
        set this.dur = this.dur - 1
        if this.dur <= 0 or GetWidgetLife(this.u) <= 0.405 or GetUnitAbilityLevel(this.u,Buff) == 0 then
            set this.u = null
            set ii = this.in
            call F.destroy(this)
            set F.Index = F.Index - 1
            set F.Data[ii] = F.Data[F.Index]
            set F.Data[ii].in = ii
            return
        endif
        
        //Checking for distanced and creating the flames
        set a = Atan2(y - this.ly, x - this.lx)
        set d = SquareRoot((x-this.lx)*(x-this.lx) + (y-this.ly)*(y-this.ly))
        if  d > CreationRange then
            if  d < MaxDistance then
                set ii = 0
                loop
                    exitwhen ii == 1
                    set this.lx = this.lx + CreationRange * Cos(a)
                    set this.ly = this.ly + CreationRange * Sin(a)
                    call CreateFlame.execute(this.level,this.u,this.lx,this.ly,a)
                    set d = d - CreationRange
                    if d < CreationRange then
                        set ii = 1
                    endif
                endloop
            else                
                set this.lx = x
                set this.ly = y
            endif
        endif
    endmethod    

endstruct

private function Actions takes nothing returns nothing
    // Starting the Spell
    // If you want a modification that its targeted and the Targeted unit starts burning just change the GetTriggerUnit() to the unit you want
    call F.create(GetTriggerUnit(),GetUnitAbilityLevel(GetTriggerUnit(),Spell))
endfunction

//===========================================================================0

private function Init takes nothing returns nothing
    local trigger tr = CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ(tr,EVENT_PLAYER_UNIT_SPELL_CAST)
    call TriggerAddCondition( tr, Condition( function RunCondition ) )
    call TriggerAddAction( tr, function Actions )
endfunction

endscope

Keywords:
Fire , Run , Fiery, vJass, Burn, Lite , Ground, Flame ,
Contents

Noch eine WARCRAFT-III-Karte (Map)

Reviews
21:18, 16th Jun 2009 hvo-busterkomo: It looks good visually, and has quite good scripting. However, there are several improvements that can be made: 1. A lot of the globals should be constant. 2. Your Lasts and SpellDuration functions should return...

Moderator

M

Moderator

21:18, 16th Jun 2009
hvo-busterkomo:
It looks good visually, and has quite good scripting. However, there are several improvements that can be made:
1. A lot of the globals should be constant.
2. Your Lasts and SpellDuration functions should return real, not integer. Add a decimal to the coefficients. By doing this, you can avoid an I2R call.
3. In your Init function, you declare a local variable that you never use.
4. When a struct is destroyed, you loop through all active instances. It's a lame way of doing it. Instead, lower the total by 1, and move the current index to the total. That might sound confusing, so I recommended reading Dynasti's tutorial on struct indexing. It's not my personal style of coding, but there aren't any better tutorials on the topic.
5. Using both 'data' and 'Data' can get quite confusing.
 
Level 17
Joined
Mar 17, 2009
Messages
1,349
Idea is simple, but as you say, it's a request... ummm, done nicely and functions properly...

I don't know if it might be laggy for some computers since there are alot of effects...

Triggering seems well done and is user friendly.

All in all, as usually, good job -JonNny (it's really annoying to type three N's after each other with the middle one capitalized... ouff! xD)


@ WraithSeeker:
Wait (ie TSA) doesn't seem like a problem to me. Waits with big values (ie larger then 0.27) function normally when used with local variables. Some people prefer to avoid it (I do some times) but it doesn't mean it's wrong to use it...
 
Level 6
Joined
Nov 10, 2006
Messages
181
Waits bigger then 1 second is wrong. Using Timers are correct and TimerUtils exist for a reason.

And he uses it alot of times.

The rest of the code seems decent.
 
Level 15
Joined
Jan 31, 2007
Messages
502
It looks good visually, and has quite good scripting. However, there are several improvements that can be made:
1. A lot of the globals should be constant.
2. Your Lasts and SpellDuration functions should return real, not integer. Add a decimal to the coefficients. By doing this, you can avoid an I2R call.
3. In your Init function, you declare a local variable that you never use.
4. When a struct is destroyed, you loop through all active instances. It's a lame way of doing it. Instead, lower the total by 1, and move the current index to the total. That might sound confusing, so I recommended reading Dynasti's tutorial on struct indexing. It's not my personal style of coding, but there aren't any better tutorials on the topic.
5. Using both 'data' and 'Data' can get quite confusing.

Thanks for that fast review
1. done
2. done
3. i must have forget that, removed
4. changed
5. renamed it

Approving a spell that uses a 1.5 triggersleepaction?

Whats so wrong about it?
TSA are mainly bad if they are used with a short duration
And even if it would bug or whatsoever - its just the delay of the removal of the dummy. would never be noticeable

Waits bigger then 1 second is wrong. Using Timers are correct and TimerUtils exist for a reason.

And he uses it alot of times.

Why are bigger evul?
And where do i use them "alot of times" ? i see 2 TSA in the whole script which will do not create any problems

and btw, i hate using others systems like TU (especially if they are not really needed)
 
Level 15
Joined
Jul 19, 2007
Messages
618
Waits bigger then 1 second is wrong. Using Timers are correct and TimerUtils exist for a reason.

And he uses it alot of times.

The rest of the code seems decent.

waits are bad? using bigger value is more safe and precious so i cant understand what are u talking about... its far more better to use a wait then timer which is needed to be allocated, then execute another function... so just extra functions and allocate, clear stuff + TU... i am same as -JohnNny and i hate TU coz of limits and currently return bug will not work in next version... even if thats not a problem there is no need for extra systems in a spell (that is to make it slower...) TSA is not bad at all its just a little bit unprecious but for wait of 1.5 its np...


about the spell well it was requested but ill say its good enough!

Greets!
~Dark Dragon
 
Level 6
Joined
Nov 10, 2006
Messages
181
I find waits bigger then 1 second a threat. Using TimerUtils is very simple and efficient ,what's wrong with using it?

TU blue might work fine but you might go wtf over the handle limit but in fact the limit is hard to reach. TU recycles timers which is good. TSA are bad for values that high.

If you want to remove the unit after a certain time, use UnitApplyTimedLife, it does the job pretty well and you can get rid of them and it'll be a good spell.

TU is not needed yes.

JASS:
if F.Data[F.Index-1].Index != 0 then
        call TimerStart(t, TimerPeriod, true, function callback)
    endif

I don't get what you are trying to do by calling itself?

Put the method move inside the function callback, doing that way doesn't make it neat or anything but makes it slower.
 
Level 15
Joined
Jan 31, 2007
Messages
502
JASS:
if F.Data[F.Index-1].Index != 0 then
        call TimerStart(t, TimerPeriod, true, function callback)
    endif

I don't get what you are trying to do by calling itself?
dunno, i was too lazy to make it periodic and stop it instead


._. eh... damn ,should have seen that before
but the main aspect of this request was that the flames recude the targets armour if it stands insinde the flames
 
Level 6
Joined
Nov 10, 2006
Messages
181
Replace TriggerSleepAction with UnitApplyTimedLife for that dummy and try to modify this to make this unique from that and I don't think the mods will mind.
 
Level 6
Joined
Nov 10, 2006
Messages
181
Object Editor Can't Raise Does not decay solves the problem.

Just to tell you, some systems like AutoIndex break if you do RemoveUnit and you need RemoveUnitEx so RemoveUnit is a
evil function.
 
Level 14
Joined
Nov 18, 2007
Messages
816
Well, it used to work with RemoveUnit, but Vex said hes going to add native hooking sometime in the future, so grim reverted the madness hes coded into AutoIndex, and prepared his library to switch over to native hooking.

TSA doesnt pause when a player lags (which is the main flaw with pausing for a longer time).
 
Level 15
Joined
Jan 31, 2007
Messages
502
I know that its possible to create it with this Pocket Factorys ability which creates periodicly units.
That is nothing new, but it was a request of an ability which takes care of the distance a unit moves. e.g. when it does not move that there are no units created or if it moves fast that there are no spaces between
 
Top