• 🏆 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!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

[Needs help] Stub method can't run.

Status
Not open for further replies.
Level 11
Joined
Dec 3, 2011
Messages
366
JASS:
library Buff requires UnitDex, Table
// Function interface
private function interface onApply takes Buff b, unit source, unit target, real duration, real period, boolean show returns nothing
private function interface onRemove takes Buff b, unit source, unit target, real duration, real period, boolean show returns nothing
private function interface preRemove takes Buff b, unit source, unit target, real duration, real period, boolean show returns nothing
private function interface onPeriodic takes Buff b, unit source, unit target, real duration, real period, boolean show returns nothing

// Buff
    struct Buff extends array
        readonly static Table Data
        readonly Table Store
        onApply onApplyAction
        onRemove onRemoveAction
        preRemove preRemoveAction
        onPeriodic onPeriodicAction
        
        method operator raw takes nothing returns integer
            return Data[this]
        endmethod
        
        method operator rawBuff takes nothing returns integer
            return Data[.raw]
        endmethod
        
        method operator name takes nothing returns string
            return Data.string[this]
        endmethod
        
        method operator isStack takes nothing returns boolean
            return Data.boolean[this]
        endmethod
        
        static method create takes string name, integer aId, integer bId, boolean stack returns thistype
            local thistype this
            
            if Data[aId] == 0 then
                set this = Data[0] + 1
                set Data[0] = this
                set Data[this] = aId
                set Data.boolean[this] = stack
                set Data.string[this] = name
                set Data[aId] = bId
                set Store = Table.create()
            endif

            return this
        endmethod
        
        private static method onInit takes nothing returns nothing
            set Data = Table.create()
        endmethod
    endstruct
    
// UnitBuffs
    struct UnitBuffs extends array
        readonly Table Data
        
        static method operator [] takes unit u returns thistype
            return GetUnitId(u)
        endmethod
        
        method operator unit takes nothing returns unit
            return UnitDex.Unit[this]
        endmethod
        
        method hasBuff takes Buff b returns boolean
            return b.Store[GetHandleId(this.unit)] != 0
        endmethod
        
        method countBuff takes Buff b returns integer
            return b.Store[GetHandleId(this.unit)]
        endmethod
        
        private static method onIndex takes nothing returns boolean
            local unit u = GetIndexedUnit()
            local thistype this = thistype[u]
            if this.Data == 0 then
                set this.Data = Table.create()
            endif
            
            set u = null
            return false
        endmethod
        
        private static method onDeindex takes nothing returns boolean
            local unit u = GetIndexedUnit()
            local thistype this = thistype[u]
            
            call this.Data.flush()
            
            set u = null
            return false
        endmethod
        
        private static method onInit takes nothing returns nothing
            call RegisterUnitIndexEvent(Filter(function thistype.onIndex), EVENT_UNIT_INDEX)
            call RegisterUnitIndexEvent(Filter(function thistype.onDeindex), EVENT_UNIT_DEINDEX)
        endmethod
    endstruct
    
