Jump to content
EleTD.com
Sign in to follow this  
Guest cohadar

Upgrading OnDamage system

Recommended Posts

Guest cohadar

Hi there peoplez.

I was asked by Karawasa to make a more optimized version of onDamage system for EleTD.

EleTD is currently using old emjlr3's Damage Detection engine.

I will for starters make a more optimized version of that engine.

When that version in implemented in EleTD we can proceed for further optimizations.

What are further optimizations?

Well it is like this: I can optimize generic onDamage system only to a limited amount, but to get it to full potential changing some other EleTD code would be needed.

For example: current system registers damage events for units that enter the map, this is bad because you don't really need damage events for all units that enter the map.

You don't need it for towers and you don't need it for dummy units,

and unit enters region event is also adding to lag.

So solution for this would be to register damage events when units are spawned, so this would require modifying spawn trigger.

Also optimizing spells that use damage engine by using triggerconditions instead of registering function names as strings.

But we will talk about that when we get there.

See ya tomorrow.

Share this post


Link to post
Guest cohadar

lol, tnx.

Replacing OnDamage system is a dangerous job, especially because it is vitally important to game armor/damage types.

Beta testing needs to be extremely detailed, I hope you are up to it.

Share this post


Link to post
Guest Sancdar

Man, a good OnDamage system would be beneficial to a ton of custom maps. Without one, any decently sized map just chokes as you start adding neat custom abilities.

Share this post


Link to post
Guest emjlr3

the lag has nothing to do with the number of triggers, the units its registering for, or the units it is not

the only thing you can do to make it noticeably better is to have less functions run, period, this whole less triggers, not using GC for the one thing that I do, is not going to make any different, period

how my method is old, I don't understand, as far as DDS's go, its the only way I have every seen them done, and how

Also optimizing spells that use damage engine by using triggerconditions instead of registering function names as strings.

will do anything, I have no idea, and why executefunc would be any slower then this is odd to me....

the only reason its slow is that for every unit who is damaged, it has to run all OnDamage triggers, coming up with a different method for that is the only thing that will make any difference, period

Man, a good OnDamage system would be beneficial to a ton of custom maps. Without one, any decently sized map just chokes as you start adding neat custom abilities.

guess you never heard of DotA

Share this post


Link to post
Guest Sancdar
the only reason its slow is that for every unit who is damaged, it has to run all OnDamage triggers, coming up with a different method for that is the only thing that will make any difference, period

Man, a good OnDamage system would be beneficial to a ton of custom maps. Without one, any decently sized map just chokes as you start adding neat custom abilities.

guess you never heard of DotA

I thought that was what he was talking about.

As for DotA, it doesn't count as much as you think because it doesn't have that many units on the map at once, most TDs outstrip it. A better comparison would be EotA, and I think they were running into problems in this area.

Share this post


Link to post
Guest cohadar
the only thing you can do to make it noticeably better is to have less functions run, period, this whole less triggers, not using GC for the one thing that I do, is not going to make any different, period

It will make a small difference, but small differences multiply with increase of unit numbers. And using UnitUserData over GC is like 10 times faster

how my method is old, I don't understand, as far as DDS's go, its the only way I have every seen them done, and how

There is always a better way.

That is why systems have versions.

>>Also optimizing spells that use damage engine by using triggerconditions instead of registering function names as strings.

will do anything, I have no idea, and why executefunc would be any slower then this is odd to me....

It is slower because jass virtual machine has to do hashing from string function name to function handle, the more functions are in map this hashing is slower.

When you use action handles directly you avoid that overhead

So basically instead of this:

public function Attacks takes string funcName returns nothing
    //used for attack damage
    set AttackCount = AttackCount + 1
  
    set AttackFunction[AttackCount] = funcName
endfunction

we will be using this:

public function Attacks takes code funcName returns nothing
    //used for attack damage
    call TriggerAddAction(Attack_trig, funcName)
endfunction

This will not only save that unnecessary function name hashing but will replace jass looping with native looping inside trigger.

the only reason its slow is that for every unit who is damaged, it has to run all OnDamage triggers, coming up with a different method for that is the only thing that will make any difference, period

Almost true, I agree that it would be better if there is direct unit-type -> damage function hashing, that would save a LOT of speed,

but it requires to change ALL spells that currently use damage system.

I decided to optimize what we currently have before I make such a drastic step in changing how damage is handled in entire map.

Like I said those few "small speed" improvements multiply with unit number and difference will be noticeable enough.

I expected you to have more faith in me emjlr3 ...

--------------------

progress report:

* PUI installed in map, all triggers that were using UnitUserData directly converted to use PUI.

(PUI can be used from GUI btw, lolz)

* Done a first set of optimization on attack system - replaced gamecache with PUI

* fixed a bug - attack system was not working for preplaced units,

(witch noone noticed because there are no preplaced units that use it in EleTD)

* Small improvements on some triggers.

--------------------

Map was shortly debugged by Karawasa and me, it was working ok.

Second set of optimization is scheduled for later this day.

Share this post


Link to post

Hi and first of all welcome to the forum cohadar.

Also optimizing spells that use damage engine by using triggerconditions instead of registering function names as strings.

Is that onDamage system going to make it possible that skill/ability-damage will be affected by armor type of the attacked unit and the game difficulty?

(Maybe this point is already solved, I dont remember right now, but I remember that most skills of 3.0 where armor ignoring and didnt take into consideration the game difficulties armor increase)

Share this post


Link to post
Is that onDamage system going to make it possible that skill/ability-damage will be affected by armor type of the attacked unit and the game difficulty?

(Maybe this point is already solved, I dont remember right now, but I remember that most skills of 3.0 where armor ignoring and didnt take into consideration the game difficulties armor increase)

All of the triggered spells that do damage (i.e. any spell that isn't from WarCraft 3 ladder) is affected by armor and armor type. So yes, that problem has been solved for the most part. There are a total of 6 towers that ignore armor in 4.0 currently (beta5), and I intend to reduce this number to 3.

Moved to Programmer's Corner

Share this post


Link to post
Guest cohadar
Is that onDamage system going to make it possible that skill/ability-damage will be affected by armor type of the attacked unit and the game difficulty?

It was possible before, it will only be more easier now.

Share this post


Link to post
Guest emjlr3
And using UnitUserData over GC is like 10 times faster

i dont know about 10, maybe 2 or 3, and if that is a different of, say, 1/1000th of a second, whenever a unit dies or enters the map

units enter map every .35s/player

so say 10 every .35s, which will save us 1/100th of a sec in game every second when units are spawned, and that is giving it a little, noticeable....doubtful

and units die a good bit slower then that, no doubt

fixed a bug - attack system was not working for preplaced units,

it was written for Ele TD, preplaced unit attack detection is uneeded

as far as adding triggeractions, you will either need to have 1 trigger for spell damage and another for physical, or edit all onDamage triggers to detect in themselves the physical or magical damage, as well as to make sure the damage taken is greater then .01 or so

It was possible before, it will only be more easier now.

how so?

Share this post


Link to post
Guest 1mpulse

i dont really understand why anything needs to be changed..... but thats just me :)

Share this post


Link to post
Guest emjlr3

apparently on Karawasa's crap computer at his parents house, it gets laggy for him

so he figures, if it lags for him, it may lag for someone else somewhere

Share this post


Link to post
Guest cohadar

No need to be negative emjlr3.

Here a figured a way how to make direct unit -> onDamage function calls to avoid calling all registered functions.

public function Attacks takes integer index, string funcName returns nothing
    if  AttackFunction[index] != null then
        call BJDebugMsg("Error: Damage functions " + funcName + " and " + AttackFunction[index] + " have same index - " + I2S(index))
    else
        set AttackFunction[index] = funcName
    endif
endfunction

