| 10-06-2009, 06:13 PM | #1 |
Hi all, This is an equipment system used to simulate an equipment menu. I'm posting this here to hopefully get some feedback on the functionality, as well as the code. Note that this is just a testversion, the code is not properly commented, nor is there any full documentation. Importing is not supported yet, which is why abilityid's are hardcoded. I embarked on this project April 2006, where it was uploaded at clancbs.com. It was also reviewed here by blu_da_noob, however it was rejected due to some coding issues. In January 2009 I made a revamp of it, adding new functionality and remaking alot of the code. Today, I'm hopefully rewriting it for the last time. It now uses vJass and ObjectMerger for easy importing and a clean code structure. So the system requires NewGen/JassHelper. The new system should support any kind of item bonuses you may want with some Jass knowledge. It currently only functions as a template, however, I will later add modules to simplify adding basic stats. Upcoming features:
Enjoy TEEquip v0.2:library TEEquip initializer Init requires Table, Stack, UnitIndexingUtils, SimError //*********************************************************************************************************************** //* TEEquip //* //* Author: Thunder_Eye //* //* Credits: //* * Vexorian for vJass, JassHelper, and the finding of the spellbook trick //* * PitzerMike for the ObjectMerger //* * PipeDream for Grimoire //* * SFilip for TESH //* * MindWorX for maintaining NewGen //* //* Required Libraries: //* * Table by Vexorian //* * Stack by Anitarf //* * UnitIndexingUtils by Rising Dusk //* * SimError by Vexorian //* //* Optional Libraries: //* * UnitMaxState by Earth-Fury //* * BonusMod by Earth-Fury //* //* This is an equipment system which is easy to implent, and outputs a smooth //* userinterface for the endgame user. However, it requires some massive Object //* Editor use, and if used incorrectly, may clutter up your Ability section. //* It supports up to 8191 different allocated itemtypes, and the same amount of //* units utilizing the system. //* //* The basic system only works as a template with the addition that it handles //* item requirements for you. //* //* In a future version however, there will be additional modules that can manage //* changing the basic stats for you. //* //* Note that using UnitIndexingUtils will render you unable to use UnitUserData(). //* //* To initialize a unit, call InitUnit (with the TEEquip prefix) //* To add an itemtype, call AddItemType (again, with the TEEquip prefix) //* Note that these are just wrapper functions, I suggest creating the structs //* directly. //* //* Function list: //* function InitUnit takes unit u returns nothing //* function AddItemType takes integer iType, integer aId, integer sbId, integer slot, code eF, code uF returns nothing //* function AddRestriction takes string restriction returns nothing //* function AddRequirement takes string requirement returns nothing //* function SetRequiredLevel takes integer value returns nothing //* function SetRequiredStr takes integer value returns nothing //* function SetRequiredAgi takes integer value returns nothing //* function SetRequiredInt takes integer value returns nothing //* function AddFunction takes code eF, code uF returns nothing //* function GetSlotId takes string s returns integer //* //* Initialize a unit and give it an equipment menu. //* This is just a wrapper function, I suggest creating the struct directly instead. //* function InitUnit takes unit u returns nothing //* unit u: The unit to initialize //* //* Add an itemtype to the system, making it equippable //* This is just a wrapper function, I suggest creating the struct directly instead. //* function AddItemType takes integer iType, integer aId, integer sbId, integer slot, code eF, code uF returns nothing //* integer iType: The rawid of the itemtype. //* integer aId: The rawid of the UI ability. //* integer sbId: The rawid of the spellbook holding ability aId. //* integer slot: The slot where the item is placed when equipped. //* Can be anything between 0-10. //* code eF: The function which runs when the item is equipped. //* code uF: The function which runs when the item is unequipped. //* //* Add a restriction to a unit, enabling it to use items with the proper requirement. //* Note that units with no restrictions may only equip items with no requirements. //* Member of: equipunit //* function AddRestriction takes string restriction returns nothing //* string restriction: The key of the restrictiontype, upper- or lowercase does not matter. //* //* Add a requirement to an item, requiring units to have the proper restrictions to use it. //* Note that items with no requirements may be equipped by any initialized unit. //* Units must match ALL requirements to equip item. //* Member of: equipitem //* function AddRequirement takes string requirement returns nothing //* string requirement: The key of the requirementtype, upper- or lowercase does not matter. //* //* Temporary function to set a required level on itemtypes. //* Member of: equipitem //* function SetRequiredLevel takes integer value returns nothing //* integer value: The required level. //* //* Temporary function to set a required strength on itemtypes. //* Member of: equipitem //* function SetRequiredStr takes integer value returns nothing //* integer value: The required strength. //* //* Temporary function to set a required agility on itemtypes. //* Member of: equipitem //* function SetRequiredAgi takes integer value returns nothing //* integer value: The required agility. //* //* Temporary function to set a required intelligence on itemtypes. //* Member of: equipitem //* function SetRequiredInt takes integer value returns nothing //* integer value: The required intelligence. //* //* Adds an additional function (including the one when you add an itemtype) to an itemtype. //* Member of: equipitem //* function AddFunction takes code eF, code uF returns nothing //* code eF: The function which runs when the item is equipped. //* code uF: The function which runs when the item is unequipped. //* //* Gets the id of a slot. //* Can be used if you want to clarify the slot when using AddItemType. //* function GetSlotId takes string slot returns integer //* string slot: The slot you want the id from. //* "shoulder" = 0, "head" = 1, "neck" = 2, "finger" = 3, //* "mainhand" = 4, "chest" = 5, "offhand" = 6, "wrists" = 7 //* "feet" = 8, "legs" = 9, "hands" = 10 //* //*********************************************************************************************************************** globals //equipItemTable = key is itemtype-id, value is struct-id //equipUnitTable = key is id of unit, value is struct-id private Table equipItemTable private Table equipUnitTable //requirementTable = key is the name of the requirement, value is the id (requirementTable["plate"] = 1) //requirementKey = key is the id of the requirement, value is the name (requirementKey[1] = "plate") //requirementTotal = Amount of requirements and key for new requirements (requirementTotal = 2) private StringTable requirementTable private string array requirementKey private integer requirementTotal = 0 //itemTypesAtP[11] = Stack pointing to struct-ids //emptySlot[11] = Array with the "unequipped" spellbooks private Stack array itemTypesAtP[11] private integer array emptySlot[11] //slotId = key is the name of the slot, value is the id //hasInited = set to true when a unit is initialized private StringTable slotId private boolean hasInited = false //passUnit = triggering unit passed for equip/unequip functions //passItem = manipulated item passed for equip/unequip functions public unit passUnit public item passItem endglobals struct equipitem private integer itemTypeId private integer abilityId private integer spellbookId private integer slot private Stack requirements = Stack.create() private trigger equipTrigger = CreateTrigger() private trigger unequipTrigger = CreateTrigger() //Temporary until I add some kind of table to handle this. private integer levelReq = 0 private integer strReq = 0 private integer agiReq = 0 private integer intReq = 0 //************************************************************************************ //******************************Call functions (public)******************************* //************************************************************************************ public method AddRequirement takes string requirement returns nothing local integer i set requirement = StringCase(requirement, false) //Check so that it doesn't create duplicate keys of requirements. if not .requirements.contains(requirementTable[requirement]) then if requirementTable.exists(requirement) then //Item requirement type already exists. set i = requirementTable[requirement] else //Item requirement type does not exist, so add it to the table. set requirementTotal = requirementTotal + 1 set i = requirementTotal set requirementTable[requirement] = i set requirementKey[i] = requirement endif //Add the key for the requirement type to the itemtype call .requirements.push(i) endif endmethod public method SetRequiredLevel takes integer value returns nothing set .levelReq = value endmethod public method SetRequiredStr takes integer value returns nothing set .strReq = value endmethod public method SetRequiredAgi takes integer value returns nothing set .agiReq = value endmethod public method SetRequiredInt takes integer value returns nothing set .intReq = value endmethod public method AddFunction takes code eF, code uF returns nothing call .AddEquipFunc(eF) call .AddUnequipFunc(uF) endmethod public method GetItemTypeId takes nothing returns integer return .itemTypeId endmethod public method GetAbilityId takes nothing returns integer return .abilityId endmethod public method GetSpellbookId takes nothing returns integer return .spellbookId endmethod public method GetRequirementList takes nothing returns Stack return .requirements endmethod public method GetSlot takes nothing returns integer return .slot endmethod //************************************************************************************ //*****************************System functions (private)***************************** //************************************************************************************ public method TryStats takes integer level, integer str, integer agi, integer int returns boolean if level >= .levelReq and str >= .strReq and agi >= .agiReq and int >= .intReq then return true endif return false endmethod private method AddEquipFunc takes code f returns nothing if f != null then call TriggerAddAction(.equipTrigger, f) endif endmethod private method AddUnequipFunc takes code f returns nothing if f != null then call TriggerAddAction(.unequipTrigger, f) endif endmethod public method Equip takes unit u, item i returns nothing set passUnit = u set passItem = i call TriggerExecute(.equipTrigger) endmethod public method Unequip takes unit u, item i returns nothing set passUnit = u set passItem = i call TriggerExecute(.unequipTrigger) endmethod static method create takes integer itemTypeId, integer abilityId, integer spellbookId, integer slot, code eF, code uF returns equipitem local equipitem new //If no unit has been registered, create the itemtype. if not hasInited then set new = equipitem.allocate() set new.itemTypeId = itemTypeId set new.abilityId = abilityId set new.spellbookId = spellbookId set new.slot = slot call new.AddEquipFunc(eF) call new.AddUnequipFunc(uF) call itemTypesAtP[slot].push(new) endif set equipItemTable[itemTypeId] = new set equipItemTable[abilityId] = new return new endmethod endstruct struct equipunit private unit u integer array equippedItem[11] Stack res = Stack.create() static group equipUnits = CreateGroup() static trigger onEquip = CreateTrigger() static trigger onUnequip = CreateTrigger() //************************************************************************************ //******************************Call functions (public)******************************* //************************************************************************************ method AddRestriction takes string restriction returns nothing local integer i set restriction = StringCase(restriction, false) if requirementTable.exists(restriction) then //Item requirement type already exists. set i = requirementTable[restriction] else //Item requirement type does not exist, so add it to the table. set requirementTotal = requirementTotal + 1 set i = requirementTotal set requirementTable[restriction] = i set requirementKey[i] = restriction endif //Add the key for the requirement type to the unit call .res.push(i) endmethod method onDestroy takes nothing returns nothing local integer i = 0 call UnitRemoveAbility(.u, 'A000') loop exitwhen i > 10 call UnitAddAbility(.u, emptySlot[i]) set i = i + 1 endloop call .res.destroy() set .u = null endmethod method Reset takes nothing returns nothing call .destroy() endmethod //************************************************************************************ //*****************************System functions (private)***************************** //************************************************************************************ private static method condition takes nothing returns boolean return IsUnitInGroup(GetTriggerUnit(), equipunit.equipUnits) endmethod private static method onequip takes nothing returns nothing local unit u = GetTriggerUnit() local item i = GetManipulatedItem() local equipitem ei = equipItemTable[GetItemTypeId(i)] local equipunit eu = equipUnitTable[GetUnitId(u)] local integer slot = ei.GetSlot() local Stack unitRes = Stack.create() local Stack itemReq = Stack.create() local integer l local boolean b = true if ei != 0 and eu.equippedItem[slot] == 0 and eu != 0 then //Check requirements by looping through them. set unitRes = eu.res.copy() set itemReq = ei.GetRequirementList().copy() loop set l = itemReq.pop() exitwhen l == Stack.EMPTY if not unitRes.contains(l) then set b = false endif endloop //If unit can equip item. if b and ei.TryStats(GetHeroLevel(u),GetHeroStr(u, false),GetHeroAgi(u, false),GetHeroInt(u, false)) then set eu.equippedItem[slot] = ei.GetItemTypeId() call UnitRemoveAbility(u, emptySlot[slot]) call UnitAddAbility(u, ei.GetSpellbookId()) call RemoveItem(i) if GetLocalPlayer() == GetOwningPlayer(u) then call ForceUIKey("I") endif call ei.Equip(u, i) else call SimError(GetOwningPlayer(u), "You do not meet the requirements for that item.") endif elseif ei != 0 and eu != 0 then call SimError(GetOwningPlayer(u), "You already have an item equipped.") else call SimError(GetOwningPlayer(u), "You cannot equip that item.") endif call unitRes.destroy() call itemReq.destroy() set u = null set i = null endmethod private static method onunequip takes nothing returns nothing local unit u = GetTriggerUnit() local item i local integer a = GetSpellAbilityId() local equipitem ei = equipItemTable[a] local equipunit eu = equipUnitTable[GetUnitId(u)] local integer slot = ei.GetSlot() if ei != 0 and eu.equippedItem[slot] != 0 then //Check if inventory is full, if so halt trigger. if UnitInventoryCount(u) == UnitInventorySize(u) then call SimError(GetOwningPlayer(u), "Inventory is full") set u = null return endif set eu.equippedItem[slot] = 0 set i = CreateItem(ei.GetItemTypeId(), 0, 0) call UnitRemoveAbility(u, ei.GetSpellbookId()) call UnitAddAbility(u, emptySlot[slot]) call UnitAddItem(u, i) if GetLocalPlayer() == GetOwningPlayer(u) then call ForceUIKey("I") endif call ei.Unequip(u, i) endif set u = null endmethod private static method onInit takes nothing returns nothing call TriggerRegisterAnyUnitEventBJ(equipunit.onEquip, EVENT_PLAYER_UNIT_USE_ITEM) call TriggerAddCondition(equipunit.onEquip, Condition(function equipunit.condition)) call TriggerAddAction(equipunit.onEquip, function equipunit.onequip) call TriggerRegisterAnyUnitEventBJ(equipunit.onUnequip, EVENT_PLAYER_UNIT_SPELL_CAST) call TriggerAddCondition(equipunit.onUnequip, Condition(function equipunit.condition)) call TriggerAddAction(equipunit.onUnequip, function equipunit.onunequip) endmethod static method create takes unit u returns equipunit local equipunit new = equipunit.allocate() local player p = GetOwningPlayer(u) local Stack s = Stack.create() local equipitem ei local integer sbId local integer i set new.u = u call GroupAddUnit(equipunit.equipUnits, u) call UnitAddAbility(u, 'A000') set i = 0 loop exitwhen i > 10 set new.equippedItem[i] = 0 set i = i + 1 endloop set i = 0 loop exitwhen i > 10 call UnitAddAbility(u, emptySlot[i]) call SetPlayerAbilityAvailable(p, emptySlot[i], false) set s = itemTypesAtP[i].copy() loop exitwhen s.peek()==Stack.EMPTY set ei = s.peek() set sbId = ei.GetSpellbookId() call UnitAddAbility(u, sbId) call UnitRemoveAbility(u, sbId) call SetPlayerAbilityAvailable(p, sbId, false) call s.pop() endloop set i = i + 1 endloop //Add the unit to the table and make sure no more itemtypes are registered. set equipUnitTable[GetUnitId(u)] = new set hasInited = true call s.destroy() return new endmethod endstruct public function InitUnit takes unit u returns equipunit return equipunit.create(u) endfunction public function AddItemType takes integer itemTypeId, integer abilityId, integer spellbookId, integer slot, code eF, code uF returns equipitem return equipitem.create(itemTypeId, abilityId, spellbookId, slot, eF, uF) endfunction function GetSlotId takes string s returns integer return slotId[StringCase(s, false)] endfunction private function Init takes nothing returns nothing local integer i = 0 set equipItemTable = Table.create() set equipUnitTable = Table.create() set requirementTable = Table.create() set slotId = StringTable.create() loop exitwhen i > 10 set itemTypesAtP[i] = Stack.create() set i = i + 1 endloop set slotId["shoulders"] = 0 set slotId["head"] = 1 set slotId["neck"] = 2 set slotId["finger"] = 3 set slotId["mainhand"] = 4 set slotId["chest"] = 5 set slotId["offhand"] = 6 set slotId["wrists"] = 7 set slotId["feet"] = 8 set slotId["legs"] = 9 set slotId["hands"] = 10 set emptySlot[0] = 'ES01' set emptySlot[1] = 'ES02' set emptySlot[2] = 'ES03' set emptySlot[3] = 'ES04' set emptySlot[4] = 'ES05' set emptySlot[5] = 'ES06' set emptySlot[6] = 'ES07' set emptySlot[7] = 'ES08' set emptySlot[8] = 'ES09' set emptySlot[9] = 'ES0A' set emptySlot[10] = 'ES0B' endfunction endlibrary TEEquip v0.1:library TEEquip initializer Init requires Table, Stack, UnitIndexingUtils, SimError //*********************************************************************************************************************** //* TEEquip //* //* Author: Thunder_Eye //* //* Credits: //* * Vexorian for vJass, JassHelper, and the finding of the spellbook trick //* * PitzerMike for the ObjectMerger //* * PipeDream for Grimoire //* * SFilip for TESH //* * MindWorX for maintaining NewGen //* * Earth-Fury for UnitMaxState and BonusMod //* //* Required Libraries: //* * Table by Vexorian //* * Stack by Anitarf //* * UnitIndexingUtils by Rising Dusk //* * SimError by Vexorian //* //* This is an equipment system which is easy to implent, and outputs a smooth //* userinterface for the endgame user. However, it requires some massive Object //* Editor use, and if used incorrectly, may clutter up your Ability section. //* It supports up to 8191 different allocated itemtypes, and the same amount of //* units utilizing the system. //* //* The basic system only works as a template with the addition that it handles //* item requirements for you. //* //* In a future version however, there will be additional modules that can manage //* changing the basic stats for you. //* //* Note that using UnitIndexingUtils will make you unable to use UnitUserData(). //* //* To initialize a unit, call InitUnit (with the TEEquip prefix) //* To add an itemtype, call AddItemType (again, with the TEEquip prefix) //* //* Function list: //* function InitUnit takes unit u returns nothing //* function AddItemType takes integer iType, integer aId, integer sbId, integer slot, code eF, code uF returns nothing //* function UnitAddRestriction takes unit u, string restriction returns nothing //* function ItemTypeAddRequirement takes integer iType, string requirement returns nothing //* function SetItemTypeLevel takes integer iType, integer level returns nothing //* function ItemTypeAddFunction takes integer iType, code eF, code uF returns nothing //* function GetSlotId takes string s returns integer //* //* Initialize a unit and give it an equipment menu. //* function InitUnit takes unit u returns nothing //* unit u: The unit to initialize //* //* Add an itemtype to the system, making it equippable //* function AddItemType takes integer iType, integer aId, integer sbId, integer slot, code eF, code uF returns nothing //* integer iType: The rawid of the itemtype. //* integer aId: The rawid of the UI ability. //* integer sbId: The rawid of the spellbook holding ability aId. //* integer slot: The slot where the item is placed when equipped. //* Can be anything between 0-10. //* code eF: The function which runs when the item is equipped. //* code uF: The function which runs when the item is unequipped. //* //* Add a restriction to a unit, enabling it to use items with the proper requirement. //* Note that units with no restrictions may only equip items with no requirements. //* function UnitAddRestriction takes unit u, string restriction returns nothing //* unit u: The unit to add a restriction to. //* string restriction: The key of the restrictiontype, upper- or lowercase does not matter. //* //* Add a requirement to an item, requiring units to have the proper restrictions to use it. //* Note that items with no requirements may be equipped by any initialized unit. //* Units must match ALL requirements to equip item. //* function ItemTypeAddRequirement takes integer iType, string requirement returns nothing //* integer iType: The rawid of the itemtype. //* string requirement: The key of the requirementtype, upper- or lowercase does not matter. //* //* Temporary function to set a required level on itemtypes. //* function SetItemTypeLevel takes integer iType, integer level returns nothing //* integer iType: The rawid of the itemtype. //* integer level: The required level. //* //* Adds an additional function (including the one when you add an itemtype) to an itemtype. //* function ItemTypeAddFunction takes integer iType, code eF, code uF returns nothing //* integer iType: The rawid of the itemtype. //* code eF: The function which runs when the item is equipped. //* code uF: The function which runs when the item is unequipped. //* //* Gets the id of a slot. //* Can be used if you want to clarify the slot when using AddItemType. //* function GetSlotId takes string slot returns integer //* string slot: The slot you want the id from. //* "shoulder" = 0, "head" = 1, "neck" = 2, "finger" = 3, //* "mainhand" = 4, "chest" = 5, "offhand" = 6, "wrists" = 7 //* "feet" = 8, "legs" = 9, "hands" = 10 //* //*********************************************************************************************************************** globals private Table itemTypeTable private Table unitTable private Stack array itemTypesAtP[11] private integer array emptySlot[11] private StringTable requirementTable private string array requirementKey private integer requirementCount = 0 private StringTable slotId private boolean hasInited = false public unit passUnit public item passItem endglobals private struct itemType private integer iType private integer aId private integer sbId private integer slot private Stack req = Stack.create() private trigger eT = CreateTrigger() private trigger uT = CreateTrigger() //Temporary until I add some kind of table to handle this. public integer levelReq = 0 public method AddEquipFunc takes code f returns nothing if f != null then call TriggerAddAction(.eT, f) endif endmethod public method AddUnequipFunc takes code f returns nothing if f != null then call TriggerAddAction(.uT, f) endif endmethod public method Equip takes unit u, item i returns nothing set passUnit = u set passItem = i call TriggerExecute(.eT) endmethod public method Unequip takes unit u, item i returns nothing set passUnit = u set passItem = i call TriggerExecute(.uT) endmethod public method GetItemTypeId takes nothing returns integer return .iType endmethod public method GetSlot takes nothing returns integer return .slot endmethod public method GetSpellbookId takes nothing returns integer return .sbId endmethod public method GetAbilityId takes nothing returns integer return .aId endmethod public method GetRequirementList takes nothing returns Stack return .req endmethod static method create takes integer iType, integer aId, integer sbId, integer slot returns itemType local itemType new = itemType.allocate() set new.iType = iType set new.aId = aId set new.sbId = sbId set new.slot = slot set itemTypeTable[iType] = new set itemTypeTable[aId] = new return new endmethod endstruct private struct equipunit private unit u integer array equippedItem[11] Stack res = Stack.create() static group equipUnits = CreateGroup() static trigger onEquip = CreateTrigger() static trigger onUnequip = CreateTrigger() private static method condition takes nothing returns boolean return IsUnitInGroup(GetTriggerUnit(), equipunit.equipUnits) endmethod private static method onequip takes nothing returns nothing local unit u = GetTriggerUnit() local item i = GetManipulatedItem() local itemType iT = itemTypeTable[GetItemTypeId(i)] local equipunit eu = unitTable[GetUnitId(u)] local integer slot = iT.GetSlot() local Stack unitRes = Stack.create() local Stack itemReq = Stack.create() local integer l local boolean b = true if iT != 0 and eu.equippedItem[slot] == 0 and eu != 0 then //Check requirements by looping through them. set unitRes = eu.res.copy() set itemReq = iT.GetRequirementList().copy() loop set l = itemReq.pop() exitwhen l == Stack.EMPTY if not unitRes.contains(l) then set b = false endif endloop //If unit can equip item. if b and iT.levelReq <= GetHeroLevel(u) then set eu.equippedItem[slot] = iT.GetItemTypeId() call UnitRemoveAbility(u, emptySlot[slot]) call UnitAddAbility(u, iT.GetSpellbookId()) call RemoveItem(i) if GetLocalPlayer() == GetOwningPlayer(u) then call ForceUIKey("I") endif call iT.Equip(u, i) else call SimError(GetOwningPlayer(u), "You do not meet the requirements for that item.") endif elseif iT != 0 and eu != 0 then call SimError(GetOwningPlayer(u), "You already have an item equipped.") else call SimError(GetOwningPlayer(u), "You cannot equip that item.") endif call unitRes.destroy() call itemReq.destroy() set u = null set i = null endmethod private static method onunequip takes nothing returns nothing local unit u = GetTriggerUnit() local item i local integer a = GetSpellAbilityId() local itemType iT = itemTypeTable[a] local equipunit eu = unitTable[GetUnitId(u)] local integer slot = iT.GetSlot() if iT != 0 and eu.equippedItem[slot] != 0 then //Check if inventory is full, if so halt trigger. if UnitInventoryCount(u) == UnitInventorySize(u) then call SimError(GetOwningPlayer(u), "Inventory is full") set u = null return endif set eu.equippedItem[slot] = 0 set i = CreateItem(iT.GetItemTypeId(), 0, 0) call UnitRemoveAbility(u, iT.GetSpellbookId()) call UnitAddAbility(u, emptySlot[slot]) call UnitAddItem(u, i) if GetLocalPlayer() == GetOwningPlayer(u) then call ForceUIKey("I") endif call iT.Unequip(u, i) endif set u = null endmethod method onDestroy takes nothing returns nothing call .res.destroy() set .u = null endmethod static method create takes unit u returns equipunit local equipunit new = equipunit.allocate() local integer i = 0 set new.u = u call GroupAddUnit(equipunit.equipUnits, u) loop exitwhen i > 10 set new.equippedItem[i] = 0 set i = i + 1 endloop return new endmethod static method onInit takes nothing returns nothing call TriggerRegisterAnyUnitEventBJ(equipunit.onEquip, EVENT_PLAYER_UNIT_USE_ITEM) call TriggerAddCondition(equipunit.onEquip, Condition(function equipunit.condition)) call TriggerAddAction(equipunit.onEquip, function equipunit.onequip) call TriggerRegisterAnyUnitEventBJ(equipunit.onUnequip, EVENT_PLAYER_UNIT_SPELL_CAST) call TriggerAddCondition(equipunit.onUnequip, Condition(function equipunit.condition)) call TriggerAddAction(equipunit.onUnequip, function equipunit.onunequip) endmethod endstruct public function InitUnit takes unit u returns nothing local player p = GetOwningPlayer(u) local integer i = 0 local itemType iT local Stack s = Stack.create() local equipunit eu = equipunit.create(u) local integer sbId //Equipment spellbook ability call UnitAddAbility(u, 'A000') set i = 0 loop exitwhen i > 10 call UnitAddAbility(u, emptySlot[i]) call SetPlayerAbilityAvailable(p, emptySlot[i], false) set s = itemTypesAtP[i].copy() loop exitwhen s.peek()==Stack.EMPTY set iT = s.peek() set sbId = iT.GetSpellbookId() call UnitAddAbility(u, sbId) call UnitRemoveAbility(u, sbId) call SetPlayerAbilityAvailable(p, sbId, false) call s.pop() endloop set i = i + 1 endloop //Add the unit to the table and make sure no more itemtypes are registered. set unitTable[GetUnitId(u)] = eu set hasInited = true call s.destroy() endfunction public function AddItemType takes integer iType, integer aId, integer sbId, integer slot, code eF, code uF returns nothing local itemType i //If no unit has been registered, create the itemtype. if not hasInited then set i = itemType.create(iType, aId, sbId, slot) call i.AddEquipFunc(eF) call i.AddUnequipFunc(uF) call itemTypesAtP[slot].push(i) endif endfunction public function ResetUnit takes unit u returns nothing local equipunit eu = unitTable[GetUnitId(u)] local integer i = 0 call UnitRemoveAbility(u, 'A000') loop exitwhen i > 10 call UnitAddAbility(u, emptySlot[i]) set i = i + 1 endloop call eu.destroy() endfunction public function UnitAddRestriction takes unit u, string restriction returns nothing local equipunit eu = unitTable[GetUnitId(u)] local integer count set restriction = StringCase(restriction, false) if requirementTable.exists(restriction) then //Item requirement type already exists. set count = requirementTable[restriction] else //Item requirement type does not exist, so add it to the table. set requirementCount = requirementCount + 1 set count = requirementCount set requirementTable[restriction] = count set requirementKey[count] = restriction endif //Add the key for the requirement type to the unit call eu.res.push(count) endfunction public function ItemTypeAddRequirement takes integer iType, string requirement returns nothing local itemType i = itemTypeTable[iType] local integer count set requirement = StringCase(requirement, false) if requirementTable.exists(requirement) then //Item requirement type already exists. set count = requirementTable[requirement] else //Item requirement type does not exist, so add it to the table. set requirementCount = requirementCount + 1 set count = requirementCount set requirementTable[requirement] = count set requirementKey[count] = requirement endif //Add the key for the requirement type to the itemtype call i.GetRequirementList().push(count) endfunction public function ItemTypeAddStatRequirement takes integer iType, string requirement, integer level returns nothing local itemType i = itemTypeTable[iType] local integer count set requirement = StringCase(requirement, false) if requirementTable.exists(requirement) then //Item requirement type already exists. set count = requirementTable[requirement] else //Item requirement type does not exist, so add it to the table. set requirementCount = requirementCount + 1 set count = requirementCount set requirementTable[requirement] = count set requirementKey[count] = requirement endif //Add the key for the requirement type to the itemtype call i.GetRequirementList().push(count) endfunction public function SetItemTypeLevel takes integer iType, integer level returns nothing local itemType i = itemTypeTable[iType] set i.levelReq = level endfunction public function ItemTypeAddFunction takes integer iType, code eF, code uF returns nothing local itemType i = itemTypeTable[iType] call i.AddEquipFunc(eF) call i.AddUnequipFunc(uF) endfunction public function GetSlotId takes string s returns integer return slotId[StringCase(s, false)] endfunction private function Init takes nothing returns nothing local integer i = 0 set itemTypeTable = Table.create() set unitTable = Table.create() set requirementTable = Table.create() set slotId = StringTable.create() loop exitwhen i > 10 set itemTypesAtP[i] = Stack.create() set i = i + 1 endloop set slotId["shoulders"] = 0 set slotId["head"] = 1 set slotId["neck"] = 2 set slotId["finger"] = 3 set slotId["mainhand"] = 4 set slotId["chest"] = 5 set slotId["offhand"] = 6 set slotId["wrists"] = 7 set slotId["feet"] = 8 set slotId["legs"] = 9 set slotId["hands"] = 10 set emptySlot[0] = 'ES01' set emptySlot[1] = 'ES02' set emptySlot[2] = 'ES03' set emptySlot[3] = 'ES04' set emptySlot[4] = 'ES05' set emptySlot[5] = 'ES06' set emptySlot[6] = 'ES07' set emptySlot[7] = 'ES08' set emptySlot[8] = 'ES09' set emptySlot[9] = 'ES0A' set emptySlot[10] = 'ES0B' endfunction endlibrary |
| 10-06-2009, 06:23 PM | #2 |
Funny, something like this is what I did before: Advanced Inventory Handling. Yours is more RPG like, but mine does also allow bonuses to be applied to the hero on pickup. Edit: For the system, its pretty nice, but it leaks bonusses. |
| 10-06-2009, 08:53 PM | #3 |
True that I'm focusing more thowards the RPG genre with this system. I tried your system but couldn't find many similiarities other then some basics. I didn't look through the code and I'm unsure if it was just that the demo was very basic. But there seemed to lack functionalities other then some basic restrictions like level and stats? Anyway, I attached the code for easy viewing. Note that in the next version (which is almost done), I've merged the "outside functions" into the structs. I'll be releasing a v0.2 shortly. |
| 10-07-2009, 06:09 AM | #4 |
Good job, so far. I have a question though: Will users have the opportunity to limit the amount of types of equipment a single unit/hero can carry? In your picture, I see 11 slots for equipment, but for some people (like myself) that's a too much. I'll be assuming that if I plan to use this, there is no longer a need for BonusMod or Unit-er... I forget what it's called. You know what I mean though, right? |
| 10-07-2009, 01:14 PM | #5 |
By blanking out the icons that you dont want (setting their icon to black), you could hide the slots you don't use. Unfortunately when you hover over those blank icons they'll still display an empty tooltip box. I don't think there is a solution to that problem using this implementation. The effect is currently also global. for all units I might be able to add support for locking/hiding certain slots for specific units. I'll see if I can find a good solution for it. I'm unsure of how to design this without cluttering it up with features not all may need. I might have to split the project up into two libraries, one which functions more as a template, and one library focusing on making a pure RPG-equipment interface. Yes, BonusMod and UnitMaxState are just optional libraries used in the demo map to demonstrate what the system can do. You can script whatever effect you want in the equip/unequip functions. I'm uploading the next version, v0.2. |