// Buff List
    struct BuffList
        private static Table Data
        private static Table Store
        // Operator
        static method operator [] takes trigger t returns thistype
            return Data[GetHandleId(t)]
        endmethod
        
        method operator Trigger takes nothing returns trigger
            return Store.trigger[this]
        endmethod
        
        method operator Id takes nothing returns integer
            return GetHandleId(this.Trigger)
        endmethod
        
        method operator Source takes nothing returns unit
            return Data.unit[this.Id]
        endmethod
        
        method operator Period takes nothing returns real
            return Data.real[this.Id]
        endmethod
        
        method operator Target takes nothing returns unit
            return Data.unit[this]
        endmethod
        
        method operator Duration takes nothing returns real
            return Data.real[this]
        endmethod
        
        method operator Duration= takes real d returns nothing
            set Data.real[this] = d
        endmethod
        
        method operator Buff takes nothing returns Buff
            return Data[this]
        endmethod
        
        method operator isShowIcon takes nothing returns boolean
            return Data.boolean[this]
        endmethod
        
        method operator isShowIcon= takes boolean flag returns nothing
            call showIcon(this.Buff , this.Target, flag)
        endmethod
        // Stub methods
        stub method onApply takes nothing returns nothing
        endmethod
        // Main procress
        private static method clear takes thistype this returns nothing
            set Data[this] = 0
            set Data.unit[this] = null
            set Data.real[this] = 0
        endmethod
        
        private static method periodic takes nothing returns boolean
            local trigger t = GetTriggeringTrigger()
            local thistype this = thistype[t]
            if this.Duration - this.Period <= 0 then
                set this.Duration = 0
                call this.destroy()
            else
                set Data.real[this] = this.Duration - this.Period
                
                if this.Duration - this.Period <= 0 then
                    call Buff.preRemoveAction.evaluate(this.Buff, this.Source, this.Target, this.Duration, this.Period, this.isShowIcon)
                else
                    call Buff.onPeriodicAction.evaluate(this.Buff, this.Source, this.Target, this.Duration, this.Period, this.isShowIcon)
                endif
            endif
            
            return false
        endmethod
        
        method destroy takes nothing returns nothing
            local trigger t = Store.trigger[this]
            local thistype last = Data[0]
            local integer i = this.Buff.Store[0]
            
            loop
                exitwhen this.Buff.Store[i] == this or i == 0
                set i = i - 1
            endloop
            
            if i > 0 then
                set this.Buff.Store[i] = this.Buff.Store[this.Buff.Store[0]]
                set this.Buff.Store[this.Buff.Store[0]] = 0
            endif
            set this.Buff.Store[GetHandleId(this.Target)] = this.Buff.Store[GetHandleId(this.Target)] - 1
            call showIcon(this.Buff , this.Target, false)
            call this.Buff.onRemoveAction.evaluate(this.Buff, this.Source, this.Target, this.Duration, this.Period, false)
            
            // Swap data between last and this
            if this != last then
                set Data[this] = Data[last]
                set Data.unit[this] = Data.unit[last]
                set Data.real[this] = Data.real[last]
                set Store.trigger[this] = Store.trigger[last]
            endif
            
            set Data[0] = Data[0] - 1
            
            call clear(thistype[t])
            call clear(last)
            call DestroyTrigger(t)
        endmethod
        
        static method showIcon takes Buff b, unit t, boolean f returns nothing
            if f and b.Store[GetHandleId(t)]  > 0 then
                call UnitAddAbility(t, b.raw)
                call UnitMakeAbilityPermanent(t, true, b.raw)
            elseif not f and b.Store[GetHandleId(t)]  <= 0 then
                call UnitRemoveAbility(t, b.raw)
                call UnitRemoveAbility(t, b.rawBuff)
            endif
        endmethod
        
        static method getFirst takes Buff b, unit t returns thistype
            local thistype this = 0
            local integer i = 0
            if b.Store[GetHandleId(t)] > 0 then
                loop
                    set i = i + 1
                    set this = b.Store[i]
                    
                    if this.Target == t then
                        call BJDebugMsg(GetUnitName(t) + " with number " + I2S(this) + " is first!!!!")
                        return this
                    endif
                    
                    exitwhen i == b.Store[0]
                endloop
            endif
            return 0
        endmethod
        
        static method apply takes Buff b, unit s, unit t, real d, real p, boolean f returns thistype
            local thistype this
                
            if not b.isStack then
                set this = getFirst(b,t)
                if this != 0 then
                    call this.destroy()
                    call BJDebugMsg("Re-applied")
                endif
            endif
            
            set this = Data[0] + 1
            set Data[0] = this
            set Store.trigger[this] = CreateTrigger()
            set Data[this] = b
            set Data.unit[this] = t
            set Data.real[this] = d
            set Data.boolean[this] = f
            set Data[this.Id] = this
            set Data.unit[this.Id] = s
            set Data.real[this.Id] = p
            
            call TriggerRegisterTimerEvent(this.Trigger, p, true)
            call TriggerAddCondition(this.Trigger, Filter(function thistype.periodic))
            set this.Buff.Store[GetHandleId(t)]  = this.Buff.Store[GetHandleId(t)]  + 1
            
            set this.Buff.Store[0] = this.Buff.Store[0] + 1
            set this.Buff.Store[this.Buff.Store[0]] = this
            
            call showIcon(b,t,f)
            call this.Buff.onApplyAction.evaluate(this.Buff, this.Source, this.Target, this.Duration, this.Period, this.isShowIcon)
            call this.onApply()
            return this
        endmethod
        
        private static method onInit takes nothing returns nothing
            set Data = Table.create()
            set Store = Table.create()
        endmethod
    endstruct
    
