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

Linear- & Parabolic Throw

Level 11
Joined
Apr 29, 2007
Messages
826
hai thar, I present you a new system (wow)
It allows you to make simple projectils with a linear or a parabolic throw(parabola is the standard wc3 thingie from Shadow1500)
You can configurate everything the projectile is going to do.

JASS:
/*

                LINEAR- & PARABOLIC THROW
                    by YourName
                    
            
            DESCRIPTION
                >> This is an easy to modificate system that allows you to throw projectiles by the
                   linear of parabolic way. Through an interface you're able to setup anything the
                   projectile should do.
                   Some functions are made by default, but you can simply rewrite those methods in
                   your child struct.
                   
            FUNCTIONS LIST
                >> Interface
                     >> method OnInit takes nothing returns nothing
                        method OnLoop takes nothing returns nothing
                        method OnDestroy takes nothing returns nothing
                        method OnHeightCollision takes nothing returns nothing
                        method OnUnitCollision takes nothing returns nothing
                        method OnUnitCollisionCheck takes nothing returns boolean
                        method OnDoodadCollision takes destructable d returns nothing
                        method OnPathableCollision takes nothing returns nothing
                        
                >> Struct
                    >> method create takes unit target, real angle, real speed, real reduce returns Throw
                       method stop takes nothing returns nothing
                         NOTE: Please use this instead of destroying the struct, this won't screw things up.
            
            SIMPLE USAGE
                >> All you have to do is extend the LinearThrow or ParabolicThrow struct depending on
                   which one you want. After that setup all the stuff and you're done.
                   For an example look in the spell section at the demo map.
                   
*/

JASS:
library_once LinearThrow initializer Init

globals // Configuration
    // The interval how often the stuff is executed
    constant real    THROWSYSTEM_INTERVAL           = 0.02
    // The Radius in which units/doodads get picked
    constant real    THROWSYSTEM_RADIUS             = 100
    // The minimum height the projectile has to have before it can hit any of those 2
    constant real    THROWSYSTEM_MIN_UNIT_HEIGHT    = 125
    constant real    THROWSYSTEM_MIN_DESTR_HEIGHT   = 225
    // If the height should decrease or be constant
    constant boolean THROWSYSTEM_DECREASE_HEIGHT    = true
    // Whether the projectile should drift a bit or not
    constant boolean THROWSYSTEM_ALLOW_DRIFT        = true
    // Maximum drift amount
    constant real    THROWSYSTEM_DRIFT_MAX          = 1000
    // It might look ugly when the projectiles flies of too much. So set this value higher
    constant real    THROWSYSTEM_DRIFT_Z_CORRECTION = 2
    // If the projectile should be stopped whenever the Z of it reaches 0
    constant boolean THROWSYSTEM_DESTROY_WHEN_Z_0   = true
endglobals

interface LinearThrowFace // I love Vex
    static timer t
    static integer total
    static LinearThrow array save
    static group g
    static boolexpr bool
    static unit victim
    static rect r
    static LinearThrow tempsave
    static location zloc
    static item i1 = null
    static item i2 = null
    
    real Interval = THROWSYSTEM_INTERVAL
    real Radius = THROWSYSTEM_RADIUS
    real MinUnitHeight = THROWSYSTEM_MIN_UNIT_HEIGHT
    real MinDestrHeight = THROWSYSTEM_MIN_DESTR_HEIGHT
    boolean DecreaseHeight = THROWSYSTEM_DECREASE_HEIGHT
    boolean Drift = THROWSYSTEM_ALLOW_DRIFT
    real DriftValue = THROWSYSTEM_DRIFT_MAX*.Interval
    real DriftCorrection = THROWSYSTEM_DRIFT_Z_CORRECTION
    boolean DestroyWhenZ = THROWSYSTEM_DESTROY_WHEN_Z_0

    method OnInit takes nothing returns nothing defaults nothing
    method OnLoop takes nothing returns nothing defaults nothing
    method OnDestroy takes nothing returns nothing defaults nothing
    method OnHeightCollision takes nothing returns nothing defaults nothing
    method OnUnitCollision takes nothing returns nothing defaults nothing
    method OnUnitCollisionCheck takes nothing returns boolean defaults true
    method OnDoodadCollision takes destructable d returns nothing defaults nothing
    method OnPathableCollision takes nothing returns nothing defaults nothing
endinterface

