예제 #1
0
 private void TryFalling(ILevel level, TileCoordinates coordinates)
 {
     if (!IsSupported(level, coordinates))
     {
         Fall(level, coordinates);
     }
 }
예제 #2
0
 public override void OnSteppedOff(ILevel level, TileCoordinates coordinates, Robot.Robot robot, FlatDirection direction)
 {
     if (m_trigger == FallingTrigger.SteppedOn)
     {
         TryFalling(level, coordinates);
     }
 }
예제 #3
0
        public override void OnRenderLiquid(ILevel level, TileCoordinates coordinates, Geometry output)
        {
            // Render top
            var topLeft     = new Vector3(coordinates.X, coordinates.Y * 0.5f + 0.5f, coordinates.Z);
            var topRight    = new Vector3(coordinates.X + 1.0f, coordinates.Y * 0.5f + 0.5f, coordinates.Z);
            var bottomLeft  = new Vector3(coordinates.X, coordinates.Y * 0.5f + 0.5f, coordinates.Z + 1.0f);
            var bottomRight = new Vector3(coordinates.X + 1.0f, coordinates.Y * 0.5f + 0.5f, coordinates.Z + 1.0f);

            output.AddQuad(
                topLeft,
                topRight,
                bottomLeft,
                bottomRight,
                new Quad(coordinates.X * m_textureScale, coordinates.Z * m_textureScale, m_textureScale, m_textureScale),
                Vector4.One
                );
            output.AddQuad(
                bottomLeft,
                bottomRight,
                topLeft,
                topRight,
                new Quad(coordinates.X * m_textureScale, -coordinates.Z * m_textureScale, m_textureScale, m_textureScale),
                Vector4.One
                );
        }
예제 #4
0
 public void RemoveTelepad(string colour, TileCoordinates coordinates)
 {
     if (m_telepads.ContainsKey(colour))
     {
         m_telepads[colour].Remove(coordinates);
     }
 }
예제 #5
0
        public TileBehaviour GetBehaviour(ILevel level, TileCoordinates coordinates)
        {
            var baseCoords = GetBase(level, coordinates);
            var baseTile   = level.Tiles[baseCoords];

            return(baseTile.m_behaviour);
        }
예제 #6
0
        private void OnDirectionalStepOnOff(ILevel level, TileCoordinates coordinates, FlatDirection direction)
        {
            var tileDirection = level.Tiles[coordinates].GetDirection(level, coordinates);

            if (direction == (m_inverted ? tileDirection.Opposite() : tileDirection))
            {
                if (IsPowered(level, coordinates))
                {
                    SetPowered(level, coordinates, false, true);
                    if (m_soundPath != null)
                    {
                        level.Audio.PlaySound(m_soundPath);
                    }
                }
            }
            else if (direction == (m_inverted ? tileDirection : tileDirection.Opposite()))
            {
                if (!IsPowered(level, coordinates))
                {
                    SetPowered(level, coordinates, true, true);
                    if (m_soundPath != null)
                    {
                        level.Audio.PlaySound(m_soundPath);
                    }
                }
            }
        }
예제 #7
0
        public bool CanEnterOnSide(Robot.Robot robot, TileCoordinates coordinates, FlatDirection side, bool ignoreMovingObjects)
        {
            if (GetIncline(robot.Level, coordinates, side.Opposite()) <= 0 && IsSolidOnSide(robot.Level, coordinates, side.ToDirection()))
            {
                return(false);
            }
            if (IsOccupiedByNonVacatingRobot(robot.Level, coordinates, side, robot, ignoreMovingObjects))
            {
                return(false);
            }
            var belowCoords = coordinates.Below();
            var belowTile   = robot.Level.Tiles[belowCoords];

            if (belowTile.IsConveyor(robot.Level, belowCoords))
            {
                var conveyor          = (Conveyor)belowTile.GetEntity(robot.Level, belowCoords);
                var conveyorDirection = belowTile.GetDirection(robot.Level, belowCoords);
                if (conveyor.CurrentMode == ConveyorMode.Forwards)
                {
                    return(side != conveyorDirection);
                }
                else if (conveyor.CurrentMode == ConveyorMode.Reverse)
                {
                    return(side != conveyorDirection.Opposite());
                }
            }
            return(true);
        }
예제 #8
0
 public void AddHint(TileCoordinates coordinates)
 {
     if (!m_hints.Contains(coordinates))
     {
         m_hints.Add(coordinates);
     }
 }
예제 #9
0
        protected bool IsFaceHidden(ILevel level, TileCoordinates coordinates, Direction direction)
        {
            var tiles = level.Tiles;

            if (direction.IsFlat())
            {
                var adjoiningPos  = coordinates.Move(direction);
                var adjoiningSide = direction.Opposite();
                for (int i = 0; i < Tile.Height; ++i)
                {
                    var tile = tiles[adjoiningPos];
                    if (tile.IsHidden(level, adjoiningPos) || !tiles[adjoiningPos].IsOpaqueOnSide(level, adjoiningPos, adjoiningSide))
                    {
                        return(false);
                    }
                    adjoiningPos = adjoiningPos.Above();
                }
                return(true);
            }
            else if (direction == Direction.Up)
            {
                var adjoiningPos = coordinates.Move(Direction.Up, Tile.Height);
                var tile         = tiles[adjoiningPos];
                return(!tile.IsHidden(level, adjoiningPos) && tile.IsOpaqueOnSide(level, adjoiningPos, Direction.Down));
            }
            else //if(direction == Direction.Down)
            {
                var adjoiningPos = coordinates.Below();
                var tile         = tiles[adjoiningPos];
                return(!tile.IsHidden(level, adjoiningPos) && tile.IsOpaqueOnSide(level, adjoiningPos, Direction.Up));
            }
        }
예제 #10
0
        public override void OnSteppedOff(ILevel level, TileCoordinates coordinates, Robot.Robot robot, FlatDirection direction)
        {
            if (m_colour == null || robot.Colour == m_colour)
            {
                switch (m_type)
                {
                case ButtonType.Momentary:
                {
                    if (IsPowered(level, coordinates))
                    {
                        SetPowered(level, coordinates, false, true);
                        if (m_soundPath != null)
                        {
                            level.Audio.PlaySound(m_soundPath);
                        }
                    }
                    break;
                }

                case ButtonType.Directional:
                {
                    OnDirectionalStepOnOff(level, coordinates, direction);
                    break;
                }
                }
            }
        }
예제 #11
0
 public override void OnLevelStart(ILevel level, TileCoordinates coordinates)
 {
     if (!s_searching && !level.InEditor)
     {
         UpdateNetwork(level, coordinates);
     }
 }
예제 #12
0
        public bool SetSubState(TileCoordinates coordinates, int subState, bool notifyNeighbours)
        {
            var tile        = GetTile(coordinates);
            int oldSubState = tile.GetSubState(m_level, coordinates);

            if (subState != oldSubState)
            {
                ExpandToFit(coordinates);
                SetSubStateInternal(coordinates, subState);
                if (m_latestTimeStamp > 0.0f)
                {
                    var change = new TileChange();
                    change.Type        = TileChangeType.SubState;
                    change.TimeStamp   = m_latestTimeStamp;
                    change.Coordinates = coordinates;
                    change.OldSubState = oldSubState;
                    m_history.Push(change);
                }
                if (notifyNeighbours)
                {
                    tile.NotifyNeighboursChanged(m_level, coordinates);
                }
                return(true);
            }
            return(false);
        }
예제 #13
0
        public bool SetTile(TileCoordinates coordinates, Tile tile, FlatDirection direction = FlatDirection.North, bool notifyNeighbours = true)
        {
            var oldTile      = GetTile(coordinates);
            var oldDirection = oldTile.GetDirection(m_level, coordinates);

            if (tile != oldTile || direction != oldDirection)
            {
                int oldSubState = oldTile.GetSubState(m_level, coordinates);
                ExpandToFit(coordinates);
                SetTileInternal(coordinates, tile, direction, 0);
                if (m_latestTimeStamp > 0.0f)
                {
                    var change = new TileChange();
                    change.Type         = TileChangeType.Tile;
                    change.TimeStamp    = m_latestTimeStamp;
                    change.Coordinates  = coordinates;
                    change.OldTile      = oldTile;
                    change.OldDirection = oldDirection;
                    change.OldSubState  = oldSubState;
                    m_history.Push(change);
                }
                if (notifyNeighbours)
                {
                    tile.NotifyNeighboursChanged(m_level, coordinates);
                }
                return(true);
            }
            return(false);
        }
