function EnableScriptUsage takes nothing returns nothing
endfunction
Name | Type | is_array | initial_value |
IFShop_Bagpack_Enabled | boolean | No | |
IFShop_Bagpack_Hero_Max_Distan | real | No | |
IFShop_Bagpack_Pick_SlotBased | boolean | No | |
IFShop_Bagpack_Shopper_First | boolean | No | |
IFShop_Bagpack_Timer | timer | No | |
IFShop_Buy_Zones | rect | Yes | |
IFShop_Buy_Zones_Excluded | force | Yes | |
IFShop_Buy_Zones_Last | integer | No | |
IFShop_Fusion_SFX_Path | string | No | |
IFShop_Gold | integer | No | |
IFShop_Is_Shopping | boolean | Yes | |
IFShop_Item_List_Fusions_Last | integer | No | |
IFShop_Item_Stack | item | Yes | |
IFShop_Item_Stack_Last | integer | No | |
IFShop_Item_Stack_Old_Custom | integer | Yes | |
IFShop_Item_Type | itemcode | No | |
IFShop_Item_Type_Fake | itemcode | No | |
IFShop_Loop_A | integer | No | |
IFShop_Mats | itemcode | Yes | |
IFShop_Page_Current | integer | Yes | |
IFShop_Page_Max | integer | Yes | |
IFShop_Page_Skill_Next | abilcode | No | |
IFShop_Page_Skill_Previous | abilcode | No | |
IFShop_Shop | unit | Yes | |
IFShop_Shop_Avaible_Fuse_Costs | integer | Yes | |
IFShop_Shop_Avaible_Fuse_Fakes | itemcode | Yes | |
IFShop_Shop_Avaible_Fuse_First | integer | Yes | |
IFShop_Shop_Avaible_Fuse_Last | integer | Yes | |
IFShop_Shop_Avaible_Fusions | integer | Yes | |
IFShop_Shop_Bagpack_Accessable | boolean | Yes | |
IFShop_Shop_LastTry | itemcode | Yes | |
IFShop_Shop_Shopper | unit | Yes | |
IFShop_Shop_Shopper_Bagpack | unit | Yes | |
IFShop_Shop_UnitType | unitcode | No | |
IFShop_Shopper | unit | No | |
IFShop_Shopper_Bagpack | unit | No | |
IFShop_Shopper_Count | integer | No | |
IFShop_SHOW_SHOP_AFTER_UPGRADE | boolean | No | |
IFShop_ShowMaxUpgrades | boolean | No | |
IFShop_Skill_Show_Upgrades | abilcode | No | |
IFShop_Sound_No_Gold | sound | No | |
IFShop_Stacksize_Each_Player | integer | No | |
IFShop_Table | hashtable | No | |
IFShop_VALUE_MARKEDITEM | integer | No |
//==========================//
// Item Fusion Shop 1.6 //
//==========================//
// By Tasyen
// -------------------------------
// What is Item Fusion Shop?
//--------------------------
//Item fusion shop is a Recipe System showing avaiable upgrades of an item inside the Warcraft basic user interface.
//The system calculates the needed gold cost and regards items already obtained by the hero and its backpack if wanted.
//This way the player gets control over the fusions he want to do and it feels like visiting a shop in basic Warcraft 3.
// API Fusion Creation
// function AddFusion takes integer fusion, integer fake, integer mat0, integer mat1, integer mat2, integer mat3, integer mat4, integer mat5, integer mat6 returns boolean
// Creates a Fusion with Mat 0 to 6 returns false if the Fake-Fusion combination already was registered.
// You need to set all mats, with a ItemTypeId or 0 for not needed.
// function AddFusionMat takes integer mat, integer fake returns nothing
// Adds a Material component to the plan
// expects ItemTypeId
// function AddFusionMatLastFusion takes integer mat returns nothing
// Wraper function for AddFusionMat for the Last register Fusion
// function CreateFusion takes integer fusion, integer fake returns boolean
// Creates a Fusion without material
// returns false if the Fake-Fusion combination already was registered.
// API Show Shop
// function IsInShopZone takes unit u returns boolean
// Checks if the unit is inside an BuyZone which his owner can use.
// This should be used before calling ShowShop, but is not requiered.
// function ShowShop takes integer playerIndex, unit shopper, unit bagpack, integer itemType returns nothing
// this will show the shop the owner of shopper
// if you set itemType = 0 all items in the inventory will be considered, on not 0 it will only show upgrades for that specific itemType.
// API for getting fusions (not needed on default usage)
// function CalcCostOfAll takes integer playerIndex, unit shopper, unit bagpack returns nothing
// calcs the goldcosts regarding owned items from the two units.
// into udg_IFShop_Shop_Avaible_Fuse_Costs
// you should fill the list with GetAvailableFusions before using this.
// function AvailableFusionsReset takes integer playerIndex returns nothing^
// Resets the listvariables at playerIndex.
// function GetAvailableFusions takes integer itemType, integer playerIndex returns nothing
// Loads all upgrades of the itemType into udg_IFShop_Shop_Avaible_Fuse_Fakes, udg_IFShop_Shop_Avaible_Fusions
// MPI based access udg_IFShop_Shop_Avaible_Fuse_First,udg_IFShop_Shop_Avaible_Fuse_Last
// udg_IFShop_ShowMaxUpgrades enables to show itemtypes upgrade's upgrade...,
//hashtable saved:
// Normal items:
//
// +side = beeing material in fake
// 0 = Goldvalue
// -side = built ways
// fakes = Plans
// 0 = -1 easy identyfier
// 1 = result
// 2 = Mat amount
// 3+ = Mats
// The intervale in which the System rechecks Bagpack accessability
constant function GetBagpackIntervall takes nothing returns real
return 0.4
endfunction
//WC3 v1.28.5 returns 11.
//With something higher then 11 it will not work.
constant function GetFirstPageMaxEntry takes nothing returns integer
return bj_MAX_STOCK_ITEM_SLOTS
endfunction
//this are the number of Items each page shows as soon the avaiable options exceed 11.
//Beaware that setting this to something higher than 9 is not working (2 pagecontrol +1 target control) (Wc3 V1.28.5)
constant function GetPageMaxEntry takes nothing returns integer
return 9
endfunction
//System constants
//The OrderId of select ShopTarget.
constant function SelectShopTarget takes nothing returns integer
return 852566
endfunction
constant function AbiltiyIdSellItems takes nothing returns integer
return 'Asid'
endfunction
constant function GetTabelIndexItem takes nothing returns integer
return 1
endfunction
constant function GetTabelIndexFake takes nothing returns integer
return 0
endfunction
constant function GetTabelIndexMatsAmount takes nothing returns integer
return 2
endfunction
constant function GetTabelIndexMatsStart takes nothing returns integer
return 3
endfunction
//Is this buildway already registered?
function IsItemAncestor takes integer itemType, integer fake returns boolean
local integer index = 0
local integer ancestor
//find next free ancestor spot
loop
set index = index -1
set ancestor = LoadInteger(udg_IFShop_Table,itemType,index)
exitwhen ancestor == 0
if ancestor == fake then
return true
endif
endloop
return false
endfunction
//Returns the already existing amount of builtways for an item
function ItemAncestorsAmount takes integer itemType returns integer
local integer index = 0
//find next free ancestor spot
loop
set index = index -1
exitwhen LoadInteger(udg_IFShop_Table,itemType,index) == 0
endloop
return - (index + 1)
endfunction
//Remember that this item can be built by this fake.
//Builtways are saved at the "-" Side.
function SaveItemAncestor takes integer itemType, integer fake returns nothing
local integer index = 0
if fake == 0 then
return
endif
//find next free ancestor spot
loop
set index = index -1
exitwhen LoadInteger(udg_IFShop_Table,itemType,index) == 0
endloop
call SaveInteger(udg_IFShop_Table, itemType, index, fake)
endfunction
//Remebers that this item is used in fake as material
//Beeing Material is at the "+" side.
function SaveItemIsMatInPlan takes integer itemType, integer fake returns nothing
local integer index = 0
if fake == 0 then
return
endif
//find next free ancestor spot
loop
set index = index +1
//Already know this mat can be used in this plan?
if LoadInteger(udg_IFShop_Table,itemType,index) == fake then
return
endif
exitwhen LoadInteger(udg_IFShop_Table,itemType,index) == 0
endloop
call SaveInteger(udg_IFShop_Table, itemType, index, fake)
endfunction
//The most important API action
//It creates an new way to built an Fusion.
//taking up to 7 mats as argument ( this is not the max limit)
function AddFusion takes integer fusion, integer fake, integer mat0, integer mat1, integer mat2, integer mat3, integer mat4, integer mat5, integer mat6 returns boolean
local integer amount = -1
//Is Fake already added to the Pool? returns false if it is.
if fusion == 0 or fake == 0 or fake == fusion then
call DisplayTimedTextToPlayer( GetLocalPlayer(),0,0, 30, "|cffff0000Error|r: - Try registering fusion:" )
call DisplayTimedTextToPlayer( GetLocalPlayer(),0,0, 30, "|cffffff00Fusion|r: " +GetObjectName(fusion) )
call DisplayTimedTextToPlayer( GetLocalPlayer(),0,0, 30, "|cffffff00Fake|r: " +GetObjectName(fake) )
return false
endif
if IsItemAncestor(fusion,fake) then
call DisplayTimedTextToPlayer( GetLocalPlayer(),0,0, 30, "|cffff0000Error|r: - This was already registered" )
call DisplayTimedTextToPlayer( GetLocalPlayer(),0,0, 30, "|cffffff00Fusion|r: " +GetObjectName(fusion) )
call DisplayTimedTextToPlayer( GetLocalPlayer(),0,0, 30, "|cffffff00Fake|r: " +GetObjectName(fake) )
return false
endif
//PrintOut multiple Builtways in Single player, might be an possible error.
if bj_isSinglePlayer then
if ItemAncestorsAmount(fusion) != 0 then
call DisplayTimedTextToPlayer( GetLocalPlayer(),0,0, 30, "|cffffff00Singpleplayer Info|r: "+GetObjectName(fusion) +" can be built by: "+I2S(ItemAncestorsAmount(fusion)+1)+" ways." )
endif
endif
call SaveItemAncestor(fusion, fake)
//savedlast create fusion plan
set udg_IFShop_Item_List_Fusions_Last = fake
//Save Fusion and Fake
call SaveInteger( udg_IFShop_Table, fake, GetTabelIndexItem(), fusion)
call SaveInteger( udg_IFShop_Table, fake, GetTabelIndexFake(), -1 )
//Check for Mats and save them at nearest slot
if( mat0 != 0) then
set amount = amount + 1
call SaveInteger(udg_IFShop_Table, fake, GetTabelIndexMatsStart()+amount, mat0)
call SaveItemIsMatInPlan(mat0, fake)
endif
if( mat1 != 0) then
set amount = amount + 1
call SaveInteger(udg_IFShop_Table, fake, GetTabelIndexMatsStart()+amount, mat1)
call SaveItemIsMatInPlan(mat1, fake)
endif
if( mat2 != 0) then
set amount = amount + 1
call SaveInteger(udg_IFShop_Table, fake, GetTabelIndexMatsStart()+amount, mat2)
call SaveItemIsMatInPlan(mat2, fake)
endif
if( mat3 != 0) then
set amount = amount + 1
call SaveInteger(udg_IFShop_Table, fake, GetTabelIndexMatsStart()+amount, mat3)
call SaveItemIsMatInPlan(mat3, fake)
endif
if( mat4 != 0) then
set amount = amount + 1
call SaveInteger(udg_IFShop_Table, fake, GetTabelIndexMatsStart()+amount, mat4)
call SaveItemIsMatInPlan(mat4, fake)
endif
if( mat5 != 0) then
set amount = amount + 1
call SaveInteger(udg_IFShop_Table, fake, GetTabelIndexMatsStart()+amount, mat5)
call SaveItemIsMatInPlan(mat5, fake)
endif
if( mat6 != 0) then
set amount = amount + 1
call SaveInteger(udg_IFShop_Table, fake, GetTabelIndexMatsStart()+amount, mat6)
call SaveItemIsMatInPlan(mat6, fake)
endif
call SaveInteger( udg_IFShop_Table, fake, GetTabelIndexMatsAmount(), amount)
return true
endfunction
//Adds material to fake.
//both are
function AddFusionMat takes integer mat, integer fake returns nothing
local integer amount
//Ignore calls with no ItemType
if( mat != 0 and fake != 0) then
set amount = LoadInteger(udg_IFShop_Table, fake, GetTabelIndexMatsAmount())+1
call SaveInteger( udg_IFShop_Table, fake, GetTabelIndexMatsAmount(), amount)
call SaveInteger(udg_IFShop_Table, fake, GetTabelIndexMatsStart()+amount, mat)
call SaveItemIsMatInPlan(mat, fake)
endif
endfunction
//Add an material to the last created Fake
function AddFusionMatLastFusion takes integer mat returns nothing
call AddFusionMat(mat, udg_IFShop_Item_List_Fusions_Last)
endfunction
//Creates an fusion without mats.
function CreateFusion takes integer fusion, integer fake returns boolean
//Is Fake already added to the Pool? returns false if it is.
if fusion == 0 or fake == 0 or fake == fusion then
call DisplayTimedTextToPlayer( GetLocalPlayer(),0,0, 30, "|cffff0000Error|r: - Try registering fusion:" )
call DisplayTimedTextToPlayer( GetLocalPlayer(),0,0, 30, "|cffffff00Fusion|r: " +GetObjectName(fusion) )
call DisplayTimedTextToPlayer( GetLocalPlayer(),0,0, 30, "|cffffff00Fake|r: " +GetObjectName(fake) )
return false
endif
if IsItemAncestor(fusion,fake) then
call DisplayTimedTextToPlayer( GetLocalPlayer(),0,0, 30, "|cffff0000Error|r: - This was already registered" )
call DisplayTimedTextToPlayer( GetLocalPlayer(),0,0, 30, "|cffffff00Fusion|r: " +GetObjectName(fusion) )
call DisplayTimedTextToPlayer( GetLocalPlayer(),0,0, 30, "|cffffff00Fake|r: " +GetObjectName(fake) )
return false
endif
//PrintOut multiple Builtways in Single player, might be an possible error.
if bj_isSinglePlayer then
if ItemAncestorsAmount(fusion) != 0 then
call DisplayTimedTextToPlayer( GetLocalPlayer(),0,0, 30, "|cffffff00Singpleplayer Info|r: "+GetObjectName(fusion) +" can be built by: "+I2S(ItemAncestorsAmount(fusion)+1)+" ways." )
endif
endif
//Inc Pool Size
set udg_IFShop_Item_List_Fusions_Last = fake
call SaveItemAncestor(fusion, fake)
//Save ItemTypes and mat amount
call SaveInteger( udg_IFShop_Table, fake, GetTabelIndexItem(), fusion)
call SaveInteger( udg_IFShop_Table, fake, GetTabelIndexFake(), fake )
call SaveInteger( udg_IFShop_Table, fake, GetTabelIndexMatsAmount(), -1)
return true
endfunction
//Updates the shop for this Player.
//Uses GUI Indexing Red = 1 blue = 2
function UpdateShop takes integer playerIndex returns nothing
local integer Loop_A
local integer Loop_A_End
local integer itemType
//Clear Shop
call UnitRemoveAbility( udg_IFShop_Shop[playerIndex] , AbiltiyIdSellItems() )
call UnitAddAbility( udg_IFShop_Shop[playerIndex] , AbiltiyIdSellItems() )
//Is Multipaging needed?
if( udg_IFShop_Page_Max[playerIndex] > 0) then
//Get Current-Page ItemTypes
set Loop_A = ( udg_IFShop_Shop_Avaible_Fuse_First[playerIndex] + ( GetPageMaxEntry() * udg_IFShop_Page_Current[playerIndex] ) )
set Loop_A_End = Loop_A + (GetPageMaxEntry()-1)
if Loop_A_End > udg_IFShop_Shop_Avaible_Fuse_Last[playerIndex] then
set Loop_A_End = udg_IFShop_Shop_Avaible_Fuse_Last[playerIndex]
endif
//Add Page Controll
call UnitAddAbility( udg_IFShop_Shop[playerIndex] ,udg_IFShop_Page_Skill_Next )
call UnitAddAbility( udg_IFShop_Shop[playerIndex] ,udg_IFShop_Page_Skill_Previous )
else
//Remove Page Controll
call UnitRemoveAbility( udg_IFShop_Shop[playerIndex], udg_IFShop_Page_Skill_Next )
call UnitRemoveAbility( udg_IFShop_Shop[playerIndex], udg_IFShop_Page_Skill_Previous )
//Get ItemTypes
set Loop_A = udg_IFShop_Shop_Avaible_Fuse_First[playerIndex]
set Loop_A_End = udg_IFShop_Shop_Avaible_Fuse_Last[playerIndex]
endif
loop
exitwhen Loop_A > Loop_A_End
set itemType = udg_IFShop_Shop_Avaible_Fuse_Fakes[Loop_A]
//Does Upgrade costs Gold? 0 Costs = 1 Charge
if(udg_IFShop_Shop_Avaible_Fuse_Costs[Loop_A]!=0)then
call AddItemToStock(udg_IFShop_Shop[playerIndex], udg_IFShop_Shop_Avaible_Fuse_Fakes[Loop_A], udg_IFShop_Shop_Avaible_Fuse_Costs[Loop_A], udg_IFShop_Shop_Avaible_Fuse_Costs[Loop_A])
else
call AddItemToStock(udg_IFShop_Shop[playerIndex], udg_IFShop_Shop_Avaible_Fuse_Fakes[Loop_A], 1, 1)
endif
set Loop_A = Loop_A + 1
endloop
endfunction
function HideShop_Condition takes nothing returns boolean
return ( GetUnitTypeId(GetTriggerUnit()) == udg_IFShop_Shop_UnitType )
endfunction
//When one deselects the shop hide it.
function HideShop_Action takes nothing returns nothing
local integer playerIndex = GetPlayerId( GetTriggerPlayer() ) + 1
//Clear and Hide Shop
call UnitRemoveAbility( udg_IFShop_Shop[playerIndex] , AbiltiyIdSellItems() )
call ShowUnit(GetTriggerUnit(),false)
set udg_IFShop_Is_Shopping[playerIndex] = false
set udg_IFShop_Shopper_Count = udg_IFShop_Shopper_Count - 1
//If none is shopping disable Backpack loop checking.
if(udg_IFShop_Shopper_Count == 0) then
call PauseTimer( udg_IFShop_Bagpack_Timer )
endif
endfunction
function SwitchPage_Conditions takes nothing returns boolean
return (GetSpellAbilityId() == udg_IFShop_Page_Skill_Next or GetSpellAbilityId() == udg_IFShop_Page_Skill_Previous)
endfunction
//When an shop casts a spell
function SwitchPage_Action takes nothing returns nothing
local integer playerIndex = GetPlayerId(GetTriggerPlayer()) + 1
//Next Page used?
if( GetSpellAbilityId() == udg_IFShop_Page_Skill_Next ) then
set udg_IFShop_Page_Current[playerIndex] = ( udg_IFShop_Page_Current[playerIndex] + 1 )
//Return to Page 0?
if ( udg_IFShop_Page_Current[playerIndex] > udg_IFShop_Page_Max[playerIndex]) then
set udg_IFShop_Page_Current[playerIndex] = 0
endif
else
//Previous Page.
set udg_IFShop_Page_Current[playerIndex] = ( udg_IFShop_Page_Current[playerIndex] - 1 )
//Return to max Max?
if ( udg_IFShop_Page_Current[playerIndex] < 0) then
set udg_IFShop_Page_Current[playerIndex] = udg_IFShop_Page_Max[playerIndex]
endif
endif
call UpdateShop(playerIndex)
endfunction
//Checks if the unit is inside an BuyZone whiche his owner can use.
// This should be used before calling ShowShop
function IsInShopZone takes unit u returns boolean
local real x = GetUnitX(u)
local real y = GetUnitY(u)
local integer Loop_A=0
//loop All Registere Buyzones.
loop
exitwhen Loop_A > udg_IFShop_Buy_Zones_Last
//Is Shopper inside BuyZone and is his owner allowed to use it? yes = true
if ( RectContainsCoords(udg_IFShop_Buy_Zones[Loop_A], x,y) and not (IsPlayerInForce ( GetOwningPlayer (u), udg_IFShop_Buy_Zones_Excluded[Loop_A] )) ) then
return true
endif
set Loop_A = Loop_A + 1
endloop
return false
endfunction
function IsBagPackAvaible takes unit shopper, unit bagpack returns boolean
local real dx = GetUnitX(shopper)- GetUnitX(bagpack)
local real dy = GetUnitY(shopper)- GetUnitY(bagpack)
//null Pointer?
if GetUnitTypeId (bagpack) == 0 then
return false
endif
//Developer don't want Bagpack?
if not(udg_IFShop_Bagpack_Enabled)then
return false
endif
//Bagpack is alive?
if GetUnitState(bagpack, UNIT_STATE_LIFE) <= 0.45 then
return false
endif
//In Range Check?
if( SquareRoot(dx * dx + dy * dy) > udg_IFShop_Bagpack_Hero_Max_Distan ) then
return false
endif
return true
endfunction
//Helper Function
//Saves old Custom Value and loads into the stack
function CheckAndMarkItem takes item mat, integer itemType returns boolean
//Filters other Item Types, Marked Items and Not existing items
if(itemType != GetItemTypeId(mat) or GetItemUserData(mat) == udg_IFShop_VALUE_MARKEDITEM or mat == null ) then
return false
endif
//call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,10, GetItemName(mat))
//Inser into Item stack and Mark it.
set udg_IFShop_Item_Stack_Last = ( udg_IFShop_Item_Stack_Last + 1 )
set udg_IFShop_Item_Stack[udg_IFShop_Item_Stack_Last] = mat
set udg_IFShop_Item_Stack_Old_Custom[udg_IFShop_Item_Stack_Last] = GetItemUserData(mat)
call SetItemUserData( mat, udg_IFShop_VALUE_MARKEDITEM )
return true
endfunction
//Resets the found itemTypes stack for this player.
//Playerindexes are in this system overall GUI-Like
//But if you do not use the shops you don't have care about that.
function AvailableFusionsReset takes integer playerIndex returns nothing
set udg_IFShop_Shop_Avaible_Fuse_First[playerIndex] = ( udg_IFShop_Stacksize_Each_Player * playerIndex )
set udg_IFShop_Shop_Avaible_Fuse_Last[playerIndex] = ( udg_IFShop_Shop_Avaible_Fuse_First[playerIndex] - 1 )
set udg_IFShop_Page_Max[playerIndex] = 0
set udg_IFShop_Page_Current[playerIndex] = 0
endfunction
function GetAvailableFusions takes integer itemType, integer playerIndex returns nothing
local integer Loop_B = 1
local integer Loop_A = 0
local integer fake
local integer counter = ( udg_IFShop_Shop_Avaible_Fuse_Last[playerIndex] - udg_IFShop_Shop_Avaible_Fuse_First[playerIndex]) +1
local boolean skip
//Loop the Material of current Fusion
loop
//Exceeds Players Array Size? yes -> stop. Should normally not happen.
if ( counter >= udg_IFShop_Stacksize_Each_Player ) then
//show Stacksize to small only in singleplayer.
if bj_isSinglePlayer then
call DisplayTimedTextToPlayer( GetLocalPlayer(),0,0, 30, "|cffff0000Error|r:|nStacksize for each Player reached its Limit.|nPlease Increase its Value in IFS Init General to show all Upgrades corretly" )
endif
return
endif
set fake = LoadInteger(udg_IFShop_Table, itemType, Loop_B)
set skip = false
exitwhen fake == 0
//filter out duplicates.
set Loop_A = udg_IFShop_Shop_Avaible_Fuse_First[playerIndex]
loop
exitwhen Loop_A > udg_IFShop_Shop_Avaible_Fuse_Last[playerIndex] or skip
if fake == udg_IFShop_Shop_Avaible_Fuse_Fakes[Loop_A] then
set skip = true
endif
set Loop_A = Loop_A +1
endloop
// if no duplicate load it in.
if not skip then
set udg_IFShop_Shop_Avaible_Fuse_Last[playerIndex] = ( udg_IFShop_Shop_Avaible_Fuse_Last[playerIndex] + 1 )
set udg_IFShop_Shop_Avaible_Fusions[udg_IFShop_Shop_Avaible_Fuse_Last[playerIndex]] = LoadInteger(udg_IFShop_Table, fake, GetTabelIndexItem())
//call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,10, "Found: "+GetObjectName(fake))
set udg_IFShop_Shop_Avaible_Fuse_Fakes[udg_IFShop_Shop_Avaible_Fuse_Last[playerIndex]] = fake
set counter = counter + 1
//Is a new Page needed? First Page exceeds by 12 further ones with 9 * x
if (counter == GetFirstPageMaxEntry() + 1 ) or ( udg_IFShop_Page_Max[playerIndex] != 0 and ModuloInteger(counter, GetPageMaxEntry()) == 0 ) then
set udg_IFShop_Page_Max[playerIndex] = ( udg_IFShop_Page_Max[playerIndex] + 1 )
endif
//Find Upgrade's Upgrades?
if udg_IFShop_ShowMaxUpgrades then
call GetAvailableFusions(udg_IFShop_Shop_Avaible_Fusions[udg_IFShop_Shop_Avaible_Fuse_Last[playerIndex]],playerIndex)
endif
endif
set Loop_B = Loop_B + 1
endloop
endfunction
function CheckInventory takes unit u, integer itemType returns boolean
local integer Loop_B = 0
//Checks Full Inventory
loop
exitwhen Loop_B == bj_MAX_INVENTORY
if CheckAndMarkItem(UnitItemInSlot(u, Loop_B), itemType) then
return true
else
set Loop_B = Loop_B + 1
endif
endloop
return false
endfunction
function CheckInventorySlotBased takes unit first, unit second, integer itemType returns boolean
local integer Loop_B = 0
//Checks Shopper Bagpacks Items in turns.
loop
exitwhen Loop_B == bj_MAX_INVENTORY
if CheckAndMarkItem(UnitItemInSlot(first, Loop_B), itemType) then
return true
endif
if CheckAndMarkItem(UnitItemInSlot(second, Loop_B), itemType) then
return true
endif
set Loop_B = Loop_B + 1
endloop
return false
endfunction
//Unmarks Items starting from start and setting size to the approached amount
function UnmarkItems takes integer start returns nothing
local integer Loop_A = start
loop
exitwhen Loop_A > udg_IFShop_Item_Stack_Last
call SetItemUserData( udg_IFShop_Item_Stack[Loop_A], udg_IFShop_Item_Stack_Old_Custom[Loop_A] )
set Loop_A = Loop_A +1
endloop
set udg_IFShop_Item_Stack_Last = start - 1
endfunction
function GetSubFusions takes integer playerIndex, unit shopper, unit bagpack, integer fake returns integer
local integer Loop_A = GetTabelIndexMatsStart()
local integer Loop_B = -1
local integer subChoosen = Loop_B
local integer subCurrent
local integer subChoosenGold
local integer subCurrentGold
local integer costs = 0
local integer unmarkStart
local integer itemType
local boolean matAvailable
local integer subChoosenTry
loop
set itemType = LoadInteger(udg_IFShop_Table, fake, Loop_A )
exitwhen itemType == null
set matAvailable = false
//Followng Defines the Order of accessing the inventories.
//Is No Bagpack used or not allowed? yes -> simply check the Shopper.
if not( udg_IFShop_Shop_Bagpack_Accessable[playerIndex] ) then
set matAvailable = CheckInventory(shopper,itemType)
else
//Check Inventories in Turns?
if udg_IFShop_Bagpack_Pick_SlotBased then
//In Turns; Start with who?
if udg_IFShop_Bagpack_Shopper_First then
set matAvailable = CheckInventorySlotBased(shopper,bagpack,itemType)
else
set matAvailable = CheckInventorySlotBased(bagpack,shopper,itemType)
endif
else
//Slotbased
//Start with Shopper?
if udg_IFShop_Bagpack_Shopper_First then
set matAvailable = CheckInventory(shopper,itemType)
//Still missing?
if not (matAvailable) then
set matAvailable = CheckInventory(bagpack,itemType)
endif
else
set matAvailable = CheckInventory(bagpack,itemType)
if not (matAvailable) then
set matAvailable = CheckInventory(shopper,itemType)
endif
endif
endif
endif
//Mat unavaible?
if not (matAvailable) then
//Is Mat a Fusion? yes -> search for sub Material; Recursiv
//Fusionitems have numbers saved in the "-" side aka built ways
if(LoadInteger( udg_IFShop_Table, itemType, -1) != 0) then
//Remember Index from where to unmark.
//Without this sets the loop below won't work in recursion, why ever i had them before at the local init but it didn't work.
set unmarkStart = udg_IFShop_Item_Stack_Last+1
set subChoosenGold = 99999
set Loop_B = -1
//Loop all Builtways of this item and choose the cheapest.
loop
set subCurrent = LoadInteger(udg_IFShop_Table,itemType,Loop_B)
exitwhen subCurrent == 0
call UnmarkItems(unmarkStart)
set subCurrentGold = GetSubFusions(playerIndex, shopper, bagpack, subCurrent )
//Calced one Cheaper then cheapest?
if subCurrentGold < subChoosenGold then
set subChoosenTry = Loop_B
set subChoosen = subCurrent
set subChoosenGold = subCurrentGold
endif
set Loop_B = Loop_B - 1
endloop
//mark + Load choosen items again
//if was not found on last try
if subChoosenTry != Loop_B + 1 then
call UnmarkItems(unmarkStart)
call GetSubFusions(playerIndex, shopper, bagpack, subChoosen )
endif
set costs = costs + subChoosenGold
else
//No Fusion; Increment Gold if wanted.
set costs = costs + LoadInteger(udg_IFShop_Table, itemType, 0)
endif
endif
set Loop_A = Loop_A + 1
endloop
//call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,10, I2S(udg_IFShop_Item_Stack_Last))
return costs
endfunction
//This called to calculate Gold Costs of all avaibleFusions for this player.
function CalcCostOfAll takes integer playerIndex, unit shopper, unit bagpack returns nothing
local integer Loop_A = udg_IFShop_Shop_Avaible_Fuse_First[playerIndex]
call UnmarkItems(0)
//loop all Upgrade Options
loop
exitwhen Loop_A > udg_IFShop_Shop_Avaible_Fuse_Last[playerIndex]
set udg_IFShop_Shop_Avaible_Fuse_Costs[Loop_A] = GetSubFusions(playerIndex,shopper,bagpack,udg_IFShop_Shop_Avaible_Fuse_Fakes[Loop_A])
call UnmarkItems(0)
set Loop_A = Loop_A + 1
endloop
endfunction
function TimerBagpackAccesable takes nothing returns nothing
local integer playerIndex = 1
local boolean isAvaible=false
//loop all Players
loop
exitwhen playerIndex > bj_MAX_PLAYERS
if(udg_IFShop_Is_Shopping[playerIndex]) then
set isAvaible = IsBagPackAvaible (udg_IFShop_Shop_Shopper[playerIndex],udg_IFShop_Shop_Shopper_Bagpack[playerIndex])
//Bagpack accessability Changed?
if(udg_IFShop_Shop_Bagpack_Accessable[playerIndex] != isAvaible) then
//Access Changed Recalc Gold Costs.
set udg_IFShop_Shop_Bagpack_Accessable[playerIndex] = isAvaible
call CalcCostOfAll(playerIndex,udg_IFShop_Shop_Shopper[playerIndex],udg_IFShop_Shop_Shopper_Bagpack[playerIndex])
call UpdateShop(playerIndex)
endif
endif
set playerIndex = playerIndex + 1
endloop
endfunction
function ShowShop takes integer playerIndex, unit shopper, unit bagpack, integer itemType returns nothing
local integer Loop_A = 0
set udg_IFShop_Shop_Bagpack_Accessable[playerIndex] = IsBagPackAvaible(shopper,bagpack)
//GetAvailableFusions only if not the same as last try or it is 0 aka whole inventory?
if udg_IFShop_Shop_LastTry[playerIndex] != itemType or itemType == 0 then
set udg_IFShop_Shop_LastTry[playerIndex] = itemType
call AvailableFusionsReset(playerIndex)
//specific item
if itemType != 0 then
call GetAvailableFusions(itemType,playerIndex)
else
//Non specific item show all avaible Upgrades of all items in shopper's and bagpack's inventory
//Load Inventory
set Loop_A = 0
//Hero
loop
exitwhen Loop_A == bj_MAX_INVENTORY
set itemType = GetItemTypeId(UnitItemInSlot(shopper, Loop_A))
if itemType != 0 then
call GetAvailableFusions(itemType,playerIndex)
endif
set Loop_A = Loop_A + 1
endloop
//bagpack exists?
if GetUnitTypeId(bagpack) != 0 and udg_IFShop_Bagpack_Enabled then
//Bagpack
set Loop_A = 0
loop
exitwhen Loop_A == bj_MAX_INVENTORY
set itemType = GetItemTypeId( UnitItemInSlot(bagpack, Loop_A))
if itemType != 0 then
call GetAvailableFusions(itemType,playerIndex)
endif
set Loop_A = Loop_A + 1
endloop
endif
endif
endif
//call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,10, "Used slots "+I2S(udg_IFShop_Shop_Avaible_Fuse_First[playerIndex])+"/"+I2S(udg_IFShop_Shop_Avaible_Fuse_Last[playerIndex]))
//Does an Upgrade Exist?
if( udg_IFShop_Shop_Avaible_Fuse_Last[playerIndex] >= udg_IFShop_Shop_Avaible_Fuse_First[playerIndex] ) then
set udg_IFShop_Shopper_Count = udg_IFShop_Shopper_Count + 1
//First Player Shopping? start Periodic check.
if( udg_IFShop_Shopper_Count ==1 and udg_IFShop_Bagpack_Enabled) then
call TimerStart ( udg_IFShop_Bagpack_Timer, GetBagpackIntervall(), true, function TimerBagpackAccesable)
endif
//Save Current Shopping Situation
set udg_IFShop_Is_Shopping[playerIndex] = true
set udg_IFShop_Shop_Shopper[playerIndex] = shopper
set udg_IFShop_Shop_Shopper_Bagpack[playerIndex] = bagpack
call CalcCostOfAll(playerIndex,shopper,bagpack)
//Inser upgrade Options and Open Shop
call ShowUnit( udg_IFShop_Shop[playerIndex],true )
call UpdateShop(playerIndex)
call SelectUnitForPlayerSingle( udg_IFShop_Shop[playerIndex], Player(playerIndex - 1) )
//Make Shop target Shopper.
call IssueNeutralTargetOrderById( Player(playerIndex - 1), udg_IFShop_Shop[playerIndex], SelectShopTarget() , shopper)
else
//No Upgrades avaible Reselect Shopper.
call SelectUnitForPlayerSingle( shopper, GetOwningPlayer(shopper) )
endif
endfunction
function BuyFusion_Action takes nothing returns nothing
local integer Loop_A
local integer Loop_A_End
local integer Loop_B = 0
local integer itemType = GetItemTypeId(GetSoldItem())
local integer indexInShop = 0
local integer playerIndex = GetPlayerId( GetOwningPlayer(GetBuyingUnit()) ) + 1
local unit bagpack = udg_IFShop_Shop_Shopper_Bagpack[playerIndex]
local unit shopper = udg_IFShop_Shop_Shopper[playerIndex]
call UnmarkItems(0)
//Define searching Area
if( udg_IFShop_Page_Max[playerIndex] > 0) then
set Loop_A = ( udg_IFShop_Shop_Avaible_Fuse_First[playerIndex] + ( 9 * udg_IFShop_Page_Current[playerIndex] ) )
set Loop_A_End = Loop_A + 8
if Loop_A_End > udg_IFShop_Shop_Avaible_Fuse_Last[playerIndex] then
set Loop_A_End = udg_IFShop_Shop_Avaible_Fuse_Last[playerIndex]
endif
else
set Loop_A = udg_IFShop_Shop_Avaible_Fuse_First[playerIndex]
set Loop_A_End = udg_IFShop_Shop_Avaible_Fuse_Last[playerIndex]
endif
loop
exitwhen Loop_A > Loop_A_End
//Was this one bought?
if ( udg_IFShop_Shop_Avaible_Fuse_Fakes[Loop_A] == itemType) then
set indexInShop = Loop_A
exitwhen true
endif
set Loop_A = Loop_A + 1
endloop
//Enough Gold?
if( GetPlayerState( Player(playerIndex - 1), PLAYER_STATE_RESOURCE_GOLD) >= udg_IFShop_Shop_Avaible_Fuse_Costs[indexInShop] )then
call AdjustPlayerStateBJ( ( -1 * udg_IFShop_Shop_Avaible_Fuse_Costs[indexInShop] ), Player(playerIndex - 1), PLAYER_STATE_RESOURCE_GOLD )
// Collect avaible Fusion-Material
call GetSubFusions(playerIndex, shopper, bagpack, itemType)
//Destory Found material
loop
exitwhen Loop_B > udg_IFShop_Item_Stack_Last
call SetItemUserData( udg_IFShop_Item_Stack[Loop_B], udg_IFShop_Item_Stack_Old_Custom[Loop_B] )
call RemoveItem( udg_IFShop_Item_Stack[Loop_B] )
set Loop_B = Loop_B + 1
endloop
//Create Fusion
set itemType = LoadInteger(udg_IFShop_Table, itemType, GetTabelIndexItem())
call UnitAddItemByIdSwapped( itemType, shopper )
call DestroyEffect( AddSpecialEffectTarget(udg_IFShop_Fusion_SFX_Path, shopper, "origin") )
call HideShop_Action()
//continue Shopping, with gained Fusion?
if udg_IFShop_SHOW_SHOP_AFTER_UPGRADE then
call ShowShop (playerIndex, shopper, bagpack, itemType)
else
call SelectUnitForPlayerSingle( shopper, GetTriggerPlayer() )
endif
else
call StartSoundForPlayerBJ(GetOwningPlayer(shopper),udg_IFShop_Sound_No_Gold)
endif
call RemoveItem( GetSoldItem() )
set shopper = null
set bagpack = null
endfunction
//Creates all needed stuff.
function Item_Fusion_shop_Create takes nothing returns nothing
local trigger switchPage =CreateTrigger()
local trigger hideShops =CreateTrigger()
local trigger buyFusion = CreateTrigger()
local integer playerIndex = 0
local unit shop
// Basic Setup
set udg_IFShop_Item_List_Fusions_Last = -1
set udg_IFShop_Shopper_Count = 0
set udg_IFShop_Table = InitHashtable()
call TriggerAddCondition( switchPage, Condition (function SwitchPage_Conditions) )
call TriggerAddAction( switchPage, function SwitchPage_Action )
call TriggerAddAction(hideShops, function HideShop_Action)
call TriggerAddCondition(hideShops, Condition (function HideShop_Condition))
call TriggerAddAction(buyFusion, function BuyFusion_Action)
//Loop all Players;
loop
exitwhen playerIndex == bj_MAX_PLAYERS
//Is Playing? Is User?
if ( GetPlayerSlotState(Player(playerIndex)) == PLAYER_SLOT_STATE_PLAYING and GetPlayerController(Player(playerIndex)) == MAP_CONTROL_USER ) then
//Create Shops, Register: Page Controll, Shop Closing
set shop = CreateUnit( Player(playerIndex), udg_IFShop_Shop_UnitType, GetStartLocationX(playerIndex), GetStartLocationY(playerIndex), 270.0)
call SetUnitPathing( shop, false )
call TriggerRegisterPlayerUnitEvent(hideShops, Player(playerIndex), EVENT_PLAYER_UNIT_DESELECTED, null)
call TriggerRegisterUnitEvent( switchPage, shop, EVENT_UNIT_SPELL_CAST )
call TriggerRegisterUnitEvent( buyFusion, shop, EVENT_UNIT_SELL_ITEM )
set udg_IFShop_Shop[playerIndex+1] = shop
endif
set playerIndex = playerIndex + 1
endloop
set shop = null
call TriggerClearActions(gg_trg_Item_Fusion_shop)
endfunction
//===========================================================================
function InitTrig_Item_Fusion_shop takes nothing returns nothing
set gg_trg_Item_Fusion_shop = CreateTrigger( )
call TriggerAddAction( gg_trg_Item_Fusion_shop, function Item_Fusion_shop_Create )
endfunction
function Trig_INit_Fusions_Actions takes nothing returns nothing
// result, fake, mats.
call AddFusion ( 'ward', 'I007', 'I000', 0,0,0,0,0,0)
call AddFusion ( 'ajen', 'I008', 'I000', 0,0,0,0,0,0)
call AddFusion ( 'lgdh', 'I00H', 'I000', 0,0,0,0,0,0)
call AddFusion ( 'clsd', 'I00G', 'I000', 0,0,0,0,0,0)
call AddFusion ( 'prvt', 'I00A', 'I000', 0,0,0,0,0,0)
call AddFusion ( 'bspd', 'I002', 'I000', 0,0,0,0,0,0)
call AddFusion ( 'rwiz', 'I009', 'I000', 0,0,0,0,0,0)
call AddFusion ( 'brac', 'I00B', 'I000', 0,0,0,0,0,0)
call AddFusion ( 'ciri', 'I00C', 'I000', 0,0,0,0,0,0)
call AddFusion ( 'cnob', 'I00E', 'I000', 0,0,0,0,0,0)
call AddFusion ( 'rst1', 'I00D', 'I000', 0,0,0,0,0,0)
call AddFusion ( 'rlif', 'I00I', 'I000', 0,0,0,0,0,0)
call AddFusion ( 'hval', 'I00F', 'I000', 0,0,0,0,0,0)
call AddFusion ( 'sbch', 'I00K', 'I000', 0,0,0,0,0,0)
call AddFusion ( 'lhst', 'I00J', 'I000', 0,0,0,0,0,0)
call AddFusion ( 'clfm', 'I00L', 'I000', 0,0,0,0,0,0)
call AddFusion ( 'spsh', 'I00P', 'I000', 0,0,0,0,0,0)
call AddFusion ( 'rde2', 'I00M', 'I000', 0,0,0,0,0,0)
call AddFusion ( 'gcel', 'I00N', 'I000', 0,0,0,0,0,0)
call AddFusion ( 'evtl', 'I00O', 'I000', 0,0,0,0,0,0)
call AddFusion ( 'bgst', 'I00R', 'rst1', 'rst1','I004',0,0,0,0)
call AddFusion ( 'I00S', 'I00T', 'bgst', 'bgst',0,0,0,0,0)
endfunction
//===========================================================================
function InitTrig_INit_Fusions_Jass takes nothing returns nothing
set gg_trg_INit_Fusions_Jass = CreateTrigger( )
call TriggerRegisterTimerEventSingle( gg_trg_INit_Fusions_Jass, 0.00 )
call TriggerAddAction( gg_trg_INit_Fusions_Jass, function Trig_INit_Fusions_Actions )
endfunction