- Joined
- Jul 1, 2008
- Messages
- 1,314
Good Evening Everybody,
I am using the following functions in a huge map, to change terrain tiles according to season.
The Problem is, that a loop will hit the OP limit quite easily, as the map is that huge.
I thought of several ways to do this, and the current way to change a huge terrain into other tiles, is:
Problem is: It seems, that sometimes the first trigger, that executes the actual changing attempts, crashes. I think, this happens most of the times on big rects.
Question: Can you guys maybe help me with suggestion on how to solve this? I am not very good with this whole OP limit thing, so I think, I do not understand this correctly ... Why does my main function in the first trigger crash sometimes? It should not reach the op limit, or does it?
I observe, that rect 0 and 1 are changed correctly but rect 2 is not even touched. Instead the first trigger stoppes somewhere at count 8 for example...
ps: sry for the messy code, but the new forum messes up all code tags, I post. I did not figure out yet, how to post properly ...
pps: thank you for any help
I am using the following functions in a huge map, to change terrain tiles according to season.
The Problem is, that a loop will hit the OP limit quite easily, as the map is that huge.
I thought of several ways to do this, and the current way to change a huge terrain into other tiles, is:
how it should work1. Trigger: This trigger is called by the user. It loops up to 50 times and through all rects, that I want to change upon season.
2. Trigger: The called trigger from 1. itself calls another trigger once a second, that will try to change each rect one after each other until all rects are finished.
3. If the op limit is reached in the second trigger, it will be called again by the first one anyway. To achieve that, the second trigger always saves the last checked position and checks, if it already covered the whole rect. If yes, it should advance to the next rect.
Question: Can you guys maybe help me with suggestion on how to solve this? I am not very good with this whole OP limit thing, so I think, I do not understand this correctly ... Why does my main function in the first trigger crash sometimes? It should not reach the op limit, or does it?
I observe, that rect 0 and 1 are changed correctly but rect 2 is not even touched. Instead the first trigger stoppes somewhere at count 8 for example...
JASS:
library SEASON
/* use:
set SEASON_REQUEST_SEASON_TYPE = "winter"
call TriggerExecute( SEASON_SEASONAL_CHANGE_TRIGGER)
*/
globals
private rect array SeasonalRects
private integer currentRect = 0
private constant integer maxRects = 2
private constant integer OpLimitMax = 50
private boolean array currentRectCompleted
private real array currentPosX
private real array currentPosY
private real array rectMinX
private real array rectMaxX
private real array rectMinY
private real array rectMaxY
public constant trigger SEASONAL_CHANGE_TRIGGER = CreateTrigger()
private constant trigger SEASONAL_CHANGE_TRIGGER_EX = CreateTrigger()
public string REQUEST_SEASON_TYPE = "winter" // this will be changed outside upon seasonal request
private constant integer TYPE_WINTER_SNOW = 'cNc1' // Terrain tile type
private constant integer TYPE_SUMMER_THICK_GRASS = 'cAc1' // Terrain tile type
private constant integer TYPE_WINTER_ICE = 'Nice' // Terrain tile type
private constant integer TYPE_SUMMER_DARK_GRASS = 'Vgrt' // Terrain tile type
endglobals
private function ConvertTerrainTypeSeasonal takes real x, real y, string season returns integer
// list all terrain types that are allowed to change seasonally. Link terrain types here
if season == "winter" then
// change all linked types to their spring form
if (GetTerrainType( x, y) == TYPE_SUMMER_THICK_GRASS) then
return TYPE_WINTER_SNOW
elseif (GetTerrainType( x, y) == TYPE_SUMMER_DARK_GRASS) then
return TYPE_WINTER_ICE
endif
elseif season == "spring" then
// change all linked types to their spring form
if (GetTerrainType( x, y) == TYPE_WINTER_SNOW) then
return TYPE_SUMMER_THICK_GRASS
elseif (GetTerrainType( x, y) == TYPE_WINTER_ICE) then
return TYPE_SUMMER_DARK_GRASS
endif
endif
return 0 // return 0 if tile is not of any type to be changed
endfunction
private function SeasonChangeTerrainEx takes nothing returns nothing
// this function executes seasonal terrain changes for actual "current" rects, until they are completed
local boolean exit = FALSE
local integer REQUESTED_TYLE = 0
loop
if ((currentPosX[currentRect] >= rectMaxX[currentRect]) and (currentPosY[currentRect] >= rectMaxY[currentRect])) then
call BJDebugMsg("SEASON right top corner reached of current rect index " + I2S(currentRect))
set exit = TRUE // exit this rect
set currentRectCompleted[currentRect] = TRUE // mark rect as completed
endif
exitwhen exit
// go through current rect from bottom left to top right and apply changes
// loop through every x loc at current y
set currentPosX[currentRect] = rectMinX[currentRect] // reset x position start
loop
exitwhen currentPosX[currentRect] > rectMaxX[currentRect]
call BJDebugMsg("SEASON currentX " + R2S(currentPosX[currentRect]))
// --------------------------
// apply channges
// request terrain type and change it if requested. Do not allow unregistered terrain types (which would be ==0)
set REQUESTED_TYLE = ConvertTerrainTypeSeasonal( currentPosX[currentRect], currentPosY[currentRect], REQUEST_SEASON_TYPE)
if (REQUESTED_TYLE != 0) then
// Terrain type of tile is requested to be changed
call SetTerrainType( currentPosX[currentRect], currentPosY[currentRect], REQUESTED_TYLE, -1, 1, 0)
endif
// --------------------------
// move along the x axis until rect end is reached
set currentPosX[currentRect] = currentPosX[currentRect] + 128.
endloop
// move to next y loc
set currentPosY[currentRect] = currentPosY[currentRect] + 128.
call BJDebugMsg("SEASON currentY " + R2S(currentPosY[currentRect]))
endloop
endfunction
private function SeasonChangeTerrain takes nothing returns nothing
// loop through all rects, until every rect has been completed in seasonal change
// use global variables to keep track of locations, if the op limit of actions was reached in between
local integer opLimit = 0
loop
if currentRect > maxRects then
call BJDebugMsg("SEASON all rects completed")
else
call BJDebugMsg("SEASON not completed yet")
endif
exitwhen (currentRect >= maxRects or opLimit > OpLimitMax)
set opLimit = opLimit + 1
call BJDebugMsg("SEASON index " + I2S(opLimit))
if currentRectCompleted[currentRect] then
// if rect was completed, advance to next rect
set currentRectCompleted[currentRect] = FALSE
set currentPosX[currentRect] = rectMinX[currentRect]
set currentPosY[currentRect] = rectMinY[currentRect]
set currentRect = currentRect + 1
call BJDebugMsg("SEASON next rect")
else
// if rect not completed, excute terrain change for this rect
call TriggerSleepAction( 1.)
call TriggerExecute( SEASONAL_CHANGE_TRIGGER_EX)
call BJDebugMsg("SEASON executing change")
endif
endloop
// if loop has ended, double check, if rects were completed succesfully
if currentRect < maxRects then
call TriggerExecute( SEASONAL_CHANGE_TRIGGER)
endif
// reset seasonal rect count for nex execution
set currentRect = 0
endfunction
// initializer function (called in Game_Initialization)
public function REGISTER_RECTS takes nothing returns nothing
local integer i = 0
// register all snowy rects
set SeasonalRects[0] = gg_rct_LAND_1
set SeasonalRects[1] = gg_rct_LAND_2
set SeasonalRects[2] = gg_rct_LAND_3
loop
exitwhen i > 2
set rectMinX[i] = GetRectMinX( SeasonalRects[i])
set rectMaxX[i] = GetRectMaxX( SeasonalRects[i])
set rectMinY[i] = GetRectMinY( SeasonalRects[i])
set rectMaxY[i] = GetRectMaxY( SeasonalRects[i])
set currentPosX[i] = rectMinX[i]
set currentPosY[i] = rectMinY[i]
set currentRectCompleted[i] = FALSE
set i = i + 1
endloop
// register change triggers
call DisableTrigger( SEASONAL_CHANGE_TRIGGER)
call TriggerAddAction( SEASONAL_CHANGE_TRIGGER, function SeasonChangeTerrain)
call DisableTrigger( SEASONAL_CHANGE_TRIGGER_EX)
call TriggerAddAction( SEASONAL_CHANGE_TRIGGER_EX, function SeasonChangeTerrainEx)
endfunction
endlibrary
ps: sry for the messy code, but the new forum messes up all code tags, I post. I did not figure out yet, how to post properly ...
pps: thank you for any help
Last edited: