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

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

Status
Not open for further replies.
Level 29
Joined
Feb 2, 2006
Messages
1,691
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:
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.
 
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:
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.
 
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 :(
 
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) )
 
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.
Back
Top