예제 #14
0
 private bool IsOccupiedByNonVacatingRobot(ILevel level, TileCoordinates coordinates, FlatDirection side, Robot.Robot exception, bool ignoreMovingRobots)
 {
     if (IsOccupied(level, coordinates))
     {
         var occupant = GetOccupant(level, coordinates);
         if (occupant is Robot.Robot)
         {
             var robot = (Robot.Robot)occupant;
             if (robot == exception)
             {
                 // Ignore ourselves
                 return(false);
             }
             if (ignoreMovingRobots && robot.IsMoving)
             {
                 // Ignore moving robots
                 return(false);
             }
             if (robot.Location != coordinates && robot.IsTurning)
             {
                 // Ignore robot reserving the space ahead of them when turning
                 return(false);
             }
             if ((robot.Location == coordinates || robot.Location == coordinates.Below()) &&
                 robot.Direction != side &&
                 robot.IsVacating)
             {
                 // Ignore robot about to leave
                 return(false);
             }
         }
         return(true);
     }
     return(false);
 }
예제 #15
0
 public Tile this[TileCoordinates coordinates]
 {
     get
     {
         return(GetTile(coordinates));
     }
 }
예제 #16
0
        private static bool ExploreNetwork(ILevel level, TileCoordinates coordinates, HashSet <TileCoordinates> o_coordinates)
        {
            if (!o_coordinates.Contains(coordinates))
            {
                o_coordinates.Add(coordinates);

                var  tile      = level.Tiles[coordinates];
                var  behaviour = (WireTileBehaviour)tile.GetBehaviour(level, coordinates);
                bool powered   = tile.IsPowered(level, coordinates);
                for (int i = 0; i < 6; ++i)
                {
                    var dir = (Direction)i;
                    if (behaviour.IsConnected(level, coordinates, dir))
                    {
                        var neighbourCoords = coordinates.Move(dir, (dir == Direction.Up) ? tile.Height : 1);
                        var neighbourTile   = level.Tiles[neighbourCoords];
                        if (neighbourTile.IsWire(level, neighbourCoords))
                        {
                            var neighbourBehaviour  = (WireTileBehaviour)neighbourTile.GetBehaviour(level, neighbourCoords);
                            var neighbourBaseCoords = neighbourTile.GetBase(level, neighbourCoords);
                            if (neighbourBehaviour.IsConnected(level, neighbourBaseCoords, dir.Opposite()))
                            {
                                powered = powered || ExploreNetwork(level, neighbourBaseCoords, o_coordinates);
                            }
                        }
                    }
                }
                return(powered);
            }
            return(false);
        }
예제 #17
0
 protected void OnRender(ILevel level, TileCoordinates coordinates, Geometry output, TextureAtlas textures)
 {
     if (!IsExtension())
     {
         m_behaviour.OnRender(level, coordinates, output, textures);
     }
 }
예제 #18
0
        public void NotifyNeighboursChanged(ILevel level, TileCoordinates coordinates)
        {
            if (IsExtension())
            {
                var below = coordinates.Below();
                level.Tiles[below].NotifyNeighboursChanged(level, below);
            }
            else
            {
                for (int y = 0; y < Height; ++y)
                {
                    for (int i = 0; i < 4; ++i)
                    {
                        var dir             = (Direction)i;
                        var neighbourCoords = new TileCoordinates(coordinates.X + dir.GetX(), coordinates.Y + y, coordinates.Z + dir.GetZ());
                        level.Tiles[neighbourCoords].OnNeighbourChanged(level, neighbourCoords);
                    }
                }

                var belowCoords = coordinates.Below();
                level.Tiles[belowCoords].OnNeighbourChanged(level, belowCoords);

                var aboveCoords = coordinates.Move(Direction.Up, Height);
                level.Tiles[aboveCoords].OnNeighbourChanged(level, aboveCoords);
            }
        }
예제 #19
0
 public void RenderShadows(ILevel level, TileCoordinates coordinates, Geometry output)
 {
     if (!IsHidden(level, coordinates))
     {
         OnRenderShadows(level, coordinates, output);
     }
 }
예제 #20
0
 public void Render(ILevel level, TileCoordinates coordinates, Geometry output, TextureAtlas textures)
 {
     if (!IsHidden(level, coordinates))
     {
         OnRender(level, coordinates, output, textures);
     }
 }
예제 #21
0
 protected void OnRenderShadows(ILevel level, TileCoordinates coordinates, Geometry output)
 {
     if (!IsExtension())
     {
         m_behaviour.OnRenderShadows(level, coordinates, output);
     }
 }
