System ItemStruct

Jesus4Lyf

Good Idea™
Reaction score
397
ItemStruct​
Version 0.8.0​

Requirements:
- Jass NewGen
- AIDS

To use, make a trigger and insert the header, make another trigger and insert the footer, and make all ItemStructs in between.
Code (header):
JASS:
// ItemStruct ALPHA 0.8.0 release. By Jesus4Lyf.
library ItemStruct requires AIDS
//! externalblock extension=lua ObjectMerger $FILENAME$
    //! runtextmacro ItemStruct__StartConfig()

//===========================================================================
// CONFIG AREA
//
    
    //===========================================================================
    // System Object Editor IDs.
    //
    
    //! runtextmacro ItemStruct__BeginSysIds()
        // Uses:
        //  - 'Ixx&' for item type.
        //  - 'Axx&' for use ability.
        //  - 'Sxx&' for hider spellbook.
        
        //! runtextmacro ItemStruct__AllowSysId("0a")
        //! runtextmacro ItemStruct__AllowSysId("0b")
        //! runtextmacro ItemStruct__AllowSysId("0c")
        //! runtextmacro ItemStruct__AllowSysId("0d")
        //! runtextmacro ItemStruct__AllowSysId("0e")
        //! runtextmacro ItemStruct__AllowSysId("0f")
        //! runtextmacro ItemStruct__AllowSysId("0g")
        //! runtextmacro ItemStruct__AllowSysId("0h")
        //! runtextmacro ItemStruct__AllowSysId("0i")
        //! runtextmacro ItemStruct__AllowSysId("0j")
        //! runtextmacro ItemStruct__AllowSysId("0k")
        //! runtextmacro ItemStruct__AllowSysId("0l")
        //! runtextmacro ItemStruct__AllowSysId("0m")
        //! runtextmacro ItemStruct__AllowSysId("0n")
        //! runtextmacro ItemStruct__AllowSysId("0o")
        //! runtextmacro ItemStruct__AllowSysId("0p")
        //! runtextmacro ItemStruct__AllowSysId("0q")
        //! runtextmacro ItemStruct__AllowSysId("0r")
        //! runtextmacro ItemStruct__AllowSysId("0s")
        //! runtextmacro ItemStruct__AllowSysId("0t")
        //! runtextmacro ItemStruct__AllowSysId("0u")
        //! runtextmacro ItemStruct__AllowSysId("0v")
        //! runtextmacro ItemStruct__AllowSysId("0w")
        //! runtextmacro ItemStruct__AllowSysId("0x")
        //! runtextmacro ItemStruct__AllowSysId("0y")
        //! runtextmacro ItemStruct__AllowSysId("0z")
        //! runtextmacro ItemStruct__AllowSysId("0A")
        //! runtextmacro ItemStruct__AllowSysId("0B")
        //! runtextmacro ItemStruct__AllowSysId("0C")
        //! runtextmacro ItemStruct__AllowSysId("0D")
        //! runtextmacro ItemStruct__AllowSysId("0E")
        //! runtextmacro ItemStruct__AllowSysId("0F")
        //! runtextmacro ItemStruct__AllowSysId("0G")
        //! runtextmacro ItemStruct__AllowSysId("0H")
        //! runtextmacro ItemStruct__AllowSysId("0I")
        //! runtextmacro ItemStruct__AllowSysId("0J")
        //! runtextmacro ItemStruct__AllowSysId("0K")
        //! runtextmacro ItemStruct__AllowSysId("0L")
        //! runtextmacro ItemStruct__AllowSysId("0M")
        //! runtextmacro ItemStruct__AllowSysId("0N")
        //! runtextmacro ItemStruct__AllowSysId("0O")
        //! runtextmacro ItemStruct__AllowSysId("0P")
        //! runtextmacro ItemStruct__AllowSysId("0Q")
        //! runtextmacro ItemStruct__AllowSysId("0R")
        //! runtextmacro ItemStruct__AllowSysId("0S")
        //! runtextmacro ItemStruct__AllowSysId("0T")
        //! runtextmacro ItemStruct__AllowSysId("0U")
        //! runtextmacro ItemStruct__AllowSysId("0V")
        //! runtextmacro ItemStruct__AllowSysId("0W")
        //! runtextmacro ItemStruct__AllowSysId("0X")
        //! runtextmacro ItemStruct__AllowSysId("0Y")
        //! runtextmacro ItemStruct__AllowSysId("0Z")
        
    //! runtextmacro ItemStruct__EndSysIds()
    
    //===========================================================================
    // System Object Editor Orders.
    //
    
    //! runtextmacro ItemStruct__BeginSysOrders()
        
        //! runtextmacro ItemStruct__AllowSysOrder("earthquake")
        //! runtextmacro ItemStruct__AllowSysOrder("chainlightning")
        //! runtextmacro ItemStruct__AllowSysOrder("thunderclap")
        //! runtextmacro ItemStruct__AllowSysOrder("stormbolt")
        //! runtextmacro ItemStruct__AllowSysOrder("mirrorimage")
        
    //! runtextmacro ItemStruct__EndSysOrders()
    
    //===========================================================================
    // Pockets
    //
    
    //! runtextmacro ItemStruct__BeginPockets()
        
        // Something special that relates to pockets.
        //! runtextmacro ItemStruct__BeginLastOpenedIcon()
            //! runtextmacro ItemStruct__SetLastOpenedIconHotkey("Y")
            //! runtextmacro ItemStruct__SetLastOpenedIconX("2")
            //! runtextmacro ItemStruct__SetLastOpenedIconY("1")
            //! runtextmacro ItemStruct__SetLastOpenedIconIcon("ReplaceableTextures\\CommandButtons\\BTNChestOfGold.blp")
            //! runtextmacro ItemStruct__SetLastOpenedIconTooltip("Open Inventor|cffffcc00y|r Pocket")
            //! runtextmacro ItemStruct__SetLastOpenedIconUbertip("Opens up the last pocket you accessed in your inventory.")
        //! runtextmacro ItemStruct__EndLastOpenedIcon()
        
        // Pockets.
        //! runtextmacro ItemStruct__Pocket("Pocket1")
            //! runtextmacro ItemStruct__SetPocketName("MyFirstPocket")
            //! runtextmacro ItemStruct__SetPocketDescription("It's a REAL pocket.")
            //! runtextmacro ItemStruct__SetPocketIcon("ReplaceableTextures\\CommandButtons\\BTNControlMagic.blp")
        //! runtextmacro ItemStruct__EndPocket()
        //! runtextmacro ItemStruct__Pocket("Pocket2")
            //! runtextmacro ItemStruct__SetPocketName("MySecondPocket")
            //! runtextmacro ItemStruct__SetPocketDescription("It's a REAL pocket.")
            //! runtextmacro ItemStruct__SetPocketIcon("ReplaceableTextures\\CommandButtons\\BTNHelmOfValor.blp")
        //! runtextmacro ItemStruct__EndPocket()
        
    //! runtextmacro ItemStruct__EndPockets()
    