endlibrary

JASS:
library br requires Buff

struct rage extends BuffList
    static Buff BuffRage
    
    method onApply takes nothing returns nothing
        call BJDebugMsg("ASASA")
    endmethod
    
    private static method onInit takes nothing returns nothing
        local unit s = CreateUnit(Player(0), 'Hpal', 0 , 0 , 0)
        local unit t = CreateUnit(Player(0), 'Hblm', 0 , 0 , 0)
        set BuffRage = Buff.create("Rage",'Arag','Brag', false)
        call BuffList.apply(BuffRage, s, t, 10, .03125, true)
        
    endmethod
endstruct
endlibrary

I used
JASS:
stub method onApply takes nothing returns nothing
endmethod
and run it after apply method.
When I create a struct extends BuffList

I declare method onApply but onApply didn't run :ogre_frown:

Anyone can help me :goblin_cry::goblin_cry:

Demo map below :fp:
 

Attachments

  • Demo Buff.w3x
    41.3 KB · Views: 40
Level 23
Joined
Apr 16, 2012
Messages
4,041
from what Ive read out of Muzzel's one(you linked it), you are actually misusing this. I think you should be calling this.apply, not BuffList.apply, because the way you do it, this gets converted into BuffList and BuffList's onApply is empty, and since it is already BuffList, it has no derived method onApply, whereas you are trying to fire Buff.onApply.

Also, the "correct" approach should be:

JASS:
    private static method onInit takes nothing returns nothing
        local unit s = CreateUnit(Player(0), 'Hpal', 0 , 0 , 0)
        local unit t = CreateUnit(Player(0), 'Hblm', 0 , 0 , 0)
        local thistype this = thistype.create()
        set BuffRage = Buff.create("Rage",'Arag','Brag', false)
        call this.apply(BuffRage, s, t, 10, .03125, true)
       
    endmethod
 
Level 11
Joined
Dec 3, 2011
Messages
366
from what Ive read out of Muzzel's one(you linked it), you are actually misusing this. I think you should be calling this.apply, not BuffList.apply, because the way you do it, this gets converted into BuffList and BuffList's onApply is empty, and since it is already BuffList, it has no derived method onApply, whereas you are trying to fire Buff.onApply.

Also, the "correct" approach should be:

JASS:
    private static method onInit takes nothing returns nothing
        local unit s = CreateUnit(Player(0), 'Hpal', 0 , 0 , 0)
        local unit t = CreateUnit(Player(0), 'Hblm', 0 , 0 , 0)
        local thistype this = thistype.create()
        set BuffRage = Buff.create("Rage",'Arag','Brag', false)
        call this.apply(BuffRage, s, t, 10, .03125, true)
       
    endmethod

Still fail!
:goblin_cry: No :goblin_cry:
 
Last edited:
Why do you extend your custom buff from BuffList and not from Buff? That makes absolutely no sense from a logical perspective.

Your entire object structure is completely out of whack as you basicly mix up BuffList and Buff, which makes this hard to read and confusing to use.

Take a look at Muzzel's BuffHandler again, it has a clear defined structure that easy to understand at first sight.
 
Level 11
Joined
Dec 3, 2011
Messages
366
Why do you extend your custom buff from BuffList and not from Buff? That makes absolutely no sense from a logical perspective.

Your entire object structure is completely out of whack as you basicly mix BuffList and Buff, which makes this hard to read and confusing to use.

Take a look at Muzzel's BuffHandler again, it has a clear defined structure that easy to understand at first sight.

I'm testing about stub method. BuffList or Buff is just a name, you know. Sort, clear and add documentation can make it read easier.

This is just a demo.

Why I use both function interface / stub method? That for user who used this system.

Anyway, thank for your notice that I have a new idea :ogre_hurrhurr::ogre_hurrhurr:

Thank so much :ogre_kawaii::ogre_kawaii:
 
Status
Not open for further replies.
Top