예제 #22
0
 public override void OnNeighbourChanged(ILevel level, TileCoordinates coordinates)
 {
     if (!s_searching && !level.InEditor)
     {
         UpdateNetwork(level, coordinates);
     }
 }
예제 #23
0
 public void AddTelepad(string colour, TileCoordinates coordinates)
 {
     if (!m_telepads.ContainsKey(colour))
     {
         m_telepads.Add(colour, new List <TileCoordinates>());
     }
     m_telepads[colour].Add(coordinates);
 }
예제 #24
0
 public override Entity CreateEntity(ILevel level, TileCoordinates coordinates)
 {
     if (level.InEditor)
     {
         return(new EditorRobot(Tile, coordinates));
     }
     return(null);
 }
예제 #25
0
 public override bool GetPowerOutput(ILevel level, TileCoordinates coordinates, Direction direction)
 {
     if (!s_searching && IsConnected(level, coordinates, direction))
     {
         return(Tile.GetSubState(level, coordinates) > 0);
     }
     return(false);
 }
예제 #26
0
 public void Shutdown(ILevel level, TileCoordinates coordinates)
 {
     OnShutdown(level, coordinates);
     for (int i = 1; i < m_height; ++i)
     {
         level.Tiles.SetTile(coordinates.Move(Direction.Up, i), Tiles.Air, FlatDirection.North, false);
     }
 }
예제 #27
0
 protected void OnShutdown(ILevel level, TileCoordinates coordinates)
 {
     if (!IsExtension())
     {
         SetEntity(level, coordinates, null);
         m_behaviour.OnShutdown(level, coordinates);
     }
 }
예제 #28
0
 public override bool GetPowerOutput(ILevel level, TileCoordinates coordinates, Direction direction)
 {
     if (IsConnected(level, coordinates, direction))
     {
         return(GetPowerOutput(level, coordinates));
     }
     return(false);
 }
예제 #29
0
        private void RebuildGeometry()
        {
            // Clear
            for (int i = 0; i < m_geometry.Length; ++i)
            {
                var geometry = m_geometry[i];
                geometry.Clear();
            }
            foreach (var liquidGeometry in m_liquidGeometry.Values)
            {
                liquidGeometry.Clear();
            }
            m_shadowGeometry.Clear();

            // Populate
            for (int x = MinX; x < MaxX; ++x)
            {
                for (int y = MinY; y < MaxY; ++y)
                {
                    for (int z = MinZ; z < MaxZ; ++z)
                    {
                        var here = new TileCoordinates(x, y, z);
                        var tile = GetTile(here);
                        if (!tile.IsExtension())
                        {
                            tile.Render(m_level, here, m_geometry[(int)tile.RenderPass], m_atlas);
                            if (tile.IsLiquid(m_level, here))
                            {
                                Geometry liquidGeometry;
                                var      behaviour = tile.GetBehaviour(m_level, here) as LiquidTileBehaviour;
                                if (!m_liquidGeometry.TryGetValue(behaviour, out liquidGeometry))
                                {
                                    liquidGeometry = new Geometry(Primitive.Triangles);
                                    m_liquidGeometry.Add(behaviour, liquidGeometry);
                                }
                                tile.RenderLiquid(m_level, here, liquidGeometry);
                            }
                            if (tile.CastShadows && tile.RenderPass == RenderPass.Opaque)
                            {
                                tile.RenderShadows(m_level, here, m_shadowGeometry);
                            }
                        }
                    }
                }
            }

            // Rebuild
            for (int i = 0; i < m_geometry.Length; ++i)
            {
                var geometry = m_geometry[i];
                geometry.Rebuild();
            }
            foreach (var liquidGeometry in m_liquidGeometry.Values)
            {
                liquidGeometry.Rebuild();
            }
            m_shadowGeometry.Rebuild();
        }
예제 #30
0
 public override void OnLevelStart(ILevel level, TileCoordinates coordinates)
 {
     if (!level.InEditor)
     {
         var direction     = level.Tiles[coordinates].GetDirection(level, coordinates);
         var initialAction = (m_immobile || level.InMenu) ? (RobotAction)RobotActions.LongWait : (RobotAction)RobotActions.PreSpawn;
         level.Entities.Add(CreateRobot(level, coordinates, direction, initialAction));
     }
 }