Infinitegde
O.O
- Reaction score
- 86
Arrow System v 1.00
Requires Timer32(Make the "next" and "prev" members of T32x module not private)Ver History:
11/23/2009: Ver 1.00 Released
Description: vJass System created for the simple purpose of making it extremely easy to create "projectiles" that start in one place and end up in another. This system DOES obey the laws of physics (neglecting air friction)and the constant of gravity can be changed (not in game). The main reason I created this system was simply because I started making it for my Archer map and decided that it was pretty useful so why not post it.
One major thing that I haven't completely finished yet was creating more BJ's. When I made this I envisioned a system that would give you functions to cope with almost any possibility.
For example, hit a certain Z before reaching target.
Reach the target in a certain amount of time.
And a lot more, which I haven't done yet or had the need to do.
(The only reason I haven't done so was because the need for it hasn't come up in the map. I will be making more functions soon.)
Usage:
Pretty simple:
JASS:
local Arrow A = ArrowHeightToXY(GetTriggerUnit(),0,0,10,1000,1000,500)
set A.HitGround = DestroyUnit
set A.range=100
set A.UnitInRange=DamageUnit
set A.ArrowInRange= DestroyArrow
function DestroyUnit takes Arrow A returns nothing
call RemoveUnit(A.u)
endfunction
function DamageUnit takes Arrow A,unit targ returns nothing
call UnitDamageTarget(A.u,targ,10....)
endfunction
function DestroyArrow takes Arrow A, Arrow B returns nothing
call B.destroy()
endfunction
Creates an Arrow that fires the TriggeringUnit from (0,0) to (1000,1000) that peaks at a height of 500. If a unit enters within range of 100, it damages it. If an arrow enters within range of 100, it destroys it. When it hits the ground it removes the unit.
Members:
JASS:
struct Arrow
unit u =null //Arrow unit
real x =0 //X of arrow
real y=0 //Y of arrow
real z=0 //Z of arrow
real vx=0 // X Velocity
real vy=0 // Y Velocity
real vz=0 // Z Velocity
real time = 0 // Time passed since creation
integer data=0 // integer data that can be stored
real range=0 // Range in which a unit/arrow must enter for it to trigger call back. Leave as 0 if you don't want anything to happen when unit/arrow approaches.
CallBacks HitGround=-1//When the Arrow hits the ground, calls this function.
CallBacks Period=-1 //Every Period it calls this function
CallBacks Peak=-1 //When the Arrow is at it's peak it calls this function
CallBacksArrow ArrowInRange=-1 //When arrow is in range it calls this function
CallBacksUnit UnitInRange=-1 //When unit is in range, calls this function
...
endstruct
Code:
JASS:
library ArrowSys requires T32
globals
constant real Arrow_g = .981
endglobals
private function SetUnitZ takes unit u, real z returns nothing
call UnitAddAbility(u,039;Amrf039;)
call SetUnitFlyHeight(u,z,0)
call UnitRemoveAbility(u,039;Amrf039;)
endfunction
function ArrowTimedToXY takes unit u, real fX, real fY, real fZ, real toX, real toY, real time returns Arrow
local Arrow A = Arrow.create(u)
local real dx=toX-fX
local real dy=toY-fY
local real theta = Atan2(dy,dx)
local real dist = SquareRoot(dx*dx+dy*dy)
local real gV
set A.x=fX
set A.y=fY
set A.z=fZ
set gV= dist/(time)
set A.vx= gV*Cos(theta)
set A.vy=gV*Sin(theta)
set A.vz=Arrow_g*time/2
return A
endfunction
function ArrowHeightToXY takes unit u, real fX, real fY, real fZ, real toX, real toY, real height returns Arrow
local Arrow A = Arrow.create(u)
local real dx=toX-fX
local real dy=toY-fY
local real theta = Atan2(dy,dx)
local real dist = SquareRoot(dx*dx+dy*dy)
local real gV
set A.x=fX
set A.y=fY
set A.z=fZ
set A.vz=SquareRoot(2*Arrow_g*height)
set gV= dist/(2*A.vz/Arrow_g)
set A.vx= gV*Cos(theta)
set A.vy=gV*Sin(theta)
return A
endfunction
function interface CallBacks takes Arrow A returns nothing
function interface CallBacksArrow takes Arrow A, Arrow B returns nothing
function interface CallBacksUnit takes Arrow A, unit B returns nothing
private function True takes nothing returns boolean
return true
endfunction
struct Arrow
unit u =null
real x =0
real y=0
real z=0
real vx=0
real vy=0
real vz=0
real time = 0
integer data=0
real range=0
CallBacks HitGround=-1
CallBacks Period=-1
CallBacks Peak=-1
CallBacksArrow ArrowInRange=-1
CallBacksUnit UnitInRange=-1
static method create takes unit u returns Arrow
local Arrow X = Arrow.allocate()
call X.startPeriodic()
set X.u=u
return X
endmethod
static method GetArrowsInRange takes Arrow A, real range returns nothing
local Arrow cur = Arrow(0).next
local real x
local real y
local real z
loop
exitwhen cur==0
set x = cur.x-A.x
set y = cur.y-A.y
set z= cur.z-A.z
if(A!=cur and SquareRoot(x*x+y*y+z*z)<range)then
call A.ArrowInRange.evaluate(A, cur)
endif
set cur=cur.next
endloop
endmethod
static method GetUnitsInRange takes Arrow A, real range returns nothing
local Arrow cur = Arrow(0).next
local group g = CreateGroup()
local real x
local real y
local real z
local unit u
call GroupEnumUnitsInRange(g,A.x,A.y,range+100,Condition(function True))
loop
set u = FirstOfGroup(g)
exitwhen u==null
set x = GetUnitX(u)-A.x
set y = GetUnitY(u)-A.y
set z= GetUnitFlyHeight(u)-A.z
if(A.u!=u and SquareRoot(x*x+y*y+z*z)<range)then
call A.UnitInRange.evaluate(A,u)
endif
call GroupRemoveUnit(g,u)
endloop
call DestroyGroup(g)
set g=null
endmethod
method onDestroy takes nothing returns nothing
call .stopPeriodic()
endmethod
method periodic takes nothing returns boolean
local boolean pos= .vz>0
set .x = .x+.vx
set .y=.y+.vy
set .z=.z+.vz
set .vz = .vz-Arrow_g
if(Period !=-1)then
call Period.evaluate(this)
endif
if(range!=0)then
call Arrow.GetArrowsInRange(this,range)
call Arrow.GetUnitsInRange(this,range)
endif
if(pos and .vz<0 and Peak!=-1)then
call Peak.evaluate(this)
endif
call SetUnitX(.u,.x)
call SetUnitY(.u,.y)
call SetUnitZ(.u,.z)
if(.z<0)then
call HitGround.evaluate(this)
call .destroy()
return true
endif
set time=time+T32_PERIOD
return false
endmethod
implement T32x
endstruct
endlibrary