struct LinearThrow extends LinearThrowFace

    unit target
    real sin
    real cos
    real speed
    real reduce
    real distance
    real maxdist
    real iniz
    real zr
    integer i
    
    
    method operator x takes nothing returns real
        return GetUnitX(.target)
    endmethod
    
    method operator y takes nothing returns real
        return GetUnitY(.target)
    endmethod
    
    method operator z takes nothing returns real
        call MoveLocation(.zloc, .x, .y)
        if .DecreaseHeight then
            return .iniz - GetLocationZ(.zloc) - (.zr*.i)
        else
            return .iniz - GetLocationZ(.zloc)
        endif
    endmethod
    
    private method operator x= takes real x returns nothing
        call SetUnitX(.target, x)
    endmethod
    
    private method operator y= takes real y returns nothing
        call SetUnitY(.target, y)
    endmethod
    
    private method operator z= takes real z returns nothing
        call SetUnitFlyHeight(.target, z, 0)
    endmethod
    
    method operator pathable takes nothing returns boolean
        if .i1 == null or .i2 == null then
            if .i1 == null then
                set .i1 = CreateItem('sehr', .x, .y)
            endif
            if .i2 == null then
                set .i2 = CreateItem('sehr', .x, .y)
            endif
        endif
        
        call SetItemPosition(.i1, .x, .y)
        call SetItemPosition(.i2, .x, .y)
        
        if (GetItemX(.i1) == .x and GetItemY(.i1) == .y) and not (GetItemX(.i2) == .x and GetItemY(.i2) == .y) then
            call SetItemVisible(.i1, false)
            call SetItemVisible(.i2, false)
            return true
        endif
        
        call SetItemVisible(.i1, false)
        call SetItemVisible(.i2, false)
        return false
    endmethod
    
    method OnHeightCollision takes nothing returns nothing
        call .stop()
    endmethod
    
    method OnDoodadCollision takes destructable d returns nothing
        if GetWidgetLife(d) > 0.405 then
            call KillDestructable(d)
            call .stop()
        endif
    endmethod
    
    
    method stop takes nothing returns nothing
        set .speed = 0
    endmethod
    
    static method create takes unit target, real angle, real speed, real reduce returns LinearThrow
        local LinearThrow this = LinearThrow.allocate()
        local real time
        
        set .target = target
        set .sin = Sin(angle)
        set .cos = Cos(angle)
        set .speed = speed
        set .reduce = reduce
        call MoveLocation(.zloc, .x, .y)
        set .iniz = GetUnitFlyHeight(.target) + GetLocationZ(.zloc)
        set .zr = .iniz / ( speed / reduce )
        set .i = 0
        set time = speed / ((reduce/.Interval)+1)
        set .maxdist =  (speed*((time/.Interval)+1)) / 2
        set .distance = 0.01
        
        call .OnInit()
        
        if .total == 0 then
            call TimerStart(.t, .Interval, true, function LinearThrow.work)
        endif
        
        set .save[.total] = this
        set .total = .total + 1
        
        return this
    endmethod
    
    private static method work takes nothing returns nothing
        local LinearThrow this
        local integer i = 0
        local real angle
        loop
            exitwhen i >= .total
            set this = .save[i]
            set .i = .i + 1
            
            set .distance = .distance + .speed
            
            set .x = .x + .speed * .cos
            set .y = .y + .speed * .sin
            set .z = .z
            
            if .Drift then
                set angle = (GetUnitFacing(.target) - 90)
                set .x = .x + GetRandomReal(-.DriftValue, .DriftValue) * Cos(angle * bj_DEGTORAD)
                set .y = .y + GetRandomReal(-.DriftValue, .DriftValue) * Sin(angle * bj_DEGTORAD)
                set .z = .z + GetRandomReal(-.DriftValue, .DriftValue)/.DriftCorrection
                call SetUnitFacing(.target, angle)
            endif
            
            call .OnLoop()
            
            set .speed = .speed - .reduce
            
            if .z < .MinUnitHeight then
                call GroupEnumUnitsInRange(.g, .x, .y, .Radius, .bool)
                loop
                    set .victim = FirstOfGroup(.g)
                    exitwhen .victim == null
                    if .OnUnitCollisionCheck() then
                        call .OnUnitCollision()
                    endif
                    call GroupRemoveUnit(.g, .victim)
                endloop
                set .victim = null
            endif
            
            if .z < .MinDestrHeight then
                if .Radius != THROWSYSTEM_RADIUS then
                    set .r = Rect(0-.Radius, 0-.Radius, 0+.Radius, 0+.Radius)
                endif
                call MoveRectTo(.r, .x, .y)
                set .tempsave = this
                call EnumDestructablesInRect(.r, .bool, function LinearThrow.DoodadCollision)
            endif
            
            if GetLocationZ(.zloc) > .iniz then
                call .OnHeightCollision()
            endif
            
            if not .pathable then
                call .OnPathableCollision()
            endif
            
            if .speed <= 0 or (.z < 1 and .DestroyWhenZ) or .distance > .maxdist then
                set .total = .total - 1
                set .save[i] = .save[.total]
                call .OnDestroy()
                call .destroy()
            endif
            
            set i = i + 1
        endloop
        
        if .total == 0 then
            call PauseTimer(.t)
        endif
            
    endmethod
    
    private static method DoodadCollision takes nothing returns nothing
        local LinearThrow this = .tempsave
        call .OnDoodadCollision(GetEnumDestructable())
    endmethod
    
