1. Updated Resource Submission Rules: All model & skin resource submissions must now include an in-game screenshot. This is to help speed up the moderation process and to show how the model and/or texture looks like from the in-game camera.
    Dismiss Notice
  2. DID YOU KNOW - That you can unlock new rank icons by posting on the forums or winning contests? Click here to customize your rank or read our User Rank Policy to see a list of ranks that you can unlock. Have you won a contest and still havn't received your rank award? Then please contact the administration.
    Dismiss Notice
  3. We have recently started the 16th edition of the Mini Mapping Contest. The theme is mini RPG. Do check it out and have fun.
    Dismiss Notice
  4. Dismiss Notice
  5. The Highway to Hell has been laid open. Come along and participate in the 5th Special Effect Contest.
    Dismiss Notice
  6. Check out the Staff job openings thread.
    Dismiss Notice
Dismiss Notice
60,000 passwords have been reset on July 8, 2019. If you cannot login, read this.

Blood rage problems

Discussion in 'Triggers & Scripts' started by Erkki2, Apr 27, 2016.

  1. Erkki2

    Erkki2

    Joined:
    Jun 6, 2007
    Messages:
    382
    Resources:
    7
    Skins:
    6
    Spells:
    1
    Resources:
    7
    Hello! I have 2 problems concerning my blood rage ability, description and triggers can be found here.

    1. Sometimes when the computer learns the ability, the bars aren't created. This doesn't happen when a player controlled hero learns blood rage. The issue can be seen in this replay.

    2. After some time, the game begins to get lag spikes. This only happens when there are computer controlled heroes with blood rage.

    I've been trying to solve these issues without any luck. Any help appreciated.
     
  2. Meatmuffin

    Meatmuffin

    Joined:
    Jul 25, 2014
    Messages:
    451
    Resources:
    9
    Maps:
    2
    Spells:
    7
    Resources:
    9
    Yea, the resource is not available.
     
  3. Erkki2

    Erkki2

    Joined:
    Jun 6, 2007
    Messages:
    382
    Resources:
    7
    Skins:
    6
    Spells:
    1
    Resources:
    7
    I assume you mean the replay? It can also be found in my pastebin.
     
  4. TriggerHappy

    TriggerHappy

    Code Moderator

    Joined:
    Jun 23, 2007
    Messages:
    3,683
    Resources:
    22
    Spells:
    11
    Tutorials:
    2
    JASS:
    9
    Resources:
    22
  5. IcemanBo

    IcemanBo

    Joined:
    Sep 6, 2013
    Messages:
    6,208
    Resources:
    22
    Maps:
    3
    Spells:
    11
    Template:
    1
    Tutorials:
    4
    JASS:
    3
    Resources:
    22
    The current status is probably rejected, so other people don't see it.
    But since you still work on it, mods could set it back to NeedsFix, if you ask.
     
  6. Erkki2

    Erkki2

    Joined:
    Jun 6, 2007
    Messages:
    382
    Resources:
    7
    Skins:
    6
    Spells:
    1
    Resources:
    7
    In that case, here's the description:
    description
    Description:
    Allows the hero to gain rage points when dealing damage or when nearby unit dies. Rage points will be used to reduce damage taken by the hero. If hero has enough rage points, he will also gain additional bonuses.

    Level 1 - Level 1 bonus (+10 damage) enabled at 250 rage points.
    Level 2 - Level 2 bonus (+3 hp regen) enabled at 500 rage points.
    Level 3 - Level 3 bonus (+50% attack rate) enabled at 750 rage points.

    and trigger:
    trigger
    Code (vJASS):
    //###########################################################################################################
    //# Blood Rage                                                                                              #
    //# Created by Erkki2                                                                                       #
    //# Required libraries:                                                                                     #
    //#     Unit Indexer by Bribe                                                                               #
    //#     Damage Engine by Bribe                                                                              #
    //#                                                                                                         #
    //# Import instructions:                                                                                    #
    //#     1. Copy the cheat death ability to your map and create an ability for Blood Rage                    #
    //#     2. Check "automatically create unknown variables while pasting trigger data" in map preferences     #
    //#     3. Copy this trigger and required libraries to your map                                             #
    //#     4. Set DamageBlockingAbility in Damage Engine trigger to the ability copied at 1                    #
    //#     5. Set configurables in this trigger                                                                #
    //#     6. To modify rage from in your own triggers, call addRage(unit, amount)                             #
    //###########################################################################################################

    scope BloodRage

    //  #################
    //  # CONFIGURABLES #
    //  #################
         globals
             
             //Raw code of the spell ability
             private constant integer ABIL_CODE = 'A000'
                   
             //Iteration interval
             private constant real TIMEOUT = 0.03125
             
             //How high above unit the bar is
             private constant real BAR_HEIGHT = 150.0
             
             //Maximum amount of rage
             private constant real MAX_RAGE = 1000.0
             
             //How many characters ("|") the bar has
             private constant integer BAR_WIDTH = 150
             
             //Setting this to smaller value will move the bar left, and higher value to tight
             private constant real LETTER_WIDTH = 0.4
             
             //Height of the bar
             private constant real BAR_FONT_SIZE = 0.015
             
             //Colour settings for the bar
             private constant integer BAR_RED = 255
             private constant integer BAR_GREEN = 0
             private constant integer BAR_BLUE = 0
             private constant integer BAR_ALPHA = 255
             private constant integer BAR_BACKGROUND_RED = 102
             private constant integer BAR_BACKGROUND_GREEN = 0
             private constant integer BAR_BACKGROUND_BLUE = 0
             private constant integer BAR_BACKGROUND_ALPHA = 255
             
             //Unit will gain (X * damage dealt) rage points when dealing damage
             private constant real ATTACK_RAGE_FACTOR = 0.3
             
             //Unit will gain X rage when an allied unit dies nearby
             private constant real ALLY_DEATH_RAGE_AMOUNT = 50
             
             //Unit will gain X rage when an enemy unit dies nearby
             private constant real ENEMY_DEATH_RAGE_AMOUNT = 30
             
             //Unit will gain rage points when a unit dies within this area
             private constant real RAGE_GAIN_AREA = 800
             
             //The speed at which rage depletes
             private constant real DEGENERATION_PER_SECOND = 30
             
             //If the unit has not gained rage in x seconds, it will begin to degenerate
             private constant real DEGENERATION_DELAY = 10.0
             
             //Damage blocked by rage
             private constant real DAMAGE_REDUCTION_FACTOR = 0.5
             
             //Rage lost per point of blocked damage
             private constant real RAGE_DRAIN_FACTOR = 1

         endglobals
         
         //Rage points required to gain level "level"
         private function levelRageAmount takes integer level returns real
             return level*250.0
         endfunction
         
         //Rage bonus ability for level "level"
         private function rageAbility takes integer level returns integer
             if level == 1 then
                 return 'A002'
             elseif level == 2 then
                 return 'A003'
             elseif level == 3 then
                 return 'A004'
             endif
             return 0
         endfunction
         
         //Level of rage bonus ability for level "level".
         private function rageBonusLevel takes integer level returns integer
             return 1
         endfunction

         //Rage doesn't deregenerate if current rage is below this amount
         private function degenerationTreshold takes unit u returns real
             return 100.0*GetUnitAbilityLevel(u, ABIL_CODE)
         endfunction
         
    //  ############################################################
    //  # CONFIGURABLES END, Don't touch anything after this line. #
    //  ############################################################

         private struct Spell
         
             private thistype next
             private thistype prev
             private static timer iterator = CreateTimer()
             private static integer count = 0
             
             private unit u
             private texttag rageBarTotal
             private texttag rageBarCurrent
             private real currentRage
             private integer rageLevel
             private real degenDelay
             
             private method destroy takes nothing returns nothing
                 call this.deallocate()
                 set this.next.prev = this.prev
                 set this.prev.next = this.next
                 call DestroyTextTag(this.rageBarCurrent)
                 call DestroyTextTag(this.rageBarTotal)
                 set this.rageBarCurrent = null
                 set this.rageBarTotal = null
                 set this.u = null
                 set count = count - 1
             endmethod
             
             private static method periodic takes nothing returns nothing
                 local thistype this = thistype(0).next
                 local real x
                 local real y
                 local string text
                 local integer i
                 local integer treshold
                 
                 loop
                     exitwhen this == 0
                     
                     //Set bar position to unit's position.
                     //Move bar to left so that its center is at the unit.
                     set x = GetUnitX(this.u) - BAR_WIDTH*LETTER_WIDTH
                     set y = GetUnitY(this.u)
                     
                     call SetTextTagPos(this.rageBarTotal, x, y, BAR_HEIGHT)
                     call SetTextTagPos(this.rageBarCurrent, x, y, BAR_HEIGHT)

                     //Set bar to match unit's current rage amount
                     set text = ""
                     set i = 0
                     set treshold = R2I(this.currentRage/MAX_RAGE*I2R(BAR_WIDTH))
                     loop
                         exitwhen i >= treshold
                         set text = text + "|"
                         set i = i + 1
                     endloop
                 
                     call SetTextTagText(this.rageBarCurrent, text, BAR_FONT_SIZE)
                     
                     //If unit is dead, hide the bar, and if unit is alive, show the bar
                     call SetTextTagVisibility(rageBarTotal, GetUnitState(this.u, UNIT_STATE_LIFE) > 0)
                     call SetTextTagVisibility(rageBarCurrent, GetUnitState(this.u, UNIT_STATE_LIFE) > 0)
                     
                     //If unit's rage level changes, add/remove bonuses accordingly
                     loop
                         if this.currentRage >= levelRageAmount(this.rageLevel + 1) /*
     */
                     and GetUnitAbilityLevel(this.u, ABIL_CODE) > this.rageLevel then
                             call UnitAddAbility(this.u, rageAbility(this.rageLevel + 1))
                             call SetUnitAbilityLevel(this.u, rageAbility(this.rageLevel + 1), rageBonusLevel(this.rageLevel))
                             set this.rageLevel = this.rageLevel + 1
                         elseif this.currentRage < levelRageAmount(this.rageLevel) then
                             call UnitRemoveAbility(this.u, rageAbility(this.rageLevel))
                             set this.rageLevel = this.rageLevel - 1
                         else
                             exitwhen true
                         endif
                     endloop
                     
                     //This unit hasn't gained rage in DEGENERATION_DELAY seconds
                     if this.degenDelay < TIMEOUT then
                         //Degenerate unit's rage
                         if this.currentRage - DEGENERATION_PER_SECOND > degenerationTreshold(this.u) then
                             set this.currentRage = this.currentRage - DEGENERATION_PER_SECOND*TIMEOUT
                         endif
                     else
                         set this.degenDelay = this.degenDelay - TIMEOUT
                     endif
                     
                     set this = this.next
                 
                 endloop
             
                 //if there are no spell instances running, pause the timer
                 if count == 0 then
                     call PauseTimer(iterator)
                 endif
                 
             endmethod

             //Registers a unit to have blood rage
             private static method registerUnit takes unit u returns nothing
                 local thistype this
                 local string text
                 local integer i

                 set this = thistype.allocate()
                 set this.next = 0
                 set this.prev = thistype(0).prev
                 set thistype(0).prev.next = this
                 set thistype(0).prev = this
                 set count = count + 1
                     
                 if count == 1 then
                     call TimerStart(iterator, TIMEOUT, true, function thistype.periodic)
                 endif
                 
                 set this.u = u
                 set this.currentRage = 0
                 set this.rageLevel = 0
                 set this.degenDelay = DEGENERATION_DELAY
                 
                 set text = ""
                 set i = 0
                 
                 loop
                     exitwhen i >= BAR_WIDTH
                     set text = text + "|"
                     set i = i + 1
                 endloop
                 
                 set this.rageBarCurrent = CreateTextTag()
                 call SetTextTagText(this.rageBarCurrent, "", BAR_FONT_SIZE)
                 call SetTextTagPos(this.rageBarCurrent, GetUnitX(this.u), GetUnitY(this.u), BAR_HEIGHT)
                 call SetTextTagColor(this.rageBarCurrent, BAR_RED, BAR_GREEN, BAR_BLUE, BAR_ALPHA)
                 
                 set this.rageBarTotal = CreateTextTag()
                 call SetTextTagText(this.rageBarTotal, text, BAR_FONT_SIZE)
                 call SetTextTagPos(this.rageBarTotal, GetUnitX(this.u), GetUnitY(this.u), BAR_HEIGHT)
                 call SetTextTagColor(this.rageBarTotal, BAR_BACKGROUND_RED, BAR_BACKGROUND_GREEN, BAR_BACKGROUND_BLUE, BAR_BACKGROUND_ALPHA)
             endmethod
             
             //Registers units that are indexed
             private static method registerUnitsIndexed takes nothing returns boolean
                 if GetUnitAbilityLevel(udg_UDexUnits[udg_UDex], ABIL_CODE) > 0 then
                     call thistype.registerUnit(udg_UDexUnits[udg_UDex])
                 endif
                 return false
             endmethod
             
             //Registers a hero that learns blood rage
             private static method registerLearningHero takes nothing returns boolean            
                 if GetUnitAbilityLevel(GetTriggerUnit(), ABIL_CODE) == 1 and (GetLearnedSkill() == ABIL_CODE) then
                     call thistype.registerUnit(GetTriggerUnit())
                 endif
                 return false
             endmethod
             
             //Unregisters a unit from blood rage
             private static method deindexUnit takes nothing returns boolean
                 local thistype this = thistype(0).next
                 loop
                     exitwhen this == 0
                     if GetUnitUserData(this.u) == 0 then
                         call this.destroy()
                         return false
                     endif
                     set this = this.next
                 endloop
                 return false
             endmethod
             
             //Changes unit's current rage by amount
             private method modifyRage takes real amount returns nothing
                 if this.currentRage + amount <= 0 then
                     set this.currentRage = 0
                 elseif currentRage + amount >= MAX_RAGE then
                     set this.currentRage = MAX_RAGE
                 else
                     set this.currentRage = this.currentRage + amount
                     if amount > 0 then
                         set this.degenDelay = DEGENERATION_DELAY
                     endif
                 endif
             endmethod
             
             //This function allows modifying rage from outside this trigger
             static method addRage takes unit u, real amount returns nothing
                 local thistype this = thistype(0).next
                 loop
                     exitwhen this == 0
                     if u == this.u then
                         call this.modifyRage(amount)
                         return
                     endif
                     set this = this.next
                 endloop
             endmethod
             
             //Adds rage when unit deals damage
             private static method addRageAttack takes nothing returns boolean
                 local thistype this = thistype(0).next
                 if not (GetUnitAbilityLevel(udg_DamageEventSource, ABIL_CODE) == 0) then
                     loop
                         exitwhen this == 0
                         if udg_DamageEventSource == this.u then
                             call this.modifyRage(udg_DamageEventAmount*ATTACK_RAGE_FACTOR)
                             return false
                         endif
                         set this = this.next
                     endloop
                 endif
                 return false
             endmethod
             
             //Adds rage when a unit dies nearby
             private static method addRageDeath takes nothing returns boolean
                 local real dx
                 local real dy
                 local unit dying = GetTriggerUnit()
                 local thistype this = thistype(0).next
                 if GetUnitAbilityLevel(dying, 'Aloc') == 0 then
                     loop
                         exitwhen this == 0
                         set dx = GetUnitX(this.u) - GetUnitX(dying)
                         set dy = GetUnitY(this.u) - GetUnitY(dying)
                         if SquareRoot(dx*dx + dy*dy) <= RAGE_GAIN_AREA then
                             if IsUnitAlly(dying, GetOwningPlayer(this.u)) then
                                 call this.modifyRage(ALLY_DEATH_RAGE_AMOUNT)
                             else
                                 call this.modifyRage(ENEMY_DEATH_RAGE_AMOUNT)
                             endif
                         endif
                         set this = this.next
                     endloop
                 endif
                 return false
             endmethod
         
             //Reduces damage taken by units that have blood rage
             private static method reduceDamage takes nothing returns boolean
                 local thistype this = thistype(0).next
                 local real reduction
                 if not (GetUnitAbilityLevel(udg_DamageEventTarget, ABIL_CODE) == 0) then
                     loop
                         exitwhen this == 0
                         if udg_DamageEventTarget == this.u then
                             if this.currentRage > udg_DamageEventAmount*DAMAGE_REDUCTION_FACTOR*RAGE_DRAIN_FACTOR then
                                 set reduction = udg_DamageEventAmount*DAMAGE_REDUCTION_FACTOR
                             else
                                 set reduction = this.currentRage/RAGE_DRAIN_FACTOR
                             endif
                                 set this.currentRage = this.currentRage - reduction*RAGE_DRAIN_FACTOR
                                 set udg_DamageEventAmount = udg_DamageEventAmount - reduction
                             return false
                         endif
                         set this = this.next
                     endloop
                 endif
                 return false
             endmethod
         
             private static method onInit takes nothing returns nothing
                 local trigger t = CreateTrigger()
                 local trigger t2 = CreateTrigger()
                 local trigger t3 = CreateTrigger()
                 local trigger t4 = CreateTrigger()
                 local trigger t5 = CreateTrigger()
                 local trigger t6 = CreateTrigger()
                 local integer i = 0
                 
                 call TriggerRegisterVariableEvent( t, "udg_UnitIndexEvent", EQUAL, 1.00 )
                 call TriggerAddCondition(t, Condition(function thistype.registerUnitsIndexed))
                 call TriggerAddCondition(t2, Condition(function thistype.registerLearningHero))
                 call TriggerAddCondition(t3, Condition(function thistype.deindexUnit))
                 call TriggerRegisterVariableEvent( t4, "udg_UnitIndexEvent", EQUAL, 2.00 )
                 call TriggerRegisterVariableEvent( t4, "udg_DamageEvent", EQUAL, 1.00 )
                 call TriggerAddCondition(t4, Condition(function thistype.addRageAttack))
                 call TriggerAddCondition(t5, Condition(function thistype.addRageDeath))
                 call TriggerRegisterVariableEvent( t6, "udg_DamageModifierEvent", EQUAL, 1.00 )
                 call TriggerAddCondition(t6, Condition(function thistype.reduceDamage))
                 
                 loop
                     exitwhen i == 16
                     
                     call TriggerRegisterPlayerUnitEvent(t2, Player(i),  EVENT_PLAYER_HERO_SKILL, null)
                     call TriggerRegisterPlayerUnitEvent(t5, Player(i),  EVENT_PLAYER_UNIT_DEATH, null)
                 
                     set i = i + 1
                 endloop
                 
             endmethod
             
         endstruct
         
         //This function can be used to modify rage from outside this trigger
         function addRage takes unit u, real amount returns nothing
             call Spell.addRage(u, amount)
         endfunction

    endscope