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

Primary Attribute Comparison ?

Status
Not open for further replies.
Level 7
Joined
Oct 8, 2007
Messages
154
Hi
I want to make a trigger condition like

  • ai
    • Events
      • ...
    • Conditions
      • ((Triggering unit) is A Hero) Equal to True
      • ((Owner of (Triggering unit)) controller) Equal to Computer
      • ((Triggering unit) Primary Attribute) Equal to Strengh
  • Actions
  • ....
But I don't have idea how to check what is the primary attribute of unit when it is a hero
 

Dr Super Good

Spell Reviewer
Level 64
Joined
Jan 18, 2005
Messages
27,198
Most of the time, the largest attribute is the primary attribute so you can often get away with such a simple assumption. However this is not always the case and especially in item dependant maps it is possible that a player can stack a non-primary attribute higher than his prime (although this is usually a bad idea from a strategic point of view).

The only other way is to hard code a lookup table of sorts that maps a unit type (which are integers in reality, GUI hides this) to its prime attribute. Such a table usually is implemented as a hashtable for optimum performance. If you plan to use the table to map multiple values to a unit type, consider using parallel arrays (like a struct) for the actual data and the hashtables to hold a reference to the data.
 
Level 7
Joined
Oct 8, 2007
Messages
154
Thank you for advice your idea seems best because we are working on AI and Issuing different orders to it depending of hero Primary Attribute.

So according to your idea I shall write 3 different triggers each of them will be ai for different type of heroes. I see you are experienced modder, so may I ask if this for would work well ?


for ex this would be a trigger issuing orders to computer players which hero Primary Attribute is intelligence.
  • ai
    • Events
      • Unit - A unit comes within 15000.00 of int 0006 <gen>
    • Conditions
      • ((Triggering unit) is A Hero) Equal to True
      • ((Owner of (Triggering unit)) controller) Equal to Computer
      • (Intelligence of (Triggering unit) (Exclude bonuses)) Greater than (Agility of (Triggering unit) (Exclude bonuses))
      • (Intelligence of (Triggering unit) (Exclude bonuses)) Greater than (Strength of (Triggering unit) (Exclude bonuses))
    • Actions
      • Unit - Order (Triggering unit) to Move To (Center of (Playable map area))
 

Dr Super Good

Spell Reviewer
Level 64
Joined
Jan 18, 2005
Messages
27,198
Sounds like it will result in too much procedural coupling to be useful.

I advise the use of a case like statement (since JASS does not support this, use a multiple if then elseif then... else endif statement with a script block representing each case. GUI can do something like this with nested if blocks but this results in less optimized and readable code.

This way you can have 1 trigger control the decisions for all hero types saving on the extra trigger and event overhead.

To prevent procedural coupling with discerning the prime attribute, I would advise using a variable to cache the decision and have a trigger decide the moment the moment the AI chooses the hero. This would mean it only gets evaluated once and you can then use a much simpler value to evaluate with. An example would be 1 = strength, 2 = agility and 3 = intelligence. You could then tell if a hero is intelligence based simply by testing if its prime attribute value == 3.

If you do not want to cache the results, you could write a function which does all the decision logic and returns such an integer. In any case the idea is to move the decision logic into one place which you then reference instead of duplicating it everywhere. This not only can make triggering faster as you have to create less duplicate script / actions each time but also results in smaller script and reduces chances of a copying error occurring.
 
Level 37
Joined
Mar 6, 2006
Messages
9,240
  • Untitled Trigger 116
    • Events
      • Map initialization
    • Conditions
    • Actions
      • Hashtable - Create a hashtable
      • Set hash = (Last created hashtable)
      • -------- ------------------------------------------------------------ --------
      • Custom script: call SaveInteger(udg_hash, 'Hpal', 0, bj_HEROSTAT_STR)
      • Custom script: call SaveInteger(udg_hash, 'Hblm', 0, bj_HEROSTAT_INT)
      • Custom script: call SaveInteger(udg_hash, 'Obla', 0, bj_HEROSTAT_AGI)
      • -------- ------------------------------------------------------------ --------
      • Custom script: set udg_i = LoadInteger(udg_hash, GetUnitTypeId(GetTriggerUnit()), 0)
      • -------- ------------------------------------------------------------ --------
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • i Equal to 0
        • Then - Actions
          • Game - Display to Player Group - Player 1 (Red) for 5.00 seconds the text: STR
        • Else - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • i Equal to 1
            • Then - Actions
              • Game - Display to Player Group - Player 1 (Red) for 5.00 seconds the text: AGI
            • Else - Actions
              • Game - Display to Player Group - Player 1 (Red) for 5.00 seconds the text: INT

Press Ctrl + D in object editor to see raw codes. Replace those Obla (Blademaster), Hpal (Paladin) and HBlm (Blood Mage) with your unit types.

The load function and if/then/else you can use in the detection trigger.

I used a variables named i and hash, but you can use whatever you like. Remember to replace the variable names in the custom scripts.
 
Status
Not open for further replies.
Top