endstruct

private function Init takes nothing returns nothing
    set LinearThrow.t = CreateTimer()
    set LinearThrow.zloc = Location(0,0)
    set LinearThrow.g = CreateGroup()
    set LinearThrow.bool = null
    set LinearThrow.victim = null
    set LinearThrow.r = Rect(0-THROWSYSTEM_RADIUS, 0-THROWSYSTEM_RADIUS, 0+THROWSYSTEM_RADIUS, 0+THROWSYSTEM_RADIUS)
    set LinearThrow.total = 0
endfunction

endlibrary

JASS:
library_once ParabolicThrow initializer Init

globals // Configuration
    // The interval how often the stuff is executed
    constant real    THROWPARABOLICSYSTEM_INTERVAL           = 0.02
    // The Radius in which units/doodads get picked
    constant real    THROWPARABOLICSYSTEM_RADIUS             = 100
    // The minimum height the projectile has to have before it can hit any of those 2
    constant real    THROWPARABOLICSYSTEM_MIN_UNIT_HEIGHT    = 125
    constant real    THROWPARABOLICSYSTEM_MIN_DESTR_HEIGHT   = 225
    // If the height should decrease or be constant
    constant boolean THROWPARABOLICSYSTEM_DECREASE_HEIGHT    = true
    // Whether the projectile should drift a bit or not
    constant boolean THROWPARABOLICSYSTEM_ALLOW_DRIFT        = true
    // Maximum drift amount
    constant real    THROWPARABOLICSYSTEM_DRIFT_MAX          = 1000
    // It might look ugly when the projectiles flies of too much. So set this value higher
    constant real    THROWPARABOLICSYSTEM_DRIFT_Z_CORRECTION = 2
    // If the projectile should be stopped whenever the Z of it reaches 0
    constant boolean THROWPARABOLICSYSTEM_DESTROY_WHEN_Z_0   = true
    // The curve the projectile will have
    constant real    THROWPARABOLICSYSTEM_CURVE = 2
endglobals

interface ParabolicThrowFace // I love Vex
    static timer t
    static integer total
    static ParabolicThrow array save
    static group g
    static boolexpr bool
    static unit victim
    static rect r
    static ParabolicThrow tempsave
    static location zloc
    static item i1 = null
    static item i2 = null
    
    real Interval = THROWPARABOLICSYSTEM_INTERVAL
    real Radius = THROWPARABOLICSYSTEM_RADIUS
    real MinUnitHeight = THROWPARABOLICSYSTEM_MIN_UNIT_HEIGHT
    real MinDestrHeight = THROWPARABOLICSYSTEM_MIN_DESTR_HEIGHT
    boolean DecreaseHeight = THROWPARABOLICSYSTEM_DECREASE_HEIGHT
    boolean Drift = THROWPARABOLICSYSTEM_ALLOW_DRIFT
    real DriftValue = THROWPARABOLICSYSTEM_DRIFT_MAX*.Interval
    real DriftCorrection = THROWPARABOLICSYSTEM_DRIFT_Z_CORRECTION
    boolean DestroyWhenZ = THROWPARABOLICSYSTEM_DESTROY_WHEN_Z_0
    real Curve = THROWPARABOLICSYSTEM_CURVE

    method OnInit takes nothing returns nothing defaults nothing
    method OnLoop takes nothing returns nothing defaults nothing
    method OnDestroy takes nothing returns nothing defaults nothing
    method OnHeightCollision takes nothing returns nothing defaults nothing
    method OnUnitCollision takes nothing returns nothing defaults nothing
    method OnUnitCollisionCheck takes nothing returns boolean defaults true
    method OnDoodadCollision takes destructable d returns nothing defaults nothing
    method OnPathableCollision takes nothing returns nothing defaults nothing
endinterface

struct ParabolicThrow extends ParabolicThrowFace

    unit target
    real sin
    real cos
    real speed
    real reduce
    real distance
    real maxdist
    real iniz
    real zr
    integer i
    
    // Function by Shadow1500
    private method operator parabola takes nothing returns real
        local real t = (.distance*2) / .maxdist-1
        return (-t*t+1) * (.maxdist/.Curve)
    endmethod
    
    method operator x takes nothing returns real
        return GetUnitX(.target)
    endmethod
    
    method operator y takes nothing returns real
        return GetUnitY(.target)
    endmethod
    
    method operator z takes nothing returns real
        call MoveLocation(.zloc, .x, .y)
        if .DecreaseHeight then
            return .iniz + .parabola - GetLocationZ(.zloc) - (.zr*.i)
        else
            return .iniz + .parabola - GetLocationZ(.zloc)
        endif
    endmethod
    
    private method operator x= takes real x returns nothing
        call SetUnitX(.target, x)
    endmethod
    
    private method operator y= takes real y returns nothing
        call SetUnitY(.target, y)
    endmethod
    
    private method operator z= takes real z returns nothing
        call SetUnitFlyHeight(.target, z, 0)
    endmethod
    
    private method operator pathable takes nothing returns boolean
        if .i1 == null or .i2 == null then
            if .i1 == null then
                set .i1 = CreateItem('sehr', .x, .y)
            endif
            if .i2 == null then
                set .i2 = CreateItem('sehr', .x, .y)
            endif
        endif
        
        call SetItemPosition(.i1, .x, .y)
        call SetItemPosition(.i2, .x, .y)
        
        if (GetItemX(.i1) == .x and GetItemY(.i1) == .y) and not (GetItemX(.i2) == .x and GetItemY(.i2) == .y) then
            call SetItemVisible(.i1, false)
            call SetItemVisible(.i2, false)
            return true
        endif
        
        call SetItemVisible(.i1, false)
        call SetItemVisible(.i2, false)
        return false
    endmethod
    
    method OnHeightCollision takes nothing returns nothing
        call .stop()
    endmethod
    
    method OnDoodadCollision takes destructable d returns nothing
        if GetWidgetLife(d) > 0.405 then
            call KillDestructable(d)
            call .stop()
        endif
    endmethod
    
    
    method stop takes nothing returns nothing
        set .speed = 0
    endmethod
    
    static method create takes unit target, real angle, real speed, real reduce returns ParabolicThrow
        local ParabolicThrow this = ParabolicThrow.allocate()
        local real time
        
        set .target = target
        set .sin = Sin(angle)
        set .cos = Cos(angle)
        set .speed = speed
        set .reduce = reduce
        set time = speed / ((reduce/.Interval)+1)
        set .maxdist =  (speed*((time/.Interval)+1)) / 2
        set .distance = 0.01
        call MoveLocation(.zloc, .x, .y)
        set .iniz = GetUnitFlyHeight(.target) + GetLocationZ(.zloc)
        set .zr = .iniz / ( speed / reduce )
        set .i = 0
        
        call .OnInit()
        
        if .total == 0 then
            call TimerStart(.t, .Interval, true, function ParabolicThrow.work)
        endif
        
        set .save[.total] = this
        set .total = .total + 1
        
        return this
    endmethod
    
    private static method work takes nothing returns nothing
        local ParabolicThrow this
        local integer i = 0
        local real angle
        loop
            exitwhen i >= .total
            set this = .save[i]
            set .i = .i + 1
            
            set .distance = .distance + .speed
            
            set .x = .x + .speed * .cos
            set .y = .y + .speed * .sin
            set .z = .z
            
            if .Drift then
                set angle = (GetUnitFacing(.target) - 90)
                set .x = .x + GetRandomReal(-.DriftValue, .DriftValue) * Cos(angle * bj_DEGTORAD)
                set .y = .y + GetRandomReal(-.DriftValue, .DriftValue) * Sin(angle * bj_DEGTORAD)
                set .z = .z + GetRandomReal(-.DriftValue, .DriftValue)/.DriftCorrection
                call SetUnitFacing(.target, angle)
            endif
            
            call .OnLoop()
            
            set .speed = .speed - .reduce
            
            if .z < .MinUnitHeight then
                call GroupEnumUnitsInRange(.g, .x, .y, .Radius, .bool)
                loop
                    set .victim = FirstOfGroup(.g)
                    exitwhen .victim == null
                    if .OnUnitCollisionCheck() then
                        call .OnUnitCollision()
                    endif
                    call GroupRemoveUnit(.g, .victim)
                endloop
                set .victim = null
            endif
            
            if .z < .MinDestrHeight then
                if .Radius != THROWPARABOLICSYSTEM_RADIUS then
                    set .r = Rect(0-.Radius, 0-.Radius, 0+.Radius, 0+.Radius)
                endif
                call MoveRectTo(.r, .x, .y)
                set .tempsave = this
                call EnumDestructablesInRect(.r, .bool, function ParabolicThrow.DoodadCollision)
            endif
            
            if GetLocationZ(.zloc) > .iniz then
                call .OnHeightCollision()
            endif
            
            if not .pathable then
                call .OnPathableCollision()
            endif
            
            if .speed <= 0 or (.z < 1 and .DestroyWhenZ) or .distance >= .maxdist then
                set .total = .total - 1
                set .save[i] = .save[.total]
                call .OnDestroy()
                call .destroy()
            endif
            
            set i = i + 1
        endloop
        
        if .total == 0 then
            call PauseTimer(.t)
        endif
            
    endmethod
    
    private static method DoodadCollision takes nothing returns nothing
        local ParabolicThrow this = .tempsave
        call .OnDoodadCollision(GetEnumDestructable())
    endmethod
    
