• 🏆 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!
  • 🏆 Hive's 6th HD Modeling Contest: Mechanical is now open! Design and model a mechanical creature, mechanized animal, a futuristic robotic being, or anything else your imagination can tinker with! 📅 Submissions close on June 30, 2024. Don't miss this opportunity to let your creativity shine! Enter now and show us your mechanical masterpiece! 🔗 Click here to enter!

[Trigger] Command button effects for a player only or changing ability icons during the game

Status
Not open for further replies.
Level 26
Joined
Feb 2, 2006
Messages
1,695
Hi,
I use command button effects from Reforged to indicate which unit types are spawned. Whenever I play alone or 1 vs 1 it seems to work but as soon as multiple players play the wrong buttons have an effect.

This is my trigger to create/recreate the effect:
  • Actions
    • Custom script: set udg_TmpHandle = udg_TmpUnit
    • Custom script: set udg_TmpInt2 = udg_TmpUnitType
    • For each (Integer A) from 0 to AllBarrackUnitTypesSize, do (Actions)
      • Loop - Actions
        • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
          • If - Conditions
            • TmpUnitType Equal to AllBarrackUnitTypes[(Integer A)]
          • Then - Actions
            • Custom script: set udg_TmpString2 = GetObjectName(udg_TmpInt2)
            • Hashtable - Save TmpInt as TmpInt2 of (Key TmpHandle.) in AllBarracksUnitTypes.
            • -------- Ability Command Effect --------
            • Custom script: set udg_TmpInt3 = Index2D(GetForLoopIndexA(), GetConvertedPlayerId(GetOwningPlayer(udg_TmpUnit)), 9)
            • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
              • If - Conditions
                • TmpInt Equal to 0
              • Then - Actions
                • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                  • If - Conditions
                    • AllBarracksCommandEffectsB[TmpInt3] Equal to True
                  • Then - Actions
                    • Game - Destroy Button Effect AllBarracksCommandEffects[TmpInt3]
                    • Set VariableSet AllBarracksCommandEffectsB[TmpInt3] = False
                  • Else - Actions
                    • Do nothing
              • Else - Actions
                • Custom script: call CreateCommandButtonEffectBJ(udg_AllBarrackUnitTypesAbilities[GetForLoopIndexA()], udg_AllBarrackUnitTypesOrders[GetForLoopIndexA()])
                • Set VariableSet AllBarracksCommandEffects[TmpInt3] = (Last created Button effect)
                • Set VariableSet AllBarracksCommandEffectsB[TmpInt3] = True
          • Else - Actions
            • Do nothing
    • Trigger - Run Update Unit Type Priority Floating Text <gen> (checking conditions)
As you can see I use an array of command button effects to store them and a boolean flag to indicate if one has been created or not.

The custom JASS function Index2D looks like this:
Code:
function Index2D takes integer value0, integer value1, integer maxValue1 returns integer
  return (value0 * maxValue1) + value1
endfunction

It should calculate the 2-dimensional index using the unit type (integer a) as value 0 and the player number as value 1. There is only one barrack per player, so the player number should be enough. One barrack has buttons for every unit type. When a unit type is enabled, the command effect should appear.

It works perfectly when I play alone but as I wrote I get issues playing with other players. Maybe the player number causes problems?
 
Last edited:
Level 26
Joined
Feb 2, 2006
Messages
1,695
I think I found the bug/solution. The problem is that commandbuttoneffects are not enabled per player or unit etc. I had a misunderstanding. Hence, they are either enabled globally or disabled globally. They are of no use in a multiplayer map :( Unfortunately, there is no show/hide function for them.

I will look for a different solution. Maybe I will try to change the icon of the specific ability being cast to indicate that the unit type is enabled or not.
 
Level 26
Joined
Feb 2, 2006
Messages
1,695
You think one can create a commandbuttoneffect for only one player without desyncs? My idea was to change the ability icon and tooltip text instead of using a commandbuttoneffect:

  • Set Unit Type Priority For Barracks
    • Events
    • Conditions
    • Actions
      • Custom script: set udg_TmpHandle = udg_TmpUnit
      • Custom script: set udg_TmpInt2 = udg_TmpUnitType
      • For each (Integer A) from 0 to AllBarrackUnitTypesSize, do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • TmpUnitType Equal to AllBarrackUnitTypes[(Integer A)]
            • Then - Actions
              • Custom script: set udg_TmpString2 = GetObjectName(udg_TmpInt2)
              • Hashtable - Save TmpInt as TmpInt2 of (Key TmpHandle.) in AllBarracksUnitTypes.
              • -------- Ability Icon --------
              • Set VariableSet TmpString = AllBarrackUnitTypesIcons[(Integer A)]
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • TmpInt Greater than 0
                • Then - Actions
                  • Custom script: set udg_TmpString = IconEnabled(udg_TmpString)
                  • Custom script: set udg_TmpString2 = GetObjectName(udg_TmpUnitType)
                  • Set VariableSet TmpString2 = (Disable + TmpString2)
                • Else - Actions
                  • Custom script: set udg_TmpString = IconDisabled(udg_TmpString)
                  • Custom script: set udg_TmpString2 = GetObjectName(udg_TmpUnitType)
                  • Set VariableSet TmpString2 = (Enable + TmpString2)
              • Game - Display to (All players) the text: (Change icon to: + TmpString)
              • Ability - Set Ability: (Unit: TmpUnit's Ability with Ability Code: AllBarrackUnitTypesAbilities[(Integer A)])'s String Level Field: Icon - Normal ('aart') of Level: 0 to TmpString
              • Ability - Set Ability: (Unit: TmpUnit's Ability with Ability Code: AllBarrackUnitTypesAbilities[(Integer A)])'s String Level Field: Icon - Normal ('aart') of Level: 0 to ReplaceableTextures\CommandButtons\BTNSelfDestructOn.blp
              • Ability - Set Ability: (Unit: TmpUnit's Ability with Ability Code: AllBarrackUnitTypesAbilities[(Integer A)])'s String Level Field: Tooltip - Normal ('atp1') of Level: 0 to TmpString2
              • Unit - For TmpUnit, Ability AllBarrackUnitTypesAbilities[(Integer A)], Hide ability: True
              • Unit - For TmpUnit, Ability AllBarrackUnitTypesAbilities[(Integer A)], Hide ability: False
            • Else - Actions
              • Do nothing
      • Trigger - Run Update Unit Type Priority Floating Text <gen> (checking conditions)
Changing the tooltip works however changing the icon does not have any effect. The ability change is for a unit only and hence works for a player only. As you can see I have tried to hide and show the ability again but still no effect.

Any idea why the icon change has no effect? This might be safer than using GetLocalPlayer().

edit:
I have the feeling that values like unit scaling when being changed haven't any effect as well? I tried to change a unit's scaling and it didn't change ingame. Can we just change the fields but some without any effect?
 
Last edited:
Level 19
Joined
Aug 16, 2007
Messages
881
I wouldn't trust the new ability fields, a lot of them don't work.

If you only want to create a CommandButtonEffect for a player you might be able to do something like this,

JASS:
function CreateCommandButtonEffectForPlayer takes player p, integer abilityId, string order returns commandbuttoneffect
    // If the player isn't the Local Player, then use 0 as abilityId (nothing) and null as order string;
    // this should in theory make the CommandButtonEffect invisible for all other players. The game might crash doing this, not sure.
    // I've not tested if it works, but the HandleId is the same for all players, so it shouldn't desync and is safe in multiplayer.
    if (GetLocalPlayer() != p) then
      set abilityId = 0
      set order = null
    endif
    
    set bj_lastCreatedCommandButtonEffect = CreateCommandButtonEffect(abilityId, order)
    return bj_lastCreatedCommandButtonEffect
endfunction

The only drawback using this method (if it works) is that you have to create multiple copies of the same CommandButtonEffect for every player using them.
 
Level 26
Joined
Feb 2, 2006
Messages
1,695
Yes I had that approach but without using a specific function for local player only. I fear desyncs. The command button effect has to be destroyed again as well. I guess this should happen for the local player only as well. I have to try it in a multiplayer map and see if there are desyncs or not. Another possibility would be to use two different abilities and replace the ability but then I need to create a second icon which shows that the type is enabled or not.

Isn't there any possibility with the new frame functions to modify the frame of an ability and add a border or some marker or some check? I don't want to create icons for every unit type with a check on them :(
 
Level 25
Joined
Sep 26, 2009
Messages
2,390
I checked the following action:
  • Ability - Set Ability: (Unit: TmpUnit's Ability with Ability Code: AllBarrackUnitTypesAbilities[(Integer A)])'s String Level Field: Icon - Normal ('aart') of Level: 0 to TmpString
and it really does work in the sense that it sets the value for "Icon - Normal" to the TmpString. However the new value is never used even when "refreshing" the ability.

Had to test it via custom script, since the GUI version of "Ability - Ability string level field" does not show the "Icon - Normal" option when you try to get the value.
In my case the script got the "Icon - Normal" string field for Fireball spell of my footman and printed it as message in game - the get method returned the new value, not the original, yet the icon remained as the original and not the new one :(
  • Custom script: call DisplayTextToForce( GetPlayersAll(), BlzGetAbilityStringLevelField(BlzGetUnitAbility(gg_unit_hfoo_0000, 'A000'), ABILITY_SLF_ICON_NORMAL, 0) )
 
Level 26
Joined
Feb 2, 2006
Messages
1,695
thx, so this means that the action does not change the icon, right? :( I could try to create two abilities per unit type and replace the ability.

Did anybody test the command button effect per player in multiplayer? I really do not want to go this way without being 100 % sure that there won't be any desync. I prefer the safe method with the ability icons.
 
Status
Not open for further replies.
Top