private function Damaged takes nothing returns boolean
    local integer index
    
    if Enabled then
        set U = GetTriggerUnit()
        if GetEventDamage()>.1 then  
            set index = PUI_DamageIndex[GetUnitUserData(U)]
            if GetUnitAbilityLevel(U, BUFF_ORB) > 0 then    
                call UnitRemoveAbility(U, BUFF_ORB)  
                call ExecuteFunc(AttackFunction[index])
            else      
                call ExecuteFunc(SpellFunction[index])
            endif
        endif
    endif
    
    return false
endfunction

Share this post


Link to post

It lags on my machine too. The creeps don't come out in a straight line, they stutter on spawning or take a break on the road.. :)

Share this post


Link to post
Guest emjlr3

I rewrote the spawning and units enter spawn region triggers, that should be resolved through them, hopefully ^^

Share this post


Link to post
Guest cohadar
I rewrote the spawning and units enter spawn region triggers, that should be resolved through them, hopefully ^^

Yeah I was wondering if that was the case.

Could you post new spawn triggers here?

Share this post


Link to post
Guest emjlr3

Karawasa may have edited them a bit, but these are what I gave him, keep in mind, if you have the map, they should be in it under the catagory Level

function Trig_Spawn_Conditions takes nothing returns boolean
    return IsUnitType(GetTriggerUnit(), UNIT_TYPE_HERO) == false and GetUnitTypeId(GetTriggerUnit()) != 'u000'
endfunction

function Trig_Spawn_Actions takes nothing returns nothing
    local unit u = GetTriggerUnit()
    local integer i = 0
    
    if GetUnitTypeId(u) == 'n00K' or GetUnitTypeId(u) == 'n00J' or GetUnitTypeId(u) == 'n023' or GetUnitTypeId(u) == 'n024' then
        call KillUnit(u)
        call RemoveUnit( u )
    endif
    
    loop
        exitwhen i > 7
        if RectContainsUnit(udg_Region_Spawn[i], u) == true then
            call SetUnitInvulnerable( u, true )
            call SetUnitAbilityLevel(u,'A00V',udg_Difficulty[i])
            call SetUnitAbilityLevel(u,'A01R',udg_Level)
            
            if udg_Extreme_Mode_On == true then
                call UnitAddAbility(u,'A03N')
                call UnitAddAbility(u,'A00I')
            endif
            
            if IsUnitType(GetTriggerUnit(), UNIT_TYPE_UNDEAD) == true then
                call TriggerRegisterUnitLifeEvent( gg_trg_Undead_Reincarnate, u, LESS_THAN_OR_EQUAL, 0.00 )
            endif
            
            if IsUnitType(GetTriggerUnit(), UNIT_TYPE_MECHANICAL) == true then
                call TriggerRegisterUnitManaEvent( gg_trg_Mechanical_Activate, u, GREATER_THAN_OR_EQUAL, 12.00 )
                call SetUnitState(u,UNIT_STATE_MANA,GetRandomReal(0.,12.))
            endif
            
            set udg_Temp_Point = GetRectCenter(udg_Region_Leak[i])
            call IssuePointOrderLoc(u,"move",udg_Temp_Point)
            call RemoveLocation(udg_Temp_Point)                
        endif
        
        set i = i + 1
    endloop
    
    call PolledWait2( 1.00 )
    call SetUnitInvulnerable( u, false )
    
    set u = null
endfunction

//===========================================================================
function InitTrig_Spawn takes nothing returns nothing
    set gg_trg_Spawn = CreateTrigger(  )
    call TriggerRegisterEnterRectSimple( gg_trg_Spawn, gg_rct_Spawn_Red )
    call TriggerRegisterEnterRectSimple( gg_trg_Spawn, gg_rct_Spawn_Blue )
    call TriggerRegisterEnterRectSimple( gg_trg_Spawn, gg_rct_Spawn_Green )
    call TriggerRegisterEnterRectSimple( gg_trg_Spawn, gg_rct_Spawn_Orange )
    call TriggerRegisterEnterRectSimple( gg_trg_Spawn, gg_rct_Spawn_Pink )
    call TriggerRegisterEnterRectSimple( gg_trg_Spawn, gg_rct_Spawn_Purple )
    call TriggerRegisterEnterRectSimple( gg_trg_Spawn, gg_rct_Spawn_Teal )
    call TriggerRegisterEnterRectSimple( gg_trg_Spawn, gg_rct_Spawn_Yellow )
    call TriggerAddCondition( gg_trg_Spawn, Condition( function Trig_Spawn_Conditions ) )
    call TriggerAddAction( gg_trg_Spawn, function Trig_Spawn_Actions )