//===========================================================================
// END CONFIG AREA
//
    //! runtextmacro ItemStruct__EndConfig()
    
    
    //===========================================================================
    // SYSTEM AREA (don't touch)
    //
    
    //! textmacro ItemStruct__StartConfig
        // For IdBase struct members.
        //private keyword ...
    //! endtextmacro
    //! textmacro ItemStruct__EndConfig
    //! endtextmacro
    
    
    //===========================================================================
    // Id Declaration
    //
    
    //! textmacro ItemStruct__BeginSysIds
        private module IdBaseInitModule
            private static method onInit takes nothing returns nothing
                //! i sysIds={}
                //! i maxSysIds=0
    //! endtextmacro
    //! textmacro ItemStruct__EndSysIds
            endmethod
        endmodule
        //! i sysIdsUsed=0
    //! endtextmacro
    
    //! textmacro ItemStruct__AllowSysId takes SYSID
        set thistype.idMax=thistype.idMax+1
        //! i maxSysIds=maxSysIds+1
        
        set thistype(thistype.idMax).ItemStruct__itemType='I$SYSID$&'
        set thistype(thistype.idMax).ItemStruct__spellbookType='S$SYSID$&'
        set thistype(thistype.idMax).ItemStruct__abilityType='A$SYSID$&'
        //! i sysIds[maxSysIds]={itemType="I$SYSID$&", spellbookType="S$SYSID$&", abilityType="A$SYSID$&"}
    //! endtextmacro
    
    
    //===========================================================================
    // Order Declaration
    //
    
    //! textmacro ItemStruct__BeginSysOrders
        globals
            private integer array SysOrders
            private integer MaxSysOrders=0
        endglobals
        private module OrdersInitModule
            private static method onInit takes nothing returns nothing
                //! i sysOrders={}
                //! i maxSysOrders=0
    //! endtextmacro
    //! textmacro ItemStruct__EndSysOrders
            endmethod
        endmodule
        globals
            private integer SysOrdersUsed=0
        endglobals
        //! i sysOrdersUsed=0
    //! endtextmacro
    
    //! textmacro ItemStruct__AllowSysOrder takes SYSORDER
        set MaxSysOrders=MaxSysOrders+1
        set SysOrders[MaxSysOrders]=OrderId("$SYSORDER$")
        //! i maxSysOrders=maxSysOrders+1
        //! i sysOrders[maxSysOrders]="$SYSORDER$"
    //! endtextmacro
    
    
    //===========================================================================
    // Pocket Declaration
    //
    
    //! textmacro ItemStruct__BeginPockets
        // Moved here for accessibility.
        private keyword Store
        private function RegisterPocketType takes integer rawCode, Pocket pocket returns nothing
            call SaveInteger(Store,rawCode,0,pocket)
        endfunction
        private function GetItemPocketType takes integer rawCode returns Pocket
            return Pocket(LoadInteger(Store,rawCode,0))
        endfunction
        
        private function PocketInit takes nothing returns nothing
            local Pocket this
            //! i setobjecttype("abilities")
            // Dummy ability for pockets.
            // Get id from first pocket's ability id (unused).
            //! i dummyItemAbility=sysIds[sysIdsUsed+1].abilityType
            //! i createobject("AItb",dummyItemAbility)
            //! i makechange(current,"acat","")
            //! i makechange(current,"anam","Dummy Item Ability")
            //! i makechange(current,"ansf","(ItemStruct)")
            //! i makechange(current,"Det1",1,0)
            //! i makechange(current,"aare",1,0)
            //! i makechange(current,"abuf",1,"")
            //! i makechange(current,"acdn",1,0)
            //! i makechange(current,"ahdu",1,0)
            //! i makechange(current,"adur",1,0)
            //! i makechange(current,"atar",1,"")
            // Init
            //! i maxPockets=0
    //! endtextmacro
    //! textmacro ItemStruct__EndPockets
        endfunction
        //! i setobjecttype("abilities")
        /*
        //! i createobject("AInv","AInv")
        //! i if maxPockets>=6 then
            //! i makechange(current,"inv1",1,6)
        //! else
            //TODO: Make this actually work.
            //! i makechange(current,"inv1",1,maxPockets)
        //! i end
        */
        // Pocket-orders duplication
        //! i pocketOrders={}
        //! i for tempPocketNum=0,maxPockets do
            //! i pocketOrders[tempPocketNum]=sysOrdersUsed
        //! i end
        private module PocketInitModule
            private static method onInit takes nothing returns nothing
                call PocketInit()
            endmethod
        endmodule
    //! endtextmacro
    
    //! textmacro ItemStruct__BeginLastOpenedIcon
        globals
            private integer LAST_OPENED_ABIL=0
        endglobals
        set LAST_OPENED_ABIL=Pocket(1).ItemStruct__spellbookType
        //! i setobjecttype("abilities")
        //! i lastOpenedPocketAbility=sysIds[sysIdsUsed+1].spellbookType
        //! i createobject("Aspb",lastOpenedPocketAbility)
        //! i makechange(current,"aite",0)
        //! i makechange(current,"anam","Open Inventory Pocket")
        //! i makechange(current,"ansf","(ItemStruct)")
        //! i makechange(current,"spb4",1,11)
        //! i makechange(current,"spb3",1,0)
        //! i makechange(current,"spb2",1,0)
        // Default spell list.
        //! i makechange(current,"spb1",1,"")
        // Order Issues.
        globals
            private integer LAST_OPENED_OID
        endglobals
        set SysOrdersUsed=SysOrdersUsed+1
        set LAST_OPENED_OID=SysOrders[SysOrdersUsed]
        //! i sysOrdersUsed=sysOrdersUsed+1
        //! i LAST_OPENED_ORDER=sysOrders[sysOrdersUsed]
        //! i makechange(current,"aord",LAST_OPENED_ORDER)
        //! i makechange(current,"spb5",1,LAST_OPENED_ORDER)
        // Defaults.
        globals
            private string LAST_OPENED_HOTKEY="Y"
        endglobals
        //! i makechange(current,"ahky","Y")
        //! i makechange(current,"abpx",2)
        //! i makechange(current,"abpy",1)
        //! i makechange(current,"aart","ReplaceableTextures\\CommandButtons\\BTNChestOfGold.blp")
        //! i makechange(current,"atp1",1,"Open Inventor|cffffcc00y|r Pocket")
        //! i makechange(current,"aub1",1,"Opens up the last pocket you accessed in your inventory.")
    //! endtextmacro
    //! textmacro ItemStruct__SetLastOpenedIconHotkey takes VAL
        set LAST_OPENED_HOTKEY="$VAL$"
        //! i makechange(current,"ahky","$VAL$")
    //! endtextmacro
    //! textmacro ItemStruct__SetLastOpenedIconX takes VAL
        //! i makechange(current,"abpx",$VAL$)
    //! endtextmacro
    //! textmacro ItemStruct__SetLastOpenedIconY takes VAL
        //! i makechange(current,"abpy",$VAL$)
    //! endtextmacro
    //! textmacro ItemStruct__SetLastOpenedIconIcon takes VAL
        //! i makechange(current,"aart","$VAL$")
    //! endtextmacro
    //! textmacro ItemStruct__SetLastOpenedIconTooltip takes VAL
        //! i makechange(current,"atp1",1,"$VAL$")
    //! endtextmacro
    //! textmacro ItemStruct__SetLastOpenedIconUbertip takes VAL
        //! i makechange(current,"aub1",1,"$VAL$")
    //! endtextmacro
    //! textmacro ItemStruct__EndLastOpenedIcon
    //! endtextmacro
    
    //! textmacro ItemStruct__Pocket takes IDENTIFIER
        globals
            Pocket $IDENTIFIER$
        endglobals
        set $IDENTIFIER$=Pocket.create()
        set this=$IDENTIFIER$
        call RegisterPocketType(this.ItemStruct__itemType,this)
        //! i sysIdsUsed=sysIdsUsed+1
        //! i maxPockets=maxPockets+1
        //! i $IDENTIFIER$=maxPockets
        //! i pocketIdentifier="$IDENTIFIER$"
        
        // Defaults.
        //! i pocketName=""
        //! i pocketDescription=""
        //! i pocketIcon=""
    //! endtextmacro
    
    //! textmacro ItemStruct__SetPocketName takes NAME
        set this.ItemStruct__name="$NAME$"
        //! i pocketName="$NAME$"
    //! endtextmacro
    //! textmacro ItemStruct__SetPocketDescription takes DESCRIPTION
        set this.ItemStruct__description="$DESCRIPTION$"
        //! i pocketDescription="$DESCRIPTION$"
    //! endtextmacro
    //! textmacro ItemStruct__SetPocketIcon takes ICON
        //! i pocketIcon="$ICON$"
    //! endtextmacro
    
    //! textmacro ItemStruct__EndPocket
        // Make object data.
        //! i setobjecttype("items")
        //! i createobject("ssil",sysIds[sysIdsUsed].itemType)
        //! i makechange(current,"iabi",dummyItemAbility)
        //! i makechange(current,"idro",0)
        //! i makechange(current,"isel",0)
        //! i makechange(current,"icla","Miscellaneous")
        //! i makechange(current,"igol",0)
        //! i makechange(current,"iicd",1)
        //! i makechange(current,"iprn",0)
        //! i makechange(current,"ilev",0)
        //! i makechange(current,"ipri",0)
        //! i makechange(current,"isto",0)
        //! i makechange(current,"istr",0)
        //! i makechange(current,"ides","")
        //! i makechange(current,"uhot","")
        //! i makechange(current,"utip","")
        //! i makechange(current,"iico",pocketIcon)
        //! i makechange(current,"unam",pocketName)
        //! i makechange(current,"utub",pocketDescription)
    //! endtextmacro
    
    
    //===========================================================================
    // Item Declaration
    //
    
    //! textmacro ItemType takes IDENTIFIER
        globals
            ItemType $IDENTIFIER$=0
        endglobals
        struct ItemStruct__$IDENTIFIER$ extends Item
            private static ItemType itemType=0
            //! i itemIdentifier="$IDENTIFIER$"
            private static method ItemStruct__init takes nothing returns nothing
                local integer i=bj_MAX_PLAYERS
                set thistype.itemType=ItemType.create(thistype.ItemStruct__create)
                //! i sysIdsUsed=sysIdsUsed+1
                set $IDENTIFIER$=thistype.itemType
                // Hide spellbook
                loop
                    set i=i-1
                    call SetPlayerAbilityAvailable(Player(i),thistype.itemType.ItemStruct__spellbookType,false)
                    exitwhen i==0
                endloop
                // Attach ItemType to item rawcode.
                call ItemStruct__RegisterItemType(thistype.itemType.ItemStruct__itemType,thistype.itemType)
                // Attach ItemType to item ability.
                call ItemStruct__RegisterItemType(thistype.itemType.ItemStruct__abilityType,thistype.itemType)
                // Defaults.
                set thistype.itemType.ItemStruct__name="$IDENTIFIER$"
                //! i itemName="$IDENTIFIER$"
                set thistype.itemType.ItemStruct__model="Objects\\InventoryItems\\TreasureChest\\treasurechest.mdl"
                //! i itemModel="Objects\\InventoryItems\\TreasureChest\\treasurechest.mdl"
                set thistype.itemType.ItemStruct__redTint=255
                set thistype.itemType.ItemStruct__greenTint=255
                set thistype.itemType.ItemStruct__blueTint=255
                //! i itemTint={red=255,green=255,blue=255}
                set thistype.itemType.ItemStruct__scale=1.0
                //! i itemScale=1.0
                set thistype.itemType.ItemStruct__goldCost=0
                set thistype.itemType.ItemStruct__lumberCost=0
                //! i itemCost={gold=0,lumber=0}
                set thistype.itemType.ItemStruct__stockMax=0
                //! i itemStockMax=0
                set thistype.itemType.ItemStruct__stockReplenishInterval=0
                //! i itemStockReplenishInterval=0
                set thistype.itemType.ItemStruct__stockStartDelay=0
                //! i itemStockStartDelay=0
                //! i itemPocket=0
                //! i itemIcon=""
                //! i itemHotkey=""
                //! i itemDescription=""
                
                //! i itemBaseAbility="ANcl"
                //! i itemAbilityData={}
                //! i itemAbilityLevelData={}
    //! endtextmacro
    //! textmacro ItemStruct
            endmethod
            implement ItemStruct
    //! endtextmacro
    //! textmacro EndItem
            private static method ItemStruct__create takes item i returns thistype
                local thistype this=thistype.create()
                set this.item=i
                call SetItemUserData(i,this)
                // means the ItemType, not item rawcode, in this case.
                set this.ItemStruct__itemType=thistype.itemType
                call this.onCreate()
                return this
            endmethod
        endstruct
        // Make object data.
        // Dummy item.
        //! i setobjecttype("items")
        //! i createobject("dust",sysIds[sysIdsUsed].itemType)
        //! i makechange(current,"iabi",dummyItemAbility)
        //! i makechange(current,"ubpx",0)
        //! i makechange(current,"iico",itemIcon)
        //! i makechange(current,"ifil",itemModel)
        //! i makechange(current,"iclr",itemTint.red)
        //! i makechange(current,"iclg",itemTint.green)
        //! i makechange(current,"iclb",itemTint.blue)
        //! i makechange(current,"isel",1)
        //! i makechange(current,"igol",itemCost.gold)
        //! i makechange(current,"ilum",itemCost.lumber)
        //! i makechange(current,"iicd",1)
        //! i makechange(current,"isto",itemStockMax)
        //! i makechange(current,"istr",itemStockReplenishInterval)
        //! i makechange(current,"isst",itemStockStartDelay)
        //! i makechange(current,"ides",itemDescription)
        //! i makechange(current,"uhot",itemHotkey)
        //! i makechange(current,"utip","[|cffffcc00"..itemHotkey.."|r] Purchase "..itemName)
        //! i makechange(current,"utub",itemDescription)
        // Use ability.
        //! i setobjecttype("abilities")
        //! i createobject(itemBaseAbility,sysIds[sysIdsUsed].abilityType)
        //! i makechange(current,"aart",itemIcon)
        //! i makechange(current,"aher",0)
        //! i makechange(current,"aite",0)
        //! i makechange(current,"alev",1)
        //! i makechange(current,"ahky",itemHotkey)
        //! i makechange(current,"anam",itemName)
        //! i if itemBaseAbility=="ANcl" then
            //! i pocketOrders[itemPocket]=pocketOrders[itemPocket]+1
            //! i makechange(current,"aord",sysOrders[pocketOrders[itemPocket]])
            //! i makechange(current,"Ncl6",1,sysOrders[pocketOrders[itemPocket]])
            //! i makechange(current,"Ncl5",1,0)
            //! i makechange(current,"Ncl4",1,0)
            //! i makechange(current,"Ncl1",1,0)
            //! i makechange(current,"Ncl3",1,"\001")
            //! i makechange(current,"acat","")
            //! i makechange(current,"aeat","")
            //! i makechange(current,"atat","")
        //! i end
        //! i makechange(current,"atp1",1,"[|cffffcc00"..itemHotkey.."|r] "..itemName)
        //! i makechange(current,"aub1",1,itemDescription)
        /*
        // TODO: Broken.
        //! for key,value in pairs(itemAbilityData) do
            //! i makechange(current,key,value)
        //! end
        //! for key,value in pairs(itemAbilityLevelData) do
            //! i makechange(current,key,1,value)
        //! end
        */
        // Spellbook
        //! i setobjecttype("abilities")
        //! i createobject("Aspb",sysIds[sysIdsUsed].spellbookType)
        //! i makechange(current,"aart","")
        //! i makechange(current,"aite",0)
        //! i makechange(current,"anam",itemName)
        //! i makechange(current,"ansf","(ItemStruct Spellbook)")
        //! i makechange(current,"aord",LAST_OPENED_ORDER)
        //! i makechange(current,"spb5",1,LAST_OPENED_ORDER)
        //! i makechange(current,"spb4",1,11)
        //! i makechange(current,"spb3",1,0)
        //! i makechange(current,"spb2",1,0)
        //! i makechange(current,"spb1",1,sysIds[sysIdsUsed].abilityType)
    //! endtextmacro
    
    //! textmacro SetItemName takes VAL
        set thistype.itemType.ItemStruct__name="$VAL$"
        //! i itemName="$VAL$"
    //! endtextmacro
    //! textmacro SetItemPocket takes POCKET
        set thistype.itemType.ItemStruct__pocket=$POCKET$
        //! i itemPocket=$POCKET$
    //! endtextmacro
    //! textmacro SetItemIcon takes VAL
        set thistype.itemType.ItemStruct__icon="$VAL$"
        //! i itemIcon="$VAL$"
    //! endtextmacro
    //! textmacro SetItemHotkey takes VAL
        set thistype.itemType.ItemStruct__hotkey="$VAL$"
        //! i itemHotkey="$VAL$"
    //! endtextmacro
    //! textmacro SetItemDescription takes VAL
        set thistype.itemType.ItemStruct__description="$VAL$"
        //! i itemDescription="$VAL$"
    //! endtextmacro
    //! textmacro SetItemModel takes VAL
        set thistype.itemType.ItemStruct__model="$VAL$"
        //! i itemModel="$VAL$"
    //! endtextmacro
    //! textmacro SetItemTint takes RED, GREEN, BLUE
        set thistype.itemType.ItemStruct__redTint=$RED$
        set thistype.itemType.ItemStruct__greenTint=$GREEN$
        set thistype.itemType.ItemStruct__blueTint=$BLUE$
        //! i itemTint={red=$RED$,green=$GREEN$,blue=$BLUE$}
    //! endtextmacro
    //! textmacro SetItemScale takes VAL
        set thistype.itemType.ItemStruct__scale=$VAL$
        //! i itemScale="$VAL$"
    //! endtextmacro
    //! textmacro SetItemCost takes GOLD, LUMBER
        set thistype.itemType.ItemStruct__goldCost=$GOLD$
        set thistype.itemType.ItemStruct__lumberCost=$LUMBER$
        //! i itemCost={gold=$GOLD$,lumber=$LUMBER$}
    //! endtextmacro
    //! textmacro SetItemStockMax takes VAL
        set thistype.itemType.ItemStruct__stockMax=$VAL$
        //! i itemStockMax=$VAL$
    //! endtextmacro
    //! textmacro SetItemStockReplenishInterval takes VAL
        set thistype.itemType.ItemStruct__stockReplenishInterval=$VAL$
        //! i itemStockReplenishInterval=$VAL$
    //! endtextmacro
    //! textmacro SetItemStockStartDelay takes VAL
        set thistype.itemType.ItemStruct__stockStartDelay=$VAL$
        //! i itemStockStartDelay=$VAL$
    //! endtextmacro
    //! textmacro SetItemBaseAbility takes VAL
        //! i itemBaseAbility="$VAL$"
    //! endtextmacro
    //! textmacro SetItemAbilityData takes ATTRIBUTE, VALUE
        //! i itemAbilityData["$ATTRIBUTE$"]="$VALUE$"
    //! endtextmacro
    //! textmacro SetItemAbilityLevelData takes ATTRIBUTE, VALUE
        //! i itemAbilityData["$ATTRIBUTE$"]="$VALUE$"
    //! endtextmacro
    
    //===========================================================================
    // JASS System
    //
    
    globals
        private hashtable Store=InitHashtable() // stores:
        // item rawcode, 0 --> ItemType
        // item rawcode, 0 --> Pocket
    endglobals
    function ItemStruct__RegisterItemType takes integer rawCode, ItemType itemType returns nothing
        call SaveInteger(Store,rawCode,0,itemType)
    endfunction
    private function GetItemItemType takes integer rawCode returns ItemType
        return ItemType(LoadInteger(Store,rawCode,0))
    endfunction
    // pocket funcs declared above.
    
    //===========================================================================
    // Pockets and ItemTypes
    //
    
    //private function interface CreateItemTypeXY takes real x, real y returns integer
    //private function interface CreateItemUnit takes unit u
    
    private struct IdBase
        static integer idMax=0
        implement IdBaseInitModule
        implement OrdersInitModule
        
        // Autofilled.
        integer ItemStruct__itemType
        integer ItemStruct__spellbookType
        integer ItemStruct__abilityType
        
        // Filled on init.
        string ItemStruct__name
        string ItemStruct__description
        string ItemStruct__icon
        string ItemStruct__model
    endstruct
    
    //! textmacro ItemStruct__Expose takes TYPE, MEMBER
        method operator $MEMBER$ takes nothing returns $TYPE$
            return this.ItemStruct__$MEMBER$
        endmethod
    //! endtextmacro
    
    struct Pocket extends IdBase
        //! runtextmacro ItemStruct__Expose("string","name")
        //! runtextmacro ItemStruct__Expose("string","description")
        
        private static hashtable hash
        
        readonly thistype nextPocket=0
        readonly static integer maxPockets=0
        private static thistype lastPocket=0
        static method create takes nothing returns thistype
            // increment maxPockets.
            set thistype.maxPockets=thistype.maxPockets+1
            // maintain pocket linked list.
            set thistype.lastPocket.nextPocket=thistype.allocate()
            set thistype.lastPocket=thistype.lastPocket.nextPocket
            // hash attach pocket to itemtype.
            return thistype.lastPocket
        endmethod
        implement PocketInitModule
    endstruct
    
    
    private function interface Method takes integer this returns nothing
    private function interface ItemAllocator takes item i returns Item
    private keyword allocator
    private keyword generateInstance
    
    struct ItemType extends IdBase
        /*libprivate*/ ItemAllocator allocator
        
        /*libprivate*/ static method create takes ItemAllocator allocator returns thistype
            local thistype this=thistype.allocate()
            set this.allocator=allocator
            return this
        endmethod
        
        /*libprivate*/ method generateInstance takes item i returns Item
            return this.allocator.evaluate(i)
        endmethod
        
        //! runtextmacro ItemStruct__Expose("string","name")
        //! runtextmacro ItemStruct__Expose("string","description")
        //! runtextmacro ItemStruct__Expose("integer","itemType")
        //! runtextmacro ItemStruct__Expose("integer","abilityType")
        
        string ItemStruct__hotkey
        //! runtextmacro ItemStruct__Expose("string","hotkey")
        Pocket ItemStruct__pocket
        //! runtextmacro ItemStruct__Expose("Pocket","pocket")
        integer ItemStruct__redTint=255
        //! runtextmacro ItemStruct__Expose("integer","redTint")
        integer ItemStruct__greenTint=255
        //! runtextmacro ItemStruct__Expose("integer","greenTint")
        integer ItemStruct__blueTint=255
        //! runtextmacro ItemStruct__Expose("integer","blueTint")
        real ItemStruct__scale=1.0
        //! runtextmacro ItemStruct__Expose("real","scale")
        integer ItemStruct__goldCost=0
        //! runtextmacro ItemStruct__Expose("integer","goldCost")
        integer ItemStruct__lumberCost=0
        //! runtextmacro ItemStruct__Expose("integer","lumberCost")
        integer ItemStruct__stockMax=0
        //! runtextmacro ItemStruct__Expose("integer","stockMax")
        integer ItemStruct__stockReplenishInterval=0
        //! runtextmacro ItemStruct__Expose("integer","stockReplenishInterval")
        integer ItemStruct__stockStartDelay=0
        //! runtextmacro ItemStruct__Expose("integer","stockStartDelay")
    endstruct
    
    /*libprivate*/ module ItemStruct // implemented in all items.
        private static method onInit takes nothing returns nothing
            call thistype.ItemStruct__init() // default values and stuff
        endmethod
    endmodule
    
    //===========================================================================
    // ItemStruct
    //
    
    private keyword itemListNext
    private keyword itemListPrev
    
    private interface DEFAULTS
        method onCreate takes nothing returns nothing defaults nothing // always on x/y.
        method onAcquire takes nothing returns nothing defaults nothing
        method onUse takes nothing returns nothing defaults nothing
        method onDrop takes nothing returns nothing defaults nothing
        
        /*libprivate*/ DEFAULTS itemListNext // thistype does not compile.
        /*libprivate*/ DEFAULTS itemListPrev // thistype does not compile.
    endinterface
    
    struct Item extends DEFAULTS
        static method operator [] takes item i returns thistype
            return thistype(GetItemUserData(i))
        endmethod
        
        Inventory holder=Inventory(0) // updated by Inventory only.
        delegate ItemType ItemStruct__itemType
        //! runtextmacro ItemStruct__Expose("ItemType","itemType")
        
        /*libprivate*/ item item
        
        method setPosition takes real x, real y returns nothing
            if this.holder==0 then
                call SetItemPosition(this.item,x,y)
            else
                call holder.removeItem(this)
                set this.item=CreateItem(this.itemType.ItemStruct__itemType,x,y)
                call SetItemUserData(this.item,this)
            endif
        endmethod
        method giveToUnit takes unit whichUnit returns nothing
            if this.holder==0 then
                call RemoveItem(this.item)
                set this.item=null
            else
                call holder.removeItem(this)
            endif
            call Inventory[whichUnit].addItem(this)
        endmethod
    endstruct
    function CreateItemXY takes ItemType itemType, real x, real y returns Item
        return itemType.generateInstance(CreateItem(itemType.ItemStruct__itemType,x,y))
    endfunction
    function CreateItemUnit takes ItemType itemType, unit whichUnit returns Item
        local Item i=itemType.generateInstance(CreateItem(itemType.ItemStruct__itemType,GetUnitX(whichUnit),GetUnitY(whichUnit)))
        call UnitAddItem(whichUnit,i.item)
        return i
    endfunction
    
    
    private function interface ItemFunction takes Item i returns nothing
    
    struct ItemList extends DEFAULTS // will always exist for each pocket for each unit.
        /*libprivate*/ readonly ItemType itemType
        readonly integer count
        //DEFAULTS itemListNext // thistype does not compile.
        //DEFAULTS itemListPrev // thistype does not compile.
        
        // links together ItemInstanceLists, items bunched by ItemTypes,
        // forming a PocketList, the ItemTypes that are in a Pocket for a unit.
        private thistype next
        private thistype prev
        /*libprivate*/ method loadPocketList takes unit u returns nothing
            local thistype curr=this.next
            loop
                exitwhen curr==this
                call UnitAddAbility(u,curr.itemType.ItemStruct__spellbookType)
                call UnitMakeAbilityPermanent(u,true,curr.itemType.ItemStruct__spellbookType)
                set curr=curr.next
            endloop
        endmethod
        /*libprivate*/ method unloadPocketList takes unit u returns nothing
            local thistype curr=this.next
            loop
                exitwhen curr==this
                call UnitMakeAbilityPermanent(u,false,curr.itemType.ItemStruct__spellbookType)
                call UnitRemoveAbility(u,curr.itemType.ItemStruct__spellbookType)
                set curr=curr.next
            endloop
        endmethod
        /*libprivate*/ static method createPocketList takes nothing returns thistype
            local thistype this=thistype.allocate()
            set this.next=this
            set this.prev=this
            return this
        endmethod
        /*libprivate*/ method createItemInstanceList takes Item firstNode returns thistype
            local thistype new=thistype.allocate()
            set new.itemType=firstNode.itemType
            set new.count=1
            
            // attach to PocketList this.
            set this.prev.next=new
            set new.prev=this.prev
            set this.prev=new
            set new.next=this
            
            // circularly link with item.
            set new.itemListNext=firstNode
            set new.itemListPrev=firstNode
            set firstNode.itemListNext=new
            set firstNode.itemListPrev=new
            
            return new
        endmethod
        
        method forEach takes ItemFunction func returns nothing
            local Item curr=Item(this.itemListNext)
            loop
                exitwhen curr==this
                call func.evaluate(curr)
                set curr=Item(curr.itemListNext)
            endloop
        endmethod
        method operator first takes nothing returns Item
            // empty should never exist
            return Item(this.itemListNext)
        endmethod
        method operator last takes nothing returns Item
            // empty should never exist
            return Item(this.itemListPrev)
        endmethod
        /*libprivate*/ method operator append= takes Item whichItem returns nothing
            set this.itemListPrev.itemListNext=whichItem
            set whichItem.itemListPrev=this.itemListPrev
            set this.itemListPrev=whichItem
            set whichItem.itemListNext=this
            set this.count=this.count+1
        endmethod
        /*libprivate*/ method operator remove= takes Item whichItem returns nothing
            set whichItem.itemListPrev.itemListNext=whichItem.itemListNext
            set whichItem.itemListNext.itemListPrev=whichItem.itemListPrev
            set this.count=this.count-1
        endmethod
        /*libprivate*/ method destroyItemInstanceList takes nothing returns nothing
            // assumes the list is empty.
            set this.next.prev=this.prev
            set this.prev.next=this.next
            call this.deallocate()
        endmethod
    endstruct
    
    struct Inventory extends array
        private static hashtable itemListHash=InitHashtable()
        //Exposed:
        method getItemList takes ItemType itemType returns ItemList
            return ItemList(LoadInteger(thistype.itemListHash,this,itemType))
        endmethod
        private method setItemList takes ItemType itemType, ItemList itemInstanceList returns nothing
            call SaveInteger(thistype.itemListHash,this,itemType,itemInstanceList)
        endmethod
        private method removeItemList takes ItemType itemType returns nothing
            call RemoveSavedInteger(thistype.itemListHash,this,itemType)
        endmethod
        
        private static ItemList array pocketListArray // look at my leet hashtable.
        private method getPocketList takes Pocket pocket returns ItemList
            return pocketListArray[this*Pocket.maxPockets+pocket]
        endmethod
        private method setPocketList takes Pocket pocket, ItemList pocketList returns nothing
            set pocketListArray[this*Pocket.maxPockets+pocket]=pocketList
        endmethod
        
        private static method AIDS_filter takes unit u returns boolean
            return GetUnitAbilityLevel(u,'AInv')>0
        endmethod
        private method AIDS_onCreate takes nothing returns nothing
            local Pocket pocket=Pocket(0).nextPocket
            // load first pocket as default.
            set this.currentPocket=pocket // assumes unit has no items, does not update list.
            // add dummy items and create PocketLists.
            loop
                exitwhen pocket==0
                call UnitAddItemById(this.unit,pocket.ItemStruct__itemType)
                call this.setPocketList(pocket,ItemList.createPocketList())
                set pocket=pocket.nextPocket
            endloop
            // add last opened pocket ability.
            call UnitAddAbility(this.unit,LAST_OPENED_ABIL)
            call UnitMakeAbilityPermanent(this.unit,true,LAST_OPENED_ABIL)
        endmethod
        private method AIDS_onDestroy takes nothing returns nothing
            //TODO
        endmethod
        //! runtextmacro AIDS()
        
        
        private Pocket currentPocket
        
        /*libprivate*/ method setCurrentPocket takes Pocket pocket returns nothing
            call this.getPocketList(this.currentPocket).unloadPocketList(this.unit)
            set this.currentPocket=pocket
            call this.getPocketList(pocket).loadPocketList(this.unit)
        endmethod
        
        /*libprivate*/ method addItem takes Item whichItem returns nothing
            // does not affect the Item's existance, just attaches.
            // assumes the item is in no inventory.
            local ItemType itemType=whichItem.itemType
            local ItemList itemInstanceList=this.getItemList(itemType)
            
            if itemInstanceList==0 then
                set itemInstanceList=this.getPocketList(itemType.pocket).createItemInstanceList(whichItem)
                call this.setItemList(itemType,itemInstanceList)
                // If the instance list is created for the current pocket, update display list...
                if itemType.pocket==this.currentPocket then
                    call UnitAddAbility(this.unit,itemType.ItemStruct__spellbookType)
                    call UnitMakeAbilityPermanent(this.unit,true,itemType.ItemStruct__spellbookType)
                endif
            else
                set itemInstanceList.append=whichItem
            endif
            
            //other:
            set whichItem.holder=this
        endmethod
        
        /*libprivate*/ method removeItem takes Item whichItem returns nothing
            // does not affect the Item's existance, just detaches.
            // assumes the item is in this inventory.
            local ItemType itemType=whichItem.itemType
            local ItemList itemInstanceList=this.getItemList(whichItem.itemType)
            set itemInstanceList.remove=whichItem
            if itemInstanceList.count==0 then
                // If the instance list is destroyed for the current pocket, update display list...
                if itemType.pocket==this.currentPocket then
                    call UnitMakeAbilityPermanent(this.unit,false,itemType.ItemStruct__spellbookType)
                    call UnitRemoveAbility(this.unit,itemType.ItemStruct__spellbookType)
                endif
                call this.removeItemList(whichItem.itemType)
                call itemInstanceList.destroyItemInstanceList()
            endif
            
            //other:
            set whichItem.holder=Inventory(0)
        endmethod
    endstruct
    
    //===========================================================================
    // Event Responses
    //
    
    globals//locals
        private item TriggeringItem
        private Item TriggeringItemItem
        private Pocket TriggeringPocket
        private ItemType TriggeringItemType
        private unit TriggeringItemUnit
    endglobals
    private function OnAcquire takes nothing returns boolean
        set TriggeringItem=GetManipulatedItem()
        set TriggeringItemItem=Item[TriggeringItem]
        if TriggeringItemItem!=0 then
            call Inventory[GetManipulatingUnit()].addItem(TriggeringItemItem)
            set TriggeringItemItem.item=null
            call TriggeringItemItem.onAcquire()
            call SetWidgetLife(TriggeringItem,0) // safety
            call RemoveItem(TriggeringItem)
        endif
        return false
    endfunction
    private function OnSell takes nothing returns boolean
        set TriggeringItem=GetSoldItem()
        // will set to 0 for invalid items.
        call GetItemItemType(GetItemTypeId(TriggeringItem)).generateInstance(TriggeringItem)
        return false
    endfunction
    private function OnUseItem takes nothing returns boolean
        set TriggeringPocket=GetItemPocketType(GetItemTypeId(GetManipulatedItem()))
        if TriggeringPocket!=0 then
            set TriggeringItemUnit=GetManipulatingUnit()
            call Inventory[TriggeringItemUnit].setCurrentPocket(TriggeringPocket)
            if GetLocalPlayer()==GetOwningPlayer(TriggeringItemUnit) then
                call ForceUICancel()
                call ForceUIKey(LAST_OPENED_HOTKEY)
            endif
        endif
        return false
    endfunction
    private function OnSpellEffect takes nothing returns boolean
        set TriggeringItemType=GetItemItemType(GetSpellAbilityId())
        if TriggeringItemType!=0 then
            call Inventory[GetTriggerUnit()].getItemList(TriggeringItemType).first.onUse()
        endif
        return false
    endfunction
    
    //===========================================================================
    // Init
    //
    
    private module InitModule
        private static method onInit takes nothing returns nothing
            local trigger t
            //! textmacro ItemStruct__InitTrigger takes EVENT, FUNCTION
                set t=CreateTrigger()
                call TriggerAddCondition(t,Filter(function $FUNCTION$))
                call TriggerRegisterAnyUnitEventBJ(t,EVENT_PLAYER_UNIT_$EVENT$)
            //! endtextmacro
            //! runtextmacro ItemStruct__InitTrigger("PICKUP_ITEM","OnAcquire")
            //! runtextmacro ItemStruct__InitTrigger("SELL_ITEM","OnSell")
            //! runtextmacro ItemStruct__InitTrigger("SPELL_EFFECT","OnSpellEffect")
            //! runtextmacro ItemStruct__InitTrigger("USE_ITEM","OnUseItem")
        endmethod
    endmodule
    struct InitModuleStruct extends array
        implement InitModule
    endstruct
endlibrary

Code (footer):
JASS:
//! endexternalblock


Please bare with me on this, this is an ALPHA release. Meaning no, it is not yet complete. It is usable and works, however. The nature of this system is that it is so complicated that I need to start getting feedback early to direct it, or it may be difficult to maintain later.

I have a big to-do list, but this is pretty cool.

It's... an item and inventory system. It displays in the ability section of the UI instead of ... something else. The interface is pretty small for what it does.

Example:
JASS:
//! runtextmacro ItemType("Sword")
    //! runtextmacro SetItemName("Really Big Sword")
    //! runtextmacro SetItemDescription("No really, this sword is huge.")
    //! runtextmacro SetItemHotkey("X")
    //! runtextmacro SetItemPocket("Pocket1")
    //! runtextmacro SetItemIcon("ReplaceableTextures\\CommandButtons\\BTNDaggerOfEscape.blp")
    //! runtextmacro SetItemBaseAbility("ACbf")
//! runtextmacro ItemStruct()
    method onUse takes nothing returns nothing
        call BJDebugMsg(this.name+" used.")
        call BJDebugMsg(GetUnitName(this.holder.unit))
    endmethod
    method onAcquire takes nothing returns nothing
        call BJDebugMsg(this.name+" acquired.")
        call BJDebugMsg(GetUnitName(this.holder.unit))
    endmethod
    method onCreate takes nothing returns nothing
        call BJDebugMsg(this.name+" created.")
    endmethod
    private static method onInit takes nothing returns nothing
        call CreateItemXY(thistype.itemType,0,0)
    endmethod
