예제 #1
0
        private bool CanMoveTo_Cardinal__CanOccupy(int targetX, int targetY,
                                                   BlocksetBlockBehavior curBehavior, BlocksetBlockBehavior blockedTarget, bool checkElevation, byte curElevation)
        {
            // Get the x/y/map of the target block
            Map.GetXYMap(targetX, targetY, out int outX, out int outY, out Map outMap);
            Map.Layout.Block targetBlock = outMap.GetBlock_InBounds(outX, outY);
            // Check occupancy permission
            if ((targetBlock.Passage & LayoutBlockPassage.AllowOccupancy) == 0)
            {
                return(false);
            }
            // Check block behaviors
            BlocksetBlockBehavior targetBehavior = targetBlock.BlocksetBlock.Behavior;

            if (targetBehavior == BlocksetBlockBehavior.Surf || targetBehavior == blockedTarget)
            {
                return(false);
            }
            // Check elevation
            byte targetElevations = targetBlock.Elevations;

            if (checkElevation && !ElevationCheck(curBehavior, targetBehavior, curElevation, targetElevations))
            {
                return(false);
            }
            byte newElevation = GetElevationIfMovedTo(curElevation, targetElevations);

            // Check if we can pass through objs at the position
            if (CollidesWithAny_InBounds(outMap, outX, outY, newElevation))
            {
                return(false);
            }
            return(true);
        }
예제 #2
0
        private void ApplyStairMovement(Position curPos, BlocksetBlockBehavior upBehavior, BlocksetBlockBehavior downBehavior)
        {
            Map.Layout.Block      curBlock    = Map.GetBlock_InBounds(curPos.X, curPos.Y);
            BlocksetBlockBehavior curBehavior = curBlock.BlocksetBlock.Behavior;

            if (curBehavior == downBehavior)
            {
                Pos.Y++;
            }
            Position newPos = Pos;
            int      newX   = newPos.X;
            int      newY   = newPos.Y;

            Map.Layout.Block      upStairBlock    = Map.GetBlock_CrossMap(newX, newY - 1);
            BlocksetBlockBehavior upStairBehavior = upStairBlock.BlocksetBlock.Behavior;

            if (upStairBehavior == upBehavior)
            {
                Pos.Y--;
                Pos.YOffset = StairYOffset;
                return;
            }
            Map.Layout.Block      newBlock    = Map.GetBlock_CrossMap(newX, newY);
            BlocksetBlockBehavior newBehavior = newBlock.BlocksetBlock.Behavior;

            if (newBehavior == downBehavior)
            {
                Pos.YOffset = StairYOffset;
            }
            else
            {
                Pos.YOffset = 0;
            }
        }
예제 #3
0
        private bool CanPassThroughDiagonally(int x, int y, byte elevation, LayoutBlockPassage diagonalPassage,
                                              BlocksetBlockBehavior blockedCardinal1, BlocksetBlockBehavior blockedCardinal2, BlocksetBlockBehavior blockedDiagonal)
        {
            // Get the x/y/map of the block
            Map.GetXYMap(x, y, out int outX, out int outY, out Map outMap);
            Map.Layout.Block block = outMap.GetBlock_InBounds(outX, outY);
            // Check occupancy permission
            if ((block.Passage & diagonalPassage) == 0)
            {
                return(false);
            }
            // Check block behaviors
            BlocksetBlockBehavior blockBehavior = block.BlocksetBlock.Behavior;

            if (blockBehavior == blockedCardinal1 || blockBehavior == blockedCardinal2 || blockBehavior == blockedDiagonal)
            {
                return(false);
            }
            // Check if we can pass through objs at the position (only checks current elevation, not the target elevation or any other elevations)
            if (CollidesWithAny_InBounds(outMap, outX, outY, elevation))
            {
                return(false);
            }
            return(true);
        }
예제 #4
0
        // Temp - start a test wild battle
        public void TempCreateWildBattle(Map map, Map.Layout.Block block, EncounterTable.Encounter encounter)
        {
            Save sav      = Save;
            var  me       = new PBETrainerInfo(sav.PlayerParty, sav.PlayerName);
            var  wildPkmn = PartyPokemon.GetTestWildPokemon(encounter);
            var  wild     = new PBETrainerInfo(new Party {
                wildPkmn
            }, "Wild " + PBELocalizedString.GetSpeciesName(wildPkmn.Species).English);

            void OnBattleEnded()
            {
                void FadeFromTransitionEnded()
                {
                    _fadeFromTransition = null;
                }

                _fadeFromTransition = new FadeFromColorTransition(20, 0, FadeFromTransitionEnded);
                _battleGUI          = null;
            }

            _battleGUI = new BattleGUI(new PBEBattle(PBEBattleFormat.Single, PBESettings.DefaultSettings, me, wild,
                                                     battleTerrain: Overworld.GetPBEBattleTerrainFromBlock(block.BlocksetBlock),
                                                     weather: Overworld.GetPBEWeatherFromMap(map)),
                                       OnBattleEnded);
            void OnBattleTransitionEnded()
            {
                _battleTransition = null;
            }

            _battleTransition = new SpiralTransition(OnBattleTransitionEnded);
        }
예제 #5
0
        // Southwest/Southeast/Northwest/Northeast
        private bool CanMoveTo_Diagonal(int targetX, int targetY, bool allowSurf, LayoutBlockPassage neighbor1Passage, int neighbor1X, int neighbor1Y, LayoutBlockPassage neighbor2Passage, int neighbor2X, int neighbor2Y,
                                        BlocksetBlockBehavior blockedCurrentCardinal1, BlocksetBlockBehavior blockedCurrentCardinal2, BlocksetBlockBehavior blockedCurrentDiagonal,
                                        BlocksetBlockBehavior blockedTargetCardinal1, BlocksetBlockBehavior blockedTargetCardinal2, BlocksetBlockBehavior blockedTargetDiagonal,
                                        BlocksetBlockBehavior blockedNeighbor1, BlocksetBlockBehavior blockedNeighbor2)
        {
            // Current block - return false if we are blocked
            Position p = Pos;

            Map.Layout.Block      curBlock    = Map.GetBlock_InBounds(p.X, p.Y);
            BlocksetBlockBehavior curBehavior = curBlock.BlocksetBlock.Behavior;

            if (curBehavior == blockedCurrentCardinal1 || curBehavior == blockedCurrentCardinal2 || curBehavior == blockedCurrentDiagonal)
            {
                return(false);
            }
            // Target block - return false if we are blocked
            Map.GetXYMap(targetX, targetY, out int targetOutX, out int targetOutY, out Map targetOutMap);
            Map.Layout.Block targetBlock = targetOutMap.GetBlock_InBounds(targetOutX, targetOutY);
            if ((targetBlock.Passage & LayoutBlockPassage.AllowOccupancy) == 0)
            {
                return(false);
            }
            // Check block behaviors
            BlocksetBlockBehavior targetBehavior = targetBlock.BlocksetBlock.Behavior;

            if ((!allowSurf && Overworld.IsSurfable(targetBehavior)) ||
                targetBehavior == blockedTargetCardinal1 || targetBehavior == blockedTargetCardinal2 || targetBehavior == blockedTargetDiagonal)
            {
                return(false);
            }
            // Check elevation
            byte curElevation     = p.Elevation;
            byte targetElevations = targetBlock.Elevations;

            if (!ElevationCheck(curBehavior, targetBehavior, curElevation, targetElevations))
            {
                return(false);
            }
            byte newElevation = Overworld.GetElevationIfMovedTo(curElevation, targetElevations);

            // Check if we can pass through objs at the position
            if (CollidesWithAny_InBounds(targetOutMap, targetOutX, targetOutY, newElevation))
            {
                return(false);
            }
            // Target's neighbors - check if we can pass through them diagonally
            if (!CanPassThroughDiagonally(neighbor1X, neighbor1Y, curElevation, neighbor1Passage, blockedCurrentCardinal1, blockedTargetCardinal2, blockedNeighbor1) ||
                !CanPassThroughDiagonally(neighbor2X, neighbor2Y, curElevation, neighbor2Passage, blockedTargetCardinal1, blockedCurrentCardinal2, blockedNeighbor2))
            {
                return(false);
            }
            return(true);
        }
