System BuffStruct

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 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. :)
 
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. :)
 
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.
 
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. :)
 
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.
 
I just move over a Integer through the onCreate-method - but thats just for some math in the buff and not for displaying.
 
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
 
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. ;)
 
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.
 
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. ;)
 
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
 
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).
 
Well, it seems to work now. The create(null) thing works too. Maybe because I restarted NewGen?
 
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.
 
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.
 
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.
  • Varine Varine:
    A probate is usually done with a will, yes? If so I am sorry for your loss
    +1
  • The Helper The Helper:
    Yeah Tom, me too sorry for your loss buddy my mom told me she finds out her olds friend died from Google searching them. She had not talked to one of her old friends in a year and found out she died from Google. Also another one in the same session. RIP all of them my sincere condolences Tom
    +1
  • Varine Varine:
    We have some elderly guests that regularly come hang out at the bar at the end of the night, and every once in a while we don't see someone for a few weeks and then someone shows up with their obituary.
  • Varine Varine:
    We usually let them do their memorials there in the morning if they want to and I'll make them some snacks and drinks. There was one guy named Tom that came in like every night and would sit by himself and get a bunch of soup and a glass of wine. idk why but he LOVED our fucking soup, like he would order a fucking quart of it at a time and would always get so sad when we stop doing it for the summer.
    +1
  • Varine Varine:
    But he also loved our calamari, which is another thing I hate but it sells super well so I can't change it. There was one day he came in and was asking me how to make it, because he tried to at home once in the off season when we stop running it and he really wanted it lol
  • Varine Varine:
    I think he's one of the only people I've made recipes for for free because he really wanted a broccoli cheddar, and it was like dude I don't have a recipe, it's just whatever I have, but here, this is how you do it
  • Varine Varine:
    I don't think he ever figured out how to do the calamari in a pan though, like idk how to do that either. He was afraid of the at home deep fryers though and it's like yeah, that's fair, I am too
  • Varine Varine:
    He was just such a sweet old man, we had two servers pregnant and they held a baby shower together, he was soooooo fucking excited to get to see a baby. Unfortunately he died a month or so before they were born
  • The Helper The Helper:
    So I decided to Google some people that I had not seen or heard from in a while and sure enough one of my old best friends, we had a falling out years ago but whatever, find out he died of Pancreatic Cancer in January. I have also lost a few of my closer acquaintances from growing up the last year. Getting old - people die - I kinda thought it was going to be this way a few years ago....
    +2
  • The Helper The Helper:
    Forum running super slow again
  • Ghan Ghan:
    Not really clear from the stats as to what is causing the slowness.
  • Ghan Ghan:
    We get a lot of guest traffic so it may just be the load is getting too high and not from any particular source.
  • Ghan Ghan:
    Looks like the server is maxed out on CPU.
  • Ghan Ghan:
    Oh it looks like a lot of the traffic is Silkroad Forums. That domain isn't protected by Cloudflare.
  • Ghan Ghan:
    But the old Silkroad site is still on its own server. I just had a test site set up on this server for it.
  • Ghan Ghan:
    I just disabled that test site. Let's see if that helps the load.
  • Ghan Ghan:
    Looks much better already.
  • The Helper The Helper:
    I had actually forgot about the Silkroad site. I had asked
  • The Helper The Helper:
    SD Ryoko about it and he said the couple of people left on there really like it, that was a few years ago, maybe I should check back
  • jonas jonas:
    I guess when you're getting old, and the last day of soup season draws near, you start wondering
  • jonas jonas:
    will I make it to the start of the next season? or was this the last time I'll ever have my favorite dish?
  • The Helper The Helper:
    I am doing my first Vibe Coding project. In installed the environment and tools according to instructions but it is all chat doing this for me at my direction. It is fun really and holy shit I might finish in 2 hours what it would have taken a day to in my Access and this would be an electron app complete new
  • Ghan Ghan:
    Good stuff.
  • Ghan Ghan:
    Just make sure it is secure. :)
  • The Helper The Helper:
    It will only be on internal network

      The Helper Discord

      Members online

      No members online now.

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials
      Top