endfunction

function Trig_Start_Level_Func004Func003Func003002001002 takes nothing returns boolean
    return GetUnitUserData(GetFilterUnit()) == GetConvertedPlayerId(GetEnumPlayer()) and not IsUnitType(GetFilterUnit(), UNIT_TYPE_ANCIENT) and GetWidgetLife(GetFilterUnit())>.405
endfunction
function Trig_Start_Level_Func004Func002002001 takes nothing returns boolean
    return ( udg_Player_Lives[GetPlayerId(GetFilterPlayer())] > 0 )
endfunction
function Trig_Start_Level_Func004Func003A takes nothing returns nothing
    local integer id = GetPlayerId(GetEnumPlayer())
    local group g = CreateGroup()
    
    set udg_Level_Name = GetObjectName(udg_Spawns[udg_Level - 1])
    call DisplayTimedTextToPlayer( GetEnumPlayer(),0.,0., 5.00, ( "Level " + ( I2S(udg_Level) + ( ": " + ( udg_Level_Name + ( " " + ( udg_Extra + ( " - " + ( I2S(( 15 + ( ( udg_Difficulty[id] + 0 ) * 3 ) )) + " spawns" ) ) ) ) ) ) ) ) )

    call GroupEnumUnitsOfPlayer(g,ConvertedPlayer( ( id  / 2 ) + 9 ),Condition(function Trig_Start_Level_Func004Func003Func003002001002))
    set udg_Creeps_Left[id] = CountUnitsInGroup(g)
    set udg_Creeps_Left[id] = udg_Creeps_Left[id]+(15+(udg_Difficulty[id]*3))
    
    call DestroyGroup(g)
    set g = null
endfunction

function Trig_Start_Level_Func005Func004Func002002001 takes nothing returns boolean
    return ( udg_Player_Lives[GetPlayerId(GetFilterPlayer())] > 0 )
endfunction
function Trig_Start_Level_Func005Func004Func003A takes nothing returns nothing
    local integer id = GetPlayerId(GetEnumPlayer())
    local unit u
    local real hp
    
    if udg_Spawn_Loop > 15 - (udg_Difficulty[id] * 3) then
        set udg_Temp_Point = GetRectCenter(udg_Region_Spawn[id])
        set u = CreateUnitAtLoc(ConvertedPlayer( ( id  / 2 ) + 9 ),'n00I',udg_Temp_Point,270.)
        call RemoveLocation(udg_Temp_Point)
        call SetUnitUserData( u, GetConvertedPlayerId(GetEnumPlayer()) )
        set hp = (udg_Difficulty[id]*.125)+.50
        call SetWidgetLife(u,GetUnitState(u,UNIT_STATE_MAX_LIFE)*hp)
        
        set u = null
    endif
endfunction
function Start_Level_Ronalds takes nothing returns nothing
    set udg_Spawn_Loop = udg_Spawn_Loop + 1
    if udg_Spawn_Loop>30. then
        call EndTimer(GetExpiredTimer())
        return
    endif
    
    set udg_Player_Group = GetPlayersMatching(Condition(function Trig_Start_Level_Func005Func004Func002002001))
    call ForForce( udg_Player_Group, function Trig_Start_Level_Func005Func004Func003A )
    call DestroyForce(udg_Player_Group)
endfunction

function Trig_Start_Level_Func005Func005Func002002001 takes nothing returns boolean
    return ( udg_Player_Lives[GetPlayerId(GetFilterPlayer())] > 0 )