//! runtextmacro EndItem()
The above writes all associated object data. Only that code is required to generate everything.

I need to implement heaps of things like an ItemData module to apply to plug systems and global things in, and dropping items, etc. :)

Updates:
- Version 0.8.0 (ALPHA): ALPHA Release.
 

Attachments

  • ItemStruct.w3x
    81.4 KB · Views: 284

Sevion

The DIY Ninja
Reaction score
424
Ooh. That is nice. Maybe I'll mess around with it after my party today. :eek: Bookmarked so I don't forget.
 

Immolation

Member
Reaction score
20
Bug:

If you open/close or change pocket, the cooldowns reset.

Anyway, it's awesome.

Note: J4L obligated me to write that this system was awsum.

Proof:
[17:27] <Jesus4Lyf> yea
[17:27] <Jesus4Lyf> comment in thread tho
[17:27] <Jesus4Lyf> but say its awesome as well as the bug report
[17:27] <Jesus4Lyf> plz
[17:27] <Jesus4Lyf> lol
 

GetTriggerUnit-

DogEntrepreneur
Reaction score
129
awesome.png
It's awesome!

we see that white text btw, imo
 

Jesus4Lyf

Good Idea™
Reaction score
397
>J4L obligated me to write that this system was awsum.
Ahh, you tool. :p
If you open/close a pocket or change pocket, the cooldown reset.
I think I have a way to solve that. I recall this issue in Savage Creed, where this sys started a year or two ago. Hm.

There's a couple of ways to solve it... I'll think about it. :)
 

GetTriggerUnit-

DogEntrepreneur
Reaction score
129
>J4L

Maybe have 1 spell book per bag, that all have the same icon. Disable all books, when you click and item, enable the good spellbook. Cooldown should be saved if I'm right.

Ya? ya? no?
 

Jesus4Lyf

Good Idea™
Reaction score
397
Well actually, I was thinking I could have it done on the object data side of things. Each pocket could have a spellbook with ALL itemtypes for that pocket, and then disable/enable the actual abilities for the player when they click on the unit. I don't like that a heap because it'd add delay, though.

Edit: I can do it a few ways. Have multiple "open last" abilities with different orders is one such way. Then the item abilities can remain there. Else I can enable/disable for players. I kind of like the multiple open last abilities thing. :)
 

GetTriggerUnit-

DogEntrepreneur
Reaction score
129
Ah you're right, it would be slow. But it's an ultime solution if others don't work.

Offtopic:
I'd like to see something like that from you.

JASS:

library UnitMerge

    //! textmacro InitUnitStruct
        private struct UnitMerge
            string unitname
            string tooltip
            string ubertooltip
    //! endtextmacro
    
    //! textmacro EndUnitStruct
        endstruct
    //! endtextmacro


    //! textmacro SetUnitName takes NAME
        thistype.unitname = $NAME$
    //! endtextmacro
    //! textmacro SetUnitTooltip takes NAME
        thistype.tooltip = $NAME$
    //! endtextmacro
    //! textmacro SetUberUnitTooltip takes NAME
        thistype.ubertooltip = $NAME$
    //! endtextmacro
    
    // And then, with these informations, merge the unit.
    //! textmacro MergeUnit
        //! external ObjectMerger
    //! endtextmacro    


