1. Find your way through the deepest dungeon in the 18th Mini Mapping Contest Poll.
    Dismiss Notice
  2. A brave new world lies beyond the seven seas. Join the 34th Modeling Contest today!
    Dismiss Notice
  3. Check out the Staff job openings thread.
    Dismiss Notice
Dismiss Notice
Hive 3 Remoosed BETA - NOW LIVE. Go check it out at BETA Hive Workshop! Post your feedback in this new forum BETA Feedback.
Dismiss Notice
60,000 passwords have been reset on July 8, 2019. If you cannot login, read this.

[system] Damage Queue

Discussion in 'Graveyard' started by Nestharus, Mar 27, 2012.

  1. Nestharus

    Nestharus

    Joined:
    Jul 10, 2007
    Messages:
    6,146
    Resources:
    8
    Spells:
    3
    Tutorials:
    4
    JASS:
    1
    Resources:
    8
    Code (vJASS):

    library DamageQueue /* v1.0.0.1
    *************************************************************************************
    *
    *   Allows on to queue up damage events. ALWAYS use this instead of unitDamageTarget
    *   within a DamageEvent.
    *
    *   ONLY use this on Damage Creators (sources of damage that generate damage).
    *
    *************************************************************************************
    *
    *   */
    uses/*
    *
    *       */
    AdvDamageEvent       /*          hiveworkshop.com/forums/submissions-414/extension-advanced-damage-event-213572/
    *       */
    AVL                  /*          hiveworkshop.com/forums/jass-resources-412/snippet-avl-tree-203168/
    *       */
    DamagePriority       /*          hiveworkshop.com/forums/submissions-414/repo-damage-priority-213750/
    *       */
    DamageType           /*          hiveworkshop.com/forums/submissions-414/snippet-damagetype-213751/
    *
    ************************************************************************************
    *
    *   struct DamageQueue extends array
    *       readonly static DamageQueue first
    *       readonly static boolean head
    *       readonly DamageQueue next
    *       readonly DamageType type
    *       readonly real damage
    *
    *       static method add takes UnitIndex source, UnitIndex target, real damage, integer damageType, integer damageId, integer instance returns nothing
    *       static method clear takes nothing returns nothing
    *
    ************************************************************************************/

        private struct Tree extends array
            method lessThan takes DamageType value returns boolean
                return DamageType(this).invPriority > value.invPriority
            endmethod
           
            method greaterThan takes DamageType value returns boolean
                return DamageType(this).invPriority < value.invPriority
            endmethod
           
            implement AVL
        endstruct
       
        private module DamageQueue_pmod
            private static method onInit takes nothing returns nothing
                set damageTree = Tree.create()
            endmethod
        endmodule
       
        private struct DamageQueue_p extends array
            static thistype instanceCount = 0
            thistype last
            thistype first
           
            real damage
            integer damageType
            integer damageId
            UnitIndex source
            UnitIndex target
            integer instance
           
            static real array totalDamage
            static Tree damageTree
           
            boolean cleared
           
            static method allocate takes nothing returns thistype
                set instanceCount = instanceCount + 1
                return instanceCount
            endmethod
           
            static method add takes UnitIndex source, UnitIndex target, real damage, integer damageType, integer damageId, integer instance returns nothing
                local thistype this = allocate()
               
                set thistype(DamageEvent.depth).last = this
               
                set this.source = source
                set this.target = target
                set this.damage = damage
                set this.damageType = damageType
                set this.damageId = damageId
                set this.instance = instance
            endmethod
            static method execute takes nothing returns nothing
                local thistype last = thistype(DamageEvent.depth).last
                local thistype this = thistype(DamageEvent.depth).first
                if (not thistype(DamageEvent.depth).cleared) then
                    loop
                        set this = this + 1
                        exitwhen integer(this) > integer(last)
                        if (0 == damageTree.search(damageType)) then
                            call damageTree.add(damageType)
                            set totalDamage[damageType] = 0
                        endif
                        call DamageEvent.unitDamageTarget(GetUnitById(source), GetUnitById(target), damage, damageType, damageId, instance)
                    endloop
                endif
            endmethod
            static method clear takes nothing returns nothing
                set thistype(DamageEvent.depth).cleared = true
            endmethod
           
            implement DamageQueue_pmod
        endstruct
       
        private struct DamageQueueCreator extends array
            private static constant method PRIORITY takes nothing returns integer
                return DAMAGE_PRIORITY_SETUP
            endmethod
           
            private static method onDamage takes nothing returns nothing
                local DamageQueue_p head
               
                if (1 == depth) then
                    call DamageQueue_p.damageTree.clear()
                    set DamageQueue_p.instanceCount = 0
                endif
               
                set head = DamageQueue_p.allocate()
               
                set DamageQueue_p(depth).first = head
                set DamageQueue_p(depth).last = head
               
                set DamageQueue_p(depth).cleared = false
            endmethod
           
            implement DamageEvent
        endstruct
       
        private struct DamageQueueExecute extends array
            private static constant method PRIORITY takes nothing returns integer
                return DAMAGE_PRIORITY_EXECUTION
            endmethod
           
            private static method onDamage takes nothing returns nothing
                call DamageQueue_p.execute()
            endmethod
           
            implement DamageEvent
        endstruct
       
        private struct DamageQueueCancellor extends array
            private static constant method PRIORITY takes nothing returns integer
                return DAMAGE_PRIORITY_CLEANUP
            endmethod
           
            private static method onDamage takes nothing returns nothing
                if (1 == depth) then
                    set modifiedAmount = 0
                else
                    set DamageQueue_p.totalDamage[damageType] = DamageQueue_p.totalDamage[damageType] + modifiedAmount
                endif
            endmethod
           
            implement DamageEvent
        endstruct
       
        struct DamageQueue extends array
            static method add takes UnitIndex source, UnitIndex target, real damage, integer damageType, integer damageId, integer instance returns nothing
                call DamageQueue_p.add(source,  target, damage, damageType, damageId, instance)
            endmethod
            static method operator first takes nothing returns thistype
                return DamageQueue_p.damageTree.next
            endmethod
            static method clear takes nothing returns nothing
                call DamageQueue_p.clear()
            endmethod
            method operator next takes nothing returns thistype
                return Tree(this).next
            endmethod
            method operator head takes nothing returns boolean
                return Tree(this).head
            endmethod
            method operator type takes nothing returns DamageType
                return Tree(this).value
            endmethod
            method operator damage takes nothing returns real
                return DamageQueue_p.totalDamage[type]
            endmethod
        endstruct
    endlibrary
     



    Demonstrations of Excellent Custom Damage Modifier/Creator Implementations
    Code (vJASS):

    library HandDamageCreator uses DamageQueue, DamageSourceTypes, DamageSourceInstance
        struct HandDamageCreator extends array
            readonly DamageSource leftHand
            readonly DamageSource rightHand
           
            readonly thistype leftHandModifier
            readonly thistype rightHandModifier
           
            readonly DamageSource source
           
            private static method PRIORITY takes nothing returns integer
                return DAMAGE_PRIORITY_CREATOR
            endmethod

            private method onDamageOutgoing takes nothing returns nothing
                if (DamageSource(damageId).type == DamageSourceTypes.NULL) then
                    call DamageQueue.add(sourceId, targetId, amount/2, DamageTypes.PHYSICAL, source, DamageSourceInstance.create(targetId, source))
                endif
            endmethod

            implement DamageModificationEffect
           
            private method index takes nothing returns nothing
                set leftHand = DamageSource.create(DamageSourceTypes.HANDS)
                set rightHand = DamageSource.create(DamageSourceTypes.HANDS)
               
                set leftHandModifier = apply(false)
                set leftHandModifier.source = leftHand
               
                set rightHandModifier = apply(false)
                set rightHandModifier.source = rightHand
            endmethod
           
            private method deindex takes nothing returns nothing
                call leftHand.destroy()
                call rightHand.destroy()
            endmethod
           
            implement UnitIndexStruct
        endstruct
    endlibrary
     


    Code (vJASS):

    library PhysicalDamageModifier uses DamageQueue, DamageSource
        private struct PhysicalDamageModifier_p extends array
            real change
           
            private static method PRIORITY takes nothing returns integer
                return DAMAGE_PRIORITY_MODIFIER
            endmethod

            private method onDamageOutgoing takes nothing returns nothing
                if (damageType == DamageTypes.PHYSICAL and DamageSource(damageId).type == DamageSourceTypes.WEAPON) then
                    set modifiedAmount = modifiedAmount + change
                endif
            endmethod
           
            private method onDamageIncoming takes nothing returns nothing
                if (damageType == DamageTypes.PHYSICAL and DamageSource(damageId).type == DamageSourceTypes.WEAPON) then
                    set modifiedAmount = modifiedAmount + change
                endif
            endmethod
           
            implement DamageModificationEffect
        endstruct
       
        struct PhysicalDamageModifier extends array
            method operator change takes nothing returns real
                return PhysicalDamageModifier_p(this).change
            endmethod
            method operator change= takes real value returns nothing
                set PhysicalDamageModifier_p(this).change = value
            endmethod
           
            implement UnitIndexStructMethods
           
            method apply takes real change, boolean incoming returns thistype
                set this = PhysicalDamageModifier_p(this).apply(incoming)
               
                set this.change = change
               
                return this
            endmethod
            method destroy takes nothing returns nothing
                call PhysicalDamageModifier_p(this).destroy()
            endmethod
        endstruct
    endlibrary
     


    Code (vJASS):

    library WeaponSourceEvasion uses DamageQueue, DamageSourceTypes, DamagePriority
        globals
            private real array evasion
        endglobals
       
        private struct WeaponSourceEvasionModifier_p extends array
            real change
           
            private static method PRIORITY takes nothing returns integer
                return DAMAGE_PRIORITY_PERCENT_MODIFIER
            endmethod
           
            private method onDamageIncoming takes nothing returns nothing
                if (DamageSource(damageId).type == DamageSourceTypes.WEAPON) then
                    set evasion[targetId] = evasion[targetId] + change
                endif
            endmethod
           
            implement DamageModificationEffect
        endstruct
       
        struct WeaponSourceEvasionModifier extends array
            method operator change takes nothing returns real
                return WeaponSourceEvasionModifier_p(this).change
            endmethod
            method operator change= takes real value returns nothing
                set WeaponSourceEvasionModifier_p(this).change = value
            endmethod
           
            implement UnitIndexStructMethods
           
            method apply takes real change returns thistype
                set this = WeaponSourceEvasionModifier_p(this).apply(true)
               
                set this.change = change
               
                return this
            endmethod
            method destroy takes nothing returns nothing
                call WeaponSourceEvasionModifier_p(this).destroy()
            endmethod
        endstruct
       
        private struct WeaponSourceEvasion_p extends array
            private static method PRIORITY takes nothing returns integer
                return DAMAGE_PRIORITY_PERCENT_MODIFIER
            endmethod
           
            private static method onDamage takes nothing returns nothing
                if (DamageSource(damageId).type == DamageSourceTypes.WEAPON) then
                    if (evasion[targetId] > GetRandomReal(0, 1)) then
                        call DamageQueue.clear()
                    endif
                   
                    set evasion[targetId] = 0
                endif
            endmethod
       
            implement DamageEvent
        endstruct
    endlibrary
     


    Code (vJASS):

    struct Tester extends array
        private static method onInit takes nothing returns nothing
            local unit u1 = CreateUnit(Player(2), 'hfoo', GetStartLocationX(0), GetStartLocationY(0) - 256, 270)
            local unit u2 = CreateUnit(Player(2), 'hrif', GetStartLocationX(0), GetStartLocationY(0) - 256, 270)
            local unit u3 = CreateUnit(Player(0), 'hgtw', GetStartLocationX(0), GetStartLocationY(0), 270)
            local unit u4 = CreateUnit(Player(0), 'hfoo', GetStartLocationX(0), GetStartLocationY(0), 270)
           
            call PhysicalDamageModifier[u4].apply(-10, true)        //-10 to incoming damage
            call WeaponSourceEvasionModifier[u2].apply(.5)          //50% chance to evade
        endmethod
    endstruct
     
     
    Last edited: Jul 12, 2012
  2. Nestharus

    Nestharus

    Joined:
    Jul 10, 2007
    Messages:
    6,146
    Resources:
    8
    Spells:
    3
    Tutorials:
    4
    JASS:
    1
    Resources:
    8
    Graveyarding due to deprecation