kingkingyyk3
Visitor (Welcome to the Jungle, Baby!)
- Reaction score
- 216
I'm here to present :
Link : Event
Updates :
v1.0.1 -> No longer fire if the combined item is removed.
v1.0.0 -> Release.
AutoCombine
v1.0.1
JASS:
/******************************************************************************************************
AutoCombine by kingking
v1.0.1
******************************************************************************************************
What is AutoCombine?
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
AutoCombine is an automatic item combiner.
Example(In DotA) : Preservance + Claymore + Broadsword -> Battle Fury.
How to implement?
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
Copy this trigger and Event into your map.
Requirements
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
• Event by Jesus4Lyf
• Jasshelper 0.2.A.B or later (<a href="http://www.wc3c.net/showthread.php?p=1122566" target="_blank" class="link link--external" rel="nofollow ugc noopener">http://www.wc3c.net/showthread.php?p=1122566</a>)
Detail
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
• AutoCombine will search the most common used combination instead of iterating all combinations.
This enhances AutoCombine's effiency greatly because it does not search unliked combinations.
• AutoCombine uses a linked list as it's storage. This is faster than an array stack in iteration process.
******************************************************************************************************
API
******************************************************************************************************
Normal API
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
• ItemCombo.create() -> ItemCombo
Create an combination
• call vars.addItem( integer id )
Add an item type.
• call vars.removeItem( integer id )
Remove an item type.
• set vars.result = integer id
Set the type of combined item.
• set vars.model = string
Effect created when a item is successfully combined.
• set vars.attachment = string
Atttachment point for model.
• set vars.enable = boolean
Enable the combination?
• call vars.destroy()
Destroy the combination.
• ItemCombo[integer id] -> ItemCombo
Get the combination from item type (Returns last combination if you have >1 combinations for 1 item type)
Wrapped AI
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
For better readability, more like JASS syntax.
• CreateItemCombination() -> ItemCombo
• AddItemToCombination(ItemCombo, integer id)
• RemoveItemFromCombination(ItemCombo, integer id)
• SetOnCombineEffect(ItemCombo, string model, string attachment point)
• GetCombinationById(integer id) -> ItemCombo
• SetCombinationResult(ItemCombo,integer id)
• GetCombinationResult(ItemCombo) -> id
• EnableItemCombination(ItemCombo,boolean)
• IsCombinationEnabled(ItemCombo,boolean)
• DestroyItemCombination(ItemCombo)
BJ-Like API
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
Does not require you to store the ItemCombo variable, useful for normal item combinations.
• CreateItemCombinationBJ(integer result)
• AddItemToCombinationBJ(integer id)
• SetOnCombineEffectBJ(string model, string attachment point)
Other API
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
• DisassembleItem(item) (Uses last combination if you have >1 combinations for 1 item type)
• EnableAutoChargeMerging(integer id) (Merge the charges of items.)
Event API
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
• GetCombiner() -> unit - The unit who recieves the combined item.
• GetCombinedItem() -> item - The item which is made.
• AutoCombine_RegisterEvent(trigger) -> EventReg
• AutoCombine_UnregisterEvent(trigger)
• AutoCombine_EnableEvent(boolean)
*******************************************************************************************************/
library AutoCombine requires Event
globals
private Event OnCombineEvent
private boolean EventFlag = true
private unit array CombinerStack
private item array CombinedItemStack
private integer EventStackLevel = 0
//Prevent recursion.
endglobals
function GetCombiner takes nothing returns unit
return CombinerStack[EventStackLevel]
endfunction
function GetCombinedItem takes nothing returns item
return CombinedItemStack[EventStackLevel]
endfunction
public function RegisterEvent takes trigger trig returns EventReg
return OnCombineEvent.register(trig)
endfunction
public function UnregisterEvent takes trigger trig returns nothing
call OnCombineEvent.unregister(trig)
endfunction
public function EnableEvent takes boolean flag returns nothing
set EventFlag = flag
endfunction
private function FireEvent takes unit u, item i returns nothing
if EventFlag == true and GetItemTypeId(i) != 0 then
set EventStackLevel = EventStackLevel + 1
set CombinerStack[EventStackLevel] = u
set CombinedItemStack[EventStackLevel] = i
call OnCombineEvent.fire()
set EventStackLevel = EventStackLevel - 1
endif
endfunction
private struct IdList
integer id
thistype prev
thistype next
//Doubly linked list.
static method createHead takes nothing returns thistype
local thistype this = thistype.allocate()
set this.prev = this
set this.next = this
return this
endmethod
method add takes integer id returns nothing
local thistype new = thistype.allocate()
set new.id = id
set this.next.prev = new
set new.prev = this
set new.next = this.next
set this.next = new
endmethod
method search takes integer id returns thistype
local thistype list = this
set this = this.next
loop
exitwhen this == list
if this.id == id then
return this
endif
set this = this.next
endloop
return 0
endmethod
method remove takes integer id returns boolean
set this = this.search(id)
if this != 0 then
set this.next.prev = this.prev
set this.prev.next = this.next
call this.destroy()
return true
endif
return false
endmethod
method destroyHead takes nothing returns nothing
local thistype list = this
set this = this.next
loop
exitwhen this == list
set this.next.prev = this.prev
set this.prev.next = this.next
call this.destroy()
set this = this.next
endloop
call this.destroy()
endmethod
endstruct
private keyword ItemComboList
struct ItemCombo
private IdList list
readonly integer size
private integer resultx
string model
string attachment
boolean enable
//Doubly linked list.
static method create takes nothing returns thistype
local thistype this = thistype.allocate()
set this.list = IdList.createHead()
set this.enable = true
return this
endmethod
method operator result= takes integer id returns nothing
call RemoveSavedInteger(ItemComboList.hasht,0,.resultx)
call SaveInteger(ItemComboList.hasht,0,id,this)
//Hook for [] operator.
set .resultx = id
endmethod
method operator result takes nothing returns integer
return .resultx
endmethod
static method operator [] takes integer id returns thistype
return LoadInteger(ItemComboList.hasht,0,id)
endmethod
method addItem takes integer id returns nothing
local ItemComboList cl = ItemComboList[id]
call .list.add(id)
set .size = .size + 1
if cl == 0 then
set cl = ItemComboList.createHead(id)
endif
call cl.addCombo(this)
endmethod
method removeItem takes integer id returns nothing
if .list.remove(id) then
set .size = .size - 1
endif
endmethod
method tryCombine takes unit u returns nothing
local IdList idStack = .list.next
local boolean array picked
local item array items
local integer iterator
local integer success = 0
loop
set iterator = 0
loop
if picked[iterator] == false and GetItemTypeId(UnitItemInSlot(u,iterator)) == idStack.id then
set picked[iterator] = true
set success = success + 1
set items[success] = UnitItemInSlot(u,iterator)
set iterator = 5
endif
set iterator = iterator + 1
exitwhen iterator == 6
endloop
set idStack = idStack.next
exitwhen idStack == .list
endloop
if success == .size then
loop
exitwhen success == 0
call RemoveItem(items[success])
set items[success] = null
set success = success - 1
endloop
call FireEvent(u,UnitAddItemById(u,.result))
call AddSpecialEffectTarget(.model,u,.attachment)
else
loop
exitwhen success == 0
set items[success] = null
set success = success - 1
endloop
endif
endmethod
method onDestroy takes nothing returns nothing
local IdList idStack = .list.next
loop
exitwhen idStack == .list
call ItemComboList[idStack.id].removeCombo(this)
//Remove this struct from any list.
set idStack = idStack.next
endloop
call .list.destroyHead()
call RemoveSavedInteger(ItemComboList.hasht,0,this.resultx)
//Destroy all.
endmethod
static method disassemble takes item i, real x, real y returns nothing
local thistype this = thistype[GetItemTypeId(i)]
local IdList idStack
if this != 0 then
call RemoveItem(i)
set idStack = .list.next
loop
exitwhen idStack == .list
call CreateItem(idStack.id,x,y)
set idStack = idStack.next
endloop
endif
endmethod
endstruct
private struct ItemComboList
static hashtable hasht = InitHashtable()
thistype prev
thistype next
ItemCombo combo
static method createHead takes integer itemId returns thistype
local thistype this = thistype.allocate()
set this.prev = this
set this.next = this
call SaveInteger(.hasht,itemId,0,this)
return this
endmethod
static method operator [] takes integer itemId returns thistype
return LoadInteger(.hasht,itemId,0)
endmethod
method addCombo takes ItemCombo c returns nothing
local thistype new
if HaveSavedInteger(.hasht,this,c) == false then
set new = thistype.allocate()
set new.combo = c
call SaveInteger(.hasht,this,c,this)
set this.next.prev = new
set new.prev = this
set new.next = this.next
set this.next = new
endif
endmethod
method removeCombo takes ItemCombo c returns nothing
local thistype list = this
if HaveSavedInteger(.hasht,this,c) then
set this = LoadInteger(.hasht,this,c)
set this.next.prev = this.prev
set this.prev.next = this.next
call this.destroy()
call RemoveSavedInteger(.hasht,list,c)
endif
endmethod
method checkCombo takes unit u returns nothing
local thistype list = this
set this = this.next
loop
exitwhen this == list
if this.combo.enable == true then
call this.combo.tryCombine(u)
//Is this combination ok?
endif
set this = this.next
endloop
endmethod
endstruct
private struct ChargeMerging extends array
static integer iterator = 0
static item toAdd = null
static item currItem = null //locals
static method tryMerge takes unit u, item i, integer id returns nothing
set iterator = 0
set toAdd = null
loop
set currItem = UnitItemInSlot(u,iterator)
if GetItemTypeId(currItem) == id and currItem != i then
set toAdd = currItem
set iterator = 5
endif
set iterator = iterator + 1
exitwhen iterator == 0
endloop
if toAdd != null then
call SetItemCharges(toAdd,GetItemCharges(toAdd) + GetItemCharges(i))
call RemoveItem(i)
endif
endmethod
endstruct
// -> Wrappers. <-
function CreateItemCombination takes nothing returns ItemCombo
return ItemCombo.create()
endfunction
function AddItemToCombination takes ItemCombo c, integer itemId returns nothing
call c.addItem(itemId)
endfunction
function RemoveItemFromCombination takes ItemCombo c, integer itemId returns nothing
call c.removeItem(itemId)
endfunction
function SetOnCombineEffect takes ItemCombo c, string path, string att returns nothing
set c.model = path
set c.attachment = att
endfunction
function GetCombinationById takes integer itemId returns ItemCombo
return ItemCombo[itemId]
endfunction
function SetCombinationResult takes ItemCombo c, integer itemId returns nothing
set c.result = itemId
endfunction
function GetCombinationResult takes ItemCombo c returns integer
return c.result
endfunction
function EnableItemCombination takes ItemCombo c, boolean flag returns nothing
set c.enable = flag
endfunction
function IsCombinationEnabled takes ItemCombo c returns boolean
return c.enable
endfunction
function DestroyItemCombination takes ItemCombo c returns nothing
call c.destroy()
endfunction
function DisassembleItem takes item i, real x, real y returns nothing
call ItemCombo.disassemble(i,x,y)
endfunction
//
//BJ-liked wrappers
globals
private ItemCombo bj_lastCreatedCombination = 0
endglobals
function CreateItemCombinationBJ takes integer id returns nothing
set bj_lastCreatedCombination = ItemCombo.create()
set bj_lastCreatedCombination.result = id
endfunction
function AddItemToCombinationBJ takes integer id returns nothing
call bj_lastCreatedCombination.addItem(id)
endfunction
function SetOnCombineEffectBJ takes string model, string attach returns nothing
set bj_lastCreatedCombination.model = model
set bj_lastCreatedCombination.attachment = attach
endfunction
//
//Auto Charge Merging
function EnableAutoChargeMerging takes integer itemId returns nothing
call SaveBoolean(ItemComboList.hasht,itemId,1,true)
endfunction
//
//Initializer...
private struct Initializer extends array
private static method check takes nothing returns boolean
local unit u = GetTriggerUnit()
local integer id = GetItemTypeId(GetManipulatedItem())
if LoadBoolean(ItemComboList.hasht,id,1) == true then
call ChargeMerging.tryMerge(u,GetManipulatedItem(),id)
endif
call ItemComboList[id].checkCombo(u)
//Iterate those most likely combination, more efficient than looping all combinations.
set u = null
return false
endmethod
private static method onInit takes nothing returns nothing
local trigger trig = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(trig,EVENT_PLAYER_UNIT_PICKUP_ITEM)
//I <3 this BJ.
call TriggerAddCondition(trig,Condition(function thistype.check))
set OnCombineEvent = Event.create()
endmethod
endstruct
endlibrary
Link : Event
Updates :
v1.0.1 -> No longer fire if the combined item is removed.
v1.0.0 -> Release.