endlibrary

// Ex. of usage.

scope fun

//! runtextmacro InitUnitStruct()

//! runtextmacro SetUnitName(&quot;Jesus4Lyf&quot;)

//! runtextmacro EndUnitStruct()
//! runtextmacro MergeUnit()

// POOF unit is merged and it was much simplier than the command //! external ObjectMerger zzzz zzzz &quot;zzz&quot; zz etc..

endscope
 

Jesus4Lyf

Good Idea™
Reaction score
397
Can't drop abilities >.<
In Savage Creed I didn't use point-target or unit-target items, so I wrote a system that let you click a "drop" icon and then the ability of the item you wish to stop. I thought for this, I would have a "drop" icon which would display a dialogue of the items in the pocket. Click on the item you wish to drop. What do you think? :)
 

GetTriggerUnit-

DogEntrepreneur
Reaction score
129
In Savage Creed I didn't use point-target or unit-target items, so I wrote a system that let you click a "drop" icon and then the ability of the item you wish to stop. I thought for this, I would have a "drop" icon which would display a dialogue of the items in the pocket. Click on the item you wish to drop. What do you think? :)

Perfect.
 

weaaddar

New Member
Reaction score
6
This is really cool from a scripting standpoint, and I shamelessly might steal the idea of external blocking object mergering to do the dirty work in the OE and the hooks for the jass end.

I kind of think though the example is anemic, and hard to demonstrate why this is so cool.
 

Jesus4Lyf

Good Idea™
Reaction score
397
This is really cool from a scripting standpoint, and I shamelessly might steal the idea of external blocking object mergering to do the dirty work in the OE and the hooks for the jass end.
Go ahead. I wouldn't mind a little credit note if that's alright.

I kind of think though the example is anemic, and hard to demonstrate why this is so cool.
It totally is, but I need to do a little more work on the core sys. I found the bug I was experiencing - object merger doesn't seem to correctly do Channel based abilities.

There's a lot of design going on. I want this:
JASS:
struct MyItemData extends array
    implement ItemData
    integer timesUsed
    private method onUse takes nothing returns boolean
        set this.timesUsed=this.timesUsed+1
        return this.timesUsed&lt;=3 // items may only be used 3 times. true lets item be used, false blocks.
    endmethod
    private method onCreate takes nothing returns nothing
        set this.timesUsed=0
    endmethod
endstruct
 

Nestharus

o-o
Reaction score
84
This system is like.. really epic ^_-

I was first looking through going omg at the text macros and then I just didn't want to comment because I was going omg at the text macros, but then I look at the example and go wow


You somehow pulled off a brilliant interface with text macros of all things which deserves like 20 thumbs up from me. The interface *would* be a lot better using definitions as that'd get rid of the fugly text macros and just allow you to do a lot more to make it easier to use, but again that's cJASS so while it may be beneficial, the benefits are so very small in comparison to the work you'd have to go through and the fact that it wouldn't be allowed anywhere, lol ^_^.

Anyhow, really awesome job ^_-.


If only there was a prettier way to code in LUA /cry
 

weaaddar

New Member
Reaction score
6
Yeah, I'll totally credit you. Great Idea, I think I'll recreate my old framework DBMod (drunken brawler mod) and do it with object merger so that its a lot more easy to plop into a map.
 
General chit-chat
Help Users
  • No one is chatting at the moment.

      The Helper Discord

      Staff online

      Members online

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top