library inv initializer init uses libassert
globals
private integer array inv
private integer array slots
private integer g_s1
private integer g_s2
private integer g_s3
private integer g_s4
private integer g_s5
private integer g_s6
endglobals
private function inv_load takes unit u returns nothing
local integer aa
local integer a = 0
local item it
local integer tmp
set aa = UnitInventorySize(u)
loop
exitwhen a == aa
set it = UnitItemInSlot(u, a)
if it == null then
set inv[a] = 0x7FFFFFFF
else
set inv[a] = GetItemTypeId(it)
endif
set a = a + 1
endloop
loop
exitwhen a == 6
set inv[a] = 0x7FFFFFFF
set a = a + 1
endloop
set slots[0] = 0
set slots[1] = 1
set slots[2] = 2
set slots[3] = 3
set slots[4] = 4
set slots[5] = 5
// sort the inv array using a sorting network for N = 6;
// remember the items' original slots
//
//! textmacro SWAP takes a, b
if inv[$a$] > inv[$b$] then
set tmp = inv[$a$]
set inv[$a$] = inv[$b$]
set inv[$b$] = tmp
set tmp = slots[$a$]
set slots[$a$] = slots[$b$]
set slots[$b$] = tmp
endif
//! endtextmacro
//! runtextmacro SWAP("1", "2")
//! runtextmacro SWAP("0", "2")
//! runtextmacro SWAP("0", "1")
//! runtextmacro SWAP("4", "5")
//! runtextmacro SWAP("3", "5")
//! runtextmacro SWAP("3", "4")
//! runtextmacro SWAP("0", "3")
//! runtextmacro SWAP("1", "4")
//! runtextmacro SWAP("2", "5")
//! runtextmacro SWAP("2", "4")
//! runtextmacro SWAP("1", "3")
//! runtextmacro SWAP("2", "3")
endfunction
//! textmacro MATCH takes n
set m = false
loop
exitwhen a == 6
if x$n$ == inv[a] then
set m = true
set g_s$n$ = slots[a]
exitwhen true
endif
set a = a + 1
endloop
if not m then
return false
endif
set a = a + 1
//! endtextmacro
private function inv_test2 takes unit u, integer x1, integer x2, boolean flag returns boolean
local integer a
local boolean m
static if DEBUG_MODE then
call assert("[inv_test2] x1 <= x2", /*
*/ x1 <= x2)
endif
set a = 0
//! runtextmacro MATCH("1")
//! runtextmacro MATCH("2")
if flag then
call RemoveItem(UnitItemInSlot(u, g_s1))
call RemoveItem(UnitItemInSlot(u, g_s2))
endif
return true
endfunction
private function inv_match2 takes unit u, integer x1, integer x2 returns boolean
return inv_test2(u, x1, x2, true)
endfunction
private function inv_accept2 takes unit u, integer x1, integer x2 returns boolean
return inv_test2(u, x1, x2, false)
endfunction
private function inv_remove_items2 takes unit u returns nothing
call RemoveItem(UnitItemInSlot(u, g_s1))
call RemoveItem(UnitItemInSlot(u, g_s2))
endfunction
private function inv_test3 takes unit u, integer x1, integer x2, integer x3, boolean flag returns boolean
local integer a
local boolean m
static if DEBUG_MODE then
call assert("[inv_test3] x1 <= x2 and x2 <= x3", /*
*/ x1 <= x2 and x2 <= x3)
endif
set a = 0
//! runtextmacro MATCH("1")
//! runtextmacro MATCH("2")
//! runtextmacro MATCH("3")
if flag then
call RemoveItem(UnitItemInSlot(u, g_s1))
call RemoveItem(UnitItemInSlot(u, g_s2))
call RemoveItem(UnitItemInSlot(u, g_s3))
endif
return true
endfunction
private function inv_match3 takes unit u, integer x1, integer x2, integer x3 returns boolean
return inv_test3(u, x1, x2, x3, true)
endfunction
private function inv_accept3 takes unit u, integer x1, integer x2, integer x3 returns boolean
return inv_test3(u, x1, x2, x3, false)
endfunction
private function inv_remove_items3 takes unit u returns nothing
call RemoveItem(UnitItemInSlot(u, g_s1))
call RemoveItem(UnitItemInSlot(u, g_s2))
call RemoveItem(UnitItemInSlot(u, g_s3))
endfunction
private function inv_test4 takes unit u, integer x1, integer x2, integer x3, integer x4, boolean flag returns boolean
local integer a
local boolean m
static if DEBUG_MODE then
call assert("[inv_test4] x1 <= x2 and x2 <= x3 and x3 <= x4", /*
*/ x1 <= x2 and x2 <= x3 and x3 <= x4)
endif
set a = 0
//! runtextmacro MATCH("1")
//! runtextmacro MATCH("2")
//! runtextmacro MATCH("3")
//! runtextmacro MATCH("4")
if flag then
call RemoveItem(UnitItemInSlot(u, g_s1))
call RemoveItem(UnitItemInSlot(u, g_s2))
call RemoveItem(UnitItemInSlot(u, g_s3))
call RemoveItem(UnitItemInSlot(u, g_s4))
endif
return true
endfunction
private function inv_match4 takes unit u, integer x1, integer x2, integer x3, integer x4 returns boolean
return inv_test4(u, x1, x2, x3, x4, true)
endfunction
private function inv_accept4 takes unit u, integer x1, integer x2, integer x3, integer x4 returns boolean
return inv_test4(u, x1, x2, x3, x4, false)
endfunction
private function inv_remove_items4 takes unit u returns nothing
call RemoveItem(UnitItemInSlot(u, g_s1))
call RemoveItem(UnitItemInSlot(u, g_s2))
call RemoveItem(UnitItemInSlot(u, g_s3))
call RemoveItem(UnitItemInSlot(u, g_s4))
endfunction
private function inv_test5 takes unit u, integer x1, integer x2, integer x3, integer x4, integer x5, boolean flag returns boolean
local integer a
local boolean m
static if DEBUG_MODE then
call assert("[inv_test5] x1 <= x2 and x2 <= x3 and x3 <= x4 and x4 <= x5", /*
*/ x1 <= x2 and x2 <= x3 and x3 <= x4 and x4 <= x5)
endif
set a = 0
//! runtextmacro MATCH("1")
//! runtextmacro MATCH("2")
//! runtextmacro MATCH("3")
//! runtextmacro MATCH("4")
//! runtextmacro MATCH("5")
if flag then
call RemoveItem(UnitItemInSlot(u, g_s1))
call RemoveItem(UnitItemInSlot(u, g_s2))
call RemoveItem(UnitItemInSlot(u, g_s3))
call RemoveItem(UnitItemInSlot(u, g_s4))
call RemoveItem(UnitItemInSlot(u, g_s5))
endif
return true
endfunction
private function inv_match5 takes unit u, integer x1, integer x2, integer x3, integer x4, integer x5 returns boolean
return inv_test5(u, x1, x2, x3, x4, x5, true)
endfunction
private function inv_accept5 takes unit u, integer x1, integer x2, integer x3, integer x4, integer x5 returns boolean
return inv_test5(u, x1, x2, x3, x4, x5, false)
endfunction
private function inv_remove_items5 takes unit u returns nothing
call RemoveItem(UnitItemInSlot(u, g_s1))
call RemoveItem(UnitItemInSlot(u, g_s2))
call RemoveItem(UnitItemInSlot(u, g_s3))
call RemoveItem(UnitItemInSlot(u, g_s4))
call RemoveItem(UnitItemInSlot(u, g_s5))
endfunction
private function inv_test6 takes unit u, integer x1, integer x2, integer x3, integer x4, integer x5, integer x6, boolean flag returns boolean
local integer a
local boolean m
static if DEBUG then
call assert("[inv_test6] x1 <= x2 and x2 <= x3 and x3 <= x4 and x4 <= x5 and x5 <= x6", /*
*/ x1 <= x2 and x2 <= x3 and x3 <= x4 and x4 <= x5 and x5 <= x6)
endif
set a = 0
//! runtextmacro MATCH("1")
//! runtextmacro MATCH("2")
//! runtextmacro MATCH("3")
//! runtextmacro MATCH("4")
//! runtextmacro MATCH("5")
//! runtextmacro MATCH("6")
if flag then
call RemoveItem(UnitItemInSlot(u, g_s1))
call RemoveItem(UnitItemInSlot(u, g_s2))
call RemoveItem(UnitItemInSlot(u, g_s3))
call RemoveItem(UnitItemInSlot(u, g_s4))
call RemoveItem(UnitItemInSlot(u, g_s5))
call RemoveItem(UnitItemInSlot(u, g_s6))
endif
return true
endfunction
private function inv_match6 takes unit u, integer x1, integer x2, integer x3, integer x4, integer x5, integer x6 returns boolean
return inv_test6(u, x1, x2, x3, x4, x5, x6, true)
endfunction
private function inv_accept6 takes unit u, integer x1, integer x2, integer x3, integer x4, integer x5, integer x6 returns boolean
return inv_test6(u, x1, x2, x3, x4, x5, x6, false)
endfunction
private function inv_remove_items6 takes unit u returns nothing
call RemoveItem(UnitItemInSlot(u, g_s1))
call RemoveItem(UnitItemInSlot(u, g_s2))
call RemoveItem(UnitItemInSlot(u, g_s3))
call RemoveItem(UnitItemInSlot(u, g_s4))
call RemoveItem(UnitItemInSlot(u, g_s5))
call RemoveItem(UnitItemInSlot(u, g_s6))
endfunction
private function inv_remove_slot1 takes unit u returns nothing
call RemoveItem(UnitItemInSlot(u, g_s1))
endfunction
private function inv_remove_slot2 takes unit u returns nothing
call RemoveItem(UnitItemInSlot(u, g_s2))
endfunction
private function inv_remove_slot3 takes unit u returns nothing
call RemoveItem(UnitItemInSlot(u, g_s3))
endfunction
private function inv_remove_slot4 takes unit u returns nothing
call RemoveItem(UnitItemInSlot(u, g_s4))
endfunction
private function inv_remove_slot5 takes unit u returns nothing
call RemoveItem(UnitItemInSlot(u, g_s5))
endfunction
private function inv_remove_slot6 takes unit u returns nothing
call RemoveItem(UnitItemInSlot(u, g_s6))
endfunction
private function unit_add_item_by_id takes unit u, integer item_id returns nothing
call UnitAddItemById(u, item_id)
endfunction
private function unit_add_item_by_id_charges takes unit u, integer item_id, integer charges returns nothing
local item it = UnitAddItemById(u, item_id)
call SetItemCharges(it, charges)
set it = null
endfunction
native UnitAlive takes unit u returns boolean
globals
private group g_group = CreateGroup()
endglobals
private function no_trolls_alive takes nothing returns boolean
local unit u
local boolean res = true
call GroupEnumUnitsInRect(g_group, bj_mapInitialPlayableArea, null)
loop
set u = FirstOfGroup(g_group)
exitwhen u == null
call GroupRemoveUnit(g_group, u)
if GetUnitTypeId(u) == 'ndtb' and UnitAlive(u) then
set res = false
exitwhen true
endif
endloop
call GroupClear(g_group)
set u = null
return res
endfunction
private function unit_try_match_recipes takes unit u returns nothing
call inv_load(u)
if inv_match2(u, 'kybl', 'kygh') then
call unit_add_item_by_id(u, 'mgtk')
elseif inv_accept2(u, 'ches', 'kybl') or inv_accept2(u, 'ches', 'kygh') /*
*/ or inv_accept2(u, 'ches', 'kymn') or inv_accept2(u, 'ches', 'kysn') then
call inv_remove_slot2(u)
call unit_add_item_by_id_charges(u, 'mcri', 2)
elseif inv_accept3(u, 'hcun', 'hval', 'mcou') then
if no_trolls_alive() then
call inv_remove_items3(u)
call unit_add_item_by_id(u, 'ckng')
else
call writeln("There are still some trolls alive on the map. Kill them first.")
endif
elseif inv_accept6(u, 'bzbe', 'gopr', 'wcyc', 'wlsd', 'woms', 'wshs') then
call inv_remove_slot1(u)
call inv_remove_slot3(u)
call inv_remove_slot4(u)
call inv_remove_slot5(u)
call inv_remove_slot6(u)
call unit_add_item_by_id(u, 'bzbf')
endif
endfunction
private function on_item_pickup takes unit u returns nothing
call unit_try_match_recipes(u)
endfunction
private function on_item_pickup_action takes nothing returns nothing
call on_item_pickup(GetTriggerUnit())
endfunction
private function on_unit_death takes unit d, unit k returns nothing
if k != null then
call unit_try_match_recipes(k)
endif
endfunction
private function on_unit_death_action takes nothing returns nothing
call on_unit_death(GetTriggerUnit(), GetKillingUnit())
endfunction
private function on_spell_effect takes unit u returns nothing
local integer sid = GetSpellAbilityId()
if sid != 'AHtc' then
return
endif
call inv_load(u)
if sid == 'AHtc' and inv_match4(u, 'ocor', 'ofir', 'oli2', 'oven') then
call unit_add_item_by_id(u, 'sora')
endif
endfunction
private function on_spell_effect_action takes nothing returns nothing
call on_spell_effect(GetTriggerUnit())
endfunction
private function init takes nothing returns nothing
local trigger t
set t = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_PICKUP_ITEM)
call TriggerAddAction(t, function on_item_pickup_action)
set t = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_DEATH)
call TriggerAddAction(t, function on_unit_death_action)
set t = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerAddAction(t, function on_spell_effect_action)
endfunction
endlibrary // inv
library libassert
function assert takes string s, boolean b returns nothing
if not b then
call BJDebugMsg("|cffFF0000assert failed: |r" + s)
call I2S(1/0)
endif
endfunction
function writeln takes string s returns nothing
call BJDebugMsg(s)
endfunction
endlibrary