Archived copy of war3source.com, the War3Source forum (2009–2020), rebuilt from the Internet Archive by wc3mods.net. This page was captured on 2012-10-25 (original capture). Forum · All archived topics · Wiki · Bug tracker · Blog
Chat

War3:Source
October 24, 2012, 09:02:19 PM *
Welcome, Guest. Please login or register.
Did you miss your activation email?

Login with username, password and session length
News: Download: http://war3source.com/index.php?board=9.0
What is War3Source?: http://war3source.com/index.php?topic=200.0
Sample Stats: http://war3source.com/war3stats
Steam Community Group: http://steamcommunity.com/groups/war3source
War3Source SVN Checkout: http://ownageclan.com/svn/war3source/
War3Source servers: http://www.game-monitor.com/search.php?vars=war3_version=
 
   Home   Help Search Login Register  
Pages: [1]
  Print  
Author Topic: Introducing the new ward creation system!  (Read 393 times)
Invalid
Newbie
*
Posts: 48


View Profile Email
« on: November 03, 2011, 09:18:25 AM »

Been working with Necavi for the past few days to make a system for ward creation. Since I'm excited about this new feature, and nobody has given it a mention yet, I'm going to explain how it works, along with motivations for certain design decisions.

Our first concern was making wards more tangible within the code. The original way we did them was to create an infinite timer for ward "pulses". Within this timer, it would check every possible ward to see if it was "active" and trigger its pulse. This is ugly for two reasons. One, because the code has to look at EVERY ward every time the timer fires off. And two, because it meant wards could only pulse at set intervals (unless we did some even more ugly workarounds). So we scrapped that and came up with a new way to handle wards. At ward creation, a handle to the ward pulse timer is generated and stored. If the ward duration is finite, we create another timer to kill the pulse timer. This means that every ward now has a unique pulse timer, and can thus have unique properties associated with it. No more looping through every ward, and no more fixed pulse intervals.

Our second concern was abstractly separating the idea of a ward from any particular type of ward. We've seen damaging wards and healing wards, but there can be so many different types of wards with different effects. We wanted to make it easy for people to not only implement custom ward behavior, but to reuse that behavior without resorting to copy/paste. I've worked with making wards before and I can tell you how annoying it is. So we scrapped our fixed-behavior wards and created a system for developing and registering custom ward behaviors with the war3 system. The idea is remarkably similar to race creation.

So what does all of this amount to? 14 new natives and 4 new forwards, with room for expansion.

Let's talk about ward creation.
Relevant natives:
Code:
_:War3_CreateWard(client, Float:location[], radius, Float:duration, Float:pulseInterval, String:behavior[], any:data[]={0}, bool:selfInflict=false, War3WardAffinity:affinity=ENEMIES);
_:War3_GetWardBehavior(wardindex);
War3_GetWardLocation(wardindex, Float:location[]);
Float:War3_GetWardInterval(wardindex);
_:War3_GetWardRadius(wardindex);
_:War3_GetWardOwner(wardindex);
War3_GetWardData(wardindex, any:data[]);

When you call the War3_CreateWard function, a ward index is returned, which will be used extensively for other functions. Notice the parameters for ward creation. You need an owner id, location, radius, duration, pulse interval, and a behavior shortname. Optional parameters are data, selfInflict, and affinity. Data is specialized parameterization that is sent to ward behaviors to determine things like damage or heal amount. The selfInflict and affinity parameters determine what the ward will target. If selfInflict=true, it will trigger on its owner in addition to its targeting affinity. The possible affinities are ENEMIES, ALLIES, ALL, and SELF_ONLY. Note that if you do selfInflict=false and affinity=SELF_ONLY, this ward will not trigger on anybody. This can be used as a special type of ward that doesn't need to target anything.

So let's talk about ward behaviors.

Relevant natives:
Code:
_:War3_CreateWardBehavior(String:shortname[],String:name[],String:desc[]);
_:War3_GetWardBehaviorsLoaded();
War3_GetWardBehaviorName(id,String:retstr[],maxlen);
War3_GetWardBehaviorShortname(id,String:retstr[],maxlen);
War3_GetWardBehaviorDesc(id,String:retstr[],maxlen);
_:War3_GetWardBehaviorByShortname(String:shortname[]);

When War3_CreateWardBehavior is called, a behavior index is generated to identify that behavior. You'll need this index to identify your behavior throughout a ward's lifetime. By ward lifetime, I am, of course, referring to the forwarded ward events.

Forwards:
Code:
OnWardCreated(wardindex,behaviorID);
OnWardPulse(wardindex,behaviorID);
OnWardTrigger(wardindex,victim,owner,behaviorID);
OnWardExpire(wardindex,owner,behaviorID);

These forwards should be pretty self explanatory, so I'll be brief. When a ward "pulses" it fires off an OnWardPulse event. This is where you will want to implement the visual effects for your custom ward behaviors. When a ward pulses with a potential target in range, it will fire off an OnWardTrigger event. This is where you will want to implement the physical effects for your custom ward behaviors. Whenever a ward is removed from the map, an OnWardExpire event is fired off. Because the ward information is lost upon ward death, this one sends the owner's id and the behaviorID so that you can actually work with it. I may need to add additional information to this forward, so this probably won't be the end result of my labors.

Well that was a loooooong post. Thanks for reading, and I hope you're just as excited about this new feature as I am!
« Last Edit: May 13, 2012, 03:14:49 PM by Invalid » Logged
Ownz
Developer
Administrator
Hero Member
*****
Posts: 2046



View Profile WWW Email
« Reply #1 on: November 03, 2011, 11:39:38 AM »

excellent self thought process. we all learn through trial and error.
Logged

DarkEnergy
Ownz
Developer
Administrator
Hero Member
*****
Posts: 2046



View Profile WWW Email
« Reply #2 on: November 03, 2011, 12:05:10 PM »

do i have u on steam? if not http://steamcommunity.com/id/ownageclan
Logged

DarkEnergy
Glider⠠⠵
Global Moderator
Sr. Member
*****
Posts: 413


⠠⠵


View Profile
« Reply #3 on: November 03, 2011, 12:51:08 PM »

Glad my insights regarding ward behaviors were listened to so you guys came up with something better than just a generic heal/damage ward system Wink

I still think great parts of wards/auras can be combined into one engine. Wards are imho just stationary auras. I really like the forwards though - forwards are so much fun sometimes.
In my opinion all ward forwards should provide the behavior though. Since the effect both from the mathematical and effect standpoint will be related to the behavior you'll end up querying for the behavior each tick/pulse/creation/expire anyway.
« Last Edit: November 03, 2011, 12:54:18 PM by Glider⠠⠵ » Logged

Invalid
Newbie
*
Posts: 48


View Profile Email
« Reply #4 on: November 03, 2011, 03:50:00 PM »

In my opinion all ward forwards should provide the behavior

I could do that, but it's unnecessary. You can get the behavior through the native War3_GetWardBehavior(wardindex).

But you bring up a valid point: it will be rare that anybody needs to use that forward and doesn't need the ward behavior index. So I guess I'll add that to the forward despite redundancy.
Logged
Glider⠠⠵
Global Moderator
Sr. Member
*****
Posts: 413


⠠⠵


View Profile
« Reply #5 on: November 03, 2011, 05:38:44 PM »

Getting the ward behavior manually in each forward is redundancy. The only time I wouldn't want the behavior is when I have some generic effect applied. (For example whenever a Ward dies I put a explosion particle, then I wouldn't care what kind of ward it was)
Logged

Invalid
Newbie
*
Posts: 48


View Profile Email
« Reply #6 on: November 03, 2011, 07:08:31 PM »

You're right. Thought it through, and discovered that querying the info manually is less efficient than pushing it onto the forward.

I still think great parts of wards/auras can be combined into one engine. Wards are imho just stationary auras.

I might consider doing this, but I am skeptical at the moment. Several things are iffy to me, but maybe just because I might have to change my naming conventions or add even more natives/forwards. It would be a little awkward to have an OnWardOrAuraPulse forward, for example. I'd probably just have two forwards for that so it doesn't confuse people. But if I were going to do that I might as well just separate the two entirely. Ugh. I'm torn between uniting these two similar ideas and making things simple for the implementers. In this case, I just can't see simplicity residing happily with generality. Maybe I'm just shortsighted? I'll look into it and see what I can do some time.
Logged
Pages: [1]
  Print  
 
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.11 | SMF © 2006-2009, Simple Machines LLC Valid XHTML 1.0! Valid CSS!