endstruct

private function Init takes nothing returns nothing
    set ParabolicThrow.t = CreateTimer()
    set ParabolicThrow.zloc = Location(0,0)
    set ParabolicThrow.g = CreateGroup()
    set ParabolicThrow.bool = null
    set ParabolicThrow.victim = null
    set ParabolicThrow.r = Rect(0-THROWPARABOLICSYSTEM_RADIUS, 0-THROWPARABOLICSYSTEM_RADIUS, 0+THROWPARABOLICSYSTEM_RADIUS, 0+THROWPARABOLICSYSTEM_RADIUS)
    set ParabolicThrow.total = 0
endfunction

endlibrary

JASS:
library_once Convert

/*
    This is just a simple library to convert those values, so you don't have to type the damn formulas
    yourself.
*/

function Distance2Speed takes real distance, real time returns real
    return (2*distance) / ((time/THROWSYSTEM_INTERVAL)+1)
endfunction

function Time2SpeedReduce takes real time, real speed returns real
    return speed / (time/THROWSYSTEM_INTERVAL)
endfunction

endlibrary

Demo map with 2 example spells below. Enjoy :)
 

Attachments

  • Throw.w3x
    39.8 KB · Views: 67
Last edited:
Level 12
Joined
Feb 23, 2007
Messages
1,030
There already are some great parabolic functions.

I believe Deathcom wrote them.

JASS:
library ParabolicFunctions

    globals
        private location L = Location(0, 0)
    endglobals

    function GetUnitZ takes unit u returns real
        call MoveLocation(L, GetUnitX(u), GetUnitY(u))
        return GetLocationZ(L) + GetUnitFlyHeight(u)
    endfunction

    function SetUnitZ takes unit u, real z returns nothing
        call MoveLocation(L, GetUnitX(u), GetUnitY(u))
        call SetUnitFlyHeight(u, z - GetLocationZ(L), 0)
    endfunction

    function IsUnitInRangeXYZ takes unit u, real x, real y, real z, real d returns boolean
        local real x2
        call GetUnitPointValueByType(GetUnitTypeId(u))
        return true
    endfunction

    function ParabolicMovement takes real h, real d, real x returns real
        local real a = -4*h/(d*d)
        local real b = 4*h/d
        return a*x*x + b*x
    endfunction

    function ParabolaZ2 takes real y0, real y1, real h, real d, real x returns real
      local real A = (2*(y0+y1)-4*h)/(d*d)
      local real B = (y1-y0-A*d*d)/d
      return A*x*x + B*x + y0
    endfunction

    function ZAngle takes real a returns integer
        local integer i = R2I(a + 90)
        
        if(i>=180) then
            set i=179
        elseif(i<0) then
            set i=0
        endif
               
        return i
    endfunction

    function SetUnitZAngle takes unit u, real r returns nothing
        call SetUnitAnimationByIndex(u, ZAngle(r))
    endfunction

