• 🏆 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!
  • ✅ Time to vote for the top 3 models! The POLL for Hive's 6th HD Modeling Contest: Mechanical is now open! 📅 Poll close on July 16, 2024! 🔗 Cast your vote now!
  • ✅ The POLL for Hive's Texturing Contest #33 is OPEN! Vote for the TOP 3 SKINS! 🔗Click here to cast your vote!

Region-specific and player-specific unit invisiblity

Status
Not open for further replies.
Level 4
Joined
Jan 7, 2011
Messages
72
I am creating a multi-storey building system and I need units on the bottom floor to be incapable of seeing units on the top floor.

The best solution I have come up with so far is giving units permanent invisibility and true sight when they enter the top floor (and removing those abilities when they return to the bottom floor). The problem, however, is that units with permanent invisibility look transparent to the players controlling those units and I want them to appear completely normal.

Any suggestions?
 
Level 25
Joined
Jul 10, 2006
Messages
3,315
You could locally set each unit's model size to 0% for the other players, although this doesn't prevent them from being targetted.

  • Actions
    • Set MyPlayerVariable = the player that the unit must be hidden for
    • Custom script: if GetLocalPlayer() == udg_MyPlayerVariable then
    • Animation - Change unit's size to 0%, 0%, 0%
    • Custom script: endif
This will change the unit's size to 0% for only player MyPlayerVariable.

Do you have a custom movement system for the multi stories? I'm really interested to see how you did it, since I recently came to the ultimate conclusion that bridges that can be walked under simply cannot work.
 
Level 4
Joined
Jan 7, 2011
Messages
72
Thanks for the help, ruler. Unfortunately, I should have been clearer in my OP: there might be multiple player-controlled units on each floor. So I need a trigger that will change the size of units on the top floor for all players who don't have a unit on the top floor.

Could I use an integer array to track which level a unit is on (e.g. set the array value for a unit to 1 when it enters the bottom floor and 2 when it enters the top floor), and then use a trigger that changes the size of all units with an array value of 2 for all players who control units with an array value of 1?

The movement system is pretty easy. I just turn off collisions for units when they enter the building and place regions around anything that has pathing. Then, when units enter those regions, I turn collisions back on for them.

I'll be uploading my test map as soon as it is finished. The last piece of the puzzle is this business of hiding units on the top floor from those on the bottom one.
 
Level 4
Joined
Jan 7, 2011
Messages
72
I hope to have it ready in a day or two.

If I want to change the size of a unit to hide it from more than one player, should I add the players from whom the unit should be hidden to a player group variable? Or should I allocate each player to its own variable like in your example?
 
Level 25
Joined
Jul 10, 2006
Messages
3,315
I hope to have it ready in a day or two.

If I want to change the size of a unit to hide it from more than one player, should I add the players from whom the unit should be hidden to a player group variable? Or should I allocate each player to its own variable like in your example?

The easiest would be to just do it one by one, but you can do this:

  • Player Group - pick every player in group and do actions
    • Loop - Actions
      • Custom script: if GetLocalPlayer() == GetEnumPlayer() then
      • // do things
      • Custom script: endif
 

Chaosy

Tutorial Reviewer
Level 40
Joined
Jun 9, 2011
Messages
13,198
that will make for every player, if you want a more configurable trigger you could use this
  • better
    • Events
      • Map initialization
    • Conditions
    • Actions
      • Custom script: set udg_p = GetLocalPlayer()
  • even better
    • Events
    • Conditions
    • Actions
      • Player Group - Pick every player in (All players) and do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • Or - Any (Conditions) are true
                • Conditions
                  • p Equal to Player 1 (Red)
                  • p Equal to Player 2 (Blue)
                  • p Equal to Player 3 (Teal)
            • Then - Actions
              • -------- action stuff here --------
            • Else - Actions
 
Level 4
Joined
Jan 7, 2011
Messages
72
Thanks, guys! Both of those triggers make perfect sense but I have a few more questions.

I want to pick the players from whom a unit must be hidden based on whether they control units that are on the same level as the triggering unit. I was planning to do this by using an array to assign every player-controlled unit a value: 0 = it isn't in the building; 1 = it is on the first floor; 2 = it is on the second floor; etc.

So the trigger that I have in mind would work something like this:

Event - A unit enters the second floor

Action (1) - Change the array value of the triggering unit to 2

Action (2) - Pick every player that does not control a unit with an array value of 2 and change the triggering unit's size to 0%

Action (3) - Change the unit size of every unit with an array value of 2 to 100% for the player who controls the triggering unit

So here are my questions:

1. In theory, should this trigger work? (i.e. hide units from players who don't control units on the same floor)

2. I am not terribly familiar with variables. Should I use an array or a hashtable?

3. How would I actually change a unit's particular array / hashtable "floor" value when it enters a certain floor? I know how to make simple variable changes using "set variable", but how do I reference a specific unit's array / hashtable "slot"?

4. If I want to hide a unit from all players in a group, how would I place players in that group based on the "floor" values of the units that they control? Again, I know how to use simple variable references ("if variable = X then do action) but how do I reference the specific array / hashtable "slot" for each player's units?

I know I am asking for a lot of help here, so I apologise if this comes across as a lazy request for someone to write my entire trigger for me. I think I "get it" in theory, but I have very limited experience in practice.
 
Level 6
Joined
Nov 24, 2012
Messages
218
Well, I'll take a shot but I'm not very knowledgeable.

1. Yes but don't forget to do actions 2 and 3 locally to the specified players only.

2. I would say use array since it's faster. However, I would just use Player Groups.
You either have 1 array for each Floor or 1 array for each player, or use Unit Indexer.
I assume each player is in control of 1 unit only, or this whole thing is impossible.

3&4. You reference the array by player #, but you'd need one boolean array for each floor or player, I pick floor. Unit indexer works too. My method below uses none of those, instead it uses just a Player Group with Array (IsOnFloor, pardon me if it sounds like a boolean, I had it as boolean at first but changed to Player Group and kept the same name).

5. Use kLoader (http://www.hiveworkshop.com/forums/...multiple-warcraft-3-running-single-pc-226287/) to test your triggers, I recommend trying with 3 WC3s opened locally when ur done.

I'm trying to clarify this but I'm confused myself. I hope Iron helps you out.

Here is my proposal on one way to go about doing this. Certainly not the best.
Also I can't guarantee this works.

  • Magic Setup 1
    • Events
      • Unit - A unit enters Floor 1
    • Conditions
    • Actions
      • Set TempInt = 1
      • Set TempUnit = (Entering unit)
      • Set TempPlayer = (Owner of (Triggering unit))
      • Trigger - Run Magic Action (checking conditions)
  • Magic Setup 2
    • Events
      • Unit - A unit enters Floor 2
    • Conditions
    • Actions
      • Set TempInt = 2
      • Set TempUnit = (Entering unit)
      • Set TempPlayer = (Owner of (Triggering unit))
      • Trigger - Run Magic Action (checking conditions)
  • Magic Setup 3
    • Events
      • Unit - A unit enters Floor 3
    • Conditions
    • Actions
      • Set TempInt = 3
      • Set TempUnit = (Entering unit)
      • Set TempPlayer = (Owner of (Triggering unit))
      • Trigger - Run Magic Action (checking conditions)
  • Magic Setup 4
    • Events
      • Unit - A unit enters Floor 4
    • Conditions
    • Actions
      • Set TempInt = 4
      • Set TempUnit = (Entering unit)
      • Set TempPlayer = (Owner of (Triggering unit))
      • Trigger - Run Magic Action (checking conditions)
  • Magic Action
    • Events
    • Conditions
    • Actions
      • Animation - Change TempUnit's size to 0% of its original size
      • -------- This is nonlocal change, only 100% size (same floor) will be local player change. --------
      • For each (Integer A) from 1 to 4, do (Actions)
        • Loop - Actions
          • Player Group - Remove (Owner of TempUnit) from IsOnFloor[(Integer A)]
      • Player Group - Add (Owner of TempUnit) to IsOnFloor[TempInt]
      • -------- Flush the player groups and re-add to this floor only! --------
      • -------- Prepare for LocalPlayer change below, I don't know how to use GetLocalPlayer, but it starts below --------
      • Player Group - Pick every player in IsOnFloor[TempInt] and do (Actions)
        • Loop - Actions
          • Custom script: if GetLocalPlayer() == GetEnumPlayer() then
          • Animation - Change TempUnit's size to 100% of its original size
          • Custom script: endif
      • -------- This change here is local player only, ask someone else how, I don't know how to use GetLocalPlayer --------
      • -------- I picked all players in same floor and set entering unit's size to normal for them --------
Currently testing with 3 WC3's on LAN... not working very well :/ Help anyone?
I give up. How hard can it be to set it so each floor is only visible to the people on that floor?
I can't do this T_T
 
Last edited:
Level 4
Joined
Jan 7, 2011
Messages
72
Thanks for your suggestions, HesitationSnow.

Yes, each player can only control one unit. I may try create a more advanced system involving multiple units for each player later.

I decided to try use a Player Group and Unit Group array to assign every unit (and its owner) a "floor" value. But my trigger still isn't working since units aren't hidden from players who don't control a unit on the same floor. This is what I came up with:

  • Enter building
    • Events
      • Unit - A unit enters Building Entrance <gen>
    • Conditions
    • Actions
      • Unit - Turn collision for (Triggering unit) Off
      • Player Group - Add (Owner of (Triggering unit)) to Player_Floor[2]
      • Unit Group - Add (Triggering unit) to Unit_Floor[2]
      • Player Group - Pick every player in Player_Floor[1] and do (Actions)
        • Loop - Actions
          • Custom script: if GetLocalPlayer() == GetEnumPlayer() then
          • Set Transparency = 0.00
          • Custom script: endif
          • Unit Group - Pick every unit in Unit_Floor[2] and do (Animation - Change (Picked unit)'s size to (Transparency%, Transparency%, Transparency%) of its original size)
      • Player Group - Pick every player in Player_Floor[2] and do (Actions)
        • Loop - Actions
          • Custom script: if GetLocalPlayer() == GetEnumPlayer() then
          • Set Transparency = 100.00
          • Custom script: endif
          • Unit Group - Pick every unit in Unit_Floor[2] and do (Animation - Change (Picked unit)'s size to (Transparency%, Transparency%, Transparency%) of its original size)
      • Player Group - Pick every player in Player_Floor[3] and do (Actions)
        • Loop - Actions
          • Custom script: if GetLocalPlayer() == GetEnumPlayer() then
          • Set Transparency = 0.00
          • Custom script: endif
          • Unit Group - Pick every unit in Unit_Floor[2] and do (Animation - Change (Picked unit)'s size to (Transparency%, Transparency%, Transparency%) of its original size)
 
Level 4
Joined
Jan 7, 2011
Messages
72
OK, so I figured out the problem with the trigger that I posted (I wasn't removing players and units from the group array slots that I was adding them to in other triggers).

However, now I have a new problem. The top floor destructables are hidden correctly when units enter a specific region using this trigger:

  • Approach building
    • Events
      • Unit - A unit enters Building Approach <gen>
    • Conditions
      • ((Triggering unit) is in Unit_Floor[1]) Equal to True
    • Actions
      • Custom script: if GetLocalPlayer() == GetOwningPlayer(GetTriggerUnit()) then
      • Set House_Hide = False
      • Custom script: endif
      • Destructible - Pick every destructible in Building <gen> and do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • Or - Any (Conditions) are true
                • Conditions
                  • (Destructible-type of (Picked destructible)) Equal to Brick Roof
                  • (Destructible-type of (Picked destructible)) Equal to Level 2: Table
            • Then - Actions
              • Custom script: call ShowDestructable( GetEnumDestructable(), udg_House_Hide )
            • Else - Actions
Those same destructables are supposed to be unhidden when units enter the same region provided that they aren't in unit group array [1] (the slot assigned to units that are outside the building). That trigger isn't working and looks like this:

  • Exit building
    • Events
      • Unit - A unit enters Building Approach <gen>
    • Conditions
      • ((Triggering unit) is in Unit_Floor[1]) Equal to False
    • Actions
      • Custom script: if GetLocalPlayer() == GetOwningPlayer(GetTriggerUnit()) then
      • Set House_Hide = True
      • Custom script: endif
      • Destructible - Pick every destructible in Building <gen> and do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • Or - Any (Conditions) are true
                • Conditions
                  • (Destructible-type of (Picked destructible)) Equal to Brick Roof
                  • (Destructible-type of (Picked destructible)) Equal to Level 2: Table
            • Then - Actions
              • Custom script: call ShowDestructable( GetEnumDestructable(), udg_House_Hide )
            • Else - Actions
      • Unit - Turn collision for (Triggering unit) On
      • Player Group - Remove (Owner of (Triggering unit)) from Player_Floor[2]
      • Player Group - Add (Owner of (Triggering unit)) to Player_Floor[1]
      • Unit Group - Remove (Triggering unit) from Unit_Floor[2]
      • Unit Group - Add (Triggering unit) to Unit_Floor[1]
      • Animation - Change (Triggering unit)'s size to (100.00%, 100.00%, 100.00%) of its original size
I thought that there might be a problem with a conditional trigger, so I created another trigger that displays the player and unit group array values for all players and units. Using that trigger, I can see that the destructibles aren't being unhidden even for units that are definitely in unit group array [1].

Can anyone see what might be going wrong here?
 
Level 4
Joined
Jan 7, 2011
Messages
72
Collisions are turned off for units inside the building except when they enter regions to control pathing.
 
Status
Not open for further replies.
Top