endfunction
function Trig_Start_Level_Func005Func005Func003A takes nothing returns nothing
    local integer id = GetPlayerId(GetEnumPlayer())
    local unit u
    local real hp
    
    if udg_Spawn_Loop > 15 - (udg_Difficulty[id] * 3) then
        set udg_Temp_Point = GetRectCenter(udg_Region_Spawn[id])
        set u = CreateUnitAtLoc(ConvertedPlayer( ( id  / 2 ) + 9 ),udg_Spawns[udg_Level - 1],udg_Temp_Point,270.)
        call RemoveLocation(udg_Temp_Point)
        call SetUnitUserData( u, GetConvertedPlayerId(GetEnumPlayer()) )
        call UnitAddAbility(u,udg_Spawn_HP[udg_Level - 1])
        set hp = (udg_Difficulty[id]*.125)+.50
        call SetWidgetLife(u,GetUnitState(u,UNIT_STATE_MAX_LIFE)*hp)
        
        set u = null
    endif
endfunction
function Start_Level_Spawns takes nothing returns nothing
    set udg_Spawn_Loop = udg_Spawn_Loop + 1
    if udg_Spawn_Loop>30. then
        call EndTimer(GetExpiredTimer())
        return
    endif
    
    set udg_Player_Group = GetPlayersMatching(Condition(function Trig_Start_Level_Func005Func005Func002002001))
    call ForForce( udg_Player_Group, function Trig_Start_Level_Func005Func005Func003A )
    call DestroyForce(udg_Player_Group)
endfunction

function Trig_Start_Level_Actions takes nothing returns nothing
    local timer t
    
    set udg_Between_Levels = false
    set udg_Level =  udg_Level + 1
    set udg_Extra = ( "(" + ( udg_Level_Desc[( udg_Level - 1 )] + ")" ) )
    
    if udg_Level < 61 then
        set udg_Player_Group = GetPlayersMatching(Condition(function Trig_Start_Level_Func004Func002002001))
        call ForForce( udg_Player_Group, function Trig_Start_Level_Func004Func003A )
        call DestroyForce(udg_Player_Group)
    endif
    
    if udg_Level < 61 then
        set udg_Spawn_Loop = 1
        set t = GetTimer()
        call TimerStart(t,.35,true,function Start_Level_Spawns)
    else
        call DisplayTextToForce( bj_FORCE_ALL_PLAYERS, "The Ronald round starts now. Good luck!" )
        call TriggerExecute( gg_trg_Create_Leaderboard )
        call PauseTimer(udg_Income_Timer)
        set udg_Spawn_Loop = 1
        set t = GetTimer()
        call TimerStart(t,.35,true,function Start_Level_Ronalds)
    endif
endfunction

//===========================================================================
function InitTrig_Start_Level takes nothing returns nothing
    set gg_trg_Start_Level = CreateTrigger(  )
    call TriggerRegisterTimerExpireEventBJ( gg_trg_Start_Level, udg_Between_Levels_Timer )
    call TriggerAddAction( gg_trg_Start_Level, function Trig_Start_Level_Actions )
endfunction

Start Level is a bit confusing, it was though for me too, ROFL

Share this post


Link to post
Guest cohadar

How about now?

scope StartLevel

globals
    private constant integer UID_RONALD = 'n00I'
    
    private constant real SPAWN_PERIOD = 0.4
endglobals


//===========================================================================
function CreepFilter takes nothing returns boolean
    return udg_CreepOwner[GetUnitUserData(GetFilterUnit())] == GetEnumPlayer() and IsUnitType(GetFilterUnit(), UNIT_TYPE_ANCIENT) == false and IsUnitAliveBJ(GetFilterUnit()) == true
endfunction


//===========================================================================
function CountCreeps takes nothing returns nothing
    local integer id = GetPlayerId(GetEnumPlayer())
    local group g = CreateGroup()
  
    set udg_Level_Name = GetObjectName(udg_Spawns[udg_Level - 1])
    call DisplayTimedTextToPlayer( GetEnumPlayer(),0.,0., 5.00, ( "Level " + ( I2S(udg_Level) + ( ": " + ( udg_Level_Name + ( " " + ( udg_Extra + ( " - " + ( I2S(30) + " Spawns" ) ) ) ) ) ) ) ) )

    call GroupEnumUnitsOfPlayer(g,ConvertedPlayer( ( id  / 2 ) + 9 ),Condition(function CreepFilter))
    set udg_Creeps_Left[id] = CountUnitsInGroup(g)
    set udg_Creeps_Left[id] = udg_Creeps_Left[id]+(30)
  
    call DestroyGroup(g)
    set g = null
endfunction


//===========================================================================
function AlivePlayerFilter takes nothing returns boolean
    return ( udg_Player_Lives[GetPlayerId(GetFilterPlayer())] > 0 )
endfunction

//===========================================================================
function SpawnRonald takes nothing returns nothing
    local integer id = GetPlayerId(GetEnumPlayer())
    local unit u
    local real hp
  
    if udg_Spawn_Loop > 0 then
        set udg_Temp_Point = GetRectCenter(udg_Region_Spawn[id])
        set u = CreateUnitAtLoc(ConvertedPlayer( ( id  / 2 ) + 9 ),UID_RONALD,udg_Temp_Point,270.)
        call RemoveLocation(udg_Temp_Point)
        //call SetUnitUserData( u, GetConvertedPlayerId(GetEnumPlayer()) )
        set udg_CreepOwner[GetUnitIndex(u)] = GetEnumPlayer()
        set hp = ((udg_Difficulty[id]-1)*.125)+.50
        call SetWidgetLife(u,GetUnitState(u,UNIT_STATE_MAX_LIFE)*hp)
      
        set u = null
    endif
endfunction

//===========================================================================
function Start_Level_Ronalds takes nothing returns nothing
    set udg_Spawn_Loop = udg_Spawn_Loop + 1
    if udg_Spawn_Loop>31. then
        call EndTimer(GetExpiredTimer())
        return
    endif
  
    set udg_Player_Group = GetPlayersMatching(Condition(function AlivePlayerFilter))
    call ForForce( udg_Player_Group, function SpawnRonald )
    call DestroyForce(udg_Player_Group)
endfunction


//===========================================================================
function SpawnCreep takes nothing returns nothing
    local integer id = GetPlayerId(GetEnumPlayer())
    local unit u
    local real hp
  
    if udg_Spawn_Loop > 0 then
        set udg_Temp_Point = GetRectCenter(udg_Region_Spawn[id])
        set u = CreateUnitAtLoc(ConvertedPlayer( ( id  / 2 ) + 9 ),udg_Spawns[udg_Level - 1],udg_Temp_Point,270.)
        call RemoveLocation(udg_Temp_Point)
        //call SetUnitUserData( u, GetConvertedPlayerId(GetEnumPlayer()) )
        set udg_CreepOwner[GetUnitIndex(u)] = GetEnumPlayer()
        call UnitAddAbility(u,udg_Spawn_HP[udg_Level - 1])
        set hp = ((udg_Difficulty[id]-1)*.125)+.50
        call SetWidgetLife(u,GetUnitState(u,UNIT_STATE_MAX_LIFE)*hp)
      
        set u = null
    endif
endfunction

//===========================================================================
function Start_Level_Spawns takes nothing returns nothing
    set udg_Spawn_Loop = udg_Spawn_Loop + 1
    if udg_Spawn_Loop>31. then
        call EndTimer(GetExpiredTimer())
        return
    endif
  
    set udg_Player_Group = GetPlayersMatching(Condition(function AlivePlayerFilter))
    call ForForce( udg_Player_Group, function SpawnCreep )
    call DestroyForce(udg_Player_Group)
endfunction

