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

[JASS] Detect which region the point is in

Status
Not open for further replies.
Level 10
Joined
Mar 31, 2009
Messages
732
[Solved] Region looping; [Unsolved] Triggering ability cooldown

Say I have a point (target of where an ability is being cast).
On the map, I have a bunch of regions laid out in a grid, so the ability is supposed to be targetted into one of these regions.

How can I work out which one of the regions the ability was cast to?
I can't really think of a better way to do this than using regions anyway, because the idea is to have the unit cast the ability at the center of the region, not the targetted point.
 
Last edited:
Level 10
Joined
Mar 31, 2009
Messages
732
Maybe. Too many regions to loop through them all, and wouldn't have a clue where to start for doing a binary tree type search in JASS.

However, I thought of another way to do what I wanted without needing find the center of the regions; if it doesn't work out I'll have to fall back on this.
 
Level 40
Joined
Dec 14, 2005
Messages
10,532
Just have every square contain, say, 16 smaller ones.

Also, for a binary tree, an element at position n has children at 2n and 2n+1 if you want to store the information in an array.

Also, if your arrays are in a regular grid, then this is pretty easy. In fact, you don't even need rects if so.
 
Level 8
Joined
Feb 15, 2009
Messages
463
u can detect it when using rects with :
1.
JASS:
function RectContainsCoords takes rect r, real x, real y returns boolean

2.
JASS:
function RectContainsLoc takes rect r, location loc returns boolean
    return RectContainsCoords(r, GetLocationX(loc), GetLocationY(loc))
endfunction
 
Level 10
Joined
Mar 31, 2009
Messages
732
Okay, I have another unrelated problem now. Since its for the same project, I'll just reuse this thread.

I have an ability to move a unit, and its supposed to have a thirty second cooldown.
If the trigger decides that the unit can't be moved to where you want it, then the cooldown still applies.
If the trigger decides that the unit can be moved, then the cooldown is reset when the trigger hits the "Unit - Move" statement.

The first one can be fixed with a Unit - Reset Ability Cooldowns trigger, only this will reset them all... what if I want to keep the other abilities on cooldown?
But the second one.. I don't see a trigger action to put an ability on cooldown :(

And yes, I wound up doing this whole movement trigger in GUI, because with all the angle and distance calculations, I didn't want my eyes to bleed looking at jass.
 
Level 3
Joined
Apr 1, 2005
Messages
53
I don't think there is a way to apply the cooldown to only one ability. Maybe you could remove and add the abilities that should not have the cooldown?
 
Level 10
Joined
Mar 31, 2009
Messages
732
PurplePoot, do you mean my Move Unit statement, or my clunky target calculation?

Edit: On a similiar note, is there a way to make two abilities have a global cooldown? Like say ability a has a cooldown of 10 seconds, and ability b has a cooldown of 25 seconds.. when I use one then the other should be locked out for five seconds.
The idea of removing the ability would work, but.. I don't think it would really look very good :(
 
Level 12
Joined
Apr 15, 2008
Messages
1,063
You propably have "unit starts cansting an ability" as your trigger's effect. If you move the unit in such trigger, it won't even cast the spell, therefor the spell won't be on cooldown.

My suggestion:
2 triggers
1. detects the unit is issued order (order to cast your ability)
->if it is supposed to move, turn on second trigger and store the targeted position.
->if not, pause+unpause it (it will prevent the unit from casting the ability and setting it on cooldown)
2. trigger defaultly turned off
when the unit finishes casting the ability, move it to previously stored location (you can't detect the location now (due to the effect - finishes casting doesn't give the ability target), and it would be ineffective to run the location test two times)

Btw. if you have a checkers board, you don't need regions for each square, just make a big one around the whole board. Then, simply calculate which square you are in (you know coordinates where the board is located (from the big region) and width of one square (width of region/amount of squares)
 
Level 10
Joined
Mar 31, 2009
Messages
732
Yeah, I ended up doing something like that. Not quite that, but I placed a piece on the editor, and every move command either goes 384 horizontally/vertically, or 543 for diagonal.

And yeah I do have Unit starts casting an ability. Ill try out your trigger suggestion tomorrow. Thanks for that.
 
Level 40
Joined
Dec 14, 2005
Messages
10,532
PurplePoot, do you mean my Move Unit statement, or my clunky target calculation?

Edit: On a similiar note, is there a way to make two abilities have a global cooldown? Like say ability a has a cooldown of 10 seconds, and ability b has a cooldown of 25 seconds.. when I use one then the other should be locked out for five seconds.
The idea of removing the ability would work, but.. I don't think it would really look very good :(
Techtree requirements with an invisible unit.

And yeah I do have Unit starts casting an ability. Ill try out your trigger suggestion tomorrow. Thanks for that.
Skip that suggestion (it's overcomplicated).

JASS:
native SetUnitX takes unit whichUnit, real newX returns nothing
native SetUnitY takes unit whichUnit, real newY returns nothing

do not interrupt orders.
 
Level 10
Joined
Mar 31, 2009
Messages
732
native SetUnitX takes unit whichUnit, real newX returns nothing
I'll give that a shot later today, is there a function like it to set the facing angle which wont interrupt the order either?


Ideally I wanted the pieces to actually walk to the target location, not be simply moved. I couldn't figure out a way to give them the ability to walk without giving the player the ability to move them wherever they wanted as well.
If I set the property of the unit - movement type to none, I can't find a trigger that will enable/disable it as required (not to mention the player would be able to move it while its on its order anyway).


Edit: Okay, just been trying out some of your suggestions.

SetUnitX() seemed to only move my units selection circle, while the unit stayed where it was :cute:
SetUnitPosition() did the trick.

Here is my code at the moment:
JASS:
function Trig_Move_Actions takes nothing returns nothing
    local unit caster = GetTriggerUnit()
    local location targetPoint = GetSpellTargetLoc()
    local real targetAngle = AngleBetweenPoints(GetUnitLoc(caster), targetPoint)
    local real targetDistance = DistanceBetweenPoints(GetUnitLoc(caster), targetPoint)
    local real targetFacing

...

    if (targetAngle < 0) then
        set targetAngle = targetAngle + 360
    endif
    set targetAngle = I2R(R2I((targetAngle / 45) + 0.5)) * 45
    set targetFacing = I2R(R2I(targetAngle / 90)) * 90
    set targetDistance = Calc_Move_Distance(targetAngle, targetDistance, targetFacing)
// Calc_Move_Distance calculates the distance to the targetted square

...

if ({checks if the target square has a unit in it already, or if the target position is not on the board}) then
        call DisplayTimedTextToPlayer(GetOwningPlayer(caster), 0, 0, 5.00, "You cannot move there")
        call PauseUnit(caster, true)
        call PauseUnit(caster, false)
    else
        call SetUnitPosition(caster, GetLocationX(targetPoint), GetLocationY(targetPoint))
        call SetUnitFacing(caster, targetFacing)
    endif
    set caster = null
    set targetPoint = null
endfunction

...

call TriggerRegisterAnyUnitEventBJ( gg_trg_Move, EVENT_PLAYER_UNIT_SPELL_CAST )
First off, the event. When I tried "Generic unit event - a unit is issued an order targeting a point", the trigger never fired.
Second,
JASS:
call PauseUnit(caster, true); call PauseUnit(caster, false)
seems to throw the trigger into an infinite loop. My guess is I need to throw a wait in there or something.
Third, something with this part:
JASS:
        call SetUnitPosition(caster, GetLocationX(targetPoint), GetLocationY(targetPoint))
        call SetUnitFacing(caster, targetFacing)
The unit's facing doesn't update until after it is moved again. While this could be solved by just changing its facing first, what if I don't want to move the piece at all, and just want to rotate it?

Solved with "EVENT_PLAYER_UNIT_SPELL_EFFECT".
 
Last edited:
Level 10
Joined
Mar 31, 2009
Messages
732
Not entirely sure what you mean there, but it sounds like something that would only work if those triggers were for one unit?

Anyway, I've uploaded my map. If you can suggest a way for me to have the units walk to their destination instead of being moved, without giving the player any control over there the unit will be moved to, it would be very appreciated.

Things I've thought of so far:
- Changing control to the computer, moving it, then changing control back
I'd have to have a trigger for when the unit arrives at the destination, and how would I store who the player was who had control before, while keeping it MUI?
- Moving it instantly, and adding some kind of movement trail behind it.
Wouldn't know where to start o_O
- Changing the movement speed with triggers, giving it an order, then setting the speed back to zero again.
Trouble is, the controller gets given the move/hold position/stop buttons.
 
Last edited:
Level 9
Joined
Mar 25, 2005
Messages
252
The natives take radians.

From Common.j:
JASS:
//============================================================================
// MathAPI
native Deg2Rad  takes real degrees returns real
native Rad2Deg  takes real radians returns real

native Sin      takes real radians returns real
native Cos      takes real radians returns real
native Tan      takes real radians returns real

// Expect values between -1 and 1...returns 0 for invalid input
native Asin     takes real y returns real
native Acos     takes real x returns real

native Atan     takes real x returns real

// Returns 0 if x and y are both 0
native Atan2    takes real y, real x returns real

If you want to use degrees, you can use the stuff in Blizzard.j:
JASS:
//===========================================================================
function SinBJ takes real degrees returns real
    return Sin(degrees * bj_DEGTORAD)
endfunction

//===========================================================================
function CosBJ takes real degrees returns real
    return Cos(degrees * bj_DEGTORAD)
endfunction

//===========================================================================
function TanBJ takes real degrees returns real
    return Tan(degrees * bj_DEGTORAD)
endfunction

//===========================================================================
function AsinBJ takes real degrees returns real
    return Asin(degrees) * bj_RADTODEG
endfunction

//===========================================================================
function AcosBJ takes real degrees returns real
    return Acos(degrees) * bj_RADTODEG
endfunction

//===========================================================================
function AtanBJ takes real degrees returns real
    return Atan(degrees) * bj_RADTODEG
endfunction

//===========================================================================
function Atan2BJ takes real y, real x returns real
    return Atan2(y, x) * bj_RADTODEG
endfunction
 
Status
Not open for further replies.
Top