System BuffStruct

Renendaru

(Evol)ution is nothing without love.
Reaction score
309
I suppose he means separate buffs, which are annotated by a higher level in the description, which is purely aesthetics. Most people copy the same buff over and all.
 

Kenny

Back for now.
Reaction score
202
I guess if you want levels right now, you could just use a textmacro and have the level of the buff written out in the tooltip or something.

I'd love to see this updated with some of the things viikuna was talking about. :)
 

Jesus4Lyf

Good Idea™
Reaction score
397
I'd love to see this updated with some of the things viikuna was talking about. :)
I'm still thinking carefully about how to add them in a maintainable way. I don't intend to rush it. :)

>I guess if you want levels right now, you could just use a textmacro and have the level of the buff written out in the tooltip or something.

I'll probably update this to support leveled buffs. It's really easy, aesthetically speaking. I actually intended to do it when I handled buff stacking properly. But once again, thinking carefully and not rushing...

... I just need this interface for a map of mine, I'm starting for real. :)
 

Grundy

Ultra Cool Member
Reaction score
35
Depends what you mean by levels. Can you give an example?

When you cast a spell like Frost Nova on a unit it get's the Frost Nova buff and when you mouse over the buff the tooltip tells you what level it is, like what level of Frost Nova you were hit with. And that goes for every spell and aura that leaves a buff.

I suppose he means separate buffs, which are annotated by a higher level in the description, which is purely aesthetics. Most people copy the same buff over and all.

I wouldn't call it purely aesthetic. It is something visual but I can be more helpful than that. If I'm playing against a level 5 Lich and I can't see what abilities enemy heroes have learned, all I know is that he could have level 3 Frost Nova. Then I see him cast Frost Armor on himself, and Dark Ritual for mana. I select his hero and put my mouse over his Frost Armor buff and it says level 3. Now I know he has put 3 skill points into Frost Armor and I saw him use Dark Ritual so I know he put at least 1 into that skill so then I know he either doesn't have Frost Nova or it is level 1.

If some hero has a DoT spell that has a longer duration the higher level it is, the buff would show the level of the ability that was cast and I'd know either it's going to wear off quickly or it's going to last a while and I better go heal up if my HP is low.

Also, if you want a buff to do something different (like maybe just some kind of multiplier) depending on the level you could have 1 spell 1 buff and check the level of the buff and handle everything the same way instead of creating a bunch of copies of the same buff with the only difference being 1 value somewhere in the code.

I think adding levels to buffs should be an easy thing to do. It uses Slow Aura to apply buffs right? A method like setLevel on the BuffStruct could just set the level of the Slow Aura which would automatically set the level of the buff and getLevel could return the level of the buff.
 

Jesus4Lyf

Good Idea™
Reaction score
397
Also, if you want a buff to do something different (like maybe just some kind of multiplier) depending on the level you could have 1 spell 1 buff and check the level of the buff and handle everything the same way instead of creating a bunch of copies of the same buff with the only difference being 1 value somewhere in the code.
That's already possible using struct members.
I think adding levels to buffs should be an easy thing to do. It uses Slow Aura to apply buffs right? A method like setLevel on the BuffStruct could just set the level of the Slow Aura which would automatically set the level of the buff and getLevel could return the level of the buff.
The problem is what if a unit is targetted by both level 2 and level 3 of a buff, and the order they wear off, etc. I need to design carefully, it'll take some time. :)
 

Grundy

Ultra Cool Member
Reaction score
35
That's already possible using struct members.
Oh, I know that. I was refering to the way Kenny suggested, creating copies of the buffs where the only difference is the level in the tooltip. Then there would be lots of duplicated code.

Jesus4Lyf is probably getting sick of me. I just think CasterStruct BuffStruct and Status are so awesome I want to use them + Damage for all my spells so I'm trying to learn how to use them all to do what I want.
 

Lehona

New Member
Reaction score
12
I just move over a Integer through the onCreate-method - but thats just for some math in the buff and not for displaying.
 

Viikuna

No Marlo no game.
Reaction score
265
Bumb.

I requests something like this:


JASS:


scope SilenceResistance initializer Init

private function Action takes nothing returns nothing
    local unit u=GetBuffedUnit()
    local buff b=GetTriggerBuff()
    local bufftype t=GetBuffType(b)
    local buff b2=UnitGetBuffOfType(u,SILENCE_RESISTANCE_BUFF )
    if IsBuffTypeInClass(t,BUFF_CLASS_SILENCE) and b2 != 0 then 
        call SetBuffDuration(b,GetBuffDuration(b)*Multiplier(GetBuffLevel(b2)))
    endif
    set u=null
endfunction

private function Init takes nothing returns nothing
     call OnBuffAdd( Action ) 
endfunction


endscope
 

Jesus4Lyf

Good Idea™
Reaction score
397
I requests something like this
That's inherantly flawed - who says buffs have durations? What about auras, or invisibilities where they're removed on attack? Also, there is a better way of doing it:

Make a silence resistance buff. Apply it for resistance. Make your silencing buffs call check, in onApply, is SilenceResistance.isOn(this.unit). Change the duration manually inside there.

It is a lot more logical instead of programming specifics into a global setting (using a global style Event for something specific to a few buffs).

But I totally agree on MyBuffType[unit]. The problem there is what if it has the buff twice? I propose to return the last instance added, or maybe the first. I'm not sure which, hence why I haven't added this yet either. Thinking carefully...
Jesus4Lyf is probably getting sick of me. I just think CasterStruct BuffStruct and Status are so awesome I want to use them + Damage for all my spells so I'm trying to learn how to use them all to do what I want.
Actually, it's really great to have someone else using and commenting on stuff. It helps keep in mind what I might like to do in the future and how I should support flexibility in my systems. ;)
 

Tukki

is Skeleton Pirate.
Reaction score
29
This is pretty cool!

Anyway, I'm just wondering if there's an easy way to get a unit's buff instance? Or is it up to the user to store them in an array?
I've currently solved the problem, but I'm looking for something neater :p

JASS:

    // seek
    mybuff     instance;
    function seek(BuffStruct i){
        if (i.getType()==mybuff.typeid)
            instance = i;
    }
    
    public function GetUnitBuff(unit who)->mybuff{
        BuffList[who].forEachBuff(BUFF_ALIGNMENT_NEGATIVE,seek);
        return instance;
    }

    // mybuff = some buff
    // both <instance>.getType() and <struct>.typeid are normal vJass features, and not Zinc-only-features


Edit:

As for the "which-instance-should-I-return"-question I do something like this:
I only allow one instance of the buff to be applied at any given time. My 'real' purpose behind that "seek" function is to find if the unit already has the buff applied, and if it does, grab the already existing and replace the newly created instance with it.
But my buffs are designed in a special way; enabling them to 'stack'. Them structs being like;

(note: this is freehand so, please, no comments on indentation)
JASS:

.....
	
	real xPos[10]; // 10 being maximum number of stacks
	real yPos[10];
	integer end[10];
	integer stacks=0;

	private method periodic(){
  		integer i;
  		
		for (1<=i<=stacks){
    			if (end<i>==T32_Tick){
      				SetUnitX(unit,xPos<i>);
       				SetUnitY(unit,yPos<i>);
       
       				if (stacks&gt;1){ // update stacks
         				xPos<i>=xPos[stacks];
         				yPos<i>=yPos[stacks];
         				end<i>=end[stacks];
         				stacks-=1;
       				} else {
					break();
         				stopPeriodic();
         				destroy();
       				}
     			}
  		 }
	}

	implement T32x
	method onApply(){
  		mybuff f = GetUnitBuff(unit);
  		if (f!=0){
   			destroy();
    			this=f;

    			stacks+=1;
    			xPos[stacks]=GetUnitX(unit);
    			yPos[stacks]=GetUnitY(unit);
    			end[stacks]=T32_Tick+R2I(10.0*FPS);
  		} else {
    			stacks+=1;
    			xPos[1]=GetUnitX(unit);
    			yPos[1]=GetUnitY(unit);
    			end[1]=T32_Tick+R2I(10.0*FPS);
    			startPeriodic();
  		}
	}
</i></i></i></i></i></i>


But instead of manually using the 'stacks' member, it could be a part of the system.
Or you could do something priority-based stuff, I really don't know what's the most flexible.
 

Jesus4Lyf

Good Idea™
Reaction score
397
As far as I'm concerned, stacking is to be achieved by just having multiple instances of the same buff on the unit. This seems to work fine for all damage over times, knockbacks, etc, it just requires me to think carefully about how to record when to add/remove the buff from the tray, and what level it should be on the tray, maintaining a list of everything. I don't really want to store how many of each level of each buff is stored on each unit using hashtables, which is the O(1) way to do it I suppose, I think it's more appropriate (efficient) to do a forEach each time a buff is removed... still designing... :p