// y0 = Starting Height
// y1 = End height
// h = max height
// d = max length
// x = distance traveled

endlibrary
 
Level 31
Joined
Jul 10, 2007
Messages
6,306
Ok, one major suggestion-
make stuff like this unique for each projectile and make these constant values default values if the projectile has nothing set-
JASS:
    constant real THROWSYSTEM_RADIUS = 100
    // The minimum height the projectile has to have before it can hit any of those 2
    constant real THROWSYSTEM_MIN_UNIT_HEIGHT = 125
    constant real THROWSYSTEM_MIN_DESTR_HEIGHT = 225
    // If the height should decrease or be constant
    constant boolean THROWSYSTEM_DECREASE_HEIGHT = true
    // Whether the projectile should drift a bit or not
    constant boolean THROWSYSTEM_ALLOW_DRIFT = true
    // Maximum drift amount
    constant real THROWSYSTEM_DRIFT_MAX = 1000
    // It might look ugly when the projectiles flies of too much. So set this value higher
    constant real THROWSYSTEM_DRIFT_Z_CORRECTION = 2
    // If the projectile should be stopped whenever the Z of it reaches 0
    constant boolean THROWSYSTEM_DESTROY_WHEN_Z_0 = true

Otherwise looks good =)

Oh, and a spawn object using this system would only be like... 6 lines, lol.
 
Level 11
Joined
Apr 29, 2007
Messages
826
Ok, one major suggestion-
make stuff like this unique for each projectile and make these constant values default values if the projectile has nothing set-
JASS:
    constant real THROWSYSTEM_RADIUS = 100
    // The minimum height the projectile has to have before it can hit any of those 2
    constant real THROWSYSTEM_MIN_UNIT_HEIGHT = 125
    constant real THROWSYSTEM_MIN_DESTR_HEIGHT = 225
    // If the height should decrease or be constant
    constant boolean THROWSYSTEM_DECREASE_HEIGHT = true
    // Whether the projectile should drift a bit or not
    constant boolean THROWSYSTEM_ALLOW_DRIFT = true
    // Maximum drift amount
    constant real THROWSYSTEM_DRIFT_MAX = 1000
    // It might look ugly when the projectiles flies of too much. So set this value higher
    constant real THROWSYSTEM_DRIFT_Z_CORRECTION = 2
    // If the projectile should be stopped whenever the Z of it reaches 0
    constant boolean THROWSYSTEM_DESTROY_WHEN_Z_0 = true

Look at the interface? It sets those values as default for each projectile you create, but you can redeclare them by your own.

Otherwise looks good =)
Thanks.

Oh, and a spawn object using this system would only be like... 6 lines, lol.[
lolwut?
 
Level 31
Joined
Jul 10, 2007
Messages
6,306
Ah ok ; ).

as for the spawn object, yea, it'd only be 6 lines... lemme cnp the documentation for it-

SpawnObject-
Refers to the type of spawn. This interface contains one method called make
for making spawns.

Spawn_SpawnObject-
Spawn objects are used to determine what a spawn produces.

methods:
public method make takes player p, integer typeId, real x, real y, real facing, Spawn spawn returns nothing
called for making a spawn.

So, rather than making projectiles you'd make the projectile struct a struct that extends an array and use the spawn index (spawn) to accesses the indexes.

Only problem that could occur is during mimicing, but I will fix that =).

So yea, this would be interesting as a spawn object : P.
 
Level 11
Joined
Feb 22, 2006
Messages
752
First of all, this needs better documentation. Nobody is going to know what reduce is. Or drfit. Or that you need to access .victim on unit collision to get what the thing collided with.

Second of all, I ran the demo map. And the parabolic throw looked...weird. It was as if the projectiles sped up as they neared the top of the curve. And also the projectiles always overshot where I cast the spell (like they overshot the entire AOE circle, not just the point where I clicked).
 
Top