SerraAvenger
Cuz I can
- Reaction score
- 234
JASS:
//=======================================================\\
//*****************Davey's Unit Indexing*****************||
//=======================================================//
//Requirements
// - A little bit of JASS knowledge
// - And JassPack NewGen 1.4c ( or Higher )
//
//What does this do?
// Davey's Unit Indexing ( DUI ) is a "small" system,
// that allows a unit management similiar to the "Custom Value"
// one which was built in into the World Editor. The differences:
// - It allows multiple Custom Values at once.
// - If you start the map in Debug Mode, it shows you the maximum
// number of Custom Values you may use. The mimum Number for
// those is 4.
// - It handles the positions for you, you only need to assign
// custom values.
//
//Purpose:
// Attach multiple integers to a unit. These integers can be
// used for almost anything, including: as indicies for
// other arrays; As some "Group affinity" marker; As a custom
// level; or whatever.
//
//How to use?
// Simply pick the unit you want to add the custom value to and do:
// call SetUnitValue( unit , custom value number - 1 , the value )
// so to set trigUnit's 2nd custom value to 15, do:
// call SetUnitValue( trigUnit , 1 , 15 )
// With the Standard Settings you can use up to 4 different custom
// values ( 0 , 1 , 2 , 3 ). Using others will result in nothing to
// happen.
//
//====================================================================D
//FAQ:
// Q : There allready is the PUI of Cohadar - Why should I use
// this one?
// A : Well, there is no really big difference. Memory usage wise, his is
// a little bit better at the beginning. Efficiency wise, I didn't
// like his Recycling thus I created my own system which is using a
// free list and really using an attach custom value system rather
// than a single indexing method. SO: It is easier to
// instant-use, Cohadars system needs an extra implementation.
// Sure, you can extend this system too with that extra implementation.
// And With a bit of work you can do everything with Cohadars system too.
//
// Q : What If I try to get a CustomValue Number from a unit I did not set
// for the unit before, or if I try to get a CustomValue from a unit
// for which I did not assign any CustomValue at all yet?
// A : It will, just like in GetUnitUserData() , return 0.
//
// Q : When I Try to Save, The Syntax checker Tells me that there are
// plenty of unexpected names / Wc3 Crashes. I have not tried
// to fuddle with the code.
// A : In most of the cases, you simply forgot to install JassPack
// NewGen; Or you started the regular WorldEditor instead
// of the application the JassPack NewGen contains.
//
// Q : When I tell the system I would need more then 2048 Indicies, it does
// only allocate 2048 at max...
// A : This was done to Set the minimum number of Custom Values that are
// usable to 4. If you need more Indicies but can live with less
// custom values, delete the "exitwhen fieldIndicator > 2048" part
// in the InitDUI function.
//
// Q : How can I concatenate this system with other custom value systems
// I use?
// A : You'll need to use only this system. Then you can use SetUnitValue( )
// with one value per system you use. ( 0 for the first; 1 for the
// second etc )
//
// Q : How is the number of available custom values computed?
// A : 8192 / The Maximum Custom Index. For 2048 possible indexes, this means
// 4; for 1024 it is 8.
//
//====================================================================D
library DUI initializer InitDUI
globals
private integer MaxCustomIndex = 2048
endglobals
// Above Value needs to be set to the Maximum Number of Custom Values.
// A lower index will allow for a better initialisation performance;
// However, less units can be indexed. 2048 Is the maximum; If
// you choose a higher value you still will only have 2048.
globals
private integer array FreeList
private integer FirstFree
private unit array IndexUnits
private integer MaxNumCustomValues
private integer array CustomValue
endglobals
function InitDUI takes nothing returns nothing
local integer fieldIndicator = 1
set FirstFree = 0
loop
exitwhen fieldIndicator > MaxCustomIndex
exitwhen fieldIndicator > 2048
set FreeList[ fieldIndicator - 1 ] = fieldIndicator
set fieldIndicator = fieldIndicator + 1
endloop
set MaxNumCustomValues = 8192 / ( fieldIndicator - 1 )
debug DisplayTextToPlayer( GetLocalPlayer() , 0 , 0 , "The Maximum Number of Custom Values is: " + I2S( MaxNumCustomValues ) )
endfunction
private function RecycleIndex takes nothing returns boolean
local unit trigUnit = GetTriggerUnit ( )
local integer recyclingIndex = GetUnitUserData( trigUnit ) - 1
if not IsUnitType( trigUnit, UNIT_TYPE_HERO ) then
set FreeList[ recyclingIndex ] = FirstFree
set FirstFree = recyclingIndex
call DestroyTrigger ( GetTriggeringTrigger() )
endif
set trigUnit = null
return false
endfunction
function SetUnitValue takes unit indexedunit , integer whichindex , integer value returns nothing
local integer indexedUnitCustomValue = GetUnitUserData( indexedunit )
local trigger recycler
local integer loopIndicator = 0
if whichindex < MaxNumCustomValues then
if indexedUnitCustomValue != 0 then
set CustomValue[ indexedUnitCustomValue - 1 + MaxCustomIndex * whichindex ] = value
else
call SetUnitUserData ( indexedunit , FirstFree + 1 )
set indexedUnitCustomValue = GetUnitUserData( indexedunit )
set CustomValue [ indexedUnitCustomValue - 1 + MaxCustomIndex * whichindex ] = value
loop
exitwhen loopIndicator > 3
if loopIndicator != whichindex then
set CustomValue [ indexedUnitCustomValue - 1 + MaxCustomIndex * loopIndicator ] = 0
endif
set loopIndicator = loopIndicator + 1
endloop
set FirstFree = FreeList[ FirstFree ]
set recycler = CreateTrigger( )
call TriggerRegisterUnitEvent( recycler , indexedunit , EVENT_UNIT_DEATH )
call TriggerAddCondition ( recycler , Condition( function RecycleIndex ) )
set recycler = null
endif
endif
endfunction
function GetUnitValue takes unit indexedunit , integer whichindex returns integer
local integer indexedUnitCustomValue = GetUnitUserData( indexedunit )
if indexedUnitCustomValue != 0 then
return CustomValue[ indexedUnitCustomValue - 1 + MaxCustomIndex * whichindex ]
else
return 0
endif
endfunction
endlibrary
The CV tester is a Demo map. It stores the unit's order in which it entered a "special" region, as well as the unit's speed while entering. The last one is actualised everytime the unit enters the region, the first one is not.
And no I don't care about the efficiency / memory leaks of the demo trigger, it really is just there for demonstrating the way it works.
Greetings, Davey.
Changelog:
-Hero's indicies won't be recycled anymore
-Added a small, tiny - 1 where I forgot it yesterday : D
Extended Version:
This one allows for custom recyceability for certain units, so you can choose for each unit indivudually wether it shall be recycled or not. Important for units that are still used after their death, or that can die multiple times but shall keep their indicies and attached integers unaffected ( heroes, p.e. )
JASS:
//=======================================================\\
//***************** Davey's Unit Indexing *****************||
//=======================================================//
// --Extended Version--
//Requirements
// - A little bit of JASS knowledge
// - And JassPack NewGen 1.4c ( or Higher )
//
//What does this do?
// Davey's Unit Indexing ( DUI ) is a "small" system,
// that allows a unit management similiar to the "Custom Value"
// one which was built in into the World Editor. The differences:
// - It allows multiple Custom Values at once.
// - If you start the map in Debug Mode, it shows you the maximum
// number of Custom Values you may use. The mimum Number for
// those is 4.
// - It handles the positions for you, you only need to assign
// custom values.
// - It allows Units to keep their Indexes after Dying
//
//Purpose:
// Attach multiple integers to a unit. These integers can be
// used for almost anything, including: as indicies for
// other arrays; As some "Group affinity" marker; As a custom
// level; or whatever.
// Don't let the attached integers be overwritten after death
// for certain units.
//
//How to use?
// Simply pick the unit you want to add the custom value to and do:
// call SetUnitValue( unit , custom value number - 1 , the value )
// so to set trigUnit's 2nd custom value to 15, do:
// call SetUnitValue( trigUnit , 1 , 15 )
// With the Standard Settings you can use up to 4 different custom
// values ( 0 , 1 , 2 , 3 ). Using others might result in a crash.
// Then, if you Want that the new Unit will be revived after its death,
// call SetUnitRecyclable( trigUnit , false )
// This will Prevent its indicies from being overwritten / deleted when
// the unit dies. It might be useful for Heros, but every unit you use
// this on will permanently occupy one index, so you might reach the end
// or leak indicies ( when a unit that is not recycable dies and is not
// revived, one index will be leaked ). If you want to change your
// mind again, use:
// call SetUnitRecyclable( trigUnit , true )
// In Default, all indicies are recycable.
//
//====================================================================D
//FAQ:
// Q : There allready is the PUI of Cohadar - Why should I use
// this one?
// A : Well, there is no really big difference. Memory usage wise, his is
// a little bit better at the beginning. Efficiency wise, I didn't
// like his Recycling thus I created my own system which is using a
// free list and really using an attach custom value system rather
// than a single indexing method. SO: It is easier to
// instant-use, Cohadars system needs an extra implementation.
// Sure, you can extend this system too with that extra implementation.
// And With a bit of work you can do everything with Cohadars system too.
//
// Q : What If I try to get a CustomValue Number from a unit I did not set
// for the unit before, or if I try to get a CustomValue from a unit
// for which I did not assign any CustomValue at all yet?
// A : It will, just like in GetUnitUserData() , return 0.
//
// Q : When I Try to Save, The Syntax checker Tells me that there are
// plenty of unexpected names / Wc3 Crashes. I have not tried
// to fuddle with the code.
// A : In most of the cases, you simply forgot to install JassPack
// NewGen; Or you started the regular WorldEditor instead
// of the application the JassPack NewGen contains.
//
// Q : When I tell the system I would need more then 2048 Indicies, it does
// only allocate 2048 at max...
// A : This was done to Set the minimum number of Custom Values that are
// usable to 4. If you need more Indicies but can live with less
// custom values, delete the "exitwhen fieldIndicator > 2048" part
// in the InitDUI function.
//
// Q : How can I concatenate this system with other custom value systems
// I use?
// A : You'll need to use only this system. Then you can use SetUnitValue( )
// with one value per system you use. ( 0 for the first; 1 for the
// second etc )
//
// Q : How is the number of available custom values computed?
// A : 8192 / The Maximum Custom Index. For 2048 possible indexes, this means
// 4; for 1024 it is 8.
//
//====================================================================D
library ExtendedDUI initializer InitExtendedDUI
globals
private integer MaxCustomIndex = 2048
endglobals
// Above Value needs to be set to the Maximum Number of Custom Values.
// A lower index will allow for a better initialisation performance;
// However, less units can be indexed. 2048 Is the maximum; If
// you choose a higher value you still will only have 2048.
globals
private integer array FreeList
private integer FirstFree
//private unit array IndexUnits
private integer MaxNumCustomValues
private integer array CustomValue
private boolean array Recycable
endglobals
function InitExtendedDUI takes nothing returns nothing
local integer fieldIndicator = 1
set FirstFree = 0
loop
exitwhen fieldIndicator > MaxCustomIndex
exitwhen fieldIndicator > 2048
set FreeList[ fieldIndicator - 1 ] = fieldIndicator
set fieldIndicator = fieldIndicator + 1
endloop
set MaxNumCustomValues = 8192 / ( fieldIndicator - 1 )
set FreeList[ fieldIndicator - 1 ] = fieldIndicator - 1
debug DisplayTextToPlayer( GetLocalPlayer() , 0 , 0 , "The Maximum Number of Custom Values is: " + I2S( MaxNumCustomValues ) )
endfunction
private function RecycleIndex takes nothing returns boolean
local unit trigUnit = GetTriggerUnit ( )
local integer recyclingIndex = GetUnitUserData( trigUnit ) - 1
if Recycable[ recyclingIndex ] then
set FreeList[ recyclingIndex ] = FirstFree
set FirstFree = recyclingIndex
call SetUnitUserData ( trigUnit , 0 )
call DestroyTrigger ( GetTriggeringTrigger() )
endif
set trigUnit = null
return false
endfunction
function SetUnitValue takes unit indexedunit , integer whichindex , integer value returns integer
local integer indexedUnitCustomValue = GetUnitUserData( indexedunit )
local trigger recycler
local integer loopIndicator = 0
if whichindex < MaxNumCustomValues then
if indexedUnitCustomValue != 0 then
set CustomValue[ indexedUnitCustomValue - 1 + MaxCustomIndex * whichindex ] = value
else
call SetUnitUserData ( indexedunit , FirstFree + 1 )
set indexedUnitCustomValue = GetUnitUserData( indexedunit )
set Recycable [ indexedUnitCustomValue - 1 ] = true
set CustomValue [ indexedUnitCustomValue - 1 + MaxCustomIndex * whichindex ] = value
loop
exitwhen loopIndicator > 3
if loopIndicator != whichindex then
set CustomValue [ indexedUnitCustomValue - 1 + MaxCustomIndex * loopIndicator ] = 0
endif
set loopIndicator = loopIndicator + 1
endloop
set FirstFree = FreeList[ FirstFree ]
set recycler = CreateTrigger( )
call TriggerRegisterUnitEvent( recycler , indexedunit , EVENT_UNIT_DEATH )
call TriggerAddCondition ( recycler , Condition( function RecycleIndex ) )
set recycler = null
endif
endif
return indexedUnitCustomValue
endfunction
function GetUnitValue takes unit indexedunit , integer whichindex returns integer
local integer indexedUnitCustomValue = GetUnitUserData( indexedunit )
if indexedUnitCustomValue != 0 then
return CustomValue[ indexedUnitCustomValue - 1 + MaxCustomIndex * whichindex ]
else
return 0
endif
endfunction
function SetUnitRecyclable takes unit whichunit , boolean recycle returns nothing
local integer unitIndex = GetUnitUserData( whichunit ) - 1
if unitIndex != -1 then
set Recycable[ unitIndex ] = recycle
else
set Recycable[ SetUnitValue( whichunit , 0 , 0 ) ] = recycle
endif
endfunction
endlibrary
Demo maps updated soon