• Check out the results of the Techtree Contest #19!
  • Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
  • Read Evilhog's interview with Gregory Alper, the original composer of the music for WarCraft: Orcs & Humans 🔗Click here to read the full interview.
  • Create a void inspired texture for Warcraft 3 and enter Hive's 34th Texturing Contest: Void! Click here to enter!
  • The Hive's 22nd Icon Contest: Creep Abilities is now concluded, time to vote for your favourite set of icons! Click here to vote!

Targets Allowed - Categorized

Level 10
Joined
Jun 30, 2017
Messages
90
Considering every once in a while we get questions about this topic on Discord, I thought it'd be a good idea to immortalize this tidbit of knowledge. These are the categories of Targets Allowed fields in object editor:

Code:
// Category 1 - Target Type
None = 0x1
Ground = 0x2
Air = 0x4
Structure = 0x8
Ward = 0x10
Item = 0x20
Tree = 0x40
Wall = 0x80
Debris = 0x100
Decoration = 0x200
Bridge = 0x400

Category 1 Default = Ground | Air | Structure
Category 1 Unit Default = Ward | Ground | Air | Building
Category 1 Item Default = Item
Category 1 Destructible Default = Bridge | Decoration | Debris | Wall | Tree

// Category 2 - Alliances
Hidden = 0x800  (this one doesn't exist in the editor, but does in game)
Self = 0x1000
Player Units = 0x2000
Allied = 0x4000
Neutral = 0x8000
Enemy = 0x10000
Friend = Allied | Player Units
Not-self = Enemy | Neutral | Allied | Player Units

Category 2 Default = Enemy | Neutral | Allied | Player Units | Self

// Category 3 - Invulnerability
Vulnerable = 0x100000
Invulnerable = 0x200000

Category 3 Default = Vulnerable

// Category 4 - Heroes
Hero = 0x400000
Non-Hero = 0x800000

Category 4 Default = Non-Hero | Hero

// Category 5 - Life
Alive = 0x1000000
Dead = 0x2000000

Category 5 Default = Alive

// Category 6 - Composition
Organic = 0x4000000
Mechanical = 0x8000000

Category 6 Default = Mechanical | Organic

// Category 7 - Sapper
Non-suicidal = 0x10000000
Suicidal = 0x20000000

Category 7 Default = Suicidal | Non-suicidal

//Category 8 - Ancient
Non-Ancient = 0x40000000
Ancient = 0x80000000

Category 8 Default = Ancient | Non-Ancient

Global Default =
(Ground | Air | Structure) &
(Self | Player Units | Allied | Neutral | Enemy) &
(Vulnerable) &
(Hero | Non-Hero) &
(Alive) &
(Organic | Mechanical) &
(Non-suicidal | Suicidal) &
(Non-Ancient | Ancient)

"Terrain" target type does not exist in game and it maps to nothing

The logic for Targets Allowed should be as follows:
A target can match only if ALL categories return true (AND operand), but in order for a category to return true, said target has to have any of the properties that belong in that category (OR operand).

If a target doesn't have any of the flags specified for a particular category, the game should fallback to the Defaults for that particular category.

Here's an example of what a Flying Machine can target:
1770670548486.png

In game's terms, Flying Machine can target objects with following properties (broken down in categories):
Category 1 - Air
Category 2 - (default), Enemy | Neutral | Allied | Player Units | Self
Category 3 - (default), Vulnerable
Category 4 - (default), Non-Hero | Hero
Category 5 - (default), Alive
Category 6 - (default), Mechanical | Organic
Category 7 - (default), Suicidal | Non-suicidal
Category 8 - (default), Ancient | Non-Ancient

Credits to sotzaii_shuen on Discord for fetching this info from somewhere.


Unfortunately, this info doesn't entirely explain this cursed field, so here's some findings after my testing.

Unit attacks do not evaluate Category 2 properties, at all

"Combat - Targeted as" field does not work for Categories 2 to 8;
  • if you want to make a unit targeted as Mechanical, Suicidal or Ancient, those have to be defined via Unit Classification
  • Alive/Dead only works if a unit is dead or not, no surprises there
  • Hero target type can only be set by making a unit a hero from the start
  • Invulnerable is set via Invulnerability (Neutral Passive) ability
  • Category 2 fields are straight up ignored

Category 1 has some interesting fields from unit's perspective. A unit can be set to be targeted as a: 'Bridge', 'Decoration', 'Debris', 'Tree' or a 'Wall', but it seems to have the same effect as if the unit was targeted as 'None'. Furthermore, Targets Allowed when using only 'Bridge', 'Decoration' or 'Debris' seem to be able to click on units to attack them, but it doesn't cancel the targeting icon on click, which happens if order was accepted. It keeps it active, but it doesn't show an error message (or play the error sound) as it would if you were to click on an invalid target, perhaps those types aren't as finished as the rest?

If Targeted as has only None selected, then it works as you'd expect, but if you combine it with another Category 1 property (e.g. Ground, None) then Ground takes priority. However, having Targets Allowed have None selected (with or without other Category 1 properties) causes the unit to be unable to attack and order goes through the unit instead of targeting the unit (Attack Move).

"None" also doesn't match if the attacker has it as Targets Allowed, and if the target has the Targetable as field only "None", which is an exception in comparison to other properties, presumably it exists as an option to reject the Category 1 Defaults that would normally apply. (Useful for giving a unit an attack it cannot use, so the attack icon is visible on UI)

TODO: Test Targeted As fields for Destructables,Doodads & Items

I'll be editing this thread once I finish a testing session.
 
Last edited:
https://github.com/lep/jassdoc/issues/129

"TERRAIN" returns 0 -- a bug?
With only "TERRAIN" enabled I think the game resets it to default from above. Everything works. I am not sure if TERRAIN is supposed to be there or do anything special. I thought they had just swapped terrain & none.
My conclusion is that the type "TERRAIN" practically doesn't exist (or is in some way an internal flag).
 
This explains a lot of confusion I've had over the years with the targeting system. I feel like a haze has been lifted from my eyes.
Unfortunately, the trouble doesn't end there. Turns out, unit attacks don't evaluate Category 2 at all, and "Combat - Targeted as" doesn't work for Categories 2 to 8, which probably added a lot towards that confusion.

Furthermore, someone had tried making a unit with 2 attacks, one which includes Ancients, and another that doesn't, and for whatever reason, the game kept using the non-ancient weapon on an Ancient target, so that requires testing to see what was going on.

I'll be editing this thread after doing each test session. But the current theory I have is that this targeting has 2 layers, 1 which is described here, how does the game interpret the editor values, and another one that is used in actual combat.

https://github.com/lep/jassdoc/issues/129


My conclusion is that the type "TERRAIN" practically doesn't exist (or is in some way an internal flag).
sotzaii_shuen said that Terrain doesn't map to anything in the game, and Hidden is an actual flag that is not visible in the editor.
 
I came here looking for a way to make a spell that can target units and points on the ground, but learned this is just for which units can be targeted and does not configure point targeting. For that I had to use the special "Channel" spell which has extra options in the world editor for configuring it to target units and points.

Also, in case you are using typescript to configure spells instead of the editor, note that there is a bug in the typescript library that makes it difficult to get the channel ability to show up: Bug: Can't Configure Channel Ability · Issue #27 · cipherxof/wc3-ts-template
 
Do you think Hidden relates to being able to target hidden units?
I tried to change targets allowed to how I believe it works with set udg_Boolean = BlzSetUnitWeaponIntegerField(udg_Unit[2], UNIT_WEAPON_IF_ATTACK_TARGETS_ALLOWED, 0, BlzGetUnitWeaponIntegerField(udg_Unit[2], UNIT_WEAPON_IF_ATTACK_TARGETS_ALLOWED, 0) + 2048) but it didnt work because it returns the same integer number as before when getting. I suppose it cant be changed with triggers or I did something wrong.
 
Back
Top