예제 #6
0
        // West/East
        private bool CanMoveTo_Cardinal_ConsiderStairs(int targetX, int targetY, BlocksetBlockBehavior blockedCurrent, BlocksetBlockBehavior blockedTarget,
                                                       BlocksetBlockBehavior upBehavior, BlocksetBlockBehavior downBehavior)
        {
            // Current block - return false if we are blocked
            Position p = Pos;

            Map.Layout.Block      curBlock    = Map.GetBlock_CrossMap(p.X, p.Y);
            BlocksetBlockBehavior curBehavior = curBlock.BlocksetBlock.Behavior;

            if (curBehavior == blockedCurrent)
            {
                return(false);
            }
            // Stairs - check if we can go up a stair that's above our target
            Map.GetXYMap(targetX, targetY - 1, out int upStairX, out int upStairY, out Map upStairMap);
            Map.Layout.Block upStairBlock = upStairMap.GetBlock_InBounds(upStairX, upStairY);
            if ((upStairBlock.Passage & LayoutBlockPassage.AllowOccupancy) != 0)
            {
                BlocksetBlockBehavior upStairBehavior = upStairBlock.BlocksetBlock.Behavior;
                if (upStairBehavior == upBehavior)
                {
                    // Check if we can pass through objs on the position
                    byte newElevation = GetElevationIfMovedTo(p.Elevation, upStairBlock.Elevations);
                    if (CollidesWithAny_InBounds(upStairMap, upStairX, upStairY, newElevation))
                    {
                        return(false);
                    }
                    return(true);
                }
            }
            bool canChangeElevation = false;

            // Stairs - If we are on a down stair, then we will be going to the block diagonally below us
            if (curBehavior == downBehavior)
            {
                canChangeElevation = true;
                targetY++;
            }
            else if (curBehavior == upBehavior)
            {
                canChangeElevation = true;
            }
            // Target block - return false if we are blocked
            if (!CanMoveTo_Cardinal__CanOccupy(targetX, targetY, curBehavior, blockedTarget, !canChangeElevation, p.Elevation))
            {
                return(false);
            }
            return(true);
        }
예제 #7
0
        // South/North
        private bool CanMoveTo_Cardinal(int targetX, int targetY, BlocksetBlockBehavior blockedCurrent, BlocksetBlockBehavior blockedTarget)
        {
            // Current block - return false if we are blocked
            Position p = Pos;

            Map.Layout.Block      curBlock    = Map.GetBlock_CrossMap(p.X, p.Y);
            BlocksetBlockBehavior curBehavior = curBlock.BlocksetBlock.Behavior;

            if (curBehavior == blockedCurrent)
            {
                return(false);
            }
            // Target block - return false if we are blocked
            if (!CanMoveTo_Cardinal__CanOccupy(targetX, targetY, curBehavior, blockedTarget, true, p.Elevation))
            {
                return(false);
            }
            return(true);
        }
예제 #8
0
        public void Warp(IWarp warp)
        {
            var  map = Map.LoadOrGet(warp.DestMapId);
            int  x   = warp.DestX;
            int  y   = warp.DestY;
            byte e   = warp.DestElevation;

            Map.Layout.Block block = map.GetBlock_CrossMap(x, y, out map); // GetBlock_CrossMap in case our warp is actually in a connection for some reason
            // Facing is of the original direction unless the block behavior says otherwise
            // All QueuedScriptMovements will be run after the warp is complete
            switch (block.BlocksetBlock.Behavior)
            {
            case BlocksetBlockBehavior.Warp_WalkSouthOnExit:
            {
                Facing = FacingDirection.South;
                QueuedScriptMovements.Enqueue(ScriptMovement.Walk_S);
                break;
            }

            case BlocksetBlockBehavior.Warp_NoOccupancy_S:
            {
                Facing = FacingDirection.North;
                y--;
                break;
            }
            }
            UpdateMap(map);
            Pos.X         = x;
            Pos.Y         = y;
            Pos.Elevation = e;
            PrevPos       = Pos;
            if (CameraObj.CameraAttachedTo == this)
            {
                CameraObj.CameraCopyMovement();
            }
        }
