public void UpdateState()
        {
            if (state == null)
            {
                state = new ItemState();
            }

            state.Enabled = gameObject.activeSelf;
            state.Name = gameObject.name;
            state.Position = gameObject.transform.position;
            state.Rotation = gameObject.transform.rotation;
        }
        /// <summary>
        /// New player is connecting to the game
        /// </summary>
        /// <param name="player">Player.</param>
        /// <param name="data">Data.</param>
        internal void OnPlayerConnecting(NearbyPlayer player, byte[] data)
        {
            PlayerInfo p = PlayerInfo.AddPendingPlayer(player, data);
            GameObject obj = owner.LevelManager.CreatePlayer(
                                 p.AvatarIndex, 
                                 p.DeviceId);

            PlayerController ctl = obj.GetComponent<PlayerController>();
            if (ctl != null)
            {
                ctl.Player = p;
                ctl.BroadcastMovement = true;

                // force the  movement message so the remote player moves to the 
                // assigned, random position.
                ItemState state = new ItemState();
                state.Enabled = obj.activeSelf;
                state.Name = obj.name;
                state.Position = obj.transform.position;
                state.PrefabIndex = p.AvatarIndex;
                state.Rotation = obj.transform.rotation;
                state.TileSetName = ItemState.PlayerTileSet;
                owner.LevelData.Add(state);
            }

            owner.CreatePlayerScorePanel(p);
        }
 /// <summary>
 /// Raises the score changed event.
 /// </summary>
 /// <param name="deviceId">Device identifier.</param>
 public void OnScoreChanged(string deviceId)
 {
     int score = PlayerInfo.GetScore(deviceId);
     ItemState state = new ItemState();
     state.Name = GameManager.ScoreChangedItemName + deviceId;
     state.PrefabIndex = score;
     state.TileSetName = deviceId;
     changesToShare[state.Name] = state;
 }
 /// <summary>
 /// Helper to send the change of a boolean property to the remote players.
 /// </summary>
 /// <param name="property">Property.</param>
 /// <param name="flag">If set to <c>true</c> flag.</param>
 public void OnObjectChanged(string property, bool flag)
 {
     ItemState state = new ItemState();
     state.Name = property;
     state.Enabled = flag;
     state.TileSetName = null;
     changesToShare[state.Name] = state;
 }
        /// <summary>
        /// Creates the player.
        /// </summary>
        /// <returns>The player.</returns>
        /// <param name="index">Index.</param>
        /// <param name="suffix">Suffix.</param>
        public GameObject CreatePlayer(int index, string suffix)
        {
            GameObject obj = GetPlayerObject(suffix);
            if (obj == null)
            {
                obj = Instantiate(
                    playerAvatars[index % playerAvatars.Length],
                    RandomPosition(),
                    Quaternion.identity) as GameObject;
                obj.name = ItemState.PlayerTileSet + suffix;
                myObjects[obj.name] = obj;

                ItemState item = new ItemState();
                item.Enabled = obj.activeSelf;
                item.Name = obj.name;
                item.Position = obj.transform.position;
                item.Rotation = obj.transform.rotation;
                item.PrefabIndex = index;
                item.TileSetName = ItemState.PlayerTileSet;
                obj.GetComponent<Shareable>().State = item;
            }

            return obj;
        }
        /// <summary>
        /// Setups the scene.
        /// SetupScene initializes our level and calls the previous
        /// functions to lay out the game board
        /// </summary>
        /// <param name="level">Level number being laid out.</param>
        /// <returns>The list of itemState objects representing the scene.</returns>
        public List<ItemState> SetupScene(int level)
        {
            // Creates the outer walls and floor.
            BoardSetup();

            // Reset our list of gridpositions.
            Initialize();

            List<ItemState> items = new List<ItemState>();

            // Instantiate a random number of food tiles based on
            // minimum and maximum, at randomized positions.
            items.AddRange(
                LayoutObjectAtRandom(
                    ItemState.DropTileSet,
                    dropTiles,
                    dropCount.minimum,
                    dropCount.maximum));

            // use a log progression to get harder
            int logval = (int)Mathf.Log(level, 2f);

            int enemyCount = logval * 3;

            // Instantiate a random number of enemies based on minimum
            // and maximum, at randomized positions.
            items.AddRange(
                LayoutObjectAtRandom(
                    ItemState.EnemyTileSet,
                    enemyTiles,
                    enemyCount,
                    enemyCount));

            // layout the buzzers
            int buzzerCount = Random.Range(1, logval);
            items.AddRange(
                LayoutObjectAtRandom(
                    ItemState.DeadlyTileSet,
                    deadlyTiles,
                    buzzerCount,
                    buzzerCount));

            // put the exit somewhere, but keep don't activate it.
            Vector3 pos = RandomPosition();
            exitObj = Instantiate(exitTile, pos, Quaternion.identity) as GameObject;
            exitObj.SetActive(false);
            exitObj.name = ItemState.ExitTileSet + "_" + pos.x + "_" + pos.y;
            ItemState item = new ItemState();
            item.Enabled = false;
            item.Name = exitObj.name;
            item.Position = pos;
            item.Rotation = Quaternion.identity;
            item.PrefabIndex = 0;
            item.TileSetName = ItemState.ExitTileSet;
            exitObj.GetComponent<Shareable>().State = item;
            items.Add(item);

            return items;
        }
        /// <summary>
        /// Creates the item.
        /// </summary>
        /// <returns>The item.</returns>
        /// <param name="item">Item.</param>
        public GameObject CreateItem(ItemState item)
        {
            GameObject prefab;

            if (myObjects.ContainsKey(item.Name) && myObjects[item.Name] != null)
            {
                return myObjects[item.Name];
            }

            if (item.TileSetName == ItemState.DropTileSet)
            {
                prefab = dropTiles[item.PrefabIndex];
            }
            else if (item.TileSetName == ItemState.DeadlyTileSet)
            {
                prefab = deadlyTiles[item.PrefabIndex];
            }
            else if (item.TileSetName == ItemState.EnemyTileSet)
            {
                prefab = enemyTiles[item.PrefabIndex];
            }
            else if (item.TileSetName == ItemState.ExitTileSet)
            {
                prefab = exitTile;
            }
            else if (item.TileSetName == ItemState.PlayerTileSet)
            {
                prefab = playerAvatars[item.PrefabIndex % playerAvatars.Length];
            }
            else
            {
                Debug.LogWarning("Unknown tile set: " + item.TileSetName + " for " + item.Name);
                return null;
            }

            GameObject obj = Instantiate(prefab, item.Position, item.Rotation) as GameObject;
            obj.name = item.Name;
            obj.GetComponent<Shareable>().State = item;
            myObjects[obj.name] = obj;

            return obj;
        }
        /// <summary>
        /// Layouts the object at random.
        /// LayoutObjectAtRandom accepts an array of game objects to choose
        /// from along with a minimum and maximum range for the number
        /// of objects to create.
        /// </summary>
        /// <param name="tileSet">the key of which set of tiles to randomly layout</param>
        /// <param name="tileArray">the array of prefabs to select from</param> 
        /// <param name="minimum">Minimum number of tiles to layout</param>
        /// <param name="maximum">Maximum number of tiles to layout</param>
        /// <returns>List of itemStates of the created objects</returns>
        internal List<ItemState> LayoutObjectAtRandom(
            string tileSet,
            GameObject[] tileArray,
            int minimum,
            int maximum)
        {
            // Choose a random number of objects to instantiate
            // within the minimum and maximum limits
            int objectCount = Random.Range(minimum, maximum + 1);

            List<ItemState> items = new List<ItemState>();

            // Instantiate objects until the randomly chosen limit
            // objectCount is reached
            for (int i = 0; i < objectCount; i++)
            {
                // Choose a position for randomPosition by getting
                // a random position from our list of available Vector3s
                // stored in gridPosition
                Vector3 randomPosition = RandomPosition();

                // Choose a random tile from tileArray and assign
                // it to tileChoice
                int index = Random.Range(0, tileArray.Length);
                GameObject tileChoice = tileArray[index];

                // Instantiate tileChoice at the position returned by
                // RandomPosition with no change in rotation
                GameObject obj = Instantiate(
                                     tileChoice,
                                     randomPosition,
                                     Quaternion.identity) as GameObject;
                
                string objName = tileSet + "_" + randomPosition.x +
                                 "_" + randomPosition.y;
                
                obj.name = objName;

                ItemState item = new ItemState();
                item.Enabled = true;
                item.Name = objName;
                item.Position = randomPosition;
                item.Rotation = Quaternion.identity;
                item.PrefabIndex = index;
                item.TileSetName = tileSet;
                obj.GetComponent<Shareable>().State = item;
                items.Add(item);
            }

            return items;
        }