• 🏆 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!

vJASS Ability Standard?

Status
Not open for further replies.
Level 21
Joined
Mar 27, 2012
Messages
3,232
I've been thinking of a way to make abilities in such a way, that I would rarely have to tinker with them and that I could use them in any way possible (separate from units, for example).

For clarification, I don't suggest this for the spell section, but rather for personal use. If someone else wants to pick it up, then sure, but it shouldn't be an official standard due to the high amount of extra work required.

I would like to know what more I could add to this before starting to convert the abilities.

1. All triggered abilities are based on channel or charge gold/lumber.
2. There are 12 versions of each ability to cover all possible slots.
3. Every ability comes with an objectmerger script line that can be toggled off to prevent it from being remade on every save. This script line creates the ability.
4. Ability scripts are preconfigured to use the IDs that objectmerger assigns to them. Using a utility to generate IDs upon compilation is not allowed, unless it's predictable what IDs it assigns.
5. Abilities support configuration in a separate library, to keep the actual script intact.
6. Each ability slot uses a specific hotkey and order ID, no matter the ability. This is to prevent collisions and promote consistency.
7. Each ability has 102 levels with cooldowns varying from 0-100 and the last being 99999.
8. Configuration inside object editor should be minimized; spells gain most of their attributes from code.
9. Abilities are registered to the system and don't individually check for when they are cast. The system detects which ability is cast and launches the appropriate triggers automatically.

Slots:
M-S-H-A
P-D-F-G
Q-W-E-R

Order IDs:
M - move
S - stop
H - holdposition
A - attack
P - patrol
D - ambush
F - banish
G - corrosivebreath
Q - taunt
W - dispel
E - slow
R - absorbmana

Viable free IDs(easy to trigger their abilities):
absorb
acidbomb
ambush
antimagicshell
banish (through a dummy caster. Duration to be handled internally)
corrosivebreath
taunt
dispel
slow
healingward
lightningshield
evileye(sentry ward)
stasistrap
absorbmana

API:
SetAbilityCooldown(unit,integer) - Each unit has an integer per ability, which defines the cooldown of this specific ability. Upon casting it (SPELL_EFFECT), the system changes the level of ability to this level and returns it back to normal after a 0-second timer. The timer makes it possible to only require the first level of the ability to have a description. Other levels still need to have numeric object data to prevent issues.
SetAbilityManacost(unit,integer) - It can be kept 0 if the ability handles it itself or uses a non-static cost. When the ability is cast it is checked whether the unit has enough mana. If not, then the cooldown and ability effects are prevented(SetAbilityCooldown)
SetAbilityVarInt(unit,whichint,amount)
SetAbilityVarReal(unit,whichreal,amount) - Those 2 are for ability data, such as damage, area of effect, etc.
UnitGrantAbility(unit,ability,slot) - Adding abilities to units through the normal function shouldn't be done, because then each spell would be required to check for 12 ability IDs.
The slots are from left to right and from up to down. If -1 is input for slot, then the first free one is used.

All stats are kept in arrays with unit ID(from indexer) and don't need a function to get them due to this. A simple array read will do.
 
Level 26
Joined
Aug 18, 2009
Messages
4,097
Not everything can be done via Channel or Charge Gold/Lumber. The versioning of abilities multiplies per attribute. Your 12 slots, 102 cooldowns already makes up 1224 objects/levels and you would usually want to have leveling of abilities in the sense of Warcraft III, too -> >5k for 5 levels. And you want to realize it via object modifications? It also takes a toll on the id pool and map size. The max native cooldown is 5 minutes. Having configurations as written code is not quite optimal either.
 
Level 12
Joined
Feb 22, 2010
Messages
1,115
Yeah, that each ability 102 level thing makes it hard, unless it is a map with small number of heroes.So this can't be standard.
 
Level 21
Joined
Mar 27, 2012
Messages
3,232
This part can be done quite easily with text macros and objectmerger combined.
I have to note that I was the one to benchmark how much different kinds of object editor data affect the loading time. Only strings are costly and channel only uses strings for actual text, unlike some abilities (*cough* raise dead *cough*)

Although yes, 102 levels means longer script lines. Currently I see nothing else to configure by ability levels than cooldown, because mana cost can and should be handled internally for the sake of consistency and because all of the ability data can be kept in variables.

The only downside I see to the user of my approach is that object merger will take a lot of time to initially make the abilities.
 
Level 23
Joined
Apr 16, 2012
Messages
4,041
the biggest concern here is that you can only have around 8k user-generated abilities, not that the map would take terribly long to load(most likely, the jass initializators would run for longer than the object load)

if you use externalblock, it will be in a whim, Ive generated 198 abilities(the ones in CSS 1.5g by doomlord) in roughly 2 seconds. ObjectMerger is only slow with one line external call, because that has to call the exe for every object. If you pass in the lua script, it will only execute the program once
 
Level 21
Joined
Mar 27, 2012
Messages
3,232
the biggest concern here is that you can only have around 8k user-generated abilities, not that the map would take terribly long to load(most likely, the jass initializators would run for longer than the object load)

if you use externalblock, it will be in a whim, Ive generated 198 abilities(the ones in CSS 1.5g by doomlord) in roughly 2 seconds. ObjectMerger is only slow with one line external call, because that has to call the exe for every object. If you pass in the lua script, it will only execute the program once

