- Joined
- Dec 12, 2008
- Messages
- 7,385
Something's wrong the code I'm writing for my RecipeEngine.
My first method was a linked list of struct instances, but it needed about a hundred iterations if a hundred recipes were in the map.
My new method needs a maximum of 5 iterations if the item aquired is included in 5 recipes.
The problem is, the system only combines the items for the last created recipe =(
What could be the problem D=
I've been banging my head against the wall for 2 days now >.<
My first method was a linked list of struct instances, but it needed about a hundred iterations if a hundred recipes were in the map.
My new method needs a maximum of 5 iterations if the item aquired is included in 5 recipes.
The problem is, the system only combines the items for the last created recipe =(
JASS:
library RecipeEngine
globals
// The effect that appears on Recipe Compiling
private constant string EFFECT = "Abilities\\Spells\\Items\\AIem\\AIemTarget.mdl"
// The attachment point of the effect
private constant string ATTACHMENT = "origin"
endglobals
private keyword Init
struct Recipe
private Table recipeItemIds
private integer recipeResultId
private integer itemCountRecipe
private static Table recipeInstancePointers
private static Table recipeInstancePointersIndex
private static Table recipeDisassembleData
static boolean enabled
private static method getItem takes unit whichUnit, integer whichItem returns item
local integer index = 0
// Loop through the units inventory
loop
exitwhen index > 5
// Find the first item in his slot with the desired item id
if GetItemTypeId(UnitItemInSlot(whichUnit,index)) == whichItem then
// return that item
return UnitItemInSlot(whichUnit,index)
endif
// increase index
set index = index + 1
endloop
// else, return null
return null
endmethod
private method hasItems takes unit whichUnit returns boolean
local integer index0 = 0
local integer index1 = 1
local integer id
local integer array count
// Loop through the items in his inventory
loop
exitwhen index0 > 5
set id = GetItemTypeId(UnitItemInSlot(whichUnit,index0))
// if it's a null id, set it to -1 because 0 could
// be a value defaulted in the Table
if 0 == id then
set id = -1
endif
// We loop through the recipe items
loop
exitwhen index1 > 6
// If the current item is equal to one of the recipe items, we increase
// the number of items found by 1
// This was made to function with double items ('I000' and 'I000' in a recipe for example)
if id == this.recipeItemIds[index1] and count[index1] == 0 then
set count[index1] = 1
// if we found an item, we exit the loop
set index1 = 6
endif
// increase index
set index1 = index1 + 1
endloop
// We check if the number of items found is equal to the item count of the recipe
if count[1] + count[2] + count[3] + count[4] + count[5] + count[6] == this.itemCountRecipe then
// if yes, the unit has the items and we'd return true
return true
endif
// reconfigure indicies
set index0 = index0 + 1
set index1 = 1
endloop
// else, the unit doesn't have the items.
return false
endmethod
// This function returns the amount of empty
// slots in a units inventory
private static method inventorySpace takes unit whichUnit returns integer
local integer index = 0
local integer count = 0
// loop through all the inventory items
loop
exitwhen index > 5
// if the item is null, the space is empty
if UnitItemInSlot(whichUnit,index) == null then
// we increase the count
set count = count + 1
endif
// we increase the index
set index = index + 1
endloop
// return the space count
return count
endmethod
private static method run takes nothing returns boolean
local thistype this
local integer id = GetItemTypeId(GetManipulatedItem())
local integer index0 = 1
local integer index = 1
local unit whichUnit = GetTriggerUnit()
local item whichItem
// If the system is enabled, we run the algorithm
if thistype.enabled then
loop
// When the count of the pointers for an item to a recipe instance
// is less than the index, we exit the loop
exitwhen index0 > integer(recipeInstancePointersIndex[id])
// we set this = the current instance of the struct using the id of the item
// and the index
set this = recipeInstancePointers[id][index0]
// if the recipe isn't null and the unit has the items
if this != 0 and this.hasItems(whichUnit) then
// we loop through the correct recipe items and remove them
loop
exitwhen index > this.itemCountRecipe
call RemoveItem(thistype.getItem(whichUnit,this.recipeItemIds[index]))
set index = index + 1
endloop
// we add and destroy the sfx
call DestroyEffect(AddSpecialEffectTarget(EFFECT,whichUnit,ATTACHMENT))
// we create the recipe item
set whichItem = CreateItem(this.recipeResultId,GetUnitX(whichUnit),GetUnitY(whichUnit))
// we give it to the unit
call UnitAddItem(whichUnit,whichItem)
// we attach the instance of the struct to the item so we can easily
// disassemble it without any searches
set recipeDisassembleData[GetHandleId(whichItem)] = this
// we set the index to force the loop to exit
set index0 = recipeInstancePointersIndex[id]
endif
// we increase the index
set index0 = index0 + 1
endloop
endif
// we null the handles
set whichUnit = null
set whichItem = null
return false
endmethod
static method disassemble takes unit whichUnit, item whichItem returns boolean
local thistype this = recipeDisassembleData[GetHandleId(whichItem)]
local real whichUnitX = GetUnitX(whichUnit)
local real whichUnitY = GetUnitY(whichUnit)
local integer index = 1
// If the item instance isn't null and there's enough space
// in the units inventory, we continue.
if 0 != this and this.itemCountRecipe <= thistype.inventorySpace(whichUnit) + 1 then
// we disable the system to prevent reassembling
set thistype.enabled = false
// we remove the item
call RemoveItem(whichItem)
loop
// we give the unit all the items needed
exitwhen index > 6
if 0 != this.recipeItemIds[index] then
call UnitAddItem(whichUnit,CreateItem(this.recipeItemIds[index],whichUnitX,whichUnitY))
endif
// increase index
set index = index + 1
endloop
// enable the system
set thistype.enabled = true
// return true to indicate successful disassembling
return true
endif
// return false to indicate an error
return false
endmethod
static method create takes integer i1, integer i2, integer i3, integer i4, integer i5, integer i6, integer i7 returns thistype
local thistype this = thistype.allocate()
local integer index = 1
// The dynamic Table is used to avoid
// increasing the InstancePointersIndex multiple times.
// This way, searches are less redundant in the run method.
local Table booleans = Table.create()
set this.recipeItemIds = Table.create()
// If the item id isn't null
if i1 != 0 then
// we increase the pointers index/count by 1
set recipeInstancePointersIndex[i1] = recipeInstancePointersIndex[i1] + 1
// we set the item id pointer of the current index to this
set recipeInstancePointers[i1][recipeInstancePointersIndex[i1]]=this
// we increase the item count
set this.itemCountRecipe = this.itemCountRecipe + 1
// we set the item id in the Table to i1
set this.recipeItemIds[this.itemCountRecipe] = i1
// we set the boolean to true to indicate that we already configured the pointers
// of the current item id
set booleans.boolean[i1] = true
endif
// If the item id isn't null
if i2 != 0 then
// If we didn't encounter the id, we configure the pointers
if not booleans.boolean[i2] then
// we increase the pointers index/count by 1
set recipeInstancePointersIndex[i2] = recipeInstancePointersIndex[i2] + 1
// we set the item id pointer of the current index to this
set recipeInstancePointers[i2][recipeInstancePointersIndex[i2]] = this
// we set the boolean to true to indicate that we already configured the pointers
// of the current item id
set booleans.boolean[i2] = true
endif
// we increase the item count
set this.itemCountRecipe = this.itemCountRecipe + 1
// we set the item id in the Table to i2
set this.recipeItemIds[this.itemCountRecipe] = i2
endif
// If the item id isn't null
if i3 != 0 then
// If we didn't encounter the id, we configure the pointers
if not booleans.boolean[i3] then
// we increase the pointers index/count by 1
set recipeInstancePointersIndex[i3] = recipeInstancePointersIndex[i3] + 1
// we set the item id pointer of the current index to this
set recipeInstancePointers[i3][recipeInstancePointersIndex[i3]] = this
// we set the boolean to true to indicate that we already configured the pointers
// of the current item id
set booleans.boolean[i3] = true
endif
// we increase the item count
set this.itemCountRecipe = this.itemCountRecipe + 1
// we set the item id in the Table to i3
set this.recipeItemIds[this.itemCountRecipe] = i3
endif
// If the item id isn't null
if i4 != 0 then
// If we didn't encounter the id, we configure the pointers
if not booleans.boolean[i4] then
// we increase the pointers index/count by 1
set recipeInstancePointersIndex[i4] = recipeInstancePointersIndex[i4] + 1
// we set the item id pointer of the current index to this
set recipeInstancePointers[i4][recipeInstancePointersIndex[i4]] = this
// we set the boolean to true to indicate that we already configured the pointers
// of the current item id
set booleans.boolean[i4] = true
endif
// we increase the item count
set this.itemCountRecipe = this.itemCountRecipe + 1
// we set the item id in the Table to i4
set this.recipeItemIds[this.itemCountRecipe] = i4
endif
// If the item id isn't null
if i5 != 0 then
// If we didn't encounter the id, we configure the pointers
if not booleans.boolean[i5] then
// we increase the pointers index/count by 1
set recipeInstancePointersIndex[i5] = recipeInstancePointersIndex[i5] + 1
// we set the item id pointer of the current index to this
set recipeInstancePointers[i5][recipeInstancePointersIndex[i5]] = this
// we set the boolean to true to indicate that we already configured the pointers
// of the current item id
set booleans.boolean[i5] = true
endif
// we increase the item count
set this.itemCountRecipe = this.itemCountRecipe + 1
// we set the item id in the Table to i5
set this.recipeItemIds[this.itemCountRecipe] = i5
endif
// If the item id isn't null
if i6 != 0 then
// If we didn't encounter the id, we configure the pointers
if not booleans.boolean[i6] then
// we increase the pointers index/count by 1
set recipeInstancePointersIndex[i6] = recipeInstancePointersIndex[i6] + 1
// we set the item id pointer of the current index to this
set recipeInstancePointers[i6][recipeInstancePointersIndex[i6]] = this
// we set the boolean to true to indicate that we already configured the pointers
// of the current item id
set booleans.boolean[i6] = true
endif
// we increase the item count
set this.itemCountRecipe = this.itemCountRecipe + 1
// we set the item id in the Table to i6
set this.recipeItemIds[this.itemCountRecipe] = i6
endif
// we configure the id of the result
set this.recipeResultId = i7
// we destroy the dynamic table
call booleans.destroy()
// we return this
return this
endmethod
method destroy takes nothing returns nothing
call this.recipeItemIds.destroy()
call this.deallocate()
endmethod
implement Init
endstruct
private module Init
private static method onInit takes nothing returns nothing
local trigger t = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(t,EVENT_PLAYER_UNIT_PICKUP_ITEM)
call TriggerAddCondition(t,Condition(function thistype.run))
// we create the static tables
set thistype.recipeInstancePointersIndex = Table.create()
set thistype.recipeInstancePointers = Table.create()
set thistype.recipeDisassembleData = Table.create()
// we enable the system
set thistype.enabled=true
set t = null
endmethod
endmodule
// Optional Jass API
function CreateRecipe takes integer i1, integer i2, integer i3, integer i4, integer i5, integer i6, integer i7 returns Recipe
return Recipe.create(i1,i2,i3,i4,i5,i6,i7)
endfunction
function DestroyRecipe takes Recipe this returns nothing
call this.destroy()
endfunction
function EnableRecipes takes nothing returns nothing
set Recipe.enabled = true
endfunction
function DisableRecipes takes nothing returns nothing
set Recipe.enabled = false
endfunction
function RecipesEnabled takes nothing returns boolean
return Recipe.enabled
endfunction
function DisassembleItem takes unit u, item it returns boolean
return Recipe.disassemble(u,it)
endfunction
endlibrary
What could be the problem D=
I've been banging my head against the wall for 2 days now >.<
Last edited: