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

Could someone help me write a hook for this?

Status
Not open for further replies.
Level 15
Joined
Nov 30, 2007
Messages
1,202
I have a simple method that returns the closest city from a given unit (200 distance), which is necessary to detect which region the unit entered/exited. The city x and y coordinates obviously never change but the unit x and y can be anything (within 200 range currently).

I'm thinking it should be possible to truncate the input x and y coordinates in such a way that we get the apropriate city from the cache rather than having to iterate through all cities each time, as there is nothing close that could conflict. The problem is, I'm not sure how to write it. Any ideas?

JASS:
        private static method getCity takes real x, real y returns thistype
            local thistype this = 1
            local real dx
            local real dy
            local integer end = count + 1
            loop
                exitwhen this == end // loops through all allocated instances
                set dx = this.x - x
                set dy = this.y - y
                if dx*dx + dy*dy < EVENT_MIN_DISTANCE then
                    // Save coordinate somehow
                    return this
                endif
                set this = this + 1
            endloop
            return 0
        endmethod

        private static method onEnter takes nothing returns boolean
            local unit u = GetTriggerUnit()
            local thistype this = getCity(GetUnitX(u), GetUnitY(u))
debug        if this != 0 then
                call this.changeOwner(GetOwningPlayer(u))
debug         else
debug             call BJDebugMsg("ERROR: [thistype.onEnter] failed to find nearby city.")
debug        endif
            set u = null
            return false
        endmethod

I'm thinking if i divide the coordinate with a constant and then multiply it with the same constant (example 300) it will be the same x and y coordinate for all values within a given range. Will try this later. ... Something like this:

JASS:
// Save on allocation

set ta[R2I(this.x/200)].integer[R2I(this.y/200)] = this


static method find takes real x, real y return thistype 
    return ta[R2I(x/200)].integer[R2I(y/200)]
endmethod

Haven't tested the above yet.
 
Last edited:
Level 15
Joined
Nov 30, 2007
Messages
1,202
The city unit could maybe be mapped by using the region handle? And when a unit enters a region, the region handle id is used as key to access the city.
I thought so first but you can't get the triggering region. But the last snippet worked, given that no city is within the same range as another city.

JASS:
private static method find takes real x, real y returns thistype  
            return hash[R2I(x/MIN_DISTANCE)][R2I(y/MIN_DISTANCE)]    // Load approximate city coordinate
        endmethod
 
Status
Not open for further replies.
Top