- Joined
- Oct 16, 2008
- Messages
- 10,454
yup, just make sure its in radians and not degress...
unit facing returns degrees...
unit facing returns degrees...
yup, just make sure its in radians and not degress...
unit facing returns degrees...
Atan2(GetSpellTargetY() - GetUnitY(GetTriggerUnit()) , GetSpellTargetX() - GetUnitX(GetTriggerUnit()))
the effect was fixed already?
for degrees to radians multiply the degree-angle by bj_DEGTORAD...
Note: if your spell is a targeted one, use this to get angle in radians, and much more accurate since unit facing only returns some angles
JASS:Atan2(GetSpellTargetY() - GetUnitY(GetTriggerUnit()) , GetSpellTargetX() - GetUnitX(GetTriggerUnit()))
llibrary AttackSystem initializer init
globals
constant real ATTACK_AREA = 300
constant real ATTACK_DAMAGE = 100
constant real ATTACK_THRUST = 100
constant string ATTACK_SFX = "Abilities\\Spells\\Other\\Monsoon\\MonsoonBoltTarget.mdl"
constant string ATTACK_ORDER_ID = "holdposition"
endglobals
struct Attack
private unit caster = null
private real x
private real y
private real angle
private static group enumGroup = CreateGroup()
private static thistype temp
private static method enumGroupFilter takes nothing returns boolean
if IsUnitEnemy(GetFilterUnit(), GetOwningPlayer( temp.caster )) then
call UnitDamageTarget( temp.caster, GetFilterUnit(), ATTACK_DAMAGE, false, false, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_NORMAL, null)
endif
return false
endmethod
static method cast takes nothing returns thistype
local thistype temp = allocate()
set temp.caster = GetTriggerUnit()
set temp.angle = (GetUnitFacing(temp.caster)*bj_DEGTORAD)
set temp.x = (GetUnitX(temp.caster) + ATTACK_THRUST * Cos(temp.angle))
set temp.y = (GetUnitY(temp.caster) + ATTACK_THRUST * Sin(temp.angle))
call DestroyEffect(AddSpecialEffect(ATTACK_SFX, temp.x, temp.y))
call GroupEnumUnitsInRange(enumGroup, temp.x, temp.y, ATTACK_AREA, Filter( function thistype.enumGroupFilter))
call temp.destroy()
return 0
endmethod
endstruct
//==============================================================================================================
private function condition takes nothing returns boolean
return ( GetIssuedOrderIdBJ() == String2OrderIdBJ(ATTACK_ORDER_ID) )
endfunction
private function init takes nothing returns nothing
local trigger t = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_ISSUED_ORDER)
call TriggerAddCondition(t, Filter(function condition))
call TriggerAddAction(t, function Attack.cast)
endfunction
endlibrary
local thistype temp
rather than the static thistype temp
meaning the temp in the enumGroupFilter has no value (because the temp in the enumGroupFilter is the static thistype temp
)...Omg it works. Thanks a bunch! .... hmmmm now to do the other stuff on thw attack system.
^^...
be sure not to have a static thistype and a local thistype having the same name...
for better understanding, read the vJASS OOP tut... ^_^
you will learn there how to use structs effectively...
yeah, that's why... basically you dont give two variables the same name inside the same code... ^_^
and as Berb said, you can just directly use temp, rather than making a local thistype...
that happened to me too while I'm reading it, especially the struct inheriting... I only managed to understand it because of TRD... ^_^
yup, you can have multiple "and" in an if statement
Ehehe I'll try to remember that
Lol. Oh who's TRD? is that his username?
yeah I did it and it worked.
Also I saw berb use these
/**/
what does these two do?
//here, if he hadn't put the /* */, this would return a compile error
//because he "cut" the parameters
//rather than typing the parameters in a straight line, he "cut" it
//to increase readability
call UnitDamageTarget(temp.caster, GetFilterUnit(), ICE_NOVA_DAMAGE, false, false, /*
*/ ATTACK_TYPE_CHAOS, DAMAGE_TYPE_NORMAL, null)
//that is easier to read than
call UnitDamageTarget(temp.caster, GetFilterUnit(), ICE_NOVA_DAMAGE, false, false, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_NORMAL, null)
The_Reborn_Devil
/**/ -> it enables you to have ENTER spaces in the code
JASS://here, if he hadn't put the /* */, this would return a compile error //because he "cut" the parameters //rather than typing the parameters in a straight line, he "cut" it //to increase readability call UnitDamageTarget(temp.caster, GetFilterUnit(), ICE_NOVA_DAMAGE, false, false, /* */ ATTACK_TYPE_CHAOS, DAMAGE_TYPE_NORMAL, null) //that is easier to read than call UnitDamageTarget(temp.caster, GetFilterUnit(), ICE_NOVA_DAMAGE, false, false, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_NORMAL, null)
call UnitDamageTarget(temp.caster, GetFilterUnit(), ICE_NOVA_DAMAGE, false, false,
ATTACK_TYPE_CHAOS, DAMAGE_TYPE_NORMAL, null)
/**/
is another way to put comments. It can be used to put space because the compiler basically ignores anything in it.You could just delete your post. (Edit button at the bottom right of your post.)
Just to add on/**/
is another way to put comments. It can be used to put space because the compiler basically ignores anything in it.
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Move System v.0.1 by neku99
//
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// A simple Move System for my map. Enables you to move/dash units and also pause them at will
// (some features are not yet implemented and somethings are not yet done)
//==================================================
// Speed Conversions
//==================================================
// I use this conversions to calculate speed
//
// 1 second = 1 meter
// 1 second = 50 units
// 0.01 second = 0.5 units
// So no distance per interval is calcualted:
//
// BASESPEED / SPEEDSCALE = distance per interval
//
// 522 / 100 = 5.22
//
//==================================================
// Configurables
//==================================================
// -speed
// -more to come
//
//==================================================
// Globals
//==================================================
//
//
//
//==================================================
// Parameters and Usage
//==================================================
// You can simply use damage with one function call:
//
// call Damage.create( PARAMETERS )
//
// Here are the parameters on their proper order
// (Parameters with the prefix "!" are not yet implemented)
//
// unit u = the unit to be moved
// real x = the x coordinate of the unit
// real y = the y coordinate of the unit
// real bs = the base speed of the move (used to determine distance per interval)
// real ss = the speed scale of the move (used to determine distance per interval)
//
//END+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
library MoveEngine
globals
private constant real MOVE_SPEED_SCALE = 100
private constant real TICK = 0.01
private timer MOVE_TIMER = CreateTimer()
private integer TOTAL = 0
private integer array MOVE_ARRAY[8190]
endglobals
struct Move
private unit u //unit to be moved
private real ux //unit x
private real uy //unit y
private real tx //target x
private real ty //target y
private real a //angle
private real bs //base speed
private real dpi//distance per interval/TICK
private real md //mas distance
private static thistype data
private static method GetDPI takes nothing returns real
set data.dpi = data.bs/MOVE_SPEED_SCALE
return data.dpi
endmethod
private static method Loop takes nothing returns nothing
local integer i = 1
loop
exitwhen i > TOTAL
if data.md > 0.00 then
set data.ux = (data.ux + data.dpi * Cos(data.a))
set data.uy = (data.uy + data.dpi * Sin(data.a))
set data.md = data.md - data.dpi
else
set MOVE_ARRAY[i] = MOVE_ARRAY[TOTAL]
set TOTAL = TOTAL - 1
set i = i - 1
call data.destroy()
if TOTAL == 0 then
call PauseTimer(MOVE_TIMER)
endif
endloop
endmethod
static method create takes unit u, real md, real bs, real a returns thistype
set TOTAL = TOTAL + 1
set data.allocate()
set data.u = u
set data.md = md
set data.bs = bs
set data.a = (a*bj_DEGTORAD)
set data.dpi = GetDPI()
if TOTAL == 1 then
call TimerStart( MOVE_TIMER, TICK, true, function Move.Loop)
endif
return data
endmethod
endstruct
endlibrary
loop
exitwhen i > TOTAL
//add this line
set data = MOVE_ARRAY[i]
if data.md > 0.00 then
set data.ux = (data.ux + data.dpi * Cos(data.a))
set data.uy = (data.uy + data.dpi * Sin(data.a))
set data.md = data.md - data.dpi
else
set MOVE_ARRAY[i] = MOVE_ARRAY[TOTAL]
set TOTAL = TOTAL - 1
set i = i - 1
call data.destroy()
//put endif here....
if TOTAL == 0 then
call PauseTimer(MOVE_TIMER)
endif
//add this here
set i = i + 1
endloop
static method create
//add this line
set MOVE_ARRAY[TOTAL] = data
It works now thanks. Ima test it out. Sorry for not seeing that endif. By the way I was wondering what the integer i was for.
yeah, you dont move the unit... ^_^
the i is used as a loop index like how GUI uses Integer A... at the end of each loop we increase i by 1 to move to the next index... and then when i becomes > TOTAL, the loop stops...
rather than doing this every loop
data.dpi * Cos(data.a)
just save it in a struct member at the create method...
Ok do I put the
MOVE_ARRAY[TOTAL] = data before or after the TOTAL = TOTAL + 1
Ok what I did was put I put it after the TOTAL = TOTAL +1
Then what happened was when I put
MOVE_ARRAY[TOTAL] = data
It didn't move and my other system the attack system that calls the Move.create() function didn't fire as well.
then I did
data = MOVE_ARRAY[TOTAL]
It didn't move but the attack system worked.
lol more bugs. Ima try renaming the thistypes for the structs.
EDIT: Also on the data = MOVE_ARRAY[TOTAL] I notice that it moves a little but I don't think it loops and it still overwrites the move. T.T
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Move System v.0.1 by neku99
//
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// A simple Move System for my map. Enables you to move/dash units and also pause them at will
// (some features are not yet implemented
//==================================================
// Speed Conversions
//==================================================
// I use this conversions to calculate speed
//
// 1 second = 1 meter
// 1 second = 50 units
// 0.01 second = 0.5 units
// So no distance per interval is calcualted:
//
// BASESPEED / SPEEDSCALE = distance per interval
//
// 522 / 100 = 5.22
//
//==================================================
// Configurables
//==================================================
// -speed
// -more to come
//
//==================================================
// Globals
//==================================================
//
//
//
//==================================================
// Parameters and Usage
//==================================================
// You can simply use damage with one function call:
//
// call Damage.create( PARAMETERS )
//
// Here are the parameters on their proper order
// (Parameters with the prefix "!" are not yet implemented)
//
// unit u = the unit to be moved
// real x = the x coordinate of the unit
// real y = the y coordinate of the unit
// real bs = the base speed of the move (used to determine distance per interval)
// real ss = the speed scale of the move (used to determine distance per interval)
//
//END+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
library MoveEngine
globals
private constant real MOVE_SPEED_SCALE = 100
private constant real TICK = 0.01
private timer MOVE_TIMER = CreateTimer()
private integer TOTAL = 0
private integer array MOVE_ARRAY[8190]
endglobals
struct Move
private unit u //unit to be moved
private real ux //unit x
private real uy //unit y
private real tx //target x
private real ty //target y
private real a //angle
private real bs //base speed
private real dpi//distance per interval/TICK
private real md //mas distance
private static thistype data
private static method GetDPI takes nothing returns real
set data.dpi = data.bs/MOVE_SPEED_SCALE
return data.dpi
endmethod
private static method Loop takes nothing returns nothing
local integer i = 1
loop
exitwhen i > TOTAL
set data = MOVE_ARRAY[i]
if data.md > 0.00 then
call SetUnitX( data.u, data.ux)
call SetUnitY( data.u, data.uy)
set data.md = data.md - data.dpi
else
set MOVE_ARRAY[i] = MOVE_ARRAY[TOTAL]
set TOTAL = TOTAL - 1
set i = i - 1
call data.destroy()
endif
if TOTAL == 0 then
call PauseTimer(MOVE_TIMER)
endif
set i = i + 1
endloop
endmethod
static method create takes unit u, real md, real bs, real a returns thistype
set TOTAL = TOTAL + 1
set data = allocate()
set data.u = u
set data.md = md
set data.bs = bs
set data.a = (a*bj_DEGTORAD)
set data.dpi = GetDPI()
set data.ux = (GetUnitX(data.u) + data.dpi * Cos(data.a))
set data.uy = (GetUnitY(data.u) + data.dpi * Sin(data.a))
set MOVE_ARRAY[TOTAL] = data
if TOTAL == 1 then
call TimerStart( MOVE_TIMER, TICK, true, function Move.Loop)
endif
return data
endmethod
endstruct
endlibrary
//on the create trigger change this
set data.ux = (GetUnitX(data.u) + data.dpi * Cos(data.a))
set data.uy = (GetUnitY(data.u) + data.dpi * Sin(data.a))
//to this
set data.ux = data.dpi * Cos(data.a)
set data.uy = data.dpi * Sin(data.a)
//then on the loop change this
call SetUnitX( data.u, data.ux)
call SetUnitY( data.u, data.uy)
//to this:
call SetUnitX( data.u, GetUnitX(data.u) + data.ux)
call SetUnitY( data.u, GetUnitY(data.u) + data.uy)
Yeah I kinda figured that part was a bit funny looking XD thanks!
And I guess the map bounds thing was what you where talking about when you told me about dash spells. It's so that units don't go out of map bounds? Right?
Dang still can't rep you T.T
So I just need to set the MaxX and MaxY to the map bounds? and check if the unit's x and y are equal to it then I just stop the move?
And if you put like Library blaha initializer init
does the init part run automatically?
can yah explain how the map bound check goes >.>
EDIT: I get it now if the unit is within the values of MIN and MAX I should stop it right?
set TempD = GetUnitX(data.u) + data.ux
if MinX <= TempD and TempD <= MaxX then
call SetUnitX( data.u, TempD)
endif
set TempD = GetUnitY(data.u) + data.uy
if MinY <= TempD and TempD <= MaxY then
call SetUnitY( data.u, TempD)
endif