예제 #9
0
        private void ApplyMovement(FacingDirection facing)
        {
            switch (facing)
            {
            case FacingDirection.South:
            {
                Pos.Y++;
                break;
            }

            case FacingDirection.North:
            {
                Pos.Y--;
                break;
            }

            case FacingDirection.West:
            {
                Position p = Pos;
                Pos.X--;
                ApplyStairMovement(p, BlocksetBlockBehavior.Stair_W, BlocksetBlockBehavior.Stair_E);
                break;
            }

            case FacingDirection.East:
            {
                Position p = Pos;
                Pos.X++;
                ApplyStairMovement(p, BlocksetBlockBehavior.Stair_E, BlocksetBlockBehavior.Stair_W);
                break;
            }

            case FacingDirection.Southwest:
            {
                Pos.X--;
                Pos.Y++;
                _movementSpeed *= DiagonalMovementSpeedModifier;
                break;
            }

            case FacingDirection.Southeast:
            {
                Pos.X++;
                Pos.Y++;
                _movementSpeed *= DiagonalMovementSpeedModifier;
                break;
            }

            case FacingDirection.Northwest:
            {
                Pos.X--;
                Pos.Y--;
                _movementSpeed *= DiagonalMovementSpeedModifier;
                break;
            }

            case FacingDirection.Northeast:
            {
                Pos.X++;
                Pos.Y--;
                _movementSpeed *= DiagonalMovementSpeedModifier;
                break;
            }
            }
            Map.Layout.Block block = GetBlock(out Map map);
            Pos.Elevation = GetElevationIfMovedTo(Pos.Elevation, block.Elevations);
            Map curMap = Map;

            if (map == curMap)
            {
                return;
            }
            // Map crossing - Update Map, Pos, and PrevPos
            curMap.Objs.Remove(this);
            map.Objs.Add(this);
            Map = map;

            int x = Pos.X;
            int y = Pos.Y;

            Pos.X      = block.X;
            Pos.Y      = block.Y;
            PrevPos.X += block.X - x;
            PrevPos.Y += block.Y - y;
        }
예제 #10
0
        private void ApplyMovement(FacingDirection facing)
        {
            switch (facing)
            {
            case FacingDirection.South:
            {
                Pos.Y++;
                break;
            }

            case FacingDirection.North:
            {
                Pos.Y--;
                break;
            }

            case FacingDirection.West:
            {
                Position p = Pos;
                Pos.X--;
                ApplyStairMovement(p, BlocksetBlockBehavior.Stair_W, BlocksetBlockBehavior.Stair_E);
                break;
            }

            case FacingDirection.East:
            {
                Position p = Pos;
                Pos.X++;
                ApplyStairMovement(p, BlocksetBlockBehavior.Stair_E, BlocksetBlockBehavior.Stair_W);
                break;
            }

            case FacingDirection.Southwest:
            {
                Pos.X--;
                Pos.Y++;
                MovementSpeed *= DiagonalMovementSpeedModifier;
                break;
            }

            case FacingDirection.Southeast:
            {
                Pos.X++;
                Pos.Y++;
                MovementSpeed *= DiagonalMovementSpeedModifier;
                break;
            }

            case FacingDirection.Northwest:
            {
                Pos.X--;
                Pos.Y--;
                MovementSpeed *= DiagonalMovementSpeedModifier;
                break;
            }

            case FacingDirection.Northeast:
            {
                Pos.X++;
                Pos.Y--;
                MovementSpeed *= DiagonalMovementSpeedModifier;
                break;
            }
            }
            Map curMap = Map;
            int newX   = Pos.X;
            int newY   = Pos.Y;

            Map.Layout.Block block = curMap.GetBlock_CrossMap(newX, newY, out int outX, out int outY, out Map map);
            Pos.Elevation = Overworld.GetElevationIfMovedTo(Pos.Elevation, block.Elevations);
            if (map == curMap)
            {
                return;
            }
            // Map crossing - Update Map, Pos, and PrevPos
            curMap.Objs.Remove(this);
            map.Objs.Add(this);
            Map = map;

            Pos.X      = outX;
            Pos.Y      = outY;
            PrevPos.X += outX - newX;
            PrevPos.Y += outY - newY;
            OnMapChanged(curMap, map);
        }
예제 #11
0
        public static unsafe void Render(uint *bmpAddress, int bmpWidth, int bmpHeight)
        {
            // Gather variables we need to draw everything at the right coordinates
            CameraObj  camera       = Camera;
            Position   cameraPos    = camera.Pos;
            int        cameraPixelX = (cameraPos.X * Overworld.Block_NumPixelsX) - (bmpWidth / 2) + (Overworld.Block_NumPixelsX / 2) + camera._progressX + CameraOfsX;
            int        cameraPixelY = (cameraPos.Y * Overworld.Block_NumPixelsY) - (bmpHeight / 2) + (Overworld.Block_NumPixelsY / 2) + camera._progressY + CameraOfsY;
            Map        cameraMap    = camera.Map;
            List <Obj> objs         = cameraMap.Objs;
            int        numObjs      = objs.Count;
            int        xpBX         = cameraPixelX % Overworld.Block_NumPixelsX;
            int        ypBY         = cameraPixelY % Overworld.Block_NumPixelsY;
            int        startBlockX  = (cameraPixelX / Overworld.Block_NumPixelsX) - (xpBX >= 0 ? 0 : 1);
            int        startBlockY  = (cameraPixelY / Overworld.Block_NumPixelsY) - (ypBY >= 0 ? 0 : 1);
            int        numBlocksX   = (bmpWidth / Overworld.Block_NumPixelsX) + (bmpWidth % Overworld.Block_NumPixelsX == 0 ? 0 : 1);
            int        numBlocksY   = (bmpHeight / Overworld.Block_NumPixelsY) + (bmpHeight % Overworld.Block_NumPixelsY == 0 ? 0 : 1);
            int        endBlockX    = startBlockX + numBlocksX + (xpBX == 0 ? 0 : 1);
            int        endBlockY    = startBlockY + numBlocksY + (ypBY == 0 ? 0 : 1);
            int        startPixelX  = xpBX >= 0 ? -xpBX : -xpBX - Overworld.Block_NumPixelsX;
            int        startPixelY  = ypBY >= 0 ? -ypBY : -ypBY - Overworld.Block_NumPixelsY;

            // Loop each elevation
            for (byte e = 0; e < Overworld.NumElevations; e++)
            {
                // Draw blocks
                int curPixelX = startPixelX;
                int curPixelY = startPixelY;
                for (int blockY = startBlockY; blockY < endBlockY; blockY++)
                {
                    for (int blockX = startBlockX; blockX < endBlockX; blockX++)
                    {
                        Map.Layout.Block block = cameraMap.GetBlock_CrossMap(blockX, blockY, out _);
                        if (block != null)
                        {
                            Blockset.Block b = block.BlocksetBlock;
                            void Draw(Blockset.Block.Tile[] subLayers, int tx, int ty)
                            {
                                int numSubLayers = subLayers.Length;

                                for (int t = 0; t < numSubLayers; t++)
                                {
                                    Blockset.Block.Tile tile  = subLayers[t];
                                    Tileset.Tile        ttile = tile.TilesetTile;
                                    RenderUtils.DrawBitmap(bmpAddress, bmpWidth, bmpHeight, tx, ty, ttile.AnimBitmap ?? ttile.Bitmap, Overworld.Tile_NumPixelsX, Overworld.Tile_NumPixelsY, xFlip: tile.XFlip, yFlip: tile.YFlip);
                                }
                            }

                            for (int by = 0; by < Overworld.Block_NumTilesY; by++)
                            {
                                Blockset.Block.Tile[][][] arrY = b.Tiles[by];
                                int ty = curPixelY + (by * Overworld.Tile_NumPixelsY);
                                for (int bx = 0; bx < Overworld.Block_NumTilesX; bx++)
                                {
                                    Draw(arrY[bx][e], curPixelX + (bx * Overworld.Tile_NumPixelsX), ty);
                                }
                            }
                        }
                        curPixelX += Overworld.Block_NumPixelsX;
                    }
                    curPixelX  = startPixelX;
                    curPixelY += Overworld.Block_NumPixelsY;
                }

                // Draw VisualObjs
                // TODO: They will overlap each other regardless of y coordinate because of the order of the list
                // TODO: Objs from other maps
                for (int i = 0; i < numObjs; i++)
                {
                    Obj o = objs[i];
                    if (o.Pos.Elevation == e && o is VisualObj v)
                    {
                        v.Draw(bmpAddress, bmpWidth, bmpHeight, startBlockX, startBlockY, startPixelX, startPixelY);
                    }
                }
            }
        }