- Joined
- Jun 17, 2014
- Messages
- 236
Iam trying to make a feature on my system that use hashtable, but i stuck when i got a problem,
is this possible but hard, or impossible?, i've been trying much hard to solve.
here is :
cause i want to make its use like this :
the whole code :
i know getDataFromUnit() will return not exact value when the unit is affected with 2 or more DoT.
but i know how to solve it
is this possible but hard, or impossible?, i've been trying much hard to solve.
here is :
JASS:
static method getDataFromUnit takes unit un returns integer
return LoadInteger(ht,2,???) // don't know :(
endmethod
cause i want to make its use like this :
JASS:
library burntilt
...
function onCast takes nothing returns boolean
call DoT.create(...)
call TimerStart(...,function onPeriod)
endfunction
function onPeriod takes nothing return nothing
local DoT i = 0
set i = DoT.getDataFromUnit(p)
loop
exitwhen HasBuff(getTargetFromData(i),'buff')
set i = DoT.getDataFromUnit(p)
endloop
if IsUnitStunned(p) then
set i.damage = i.damage*2
set i.duration = 3
...
else
i.terminate()
...
endlibrary
the whole code :
JASS:
library DamageoverInterval /*
Created by userid907
*/requires SpeedChange,/* to manage buff-with DoT
Constructor :
static method create takes unit source,unit target, real damage, real duration, real interval, integer buffid,attacktype atk returns thistype
- source is damaging unit, and target is damaged unit, damage is total damage dealed, interval is interval between damage,
buffid is buff id of the DoT but you can make it with no buff too, atk is the attacktype of damage dealed
Destructor :
method terminate takes nothing returns nothing
- finish the DoT instantly or set the duration to 0.
Available member for your own use :
unit source
unit target
real duration
real interval
real damage
integer buffid
real counter
attacktype atk
*/
// CONFIGURATION
globals
private constant player DUMMYOWNER = Player( 15 ) // the owner of DUMMYID unit
private constant real FPS = 0.0312500 // higher value = worth fps, weird effect move, lower value = worst fps, great effect move
private constant boolean TESTMODE = false // IF TRUE THE DEBUG MESSAGE WILL COME OUT
private constant boolean TESTMODELOOP = false
private hashtable ht
endglobals
// ENDCONFIGURATION
struct DoT
unit source
unit target
real duration
real interval
real damage
integer buffid
real counter
attacktype atk
private real actduration
private static integer dindex
private static timer period
private static thistype array datas
method destroy takes nothing returns nothing
//Wash leaks
call EndSpeedModifById( .target, .buffid )
set .target = null
set .atk = null
set .source = null
call RemoveSavedHandle(ht,this,1)
call RemoveSavedInteger(ht,this,2)
call RemoveSavedHandle(ht,this,0)
if dindex == -1 then
call PauseTimer( period )
endif
call this.deallocate( )
endmethod
method terminate takes nothing returns nothing
set this.duration = 0.
endmethod
static method getSourceFromData takes integer rdata returns unit
if LoadUnitHandle(ht,0,rdata) != null then
return LoadUnitHandle(ht,0,rdata)
endif
debug call BJDebugMsg(SCOPE_PREFIX + " : getUnitFromData returned null")
return null
endmethod
static method getTargetFromData takes integer rdata returns unit
if LoadUnitHandle(ht,1,rdata) != null then
return LoadUnitHandle(ht,1,rdata)
endif
debug call BJDebugMsg(SCOPE_PREFIX + " : getUnitFromData returned null")
return null
endmethod
static method getDataFromUnit takes unit un returns thistype
return LoadInteger(ht,2,???) // don't know :(
endmethod
static method isDataAttachedToUnit takes unit t,integer data returns boolean
local thistype this = data
return t == this.source or t == this.target
endmethod
static method create takes unit source,unit target, real damage, real duration, real interval, integer buffid,attacktype atk returns thistype
local thistype this
set this = thistype.allocate( )
set .atk = atk
set .source = source
set .target = target
if HaveSavedInteger(ht,0,this) or HaveSavedHandle(ht,1,this) or HaveSavedInteger(ht,2,this) then
call RemoveSavedInteger(ht,2,this)
call RemoveSavedHandle(ht,0,this)
call RemoveSavedHandle(ht,1,this)
endif
call SaveUnitHandle(ht,0,this,.source)
call SaveUnitHandle(ht,1,this,.target)
call SaveInteger(ht,2,this,this)
call BJDebugMsg(GetUnitName(LoadUnitHandle(ht,0,this)))
call BJDebugMsg(GetUnitName(LoadUnitHandle(ht,1,this)))
call BJDebugMsg(I2S(LoadInteger(ht,2,this)))
set .duration = duration
set .interval = interval
set .damage = damage
set .buffid = buffid
set .actduration = .duration
set .counter = .interval
call ChangeUnitSpeed2( .target, 1.0 , .duration , false , buffid, false )
if TESTMODE then
call BJDebugMsg( "Created DoT on : " + GetUnitName( target ) + " With : " + R2S( damage ) + " damage " + R2S( interval ) + " interval " + R2S( .damage / ( .actduration / .interval ) ) + " damage per interval and " + I2S( buffid ) + " as buffid" )
endif
set dindex = dindex + 1
set datas[dindex] = this
if dindex == 0 then
call TimerStart( period, FPS, true, function thistype.periodic )
endif
return this
endmethod
static method periodic takes nothing returns nothing
local integer i = 0
local thistype this
loop
exitwhen i > dindex
set this = datas[i]
if .counter <= 0. then
set .counter = .interval
call BJDebugMsg("this : " +I2S(this))
call BJDebugMsg("gdfu : " +I2S(DoT.getDataFromUnit(.source)))
call BJDebugMsg("getSourceFromData : " +GetUnitName(DoT.getSourceFromData(DoT.getDataFromUnit(.source))))
call BJDebugMsg("getTargetFromData : " +GetUnitName(DoT.getTargetFromData(DoT.getDataFromUnit(.target))))
if TESTMODE then
call BJDebugMsg("reached counter 0")
endif
if .damage > 0 then
call UnitDamageTarget(.source,.target,.damage / ( .actduration / .interval ),true,false,.atk,DAMAGE_TYPE_NORMAL,WEAPON_TYPE_WHOKNOWS)
if TESTMODE then
call BJDebugMsg("damage > 0")
endif
else
call SetUnitState(.target,UNIT_STATE_LIFE,GetUnitState(.target,UNIT_STATE_LIFE) + (.damage / ( .actduration / .interval )*-1))
if TESTMODE then
call BJDebugMsg("damage < 0")
endif
endif
else
set .counter = .counter - FPS
endif
if TESTMODELOOP then
call BJDebugMsg(".counter = " + R2S(.counter) + " .duration = " + R2S(.duration))
endif
set .duration = .duration - FPS
if .duration <= 0 then
set datas[i] = datas[dindex]
set i = i - 1
set dindex = dindex - 1
call this.destroy( )
endif
set i = i + 1
endloop
endmethod
static method onInit takes nothing returns nothing
set dindex = -1
set period = CreateTimer( )
set ht = InitHashtable()
endmethod
endstruct
endlibrary
i know getDataFromUnit() will return not exact value when the unit is affected with 2 or more DoT.
but i know how to solve it
Last edited: