• 🏆 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] Trigger to create a square pattern, but something is wrong :S

Status
Not open for further replies.
Level 4
Joined
Jan 29, 2007
Messages
98
Hi !

Ok, so I'm trying to create a pattern on the terrain on Map Init using special effects created a set range between eachother, with columns and rows...

Ok, so this is only supposed to create the vertical stuff atm, but something is wrong XD

It only creates one single "row" with the first big loop (But I'd believe it still puts the right amount of SFXs in those 24 lines, meaning that it isn't changing row...), and then it creates some random pattern with the other big loop (They cross the SFXs from the first loop sometimer, horizontally I mean, and create crosses and stuff)

Any ideas on why this is happening ? :S

JASS:
scope BorderInit initializer Init

    globals
        private constant integer COLUMNS = 12
        private constant integer ROWS = 12
        
        private constant integer BORDER_RES = 15          // How many effect the border for each square will consist of !
        private constant real SQUARE_HEIGHT = 480.
        private constant real SQUARE_WIDTH = 480.
        private constant real SQUARE_HD = SQUARE_HEIGHT / BORDER_RES
        private constant real SQUARE_WD = SQUARE_WIDTH / BORDER_RES
        
        private constant string SFX_PATH = "Abilities\\Weapons\\SpiritOfVengeanceMissile\\SpiritOfVengeanceMissile.mdl"
    endglobals
    
    globals
        //private effect array Border_SFX
    endglobals

    private function Init takes nothing returns nothing
        local integer r = 0
        local integer c
        local real x = 0
        local real y = 0
        
        local integer i = 0
        
        loop
            exitwhen i >= 12
            call FogModifierStart( CreateFogModifierRect( Player( i ), FOG_OF_WAR_VISIBLE, bj_mapInitialPlayableArea, true, true ) )
            
            set i = i + 1
        endloop
        
        loop
            exitwhen r >= ROWS
            set c = 0
            
            loop
                exitwhen c >= COLUMNS
                set y = r * SQUARE_HD
                set x = c * SQUARE_WIDTH
                
                loop
                    exitwhen y >= ( r * SQUARE_HD ) + SQUARE_HEIGHT
                    call AddSpecialEffect( SFX_PATH, x, y )
                    
                    set y = y + SQUARE_HD
                endloop
                
                set c = c + 1
            endloop
            
            set c = 1
            
            loop
                exitwhen c > COLUMNS
                set y = r * ( -( SQUARE_HD ) )
                set x = c * ( -SQUARE_WIDTH )
                
                loop
                    exitwhen y <= ( -( r * SQUARE_HD ) ) - SQUARE_HEIGHT
                    call AddSpecialEffect( SFX_PATH, x, y )
                    
                    set y = y - ( SQUARE_HD )
                endloop
                
                set c = c + 1
            endloop
            
            set r = r + 1
        endloop
        
        set r = 0
        set c = 0
        
        loop
            exitwhen c >= COLUMNS
            set r = 0
            
            loop
                exitwhen r >= ROWS
                set x = c * SQUARE_WD
                set y = r * SQUARE_HEIGHT
                
                loop
                    exitwhen x >= ( c * SQUARE_WD ) + SQUARE_WIDTH
                    call AddSpecialEffect( SFX_PATH, x, y )
                    
                    set x = x + SQUARE_WD
                endloop
                
                set r = r + 1
            endloop
            
            set r = 1
            
            loop
                exitwhen r > ROWS
                set x = c * ( -( SQUARE_WD ) )
                set y = r * ( -SQUARE_HEIGHT )
                
                loop
                    exitwhen x <= ( -( c * SQUARE_WD ) ) - SQUARE_WIDTH
                    call AddSpecialEffect( SFX_PATH, x, y )
                    
                    set x = x - ( SQUARE_WD )
                endloop
                
                set r = r + 1
            endloop
            
            set c = c + 1
        endloop
        
    endfunction

endscope
 
Level 18
Joined
Jan 21, 2006
Messages
2,552
You seem to have way too many calculations for something as simple as you're doing. Why do you have 4 loops inside another loop, this is completely unnecessary.

What "pattern" are you trying to display? A filled in square? You haven't told us much other than there is some mysterious pattern and this function only does the vertical of the pattern. I don't really know what you mean so I copied it into a blank map and tested it out.

It seems to make 2 "boxes" in the middle of the map and then random lines (both vertical and horizontal) running north/south/west/east of the 2 central boxes.
 
Level 4
Joined
Jan 29, 2007
Messages
98
In trying to display something like this:
117855-bigthumbnail.jpg


(Though not "filled-in" black squares...)

It's almost like a Chess table, but only the borders ;)
 
Level 18
Joined
Jan 21, 2006
Messages
2,552
Oh I see. Well in that case you still shouldn't need so many loops, I see how you're breaking it up into quadrants but its really not necessary. The starting point will just be:

JASS:
posx = centerx - (width/2.0)
posy = centery + (height/2.0)

From here you'll do a loop (for columnCount + 1) to create the vertical lines (at an offset from "posx" and "posy"). The reason you're adding one to the columnCount is because you have to fill in the right-side of the box. Once you've looped through the columns, loop through the rows and do the exact same thing.

This is something I just made now quickly, so I'm not sure if it works correctly but it compiles. You can see the math behind it too.

JASS:
scope ChessBorders initializer init
//**********************
//* Config
//*
globals 
    constant real           boxCenterX  = 0
    constant real           boxCenterY  = 0
    
    constant real           boxWidth    = 1000
    constant real           boxHeight   = 1000
    
    constant real           boxColumns  = 5
    constant real           boxRows     = 5

    constant integer        perLine     = 50
    constant string         modelPath   = ""
    
endglobals



public function init takes nothing returns nothing
    local real posx
    local real posy
    local real x
    local real y
    
    local integer ic
    local integer ir
    
    set posx = boxCenterX - (boxWidth/2)
    set posy = boxCenterY + (boxHeight/2)
    
    set ic = 0
    loop
        exitwhen (ic == boxColumns+1)
        
        set x = posx + (ic * (boxWidth/boxColumns))
        set y = posy
        
        set ir = 0
        loop
            exitwhen (ir == perLine)
        
            set y = (posy - (ir * (boxHeight/perLine)))
            
            call AddSpecialEffect(modelPath, x, y)             // add the special effect at (x, y) 
        
            set ir = ir + 1
        endloop
        
        set ic = ic + 1
    endloop

    set ir = 0
    loop
        exitwhen (ir == boxRows+1)
        
        set x = posx
        set y = posy + (ir * (boxHeight/boxRows))
        
        set ic = 0
        loop
            exitwhen (ic == perLine)
            
            set x = (x + (ic * (boxWidth/perLine)))
            
            call AddSpecialEffect(modelPath, x, y)
            
            set ic = ic + 1
        endloop
        
        set ir = ir + 1
    endloop
            
endfunction
endscope
 
Last edited:
Level 37
Joined
Mar 6, 2006
Messages
9,240
Here's the thing in GUI. Maybe it helps you with the JASS thing.

You can define the size of the grid (YxY) at map initialization trigger.

Press ESC to create the terrain from position of the unit. You can change the center location from the position of the unit to center of the region in there.

When you use the unit to create the terrain, the offset seems wrong because tiles can't be placed freely. Use the center of region to see that the offset calculation is correct.

  • Checkerboard
    • Events
      • Player - Player 1 (Red) skips a cinematic sequence
    • Conditions
    • Actions
      • Set Temp_Integer_1 = 2
      • Set Temp_Loc_1 = (Position of Temp_Unit_1) // enable either this
      • Set Temp_Loc_1 = (Center of Region 000 <gen>) // or this
      • -------- ------------------------- --------
      • -------- Terrain changing system --------
      • -------- ------------------------- --------
      • Set Temp_Loc_2 = (Temp_Loc_1 offset by ((((Real(GridSize)) - 1.00) x 0.50) x (Square root((2.00 x (Power(128.00, 2.00)))))) towards 225.00 degrees)
      • For each (Integer A) from 1 to GridSize, do (Actions)
        • Loop - Actions
          • Set Temp_Loc_3 = (Temp_Loc_2 offset by ((Real(((Integer A) - 1))) x 128.00) towards 90.00 degrees)
          • For each (Integer B) from 1 to GridSize, do (Actions)
            • Loop - Actions
              • Set Temp_Loc_4 = (Temp_Loc_3 offset by ((Real(((Integer B) - 1))) x 128.00) towards 0.00 degrees)
              • Wait 0.00 seconds
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • Temp_Integer_1 Equal to 1
                • Then - Actions
                  • Environment - Change terrain type at Temp_Loc_4 to CI_Terrain_Types[0] using variation -1 in an area of size 1 and shape Square
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • (GridSize mod 2) Equal to 0
                      • ((Integer A) mod 2) Equal to 1
                      • (Integer B) Equal to GridSize
                    • Then - Actions
                      • Set Temp_Integer_1 = 1
                    • Else - Actions
                      • Set Temp_Integer_1 = 2
                • Else - Actions
                  • Environment - Change terrain type at Temp_Loc_4 to CI_Terrain_Types[1] using variation -1 in an area of size 1 and shape Square
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • (GridSize mod 2) Equal to 0
                      • ((Integer A) mod 2) Equal to 0
                      • (Integer B) Equal to GridSize
                    • Then - Actions
                      • Set Temp_Integer_1 = 2
                    • Else - Actions
                      • Set Temp_Integer_1 = 1
              • Custom script: call RemoveLocation(udg_Temp_Loc_4)
          • Custom script: call RemoveLocation(udg_Temp_Loc_3)
      • Custom script: call RemoveLocation(udg_Temp_Loc_1)
      • Custom script: call RemoveLocation(udg_Temp_Loc_2)
 

Attachments

  • Checkerboard.w3x
    18.2 KB · Views: 42
Level 18
Joined
Jan 21, 2006
Messages
2,552
I typed that up on the forum, so obviously I didn't test it. I even stated that I don't know if it works correctly, but the logic is all here (which was the point). I'm not just going to fall over and do everything for you. Christ. When people want help nowadays they just want other people to do the shit for them.



Is this the effect you wanted? This is the same code I posted without any careless errors (it took me 3-seconds to fix, so you obviously just discarded it when it didn't work perfectly for you). As you can see (next screen-shot) it is very dynamic, allowing you to easily change the columns, rows, width, height, and the center-position of the box.

 
Level 4
Joined
Jan 29, 2007
Messages
98
I typed that up on the forum, so obviously I didn't test it. I even stated that I don't know if it works correctly, but the logic is all here (which was the point). I'm not just going to fall over and do everything for you. Christ. When people want help nowadays they just want other people to do the shit for them.

What ?!
Are you kidding me ?!!

I'm the one asking for help here, and it's YOU who just gives me a code !
I asked "What's wrong with my code ?", not "My code doesn't work, give me a working one !"...

Please, don't think I'm the kind of person who just wants people to make stuff for me :D

Is this the effect you wanted?

Yeah ! :D

This is the same code I posted without any careless errors (it took me 3-seconds to fix, so you obviously just discarded it when it didn't work perfectly for you).

Yeah, I actually did "discard" your code without having a deeper look at it, but that's because I didn't want someone else's code, I just wanted to change my own...
But anyways, thanks for it and I might take a better look at it later, though I still want to know why this can't be done my way ? :S XD

As you can see (next screen-shot) it is very dynamic, allowing you to easily change the columns, rows, width, height, and the center-position of the box.

Nice ! :D
 
Level 18
Joined
Jan 21, 2006
Messages
2,552
Komaqtion said:
because I didn't want someone else's code

To be fair you wouldn't know it didn't work if you didn't try it out, and if you tried it out then you obviously weren't too specific about who's code you were using :p But that's behind the matter at hand.

The reason for me trying to give you a less complex answer is actually a lot more useful than you may think. If your code wasn't working then it could be as simple as a couple of "careless" errors, but the point is that you don't make "careless" errors when you simplify your logic and break it down as much as possible. It also makes these errors a lot easier to find.

If your code was necessary, then I would have tried to fix yours. However, I saw that you were making it a little too complex in your head so I thought it may be easier for you to see how to break it down further. Learning from example, basically.

Here's the code:
JASS:
scope ChessBorders initializer init
//**********************
//* Config
//*
globals
    constant real boxCenterX        = 0
    constant real boxCenterY        = 0

    constant real boxWidth          = 2000
    constant real boxHeight         = 2000

    constant real boxColumns        = 8
    constant real boxRows           = 8

    constant integer perLine        = 80
    constant string modelPath       = "Abilities\\Weapons\\SpiritOfVengeanceMissile\\SpiritOfVengeanceMissile.mdl"

endglobals



public function init takes nothing returns nothing
    local real posx
    local real posy
    local real x
    local real y

    local integer ic
    local integer ir

    set posx = boxCenterX - (boxWidth/2)
    set posy = boxCenterY + (boxHeight/2)

    set ic = 0
    loop
        exitwhen (ic == boxColumns+1)

        set x = posx + (ic * (boxWidth/boxColumns))
        set y = posy

        set ir = 0
        loop
            exitwhen (ir == perLine+1)

            set y = (posy - (ir * (boxHeight/perLine)))

            call AddSpecialEffect(modelPath, x, y) // add the special effect at (x, y)

            set ir = ir + 1
        endloop

        set ic = ic + 1
    endloop

    set ir = 0
    loop
        exitwhen (ir == boxRows+1)

        set x = posx
        set y = posy - (ir * (boxHeight/boxRows))

        set ic = 0
        loop
            exitwhen (ic == perLine+1)

            set x = (posx + (ic * (boxWidth/perLine)))

            call AddSpecialEffect(modelPath, x, y)

            set ic = ic + 1
        endloop

        set ir = ir + 1
    endloop

endfunction
endscope

This is what I used to display the boxes I showed screen-shots of. You can modify any of the values in the globals block to customize it to your liking. I believe a Chess Board is an 8×8 grid (meaning you'll want 8 rows/8 columns). The height and width simply define how many WarCraft units the box will span across.
 
Level 4
Joined
Jan 29, 2007
Messages
98
Ok ! Thanks ! ;)

This is what I have now, and it works great ! :D

Just a couple of thing I actually can't get working... (It's about changes I want to make, but can't seem to figure out how XD)

[jass="Code"]scope TerrainPattern initializer Create_Checked_Pattern

globals
private constant real CENTER_X = 0
private constant real CENTER_Y = 0

private constant real SQUARE_WIDTH = 8192.
private constant real SQUARE_HEIGHT = 8192.

private constant real COLUMNS = 12.
private constant real ROWS = 12.

private constant integer BORDER_RES = 65
private constant string SFX_PATH = "Abilities\\Spells\\Human\\SpellSteal\\SpellStealMissile.mdl"

endglobals



private function Create_Checked_Pattern takes nothing returns nothing
local real posx
local real posy
local real x
local real y

local integer ic
local integer ir

local integer i = 0

loop
exitwhen i >= 12
call FogModifierStart( CreateFogModifierRect( Player( i ), FOG_OF_WAR_VISIBLE, bj_mapInitialPlayableArea, true, true ) )

set i = i + 1
endloop

set posx = CENTER_X - ( SQUARE_WIDTH / 2 )
set posy = CENTER_Y + ( SQUARE_HEIGHT / 2 )
set ic = 0

loop
exitwhen ( ic == COLUMNS + 1 )

set x = posx + ( ic * ( SQUARE_WIDTH / COLUMNS ) )
set y = posy
set ir = 0

loop
exitwhen ( ir == BORDER_RES + 1 )

set y = ( posy - ( ir * ( SQUARE_HEIGHT / BORDER_RES ) ) )

call AddSpecialEffect( SFX_PATH, x, y )

set ir = ir + 1
endloop

set ic = ic + 1
endloop

set ir = 0

loop
exitwhen ( ir == ROWS + 1 )

set x = posx
set y = posy - ( ir * ( SQUARE_HEIGHT / ROWS ) )
set ic = 0

loop
exitwhen ( ic == BORDER_RES + 1 )

set x = ( posx + ( ic * ( SQUARE_WIDTH / BORDER_RES ) ) )

call AddSpecialEffect( SFX_PATH, x, y )

set ic = ic + 1
endloop

set ir = ir + 1
endloop

endfunction

endscope[/code]

Ok, so how would I go about changing so that SQUARE_HEIGHT/WIDTH determines the height and width of the individual squares, not the big one ? :S
And also, the "BORDER_RES" in this trigger ("perLine" in yours), can this be changed to determine the amount of effects (Per line) inside each square, instead of the big one ? :S

Oh, and now I also noticed that with my current settings, the corners of the squares (Or rather the crosses created, where they meet) doesn't seem to be "flowing into eachother" as I want them too XD (Sorry if you didn't understand that, but it was the best I could explain :p)

Here's a screenie ;)

namnlsei.jpg
 
Level 18
Joined
Jan 21, 2006
Messages
2,552
Well the "resolution" of each box is a derivative of the resolution of the larger box. For instance, if you want to have 10 effects per box and you have 10×10 boxes, then you'll know you need 100 per line to achieve the effect.

Its the same thing for "SQUARE_HEIGHT/WIDTH", if you have 10×10 squares, and you want them each to be 50×50 each, then you'll need your dimensions to be (10×50) × (10×50), or in other words: (500 × 500).

I can help you make it so that the configuration reverses this, but its always good to have your minor configuration constants derived from your major configuration constants.
 
Level 4
Joined
Jan 29, 2007
Messages
98
Ok, well I'll go with what you had ;)

Anyways, how would I go about creating rects inside all of these boxes that are created ? :eek:

Would something like this work ? :S

[jass="Code"]scope TerrainPattern initializer Create_Checked_Pattern

globals
private constant real CENTER_X = 0
private constant real CENTER_Y = 0

private constant real SQUARE_WIDTH = 8192.
private constant real SQUARE_HEIGHT = 8192.

private constant real COLUMNS = 12.
private constant real ROWS = 12.

private constant integer BORDER_RES = 120
private constant string SFX_PATH = "Abilities\\Spells\\Human\\SpellSteal\\SpellStealMissile.mdl"

endglobals

globals
private rect array Box
endglobals

private function Create_Checked_Pattern takes nothing returns nothing
local real posx
local real posy
local real x
local real y

local integer ic
local integer ir

local integer i = 0

loop
exitwhen i >= 12
call FogModifierStart( CreateFogModifierRect( Player( i ), FOG_OF_WAR_VISIBLE, bj_mapInitialPlayableArea, true, true ) )

set i = i + 1
endloop

set i = 0
set posx = CENTER_X - ( SQUARE_WIDTH / 2 )
set posy = CENTER_Y + ( SQUARE_HEIGHT / 2 )
set ic = 0

loop
exitwhen ( ic == COLUMNS + 1 )

set x = posx + ( ic * ( SQUARE_WIDTH / COLUMNS ) )
set y = posy
set ir = 0

loop
exitwhen ( ir == BORDER_RES + 1 )

set y = ( posy - ( ir * ( SQUARE_HEIGHT / BORDER_RES ) ) )
set i = i + 1
set Box = Rect( posx, y, x, posy )

call AddSpecialEffect( SFX_PATH, x, y )

set ir = ir + 1
endloop

set ic = ic + 1
endloop

set ir = 0

loop
exitwhen ( ir == ROWS + 1 )

set x = posx
set y = posy - ( ir * ( SQUARE_HEIGHT / ROWS ) )
set ic = 0

loop
exitwhen ( ic == BORDER_RES + 1 )

set i = i + 1
set x = ( posx + ( ic * ( SQUARE_WIDTH / BORDER_RES ) ) )
set Box = Rect( x, posy, posx, y )

call AddSpecialEffect( SFX_PATH, x, y )

set ic = ic + 1
endloop

set ir = ir + 1
endloop

endfunction

endscope[/code]
 
Level 4
Joined
Jan 29, 2007
Messages
98
Ok, so I'm using this right now, but the only problem is that somehow the last line (And a little of the second last one) doesn't get created, and no actions afterthat will execute (It breaks the thread...) ?

Any ideas ? :S

[JASS="Code !"]scope TerrainPattern initializer Create_Checked_Pattern

globals
constant real CENTER_X = 0
constant real CENTER_Y = 0

private constant real SQUARE_WIDTH = 8192.
private constant real SQUARE_HEIGHT = 8192.

private constant real COLUMNS = 10.
private constant real ROWS = 10.

private constant integer BORDER_RES = 200
private constant string SFX_PATH = "Abilities\\Spells\\Human\\SpellSteal\\SpellStealMissile.mdl"

private constant real BOX_HEIGHT = SQUARE_HEIGHT / ROWS
private constant real BOX_WIDTH = SQUARE_WIDTH / COLUMNS
endglobals

globals
rect array BoxCol
rect Board = Rect( CENTER_X - ( SQUARE_WIDTH / 2 ), CENTER_Y - ( SQUARE_HEIGHT / 2 ), CENTER_X + ( SQUARE_WIDTH / 2 ), CENTER_Y + ( SQUARE_WIDTH / 2 ) )
endglobals

private function Create_Checked_Pattern takes nothing returns nothing
local real posx
local real posy
local real x
local real y

local integer ic
local integer ir

local integer i = 0

loop
exitwhen i >= 12
call FogModifierStart( CreateFogModifierRect( Player(i), FOG_OF_WAR_VISIBLE, bj_mapInitialPlayableArea, true, true ) )

set i = i + 1
endloop

set i = 1
set posx = CENTER_X - ( SQUARE_WIDTH / 2 )
set posy = CENTER_Y + ( SQUARE_HEIGHT / 2 )
set ic = 0

loop
exitwhen ( ic == COLUMNS + 1 )

set x = posx + ( ic * ( SQUARE_WIDTH / COLUMNS ) )
set y = posy
set ir = 0

loop
exitwhen ( ir == BORDER_RES )

set y = ( posy - ( ir * ( SQUARE_HEIGHT / BORDER_RES ) ) )

call AddSpecialEffect( SFX_PATH, x, y )

set ir = ir + 1
endloop

set ic = ic + 1
//call DisplayTextToPlayer( Player( 0 ), 0., 0., R2S( ic ) )
endloop

set ir = 0

loop
exitwhen ( ir == ROWS + 1 )

set x = posx
set y = posy - ( ir * ( SQUARE_HEIGHT / ROWS ) )
set ic = 0

loop
exitwhen ( ic == BORDER_RES )

set x = ( posx + ( ic * ( SQUARE_WIDTH / BORDER_RES ) ) )

call AddSpecialEffect( SFX_PATH, x, y )

set ic = ic + 1
endloop

set ir = ir + 1
call DisplayTextToPlayer( Player( 0 ), 0., 0., R2S( ir ) )
endloop

call DisplayTextToPlayer( Player( 0 ), 0., 0., "Starting !" )

set ic = 0
set ir = 0
set i = 0

loop
exitwhen ic == COLUMNS

set x = CENTER_X + ic
set ir = 0

loop
exitwhen ir == ROWS

set i = i + 1
set y = CENTER_Y + ir

set BoxCol = Rect( x, y, x + BOX_WIDTH, y + BOX_HEIGHT )
call BoxData.create( BoxCol )

set ir = ir + 1
endloop

set ic = ic + 1

endloop

call BJDebugMsg( I2S( i ) )
endfunction

endscope[/code]
 
Level 18
Joined
Jan 21, 2006
Messages
2,552
I must have visited this thread and then closed my browser, I didn't see your question about having each of the boxes represent a rect.

I don't get it, your last lines are:

JASS:
    endfunction

endscope

How do these cause problems?

Oh, the last line of effects. Which line are you referring to? The last horizontal line or the last vertical line?
 
Level 18
Joined
Jan 21, 2006
Messages
2,552
Why did you change your loop when you're creating the lines?

JASS:
        loop
            exitwhen ( ic == COLUMNS + 1 )
            
            set x = posx + ( ic * ( SQUARE_WIDTH / COLUMNS ) )
            set y = posy
            set ir = 0
            
            loop
                exitwhen ( ir == BORDER_RES + 1 )

This is what you had before. This is what you have now:

JASS:
        loop
            exitwhen ( ic == COLUMNS + 1 )
            
            set x = posx + ( ic * ( SQUARE_WIDTH / COLUMNS ) )
            set y = posy
            set ir = 0
            
            loop
                exitwhen ( ir == BORDER_RES )

Try using BORDER_RES + 1.
 
Level 4
Joined
Jan 29, 2007
Messages
98
Yeah, sorry...

But anyways, the last scripts actually works (XD) it's just that I want to have 20x20 instead of 10x10...
This is where it breaks the thread :(

[JASS="Code !"]scope TerrainPattern initializer Create_Checked_Pattern

globals
constant real CENTER_X = 0
constant real CENTER_Y = 0

private constant real SQUARE_WIDTH = 8192.
private constant real SQUARE_HEIGHT = 8192.

private constant real COLUMNS = 20.
private constant real ROWS = 20.

private constant integer BORDER_RES = 200
private constant string SFX_PATH = "Abilities\\Spells\\Human\\SpellSteal\\SpellStealMissile.mdl"

private constant real BOX_HEIGHT = SQUARE_HEIGHT / ROWS
private constant real BOX_WIDTH = SQUARE_WIDTH / COLUMNS
endglobals

globals
rect array BoxCol
rect Board = Rect( CENTER_X - ( SQUARE_WIDTH / 2 ), CENTER_Y - ( SQUARE_HEIGHT / 2 ), CENTER_X + ( SQUARE_WIDTH / 2 ), CENTER_Y + ( SQUARE_WIDTH / 2 ) )
endglobals

private function Create_Checked_Pattern takes nothing returns nothing
local real posx
local real posy
local real x
local real y

local integer ic
local integer ir

local integer i = 0

loop
exitwhen i >= 12
call FogModifierStart( CreateFogModifierRect( Player(i), FOG_OF_WAR_VISIBLE, bj_mapInitialPlayableArea, true, true ) )

set i = i + 1
endloop

set i = 1
set posx = CENTER_X - ( SQUARE_WIDTH / 2 )
set posy = CENTER_Y + ( SQUARE_HEIGHT / 2 )
set ic = 0

loop
exitwhen ( ic == COLUMNS + 1 )

set x = posx + ( ic * ( SQUARE_WIDTH / COLUMNS ) )
set y = posy
set ir = 0

loop
exitwhen ( ir == BORDER_RES + 1 )

set y = ( posy - ( ir * ( SQUARE_HEIGHT / BORDER_RES ) ) )

call AddSpecialEffect( SFX_PATH, x, y )

set ir = ir + 1
endloop

set ic = ic + 1
call DisplayTextToPlayer( Player( 0 ), 0., 0., R2S( ic ) )
endloop

set ir = 0

loop
exitwhen ( ir == ROWS + 1 )

set x = posx
set y = posy - ( ir * ( SQUARE_HEIGHT / ROWS ) )
set ic = 0

loop
exitwhen ( ic == BORDER_RES + 1 )

set x = ( posx + ( ic * ( SQUARE_WIDTH / BORDER_RES ) ) )

call AddSpecialEffect( SFX_PATH, x, y )

set ic = ic + 1
endloop

set ir = ir + 1
call DisplayTextToPlayer( Player( 0 ), 0., 0., R2S( ir ) )
endloop

call DisplayTextToPlayer( Player( 0 ), 0., 0., "Starting !" )

set ic = 0
set ir = 0
set i = 0

loop
exitwhen ic == COLUMNS

set x = CENTER_X + ic
set ir = 0

loop
exitwhen ir == ROWS

set i = i + 1
set y = CENTER_Y + ir

set BoxCol = Rect( x, y, x + BOX_WIDTH, y + BOX_HEIGHT )
call BoxData.create( BoxCol )

set ir = ir + 1
endloop

set ic = ic + 1

endloop

call BJDebugMsg( I2S( i ) )
endfunction

endscope[/code]

That will only show like 14 rows (All columns though), and the "Starting !" and the BJDebugMsg doesn't show (As they did when I used 10x10).

Any ideas ? :S
 
Level 18
Joined
Jan 21, 2006
Messages
2,552
Komaqtion said:
JASS:
        set ic = 0
        set ir = 0
        set i = 0
    
        loop
            exitwhen ic == COLUMNS
        
            set x = CENTER_X + ic
            set ir = 0
        
            loop
                exitwhen ir == ROWS
            
                set i = i + 1
                set y = CENTER_Y + ir
            
                set BoxCol[i] = Rect( x, y, x + BOX_WIDTH, y + BOX_HEIGHT )
                call BoxData.create( BoxCol[i] )
            
                set ir = ir + 1
            endloop
        
            set ic = ic + 1
        
        endloop

What is this supposed to do? This is the part that you're claiming is bugged, correct?

Komaqtion said:
JASS:
            set x = CENTER_X + ic

So you're offsetting x by 1? You need to multiply ic by SQUARE_WIDTH / COLUMNS like you did when you were setting them up.

You also need to put more debugs and find out exactly which line is causing the problem. Just put some more debugs throughout your code and narrow it down a little for me.
 
Level 4
Joined
Jan 29, 2007
Messages
98
Ok, I just changed what you said, and that didn't do anything actually...

But anyways, thanks :D :S

And, just to clarify what I'm actually doing, I'm making 4-in-a-row.
So I want a square checked pattern, where I will use trackables to detect when a player clicks a square, and then create a Cross or Circle in that square...
That's why I'm using rects ;)

These are both of the scripts I'm using for this:
[jass="Code !]scope TerrainPattern initializer Create_Checked_Pattern

globals
constant real CENTER_X = 0
constant real CENTER_Y = 0

private constant real SQUARE_WIDTH = 8192.
private constant real SQUARE_HEIGHT = 8192.

private constant real COLUMNS = 20.
private constant real ROWS = 20.

private constant integer BORDER_RES = 200
private constant string SFX_PATH = "Abilities\\Spells\\Human\\SpellSteal\\SpellStealMissile.mdl"

constant real BOX_HEIGHT = SQUARE_HEIGHT / ROWS
constant real BOX_WIDTH = SQUARE_WIDTH / COLUMNS
endglobals

globals
rect array BoxCol
rect Board = Rect( CENTER_X - ( SQUARE_WIDTH / 2 ), CENTER_Y - ( SQUARE_HEIGHT / 2 ), CENTER_X + ( SQUARE_WIDTH / 2 ), CENTER_Y + ( SQUARE_WIDTH / 2 ) )
endglobals

private function Create_Checked_Pattern takes nothing returns nothing
local real posx
local real posy
local real x
local real y

local integer ic
local integer ir

local integer i = 0

loop
exitwhen i >= 12
call FogModifierStart( CreateFogModifierRect( Player(i), FOG_OF_WAR_VISIBLE, bj_mapInitialPlayableArea, true, true ) )

set i = i + 1
endloop

set i = 1
set posx = CENTER_X - ( SQUARE_WIDTH / 2 )
set posy = CENTER_Y + ( SQUARE_HEIGHT / 2 )
set ic = 0

loop
exitwhen ( ic == COLUMNS + 1 )

set x = posx + ( ic * BOX_WIDTH )
set y = posy
set ir = 0

loop
exitwhen ( ir == BORDER_RES + 1 )

set y = ( posy - ( ir * ( SQUARE_HEIGHT / BORDER_RES ) ) )

call AddSpecialEffect( SFX_PATH, x, y )

set ir = ir + 1
endloop

set ic = ic + 1
call DisplayTextToPlayer( Player( 0 ), 0., 0., R2S( ic ) )
endloop

set ir = 0

loop
exitwhen ( ir == ROWS + 1 )

set x = posx
set y = posy - ( ir * BOX_HEIGHT )
set ic = 0

loop
exitwhen ( ic == BORDER_RES + 1 )

set x = ( posx + ( ic * ( SQUARE_WIDTH / BORDER_RES ) ) )

call AddSpecialEffect( SFX_PATH, x, y )

set ic = ic + 1
endloop

set ir = ir + 1
call DisplayTextToPlayer( Player( 0 ), 0., 0., R2S( ir ) )
endloop

call DisplayTextToPlayer( Player( 0 ), 0., 0., "Starting !" )

set ic = 0
set ir = 0
set i = 0

loop
exitwhen ic == COLUMNS

set x = CENTER_X + ic * BOX_WIDTH
set ir = 0

loop
exitwhen ir == ROWS

set i = i + 1
set y = CENTER_Y + ir * BOX_HEIGHT

set BoxCol[i] = Rect( x, y, x + BOX_WIDTH, y + BOX_HEIGHT )
call BoxData.create( BoxCol[i] )

set ir = ir + 1
endloop

set ic = ic + 1

endloop

call BJDebugMsg( I2S( i ) )
endfunction

endscope[/code]

This is the script which atm creates 20 columns, but only 15 rows ?!
And it should also create rects inside all of those squares it creates, but it doesn't ever get there, because the entire thread is broken when the last row (the 15th) is created...

And here's the code which should keep track of each region, and create the trackables for them:

[jass="Code 2 !"]library Boxes/* initializer Init*/ requires TrackMapSystem

globals
private constant real HEIGHT_SPACE = 0.1
private constant real WIDTH_SPACE = 0.1
endglobals

struct BoxData
private rect rct
private TrackMap track1
private TrackMap track2
private trigger t
private real maxx
private real minx
private real maxy
private real miny

private player owner = null

static method create takes rect r returns thistype
local thistype this = thistype.allocate()
local integer i = 0

set this.rct = r
set this.maxx = GetRectMaxX( r )
set this.minx = GetRectMinX( r )
set this.maxy = GetRectMaxY( r )
set this.miny = GetRectMinY( r )
set this.track1 = TrackMap.create( r, 0, 147.18, true )
set this.track2 = TrackMap.create( r, 1, 147.18, false )
set this.t = CreateTrigger()

call TriggerAddCondition( this.t, Condition( function thistype.onClick ) )
call this.track1.registerClick( this.t )
call this.track2.registerClick( this.t )

return this
endmethod

static method createCross takes real x, real y returns boolean
local real width = BOX_WIDTH - ( BOX_WIDTH * WIDTH_SPACE )
local real height = BOX_HEIGHT - ( BOX_HEIGHT * HEIGHT_SPACE )



return false
endmethod

static method onClick takes nothing returns boolean
call BJDebugMsg( "Tracked !" )

return false
endmethod

endstruct

/*static if DEBUG_MODE then

private function Init takes nothing returns nothing
call BoxData.create( gg_rct_TrackRect )
endfunction

endif*/

endlibrary[/code]

And here are the other two scripts needed to create the trackables (Called TrackMaps :D)

[jass="Code 3 !"]library TrackMapSystem initializer InitSystem uses Event

//=====================================================================================
// ||
// TrackMapSystem ||
// ||
// created by Lord_Executor alias Executor alias Executor1 ||
// ||
// Credits ||
// ||
// Vexorian [JNGP,Dummy.mdx] ||
// tamisrah [Advice] ||
// Azelier [Ideas] ||
// Jesus4Lyf [Event] ||
// ||
//=====================================================================================

//=====================================================================================
// ||
// This system allows you the fast and effective set up of TrackMaps which means ||
// filling an area with trackable objects which will callback to cursor actions. ||
// ||
// I create those trackables without a visible model, which allows them to be ||
// invisible ingame but still able to determine move and click of the cursor. ||
// ||
// There are several problems with this system because normal orders on TrackMapped ||
// ground won't be handled normal anymore. But you should try for yourself. ||
// ||
//=====================================================================================

globals
//May be modified:
private constant real TIMER_INTERVAL = 0.05
private constant integer LOOP_BREAK_VALUE = 2500

// You should know what you do if you want to modify these:
private constant string MODEL_SMALL = "Doodads\\Terrain\\InvisiblePlatformSmall\\InvisiblePlatformSmall.mdl"
private constant string MODEL_NORMAL = "Doodads\\Terrain\\InvisiblePlatform\\InvisiblePlatform.mdl"
private constant real RADIUS_NORMAL = 73.59

// Usuable Constants
constant real MOUSEPOSITION_HIGH_PRECISION = RADIUS_NORMAL
constant real MOUSEPOSITION_LESS_PRECISION = RADIUS_NORMAL * 2

//System Vars (do not modify)
private hashtable Hash = null
private constant key SLOT_TRACKDATA
private constant key SLOT_STRUCT
private real array TMpx
private real array TMpy

private boolean clicked = false
private integer TMlasttm = 0
private integer TMlastplayer = -1
endglobals

private function InitSystem takes nothing returns nothing
set Hash = InitHashtable()
endfunction

private function SetTriggerData takes trigger t, integer i returns nothing
loop
exitwhen i <= 0
call TriggerExecute(t)
set i = i - 1
endloop
endfunction

private function DestroyTriggerDelayed takes trigger t returns nothing
call TriggerSleepAction(3.0)
call DestroyTrigger(t)
endfunction

private struct trackdata
readonly real x
readonly real y
static method create takes real x, real y returns thistype
local thistype this = thistype.allocate()
set .x = x
set .y = y
return this
endmethod
endstruct

private struct cache
public real res
public string mod
public boolean timed
public real x_MIN
public real y_MIN
public real x_MAX
public real y_MAX
static method create takes nothing returns thistype
return thistype.allocate()
endmethod
endstruct

struct TrackMap
readonly trigger TrigTrack
readonly trigger TrigClick
readonly integer p
readonly rect r
readonly boolean active

private static boolexpr TrackHandle
private static boolexpr ClickHandle

private static Event anyClick
private static Event anyTrack

private Event onClick
private Event onTrack

static method registerAnyClick takes trigger t returns nothing
call .anyClick.register(t)
endmethod

static method registerAnyTrack takes trigger t returns nothing
call .anyTrack.register(t)
endmethod

static method registerAnyChange takes trigger t returns nothing
call .anyClick.register(t)
call .anyTrack.register(t)
endmethod

method registerClick takes trigger t returns nothing
call .onClick.register(t)
endmethod

method registerTrack takes trigger t returns nothing
call .onTrack.register(t)
endmethod

method registerChange takes trigger t returns nothing
call .onClick.register(t)
call .onTrack.register(t)
endmethod

private static method TrackHandleEx takes nothing returns boolean
local thistype map = GetTriggerExecCount(GetTriggeringTrigger())
local trackdata d = LoadInteger(Hash,GetHandleId(GetTriggeringTrackable()),SLOT_TRACKDATA)

set TMlasttm = map
set TMpx[map.p] = d.x
set TMpy[map.p] = d.y
set TMlastplayer = map.p
set clicked = false

call map.onTrack.fire()
call .anyTrack.fire()

return false
endmethod
private static method ClickHandleEx takes nothing returns boolean
local thistype map = GetTriggerExecCount(GetTriggeringTrigger())
local trackdata d = LoadInteger(Hash,GetHandleId(GetTriggeringTrackable()),SLOT_TRACKDATA)

set TMlasttm = map
set TMpx[map.p] = d.x
set TMpy[map.p] = d.y
set TMlastplayer = map.p
set clicked = true

call map.onClick.fire()
call .anyClick.fire()

return false
endmethod

static method create takes rect r,integer p, real resolution, boolean timed returns thistype
local thistype this = thistype.allocate()
local string mod = ""
local cache c = cache.create()

if resolution <= RADIUS_NORMAL then
set mod = MODEL_SMALL
else
set mod = MODEL_NORMAL
endif

set .p = p
set .r = r
set c.res = resolution
set c.mod = mod
set c.x_MIN = GetRectMinX(.r)
set c.y_MIN = GetRectMinY(.r)
set c.x_MAX = GetRectMaxX(.r)
set c.y_MAX = GetRectMaxY(.r)
set c.timed = timed

set .onClick = Event.create()
set .onTrack = Event.create()

set .TrigTrack = CreateTrigger()
set .TrigClick = CreateTrigger()
call SetTriggerData.execute(.TrigTrack,this)
call SetTriggerData.execute(.TrigClick,this)
call TriggerAddCondition(.TrigTrack,thistype.TrackHandle)
call TriggerAddCondition(.TrigClick,thistype.ClickHandle)

if timed then
call DynamicTrackMapGenerator.create(this,c)
else
call .generatefield(c,0)
endif
return this
endmethod
method generatefield takes cache c, integer i returns boolean
local integer j = 0
local trackable track = null
local real x = 0.
local real y = 0.
local string mod = c.mod

if GetPlayerId(GetLocalPlayer()) != .p then
set mod = ""
endif

loop
set j = 0
set x = c.x_MIN + i * c.res
loop
set y = c.y_MIN + j * c.res

set track = CreateTrackable(mod,x,y,0.)
call SaveInteger(Hash,GetHandleId(track),SLOT_TRACKDATA,trackdata.create(x,y))

call TriggerRegisterTrackableTrackEvent(.TrigTrack, track)
call TriggerRegisterTrackableHitEvent(.TrigClick, track)

set j = j + 1
exitwhen y >= c.y_MAX
endloop

set i = i + 1

if x >= c.x_MAX then
// completely done.
call c.destroy()
return true
endif

// wait for next interval to proceed
exitwhen c.timed

if (i * j >= LOOP_BREAK_VALUE) then
// recall the function in another thread to avoid a loop break.
call .generatefield.execute(c,i)
return false
endif

endloop

return false
endmethod

method onDestroy takes nothing returns nothing
call TriggerClearActions(.TrigTrack)
call TriggerClearActions(.TrigClick)
call DisableTrigger(.TrigTrack)
call DisableTrigger(.TrigClick)
call DestroyTriggerDelayed.execute(.TrigTrack)
call DestroyTriggerDelayed.execute(.TrigClick)
set .TrigTrack = null
set .TrigClick = null
endmethod

private static method onInit takes nothing returns nothing
set .anyClick = Event.create()
set .anyTrack = Event.create()
set .ClickHandle = Condition( function thistype.ClickHandleEx)
set .TrackHandle = Condition( function thistype.TrackHandleEx)
endmethod

method stop takes nothing returns nothing
if not .active then
return
endif
set .active = false
if .TrigTrack != null then
call DisableTrigger(.TrigTrack)
endif
if .TrigClick != null then
call DisableTrigger(.TrigClick)
endif
endmethod
method resume takes nothing returns nothing
if .active then
return
endif
set .active = true
if .TrigTrack != null then
call EnableTrigger(.TrigTrack)
endif
if .TrigClick != null then
call EnableTrigger(.TrigClick)
endif
endmethod
endstruct

struct DynamicTrackMapGenerator
private integer i = -1
private TrackMap m
private cache c
static method create takes TrackMap m, cache c returns thistype
local thistype this = thistype.allocate()
local timer t = CreateTimer()

set .m = m
set .c = c
call SaveInteger(Hash, GetHandleId(t),SLOT_STRUCT,this)
call TimerStart(t,TIMER_INTERVAL,true, function thistype.callback)

return this
endmethod
static method callback takes nothing returns nothing
local timer t = GetExpiredTimer()
local thistype this = LoadInteger(Hash,GetHandleId(t),SLOT_STRUCT)
set .i = .i + 1
if .m.generatefield(.c,.i) then
call RemoveSavedInteger(Hash,GetHandleId(t),SLOT_STRUCT)
call DestroyTimer(t)
call .destroy()
endif
endmethod
endstruct


// Usuable Functions

function SetUpTrackMap takes rect area, player p, boolean veryprecise returns TrackMap
if veryprecise then
return TrackMap.create(area ,GetPlayerId(p),MOUSEPOSITION_HIGH_PRECISION,true)
else
return TrackMap.create(area ,GetPlayerId(p),MOUSEPOSITION_LESS_PRECISION,true)
endif
endfunction

function SetUpTrackMapEx takes rect area, player p, real precision, boolean timed returns TrackMap
return TrackMap.create(area,GetPlayerId(p),precision,timed)
endfunction

function TriggerRegisterAnyMouseEvent takes trigger t returns nothing
call TrackMap.registerAnyChange(t)
endfunction

function TriggerRegisterAnyClickEvent takes trigger t returns nothing
call TrackMap.registerAnyClick(t)
endfunction

function TriggerRegisterAnyTrackEvent takes trigger t returns nothing
call TrackMap.registerAnyTrack(t)
endfunction

function TriggerRegisterMouseEvent takes trigger t, TrackMap tm returns nothing
call tm.registerChange(t)
endfunction

function TriggerRegisterClickEvent takes trigger t, TrackMap tm returns nothing
call tm.registerClick(t)
endfunction

function TriggerRegisterTrackEvent takes trigger t, TrackMap tm returns nothing
call tm.registerTrack(t)
endfunction

function Clicked takes nothing returns boolean
return clicked
endfunction

function Tracked takes nothing returns boolean
return not clicked
endfunction

function GetMousePosX takes integer p returns real
return TMpx
endfunction

function GetMousePosY takes integer p returns real
return TMpy
endfunction

function GetTriggerMousePosX takes nothing returns real
return TMpx[TMlastplayer]
endfunction

function GetTriggerMousePosY takes nothing returns real
return TMpy[TMlastplayer]
endfunction

function GetTriggerTrackMap takes nothing returns TrackMap
return TMlasttm
endfunction

function GetMouseUsingPlayer takes nothing returns player
return Player(TMlastplayer)
endfunction

function GetMouseUsingPlayerId takes nothing returns integer
return TMlastplayer
endfunction

endlibrary[/code]

[jass="Event !"]//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// ~~ Event ~~ By Jesus4Lyf ~~ Version 1.04 ~~
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// What is Event?
// - Event simulates Warcraft III events. They can be created,
// registered for, fired and also destroyed.
// - Event, therefore, can also be used like a trigger "group".
// - This was created when there was an influx of event style systems
// emerging that could really benefit from a standardised custom
// events snippet. Many users were trying to achieve the same thing
// and making the same kind of errors. This snippet aims to solve that.
//
// Functions:
// - Event.create() --> Creates a new Event.
// - .destroy() --> Destroys an Event.
// - .fire() --> Fires all triggers which have been
// registered on this Event.
// - .register(trigger) --> Registers another trigger on this Event.
// - .unregister(trigger) --> Unregisters a trigger from this Event.
//
// Details:
// - Event is extremely efficient and lightweight.
// - It is safe to use with dynamic triggers.
// - Internally, it is just a linked list. Very simple.
//
// How to import:
// - Create a trigger named Event.
// - Convert it to custom text and replace the whole trigger text with this.
//
// Thanks:
// - Builder Bob for the trigger destroy detection method.
// - Azlier for inspiring this by ripping off my dodgier code.
//
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
library Event
///////////////
// EventRegs //
////////////////////////////////////////////////////////////////////////////
// For reading this far, you can learn one thing more.
// Unlike normal Warcraft III events, you can attach to Event registries.
//
// Event Registries are registrations of one trigger on one event.
// These cannot be created or destroyed, just attached to.
//
// It is VERY efficient for loading and saving data.
//
// Functions:
// - set eventReg.data = someStruct --> Store data.
// - eventReg.data --> Retreive data.
// - Event.getTriggeringEventReg() --> Get the triggering EventReg.
// - eventReg.destroy() --> Undo this registration.
//
private keyword destroyNode
struct EventReg extends array
integer data
method clear takes nothing returns nothing
set this.data=0
endmethod
method destroy takes nothing returns nothing
call Event(this).destroyNode()
endmethod
endstruct

private module Stack
static thistype top=0
static method increment takes nothing returns nothing
set thistype.top=thistype(thistype.top+1)
endmethod
static method decrement takes nothing returns nothing
set thistype.top=thistype(thistype.top-1)
endmethod
endmodule

private struct EventStack extends array
implement Stack
Event current
endstruct

struct Event
private trigger trig
private thistype next
private thistype prev

static method getTriggeringEventReg takes nothing returns EventReg
return EventStack.top.current
endmethod

static method create takes nothing returns Event
local Event this=Event.allocate()
set this.next=this
set this.prev=this
return this
endmethod

private static trigger currentTrigger
method fire takes nothing returns nothing
local thistype curr=this.next
call EventStack.increment()
loop
exitwhen curr==this
set thistype.currentTrigger=curr.trig
if IsTriggerEnabled(thistype.currentTrigger) then
set EventStack.top.current=curr
if TriggerEvaluate(thistype.currentTrigger) then
call TriggerExecute(thistype.currentTrigger)
endif
else
call EnableTrigger(thistype.currentTrigger) // Was trigger destroyed?
if IsTriggerEnabled(thistype.currentTrigger) then
call DisableTrigger(thistype.currentTrigger)
else // If trigger destroyed...
set curr.next.prev=curr.prev
set curr.prev.next=curr.next
call curr.deallocate()
endif
endif
set curr=curr.next
endloop
call EventStack.decrement()
endmethod
method register takes trigger t returns EventReg
local Event new=Event.allocate()
set new.prev=this.prev
set this.prev.next=new
set this.prev=new
set new.next=this

set new.trig=t

call EventReg(new).clear()
return new
endmethod
method destroyNode takes nothing returns nothing // called on EventReg
set this.prev.next=this.next
set this.next.prev=this.prev
call this.deallocate()
endmethod
method unregister takes trigger t returns nothing
local thistype curr=this.next
loop
exitwhen curr==this
if curr.trig==t then
set curr.next.prev=curr.prev
set curr.prev.next=curr.next
call curr.deallocate()
return
endif
set curr=curr.next
endloop
endmethod

method destroy takes nothing returns nothing
local thistype curr=this.next
loop
call curr.deallocate()
exitwhen curr==this
set curr=curr.next
endloop
endmethod
method chainDestroy takes nothing returns nothing
call this.destroy() // backwards compatability.
endmethod
endstruct

/////////////////////////////////////////////////////
// Demonstration Functions & Alternative Interface //
////////////////////////////////////////////////////////////////////////////
// What this would look like in normal WC3 style JASS (should all inline).
//
function CreateEvent takes nothing returns Event
return Event.create()
endfunction
function DestroyEvent takes Event whichEvent returns nothing
call whichEvent.chainDestroy()
endfunction
function FireEvent takes Event whichEvent returns nothing
call whichEvent.fire()
endfunction
function TriggerRegisterEvent takes trigger whichTrigger, Event whichEvent returns EventReg
return whichEvent.register(whichTrigger)
endfunction

// And for EventRegs...
function SetEventRegData takes EventReg whichEventReg, integer data returns nothing
set whichEventReg.data=data
endfunction
function GetEventRegData takes EventReg whichEventReg returns integer
return whichEventReg.data
endfunction
function GetTriggeringEventReg takes nothing returns integer
return Event.getTriggeringEventReg()
endfunction
endlibrary[/code]

So... Any ideas to why the thread is broken on the creation of the 15th row ? :S
Because your guess is as good as mine at this point XD
 
Level 4
Joined
Jan 29, 2007
Messages
98
BumP ! :eek:

[jass="Code !"]scope TerrainPattern initializer Create_Checked_Pattern

globals
constant real CENTER_X = 0
constant real CENTER_Y = 0

private constant real SQUARE_WIDTH = 8192.
private constant real SQUARE_HEIGHT = 8192.

private constant real COLUMNS = 20.
private constant real ROWS = 20.

private constant integer BORDER_RES = 200
private constant string SFX_PATH = "Abilities\\Spells\\Human\\SpellSteal\\SpellStealMissile.mdl"

constant real BOX_HEIGHT = SQUARE_HEIGHT / ROWS
constant real BOX_WIDTH = SQUARE_WIDTH / COLUMNS
endglobals

globals
rect array BoxCol
rect Board = Rect( CENTER_X - ( SQUARE_WIDTH / 2 ), CENTER_Y - ( SQUARE_HEIGHT / 2 ), CENTER_X + ( SQUARE_WIDTH / 2 ), CENTER_Y + ( SQUARE_WIDTH / 2 ) )
endglobals

private function Create_Checked_Pattern takes nothing returns nothing
local real posx
local real posy
local real x
local real y

local integer ic
local integer ir

local integer i = 0

loop
exitwhen i >= 12
call FogModifierStart( CreateFogModifierRect( Player(i), FOG_OF_WAR_VISIBLE, bj_mapInitialPlayableArea, true, true ) )

set i = i + 1
endloop

set i = 1
set posx = CENTER_X - ( SQUARE_WIDTH / 2 )
set posy = CENTER_Y + ( SQUARE_HEIGHT / 2 )
set ic = 0

loop
exitwhen ( ic == COLUMNS + 1 )

set x = posx + ( ic * BOX_WIDTH )
set y = posy
set ir = 0

loop
exitwhen ( ir == BORDER_RES + 1 )

set y = ( posy - ( ir * ( SQUARE_HEIGHT / BORDER_RES ) ) )

call AddSpecialEffect( SFX_PATH, x, y )

set ir = ir + 1
endloop

set ic = ic + 1
call DisplayTextToPlayer( Player( 0 ), 0., 0., R2S( ic ) )
endloop

set ir = 0

loop
exitwhen ( ir == ROWS + 1 )

set x = posx
set y = posy - ( ir * BOX_HEIGHT )
set ic = 0

loop
exitwhen ( ic == BORDER_RES + 1 )

set x = ( posx + ( ic * ( SQUARE_WIDTH / BORDER_RES ) ) )

call AddSpecialEffect( SFX_PATH, x, y )

set ic = ic + 1
endloop

set ir = ir + 1
call DisplayTextToPlayer( Player( 0 ), 0., 0., R2S( ir ) )
endloop

call DisplayTextToPlayer( Player( 0 ), 0., 0., "Starting !" )

set ic = 0
set ir = 0
set i = 0

loop
exitwhen ic == COLUMNS

set x = CENTER_X + ic * BOX_WIDTH
set ir = 0

loop
exitwhen ir == ROWS

set i = i + 1
set y = CENTER_Y + ir * BOX_HEIGHT

set BoxCol = Rect( x, y, x + BOX_WIDTH, y + BOX_HEIGHT )
call BoxData.create( BoxCol )

set ir = ir + 1
endloop

set ic = ic + 1

endloop

call BJDebugMsg( I2S( i ) )
endfunction

endscope[/code]

That's the code, too :D
 
Level 4
Joined
Jan 29, 2007
Messages
98
Ok, I now discovered the problem...
It was somehow reaching some op-limit,so I split them up with the use of "ExecuteFunc", so it's split up into 3 functions now...

I also reduced the number of columns and rows to 15, and all that is created nicely now :D

But now I want to know how I could, when someone clicks one of the "boxes", create either a cross (X) or a circle (O), depending on the player clicking ? :S

I use the TrackMaps library to create the trackables for it, but I can't seem to create good cross yet :(

Here's what I have so far:
[jass="Code !"]library Boxes initializer Init requires TrackMapSystem

globals
private constant real HEIGHT_SPACE = 0.05
private constant real WIDTH_SPACE = 0.05
//private constant real
private constant string SFX_PATH_X = "Abilities\\Spells\\Other\\Parasite\\ParasiteMissile.mdl"
private constant string SFX_PATH_Y = "Abilities\\Weapons\\LichMissile\\LichMissile.mdl"

private constant integer X_EFFECTS = 20
private constant integer O_EFFECTS = 20
endglobals

struct BoxData
private rect rct
private TrackMap track1
private TrackMap track2
private trigger t
private real maxX
private real minX
private real maxY
private real minY

private player owner = null

static method create takes rect r returns thistype
local thistype this = thistype.allocate()
local integer i = 0

set this.rct = r
set this.maxX = GetRectMaxX( r )
set this.minX = GetRectMinX( r )
set this.maxY = GetRectMaxY( r )
set this.minY = GetRectMinY( r )
set this.track1 = TrackMap.create( r, 0, 147.18, true )
set this.track2 = TrackMap.create( r, 1, 147.18, false )
set this.t = CreateTrigger()

call TriggerAddCondition( this.t, Condition( function thistype.onClick ) )
call this.track1.registerClick( this.t )
call this.track2.registerClick( this.t )

return this
endmethod

method createCross takes nothing returns nothing
local real maxx = this.maxX - ( BOX_WIDTH * WIDTH_SPACE )
local real minx = this.minX + ( BOX_WIDTH * WIDTH_SPACE )
local real maxy = this.maxY - ( BOX_HEIGHT * HEIGHT_SPACE )
local real miny = this.minY + ( BOX_HEIGHT * HEIGHT_SPACE )
local real x
local real y

local real distr = SquareRoot( ( maxx - minx ) * ( maxx - minx ) + ( miny - maxy ) * ( miny - maxy ) ) / ( X_EFFECTS / 2 )
local real distl = SquareRoot( ( minx - maxx ) * ( minx - maxx ) + ( miny - maxy ) * ( miny - maxy ) ) / ( X_EFFECTS / 2 )

local real angr = bj_RADTODEG * Atan2( miny - maxy, maxx - minx )
local real angl = bj_RADTODEG * Atan2( miny - maxy, minx - maxx )

local integer i = 0

loop
set x = minx + ( distr * i ) * Cos( angr * bj_DEGTORAD )
set y = maxy + ( distr * i ) * Sin( angr * bj_DEGTORAD )

call AddSpecialEffect( SFX_PATH_X, x, y )

set x = maxx + ( distl * i ) * Cos( angl * bj_DEGTORAD )
set y = maxy + ( distl * i ) * Sin( angl * bj_DEGTORAD )

call AddSpecialEffect( SFX_PATH_X, x, y )

set i = i + 1
exitwhen i == 10
endloop

endmethod

static method onClick takes nothing returns boolean
call BJDebugMsg( "Tracked !" )

return false
endmethod

endstruct

static if DEBUG_MODE then

private function Init takes nothing returns nothing
local BoxData b = BoxData.create( gg_rct_TrackRect )
call b.createCross()
endfunction

endif

endlibrary[/code]

But right now the cross is a little off...
I use 10 effects per line (2 lines :p) and that means that there should be 5 effects to each corner, from the middle, but now there's 6 effects from above (Or below, can't remember XD) to where the lines meet, and 4 below (Or above :p) it...

Any ideas to why it's like this ? :S
 
Level 18
Joined
Jan 21, 2006
Messages
2,552
In order to get some real help for this you may need to post the map. This code doesn't work from a simple copy and paste which means someone trying to debug your code will either have to get it to work, or go through all of your code and find out where you've made a logic error.
 
Level 18
Joined
Jan 21, 2006
Messages
2,552
What are the WIDTH_SPACE and HEIGHT_SPACE? What do these values represent?

Also:

Komaqtion said:
JASS:
            local real angr = bj_RADTODEG * Atan2( miny - maxy, maxx - minx )
            local real angl = bj_RADTODEG * Atan2( miny - maxy, minx - maxx )
            
            local integer i = 0
            
            loop
                set x = minx + ( distr * i ) * Cos( angr * bj_DEGTORAD )
                set y = maxy + ( distr * i ) * Sin( angr * bj_DEGTORAD )

Why multiply by bj_RADTODEG if you just multiply by bj_DEGTORAD afterwards?

JASS:
        // In order to achieve the best results, you'll have to have an "amount of effects" that is derived from an
        // odd number times 2. For example, 9*2 (18 effects) will have a better result than 10*2 (20).
        private constant integer X_EFFECTS = 18
        private constant integer O_EFFECTS = 18
    endglobals

    //==================================================
    // DrawCross Function
    //==================================================
    function DrawCross takes real centx, real centy, real width, real height, integer count returns nothing
        local real x
        local real y
        local real dx
        local real dy
        local integer i
        local integer halfcount
        
        set count=count-2
        // You cannot have an even number of special effects.
        if (ModuloInteger(count, 2)==1) then
            set count=count+1
        endif
        set halfcount = count/2
        // The cross is drawn with a center of 'centx, centy' and a specified width/height. It will then draw out the lines
        // so that each of them have half of the allowed 'count'.
        set x = (centx-width)
        set y = (centy+height)    
        // 'dx' and 'dy' is the value by which each component will need to increment to achieve the desired "cross".
        set dx = (2*width / halfcount)
        set dy = (2*height / halfcount)
        // Now we can draw our first line. Note that on the first line we will be using -dy and +dx, but on the second we will
        // use +dy and +dx. The reason is because we start from the top-left the first time, then the bottom-left the second.
        set i = 0
        loop
            call AddSpecialEffect(SFX_PATH_X, x, y)
            exitwhen(i == halfcount)
            set x = x + dx
            set y = y - dy
            set i = i + 1
        endloop
        // Now we can draw our second line, starting at -width, -height.
        set x = (centx-width)
        set y = (centy-height)
        set i = 0
        loop
            call AddSpecialEffect(SFX_PATH_X, x, y)
            exitwhen(i == halfcount)
            set x = x + dx
            set y = y + dy
            set i = i + 1
        endloop
    endfunction

Add this to your code. Replace the global declarations with what I've done too. If you want to test it out, here's how its used:

JASS:
        method createCross takes nothing returns nothing
            local real centx = (.maxX+.minX)/2
            local real centy = (.maxY+.minY)/2

            call DrawCross(centx, centy, 150, 150, X_EFFECTS)
        endmethod
 
Last edited:
Status
Not open for further replies.
Top