Just having an ability with >8k levels isn't a problem though(just tested with 17k levels).
In the worst case a map like dota with all abilities custom would be around 100*4*12 abilities, which is still not enough to break this(4800).
This thing about externalblock was new to me, but I think it's not usable, because lua doesn't work for everyone last time I heard.
 
Level 21
Joined
Mar 27, 2012
Messages
3,232
Not everything can be done via Channel or Charge Gold/Lumber. The versioning of abilities multiplies per attribute. Your 12 slots, 102 cooldowns already makes up 1224 objects/levels and you would usually want to have leveling of abilities in the sense of Warcraft III, too -> >5k for 5 levels. And you want to realize it via object modifications? It also takes a toll on the id pool and map size. The max native cooldown is 5 minutes. Having configurations as written code is not quite optimal either.

Forgot to respond to the levelling part earlier.

The way I intend to do things is that all ability power comes from some variables, such as hero attributes.
The reason I prefer written configuration is that object editor is dauntingly slow, especially when it would be possible to modify 12 abilities at a time through changing the textmacro input(12 near-identical abilities).
I didn't really have a need for such automation before I started to make abilities portable and implemented slot allocation.
Ability levels themselves are actually cheap. It's the text that costs.
 
Level 12
Joined
Feb 22, 2010
Messages
1,115
Just having an ability with >8k levels isn't a problem though(just tested with 17k levels).
In the worst case a map like dota with all abilities custom would be around 100*4*12 abilities, which is still not enough to break this(4800).
This thing about externalblock was new to me, but I think it's not usable, because lua doesn't work for everyone last time I heard.

What about ability fields?Did you change them to non-default things.
 
Level 26
Joined
Aug 18, 2009
Messages
4,097
The setobjecttype function of ObjectMerger is slow as it loads and rebuilds the corresponding meta slk as a dictionary everytime. Instead of repeating this costly task, you can buffer the inputs with an own tool and in the end run Object Merger once. But external calls are kinda expensive themselves and then again, you could as well write slk or outsource the object creation.
 
Level 21
Joined
Mar 27, 2012
Messages
3,232
What about ability fields?Did you change them to non-default things.

I did not, but if the limit is around 8k, then the fields shouldn't matter. Ofc I can repeat this test with changed fields, but I don't think it'd make a difference really.
The setobjecttype function of ObjectMerger is slow as it loads and rebuilds the corresponding meta slk as a dictionary everytime. Instead of repeating this costly task, you can buffer the inputs with an own tool and in the end run Object Merger once. But external calls are kinda expensive themselves and then again, you could as well write slk or outsource the object creation.

So far I've used one objectmerger line per ability. I bet this is the slowest approach, but as long as the abilities are made within 5 minutes I'm fine with that.
 
Level 21
Joined
Mar 27, 2012
Messages
3,232
And for icons?
You need for having all icons to multiply the number of abilities by hundreds?

Why would I? Icons should be a part of the configuration and thus, I don't have to precreate every single possibility. Perhaps I'd even make it somehow configurable which ability slots will be made, if I figure out a good way. This would probably requires lua. I'll do some tests to see if it works for me.
 
Level 15
Joined
Aug 7, 2013
Messages
1,337
This sounds promising.

I've made a pseudo api with items/units, e.g. below is the code/api for generating quest items.

JASS:
	//[[ Desert Flower
	//! i igol = 0
	//! i iico = "ReplaceableTextures\\CommandButtons\\BTNDryadDispelMagic.blp"
	//! i ifil = "Objects\\InventoryItems\\Shimmerweed\\Shimmerweed.mdl"
	//! i ides = "A rare desert flower.  It smells like something rotting."
	//! i unam = "Desert Flower"
	//! i write_item(unam, ides, ifil, iico, igol)
	//]]

That script is its own JASS file, and it works by itself (well behind the scenes not really, but it's a high level illusion).

So are you trying to set a standard for how abilities should be made, or an API for making abilities?
 
Level 21
Joined
Mar 27, 2012
Messages
3,232
Somewhat both. There has to be a standard to how they are written, otherwise it couldn't be guaranteed that SetAbilityCooldown works for every ability.
Then again it needs an API, because object creation and ability registering should be done automatically once configuration is there (no more painfully looking up and writing down object IDs).
 
Level 15
Joined
Aug 7, 2013
Messages
1,337
Ah so this sounds like how one would make a custom item system, right?

Have a couple of "blank" items to use as templates, and then behind the scenes trigger each one using bonus mod, etc., to allow for infinite items from only a small set of actual item objects.

Is this the correct analogy to what you are trying to do?
 
Level 21
Joined
Mar 27, 2012
Messages
3,232
Ah so this sounds like how one would make a custom item system, right?

Have a couple of "blank" items to use as templates, and then behind the scenes trigger each one using bonus mod, etc., to allow for infinite items from only a small set of actual item objects.

Is this the correct analogy to what you are trying to do?

Not entirely. Each ability would still have actual object editor abilities to match it (7-12 of them). Those abilities have descriptions, but any non-constant numbers are not written there, because they are defined in the library and may change mid-game.

All ability effects are still triggered though. For instance, I already have functions for timed armor and damage bonuses. I'll rewrite them to have something that resembles buffs by API though, so it would be possible to make custom dispel abilities.

Each buff would have an integer type that is defined in the specific ability library. Thus, it can be something like 'BBuf'. Furthermore, if such an ability also exists in object editor, then it will be added to the unit upon granting the buff.
 
Status
Not open for further replies.
Top