//===========================================================================
function Trig_Start_Level_Actions takes nothing returns nothing
    local timer t
  
    set udg_Between_Levels = false
    set udg_Level =  udg_Level + 1
    set udg_Extra = ( "(" + ( udg_Level_Desc[( udg_Level - 1 )] + ")" ) )
  
    if udg_Level < 61 then
        set udg_Player_Group = GetPlayersMatching(Condition(function AlivePlayerFilter))
        call ForForce( udg_Player_Group, function CountCreeps )
        call DestroyForce(udg_Player_Group)
    endif
  
    if udg_Level < 61 then
        set udg_Spawn_Loop = 1
        set t = GetTimer()
        call TimerStart(t,SPAWN_PERIOD,true,function Start_Level_Spawns)
    else
        call DisplayTextToForce( bj_FORCE_ALL_PLAYERS, "The Ronald round starts now. Good luck!" )
        call TriggerExecute( gg_trg_Create_Leaderboard )
        call PauseTimer(udg_Income_Timer)
        set udg_Spawn_Loop = 1
        set t = GetTimer()
        call TimerStart(t,SPAWN_PERIOD,true,function Start_Level_Ronalds)
    endif
endfunction

//===========================================================================
public function InitTrig takes nothing returns nothing
    local trigger trig = CreateTrigger()
    call TriggerRegisterTimerExpireEventBJ( trig, udg_Between_Levels_Timer )
    call TriggerAddAction( trig, function Trig_Start_Level_Actions )
endfunction

endscope

Share this post


Link to post

I can feel a disturbance in the force, like two coders working on the same project.. :)

Share this post


Link to post
Guest cohadar

PROGRESS REPORT:

IT WORKS !!!!

Observe the beauty of new Damage Trigger handler

private function Damaged takes nothing returns boolean
    local integer i
    
    if Enabled then
        set U = GetTriggerUnit()
        if GetEventDamage()>.1 then  
        
            // functions that trigger for specific attack
            if GetUnitAbilityLevel(U, BUFF_ORB) > 0 then    
                call UnitRemoveAbility(U, BUFF_ORB)
                set i = PUI_AttackIndex[GetUnitUserData(GetEventDamageSource())]
                if i != 0 then
                    debug call BJDebugMsg(AttackFunction[i])
                    call ExecuteFunc(AttackFunction[i])
                else
                    debug call BJDebugMsg("ERROR: PUI_AttackIndex not registered for tower: " + GetUnitName(GetEventDamageSource()))
                endif
            endif
            
            call TriggerExecute(OnDamage_trig)

        endif
    endif
    
    return false
endfunction

BEFORE/NOW:

Before sys used to add Orb ability to ALL towers.

Now it is only added to towers that actually use Damage sys

Before all 11 damage abilities were executed when unit was damaged

and each ability had to check if it is the right one to run

Now system knows exactly witch function to call so only one function will be executed

Before there was no difference between damage triggers

Now there are separate functions for registering attacks (used by 25 towers/11 abilities)

and for registering actions that need to be run for every damage event. (currently used only by penitence)

STATUS:

Currently only 6 towers are "plugged in" into new system

Death,Doom,Damnation - Sporadic Damage

Flame,Solar,Sun - Penitence

19 towers to go.

Plugging is done like this:

    if id == TOWER_FLAME or id == TOWER_SOLAR or id == TOWER_SUN then 
        set PUI_AttackIndex[GetUnitIndex(U)] = PENITENCE
        if GetUnitAbilityLevel(U, AID_ORB) <= 0 then
            call UnitAddAbility(U, AID_ORB)
            call UnitMakeAbilityPermanent(U,true,AID_ORB)
        endif        
    endif

PS: Karawasa complete those tower codes ffs.

Share this post


Link to post
PS: Karawasa complete those tower codes ffs.

You will have it tomorrow. Do note that I am at work tomorrow until the afternoon.

Share this post


Link to post
Guest emjlr3

will be interested to see the final product, and the fps gain

if I am not mistaken, Kara you said it ran at 34 fps before or something?

still do not quite understand what you are doing there

on another note, the new Dialog system has been incorporated into the map for testing, works fairly well, but there are still a few kinks to work out, but once its done, this shall be a huge advancement for the map

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×
×
  • Create New...