- Joined
- Mar 3, 2006
- Messages
- 1,564
I am making this full screen inventory for the sake of learning, it uses too many nested loops and it hit the op limit so I split the code into different threads.
But I need to make some sort of a loop or a general routine that split automatically for any number of rows and/or columns.
JASS:
globals
string BIG_MSG
integer opLim = 0
integer MAX_OP_LIM = 1444
// Carry-Over (CO) variables
integer CO_pid = 0
integer CO_r = 0
integer CO_c = 0
integer CO_i = 0
integer CO_track_id = 0
real CO_x = 0.
real CO_x1 = 0.
real CO_y = 0.
real CO_y1 = 0.
integer PLAYER_INGAME_COUNT = 2
hashtable Data = InitHashtable()
string TRACK_MODEL = "war3mapImported\\Track75.mdx"
integer INV_ABILITY_ID = 'I000'
integer BASE_MODEL_ID = 'B000'
integer SELECTOR_MODEL_ID = 'B001'
integer MAX_ROW_COUNT = 22
integer MAX_COL_COUNT = 23
integer MAX_SIZE = MAX_ROW_COUNT * MAX_COL_COUNT
integer MAX_ITEMS
integer rowKey = 1
integer colKey = 21
integer trackKey = 41
integer itemTableKey = -100
real OFFSET_X = 83.75
real OFFSET_Y = OFFSET_X//84.00
real BORDER_SIZE = 100.00
real ICON_WIDTH = 80.00
real ICON_HEIGHT = 80.00
real BASE_X = - 2816
real BASE_Y = 2816
real H = 1.2 * RMaxBJ(( OFFSET_X * ( MAX_COL_COUNT - 1 ) )+ICON_WIDTH , ( OFFSET_Y * ( MAX_ROW_COUNT - 1 ) )+ICON_HEIGHT )
trigger onClick = CreateTrigger()
trigger onTrack = CreateTrigger()
trigger onOpen = CreateTrigger()
trigger onAquire = CreateTrigger()
timer cameraLockTimer = CreateTimer()
integer array groundItemId
integer array itemIcon
integer array itemType
ability array itemEffect
string array itemName
string array itemDescription
boolean array IsAnySlotSelected
boolean array IsInventoryOpened
integer array pRow
integer array pCol
integer array prevTrackId
integer array globalUnitId
camerasetup array inventoryCamera
camerasetup array initialCamera
endglobals
function itemDatabase takes nothing returns nothing
local integer i
set i = 1
set itemType[i] = i
set itemIcon[i] = 'Z000'
set groundItemId[i] = 'P000'
set itemName[i] = "Shaman Claw"
set itemDescription[i] = ""
set itemEffect[i] = null
call SaveInteger( Data , itemTableKey , groundItemId[i] , i )
set i = i + 1
set itemType[i] = i
set itemIcon[i] = 'Z001'
set groundItemId[i] = 'P001'
set itemName[i] = "Amulet"
set itemDescription[i] = ""
set itemEffect[i] = null
call SaveInteger( Data , itemTableKey , groundItemId[i] , i )
set i = i + 1
set itemType[i] = i
set itemIcon[i] = 'Z002'
set groundItemId[i] = 'P002'
set itemName[i] = "Orb of Fire"
set itemDescription[i] = ""
set itemEffect[i] = null
call SaveInteger( Data , itemTableKey , groundItemId[i] , i )
set i = i + 1
set itemType[i] = i
set itemIcon[i] = 'Z003'
set groundItemId[i] = 'P003'
set itemName[i] = "Orb of Frost"
set itemDescription[i] = ""
set itemEffect[i] = null
call SaveInteger( Data , itemTableKey , groundItemId[i] , i )
/*
set i = i + 1
set itemType[i] = i
set itemIcon[i] = 'Z003'
set groundItemId[i] = 'dust'
set itemName[i] = "Dust of Appearance"
set itemDescription[i] = ""
set itemEffect[i] = null
call SaveInteger( Data , itemTableKey , groundItemId[i] , i )
*/
set MAX_ITEMS = i
endfunction
function showInterface takes integer itemId , integer slotId returns nothing
local destructable d = LoadDestructableHandle( Data , itemId , slotId )
call ShowDestructable( d , true )
endfunction
function hideInterface takes integer itemId , integer slotId returns nothing
local destructable d = LoadDestructableHandle( Data , itemId , slotId )
if itemId != -1 then
call ShowDestructable( d , false )
endif
endfunction
function initiateInventoryForUnit takes unit whichUnit returns nothing
local integer r
local integer c
local integer trackId
local integer unitId = GetHandleId(whichUnit)
local player p = GetOwningPlayer(whichUnit)
local integer pid = GetPlayerId(p)
call UnitAddAbility( whichUnit , INV_ABILITY_ID )
set r = 1
loop
exitwhen r > MAX_ROW_COUNT
set c = 1
loop
exitwhen c > MAX_COL_COUNT
set trackId = LoadInteger( Data , -pid - trackKey , r * MAX_SIZE + c )
call SaveInteger( Data , unitId , trackId , -1 )
set c = c + 1
endloop
set r = r + 1
endloop
endfunction
function loadInventoryForUnit takes unit whichUnit returns nothing
local integer r
local integer c
local integer trackId
local integer itemId
local integer unitId = GetHandleId(whichUnit)
local player p = GetOwningPlayer(whichUnit)
local integer pid = GetPlayerId(p)
set r = 1
loop
exitwhen r > MAX_ROW_COUNT
set c = 1
loop
exitwhen c > MAX_COL_COUNT
set trackId = LoadInteger( Data , -pid - trackKey , r * MAX_SIZE + c )
set itemId = LoadInteger( Data , unitId , trackId )
call showInterface( itemId , trackId )
set c = c + 1
endloop
set r = r + 1
endloop
endfunction
function onClick_Actions takes nothing returns nothing
local integer unitId
local integer trackId
local integer pid
local trackable trigTrack
local player trigPlayer
local integer row
local integer col
local integer previousItemId
local integer currentItemId
local destructable selector
set trigPlayer = GetLocalPlayer()
set pid = GetPlayerId( trigPlayer )
set trigTrack = GetTriggeringTrackable()
set trackId = GetHandleId( trigTrack )
set unitId = globalUnitId[pid]
set row = LoadInteger( Data , -pid - rowKey , trackId )
set col = LoadInteger( Data , -pid - colKey , trackId )
if IsAnySlotSelected[pid] == false then
set pRow[pid] = row
set pCol[pid] = col
set prevTrackId[pid] = trackId
// Show Selector
set selector = LoadDestructableHandle( Data , -2 , trackId )
call ShowDestructable( selector , true )
set IsAnySlotSelected[pid] = true
else
// Get item Id in slot pRow,pCol
set previousItemId = LoadInteger( Data , unitId , prevTrackId[pid] )
// Get item Id in slot r,c
set currentItemId = LoadInteger( Data , unitId , trackId )
// swap slot item ids data
if previousItemId != currentItemId and previousItemId != -1 then
call SaveInteger( Data , unitId , trackId , previousItemId )
call SaveInteger( Data , unitId , prevTrackId[pid] , currentItemId )
// Showing and Hiding Interfaces
call showInterface(previousItemId,trackId)
call showInterface(currentItemId,prevTrackId[pid])
call hideInterface(previousItemId,prevTrackId[pid])
call hideInterface(currentItemId,trackId)
endif
// Hide Selector
set selector = LoadDestructableHandle( Data , -2 , prevTrackId[pid] )
call ShowDestructable( selector , false )
set IsAnySlotSelected[pid] = false
endif
endfunction
function onTrack_Actions takes nothing returns nothing
endfunction
function onOpen_Actions takes nothing returns nothing
local unit inventoryUnit = GetTriggerUnit()
local integer unitId = GetHandleId( inventoryUnit )
local player p = GetOwningPlayer( inventoryUnit )
local integer pid = GetPlayerId( p )
if ( GetLocalPlayer() == p ) then
set globalUnitId[pid] = unitId // a global variable that will be used in the 'onClick' and 'onTrack' function
if IsInventoryOpened[pid] == false then
set IsInventoryOpened[pid] = true
set initialCamera[pid] = GetCurrentCameraSetup()
call CameraSetupApplyForceDuration(inventoryCamera[pid] , true , 0 )
call loadInventoryForUnit( inventoryUnit )
else
set IsInventoryOpened[pid] = false
call CameraSetupApplyForceDuration(initialCamera[pid] , true , 0 )
endif
endif
endfunction
function fullInventory takes integer powerupId , unit aquiringUnit , integer pid returns nothing
local real x = GetUnitX( aquiringUnit )
local real y = GetUnitY( aquiringUnit )
call CreateItem(powerupId,x,y)
call SimError(Player(pid) , "Backpack Inventory is Full" )
endfunction
function getNextEmptySlot takes integer pid , integer unitId returns integer
local integer r
local integer c
local integer trackId
local integer itemId
set r = 1
loop
exitwhen r > MAX_ROW_COUNT
set c = 1
loop
exitwhen c > MAX_COL_COUNT
set trackId = LoadInteger( Data , -pid - trackKey , r * MAX_SIZE + c )
set itemId = LoadInteger( Data , unitId , trackId )
if itemId == -1 then
return trackId
endif
set c = c + 1
endloop
set r = r + 1
endloop
return -1
endfunction
function onAquire_Actions takes nothing returns nothing
local item aquiredItem = GetManipulatedItem()
local integer powerupId = GetItemTypeId( aquiredItem )
local integer i = LoadInteger( Data , itemTableKey , powerupId )
local unit aquiringUnit = GetTriggerUnit()
local integer unitId = GetHandleId(aquiringUnit)
local player p = GetOwningPlayer(aquiringUnit)
local integer pid = GetPlayerId(p)
local integer emptySlotId
set emptySlotId = getNextEmptySlot( pid , unitId)
if emptySlotId != -1 then
call SaveInteger( Data , unitId , emptySlotId , itemType[i] )
call showInterface( itemType[i] , emptySlotId )
else
call fullInventory( powerupId , aquiringUnit , pid )
endif
endfunction
function itemsConstruction takes nothing returns nothing
local integer i
local real x = CO_x
local real y = CO_y
local integer track_id = CO_track_id
local destructable temp_destruct
set i = 1
loop // Creating the dummy destructables for all available items
exitwhen i > MAX_ITEMS
set temp_destruct = CreateDestructable( itemIcon[i] , x , y , 0 , 1 , 0 )
call SaveDestructableHandle( Data , itemType[i] , track_id , temp_destruct )
call ShowDestructable( temp_destruct , false )
//set opLim = opLim + 1
// Check for operation limit of the thread
/*if opLim >= MAX_OP_LIM then
// Passing variables values to the Carry-Over variables
set CO_pid = pid
set CO_r = r
set CO_c = c
set CO_i = i
return
endif*/
set i = i + 1
endloop
endfunction
function slotConstruction takes nothing returns nothing
local integer pid = CO_pid
local real x1 = CO_x1
local real y1 = CO_y1
local real x = CO_x
local real y = CO_y
local integer r = 1
local integer c
local integer track_id
local trackable slotBase
local destructable temp_destruct
loop
exitwhen r > MAX_ROW_COUNT
set c = 1
loop
exitwhen c > MAX_COL_COUNT
set x = x1 + ( OFFSET_X * ( c - 1 ) )
set y = y1 - ( OFFSET_Y * ( r - 1 ) )
set slotBase = CreateTrackable( TRACK_MODEL , x , y , 0 )
set track_id = GetHandleId( slotBase )
//call TriggerSleepAction(0.0)
set BIG_MSG = "Player_ID: |cffFFCC00" + I2S(pid) +/*
*/ "|r, Row#: |cffFFCC00" + I2S(r) +/*
*/ "|r, Col#: |cffFFCC00" + I2S(c) +/*
*/ "|r,Trackable_ID: |cffFFCC00" + I2S(track_id) + "|r"
call DisplayTimedTextToPlayer(Player(0),0,0,60,BIG_MSG)
call SaveInteger( Data , -pid - rowKey , track_id , r)
call SaveInteger( Data , -pid - colKey , track_id , c)
call SaveInteger( Data , -pid - trackKey , r * MAX_SIZE + c , track_id )
call TriggerRegisterTrackableHitEvent ( onClick , slotBase )
call TriggerRegisterTrackableTrackEvent( onTrack , slotBase )
set temp_destruct = CreateDestructable( BASE_MODEL_ID , x , y , 0 , 1 , 0 )
call SaveDestructableHandle( Data , -1 , track_id , temp_destruct )
set temp_destruct = CreateDestructable( SELECTOR_MODEL_ID , x , y , 0 , 1 , 0 )
call SaveDestructableHandle( Data , -2 , track_id , temp_destruct )
call ShowDestructable( temp_destruct , false )
// Passing variables values to the Carry-Over variables
set CO_x = x
set CO_y = y
set CO_track_id = track_id
// Start a new thread
call ForForce(bj_FORCE_PLAYER[0],function itemsConstruction)
// Test Counter
set opLim = opLim + 1
set c = c + 1
endloop
set r = r + 1
endloop
//call BJDebugMsg("Construction Complete")
call DisplayTimedTextToPlayer(Player(0),0,0,60,I2S(opLim))
endfunction
function baseLayoutConstruction takes nothing returns nothing
local integer pid
local real x1
local real y1
local real x
local real y
local camerasetup temp_cam
//call BJDebugMsg(R2S(H)) // Displays the value that will be applied to Camera Field: Target Distance
set pid = 0
loop
exitwhen pid >= PLAYER_INGAME_COUNT
set x1 = BASE_X + pid * (( MAX_COL_COUNT * OFFSET_X) + BORDER_SIZE)
set y1 = BASE_Y //- pid * (( MAX_ROW_COUNT * OFFSET_Y) + BORDER_SIZE)
// Creating camera setups
set x = x1 + (( OFFSET_X * ( MAX_COL_COUNT - 1 ) )/2)
set y = y1 - (( OFFSET_Y * ( MAX_ROW_COUNT - 1 ) )/2)
set temp_cam = CreateCameraSetup()
call CameraSetupSetField( temp_cam, CAMERA_FIELD_ZOFFSET , 0.0 , 0.0)
call CameraSetupSetField( temp_cam, CAMERA_FIELD_ROTATION , 90.0 , 0.0)
call CameraSetupSetField( temp_cam, CAMERA_FIELD_ANGLE_OF_ATTACK, 270.0 , 0.0)
call CameraSetupSetField( temp_cam, CAMERA_FIELD_TARGET_DISTANCE, H , 0.0)
call CameraSetupSetField( temp_cam, CAMERA_FIELD_ROLL , 0.0 , 0.0)
call CameraSetupSetField( temp_cam, CAMERA_FIELD_FIELD_OF_VIEW , 120.0 , 0.0)
call CameraSetupSetField( temp_cam, CAMERA_FIELD_FARZ , 5000.0, 0.0)
call CameraSetupSetDestPosition(temp_cam, x , y , 0.0)
set inventoryCamera[pid] = temp_cam
// Passing variables values to the Carry-Over variables
set CO_pid = pid
set CO_x = x
set CO_x1 = x1
set CO_y = y
set CO_y1 = y1
// Start a new thread
call ForForce(bj_FORCE_PLAYER[0],function slotConstruction)
set pid = pid + 1
endloop
endfunction
function misc takes nothing returns nothing
call FogModifierStart(CreateFogModifierRect(Player(0),FOG_OF_WAR_VISIBLE,bj_mapInitialPlayableArea,true,false))
endfunction
function actn takes nothing returns nothing
if ( GetUnitTypeId(GetFilterUnit()) == 'Hpal' ) then
call initiateInventoryForUnit( GetEnumUnit() )
endif
endfunction
function init_units takes nothing returns nothing
set bj_wantDestroyGroup = true
call ForGroupBJ( GetUnitsInRectMatching(GetPlayableMapRect(), null), function actn )
endfunction
function InitTrig_FSI takes nothing returns nothing
call TriggerRegisterAnyUnitEventBJ( onOpen, EVENT_PLAYER_UNIT_SPELL_EFFECT )
call TriggerRegisterAnyUnitEventBJ( onAquire , EVENT_PLAYER_UNIT_PICKUP_ITEM )
call TriggerAddAction( onClick , function onClick_Actions )
call TriggerAddAction( onTrack , function onTrack_Actions )
call TriggerAddAction( onOpen , function onOpen_Actions )
call TriggerAddAction( onAquire , function onAquire_Actions )
call misc()
call itemDatabase()
call ForForce(bj_FORCE_PLAYER[0],function baseLayoutConstruction)
//call baseLayoutConstruction()
// initiate an empty inventory for an example unit
call initiateInventoryForUnit( gg_unit_Hpal_0012 )
call init_units()
call SelectUnit(gg_unit_Hpal_0012, true)
endfunction
But I need to make some sort of a loop or a general routine that split automatically for any number of rows and/or columns.