Добавлен Unryze,
опубликован
Алгоритмы, Наработки и Способности
Способ реализации:
Jass
Тип:
Алгоритм
Версия Warcraft:
1.21+
Вступление
Для чего эта наработка?
Фактически, данная наработка - это давняя моя фантазия, а точнее возможность иметь полноценный API групп не только для объектов типа unit, а по нужде расширять и для других объектов тоже. В итоге вышла вот такая вот короткая, но полезная наработка. Которую конечно же можно расширять и улучшать по мере нужды и без нужды в МемХаке, что и делает её столь прелестной.
Какие минусы у наработки?
Фактически единственный минус - это псевдо-реализация путём Хешатаблицы, заместо прямого использования группы. Так как единственная причина, по которой CreateGroup вообще используется - это чтобы получить уникальный хендл и не более. Остальные минусы - это подводные камни, которые ещё могут всплыть, ну и возможно несколько "ужатые" возможности, ибо нет возможность использовать GroupEnum эффективно или же ForGroup (вообще).
Для наработки необходим МемХак?
Нет! В этом и вся прелесть.
API
Базовые функции
globals
hashtable PseudoGroupTable = InitHashtable( )
endglobals
function InitPseudoGroupVariables takes nothing returns nothing
// supported handle types
call SaveInteger( PseudoGroupTable, 'type', 'hndl', 0 )
call SaveInteger( PseudoGroupTable, 'type', 'item', 1 )
// variable types
// 'size' = group size
// 'iter' = group iterator
endfunction
function CreatePseudoGroup takes integer gtype returns group
local group g = CreateGroup( )
local integer hid = GetHandleId( g )
call SaveGroupHandle( PseudoGroupTable, hid, gtype, g )
set g = null
return LoadGroupHandle( PseudoGroupTable, hid, gtype )
endfunction
function ClearPseudoGroup takes group g, integer gtype returns boolean
local integer hid = GetHandleId( g )
if g != null and g == LoadGroupHandle( PseudoGroupTable, hid, gtype ) then
call FlushChildHashtable( PseudoGroupTable, hid )
call GroupClear( g )
return true
endif
return false
endfunction
function DestroyPseudoGroup takes group g, integer gtype returns nothing
if ClearPseudoGroup( g, gtype ) then
call DestroyGroup( g )
endif
endfunction
Unit Group API
function CreateUnitGroup takes nothing returns group
return CreatePseudoGroup( 'unit' )
endfunction
function ClearUnitGroup takes group g returns nothing
call ClearPseudoGroup( g, 'unit' )
endfunction
function DestroyUnitGroup takes group g returns nothing
call DestroyPseudoGroup( g, 'unit' )
endfunction
function GroupHasUnitEx takes group g, unit u returns boolean
local integer i = 0
local integer hid = GetHandleId( g )
local unit u_temp = null
local integer size = LoadInteger( PseudoGroupTable, hid, 'size' )
local boolean result = false
if g != null and u != null and g == LoadGroupHandle( PseudoGroupTable, hid, 'unit' ) then
loop
set u_temp = LoadUnitHandle( PseudoGroupTable, hid, i )
exitwhen u_temp == u or i > size
set i = i + 1
endloop
set result = u_temp == u
endif
return result
endfunction
function GroupAddItemEx takes group g, unit u returns nothing
local integer i = 0
local integer hid = GetHandleId( g )
local integer size = LoadInteger( PseudoGroupTable, hid, 'size' )
local unit u_temp = null
if g != null and u != null and g == LoadGroupHandle( PseudoGroupTable, hid, 'unit' ) then
if not GroupHasUnitEx( g, u ) then
loop
set u_temp = LoadUnitHandle( PseudoGroupTable, hid, i )
exitwhen u_temp == null
set i = i + 1
endloop
endif
call SaveInteger( PseudoGroupTable, hid, 'size', size + 1 )
call SaveUnitHandle( PseudoGroupTable, hid, i, u )
endif
set u_temp = null
set g = null
endfunction
function GroupRemoveUnitEx takes group g, unit u returns nothing
local integer i = 0
local integer hid = GetHandleId( g )
local integer size = LoadInteger( PseudoGroupTable, hid, 'size' )
local unit u_temp = null
if g != null and u != null and g == LoadGroupHandle( PseudoGroupTable, hid, 'unit' ) then
loop
set u_temp = LoadUnitHandle( PseudoGroupTable, hid, i )
exitwhen u_temp == u or i > size
set i = i + 1
endloop
if u_temp == u then
loop
exitwhen i == size
call RemoveSavedHandle( PseudoGroupTable, hid, i )
call SaveUnitHandle( PseudoGroupTable, hid, i, LoadUnitHandle( PseudoGroupTable, hid, i + 1 ) )
set i = i + 1
endloop
call SaveInteger( PseudoGroupTable, hid, 'size', size - 1 )
endif
endif
set u_temp = null
set g = null
endfunction
function GetUnitFromGroupByIndexEx takes group g, integer index returns unit
local integer hid = GetHandleId( g )
local integer size = LoadInteger( PseudoGroupTable, hid, 'size' )
if g != null and g == LoadGroupHandle( PseudoGroupTable, hid, 'unit' ) and index < size then
return LoadUnitHandle( PseudoGroupTable, GetHandleId( g ), index )
endif
return null
endfunction
function ForEachUnitEx takes group g returns unit
local integer hid = GetHandleId( g )
local integer iterator = LoadInteger( PseudoGroupTable, hid, 'iter' )
local integer size = LoadInteger( PseudoGroupTable, hid, 'size' )
if g != null and g == LoadGroupHandle( PseudoGroupTable, hid, 'unit' ) then
if iterator < size then
call SaveInteger( PseudoGroupTable, hid, 'iter', iterator + 1 )
return LoadUnitHandle( PseudoGroupTable, hid, iterator )
else
call SaveInteger( PseudoGroupTable, hid, 'iter', 0 )
endif
endif
return null
endfunction
Item Group API
function CreateItemGroup takes nothing returns group
return CreatePseudoGroup( 'item' )
endfunction
function ClearItemGroup takes group g returns nothing
call ClearPseudoGroup( g, 'item' )
endfunction
function DestroyItemGroup takes group g returns nothing
call DestroyPseudoGroup( g, 'item' )
endfunction
function GroupHasItem takes group g, item it returns boolean
local integer i = 0
local integer hid = GetHandleId( g )
local item it_temp = null
local integer size = LoadInteger( PseudoGroupTable, hid, 'size' )
local boolean result = false
if g != null and it != null and g == LoadGroupHandle( PseudoGroupTable, hid, 'item' ) then
loop
set it_temp = LoadItemHandle( PseudoGroupTable, hid, i )
exitwhen it_temp == it or i > size
set i = i + 1
endloop
set result = it_temp == it
endif
set it_temp = null
return false
endfunction
function GroupAddItem takes group g, item it returns nothing
local integer i = 0
local integer hid = GetHandleId( g )
local integer size = LoadInteger( PseudoGroupTable, hid, 'size' )
local item it_temp = null
if g != null and it != null and g == LoadGroupHandle( PseudoGroupTable, hid, 'item' ) then
if not GroupHasItem( g, it ) then
loop
set it_temp = LoadItemHandle( PseudoGroupTable, hid, i )
exitwhen it_temp == null
set i = i + 1
endloop
endif
call SaveInteger( PseudoGroupTable, hid, 'size', size + 1 )
call SaveItemHandle( PseudoGroupTable, hid, i, it )
endif
set it_temp = null
set g = null
endfunction
function GroupRemoveItem takes group g, item it returns nothing
local integer i = 0
local integer hid = GetHandleId( g )
local integer size = LoadInteger( PseudoGroupTable, hid, 'size' )
local item it_temp = null
if g != null and it != null and g == LoadGroupHandle( PseudoGroupTable, hid, 'item' ) then
loop
set it_temp = LoadItemHandle( PseudoGroupTable, hid, i )
exitwhen it_temp == it or i > size
set i = i + 1
endloop
if it_temp == it then
loop
exitwhen i == size
call RemoveSavedHandle( PseudoGroupTable, hid, i )
call SaveItemHandle( PseudoGroupTable, hid, i, LoadItemHandle( PseudoGroupTable, hid, i + 1 ) )
set i = i + 1
endloop
call SaveInteger( PseudoGroupTable, hid, 'size', size - 1 )
endif
endif
set it_temp = null
set g = null
endfunction
function GetItemFromGroupByIndex takes group g, integer index returns item
local integer hid = GetHandleId( g )
local integer size = LoadInteger( PseudoGroupTable, hid, 'size' )
if g != null and g == LoadGroupHandle( PseudoGroupTable, hid, 'item' ) and index < size then
return LoadItemHandle( PseudoGroupTable, GetHandleId( g ), index )
endif
return null
endfunction
function ForEachItem takes group g returns item
local integer hid = GetHandleId( g )
local integer iterator = LoadInteger( PseudoGroupTable, hid, 'iter' )
local integer size = LoadInteger( PseudoGroupTable, hid, 'size' )
if g != null and g == LoadGroupHandle( PseudoGroupTable, hid, 'item' ) then
if iterator < size then
call SaveInteger( PseudoGroupTable, hid, 'iter', iterator + 1 )
return LoadItemHandle( PseudoGroupTable, hid, iterator )
else
call SaveInteger( PseudoGroupTable, hid, 'iter', 0 )
endif
endif
return null
endfunction
Effect Group API
function CreateEffectGroup takes nothing returns group
return CreatePseudoGroup( 'efct' )
endfunction
function ClearEffectGroup takes group g returns nothing
call ClearPseudoGroup( g, 'efct' )
endfunction
function DestroyEffectGroup takes group g returns nothing
call DestroyPseudoGroup( g, 'efct' )
endfunction
function GroupHasEffect takes group g, effect ef returns boolean
local integer i = 0
local integer hid = GetHandleId( g )
local effect ef_temp = null
local integer size = LoadInteger( PseudoGroupTable, hid, 'size' )
local boolean result = false
if g != null and ef != null and g == LoadGroupHandle( PseudoGroupTable, hid, 'efct' ) then
loop
set ef_temp = LoadEffectHandle( PseudoGroupTable, hid, i )
exitwhen ef_temp == ef or i > size
set i = i + 1
endloop
set result = ef_temp == ef
endif
set ef_temp = null
return false
endfunction
function GroupAddEffect takes group g, effect ef returns nothing
local integer i = 0
local integer hid = GetHandleId( g )
local integer size = LoadInteger( PseudoGroupTable, hid, 'size' )
local effect ef_temp = null
if g != null and ef != null and g == LoadGroupHandle( PseudoGroupTable, hid, 'efct' ) then
if not GroupHasEffect( g, ef ) then
loop
exitwhen not HaveSavedHandle( PseudoGroupTable, hid, i )
set i = i + 1
endloop
call SaveInteger( PseudoGroupTable, hid, 'size', size + 1 )
call SaveEffectHandle( PseudoGroupTable, hid, i, ef )
endif
endif
set ef_temp = null
set g = null
endfunction
function GroupRemoveEffect takes group g, effect ef returns nothing
local integer i = 0
local integer hid = GetHandleId( g )
local integer size = LoadInteger( PseudoGroupTable, hid, 'size' )
local effect ef_temp = null
if g != null and ef != null and g == LoadGroupHandle( PseudoGroupTable, hid, 'efct' ) then
loop
set ef_temp = LoadEffectHandle( PseudoGroupTable, hid, i )
exitwhen ef_temp == ef or i > size
set i = i + 1
endloop
if ef_temp == ef then
loop
exitwhen i == size
call RemoveSavedHandle( PseudoGroupTable, hid, i )
call SaveEffectHandle( PseudoGroupTable, hid, i, LoadEffectHandle( PseudoGroupTable, hid, i + 1 ) )
set i = i + 1
endloop
call SaveInteger( PseudoGroupTable, hid, 'size', size - 1 )
endif
endif
set ef_temp = null
set g = null
endfunction
function GetEffectFromGroupByIndex takes group g, integer index returns effect
local integer hid = GetHandleId( g )
local integer size = LoadInteger( PseudoGroupTable, hid, 'size' )
if g != null and g == LoadGroupHandle( PseudoGroupTable, hid, 'efct' ) and index < size then
return LoadEffectHandle( PseudoGroupTable, GetHandleId( g ), index )
endif
return null
endfunction
function ForEachEffect takes group g returns effect
local integer hid = GetHandleId( g )
local integer iterator = LoadInteger( PseudoGroupTable, hid, 'iter' )
local integer size = LoadInteger( PseudoGroupTable, hid, 'size' )
if g != null and g == LoadGroupHandle( PseudoGroupTable, hid, 'efct' ) then
if iterator < size then
call SaveInteger( PseudoGroupTable, hid, 'iter', iterator + 1 )
return LoadEffectHandle( PseudoGroupTable, hid, iterator )
else
call SaveInteger( PseudoGroupTable, hid, 'iter', 0 )
endif
endif
return null
endfunction
Код
`
ОЖИДАНИЕ РЕКЛАМЫ...
Чтобы оставить комментарий, пожалуйста, войдите на сайт.
Отредактирован Unryze
Но не суть, сейчас внесу правку.