Template Jumping Spell Template v3

Discussion in 'Spells' started by emjlr3, Nov 25, 2007.

  1. emjlr3

    emjlr3 Change can be a good thing Staff Member

    Ratings:
    +396 / 0 / -0
    Jumping Spell Template v3

    A re-release of my old jump template, the first of its kind mind you, that I simply ported to structs and updated some of the non-optimized parts of. Its a simple template for simple needs, however, its easy to use and works as intended.
    This allows you to jump a unit from here to there, while being able to edit every little aspect you can think of: speed, animation, effects, area, damage, arc, and even the offset between where the unit lands and where the spell was cast.

    Version Info:
    • 4: Jumping Spell Template v3 - Minor coding updates, syntax change dramatically (check it out in the Read Me), no longer requires CSSafety or CSCache and now runs on only 1 timer, now supports jumping over and onto different terrain heights (check it out in game!), new public function to check terrain pathability added, added error messages for invalid inputs
    • 3: Jumping Spell Template v2 - Now works in radians, a few other minor improvements to the code, a pathability check is now ran to keep jumping units in the map, now damages all ground units correctly
    • 2: Jumping Spell Template v1 - Ported to structs, updated some stupid coding methods, made it an actual template :), new test map!
    • 1: Jump Template - Original release
    JASS:
    
    //***************************************************************************
    //*                                                                         *
    //* Jumping Spell Template v3                                               *
    //* ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯            **URL in the works                 *
    //* Parabola function by Shadow1500                                         *
    //* System by emjlr3                                                        *
    //*                                                                         *
    //* Requires:                                                               *
    //* ¯¯¯¯¯¯¯¯¯                                                               *
    //*                                                                         *
    //* - A vJASS Preprocessor                                                 *
    //*                                                                         *
    //***************************************************************************
    
    library JST initializer InitJST
    
    globals
        // Speed at which unit's periodic movement is completed (.01-.04 recommended)
        private constant real Interval          = .025
        // Value which represents the arc of the jump movement (1.-2.), closer to 2. for a flatter arc
        private constant real Arc               = 1.3 
        // Rawcode of the Crow Form ability in your map.  This need only be changed if you have edited this ability
        // in which case, create a new, unedited copy and use it here
        private constant integer CrowForm       = 'Amrf' 
        // Rawcode of peasant unit in your map.  This need only be changed if you have edited this unit
        // in which case, create a new, unedited copy and ise it here
        private constant integer Peasant        = 'hpea'
    endglobals
    
    //=====No touching past this point=====\\
    
    globals
        private real Game_MaxX 
        private real Game_MinX 
        private real Game_MaxY 
        private real Game_MinY
        
        private constant real Runs = 1./Interval
        private constant integer HalfRuns = R2I(Runs/2.)
        
        private location L
        
        private sound S = CreateSoundFromLabel( "InterfaceError",false,false,false,10,10)
    endglobals
    
    private function Parabola takes real dist, real maxdist returns real
        local real t = (dist*2)/maxdist-1
        return (-t*t+1)*(maxdist/Arc)
    endfunction
    private function InitJST takes nothing returns nothing
        set Game_MaxX = GetRectMaxX(bj_mapInitialPlayableArea)-50.
        set Game_MinX = GetRectMinX(bj_mapInitialPlayableArea)+50.
        set Game_MaxY = GetRectMaxY(bj_mapInitialPlayableArea)-50.
        set Game_MinY = GetRectMinY(bj_mapInitialPlayableArea)+50.
    endfunction
    
    public function CheckLocPathing takes location l returns boolean
        local unit u = CreateUnitAtLoc( Player(13), Peasant, l, 0. )
        local real x = GetUnitX(u) - GetLocationX(l)
        local real y = GetUnitY(u) - GetLocationY(l)
        local boolean b = false
        
        if x < 1. and x > -1. and  y < 1. and y > -1. then        
            set b = true
        endif
        call ShowUnit(u,false)
        call KillUnit(u)
        
        call RemoveLocation(l)
        set u = null
        return b
    endfunction
    
    private function SafeX takes real x returns real
        if x<Game_MinX then
            return Game_MinX
        elseif x>Game_MaxX then
            return Game_MaxX
        endif
        return x
    endfunction
    private function SafeY takes real y returns real
        if y<Game_MinY then
            return Game_MinY
        elseif y>Game_MaxY then
            return Game_MaxY
        endif
        return y
    endfunction
    
    private struct dat
        unit u
        real area
        real damage
        real maxdist
        real movedist
        real cos
        real sin
        real diff
        real start_z
        string sfx  
        integer i = 0
    endstruct
    
    globals
        private timer T = CreateTimer()
        private dat array D
        private integer Total = 0
    endglobals
    
    //Spell:
    private function Filt takes nothing returns boolean
        return IsUnitEnemy(GetFilterUnit(),bj_groupEnumOwningPlayer) and IsUnitType(GetFilterUnit(),UNIT_TYPE_FLYING)!=true
    endfunction    
    private function Damage takes unit u, real dam, real x, real y, real area returns nothing
        local group g = CreateGroup()
        local unit v
    
        set bj_groupEnumOwningPlayer = GetOwningPlayer(u)
        call GroupEnumUnitsInRange(g, x, y, area, Condition(function Filt))
        loop
            set v = FirstOfGroup(g)
            exitwhen v == null
            call GroupRemoveUnit(g,v)
            call UnitDamageTarget(u,v,dam,false,false,ATTACK_TYPE_NORMAL,DAMAGE_TYPE_NORMAL,null)
        endloop 
       
        call DestroyGroup(g)
        set g = null
    endfunction
    
    private function Movement takes nothing returns nothing
        local dat d
        local integer i = 1
        local real dist  
        local real height
        local real x
        local real y
        
        loop
            exitwhen i>Total
            set d = D[i]
        
            set d.i = d.i + 1
            set dist = d.i*d.movedist
            
            set L = GetUnitLoc(d.u)
            set height = GetLocationZ(L)
            if height<d.start_z then
                set height = (d.start_z-height)+Parabola(dist,d.maxdist)
            elseif height>d.start_z then
                if d.start_z+Parabola(dist,d.maxdist)<=height then
                    set height = 0.
                else
                    set height = Parabola(dist,d.maxdist)-(height-d.start_z)
                endif
            else
                set height = Parabola(dist,d.maxdist)
            endif
            call RemoveLocation(L)
            
            call SetUnitX(d.u,SafeX(GetUnitX(d.u)+d.movedist*d.cos))
            call SetUnitY(d.u,SafeY(GetUnitY(d.u)+d.movedist*d.sin))
            call SetUnitFlyHeight(d.u,height,0.)
            call DisplayTextToPlayer(Player(0),0.,0.,"ZLoc = "+R2S(GetLocationZ(GetUnitLoc(d.u)))+" : FlyHeight = "+R2S(GetUnitFlyHeight(d.u)))
            
            if d.i == HalfRuns then
                call SetUnitTimeScale(d.u, 1.)
            elseif height<=1. then
                call PauseUnit( d.u,false )
                call SetUnitPathing( d.u, true )           
                call SetUnitFlyHeight(d.u,GetUnitDefaultFlyHeight(d.u),0.) 
                set x = GetUnitX(d.u) + d.diff * d.cos
                set y = GetUnitY(d.u) + d.diff * d.sin 
                call DestroyEffect(AddSpecialEffect(d.sfx, x,y))  
                call Damage(d.u, d.area, x, y, d.damage)  
                
                call d.destroy() 
                set D[i] = D[Total]
                set Total = Total - 1
                set i = i - 1
                if Total==0 then
                    call PauseTimer(T)
                endif
            endif
            
            set i = i + 1
        endloop
    endfunction     
    
    //===========================================================================
    public function Cast takes unit u, real damage, real area, real diff, string anim, string sfx returns boolean
        local dat d      
        local real ux
        local real uy   
        local location l 
        local real ang
        local real x
        local real y 
        
        if u==null or damage<0. or area<0. then
            if GetLocalPlayer()==GetOwningPlayer(u) then
                call ClearTextMessages()
                call BJDebugMsg("|c00FF0000JST Error: Invalid inputs in function Cast.")
                call StartSound(S)
            endif
            return false
        endif
        
        set d = dat.create()       
        set ux = GetUnitX(u)
        set uy = GetUnitY(u)   
        set l = GetSpellTargetLoc() 
        set ang = Atan2((GetLocationY(l)-uy),(GetLocationX(l)-ux))
        set x = GetLocationX(l) - diff * Cos(ang)
        set y = GetLocationY(l) - diff * Sin(ang)
        
        set d.u = u
        set d.damage = damage
        set d.area = area
        set d.sfx = sfx
        set d.maxdist = SquareRoot((ux-x)*(ux-x) + (uy-y)*(uy-y))
        set d.cos = Cos(ang)
        set d.sin = Sin(ang)
        set d.movedist = d.maxdist/Runs
        set d.diff = diff
        set L = GetUnitLoc(d.u)
        set d.start_z = GetLocationZ(L)
        call RemoveLocation(L)
       
        call PauseUnit( u,true )
        call SetUnitPathing( u, false )
        call UnitAddAbility( u,CrowForm )
        call UnitRemoveAbility( u,CrowForm )
        call SetUnitAnimation(u, anim) 
        call SetUnitTimeScale(u, .30) 
        
        set Total = Total + 1
        if Total == 1 then
            call TimerStart(T,Interval,true,function Movement) 
        endif
        set D[Total] = d
        
        call RemoveLocation(l)
        set l = null 
        return true
    endfunction
    
    endlibrary


    Please test, comment, and enjoy!
     

    Attached Files:

    • Like Like x 2
  2. duyen

    duyen New Member

    Ratings:
    +214 / 0 / -0
    Describe what it does?
     
  3. Cohadar

    Cohadar master of fugue

    Ratings:
    +209 / 0 / -0
    ROOOOOOOOOOOOOFFFFFLLLLLLLLLLLLLL

    Well if I had to guess, this jumping template is probably turning all land units into fish :D

    WARNING: hardcoded ability Id.
    JASS:
        call UnitAddAbility( u,'Amrf' )
        call UnitRemoveAbility( u,'Amrf' )
     
  4. Trollvottel

    Trollvottel never aging title

    Ratings:
    +261 / 0 / -0
    yeah i think he means you cant use it in another map if you dont change this?
     
  5. Frozenwind

    Frozenwind System maker

    Ratings:
    +99 / 0 / -0
    He said that sacrastic as in: "dont ask stupid questions".

    You think, I'm sure.
    That is a rawdata of a certain ability:p.

    Nice spell, the picture looks good.

    frozenwind.
     
  6. emjlr3

    emjlr3 Change can be a good thing Staff Member

    Ratings:
    +396 / 0 / -0
    its the crow form ability, ppl rarely change it, if you do, then you may have issues, then again you may not
     
  7. Tinki3

    Tinki3 Special Member

    Ratings:
    +418 / 0 / -0
    I like this, GJ.

    Though, the use of the bj_RADTODEG and bj_DEGTORAD functions is pointless.
    Just work in radians unless you need to set a unit's facing deg or get a unit's facing deg.

    There might be a few more things where you are required to use degrees as to
    radians, but with (mostly?) everything else, radians are perfect.

    I didn't damage some units, which has something to do with that filter.
    Instead of directly checking if a unit is a ground unit to rid of damaging air units,
    simply use: IsUnitType(GetFilterUnit(), UNIT_TYPE_FLYING) != true

    Simply because some units are neither flying or ground, but some other type.
    One of which I think is "amphibious", which might be the only one.

    I could also jump into the black borders of the map, might want to abolish
    that, up to you though.
     
    • Like Like x 1
  8. emjlr3

    emjlr3 Change can be a good thing Staff Member

    Ratings:
    +396 / 0 / -0
    ty

    agreed, there are a few other things I found that could be better to, will update soon

    which units exactly? will look into it

    yea....that would be a good addition I suppose as well

    thnx for input
     
  9. waaaks!

    waaaks! Zinctified

    Ratings:
    +256 / 0 / -0
    what does
    JASS:
    real diff

    do?

    u know what, i used the old jump template as many of my jumping spells in my map, and its hard to modify, cause i need to add the special effect to the hands

    now this is way cool because i can easily set what i want

    and the most interesting part is, it uses the cs safety and cs cache, which is my main engine
     
  10. Rheias

    Rheias New Helper (I got over 2000 posts)

    Ratings:
    +232 / 0 / -0
    Thanks updating this Emj|r3. I couldn't find any problems with the code, it looks good. I personally rather use ABC or HSAS (once I get it working) as it doesn't require huge codes, but that doesn't really matter.
     
  11. emjlr3

    emjlr3 Change can be a good thing Staff Member

    Ratings:
    +396 / 0 / -0
    cssafety is real small
    and it only needs CSData in CSCache, which is real small to, I think I mention that somewhere
     
  12. Cohadar

    Cohadar master of fugue

    Ratings:
    +209 / 0 / -0
    offtopic:

    ABC + PUI is small.
    CSData has 2000 lines of code so it is not.... small.
    (The reason is it has too many stuff noone ever uses - those pools for example)

    CSSafety is a must have, I love CSSafety.

    Anyways I really don't mind people using CSData or tables,
    they translate easily to ABC+PUI,
    but when I see people using some custom home-made-soon-to-fail attachment systems or old ways gamecache I get :mad:

    And the reason I get :mad: is because direct attaching with gamecache and hay-I-made-my-own systems tends to make ugly code that becomes untranslateable == unusable.

    There is nothing worse then finding a nice spell and then realising it is impossible to implement because author fucked up the code.
     
  13. emjlr3

    emjlr3 Change can be a good thing Staff Member

    Ratings:
    +396 / 0 / -0
    CSCache is huge, CSData is very small

    it is exactly this, actually
    JASS:
    globals
        gamecache cs_cache
        integer array cs_array3
    endglobals
    
    function CS_H2I takes handle h returns integer
        return h
        return 0
    endfunction
    
    function SetCSData takes handle h, integer v returns nothing
        local integer i=CS_H2I(h)-0x100000
        if (i>=8191) then
            call StoreInteger(cs_cache,"csdata",I2S(i),v)
        else
            set cs_array3[i]=v
        endif
    endfunction      
    function GetCSData takes handle h returns integer
        local integer i=CS_H2I(h)-0x100000
        if (i>=8191) then
            //can't use Get without Set
            return GetStoredInteger(cs_cache,"csdata",I2S(i))
        endif
        return cs_array3[i]
    endfunction


    for simplicity, however, i just tell ppl to copy over CSCache as a whole, for people who actually care, they can go about it anyway they want

    I use my own variants of CSData, Tables, CSSafety, and CasterSystem in my map making, I just do quick port over when i release a public "thing"
     
  14. Cohadar

    Cohadar master of fugue

    Ratings:
    +209 / 0 / -0
    Yes I was talking about CSCache from witch most people use only CSData and tables...

    CSData is nice because of it's simplicity.
    (and because it translates directly to ABC)

    Yes I noticed :p
    Btw you have some silly stuff in your caster system.

    (lets continue this in PM if needed to not pollute the thread )
     
  15. emjlr3

    emjlr3 Change can be a good thing Staff Member

    Ratings:
    +396 / 0 / -0
    v2 uploaded
     
  16. Tinki3

    Tinki3 Special Member

    Ratings:
    +418 / 0 / -0
    > which units exactly? will look into it

    By unreliable memory, I think the units were the Mur'guls.

    Nice update, works fine now.
     
  17. waaaks!

    waaaks! Zinctified

    Ratings:
    +256 / 0 / -0
    i suggest on adding ribbon attachments...like add some sfx on the hero while jumping so that it looks cool
     
  18. emjlr3

    emjlr3 Change can be a good thing Staff Member

    Ratings:
    +396 / 0 / -0
    thats just more arguments, bleh, i do not think it is needed

    if no one has anymore issues, I am moving this to the spells section
     
  19. Tinki3

    Tinki3 Special Member

    Ratings:
    +418 / 0 / -0
    Yeah no issues from me, works great, looks great, is great.

    No code problems from what I saw.
     
  20. waaaks!

    waaaks! Zinctified

    Ratings:
    +256 / 0 / -0
    can i ask for a permission on modifying the system on my map

    because im making some slashing spell, then after slashing...jumps to the target...

    but i cant make it because u used GetSpellTargetLoc in the system, and my spell is a unit target

    so i need to modify the system so that it works properly

    its just a small modification...i want to add a location on the function Jumpingspelltemplatecast...so that i can choose what location will my unit jump, not just the spell target loc...

    thanks
     

Share This Page