- Joined
- May 9, 2014
- Messages
- 1,820
Mission Type: Item
Missions Performed: Item Stacking, Item Splitting
Reason for Merging of Missions: These two felt like they are mutually inclusive of each other, which led me to submit both of these snippets.
(User-defined) Globals used:
Mandatory:
The missions performed in this submission are: Item Stacking and Item Splitting.
Item Stacking refers to the process of incrementing the number of charges for a particular item. What the Item Stacking mission mandates is to allow charged items to stack with each other.
Item Splitting refers to the process of division of a particular item into two sub-items.
Globals:
- This array is a parallel array that stores the item-types that will be stacked.
- This array is also a parallel array. It acts as the upper bound of the amount of charges for a certain item-type.
- Is worth something after you call the function
- Acts as the maximum index of the item-type stack.
- Allows allocation and deallocation of ItemType instances (implicitly)
Functions:
- This allows the triggers above to detect when a certain item of the requested item-type is acquired, and allows the stacking of said item...
- The function automatically converts the item into an item-type and searches for it in the item-type stack, returning true if it is in the stack, or false otherwise.
I decided to approach this mission with a sense of modularity, because I thought of a case-scenario wherein you do not want a certain item-type (which you know to be charged) to stack with itself. The allocation scheme is purely for including item-types in the stack, so that when the acquirement of a stackable item occurs, the system checks for it and its' internal limit.
Missions Performed: Item Stacking, Item Splitting
Reason for Merging of Missions: These two felt like they are mutually inclusive of each other, which led me to submit both of these snippets.
Code
Description
API
Approach
(User-defined) Globals used:
JASS:
globals
integer array udg_ItemType_ChargeItem
integer array udg_ItemType_ChargeLimit
integer udg_ItemType_getInstance = 0
integer udg_ItemType_maxIndex = 0
integer array udg_ItemType_recycler
endglobals
Mandatory:
JASS:
...
function PrintTo takes player p, string s, real dur returns nothing
call DisplayTimedTextToPlayer(p, 0, 0, dur, s)
endfunction
function Print takes string s returns nothing
call PrintTo(GetLocalPlayer(), s, (StringLength(s) * 0.3 + 1.5))
endfunction
...
// This frees up an instance in the recycler stack...
function ItemType_deallocate takes integer this returns nothing
set udg_ItemType_recycler[this] = udg_ItemType_recycler[0]
set udg_ItemType_recycler[0] = this
if this == udg_ItemType_maxIndex then
set udg_ItemType_maxIndex = udg_ItemType_maxIndex - 1
endif
endfunction
// This gives us an instance to work with...
function ItemType_allocate takes nothing returns integer
local integer this = udg_ItemType_recycler[0]
if udg_ItemType_recycler[this] == 0 then
set this = this + 1
set udg_ItemType_recycler[0] = this
set udg_ItemType_maxIndex = this
return this
endif
set udg_ItemType_recycler[0] = udg_ItemType_recycler[this]
set udg_ItemType_recycler[this] = 0
return this
endfunction
// Now, we search for a certain item-type and see if a match comes up..
// If it does, then we can stack items of that item-type
function ItemType_search takes integer itemType returns integer
local integer this = 1
loop
exitwhen this > udg_ItemType_maxIndex or udg_ItemType_ChargeItem[this] == itemType
set this = this + 1
endloop
if this > udg_ItemType_maxIndex then
set this = 0
endif
return this
endfunction
// Searches for an instance, then checks if it is not zero.
// If it is not zero, then we have a stackable item.
function IsItemCharged takes item whichItem returns boolean
set udg_ItemType_getInstance = ItemType_search(GetItemTypeId(whichItem))
return udg_ItemType_getInstance != 0
endfunction
// This removes a certain item-type from the stack.
// What this truly does is to no longer allow items with the item-type to stack.
function ItemType_destroy takes integer itemType returns nothing
local integer this = ItemType_search(itemType)
if this == 0 then
return
endif
set udg_ItemType_ChargeItem[this] = 0
set udg_ItemType_ChargeLimit[this] = 0
call ItemType_deallocate(this)
endfunction
// This checks if the item type is not yet in the stack, and allocates a new instance if it is so.
// After checking, it would just set the limit of charges to its' maximum
function ItemType_create takes integer itemType, integer numCharges returns integer
local integer this = ItemType_search(itemType)
if this == 0 then
set this = ItemType_allocate()
set udg_ItemType_ChargeItem[this] = itemType
endif
set udg_ItemType_ChargeLimit[this] = numCharges
return this
endfunction
// Had to create this function so that JassHelper will not yell at me for referencing functions below a requesting function..
function InitTrig_Item_Charge_Handler takes nothing returns nothing
endfunction
Item Stacking
Item Splitting
JASS:
// Due to pJASS, this compiles just fine, even if you're supposed to return a boolean.
// This is a filterfunc...
function Item_Charger_Actions takes nothing returns nothing
local unit u = GetTriggerUnit()
local item i_targ = GetManipulatedItem()
local item item_iterator = null
local integer item_items = 0
local integer i_targ_type = GetItemTypeId(i_targ)
local integer i = 0
// We check if the item is stackable as defined by the stack..
if IsItemCharged(i_targ) then
loop
// item_iterator acts as the comparator...
set item_iterator = UnitItemInSlot(u, i)
set item_items = GetItemCharges(item_iterator)
// We terminate the search should we end in either the last element or the current item eing manipulated.
exitwhen i > 5 or item_iterator == i_targ
// We compare the comparator and the manipulated item to see if they are of the same item-type
if GetItemTypeId(item_iterator) == i_targ_type then
// If the number of charges is less than the item-type's limit, then we stack the item.
if item_items < udg_ItemType_ChargeLimit[udg_ItemType_getInstance] then
call SetItemCharges(item_iterator, GetItemCharges(i_targ) + item_items)
call Print(GetItemName(item_iterator) + "[" + I2S(GetItemCharges(item_iterator)) + "]" + " [+ " + I2S(GetItemCharges(item_iterator) - item_items) + "]")
// Should the number of charges exceed that of the limit, the number of charges in the comparator would be reset to the limit, and the number of charges of the manipulated item would be updated.
// Otherwise, the comparator has technically absorbed the item.
if GetItemCharges(item_iterator) > udg_ItemType_ChargeLimit[udg_ItemType_getInstance] then
call SetItemCharges(i_targ, GetItemCharges(item_iterator) - udg_ItemType_ChargeLimit[udg_ItemType_getInstance])
call SetItemCharges(item_iterator, udg_ItemType_ChargeLimit[udg_ItemType_getInstance])
else
call RemoveItem(i_targ)
exitwhen true
endif
endif
endif
set i = i + 1
endloop
// Unlikely case, but if the number of charges exceed that of the limit as assigned in the stack of item types, then we split the item and try again.
if item_iterator == i_targ then
if GetItemCharges(i_targ) > udg_ItemType_ChargeLimit[udg_ItemType_getInstance] then
set bj_lastCreatedItem = CreateItem(i_targ_type, GetUnitX(u), GetUnitY(u))
call SetItemCharges(bj_lastCreatedItem, GetItemCharges(i_targ) - udg_ItemType_ChargeLimit[udg_ItemType_getInstance])
call SetItemCharges(i_targ, udg_ItemType_ChargeLimit[udg_ItemType_getInstance])
call UnitAddItem(u, bj_lastCreatedItem)
return
endif
endif
endif
set i_targ = null
set u = null
endfunction
// this function is just a wrapper function, which makes the code a bit more readable.
function ItemCharger__RegisterItems takes nothing returns nothing
call ItemType_create('stwp', 3)
endfunction
//===========================================================================
function InitTrig_Item_Charger takes nothing returns nothing
set gg_trg_Item_Charger = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(gg_trg_Item_Charger, EVENT_PLAYER_UNIT_PICKUP_ITEM)
call TriggerAddCondition(gg_trg_Item_Charger, Filter(function Item_Charger_Actions))
call ItemCharger__RegisterItems()
endfunction
JASS:
// This function attempts to find the item in a unit, returning -1 if the item is not found.
function GetItemSlotInUnit takes item whichItem, unit whichUnit returns integer
local integer i = 0
loop
exitwhen i > 5 or UnitItemInSlot(whichUnit, i) == whichItem
set i = i + 1
endloop
if i > 5 then
return -1
endif
return i
endfunction
// To do the split, one must take note that the order fires triggers registered to the issuance of an order targeting a certain target.
// using Order tracking, the bounds of the orders issued are 852002 (slot 1) to 852007 (slot 6)
function Item_Disassembler_Actions takes nothing returns nothing
local unit u = GetTriggerUnit()
local integer order = GetIssuedOrderId()
local integer itemSlotOrigin = 0
local integer itemSlotTarget = 0
local item i_targ
local item i_new
// this tells us if the order is that of relocating a certain item to another slot.
if 852002 <= order and order <= 852007 then
set i_targ = GetOrderTargetItem()
if IsItemCharged(i_targ) then
set itemSlotOrigin = GetItemSlotInUnit(i_targ, u)
set itemSlotTarget = order - 852002
if itemSlotOrigin != itemSlotTarget then
set i_new = UnitItemInSlot(u, itemSlotTarget)
if i_new != null then
call Print("An item was found!")
if GetItemTypeId(i_new) == GetItemTypeId(i_targ) then
if GetItemCharges(i_new) < udg_ItemType_ChargeLimit[udg_ItemType_getInstance] and GetItemCharges(i_targ) < udg_ItemType_ChargeLimit[udg_ItemType_getInstance] then
call Print("Item charges in target slot less than 3! Attempting merge!")
call SetItemCharges(i_new, GetItemCharges(i_new) + GetItemCharges(i_targ))
if GetItemCharges(i_new) > udg_ItemType_ChargeLimit[udg_ItemType_getInstance] then
call SetItemCharges(i_new, GetItemCharges(i_new) - udg_ItemType_ChargeLimit[udg_ItemType_getInstance])
call SetItemCharges(i_targ, udg_ItemType_ChargeLimit[udg_ItemType_getInstance])
else
call RemoveItem(i_targ)
endif
else
call Print("Item charges in target slot greater than or equal to 3. Ignoring merge!")
endif
else
call Print("Comparison between two different types are not allowed!")
endif
else
call Print("No item in item slot found")
if GetItemCharges(i_targ) != 1 then
call Print("Item charges are in excess, splitting!")
set i_new = CreateItem(GetItemTypeId(i_targ), GetUnitX(u), GetUnitY(u))
call SetItemCharges(i_targ, GetItemCharges(i_targ) - GetItemCharges(i_new))
call DisableTrigger(gg_trg_Item_Charger)
call UnitAddItem(u, i_new)
call EnableTrigger(gg_trg_Item_Charger)
call SetItemCharges(i_targ, GetItemCharges(i_targ) + GetItemCharges(i_new))
call SetItemCharges(i_new, GetItemCharges(i_targ) - GetItemCharges(i_new))
call SetItemCharges(i_targ, GetItemCharges(i_targ) - GetItemCharges(i_new))
else
call Print("Item charges are atomic, ignoring!")
endif
endif
set i_new = null
endif
endif
set i_targ = null
endif
set u = null
endfunction
//===========================================================================
function InitTrig_Item_Disassembler takes nothing returns nothing
local trigger t = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_ISSUED_TARGET_ORDER)
call TriggerAddCondition(t, Filter(function Item_Disassembler_Actions))
set t = null
endfunction
The missions performed in this submission are: Item Stacking and Item Splitting.
Item Stacking refers to the process of incrementing the number of charges for a particular item. What the Item Stacking mission mandates is to allow charged items to stack with each other.
Item Splitting refers to the process of division of a particular item into two sub-items.
Globals:
integer array udg_ItemType_ChargeItem
- This array is a parallel array that stores the item-types that will be stacked.
integer array udg_ItemType_ChargeLimit
- This array is also a parallel array. It acts as the upper bound of the amount of charges for a certain item-type.
integer udg_ItemType_getInstance
- Is worth something after you call the function
IsItemCharged
integer udg_ItemType_maxIndex
- Acts as the maximum index of the item-type stack.
integer array udg_ItemType_recycler
- Allows allocation and deallocation of ItemType instances (implicitly)
Functions:
function ItemType_create takes integer itemType, integer numCharges returns integer
- This allows the triggers above to detect when a certain item of the requested item-type is acquired, and allows the stacking of said item...
function IsItemCharged takes item whichItem returns boolean
- The function automatically converts the item into an item-type and searches for it in the item-type stack, returning true if it is in the stack, or false otherwise.
I decided to approach this mission with a sense of modularity, because I thought of a case-scenario wherein you do not want a certain item-type (which you know to be charged) to stack with itself. The allocation scheme is purely for including item-types in the stack, so that when the acquirement of a stackable item occurs, the system checks for it and its' internal limit.
Attachments
Last edited: