• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!

[Solved] Transferring variable type to another function

Status
Not open for further replies.
Level 7
Joined
Feb 9, 2021
Messages
301
Is there a way to transfer variable type to another function? I have a local "struct name" "local name" in a function, and I want to transfer "struct name" from another function. In particular, I want to transfer "struct name" (SuzBuff1 or SuzBuff2 or SuzBuff3 etc) from the method "onDamage" to the method "execute". I need it in order to change the applied buff based on my angle conditions. I have 6 different buffs, and I want to apply one of them, depending on the angle of attack. Would appreciate any help.

JASS:
library Suzumebachi /*


     */ uses /*

     */ SpellFramework /*
     */ BaseFunctions


     /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
     * SPELL CONFIGURATION *
     * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
    private module SpellConfiguration

        static constant integer SPELL_ABILITY_ID    = 'A00G'
        static constant integer SPELL_EVENT_TYPE    = EVENT_SPELL_EFFECT
        static constant real SFX_DEATH_TIME         = 1.50
        static constant integer STACKS_GAIN_ON_CD   = 1
        static constant real SPELL_RANGE            = 64
        static constant real SPELL_AOE              = 300
        static constant attacktype ATTACK_TYPE      = ATTACK_TYPE_MAGIC
        static constant damagetype DAMAGE_TYPE      = DAMAGE_TYPE_MAGIC
        static constant weapontype WEAPON_TYPE      = WEAPON_TYPE_WHOKNOWS
      
        //Suz
        static constant string SUZ_EFFECT_ID        = "Abilities\\Weapons\\LordofFlameMissile\\LordofFlameMissile.mdl"
        static constant string SUZ_DEATH_EFFECT_ID  = "Abilities\\Spells\\Undead\\AnimateDead\\AnimateDeadTarget.mdl"
        static constant real SUZ_DELAY              = 0.5
        static constant real SUZ_EFFECT_DIST        = 100
        static constant real SUZ_EFFECT_DEF_SCALE   = 1.0
        static constant real SUZ_EFFECT_KILL_SCALE  = 2.0
        static constant real SUZ_Z                  = 100
      
        //Rangle of angles per side
        static constant real ANGLE_FRONT            = 210.0
        static constant real ANGLE_SIDE_1           = 150.0
        static constant real ANGLE_SIDE_2           = 90.0
        static constant real ANGLE_BACK             = 30.0
        static constant real ANGLE_SIDE_3           = 330.0
        static constant real ANGLE_SIDE_4           = 270.0
      
        static constant integer INT_ANGLE_FRONT     = 1
        static constant integer INT_ANGLE_SIDE_1    = 2
        static constant integer INT_ANGLE_SIDE_2    = 3
        static constant integer INT_ANGLE_BACK      = 4
        static constant integer INT_ANGLE_SIDE_3    = 5
        static constant integer INT_ANGLE_SIDE_4    = 6
      
      
      
        static method Dmg takes integer level, unit caster returns real
            return 50. + 0. * level + 0.1 * GetHeroStr(caster, true)
        endmethod
      
        static method szbDuration takes integer level returns real
            return 5.0 + 0.0 * level
        endmethod
      
        static method FrontMaxHp takes unit caster returns real
            return 50 + 0.1 * GetHeroStr(caster, true)
        endmethod
      
        static method SideMaxHp takes unit caster returns real
            return 0.10 + 0.1 * GetHeroStr(caster, true)
        endmethod
      
        static method BackMaxHp takes unit caster returns real
            return 0.25 + 0.1 * GetHeroStr(caster, true)
        endmethod
      
        static method StackCdTime takes integer level returns integer
            return 3
        endmethod
      
        static method MaxStacks takes integer level returns integer
            return 3 + level
        endmethod
      
      
      
        static method TargetsFilter takes unit target, unit caster returns boolean
            return GetWidgetLife(target) > 0.405 and /*
             */ IsUnitEnemy(target, GetOwningPlayer(caster)) and /*
             */ (IsUnitVisible(target, GetOwningPlayer(caster))) and /*
             */ not IsUnitType(target, UNIT_TYPE_STRUCTURE) and /*
             */ GetUnitAbilityLevel(GetFilterUnit(), 'Aloc') == 0
        endmethod

    endmodule

  

     /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
     * END OF SPELL CONFIGURATION *
     * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

     /* == == == == == == == == == == == == = SPELL CODE == == == == == == == == == == == == = */
  
  
    //Buffs
     struct SuzBuff1 extends Buff
        private static constant integer RAWCODE         = 'A016'
        private static constant integer DISPEL_TYPE     = BUFF_NONE
        private static constant integer STACK_TYPE      = BUFF_STACK_NONE
      
        integer counter
        effect sfx
        string sfxId = "Abilities\\Spells\\Undead\\AnimateDead\\AnimateDeadTarget.mdl"
        string attach = "chest"
    
        method onRemove takes nothing returns nothing
            set this.counter = 0
            call DestroyEffect(this.sfx)
            set this.sfx = null
        endmethod
    
        method onApply takes nothing returns nothing
            set this.counter = this.counter + 1
            if this.counter == 1 then
                set this.sfx = AddSpecialEffectTarget(sfxId, this.target, attach)
            endif
        endmethod

        implement BuffApply
    endstruct
  
    struct SuzBuff2 extends Buff
        private static constant integer RAWCODE         = 'A020'
        private static constant integer DISPEL_TYPE     = BUFF_NONE
        private static constant integer STACK_TYPE      = BUFF_STACK_NONE
      
        integer counter
        effect sfx
        string sfxId = "Abilities\\Spells\\Undead\\AnimateDead\\AnimateDeadTarget.mdl"
        string attach = "chest"
    
        method onRemove takes nothing returns nothing
            set this.counter = 0
            call DestroyEffect(this.sfx)
            set this.sfx = null
        endmethod
    
        method onApply takes nothing returns nothing
            set this.counter = this.counter + 1
            if this.counter == 1 then
                set this.sfx = AddSpecialEffectTarget(sfxId, this.target, attach)
            endif
        endmethod

        implement BuffApply
    endstruct
  
    struct SuzBuff3 extends Buff
        private static constant integer RAWCODE         = 'A021'
        private static constant integer DISPEL_TYPE     = BUFF_NONE
        private static constant integer STACK_TYPE      = BUFF_STACK_NONE
      
        integer counter
        effect sfx
        string sfxId = "Abilities\\Spells\\Undead\\AnimateDead\\AnimateDeadTarget.mdl"
        string attach = "chest"
    
        method onRemove takes nothing returns nothing
            set this.counter = 0
            call DestroyEffect(this.sfx)
            set this.sfx = null
        endmethod
    
        method onApply takes nothing returns nothing
            set this.counter = this.counter + 1
            if this.counter == 1 then
                set this.sfx = AddSpecialEffectTarget(sfxId, this.target, attach)
            endif
        endmethod

        implement BuffApply
    endstruct
  
    struct SuzBuff4 extends Buff
        private static constant integer RAWCODE         = 'A022'
        private static constant integer DISPEL_TYPE     = BUFF_NONE
        private static constant integer STACK_TYPE      = BUFF_STACK_NONE
      
        integer counter
        effect sfx
        string sfxId = "Abilities\\Spells\\Undead\\AnimateDead\\AnimateDeadTarget.mdl"
        string attach = "chest"
    
        method onRemove takes nothing returns nothing
            set this.counter = 0
            call DestroyEffect(this.sfx)
            set this.sfx = null
        endmethod
    
        method onApply takes nothing returns nothing
            set this.counter = this.counter + 1
            if this.counter == 1 then
                set this.sfx = AddSpecialEffectTarget(sfxId, this.target, attach)
            endif
        endmethod

        implement BuffApply
    endstruct
  
    struct SuzBuff5 extends Buff
        private static constant integer RAWCODE         = 'A023'
        private static constant integer DISPEL_TYPE     = BUFF_NONE
        private static constant integer STACK_TYPE      = BUFF_STACK_NONE
      
        integer counter
        effect sfx
        string sfxId = "Abilities\\Spells\\Undead\\AnimateDead\\AnimateDeadTarget.mdl"
        string attach = "chest"
    
        method onRemove takes nothing returns nothing
            set this.counter = 0
            call DestroyEffect(this.sfx)
            set this.sfx = null
        endmethod
    
        method onApply takes nothing returns nothing
            set this.counter = this.counter + 1
            if this.counter == 1 then
                set this.sfx = AddSpecialEffectTarget(sfxId, this.target, attach)
            endif
        endmethod

        implement BuffApply
    endstruct
  
  
    struct SuzBuff6 extends Buff
        private static constant integer RAWCODE         = 'A024'
        private static constant integer DISPEL_TYPE     = BUFF_NONE
        private static constant integer STACK_TYPE      = BUFF_STACK_NONE
      
        integer counter
        effect sfx
        string sfxId = "Abilities\\Spells\\Undead\\AnimateDead\\AnimateDeadTarget.mdl"
        string attach = "chest"
    
        method onRemove takes nothing returns nothing
            set this.counter = 0
            call DestroyEffect(this.sfx)
            set this.sfx = null
        endmethod
    
        method onApply takes nothing returns nothing
            set this.counter = this.counter + 1
            if this.counter == 1 then
                set this.sfx = AddSpecialEffectTarget(sfxId, this.target, attach)
            endif
        endmethod

        implement BuffApply
    endstruct
  
  

  
    //Spell
  
    globals
        private group eG = CreateGroup()
    endglobals

    private struct Suzumebachi extends array

        implement SpellConfiguration

        private integer stacks
        private integer maxStacks
        private boolean isStackTimerOn
        private timer t
        private boolean hit
        private unit closestUnit
        
        private static method onSpellStart takes nothing returns thistype
            local real cX
            local real cY
            local real targetX
            local real targetY
            local real angle
            local unit u
            local thistype this = GetUnitId(Spell.triggerUnit)
            local real dmg

            if (this.stacks == 0) then
                debug call BJDebugMsg("[Suzumebachi] Not Enough Stacks. Stacks: " + I2S(this.stacks) )
                return 0
            endif
          
            set this.stacks = this.stacks - 1
            call SetCustomUnitAbilityCharges(Spell.triggerUnit, SPELL_ABILITY_ID, this.stacks)
            debug call BJDebugMsg("[Suzumebachi] Number of Stacks Left " + I2S(this.stacks))

            if not this.isStackTimerOn then
                set this.t = NewTimerEx(this)
                call TimerStart(this.t, StackCdTime(Spell.level), true, function thistype.StacksCd)
                set this.isStackTimerOn = true
            endif
           
            set cX = GetUnitX(Spell.triggerUnit)
            set cY = GetUnitY(Spell.triggerUnit)
            set angle = GetAngle(cX, Spell.targetX, cY, Spell.targetY)
            set targetX = GetXWithOffset(cX, SPELL_RANGE, angle)
            set targetY = GetYWithOffset(cY, SPELL_RANGE, angle)
            set dmg = Dmg(Spell.level, Spell.triggerUnit)
           
            set this.closestUnit = GetClosestEnemyUnitHeroPrio(Spell.triggerUnit, targetX, targetY, SPELL_AOE)
            if this.closestUnit != null then
                call thistype[UnitIndex[closestUnit]].enableDamageEventLocal()
                call UnitDamageTarget(Spell.triggerUnit, closestUnit, dmg, false, false, ATTACK_TYPE, DAMAGE_TYPE, WEAPON_TYPE )
            endif
          
            return this
        endmethod

        private method onSpellEnd takes nothing returns nothing
          
            if this.stacks == this.maxStacks then
                set this.isStackTimerOn = false
                call ReleaseTimer(this.t)
                set this.t = null
            elseif this.stacks == 0 then
                call StartUnitAbilityCooldown(GetUnitById(this), SPELL_ABILITY_ID, TimerGetRemaining(this.t))
            endif
          
            call thistype[UnitIndex[closestUnit]].disableDamageEventLocal()
            set this.closestUnit = null
        endmethod

        implement SpellEventEx
       
         private static method onDamage takes nothing returns nothing
            local real cFacing = GetUnitFacing(source)
            local real tFacing = GetUnitFacing(target)
            local real angleDiff = AngleDiff(cFacing, tFacing)
          
            debug call BJDebugMsg("[Suzumebachi] AngleDiff: " + R2S(angleDiff))
          
            //Front Stamp
            if (angleDiff <= ANGLE_FRONT and angleDiff > ANGLE_SIDE_1) then
                set damage = Suzumebachi.execute(source, target, damageOriginal)
              
                return
            endif
          
            if (angleDiff <= ANGLE_SIDE_1 and angleDiff > ANGLE_SIDE_2) then
                set damage = Suzumebachi.execute(source, target, damageOriginal)
              
                return
            endif
          
            //call thistype[sourceId].disableDamageEventLocalOutgoing()
        endmethod
      
        private static method execute takes unit source, unit target, real damageOriginal returns real
            local real hpShotPercent
            local texttag textTag
            local string toDisplay
            local real tX
            local real tY
            local integer spellLevel
            local real tPercentHp = GetUnitStatePercentEx(target, UNIT_STATE_LIFE, UNIT_STATE_MAX_LIFE)
            local SuzBuff1 szb
          
            set hpShotPercent = FrontMaxHp(source)
            debug call BJDebugMsg("[Suzumebachi] hpShotPerecent: " + R2S(hpShotPercent))
            debug call BJDebugMsg("[Suzumebachi] tPercentHp: " + R2S(tPercentHp))
            if tPercentHp > hpShotPercent then
                set textTag = CreateTextTag()
                set toDisplay = "missed"
                set tX = GetUnitX(target)
                set tY = GetUnitY(target)
                      
                call SetTextTagPos(textTag, tX - 32, tY, 16)
                call SetTextTagText(textTag, toDisplay, 10*.0023)
                call SetTextTagVisibility(textTag, true)
                call SetTextTagPermanent(textTag, false)
                call SetTextTagVelocity(textTag, 0, .03)
                call SetTextTagLifespan(textTag, 3)
                      
                set textTag = null
                set toDisplay = null
                  
                return 0.
            endif

            if not SuzBuff1.has(source, target, SuzBuff1.typeid) then
                debug call BJDebugMsg("[Suzumebachi] Front 1 Buff Aplied ")
                set spellLevel = GetUnitAbilityLevel(source, SPELL_ABILITY_ID)
                set szb = SuzBuff1.add(source, target)
                set szb.duration = szbDuration(spellLevel) + SUZ_DELAY
                  
                return damageOriginal
            endif
              
              
            return 999999.
      
        endmethod
      
        implement DDS
      
        //Stacks Mechanics
        static method StacksCd takes nothing returns nothing
            local thistype this = GetTimerData(GetExpiredTimer())
            if this.stacks < this.maxStacks then
                set this.stacks = this.stacks + STACKS_GAIN_ON_CD
                call SetCustomUnitAbilityCharges(GetUnitById(this), SPELL_ABILITY_ID, this.stacks)
                debug call BJDebugMsg("[Suzumebachi] CD Finished: 1 Suz Stack Added")
            else
                debug call BJDebugMsg("[Suzumebachi] CD Finished: 1 Suz Stack Added")
                set this.isStackTimerOn = false
                call ReleaseTimer(this.t)
                set this.t = null
            endif
        endmethod
      
        private static method GiveShunpoStacks takes nothing returns nothing
            local unit learner
            local thistype this
          
              
            if GetLearnedSkill() == SPELL_ABILITY_ID then
                set learner = GetTriggerUnit()
                set this = GetUnitId(learner)
                set this.maxStacks = MaxStacks(GetUnitAbilityLevel(learner, SPELL_ABILITY_ID))
              
                if GetUnitAbilityLevel(learner, SPELL_ABILITY_ID) == 1 then
                    call SetUnitAbilityCastpoint(learner, SPELL_ABILITY_ID, 0.3)
                    call InitCustomAbilityAddressChargesHook( GetUnitAbility(learner, SPELL_ABILITY_ID))
                    call EnableCustomUnitAbilityCharges(learner, SPELL_ABILITY_ID)
                    debug call BJDebugMsg("[Suzumebachi] Setup Finished")
                    set this.stacks = this.maxStacks
                else
                    set this.stacks = this.stacks + 1
                endif
                  
                call SetCustomUnitAbilityCharges(learner, SPELL_ABILITY_ID, this.stacks)
                debug call BJDebugMsg("[Suzumebachi] Stacks " + I2S(this.stacks))
                debug call BJDebugMsg("[Suzumebachi] Max Stacks " + I2S(this.maxStacks))

            endif
              
        endmethod
     
        private static method onInit takes nothing returns nothing

            call RegisterAnyPlayerUnitEvent(EVENT_PLAYER_HERO_SKILL, function thistype.GiveShunpoStacks)

        endmethod
  
    endstruct


endlibrary
 
Have you looked at functional interfaces?
I guess you could pass a function interface to the function and execute it that way.

If what you need to do is:
JASS:
            if not SuzBuff1.has(source, target, SuzBuff1.typeid) then
                debug call BJDebugMsg("[Suzumebachi] Front 1 Buff Aplied ")
                set spellLevel = GetUnitAbilityLevel(source, SPELL_ABILITY_ID)
                set szb = SuzBuff1.add(source, target)
                set szb.duration = szbDuration(spellLevel) + SUZ_DELAY
                  
                return damageOriginal
            endif
This, but for all different buffs.

As far as I know, you cannot pass a "static-reference" for the struct-type without having an instance of it.
One way would be to pass a function interface for each function you need to call on the struct-type.


Below is a sample of how this could be done using only 1 function.
JASS:
library TestLibrary initializer DecideWhatBuff
    function interface BuffApplier takes unit source, unit target, integer whatever returns nothing
    struct Buff1
        static method SomeFunctionName takes unit u1, unit u2, integer aa returns nothing
            call BJDebugMsg("Buff1")
        endmethod
    endstruct
    struct Buff2
        static method SomeOtherFunctionName takes unit u1, unit u2, integer aa returns nothing
            call BJDebugMsg("Buff2")
        endmethod
    endstruct
    function TestFunction takes BuffApplier buffApplier returns nothing
        local unit source = null
        local unit target = null
        local integer whatever = 17
        call BJDebugMsg("TestFunction")
        
        call buffApplier.execute(source, target, whatever)
    endfunction
    function DecideWhatBuff takes nothing returns nothing
        call TestFunction(Buff1.SomeFunctionName)
        call TestFunction(Buff2.SomeOtherFunctionName)
    endfunction
endlibrary

This prints:
TestFunction
Buff1
TestFunction
Buff2

Do you think this would work for you?
 

Dr Super Good

Spell Reviewer
Level 64
Joined
Jan 18, 2005
Messages
27,202
You want a BuffFactory class which you then pass around a reference to. The BuffFactory has an abstract method to CreateBuff to a target unit. Each buff type then also creates a child class of BuffFactory which statically references the buff type subclass and its constructor.

This approach can be read about here...
(yes they are all confusingly similar)

Another approach would be to create a static factory method that selects and statically links the appropriate buff constructor. This factory method would need to be passed enough information from execute to select the correct buff. This is similar to the BuffFactory approach but completely static and with less boilerplate code. However it might not be suitable for your needs.

Part of the issue you are having is likely due to how you have structured the Buff children classes. If you look at them they all seem to contain the same logic that is repeated. What you could do instead is have a single Buff class that then is constructed with the relevant state data passed to it which is currently being statically implemented into the children. Your BuffFactory class then contains which data the Buff will be populated with when the factory method is called. This data could come from a lookup table such as some arrays, or be hardcoded and selected with conditional flow control. Your onDamage method would then create a new BuffFactory for the appropriate type of buff (will create with the appropriate data) and that is then passed to execute to be applied.
 
Level 7
Joined
Feb 9, 2021
Messages
301
Have you looked at functional interfaces?
I guess you could pass a function interface to the function and execute it that way.

If what you need to do is:
JASS:
            if not SuzBuff1.has(source, target, SuzBuff1.typeid) then
                debug call BJDebugMsg("[Suzumebachi] Front 1 Buff Aplied ")
                set spellLevel = GetUnitAbilityLevel(source, SPELL_ABILITY_ID)
                set szb = SuzBuff1.add(source, target)
                set szb.duration = szbDuration(spellLevel) + SUZ_DELAY
                 
                return damageOriginal
            endif
This, but for all different buffs.

As far as I know, you cannot pass a "static-reference" for the struct-type without having an instance of it.
One way would be to pass a function interface for each function you need to call on the struct-type.


Below is a sample of how this could be done using only 1 function.
JASS:
library TestLibrary initializer DecideWhatBuff
    function interface BuffApplier takes unit source, unit target, integer whatever returns nothing
    struct Buff1
        static method SomeFunctionName takes unit u1, unit u2, integer aa returns nothing
            call BJDebugMsg("Buff1")
        endmethod
    endstruct
    struct Buff2
        static method SomeOtherFunctionName takes unit u1, unit u2, integer aa returns nothing
            call BJDebugMsg("Buff2")
        endmethod
    endstruct
    function TestFunction takes BuffApplier buffApplier returns nothing
        local unit source = null
        local unit target = null
        local integer whatever = 17
        call BJDebugMsg("TestFunction")
       
        call buffApplier.execute(source, target, whatever)
    endfunction
    function DecideWhatBuff takes nothing returns nothing
        call TestFunction(Buff1.SomeFunctionName)
        call TestFunction(Buff2.SomeOtherFunctionName)
    endfunction
endlibrary

This prints:
TestFunction
Buff1
TestFunction
Buff2

Do you think this would work for you?
You want a BuffFactory class which you then pass around a reference to. The BuffFactory has an abstract method to CreateBuff to a target unit. Each buff type then also creates a child class of BuffFactory which statically references the buff type subclass and its constructor.

This approach can be read about here...
(yes they are all confusingly similar)

Another approach would be to create a static factory method that selects and statically links the appropriate buff constructor. This factory method would need to be passed enough information from execute to select the correct buff. This is similar to the BuffFactory approach but completely static and with less boilerplate code. However it might not be suitable for your needs.

Part of the issue you are having is likely due to how you have structured the Buff children classes. If you look at them they all seem to contain the same logic that is repeated. What you could do instead is have a single Buff class that then is constructed with the relevant state data passed to it which is currently being statically implemented into the children. Your BuffFactory class then contains which data the Buff will be populated with when the factory method is called. This data could come from a lookup table such as some arrays, or be hardcoded and selected with conditional flow control. Your onDamage method would then create a new BuffFactory for the appropriate type of buff (will create with the appropriate data) and that is then passed to execute to be applied.

I am sorry, but I have a little problem understanding your proposed solutions. I just wanted to confirm that you understood the problem correctly. The idea of the spell is that the caster attacks the unit and if the target's hp is below a certain level, a mark appears (buff) on the target. If the buff is applied a second time from the same angle, the target is dead. The % of the hp threshold depends on the angle of the attack. There are 6 sides from which it is possible to put a mark on the target, and, therefore, 6 different buffs. I use Flux's Buff System for buffs. I could do this by having 6 if statements in onDamage method with approximately the same actions. However, instead of writing mostly the same things all the time, I created a method execute and transferred everything there. So, now, I will have 6 if statements in onDamage method, but they will all just call for the execute method. The problem is I need to transfer the name of the specific struct buff to apply it. So, in the execute method, I want to have "transferred struct name".has(source, target, "transferred struct name".typeid) instead of SuzBuff1.has(source, target, SuzBuff1.typeid). Accordingly, in on damage method, in the first if statement, I will have Suzumebachi.execute(source, target, damageOriginal, "struct name [For example, SuzBuff1]). The second if statement will have structname for SuzBuff2.

I am sorry if this is exactly what you were answering. I just wanted to make sure.
 
If you don't want to restructure you code too much, you can easily pass a function-reference using functional interfaces as I mentioned in my post.
Instead of passing "transferred struct name" you pass the function to your "transferred struct names function (that has the correct parameters etc.)" and execute that with the correct parameters.
 

Dr Super Good

Spell Reviewer
Level 64
Joined
Jan 18, 2005
Messages
27,202
I am sorry, but I have a little problem understanding your proposed solutions. I just wanted to confirm that you understood the problem correctly. The idea of the spell is that the caster attacks the unit and if the target's hp is below a certain level, a mark appears (buff) on the target. If the buff is applied a second time from the same angle, the target is dead. The % of the hp threshold depends on the angle of the attack. There are 6 sides from which it is possible to put a mark on the target, and, therefore, 6 different buffs. I use Flux's Buff System for buffs. I could do this by having 6 if statements in onDamage method with approximately the same actions. However, instead of writing mostly the same things all the time, I created a method execute and transferred everything there. So, now, I will have 6 if statements in onDamage method, but they will all just call for the execute method. The problem is I need to transfer the name of the specific struct buff to apply it. So, in the execute method, I want to have "transferred struct name".has(source, target, "transferred struct name".typeid) instead of SuzBuff1.has(source, target, SuzBuff1.typeid). Accordingly, in on damage method, in the first if statement, I will have Suzumebachi.execute(source, target, damageOriginal, "struct name [For example, SuzBuff1]). The second if statement will have structname for SuzBuff2.

I am sorry if this is exactly what you were answering. I just wanted to make sure.
You can either use the abstract factory or factory method patterns I mentioned earlier, or you will need to move to a dynamically typed language like Lua. In Lua you can pass types as strings.
 
Level 7
Joined
Feb 9, 2021
Messages
301
You can either use the abstract factory or factory method patterns I mentioned earlier, or you will need to move to a dynamically typed language like Lua. In Lua you can pass types as strings.
If you don't want to restructure you code too much, you can easily pass a function-reference using functional interfaces as I mentioned in my post.
Instead of passing "transferred struct name" you pass the function to your "transferred struct names function (that has the correct parameters etc.)" and execute that with the correct parameters.
Thank you, guys. I need some time to comprehend the solution. I will post here if it does not work out.
 
Status
Not open for further replies.
Top