1. Are you planning to upload your awesome spell or system to Hive? Please review the rules here.
    Dismiss Notice
  2. The poll for our 11th Music Contest is up! Help us choose the most awesome cinematic tracks by casting a vote!
    Dismiss Notice
  3. Melee Mapping contest #3 - Poll is up! Vote for the best 4v4 melee maps!
    Dismiss Notice
  4. The 30th edition of the Modeling Contest is finally up! The Portable Buildings need your attention, so come along and have a blast!
    Dismiss Notice
  5. The Aftermath has been revealed for the 19th Terraining Contest! Be sure to check out the Results and see what came out of it.
    Dismiss Notice

[GUI Friendly] Item Fusion Shop 1.6

Submitted by Tasyen
This bundle is marked as approved. It works and satisfies the submission rules.
Item Fusion Shop is a System to Fuse Recipe based Items.
Additional IFS shows any possible Upgrade option of an gained Item in the Warcraft UI.
This Upgrade Options are Shown in an dynamic default Warcraft based Shop, each Player has his own normally hidden, together with the Gold-Costs to complet this Recipe.
The Player is now able to Tier up an Item with just 1 Button.

Features:
  • Recipes
  • Showing Upgrad Options and their Gold Costs clearly in the Basic UI.
  • Able to consider a Bagpack.
  • Settingup Buy Zones, which can exclude playergroups from using them.
  • MUI, each Player has its own dynamic shop.


    • IFS Init General
      • Events
        • Map initialization
      • Conditions
      • Actions
        • -------- Choose a never used Number for Custom Item Values, its only needed for calculation. You can use custom Value of Items for other stuff --------
        • Set IFShop_VALUE_MARKEDITEM = -1
        • -------- After Fusing an Item shall the Upgrades of the fusion be shown and the shopping continue? --------
        • Set IFShop_SHOW_SHOP_AFTER_UPGRADE = True
        • -------- If enabled will show additional upgrades of upgrades. --------
        • Set IFShop_ShowMaxUpgrades = False
        • -------- For the Sound i recomment Sound/Interface/Warning/Nage/NagaNoGold --------
        • Set IFShop_Sound_No_Gold = MoreGold <gen>
        • Set IFShop_Shop_UnitType = IFS - Upgrade Options
        • Set IFShop_Skill_Show_Upgrades = IFS - Show Upgrade
        • Set IFShop_Page_Skill_Next = IFS - Page Next
        • Set IFShop_Page_Skill_Previous = IFS - Page Previous
        • Set IFShop_Fusion_SFX_Path = Abilities\Spells\Items\AIem\AIemTarget.mdl
        • -------- ---- --------
        • -------- Bagpack --------
        • -------- ---- --------
        • Set IFShop_Bagpack_Enabled = True
        • -------- Search Material Slotbased? --------
        • -------- True -> Access Order Shopper: 1/3/5/7/9/11; Bagpack 2/4/6/8/10/12 --------
        • -------- False -> Access Order Shopper: 1/2/3/4/5/6; Bagpack 7/8/9/10/11/12 --------
        • Set IFShop_Bagpack_Pick_SlotBased = False
        • -------- Start Material Search with Shopper? --------
        • Set IFShop_Bagpack_Shopper_First = True
        • Set IFShop_Bagpack_Hero_Max_Distan = 600.00
        • -------- ---- --------
        • -------- Bagpack --------
        • -------- ---- --------
        • -------- This shows how much room a Player's shop got, currently 11 Pages. --------
        • Set IFShop_Stacksize_Each_Player = 99
        • -------- Setup here The Places where the System Shall work --------
        • Set IFShop_Buy_Zones[0] = Gebiet 000 <gen>
        • Set IFShop_Buy_Zones[1] = Gebiet 001 <gen>
        • Set IFShop_Buy_Zones[2] = Gebiet 002 <gen>
        • Set IFShop_Buy_Zones[3] = Gebiet 003 <gen>
        • Set IFShop_Buy_Zones[4] = Gebiet 004 <gen>
        • Set IFShop_Buy_Zones_Last = 4
        • -------- You can Exclude Player Groups from using specific Buz_Zones --------
        • Set IFShop_Buy_Zones_Excluded[1] = Spielergruppe - Spieler 2 (Blau)
        • Set IFShop_Buy_Zones_Excluded[3] = (All players matching (((Matching player) slot status) Gleich Spielt))
        • Set IFShop_Buy_Zones_Excluded[4] = Spielergruppe - Spieler 1 (Rot)
        • -------- - --------
        • -------- This Creates the Shops and setups some basic Stuff --------
        • Trigger - Run Item Fusion shop <gen> (ignoring conditions)
        • Trigger - Run IFS Init Item <gen> (ignoring conditions)
        • -------- Auto-Generate Needed Global Variables --------
        • -------- Keep Disabled or Delete Stuff below --------
        • Set IFShop_Item_List_Fusions_Last = 0
        • Set IFShop_Table = (Last created hashtable)
        • Set IFShop_Shop[0] = IFShop_Shop_Shopper[0]
        • Set IFShop_Shop_Shopper_Bagpack[0] = IFShop_Shopper
        • Set IFShop_Page_Max[0] = IFShop_Page_Current[0]
        • Set IFShop_Shop_Avaible_Fuse_Last[0] = IFShop_Shop_Avaible_Fuse_First[0]
        • Set IFShop_Shop_Avaible_Fusions[0] = IFShop_Shopper_Count
        • Set IFShop_Shop_Avaible_Fuse_Fakes[0] = IFShop_Mats[0]
        • Set IFShop_Shop_Avaible_Fuse_Costs[0] = Value
        • Set IFShop_Is_Shopping[0] = IFShop_Shop_Bagpack_Accessable[0]
        • Set IFShop_Bagpack_Timer = IFShop_Bagpack_Timer
        • Set IFShop_Item_Stack[0] = Kein Gegenstand
        • Set IFShop_Item_Stack_Last = IFShop_Item_Stack_Old_Custom[0]
        • Set IFShop_Shop_LastTry[0] = Geheimlevel-Powerup


    • IFS Init Item
      • Events
      • Conditions
      • Actions
        • -------- Inser the Items together with their Gold value --------
        • Set IFS_Item_Type = Klauen des Angriffs +6
        • Set IFS_Gold = 200
        • Trigger - Run IFS Add Item <gen> (ignoring conditions)
        • Set IFS_Item_Type = Hammer +9
        • Set IFS_Gold = 300
        • Trigger - Run IFS Add Item <gen> (ignoring conditions)
        • Set IFS_Item_Type = Axt +12
        • Set IFS_Gold = 400
        • Trigger - Run IFS Add Item <gen> (ignoring conditions)
        • Set IFS_Item_Type = Blade +30
        • Set IFS_Gold = 1200
        • Trigger - Run IFS Add Item <gen> (ignoring conditions)
        • Set IFS_Item_Type = Rezept: 200 Gold
        • Set IFS_Gold = 200
        • Trigger - Run IFS Add Item <gen> (ignoring conditions)


    • IFS Init Fusion GUI
      • Events
        • Time - Elapsed game time is 0.00 seconds
      • Conditions
      • Actions
        • -------- - --------
        • -------- Inser the Fusions. --------
        • -------- Item_Type = Result of the Fusion --------
        • -------- Item_Type_Fake = Shown in the UI; Should have No Gold Cost, No Skills, No Modell, be Powerup --------
        • -------- Mats[0 to 6], are Supported --------
        • -------- You can split this trigger into multiple ones if it becomes to long. --------
        • Set IFShop_Item_Type = Axt +12
        • Set IFShop_Item_Type_Fake = Fake: Axt +12
        • Set IFShop_Mats[0] = Klauen des Angriffs +6
        • Set IFShop_Mats[1] = Klauen des Angriffs +6
        • Trigger - Run IFS Add Fusion <gen> (ignoring conditions)
        • Set IFShop_Item_Type = Blade +30
        • Set IFShop_Item_Type_Fake = Fake: Blade +30 (9+9+12)
        • Set IFShop_Mats[0] = Hammer +9
        • Set IFShop_Mats[1] = Hammer +9
        • Set IFShop_Mats[2] = Axt +12
        • Set IFShop_Mats[3] = Rezept: 200 Gold
        • Trigger - Run IFS Add Fusion <gen> (ignoring conditions)
        • Set IFShop_Item_Type = Blade +30
        • Set IFShop_Item_Type_Fake = Fake: Blade +30 (6x5)
        • Set IFShop_Mats[0] = Klauen des Angriffs +6
        • Set IFShop_Mats[1] = Klauen des Angriffs +6
        • Set IFShop_Mats[2] = Klauen des Angriffs +6
        • Set IFShop_Mats[3] = Klauen des Angriffs +6
        • Set IFShop_Mats[4] = Klauen des Angriffs +6
        • Set IFShop_Mats[5] = Rezept: 200 Gold
        • Trigger - Run IFS Add Fusion <gen> (ignoring conditions)
        • Set IFShop_Item_Type = Blade +30
        • Set IFShop_Item_Type_Fake = Fake: Blade +30 (12+12+6)
        • Set IFShop_Mats[0] = Klauen des Angriffs +6
        • Set IFShop_Mats[1] = Axt +12
        • Set IFShop_Mats[2] = Axt +12
        • Set IFShop_Mats[3] = Rezept: 200 Gold
        • Trigger - Run IFS Add Fusion <gen> (ignoring conditions)

    • IFS Get Bagpack
      • Events
      • Conditions
        • IFShop_BackPack_Enabled
      • Actions
        • -------- Find the Bagpack, which shall be considered for this Item Fusion shopping --------
        • -------- You can use the Unit IFS_Shop_Shopper --------
        • -------- The use of this Trigger is to allow custom finding of Bagpack units. --------
        • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
          • If - Conditions
            • (Owner of IFShop_Shopper) Equal Player 1 (Red)
          • Then - Actions
            • Set IFShop_Shopper_Bagpack = Packhorse 0032 <gen>
          • Else - Actions
            • Set IFShop_Shopper_Bagpack = Packhorse 0039 <gen>


    • IFS Hero Gains Item
      • Events
        • Unit - A unit Gains an Item
      • Conditions
        • not ( ((Item being manipulated) is Ein Powerup))
        • ((Triggering unit) is selected by (Owner of (Triggering unit)))
      • Actions
        • Set IFS_Shopper = (Triggering unit)
        • Set IFS_Item_Type = (Item-type of (Item being manipulated))
        • Trigger - Run IFS Try Shopping <gen> (ignoring conditions)

    • IFS Show Upgrades Spell
      • Events
        • Unit - A unit Starts the Effect of a spell
      • Conditions
        • (Ability being cast) Equal IFShop_Skill_Show_Upgrades
      • Actions
        • Set IFShop_Shopper = (Triggering unit)
        • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
          • If - Conditions
            • ((Target item of ability being cast) is owned) Gleich True
          • Then - Actions
            • Set IFShop_Item_Type = (Item-type of (Target item of ability being cast))
          • Else - Actions
            • Custom script: set udg_IFShop_Item_Type = 0
        • Trigger - Run IFS Try Shopping <gen> (ignoring conditions)



    Items are Unique in the Pool
    Fusion Items should be as item inside the Pool, but not the Fake.
    • IFS Add Item
      • Events
      • Conditions
      • Actions
        • call SaveInteger(udg_IFShop_Table , udg_IFShop_Item_Type, 0, udg_IFShop_Gold)

    Fusions are Unique based off the Fake-Item.
    , if you want multiple ways to Create an Item.
    You need multiple Fake Items.
    • IFS Add Fusion
      • Events
      • Conditions
      • Actions
        • Custom script: call AddFusion ( udg_IFShop_Item_Type, udg_IFShop_Item_Type_Fake, udg_IFShop_Mats[0], udg_IFShop_Mats[1], udg_IFShop_Mats[2], udg_IFShop_Mats[3], udg_IFShop_Mats[4], udg_IFShop_Mats[5], udg_IFShop_Mats[6])
        • For each (Integer A) from 0 to 6, do (Actions)
          • Schleifen - Aktionen
            • Custom script: set udg_IFShop_Mats[bj_forLoopAIndex] = 0
        • Custom script: set udg_IFShop_Item_Type = 0
        • Custom script: set udg_IFShop_Item_Type_Fake = 0

    • IFS Try Shopping
      • Events
      • Conditions
      • Actions
        • -------- Needs: udg_IFShop_Shopper, udg_IFShop_Item_Type --------
        • Custom script: if ( IsInShopZone( udg_IFShop_Shopper ) ) then
        • Trigger - Run IFS Get Bagpack <gen> (checking conditions)
        • Custom script: call ShowShop ( GetConvertedPlayerId(GetOwningPlayer(udg_IFShop_Shopper)), udg_IFShop_Shopper, udg_IFShop_Shopper_Bagpack, udg_IFShop_Item_Type)
        • Custom script: endif



  • How to Install:
    • Make sure you set the Option "File - preferences - Create Unknown Variables".
    • Copy The Ability "IFS - Select Hero".
    • Copy the Ability "IFS - Show Upgrades"
    • Copy the Ability "IFS - Page Next"
    • Copy the Ability "IFS - Page Previous"
    • Copy The "IFS - Upgrade Options" Unit.
    • Copy the Folder "Item Fusion Shop"
    • Check out the Configer below Triggers, to complet missing links and fill the database.
    • Make sure the "IFS - Upgrade Options" Unit has the right abilities
    • Custimze "IFS Get Bagpack" if you want to use a Bagpack.

  • Code (vJASS):

        //==========================//
       //   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
     



  • Changelog

    V1.6)
    One can now show all available upgrades of items in inventories ( shopper + backpack)
    the demo spell shows now this behaviour by casting it on the hero himself.​
    It is now possible to show max upgrade level of items.
    default off.​
    The GUI registering trigger now cleans off fusion result/fake.
    The Fusion Init now starts itself at 0.00 to allow printing out error messages.
    the Entries per page are now changeable inside the jass code.
    cleans now the bought plan instantly.
    fixed a bug with using an material multiple times in one built when jumping tier levels -> took less gold if wanted.​
    V1.5
    Reworked the system, it now performs better with big itempools.
    fixed a bug in which a more expensive built way was choosen
    the primary key for fusion-Plans is now the itemTypeId (tech info).
    takes only 1 Hashtable.​
    V1.3a
    Insert "return true" at the end of function CreateFusion()​
    V1.3
    Material-Amount was registered with 1 too much.
    Option: Start with Bagpack/Shopper for Material finding
    Option: Check Material Slot/Inventory based
    Default: Shopper & Inventory-Based
    Renamed some Variables​
    old Changes

    V1.2a/b
    Insert the Option to exclude a Player Group from a Buyzone
    Changed Blues Hero to blademaster
    Replaced Some BJ-functions
    Break out of loops is now done with exitwhen (true)
    Optimized the calculation time of function BuyFusion dramatically​
    V1.2
    Now in Jass
    Gold Costs are saved in another Hashtabel
    Moved not configerable basic setup into Item Fusion shop Code.
    Added an Option: Show further Upgrades after Fusing
    Fixed 2 buggs with Multi-Page​
    V1.1d
    Custom Value of Items are now correctly restored
    Insert 2 Global Constants (One is the OrderID from select Shopper the other makes it easier to find a not used Custom Value)
    Not selected Units won't Open the Shop anymore
    Added a Blue Player with a own horse.
    Altered the Get Bagpack Trigger showing how to use with 2 MPI Heroes.
    Reordered the Init General Trigger
    Inserter a break in IsInShopzone
    Insert a Variable for the Show Upgrade Spell​
    V1.1c
    Systems Prefix: IFS -> IFShop
    Some Names were shortend to accept the new Prefix
    Added a New Item to the Demo Map: Built to Many. It shows the Multi paging.​
    V1.1b
    Uses Blizzard's Function: StartSoundForPlayerBJ​
    V1.1a
    The "No-Gold" Sound is now played only on the Local PC.
    V1.1
    Added the Feature: "Multiple Pages", the Page-Control is only Shown if needed.
    Now Prices will be updated in Real time, if the accessablity of the used backpack changes; Frequenz 2,5 Hz.
    Now the Shopper is always The "Shown"-Target of the Shop, this Requiers the "Pick User Button" to be shown in the Shop, as the in the map contained ability does.
    Some Code updates
    Demo Map-Text updated.

    V1.0a
    Outsourced IFS_Shopper_Bagpack into the new Trigger IFS getBagpack
    -> this allows easier Customizing and less touching of the System.
    Changed the Trigger Order, to simplfy Importing.
    Added a New Variable IFS_Sound_No_Gold, is set in IFS Init General



Previews
Contents

Item Fusion Shop 1.6 (Map)

Reviews
KILLCIDE
The system seemed small at first, but as I began to read the code and see the mechanics, I began to see the entirety of the system. I rather like how you managed to get this to work with the WC3 interface. The movement between pages and the...
  1. KILLCIDE

    KILLCIDE

    Administrator

    Joined:
    Jul 22, 2015
    Messages:
    3,440
    Resources:
    20
    Models:
    2
    Icons:
    10
    Spells:
    7
    Tutorials:
    1
    Resources:
    20

    Needs Fixed

    • loc as a variable name is way too generic
    • IFS - Show Upgrade should be stored into a configurable variable
    • loc2 as a variable name is way too generic
    • It should be mentioned that the custom value of item's is manipulated by this system
    • Boolean as a variable name is way too generic
    • Sell Items, Page_Skill_Next, & Page_Skill_Previous should be stored into configurable variables

    Suggestions

    • Documentation for the Basic Setup variables in Init General would be appreciated. As of right now, I have no idea what they mean, especially Fusions_Last
    • In the player group loop in IFS Init General, I would store (Picked player) and (Last created unit) into variables
    • I would avoid using (Integer A) because it might clash with other user's maps, and it is also slower
    • I would add an
      exitwhen (true)
      in the for loop inside IFS shopper is in Shopzone. It seems useless to be continuing the loop if you already found that it's in one of the regions
    • Does the preplaced backpack unit work for all players? Do they only have to place one of these backpack units down or must they place one for each player?
    • In Show Upgrades Spell, you store (Triggering unit) into a variable, but you don't use it
    • Error messages should only be shown locally
    • LoadIntegerBJ()
      ->
      LoadInteger()
    • Instead of setting loop integers to an arbitary value that will exit the loop, make use of the
      exitwhen (true)
      operator

    Status


    Awaiting Update
     
  2. Tasyen

    Tasyen

    Joined:
    Jul 18, 2010
    Messages:
    978
    Resources:
    10
    Tools:
    2
    Maps:
    2
    Spells:
    5
    Tutorials:
    1
    Resources:
    10
    Thanks for your Feedback.

    It is not mentioned cause the System should restore the current custom value after usage. Currently In Version 1.1c it does not restore it cause of a simple misstake.
    Its used and needed in the Triggers called.
    Sell Items is the basic Ability of market which can't be modyfied at all, so I don't see any value in giving it a variable.
    Page_Next/Previous are allready variable based.

    In the demo Map the packhorse is used by all Units. But this kind of Bagpack finding, in a own trigger, was choosen to allow free customizing.

    Uploaded Version 1.1d
     
  3. KILLCIDE

    KILLCIDE

    Administrator

    Joined:
    Jul 22, 2015
    Messages:
    3,440
    Resources:
    20
    Models:
    2
    Icons:
    10
    Spells:
    7
    Tutorials:
    1
    Resources:
    20
    I'm referring to here: Set IFS_Index_Player = (Player number of (Owner of (Triggering unit)))

    If you are storing them into the variables, then you aren't using them in the code correctly. There are parts of the code where you refer to the actual ability in the Object Editor instead of the variable.
     
  4. Tasyen

    Tasyen

    Joined:
    Jul 18, 2010
    Messages:
    978
    Resources:
    10
    Tools:
    2
    Maps:
    2
    Spells:
    5
    Tutorials:
    1
    Resources:
    10
    You are right i did this. Currently i converting this to jass which is more suited, will be released as soon as it works as intended and fills the JAPG.
    IFShop 1.1d was a hotfix.
     
  5. KILLCIDE

    KILLCIDE

    Administrator

    Joined:
    Jul 22, 2015
    Messages:
    3,440
    Resources:
    20
    Models:
    2
    Icons:
    10
    Spells:
    7
    Tutorials:
    1
    Resources:
    20
    Sighh... why do you decide that AFTER I review it >.>
     
  6. Tasyen

    Tasyen

    Joined:
    Jul 18, 2010
    Messages:
    978
    Resources:
    10
    Tools:
    2
    Maps:
    2
    Spells:
    5
    Tutorials:
    1
    Resources:
    10
    Uploaded Version 1.2.
     
  7. KILLCIDE

    KILLCIDE

    Administrator

    Joined:
    Jul 22, 2015
    Messages:
    3,440
    Resources:
    20
    Models:
    2
    Icons:
    10
    Spells:
    7
    Tutorials:
    1
    Resources:
    20
    Meh I'm going to have to throw this at the bottom of the moderation list for now unless another reviewer comes by. There are other submissions we must go to, and I was expecting to keep reviewing this from the GUI version. Since you decided to convert it to JASS after I did my review, I'm going to have to review it all over again.

    Feel free to keep updating it if you find any bugs. For now, please get rid of the unnecessary BJs and use
    exitwhen true
    to exit a loop instead of setting the loop integer to some arbitarily large value.
     
  8. Tasyen

    Tasyen

    Joined:
    Jul 18, 2010
    Messages:
    978
    Resources:
    10
    Tools:
    2
    Maps:
    2
    Spells:
    5
    Tutorials:
    1
    Resources:
    10
    Edit: Updated to Version 1.2b.
     
    Last edited: May 2, 2017
  9. KILLCIDE

    KILLCIDE

    Administrator

    Joined:
    Jul 22, 2015
    Messages:
    3,440
    Resources:
    20
    Models:
    2
    Icons:
    10
    Spells:
    7
    Tutorials:
    1
    Resources:
    20

    Needs Fixed


    • Missing return inside function CreateFusion

    Suggestions


    • Nothing

    Status


    Awaiting Update
     
  10. Tasyen

    Tasyen

    Joined:
    Jul 18, 2010
    Messages:
    978
    Resources:
    10
    Tools:
    2
    Maps:
    2
    Spells:
    5
    Tutorials:
    1
    Resources:
    10
    updated to 1.3a
     
  11. KILLCIDE

    KILLCIDE

    Administrator

    Joined:
    Jul 22, 2015
    Messages:
    3,440
    Resources:
    20
    Models:
    2
    Icons:
    10
    Spells:
    7
    Tutorials:
    1
    Resources:
    20
    The system seemed small at first, but as I began to read the code and see the mechanics, I began to see the entirety of the system. I rather like how you managed to get this to work with the WC3 interface. The movement between pages and the combination of items feel smooth. The only con I can see is some inefficiency in the code and the rather large learning curve. Fortunately though, the system isn't periodic, so I can't imagine this causing any issues. I sort of don't feel like taking the time to re-read your code again given that it was originally in GUI, so I'm going to trust that the JASS is okay.

    Needs Fixed

    • Nothing

    Suggestions

    • I would highly appreciate it if you can leave some documentation in your code. The logics make sense to you because you made it, but you must consider that the Reviewers and Moderators just see this as arbitary code.
    • I would make use of
      bj_MAX_PLAYER_SLOTS
      instead of using random numbers like 11 or 16

    Status


    Approved
     
  12. Tasyen

    Tasyen

    Joined:
    Jul 18, 2010
    Messages:
    978
    Resources:
    10
    Tools:
    2
    Maps:
    2
    Spells:
    5
    Tutorials:
    1
    Resources:
    10
    Added some Documentation to the Code uploaded on Hive. (Not in the Map)
    Fixed a Error in "IFS Add Item" on Hive showing an old version. (was correct in the map)


    Edit: Updated to 1.5.
    This patch overworked the System overall, improving performance on big itempools by presaving connections between Plans, Fusions and Mats which takes away alot of calcing power during game time.
    Edit: Updated to 1.6.
    1.6 improves 1.5 and adds new features:
    setting items per page
    showing upgrades of upgrades.
    improved error messages for registering fusions
    show upgrades for any item hold by shopper and bagpack.
     
    Last edited: Jul 27, 2017