Your get instance thing is fine for now. I'll try to make something better some time in the future. ;)
 

Narks

Vastly intelligent whale-like being from the stars
Reaction score
90
Am I doing something wrong? The buff does not appear in the icon tray, and it looks like onApply is either not being called, or more likely armorPenalty is not being set to 5 before onApply is called.

JASS:

//! runtextmacro BuffType(&quot;BuffTaunt&quot;)
    //! runtextmacro SetBuffName(&quot;Taunted&quot;)
    //! runtextmacro SetBuffAlignment(&quot;NEGATIVE&quot;)
    //! runtextmacro SetBuffTooltip(&quot;This unit is being Taunted; it has reduced armor.&quot;)
    //! runtextmacro SetBuffIcon(&quot;ReplaceableTextures\\CommandButtons\\BTNDaggerOfEscape.blp&quot;)
//! runtextmacro BuffStruct()
    integer armorPenalty
    method onApply takes nothing returns nothing
        call Status[.unit].modArmorBonus(-.armorPenalty)
    endmethod
    method onRemove takes nothing returns nothing
        call Status[.unit].modArmorBonus(.armorPenalty)
    endmethod
//! runtextmacro EndBuff()


JASS:
scope AbilityWarriorTaunt

// == Configuration ==    
globals
    private constant integer ABILID             = &#039;A09W&#039;
    
    // Armor penalty amount
    private constant integer    ARMOR_PENALTY   = 5
    
    // Armor penalty duration
    private constant real       DURATION_BASE   = 5
    
endglobals
// == End of Config ==
// ================================================================

private struct Spell extends SpellStruct
    implement SpellStruct

    method onEffect takes nothing returns nothing
        local BuffTaunt b = BuffTaunt.create(targetUnit)
        set b.armorPenalty = ARMOR_PENALTY
        call b.destroyTimed(DURATION_BASE)
        call IssueTargetOrder(targetUnit, &quot;attack&quot;, caster)
    endmethod
    
    private static method onInit takes nothing returns nothing
        set thistype.abil = ABILID
    endmethod
endstruct

endscope
 

Jesus4Lyf

Good Idea™
Reaction score
397
Am I doing something wrong?
That all looks OK to me. Do you have a demo map? :(
I actually found once that that happened, and after a little while it just worked.
But it doesn't look inherently wrong, there (except you probably need to do BuffTaunt.create(null) and then b.setUnit(targetUnit) after setting parameters).
 

Narks

Vastly intelligent whale-like being from the stars
Reaction score
90
Well, it seems to work now. The create(null) thing works too. Maybe because I restarted NewGen?
 

Narks

Vastly intelligent whale-like being from the stars
Reaction score
90
Yeah, just tested this now with another buff. The buff works, but looks like the object data for the buff icon isn't created until you save the map, and restart NewGen. I am using the Test Map button, btw.
 

Viikuna

No Marlo no game.
Reaction score
265
That's inherantly flawed - who says buffs have durations? What about auras, or invisibilities where they're removed on attack?


If buff has duration of 0, it means that its duration is inifinitive, so setting duration to duration * x does absolutely nothing for auras and other buffs with 0 duration.

Using global events for stuff like this might look like a waste, but its actually pretty nice when you start to add new stuff.

Of course you can make some wrapper function for silence, which does all stuff like this before doing that actual silence thingy and inject stuff to your silence spells that way, but it just looks better this way.

Its easier to for example disable silence resistance trigger for debugging purposes, and leave some other silence modification thingy running, when they are in different scopes.

edit. Correction: All infinitive buffs have duration of 0, not other way around like I said before.
 

Zwiebelchen

You can change this now in User CP.
Reaction score
60
Dunno if it has been mentioned before, but which type of ability do you use to apply buffs? If you are using dummy auras hidden in disabled spellbooks, then you will require an invisible buff placer unit floating above the head of the unit with a small range aura the buffs needs.

The problem with using dummy auras is, that removing a dummy aura from a unit closes the spellbook, if the player has it opened.

If you are not using dummy auras, my bad, but then again, how do you do the buff stacking? Afaik only aura buffs stack.
 
General chit-chat
Help Users
  • No one is chatting at the moment.

      The Helper Discord

      Staff online

      Members online

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top