Azlier
Old World Ghost
- Reaction score
- 461
IDEA. The best thing since sliced items, this autoindexer and item death event is here to do all the work for you!
IDEA Code
IDEAZinc Code
Here's an example to talk for me.
IDEA Code
JASS:
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//~~ IDEA ~~ By Azlier ~~ Version 2.0 ~~
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// What is IDEA?
// - Idea is an autoindexer for items.
// - It also provides an item death event.
//
// =Pros=
// - Easy to use.
// - Highly efficient.
// - Automatically removes dead items (including tomes).
//
// =Cons=
// - You can no longer use item user data.
// - Items cannot be perfectly autoindexed, so there is a very small dip in efficiency from unit indexing.
//
// Functions:
//
// GetItemIndex takes item whichItem returns integer
// Returns the item's unique index for use as an index in an array
//
// GetItemId takes item whichItem returns integer
// Just like GetItemIndex, but faster and does NOT work on items you create
// directly on the map via a trigger. Use with care.
//
// TriggerRegisterItemDeathEvent takes trigger whichTrigger returns nothing
// Causes the given trigger to fire when an item dies.
//
// GetDyingItem takes nothing returns item
// //Returns the item that died in an item death event.
//
//
// IDEA structs (the fine print).
//
// - Insert the line 'implement IDEA' into any struct to make it an IDEA struct.
// - IDEA structs are not to be created or destroyed by the user. To get an item's
// unique IDEA struct, use StructName[item].
// - You cannot give members default values (i.e. private integer member = 5).
// - You cannot use array members.
// - IDEA structs should 'extend array' in order to remove useless functions
// and prevent mistakes.
// - There are two optional methods you can use in IDEA structs:
// IDEA_onCreate takes nothing returns nothing
// This is called when the struct is 'created' for the unit.
// In here you can assign members their default values, which
// you would usually assign in their declarations.
// (eg: set this.i=5)
// IDEA_onDestroy takes nothing returns nothing
// This is called when the struct is 'destroyed' for the item.
// This is your substitute for the normal onDestroy method.
// - You can use .item to get the item the struct is indexed for.
// - You can typecast between IDEA structs freely because they all
// share the same indexed unit.
// - Please refrain from allocating or deallocating IDEA structs or an
// ogre will eat your children.
//
//
// Thanks:
// - Jesus4Lyf: For Event, and the AIDS structs that IDEA structs are essentially rips of, and the documentation template.
//
// - Vexorian: For TimerUtils.
//
//
// How to import:
// - Create a trigger named IDEA.
// - Convert it to custom text and replace all the trigger text with this.
// - Import IDEAZinc if you are a Zinc user.
//
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
library IDEA initializer Init requires TimerUtils, Event
globals
private constant real DECAY_PERIOD = 2
//How long it takes for an item to be removed after death.
endglobals
//Please don't touch below.
globals
private trigger onAlloc = CreateTrigger()
private trigger onDealloc = CreateTrigger()
private Event Ev
private item DeadItem = null
endglobals
public struct s_Data
static boolexpr onDeath
static hashtable ht = InitHashtable()
static thistype tempData = 0
item i
trigger t
//! textmacro IDEA__RegisterItem takes ITEM
set s_Data.tempData = s_Data.create()
set s_Data.tempData.t = CreateTrigger()
set s_Data.tempData.i = $ITEM$
call SetItemUserData($ITEM$, s_Data.tempData)
call TriggerRegisterDeathEvent(s_Data.tempData.t, $ITEM$)
call TriggerAddCondition(s_Data.tempData.t, s_Data.onDeath)
call TriggerEvaluate(onAlloc)
set s_Data.tempData = 0
//! endtextmacro
static method finishDeath takes nothing returns nothing
local timer tm = GetExpiredTimer()
set tempData = GetTimerData(tm)
call ReleaseTimer(tm)
call RemoveItem(tempData.i)
set s_Data.tempData = 0
endmethod
static method onDeathFunc takes nothing returns boolean
local timer tm = NewTimer()
call SaveWidgetHandle(ht, 0, 0, GetTriggerWidget())
set DeadItem = LoadItemHandle(ht, 0, 0)
call Ev.fire()
call SetTimerData(tm, GetItemUserData(DeadItem))
call TimerStart(tm, DECAY_PERIOD, false, function thistype.finishDeath)
set DeadItem = null
return false
endmethod
static method pickUp takes nothing returns boolean
local item it = GetManipulatedItem()
if GetItemUserData(it) == 0 then
//! runtextmacro IDEA__RegisterItem("it")
endif
set it = null
return false
endmethod
static method purchase takes nothing returns boolean
local item it = GetSoldItem()
if GetItemUserData(it) == 0 then
//! runtextmacro IDEA__RegisterItem("it")
endif
set it = null
return false
endmethod
static method pawn takes nothing returns boolean
set tempData = GetItemUserData(GetSoldItem())
call RemoveItem(tempData.i)
set s_Data.tempData = 0
return false
endmethod
static method onOrder takes nothing returns boolean
local item it = GetOrderTargetItem()
if it != null then
if GetItemUserData(it) == 0 then
//! runtextmacro IDEA__RegisterItem("it")
endif
endif
return false
endmethod
static method initEnumUnits takes nothing returns boolean
local item it
local unit u = GetFilterUnit()
local integer ind
if UnitInventorySize(u) > 0 then
set ind = 5
loop
set it = UnitItemInSlot(u, ind)
if it != null then
//! runtextmacro IDEA__RegisterItem("it")
endif
exitwhen ind == 0
set ind = ind - 1
endloop
set it = null
endif
set u = null
return false
endmethod
static method initEnum takes nothing returns boolean
local item it = GetFilterItem()
//! runtextmacro IDEA__RegisterItem("it")
set it = null
return false
endmethod
static method onInit takes nothing returns nothing
local trigger t1 = CreateTrigger()
local trigger t2 = CreateTrigger()
local trigger t3 = CreateTrigger()
local trigger t4 = CreateTrigger()
local integer i = 15
loop
call TriggerRegisterPlayerUnitEvent(t1, Player(i), EVENT_PLAYER_UNIT_PICKUP_ITEM, null)
call TriggerRegisterPlayerUnitEvent(t2, Player(i), EVENT_PLAYER_UNIT_SELL_ITEM, null)
call TriggerRegisterPlayerUnitEvent(t3, Player(i), EVENT_PLAYER_UNIT_PAWN_ITEM, null)
call TriggerRegisterPlayerUnitEvent(t4, Player(i), EVENT_PLAYER_UNIT_ISSUED_TARGET_ORDER, null)
exitwhen i == 0
set i = i - 1
endloop
call TriggerAddCondition(t1, function s_Data.pickUp)
call TriggerAddCondition(t2, function s_Data.purchase)
call TriggerAddCondition(t3, function s_Data.pawn)
call TriggerAddCondition(t4, function s_Data.onOrder)
set onDeath = Filter(function thistype.onDeathFunc)
set Ev = Event.create()
endmethod
endstruct
private function Init takes nothing returns nothing
local group g = CreateGroup()
call GroupEnumUnitsInRect(g, bj_mapInitialPlayableArea, function s_Data.initEnumUnits)
call DestroyGroup(g)
set g = null
call EnumItemsInRect(bj_mapInitialPlayableArea, function s_Data.initEnum, null)
call DestroyBoolExpr(function s_Data.initEnum)
endfunction
function TriggerRegisterItemDeathEvent takes trigger t returns nothing
call Ev.register(t)
endfunction
function GetTriggerItem takes nothing returns item //for compatibility
return DeadItem
endfunction
function GetDyingItem takes nothing returns item
return DeadItem
endfunction
//Hear that horrible ripping sound?
public struct DEFAULT extends array
method IDEA_onCreate takes nothing returns nothing
endmethod
method IDEA_onDestroy takes nothing returns nothing
endmethod
endstruct
public function RegisterOnCreate takes boolexpr b returns nothing
call TriggerAddCondition(onAlloc, b)
endfunction
public function RegisterOnDestroy takes boolexpr b returns nothing
call TriggerAddCondition(onDealloc, b)
endfunction
module IDEA
private static delegate IDEA_DEFAULT IDEA_DELEGATE = 0
static method operator[] takes item it returns thistype
return GetItemIndex(it)
endmethod
method operator item takes nothing returns item
return s_Data.tempData.i
endmethod
private static method IDEA_onAllocation takes nothing returns boolean
call thistype(s_Data.tempData).IDEA_onCreate()
return false
endmethod
private static method IDEA_onDeallocation takes nothing returns boolean
call thistype(s_Data.tempData).IDEA_onDestroy()
return false
endmethod
private static method onInit takes nothing returns nothing
call IDEA_RegisterOnCreate(Filter(function thistype.IDEA_onAllocation))
call IDEA_RegisterOnDestroy(Filter(function thistype.IDEA_onDeallocation))
endmethod
endmodule
function RemoveItemEx takes item i returns nothing //For compatibility.
if s_Data.tempData == 0 then
set s_Data.tempData = GetItemUserData(i)
endif
call TriggerEvaluate(onDealloc)
call DestroyTrigger(s_Data.tempData.t)
set s_Data.tempData.t = null
set s_Data.tempData.i = null
call s_Data.tempData.destroy()
set s_Data.tempData = 0
endfunction
hook RemoveItem RemoveItemEx
function GetItemIndex takes item i returns integer
set s_Data.tempData = GetItemUserData(i)
if s_Data.tempData == 0 then
//! runtextmacro IDEA__RegisterItem("i")
endif
return s_Data.tempData
endfunction
function GetItemId takes item i returns integer
return GetItemUserData(i)
endfunction
endlibrary
IDEAZinc Code
JASS:
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//~~ IDEAZinc ~~
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// IDEAZinc is just an addition that lets you use IDEA structs in Zinc.
// They are constructed and used exactly like vJass IDEA structs, but the
// module implementation should look like:
// module IDEAZinc;
//
//
//
// How to import:
// - Create a trigger named IDEAZinc.
// - Convert it to custom text and replace all the trigger text with this..
//
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//! zinc
library IDEAZinc requires IDEA {
public module IDEAZinc {
private static delegate IDEA_DEFAULT IDEA_DELEGATE = 0;
static method operator[] (item it) -> thistype {
return GetItemIndex(it);
}
method operator item () -> item {
return IDEA_s_Data.tempData.i;
}
private static method IDEA_onAllocation () -> boolean {
thistype(IDEA_s_Data.tempData).IDEA_onCreate();
return false;
}
private static method IDEA_onDeallocation () -> boolean {
thistype(IDEA_s_Data.tempData).IDEA_onDestroy();
return false;
}
private static method onInit () {
IDEA_RegisterOnCreate(Filter(function thistype.IDEA_onAllocation));
IDEA_RegisterOnDestroy(Filter(function thistype.IDEA_onDeallocation));
}
}
}
//! endzinc
Here's an example to talk for me.
JASS:
scope Test initializer Init
private struct IDEAStruct
implement IDEA
method IDEA_onCreate takes nothing returns nothing
call BJDebugMsg("Index allocated: " + I2S(this))
endmethod
method IDEA_onDestroy takes nothing returns nothing
call BJDebugMsg("Index deallocated: " + I2S(this))
endmethod
endstruct
private function Actions takes nothing returns nothing
call BJDebugMsg("Item died.")
endfunction
private function Init takes nothing returns nothing
local trigger t = CreateTrigger()
call TriggerRegisterItemDeathEvent(t)
call TriggerAddAction(t, function Actions)
endfunction
endscope