Hi everyone
I am using The_Witcher equipment system, but my jass knowledge is too low to understand how it works, so i would like to request some help from the pro VJass user from this forum to explain with //text tag what each structure and function does, so i can graps the concept of this system, and how to adapt it to my needs, and to learn from it to code VJass....
This is not the whole system but the part wich actually do most of the things, the other parts are a setup for items to input data, and a LinkedList and a RegisterPlayerUnitEvent.
Equipment System:
[Jass=System]
library AdvancedEquipmentSystem requires LinkedListModule, RegisterPlayerUnitEvent
// The_Witcher's Equipment System
//
// Requirements:
// JASS knowledge
// LinkedList (http://www.hiveworkshop.com/forums/jass-resources-412/snippet-linkedlistmodule-206552/)
// RegisterPlayerUnitEvent (http://www.hiveworkshop.com/forums/jass-resources-412/snippet-registerplayerunitevent-203338/)
//
// have fun^^
//**************************************************
//********************SETUP PART********************
//**************************************************
globals
// this is the rawcode of the unit which works as inventory
public constant integer INVENTORY_DUMMY = 'h007'
// this is the class you selected as mainhand class
public constant integer MAINHAND_CLASS = 0
// this is the class you selected as offhand class
public constant integer OFFHAND_CLASS = 1
// this is the amount of total classes you have
public constant integer CLASSES = 9
// this is the ability to close the inventory
public constant integer EXIT_ABILITY = 'A00G'
// this is the ability to open the inventory
public constant integer OPEN_ABILITY = 'A003'
// this is the ability which gives the dummy the same inventory as your hero has
public constant integer INVENTORY_ABILITY = 'AInv'
// this is the icon ability shown in the offhand slot when a twhoanded weapon is equipeed
public constant integer TWOHAND_ABILITY = 'A00Z'
public constant boolean SHOW_TWOHAND_ABILITY = true
// this is the text shown when a unit is trying to equip an item which it isnt allowed to
// example: " can't equip " becomes ingame something like Soldier can't equip Giant Sword
public constant string UNABLE_TO_EQUIP_STRING = " can't equip "
endglobals
//************************************************************
//********************SETUP PART ENDS HERE********************
//************************************************************
//*****************Don't edit anything below******************
//************************************************************
globals
private trigger OnEquip
private trigger OnUnequip
private integer TriggeringItem
private unit EquippingUnit
private hashtable table
endglobals
private struct AbilityList extends array
integer abi
implement LinkedList
static method create takes nothing returns thistype
return .createNode()
endmethod
method remove takes nothing returns nothing
call .removeNode()
call .deallocate()
endmethod
method add takes integer abi returns nothing
local thistype new = .allocate()
set new.abi = abi
call .insertNode(new)
endmethod
endstruct
// **** struct EquipmentItem ****
private struct EquipmentItem extends array
readonly integer id
readonly integer class
readonly AbilityList abilities
readonly integer icon
readonly boolean twohanded
readonly string tag
static method operator [] takes integer itemid returns EquipmentItem
return itemid - 'I000' + CLASSES + 1
endmethod
static method create takes integer id, integer icon, integer class, boolean twohanded, string animation returns EquipmentItem
local EquipmentItem this = id - 'I000' + CLASSES + 1
if id - 'I000' >= 0 then
call SaveBoolean(table, id - 'I000', 0, true)
endif
set .id = id
set .class = class
set .icon = icon
if id >= CLASSES + 1 then
set .abilities = AbilityList.create()
if class == MAINHAND_CLASS then
set .twohanded = twohanded
else
set .twohanded = false
endif
if (class == MAINHAND_CLASS or class == OFFHAND_CLASS) and id != 0 then
set .tag = animation
else
set .tag = ""
endif
endif
return this
endmethod
method addAbility takes integer abi returns nothing
call .abilities.add( abi)
endmethod
method applyAbilities takes unit u, boolean add returns nothing
local AbilityList node = .abilities.next
loop
exitwhen node.head
if add then
call UnitAddAbility(u, node.abi)
else
call UnitRemoveAbility(u, node.abi)
endif
set node = node.next
endloop
endmethod
endstruct
public function RegisterNewClass takes integer emptyicon, integer class returns nothing
call EquipmentItem.create('I000' - CLASSES - 1 + class, emptyicon, class, false, "")
endfunction
// **** struct Equipment ****
struct Equipment
private static EquipmentItem twohandIcon
private unit u
private unit dummy
readonly string animtag = ""
readonly EquipmentItem array Item [12]
static method operator [] takes unit u returns Equipment
return LoadInteger(table, GetHandleId(u), 0)
endmethod
method operator owner takes nothing returns unit
return .u
endmethod
method operator owner= takes unit new returns nothing
local integer i = 0
loop
exitwhen i >= CLASSES
if .Item != 0 then
call .Item.applyAbilities(.u, false)
call .Item.applyAbilities(new, true)
endif
set i = i + 1
endloop
call AddUnitAnimationProperties(.u, .animtag, false)
call UnitRemoveAbility(.u, OPEN_ABILITY)
call AddUnitAnimationProperties(new, .animtag, true)
call UnitAddAbility(new, OPEN_ABILITY)
set .u = new
call SaveInteger(table, GetHandleId(.u), 0, this)
call SaveInteger(table, GetHandleId(.dummy), 0, this)
endmethod
method syncInventories takes nothing returns nothing
local integer i = 0
loop
exitwhen i >= 6
call RemoveItem(UnitItemInSlot(.dummy, i))
call UnitAddItemToSlotById(.dummy, GetItemTypeId(UnitItemInSlot(.u, i)), i)
call SetItemDroppable(UnitItemInSlot(.dummy, i), false)
set i = i + 1
endloop
endmethod
private method refreshAnimation takes nothing returns nothing
local string a = .Item[MAINHAND_CLASS].tag
if .Item[OFFHAND_CLASS] != 0 and .Item[OFFHAND_CLASS] != twohandIcon then
set a = .Item[OFFHAND_CLASS].tag
endif
call AddUnitAnimationProperties(.u, .animtag, false)
call AddUnitAnimationProperties(.u, a, true)
set .animtag = a
endmethod
method equipEmptyClass takes integer class returns nothing
call UnitAddAbility(.dummy, EquipmentItem(class).icon)
set .Item[class] = 0
endmethod
method equipTwohandIcon takes nothing returns nothing
call UnitAddAbility(.dummy, twohandIcon.icon)
set .Item[OFFHAND_CLASS] = twohandIcon
endmethod
method unequip takes integer class returns nothing
local integer i = 0
local EquipmentItem toRemove = .Item[class]
if toRemove != 0 then
if toRemove.twohanded then
call UnitRemoveAbility(.dummy, TWOHAND_ABILITY)
call .equipEmptyClass(OFFHAND_CLASS)
endif
call toRemove.applyAbilities(.u, false)
call UnitAddItemById(.u, toRemove.id)
set TriggeringItem = toRemove.id
set EquippingUnit = .u
call TriggerEvaluate(OnUnequip)
call UnitRemoveAbility(.dummy, toRemove.icon)
else
call UnitRemoveAbility(.dummy, EquipmentItem(class).icon)
endif
set .Item[class] = 0
call .refreshAnimation()
endmethod
method equip takes integer id returns nothing
local EquipmentItem toEquip = EquipmentItem[id]
local EquipmentItem mainEquip = .Item[MAINHAND_CLASS]
// remove existing
if mainEquip != 0 then
if toEquip.twohanded or (mainEquip.twohanded and (toEquip.class == OFFHAND_CLASS or toEquip.class == MAINHAND_CLASS)) then
call .unequip(MAINHAND_CLASS)
call .unequip(OFFHAND_CLASS)
if toEquip.class == MAINHAND_CLASS and not toEquip.twohanded then
call .equipEmptyClass(OFFHAND_CLASS)
elseif toEquip.class == OFFHAND_CLASS then
call .equipEmptyClass(MAINHAND_CLASS)
endif
endif
endif
call .unequip(toEquip.class)
// new is twohanded ?
if toEquip.twohanded then
call .unequip(OFFHAND_CLASS)
call .equipTwohandIcon()
if not SHOW_TWOHAND_ABILITY then
call UnitRemoveAbility(.dummy, twohandIcon.icon)
endif
endif
// equip new
call toEquip.applyAbilities(.u, true)
call UnitAddAbility(.dummy, toEquip.icon)
set .Item[toEquip.class] = toEquip
call .refreshAnimation()
// fire trigger
set EquippingUnit = .u
set TriggeringItem = id
call TriggerEvaluate(OnEquip)
endmethod
static method disable takes integer itemId, integer unitType, boolean flag returns nothing
call SaveBoolean(table, itemId - 'I000', unitType, flag)
endmethod
private method onDestroy takes nothing returns nothing
local integer i = 0
call RemoveUnit(.dummy)
loop
exitwhen i > 12
if .Item != 0 then
call .Item.applyAbilities(.u, false)
endif
set i = i + 1
endloop
call AddUnitAnimationProperties(.u, .animtag, false)
call UnitRemoveAbility(.u, OPEN_ABILITY)
endmethod
static method create takes unit u returns Equipment
local Equipment this = Equipment
local integer i = 0
local integer id = GetPlayerId(GetOwningPlayer(u))
if this != 0 then
call RemoveUnit(.dummy)
else
set this = Equipment.allocate()
call SaveInteger(table, GetHandleId(u), 0, this)
endif
set .u = u
set .dummy = CreateUnit(GetOwningPlayer(u), INVENTORY_DUMMY, GetUnitX(u), GetUnitY(u), 0)
call SaveInteger(table, GetHandleId(.dummy), 0, this)
call UnitAddAbility(.dummy, INVENTORY_ABILITY)
call UnitAddAbility(.dummy, EXIT_ABILITY)
call UnitAddAbility(.u, OPEN_ABILITY)
loop
exitwhen i >= CLASSES
call .equipEmptyClass(i)
set i = i + 1
endloop
return this
endmethod
// **** Other Stuff ****
private static method Access takes nothing returns boolean
local unit u = GetTriggerUnit()
local Equipment inv = Equipment
local integer class
local integer i = 0
if GetSpellAbilityId() == EXIT_ABILITY then
if GetLocalPlayer() == GetOwningPlayer(inv.u) then
call ClearSelection()
call SelectUnit(inv.u, true)
endif
elseif GetSpellAbilityId() == OPEN_ABILITY then
call SetUnitX(inv.dummy, GetUnitX(inv.u))
call SetUnitY(inv.dummy, GetUnitY(inv.u))
if GetLocalPlayer() == GetOwningPlayer(inv.u) then
call ClearSelection()
call SelectUnit(inv.dummy, true)
endif
call inv.syncInventories()
elseif GetUnitTypeId(u) == INVENTORY_DUMMY then
loop
exitwhen i >= CLASSES
if inv.Item.icon == GetSpellAbilityId() then
set class = i
set i = CLASSES
endif
set i = i + 1
endloop
call inv.unequip(class)
call inv.equipEmptyClass(class)
call inv.syncInventories()
endif
set u = null
return false
endmethod
private static method ItemEquip takes nothing returns boolean
local unit u = GetTriggerUnit()
local item ite = GetManipulatedItem()
local integer i = 0
local Equipment inv = Equipment
local EquipmentItem invIte = EquipmentItem[GetItemTypeId(ite)]
if GetItemTypeId(ite) - 'I000' >= 0 then
if LoadBoolean(table, GetItemTypeId(ite) - 'I000', 0) then
if invIte != 0 and inv != 0 then
if not LoadBoolean(table, GetItemTypeId(ite) - 'I000', GetUnitTypeId(inv.u)) then
if u == inv.u then
call inv.equip(GetItemTypeId(ite))
call RemoveItem(ite)
call inv.syncInventories()
elseif u == inv.dummy then
loop
exitwhen i >= 6
if invIte.id == GetItemTypeId(UnitItemInSlot(inv.u, i)) then
call UnitUseItem(inv.u, UnitItemInSlot(inv.u, i))
call RemoveItem(ite)
set i = 7
endif
set i = i + 1
endloop
endif
else
call DisplayTextToPlayer(GetOwningPlayer(inv.u), 0, 0, GetUnitName(inv.u) + UNABLE_TO_EQUIP_STRING + GetItemName(ite))
endif
endif
endif
endif
set u = null
set ite = null
return false
endmethod
private static method onInit takes nothing returns nothing
set OnEquip = CreateTrigger()
set OnUnequip = CreateTrigger()
call RegisterPlayerUnitEvent(EVENT_PLAYER_UNIT_USE_ITEM, function Equipment.ItemEquip)
call RegisterPlayerUnitEvent(EVENT_PLAYER_UNIT_SPELL_CAST, function Equipment.Access)
set .twohandIcon = EquipmentItem.create('I000' - 1, TWOHAND_ABILITY, 0, false, "")
set table = InitHashtable()
endmethod
implement optional SaveLoadPlugin
endstruct
// **** Trigger Events ****
function RegisterItemEquipEvent takes code func returns nothing
call TriggerAddCondition(OnEquip, Filter(func))
endfunction
function RegisterItemUnequipEvent takes code func returns nothing
call TriggerAddCondition(OnUnequip, Filter(func))
endfunction
function GetTriggeringItemId takes nothing returns integer
return TriggeringItem
endfunction
function GetEquippingUnit takes nothing returns unit
return EquippingUnit
endfunction
//wrappers
function InitEquipment takes unit whichunit returns nothing
call Equipment.create(whichunit)
endfunction
public function RegisterItem takes integer itemid, integer icon, integer class, boolean twohanded, string animation returns nothing
call EquipmentItem.create(itemid, icon, class, twohanded, animation)
endfunction
public function AddItemAbility takes integer itemid, integer abi returns nothing
call EquipmentItem[itemid].addAbility(abi)
endfunction
function EnableItemEquip takes integer itemId, integer unitType, boolean flag returns nothing
call Equipment.disable(itemId, unitType, not flag)
endfunction
function IsEquipmentClassEmpty takes unit u, integer class returns boolean
return Equipment.Item[class] == 0
endfunction
function EquipItem takes unit u, item ite returns nothing
call Equipment.equip(GetItemTypeId(ite))
call RemoveItem(ite)
endfunction
function EquipItemById takes unit u, integer itemId returns nothing
call Equipment.equip(itemId)
endfunction
function UnequipItemById takes unit u, integer itemid returns nothing
local integer class = EquipmentItem[itemid].class
if Equipment.Item[class].id == itemid then
call Equipment.unequip(EquipmentItem[itemid].class)
call Equipment.equipEmptyClass(class)
endif
endfunction
function UnequipItemByClass takes unit u, integer class returns nothing
call Equipment.unequip(class)
call Equipment.equipEmptyClass(class)
endfunction
function GetEquippedItemTypeId takes unit u, integer class returns integer
return Equipment.Item[class].id
endfunction
function ChangeEquipmentOwner takes unit u, unit newowner returns nothing
set Equipment.owner = newowner
endfunction
function UnequipAll takes unit u returns nothing
local integer i = 1
loop
call Equipment.unequip(i)
call Equipment.equipEmptyClass(i)
exitwhen i >= CLASSES
set i = i + 1
endloop
endfunction
endlibrary
//Code indented using The_Witcher's Script Language Aligner
//Download the newest version and report bugs at www.hiveworkshop.com[/code]
For example what the structure AbilityList extends array does?
maybe store ability? how?
it is also connected to LinkedList wich is used for a recycler i guess... but i don't really understand.
--------- 2) How to use this system (2 ---------
well its very simple to use:
call InitEquipment ( owner )
owner is the unit that gets the equipment
and thats all^^ whenever this unit uses a registered item, it will get equipped
so Owner is an unit variable?
is the unit stored after the call InitEquipment ( unit )?
and if i use it again i can store a new unit?
or should i use an unit array to store all units before to call InitEquipment ( unit(integer) )
or is the code programed to check the player associated with the unit designed and automatically allow 1 unit per player?, i though it was MUI?
thanks for your time and help.
i will try to edit if i have more precise question about specific part...
i understand what structure, member, function, method, private, static are, i have read almost all tutorial on VJass struct for begginner but seing it all like this in giant structure is a bit confusing...
it is hard to understand how they are linked to each other and how they work.
more questions:
when you call a function you need to input the needed take value but
when a function return something who use the returned value? how is it linked to other functions?
For example in EquipmentItem what does the operator do?
DEMO MAP
I am using The_Witcher equipment system, but my jass knowledge is too low to understand how it works, so i would like to request some help from the pro VJass user from this forum to explain with //text tag what each structure and function does, so i can graps the concept of this system, and how to adapt it to my needs, and to learn from it to code VJass....
This is not the whole system but the part wich actually do most of the things, the other parts are a setup for items to input data, and a LinkedList and a RegisterPlayerUnitEvent.
Equipment System:
[Jass=System]
library AdvancedEquipmentSystem requires LinkedListModule, RegisterPlayerUnitEvent
// The_Witcher's Equipment System
//
// Requirements:
// JASS knowledge
// LinkedList (http://www.hiveworkshop.com/forums/jass-resources-412/snippet-linkedlistmodule-206552/)
// RegisterPlayerUnitEvent (http://www.hiveworkshop.com/forums/jass-resources-412/snippet-registerplayerunitevent-203338/)
//
// have fun^^
//**************************************************
//********************SETUP PART********************
//**************************************************
globals
// this is the rawcode of the unit which works as inventory
public constant integer INVENTORY_DUMMY = 'h007'
// this is the class you selected as mainhand class
public constant integer MAINHAND_CLASS = 0
// this is the class you selected as offhand class
public constant integer OFFHAND_CLASS = 1
// this is the amount of total classes you have
public constant integer CLASSES = 9
// this is the ability to close the inventory
public constant integer EXIT_ABILITY = 'A00G'
// this is the ability to open the inventory
public constant integer OPEN_ABILITY = 'A003'
// this is the ability which gives the dummy the same inventory as your hero has
public constant integer INVENTORY_ABILITY = 'AInv'
// this is the icon ability shown in the offhand slot when a twhoanded weapon is equipeed
public constant integer TWOHAND_ABILITY = 'A00Z'
public constant boolean SHOW_TWOHAND_ABILITY = true
// this is the text shown when a unit is trying to equip an item which it isnt allowed to
// example: " can't equip " becomes ingame something like Soldier can't equip Giant Sword
public constant string UNABLE_TO_EQUIP_STRING = " can't equip "
endglobals
//************************************************************
//********************SETUP PART ENDS HERE********************
//************************************************************
//*****************Don't edit anything below******************
//************************************************************
globals
private trigger OnEquip
private trigger OnUnequip
private integer TriggeringItem
private unit EquippingUnit
private hashtable table
endglobals
private struct AbilityList extends array
integer abi
implement LinkedList
static method create takes nothing returns thistype
return .createNode()
endmethod
method remove takes nothing returns nothing
call .removeNode()
call .deallocate()
endmethod
method add takes integer abi returns nothing
local thistype new = .allocate()
set new.abi = abi
call .insertNode(new)
endmethod
endstruct
// **** struct EquipmentItem ****
private struct EquipmentItem extends array
readonly integer id
readonly integer class
readonly AbilityList abilities
readonly integer icon
readonly boolean twohanded
readonly string tag
static method operator [] takes integer itemid returns EquipmentItem
return itemid - 'I000' + CLASSES + 1
endmethod
static method create takes integer id, integer icon, integer class, boolean twohanded, string animation returns EquipmentItem
local EquipmentItem this = id - 'I000' + CLASSES + 1
if id - 'I000' >= 0 then
call SaveBoolean(table, id - 'I000', 0, true)
endif
set .id = id
set .class = class
set .icon = icon
if id >= CLASSES + 1 then
set .abilities = AbilityList.create()
if class == MAINHAND_CLASS then
set .twohanded = twohanded
else
set .twohanded = false
endif
if (class == MAINHAND_CLASS or class == OFFHAND_CLASS) and id != 0 then
set .tag = animation
else
set .tag = ""
endif
endif
return this
endmethod
method addAbility takes integer abi returns nothing
call .abilities.add( abi)
endmethod
method applyAbilities takes unit u, boolean add returns nothing
local AbilityList node = .abilities.next
loop
exitwhen node.head
if add then
call UnitAddAbility(u, node.abi)
else
call UnitRemoveAbility(u, node.abi)
endif
set node = node.next
endloop
endmethod
endstruct
public function RegisterNewClass takes integer emptyicon, integer class returns nothing
call EquipmentItem.create('I000' - CLASSES - 1 + class, emptyicon, class, false, "")
endfunction
// **** struct Equipment ****
struct Equipment
private static EquipmentItem twohandIcon
private unit u
private unit dummy
readonly string animtag = ""
readonly EquipmentItem array Item [12]
static method operator [] takes unit u returns Equipment
return LoadInteger(table, GetHandleId(u), 0)
endmethod
method operator owner takes nothing returns unit
return .u
endmethod
method operator owner= takes unit new returns nothing
local integer i = 0
loop
exitwhen i >= CLASSES
if .Item != 0 then
call .Item.applyAbilities(.u, false)
call .Item.applyAbilities(new, true)
endif
set i = i + 1
endloop
call AddUnitAnimationProperties(.u, .animtag, false)
call UnitRemoveAbility(.u, OPEN_ABILITY)
call AddUnitAnimationProperties(new, .animtag, true)
call UnitAddAbility(new, OPEN_ABILITY)
set .u = new
call SaveInteger(table, GetHandleId(.u), 0, this)
call SaveInteger(table, GetHandleId(.dummy), 0, this)
endmethod
method syncInventories takes nothing returns nothing
local integer i = 0
loop
exitwhen i >= 6
call RemoveItem(UnitItemInSlot(.dummy, i))
call UnitAddItemToSlotById(.dummy, GetItemTypeId(UnitItemInSlot(.u, i)), i)
call SetItemDroppable(UnitItemInSlot(.dummy, i), false)
set i = i + 1
endloop
endmethod
private method refreshAnimation takes nothing returns nothing
local string a = .Item[MAINHAND_CLASS].tag
if .Item[OFFHAND_CLASS] != 0 and .Item[OFFHAND_CLASS] != twohandIcon then
set a = .Item[OFFHAND_CLASS].tag
endif
call AddUnitAnimationProperties(.u, .animtag, false)
call AddUnitAnimationProperties(.u, a, true)
set .animtag = a
endmethod
method equipEmptyClass takes integer class returns nothing
call UnitAddAbility(.dummy, EquipmentItem(class).icon)
set .Item[class] = 0
endmethod
method equipTwohandIcon takes nothing returns nothing
call UnitAddAbility(.dummy, twohandIcon.icon)
set .Item[OFFHAND_CLASS] = twohandIcon
endmethod
method unequip takes integer class returns nothing
local integer i = 0
local EquipmentItem toRemove = .Item[class]
if toRemove != 0 then
if toRemove.twohanded then
call UnitRemoveAbility(.dummy, TWOHAND_ABILITY)
call .equipEmptyClass(OFFHAND_CLASS)
endif
call toRemove.applyAbilities(.u, false)
call UnitAddItemById(.u, toRemove.id)
set TriggeringItem = toRemove.id
set EquippingUnit = .u
call TriggerEvaluate(OnUnequip)
call UnitRemoveAbility(.dummy, toRemove.icon)
else
call UnitRemoveAbility(.dummy, EquipmentItem(class).icon)
endif
set .Item[class] = 0
call .refreshAnimation()
endmethod
method equip takes integer id returns nothing
local EquipmentItem toEquip = EquipmentItem[id]
local EquipmentItem mainEquip = .Item[MAINHAND_CLASS]
// remove existing
if mainEquip != 0 then
if toEquip.twohanded or (mainEquip.twohanded and (toEquip.class == OFFHAND_CLASS or toEquip.class == MAINHAND_CLASS)) then
call .unequip(MAINHAND_CLASS)
call .unequip(OFFHAND_CLASS)
if toEquip.class == MAINHAND_CLASS and not toEquip.twohanded then
call .equipEmptyClass(OFFHAND_CLASS)
elseif toEquip.class == OFFHAND_CLASS then
call .equipEmptyClass(MAINHAND_CLASS)
endif
endif
endif
call .unequip(toEquip.class)
// new is twohanded ?
if toEquip.twohanded then
call .unequip(OFFHAND_CLASS)
call .equipTwohandIcon()
if not SHOW_TWOHAND_ABILITY then
call UnitRemoveAbility(.dummy, twohandIcon.icon)
endif
endif
// equip new
call toEquip.applyAbilities(.u, true)
call UnitAddAbility(.dummy, toEquip.icon)
set .Item[toEquip.class] = toEquip
call .refreshAnimation()
// fire trigger
set EquippingUnit = .u
set TriggeringItem = id
call TriggerEvaluate(OnEquip)
endmethod
static method disable takes integer itemId, integer unitType, boolean flag returns nothing
call SaveBoolean(table, itemId - 'I000', unitType, flag)
endmethod
private method onDestroy takes nothing returns nothing
local integer i = 0
call RemoveUnit(.dummy)
loop
exitwhen i > 12
if .Item != 0 then
call .Item.applyAbilities(.u, false)
endif
set i = i + 1
endloop
call AddUnitAnimationProperties(.u, .animtag, false)
call UnitRemoveAbility(.u, OPEN_ABILITY)
endmethod
static method create takes unit u returns Equipment
local Equipment this = Equipment
local integer i = 0
local integer id = GetPlayerId(GetOwningPlayer(u))
if this != 0 then
call RemoveUnit(.dummy)
else
set this = Equipment.allocate()
call SaveInteger(table, GetHandleId(u), 0, this)
endif
set .u = u
set .dummy = CreateUnit(GetOwningPlayer(u), INVENTORY_DUMMY, GetUnitX(u), GetUnitY(u), 0)
call SaveInteger(table, GetHandleId(.dummy), 0, this)
call UnitAddAbility(.dummy, INVENTORY_ABILITY)
call UnitAddAbility(.dummy, EXIT_ABILITY)
call UnitAddAbility(.u, OPEN_ABILITY)
loop
exitwhen i >= CLASSES
call .equipEmptyClass(i)
set i = i + 1
endloop
return this
endmethod
// **** Other Stuff ****
private static method Access takes nothing returns boolean
local unit u = GetTriggerUnit()
local Equipment inv = Equipment
local integer class
local integer i = 0
if GetSpellAbilityId() == EXIT_ABILITY then
if GetLocalPlayer() == GetOwningPlayer(inv.u) then
call ClearSelection()
call SelectUnit(inv.u, true)
endif
elseif GetSpellAbilityId() == OPEN_ABILITY then
call SetUnitX(inv.dummy, GetUnitX(inv.u))
call SetUnitY(inv.dummy, GetUnitY(inv.u))
if GetLocalPlayer() == GetOwningPlayer(inv.u) then
call ClearSelection()
call SelectUnit(inv.dummy, true)
endif
call inv.syncInventories()
elseif GetUnitTypeId(u) == INVENTORY_DUMMY then
loop
exitwhen i >= CLASSES
if inv.Item.icon == GetSpellAbilityId() then
set class = i
set i = CLASSES
endif
set i = i + 1
endloop
call inv.unequip(class)
call inv.equipEmptyClass(class)
call inv.syncInventories()
endif
set u = null
return false
endmethod
private static method ItemEquip takes nothing returns boolean
local unit u = GetTriggerUnit()
local item ite = GetManipulatedItem()
local integer i = 0
local Equipment inv = Equipment
local EquipmentItem invIte = EquipmentItem[GetItemTypeId(ite)]
if GetItemTypeId(ite) - 'I000' >= 0 then
if LoadBoolean(table, GetItemTypeId(ite) - 'I000', 0) then
if invIte != 0 and inv != 0 then
if not LoadBoolean(table, GetItemTypeId(ite) - 'I000', GetUnitTypeId(inv.u)) then
if u == inv.u then
call inv.equip(GetItemTypeId(ite))
call RemoveItem(ite)
call inv.syncInventories()
elseif u == inv.dummy then
loop
exitwhen i >= 6
if invIte.id == GetItemTypeId(UnitItemInSlot(inv.u, i)) then
call UnitUseItem(inv.u, UnitItemInSlot(inv.u, i))
call RemoveItem(ite)
set i = 7
endif
set i = i + 1
endloop
endif
else
call DisplayTextToPlayer(GetOwningPlayer(inv.u), 0, 0, GetUnitName(inv.u) + UNABLE_TO_EQUIP_STRING + GetItemName(ite))
endif
endif
endif
endif
set u = null
set ite = null
return false
endmethod
private static method onInit takes nothing returns nothing
set OnEquip = CreateTrigger()
set OnUnequip = CreateTrigger()
call RegisterPlayerUnitEvent(EVENT_PLAYER_UNIT_USE_ITEM, function Equipment.ItemEquip)
call RegisterPlayerUnitEvent(EVENT_PLAYER_UNIT_SPELL_CAST, function Equipment.Access)
set .twohandIcon = EquipmentItem.create('I000' - 1, TWOHAND_ABILITY, 0, false, "")
set table = InitHashtable()
endmethod
implement optional SaveLoadPlugin
endstruct
// **** Trigger Events ****
function RegisterItemEquipEvent takes code func returns nothing
call TriggerAddCondition(OnEquip, Filter(func))
endfunction
function RegisterItemUnequipEvent takes code func returns nothing
call TriggerAddCondition(OnUnequip, Filter(func))
endfunction
function GetTriggeringItemId takes nothing returns integer
return TriggeringItem
endfunction
function GetEquippingUnit takes nothing returns unit
return EquippingUnit
endfunction
//wrappers
function InitEquipment takes unit whichunit returns nothing
call Equipment.create(whichunit)
endfunction
public function RegisterItem takes integer itemid, integer icon, integer class, boolean twohanded, string animation returns nothing
call EquipmentItem.create(itemid, icon, class, twohanded, animation)
endfunction
public function AddItemAbility takes integer itemid, integer abi returns nothing
call EquipmentItem[itemid].addAbility(abi)
endfunction
function EnableItemEquip takes integer itemId, integer unitType, boolean flag returns nothing
call Equipment.disable(itemId, unitType, not flag)
endfunction
function IsEquipmentClassEmpty takes unit u, integer class returns boolean
return Equipment.Item[class] == 0
endfunction
function EquipItem takes unit u, item ite returns nothing
call Equipment.equip(GetItemTypeId(ite))
call RemoveItem(ite)
endfunction
function EquipItemById takes unit u, integer itemId returns nothing
call Equipment.equip(itemId)
endfunction
function UnequipItemById takes unit u, integer itemid returns nothing
local integer class = EquipmentItem[itemid].class
if Equipment.Item[class].id == itemid then
call Equipment.unequip(EquipmentItem[itemid].class)
call Equipment.equipEmptyClass(class)
endif
endfunction
function UnequipItemByClass takes unit u, integer class returns nothing
call Equipment.unequip(class)
call Equipment.equipEmptyClass(class)
endfunction
function GetEquippedItemTypeId takes unit u, integer class returns integer
return Equipment.Item[class].id
endfunction
function ChangeEquipmentOwner takes unit u, unit newowner returns nothing
set Equipment.owner = newowner
endfunction
function UnequipAll takes unit u returns nothing
local integer i = 1
loop
call Equipment.unequip(i)
call Equipment.equipEmptyClass(i)
exitwhen i >= CLASSES
set i = i + 1
endloop
endfunction
endlibrary
//Code indented using The_Witcher's Script Language Aligner
//Download the newest version and report bugs at www.hiveworkshop.com[/code]
For example what the structure AbilityList extends array does?
maybe store ability? how?
it is also connected to LinkedList wich is used for a recycler i guess... but i don't really understand.
--------- 2) How to use this system (2 ---------
well its very simple to use:
call InitEquipment ( owner )
owner is the unit that gets the equipment
and thats all^^ whenever this unit uses a registered item, it will get equipped
so Owner is an unit variable?
is the unit stored after the call InitEquipment ( unit )?
and if i use it again i can store a new unit?
or should i use an unit array to store all units before to call InitEquipment ( unit(integer) )
or is the code programed to check the player associated with the unit designed and automatically allow 1 unit per player?, i though it was MUI?
thanks for your time and help.
i will try to edit if i have more precise question about specific part...
i understand what structure, member, function, method, private, static are, i have read almost all tutorial on VJass struct for begginner but seing it all like this in giant structure is a bit confusing...
it is hard to understand how they are linked to each other and how they work.
more questions:
when you call a function you need to input the needed take value but
when a function return something who use the returned value? how is it linked to other functions?
[Jass=EquipmentItem]
// **** struct EquipmentItem ****
private struct EquipmentItem extends array
readonly integer id
readonly integer class
readonly AbilityList abilities
readonly integer icon
readonly boolean twohanded
readonly string tag
static method operator [] takes integer itemid returns EquipmentItem
return itemid - 'I000' + CLASSES + 1
endmethod
static method create takes integer id, integer icon, integer class, boolean twohanded, string animation returns EquipmentItem
local EquipmentItem this = id - 'I000' + CLASSES + 1
if id - 'I000' >= 0 then
call SaveBoolean(table, id - 'I000', 0, true)
endif
set .id = id
set .class = class
set .icon = icon
if id >= CLASSES + 1 then
set .abilities = AbilityList.create()
if class == MAINHAND_CLASS then
set .twohanded = twohanded
else
set .twohanded = false
endif
if (class == MAINHAND_CLASS or class == OFFHAND_CLASS) and id != 0 then
set .tag = animation
else
set .tag = ""
endif
endif
return this
endmethod
method addAbility takes integer abi returns nothing
call .abilities.add( abi)
endmethod
method applyAbilities takes unit u, boolean add returns nothing
local AbilityList node = .abilities.next
loop
exitwhen node.head
if add then
call UnitAddAbility(u, node.abi)
else
call UnitRemoveAbility(u, node.abi)
endif
set node = node.next
endloop
endmethod
endstruct
[/code]
// **** struct EquipmentItem ****
private struct EquipmentItem extends array
readonly integer id
readonly integer class
readonly AbilityList abilities
readonly integer icon
readonly boolean twohanded
readonly string tag
static method operator [] takes integer itemid returns EquipmentItem
return itemid - 'I000' + CLASSES + 1
endmethod
static method create takes integer id, integer icon, integer class, boolean twohanded, string animation returns EquipmentItem
local EquipmentItem this = id - 'I000' + CLASSES + 1
if id - 'I000' >= 0 then
call SaveBoolean(table, id - 'I000', 0, true)
endif
set .id = id
set .class = class
set .icon = icon
if id >= CLASSES + 1 then
set .abilities = AbilityList.create()
if class == MAINHAND_CLASS then
set .twohanded = twohanded
else
set .twohanded = false
endif
if (class == MAINHAND_CLASS or class == OFFHAND_CLASS) and id != 0 then
set .tag = animation
else
set .tag = ""
endif
endif
return this
endmethod
method addAbility takes integer abi returns nothing
call .abilities.add( abi)
endmethod
method applyAbilities takes unit u, boolean add returns nothing
local AbilityList node = .abilities.next
loop
exitwhen node.head
if add then
call UnitAddAbility(u, node.abi)
else
call UnitRemoveAbility(u, node.abi)
endif
set node = node.next
endloop
endmethod
endstruct
[/code]
For example in EquipmentItem what does the operator do?
JASS:
static method operator [] takes integer itemid returns EquipmentItem
return itemid - 'I000' + CLASSES + 1
endmethod
DEMO MAP
Attachments
Last edited: