• 🏆 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!
  • 🏆 Hive's 6th HD Modeling Contest: Mechanical is now open! Design and model a mechanical creature, mechanized animal, a futuristic robotic being, or anything else your imagination can tinker with! 📅 Submissions close on June 30, 2024. Don't miss this opportunity to let your creativity shine! Enter now and show us your mechanical masterpiece! 🔗 Click here to enter!

Closest Building Passing Filter

Status
Not open for further replies.
Level 15
Joined
Nov 30, 2007
Messages
1,202
I need to find the closest building (within a certain range) passing a certain condition. Do I just use http://www.hiveworkshop.com/forums/jass-resources-412/snippet-getclosestunit-s-59254/ and grab the first closest building, check it, if unsuccessful remove it from group and find the next closest building by iterating the remaining group, the process repeats until all buildings have been checked or something was found?

Or do I pick them, and then sort them and return them through a struct? And then loop through the buildings that now are in order. If the second option how the hell would one do that? :p
 
Level 12
Joined
Feb 22, 2010
Messages
1,115
In that library all functions already have boolexpr parameter, you just use that to pass your conditions.
 
Level 15
Joined
Nov 30, 2007
Messages
1,202
In that library all functions already have boolexpr parameter, you just use that to pass your conditions.

I need to compare a loaded real values (the unit which is at the center and the found unit) the distance should be smaller then the loaded value of the closest unit.

All buildings will have their pathing size stored as 4x4 6x6 or 8x8, if the center building is 4x4 the following required maximum distances:
Center_Found__Max Distance
4x4 - - - 4x4 - - - 200 (192)
4x4 - - - 6x6 - - - 230 (226)
4x4 - - - 8x8 - - - 280 (272)

Any buildings beyond that range is ignored.

Come to think of it, there is no need to find the closest building although I would like to find all buildings within the above requirements so I can do with them what I please. Which is basically do some sort of damage or chance of spreading fire based on the distance and the resistance of found building.
 
Level 12
Joined
Feb 22, 2010
Messages
1,115
I see your edit now, so you just need buildings within range in same group.Do buildings in the group needs to be sorted from closest to farthest?
 
Last edited:
Level 15
Joined
Nov 30, 2007
Messages
1,202
The problem is more about the actual data storage and detection of the buildings, gonna take a break. But got this far:

JASS:
scope Fire initializer Init
    globals
        private hashtable hash = InitHashtable()
        private group groupFound = CreateGroup()
        private constant integer X2 = 0
        private constant integer X4 = 1
        private constant integer X6 = 2
        private constant integer X8 = 3
        private constant integer SYSTEM_ID = 1
        PathingRange array pathing 
    endglobals
    
    private function SaveSpreadRange takes integer uType, integer dimension returns nothing
        call SaveInteger(hash, uType, SYSTEM_ID, dimension)
    endfunction
    
    struct PathingRange 
        integer x2
        integer x4
        integer x6
        integer x8
        
        static method create takes integer d2, integer d4, integer d6, integer d8 returns PathingRange
            local thistype t = .allocate()
            set t.x2 = d2
            set t.x4 = d4
            set t.x6 = d6
            set t.x8 = d8
            return t
        endmethod
    endstruct
    
    private function BuildingFilter takes nothing returns boolean
        return true 
    endfunction 
    
    private function FindNearbyBuildings takes unit u1 returns nothing
        local integer dimension = LoadInteger(hash, GetUnitTypeId(u1), SYSTEM_ID)
        local group g = CreateGroup()
        local unit u2
        call GroupEnumUnitsInRange(g, GetUnitX(u1) , GetUnitY(u1), pathing[dimension].x8, function BuildingFilter)
        loop
            set u2 = FirstOfGroup(g)
            exitwhen u2 == null
            // Load it here.... At a loss but need to rest.. ;d
            call GroupAddUnit(groupFound, u2)    // Found Burnable Buildings
        endloop
        call DestroyGroup(g)
    endfunction
    
    private function Init takes nothing returns nothing
        set pathing[X4] = PathingRange.create(0, 192, 226, 272)
        call SaveSpreadRange(FARM, X4)
    endfunction
endscope

I see your edit now, so you just need buildings within range in same group.Do buildings in the group needs to be sorted from closest to farthest?

I think the best is to find all buildings in burnable range. In above example pathing[X4] is a range setup for all buildings identified as 4x4 and below we save farm as a 4x4 building. Then the idea is to load this identifier in the GroupEnum, so if u1 is 4x4 and the found building is 4x4 it should be compared to .x4
 
Last edited:
Level 12
Joined
Feb 22, 2010
Messages
1,115
I hope I understood your system correctly.
JASS:
scope Fire initializer Init
    globals
        private hashtable hash = InitHashtable()
        private group groupFound = CreateGroup()
        private constant integer X2 = 0
        private constant integer X4 = 4
        private constant integer X6 = 6
        private constant integer X8 = 8
        private constant integer SYSTEM_ID = 1
        PathingRange array pg 
        private PathingRange temppg
        private real TempReal1
        private real TempReal2
    endglobals
    
    private function SaveSpreadRange takes integer uType, integer dimension_2D returns nothing
        call SaveInteger(hash, uType, SYSTEM_ID, dimension_2D)
    endfunction

    private function LoadSpreadRange takes integer uType, returns integer
        return LoadInteger(hash, uType, SYSTEM_ID)
    endfunction
    
    struct PathingRange 
        integer array x[8]
        
        static method create takes integer d2, integer d4, integer d6, integer d8 returns PathingRange
            local thistype t = .allocate()
            set t.x[2] = d2 // max range to ???
            set t.x[4] = d4 // max range to 4x4
            set t.x[6] = d6 // max range to 6x6
            set t.x[8] = d8 // max range to 8x8
            return t
        endmethod
    endstruct
    
    private function BuildingFilter takes nothing returns boolean
        return IsUnitInRangeXY(GetFilterUnit(), TempReal1, TempReal2, temppg.x[LoadSpreadRange(GetUnitTypeId(GetFilterUnit()))]) // and alive structure
    endfunction 
    
    private function FindNearbyBuildings takes integer uType, real x, real y, returns nothing
        local group g = CreateGroup()
        local unit u
        set temppg = pg[LoadSpreadRange(uType)]
        set TempReal1 = x
        set TempReal2 = y
        call GroupEnumUnitsInRange(g, x , y, radius, function BuildingFilter)
        // now group g must be consists of buildings in range



    endfunction
    
    private function Init takes nothing returns nothing
        set pg[X4] = PathingRange.create(0, 192, 226, 272)
        call SaveSpreadRange(FARM, X4)
    endfunction
endscope

Also just realized array size should be 9 since first index is 0.
 
Last edited:
Level 15
Joined
Nov 30, 2007
Messages
1,202
I hope I understood your system correctly.

Yes you did. THANK YOU! :D

*Bump: Now I just need some suggestions on how the fire should spread to nearby buildings. Should it do equal damage to all nearby buildings and after a certain threshold is reached a fire spawns on that building?

I want to have a random based chance to catch fire based on fire damage taken and fire resistance. But I also want to limit the spread. So if 8 buildings are nearby all nearby shouldn't start at the same time... hm... So how to spread around the fire-damage to the above found buildings?

Also, should the fire be endless or have a limit? Like the mother fire can target (spawn to) 3, her spawn can target 2, their spawn can target 1 and their spawn can target 0. Once the mother fire destroys a target it can then proceed targeting a new nearby building.
 
Last edited:
Level 12
Joined
Feb 22, 2010
Messages
1,115
Maybe instead of a "mother fire" kind of thing, use levels for fire.Lets say there are 3 levels.

Level 1
-Default fire start level
-Becomes level 2 fire after x seconds
-Can not spread nearby
-Nothing happens if a level 1 fire kills a building

Level 2
-Can spread fire nearby with a low chance
-If building gets killed by a level 2 fire, it has a low/medium chance to spread level 1 fire to nearby buildings
-Becomes level 3 after y seconds

Level 3
-Can spread fire nearby with a medium chance
-If building gets killed by a level 3 fire, it has a medium/high chance to spread level 1 fire to nearby buildings
 
Status
Not open for further replies.
Top