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

xecastExtended - Advanced Dummy Casting.

[HINT: This is not TESTED! Don't use this, I will post the correct code later, I just CnP it here to save the code]

What is this?
Basicly its an advanced xecast to prodice interval and
delayed casts. Also an interval cast can also have delay.

Why did you make this?
Basicly to enhance the dummy spell casting with
such an useful function.

Requirements?
  • A vJASS compiler (get JNGP)
  • xecast

Something else?
Please give credits to me.

PREVIEW ONLY, DO NOT USE

JASS:
//**************************************************************************
// 
//  xecastExtended 0.1
//     by dhk_undead_lord (Aka Anachron)
//     31.08.2009
// 
//  MAX_INSTANCES: Amount of instances maximal used
// 
//  TIMER: Timer used to proceed through the whole interval functions
//
//  TIMER_INT: The delay between proceeding from the interval functions
//
//************************************************************************** 
library xecastExtended // requires xecast

    globals
        private constant integer MAX_INSTANCES = JASS_MAX_ARRAY_SIZE - 1
        //: sets the maximum amount of instances used
        private constant timer TIMER = CreateTimer()
        //: the timer used by the library. You can also create a new
        //: one by using TimerUtils.
        private constant real TIMER_INT = 0.03
        //: define in which intervall the timer loop should run
    endglobals
    
    struct xecastExtended
        xecast xeCast = 0
        string typ = null
        
        //: delay values
        boolean hasDelay = false
        real delay = 0.
        
        //: intervall values
        boolean hasDuration = false
        real interval = 0.
        real duration = 0.
        real intTime = 0.
        
        real x = 0.
        real y = 0.
        real r = 0.
        location loc = null
        group g = null
        widget target = null
        
        //: Create a new xecastExtended from an existing xecast
        public static method create takes xecast xc returns xecastExtended
            local xecastDelayed xcd = xecastExtended.allocate()
                set xcd.xeCast = xc
            return xcd 
        endmethod
        
        //: Methods which start the casting. 
        //: REMEMBER: USE ONE OF THE CAST METHODS TO DEFINE CAST!
        //: Casts can also have no delay but an interval
        
        public method startCast takes real delay returns nothing
            set xcd.hasDelay = true
            set xcd.delay = delay
            
            call theLibrary.addCast(this) 
        endmethod
        
        public method startIntervalCast takes real int, real dur returns nothing
            set .interval = int
            set .duration = dur
            set .hasDuration = true
            
            call .startCast(0.)
        endmethod
        
        public method startIntervalCastDelayed takes real int, real dur, real delay returns nothing
            set .interval = int
            set .duration = dur
            set .hasDuration = true
            
            call .startCast(delay)
        endmethod
        
        //: Basicly the XE-Cast methods, just saved in the struct and
        //: Using a delay. 
        
        public method castOnTarget takes widget target returns nothing
            set .target = target
            set .typ = "castOnTarget"    
        endmethod
        
        public method castOnPoint  takes real x, real y returns nothing
            set .x = x
            set .y = y
            set .typ = "castOnPoint"    
        endmethod
        
        public method castOnLoc    takes location loc returns nothing
            set .loc = loc
            set .typ = "castOnLoc"    
        endmethod
        
        public method castInPoint  takes real x, real y returns nothing
            set .x = x
            set .y = y
            set .typ = "castInPoint"    
        endmethod
        
        public method castInLoc    takes location loc returns nothing
            set .loc = loc
            set .typ = "castInLoc"    
        endmethod
        
        public method castOnAOE    takes real x, real y, real radius returns nothing
            set .x = x
            set .y = y
            set .typ = "castOnAOE"     
        endmethod
        
        public method castOnAOELoc takes location loc,real radius returns nothing
            set .loc = loc
            set .r = radius
            set .typ = "castOnAoeLoc"    
        endmethod
        
        public method castOnGroup  takes group g returns nothing
            set .g = g
            set .typ = "castOnGroup"    
        endmethod
        
        //: Use the cast, depending on the casttype declared.
        //: Private because a forced cast wouldn't make sense,
        //: because you could just use xecast instead.
        
        private method useCast takes nothing returns nothing
            if .typ == "castOnTarget" then
                call .xeCast.castOnTarget(.target)
            elseif .typ == "castOnPoint" then
                call .xeCast.castOnPoint(.x, .y)
            elseif .typ == "castOnLoc" then
                call .xeCast.castOnLoc(.loc)
            elseif .typ == "castInPoint" then
                call .xeCast.castInPoint(.x, .y)
            elseif .typ == "castInLoc" then
                call .xeCast.castInLoc(.loc)
            elseif .typ == "castOnAOE" then
                call .xeCast.castOnAOE(.x, .y, .r)
            elseif .typ == "castOnAoeLoc" then
                call .xeCast.castOnAOE(.loc, .r)
            elseif .typ == "castOnGroup" then
                call .xeCast.castOnGroup(.g)
            else
                debug call BJDebugMsg("ERROR: The type of the delayed cast is not registered!")
            endif
        endmethod
        
        //: Parse the extended cast. This is good to be used on loops
        //: in structs. Returns a boolean whether the xecastExtended
        //: has been destroyed or not.
        public method parseCast takes real elapsedTime returns boolean
            local boolean dest = false
            
            if .hasDelay then
                set .delay = .delay - elapsedTime
                if .delay <= 0. then
                    .hasDelay = false
                endif
            else
                if .hasDuration then
                    set .intTime = .intTime + elapsedTime
                    
                    if .intTime >= .interval then
                        call .useCast()
                        set .intTime = 0.
                    endif 
                    
                    set .duration = .duration - elapsedTime
                    if .duration <= 0. then
                        set dest = true   
                    endif
                else
                    call .useCast()
                    set dest = true   
                endif
            endif
            
            if dest then
                call .destroy()
            endif
            
            return dest
        endmethod
        
        // Destroy the xecast when the xecastExtended is done!
        private method onDestroy takes nothing returns nothing
            call .xecast.destroy()
        endmethod
        
    endstruct

    struct theLibrary
        static integer index = 0
        static xecastExtended array instances[MAX_INSTANCES]
        static timer theRunner = TIMER
        
        public static method check takes nothing returns nothing
            local integer i = 0
            local xecastDelayed xcd = 0
            local boolean exit = false
            
            loop
                exitwhen exit
                
                set xcd = thistype.instances[i]
                
                if xcd.parseCast(TIMER_INT) then
                    set thistype.instances[i] = thistype.instances[thistype.index]
                    set thistype.index = thistype.index - 1
                        
                    set i = i - 1 
                endif
                
                if i >= thistype.index then
                    set exit = true
                else
                    set i = i + 1
                endif
            endloop
            
            if thistype.index == 0 then
                call PauseTimer(thistype.theRunner)
            endif
        endmethod
        
        public static method addCast takes xecastDelayed xcd returns nothing
            set thistype.instances[thistype.index] = xcd
            set thistype.index = thistype.index + 1
            
            if thistype.index == 1 then
                call TimerStart(thistype.theRunner, TIMER_INT, true, function thistype.check)
            endif 
        endmethod
    endstruct


endlibrary

JASS:
scope test initializer init

    private function init takes nothing returns nothing
        local xecast xc = xecast.createBasic('Abil', OrderId("blizzard"), Player(0)) 
        local xecastExtended xcd = xecastExtended.create(xc)
        local unit target = CreateUnit(0, 'hpea', 0., 0., 270.)
        
        //: Register the spell target type and the target itself
        call xcd.castOnTarget(target)
        
        //: Start a normal cast with a delay of xxx
        call xcd.startCast(2.00)
        
        set target = null
    endfunction

endscope
 
Level 10
Joined
Sep 21, 2007
Messages
517
xBlackRose, No.

This may help alot of users due to the fact that they dont have to do the work, anyways... one global dummy with all the spells should be preferred.

Gj anachron, even if i dont understand it!

but i really think u can use delay options, and basically any other options in object editor, but then again, people like to trigger it for some reason t.t
 
Delayed cast? There is a casting time for abilities in Object Editor.
But the xecast need the ability itself to be an instant cast, to be able to cast with one dummy 10 spells at the same time. How else would you do that with one dummy per player?

Also, you can trigger the delay yourself by detecting seconds elapsed.
Which would require more work just for one delayed cast?

What about xe itself?
Sure, that too. I just said I would be glad if someone uses it and gives me credits.

Mind showing a case of where this could come in handy?
Just anything you would like. For example:

Mass Sheep
> Sheeps all units on target area every 5 seconds for 2 seconds.
Lasts 15 seconds.

Could be done in 4 lines with my system.
 
Level 14
Joined
Nov 18, 2007
Messages
816
This is inaccurate. Use multiple timers (which will also increase efficiency).

I can change every member of the struct (which is what encapsulation is all about).
Last time i checked, expressions as constants dont work too well.
 
Top