| 11-15-2008, 10:11 PM | #1 |
I am trying to find a damage over time system for my map and I would need some help cuz I haven't find anything yet . If it is possible ,it may also check is the unit has a specific buff to do the damage . |
| 11-16-2008, 12:01 AM | #2 |
JASS://=============================================================== //Rejuvenation Callback Timer //=============================================================== function Rejuvinate_Tick takes nothing returns nothing local timer T = GetExpiredTimer() local Rejuvinate Rejuv = GetTimerData(T) local integer BonusHeal = 0 set Rejuv.CurrentTick = Rejuv.CurrentTick + 1 set Rejuv.CurrentDuration = Rejuv.CurrentDuration + 1 if Rejuv.CurrentTick == R2I(Rejuv.Tick/INTERVAL) then if UnitHasBuffBJ(Rejuv.Target,'B000') == true then call SetUnitLifeBJ( Rejuv.Target, GetUnitStateSwap(UNIT_STATE_LIFE, Rejuv.Target) + (Rejuv.HealPerTick+BonusHeal)) call CreateTextTagUnitBJ( "+" + I2S(Rejuv.HealPerTick+BonusHeal), Rejuv.Target, 0, 12, 0.00, 100, 0.00, 0 ) call SetTextTagPermanentBJ( GetLastCreatedTextTag(), false ) call SetTextTagLifespanBJ( GetLastCreatedTextTag(), 3.00 ) call SetTextTagFadepointBJ( GetLastCreatedTextTag(), 1.50 ) call SetTextTagVelocityBJ( GetLastCreatedTextTag(), 32.00, 90 ) set Rejuv.CurrentTick = 0 else //call BJDebugMsg("Debuffed") call Rejuv.destroy() call ReleaseTimer(T) endif if Rejuv.CurrentDuration >= R2I(Rejuv.Duration/INTERVAL) then //call DisplayTextToForce(GetPlayersAll(),"Done " +I2S(Rejuv)) call UnitRemoveBuffBJ( 'B000', Rejuv.Target ) call Rejuv.destroy() call ReleaseTimer(T) endif endif endfunction //=============================================================== //Spell Cast Actions //=============================================================== function Trig_Cast_Actions takes nothing returns nothing local unit Caster = GetTriggerUnit() local unit Target = GetSpellTargetUnit() local timer T = NewTimer() local Rejuvinate Rejuv //Is Spell cast Rejuvinate==================================== if GetSpellAbilityId() == 'A001' then //Check if the unit already has the buff== if UnitHasBuffBJ(Target,'B000') == false then set Rejuv = Rejuvinate.create() set Rejuv.Caster = Caster set Rejuv.Target = Target call SetTimerData(T,Rejuv) //call DisplayTextToForce(GetPlayersAll(),"starting " +I2S(Rejuv)) call TimerStart(T,INTERVAL,true,function Rejuvinate_Tick) set T = null else //If so then do nothing=================== return endif endif //===============================================ENDRejuvinate endfunction //=========================================================================== function InitTrig_Cast takes nothing returns nothing set gg_trg_Cast = CreateTrigger( ) call TriggerRegisterAnyUnitEventBJ( gg_trg_Cast, EVENT_PLAYER_UNIT_SPELL_CAST ) call TriggerAddAction( gg_trg_Cast, function Trig_Cast_Actions ) endfunction Here is a Heal over Time setup I made, I'm sure you can convert it to damage real easy :) It's not the best, but it works. |
| 11-16-2008, 06:44 AM | #3 |
Good idea ,I'll use that to create a general DoT system. That INTERVAL is supposed to be a real like how often to heal ,right? |
| 11-16-2008, 10:02 AM | #4 |
JASS:globals constant real INTERVAL = .04 //Interval of the spell timer. endglobals struct Rejuvinate integer Tick = 2 //How many seconds do you want the unit to be healed. integer CurrentTick = 0 integer HealPerTick = 40 //Damage healed per tick. integer CurrentDuration = 0 integer Duration = 15 //Duration of the spell in seconds. boolean AddHeroIntToHeal = true //If you want to add the heroes Int to the HealPerTick set to true, false to turn off. unit Target unit Caster endstruct Interval is the timer delay, you define how often to heal with, integer Tick = 2 |
| 11-16-2008, 07:40 PM | #5 |
I've made a DoT system from what you told me but i have problems with detecting the buff . I'm using this < UnitHasBuffBJ (dat.u ,dat.Buff) > dat.u is the targeted unit and dat.Buff is the buff specified by the function .The problem is that it doesn't detect my buff or maybe dat.Buff is the problem ... The function looks like this : JASS:struct data unit caster unit target ..... integer Buff .... endstruct function DamageUnit takes nothing returns nothing local timer t = GetExpiredTimer() local data dat = GetTimerData(t) ............ if UnitHasBuffBJ (dat.u ,dat.Buff) == false or <if the target is dead>then call dat.destroy() call ReleaseTimer(t) else <something that damages the target> endif set t = null endfunction function DamageOverTime takes unit caster ,unit target,real damage .... integer Buff ...returns nothing local timer t = NewTimer() local data dat ..... set dat.Buff = Buff ....... call TimerStart(t,howoften,true,function DamageUnit) set t = null endfunction |
| 11-17-2008, 02:46 AM | #6 |
You're not setting the timer data, with the struct instance, so it's reading a null buff. Ya need to do JASS:call SetTimerData(t,dat) |
| 11-17-2008, 04:48 AM | #7 |
I was setting the data but I didn't write that . Still not working . I got to think of something else ... |
| 11-18-2008, 01:44 AM | #8 |
Just copy your whole trigger and I'll see whats wrong with it. |
| 11-18-2008, 05:47 AM | #9 |
Ok this is the code and it requires CSData and CSSafety : JASS:library DamageTargetOverTime uses CSSafety private struct data unit c unit u timer t real dmg boolean attack boolean ranged damagetype DamageType attacktype AttackType weapontype WeaponType real runned real duration real howoften integer Buff string Effect string where string stack effect e static method create takes unit c, unit u, real dmg, boolean attack, boolean ranged, attacktype AttackType, damagetype DamageType, weapontype WeaponType, real duration, real howoften, string stack,integer Buff, string Effect, string where returns data local data dat = data.allocate() local data d = GetCSData(u) if stack!=null and stack==d.stack then call data.destroy(d) endif set dat.t = NewTimer() set dat.u = u set dat.c = c set dat.dmg = dmg set dat.attack=attack set dat.ranged=ranged set dat.AttackType=AttackType set dat.DamageType=DamageType set dat.WeaponType=WeaponType set dat.duration = duration set dat.howoften=howoften set dat.Buff=Buff set dat.Effect=Effect set dat.where=where set dat.stack=stack set dat.runned=0 if (Effect!=null or Effect!="") and (where!=null or where!="") then set dat.e=AddSpecialEffectTarget(Effect,u,where) endif call SetCSData(dat.t,dat) call SetCSData(u,dat) return dat endmethod method onDestroy takes nothing returns nothing call DestroyEffect(.e) call ReleaseTimer(.t) endmethod endstruct private function Child takes nothing returns nothing local timer t = GetExpiredTimer() local data dat = GetCSData(t) set dat.runned=dat.runned+dat.howoften if dat.runned>=dat.duration or GetUnitState(dat.u,UNIT_STATE_LIFE)<=.405 or (dat.Buff!=0 and UnitHasBuffBJ(dat.u,dat.Buff)==false) then call data.destroy(dat) else call DestroyEffect(dat.e) set dat.e=AddSpecialEffectTarget(dat.Effect,dat.u,dat.where) call UnitDamageTarget(dat.c, dat.u, dat.dmg, dat.attack, dat.ranged, dat.AttackType, dat.DamageType, dat.WeaponType) endif set t = null endfunction function DamageOverBuff takes unit whichUnit, unit target, real amount, boolean attack, boolean ranged, attacktype AttackType, damagetype DamageType, weapontype WeaponType, real howoften,integer Buff,string stack, string Effect, string where returns nothing call TimerStart(data.create(whichUnit, target,amount,attack,ranged, AttackType, DamageType,WeaponType, 9999999, howoften,stack, Buff,Effect, where).t, howoften, true, function Child) endfunction function DamageOverTime takes unit whichUnit, unit target, real amount, boolean attack, boolean ranged, attacktype AttackType, damagetype DamageType, weapontype WeaponType, real duration, real howoften,string stack, string Effect, string where returns nothing call TimerStart(data.create(whichUnit, target,amount,attack,ranged, AttackType, DamageType,WeaponType, duration, howoften,stack,0, Effect, where).t, howoften, true, function Child) endfunction endlibrary |
| 11-18-2008, 06:36 AM | #10 |
The buff integer will be something like 'B000' or 'B001' go into your abilities module and press CTRL+D it'll have the buffcode. Try that out. |
| 11-18-2008, 09:05 AM | #11 |
....... thats a buff's raw code and to convert to integer you use 'raw' ... Those numbers are displayed when converting an integer like 'B00T' into a string ...but that doesn't matter . the function looks like this<call DamageOverBuff (caster,target,50(damage),ATTACK_TYPE_NORMAL,DAMAGE_TYPE_NORMAL,null(no weapon type),'B000'(this is a buff's code or id)....) > and with the struct dat.Buff should be 'B000' but this isn't an integer and thats why when converting a raw code into a string it displays those numbers . Now ,the raw code converted into an integer is a number and the dat.Buff is 0. I think there is something wrong with this ... |
