예제 #1
0
    public override byte[] ReadCollisionMap()
    {
        GscMap map    = Map;
        int    width  = map.Width;
        int    height = map.Height;

        byte[] overworldMap = CpuRead("wOverworldMapBlocks", 1300);
        byte[] blocks       = new byte[width * height];

        for (int i = 0; i < height; i++)
        {
            Array.Copy(overworldMap, (i + 3) * (width + 6) + 3, blocks, i * width, width);
        }

        byte[] collision = new byte[width * 2 * height * 2];
        for (int i = 0; i < blocks.Length; i++)
        {
            byte block = blocks[i];
            for (int j = 0; j < 4; j++)
            {
                byte coll           = ROM[map.Tileset.Coll + block * 4 + j];
                int  tileSpaceIndex = i * 2 + (j & 1) + (j >> 1) * (width * 2) + (i / width * 2 * width);
                collision[tileSpaceIndex] = coll;
            }
        }

        return(collision);
    }
예제 #2
0
 public GscBGEvent(Gsc game, GscMap map, ByteStream data)
 {
     Y             = data.u8();
     X             = data.u8();
     Function      = (GscBGEventType)data.u8();
     ScriptPointer = data.u16le();
 }
예제 #3
0
 public GscCoordEvent(Gsc game, GscMap map, ByteStream data)
 {
     Map     = map;
     SceneId = data.u8();
     Y       = data.u8();
     X       = data.u8();
     data.Seek(1);
     ScriptPointer = data.u16le();
     data.Seek(2);
 }
예제 #4
0
 public GscWarp(Gsc game, GscMap map, byte index, ByteStream data)
 {
     Map              = map;
     Index            = index;
     Y                = data.u8();
     X                = data.u8();
     DestinationIndex = (byte)(data.u8() - 1);
     MapGroup         = data.u8();
     MapNumber        = data.u8();
     Allowed          = false;
 }
예제 #5
0
 public GscConnection(GscMap map, ByteStream data)
 {
     Map         = map;
     DestGroup   = data.u8();
     DestNumber  = data.u8();
     Source      = data.u16le();
     Destination = data.u16le();
     Length      = data.u8();
     Width       = data.u8();
     YAlignment  = data.u8();
     XAlignment  = data.u8();
     Window      = data.u16le();
 }
예제 #6
0
    public List <GscTile> Sight(GscMap map)
    {
        Action         dir     = ActionFunctions.FromSpriteDirection(Direction);
        List <GscTile> sight   = new List <GscTile>();
        GscTile        current = map[StandingMapX - 4, StandingMapY - 4];

        for (int j = 0; j < Range; j++)
        {
            current = current.GetNeighbor(dir);
            if (current == null)
            {
                break;
            }
            sight.Add(current);
        }

        return(sight);
    }
예제 #7
0
 public GscSprite(Gsc game, GscMap map, byte id, ByteStream data)
 {
     Map              = map;
     Id               = id;
     PictureId        = data.u8();
     Y                = (byte)(data.u8() - 4);
     X                = (byte)(data.u8() - 4);
     MovementFunction = (GscSpriteMovement)data.u8();
     MovementRadiusY  = data.Nybble();
     MovementRadiusX  = data.Nybble();
     H1               = data.u8();
     H2               = data.u8();
     Color            = data.Nybble();
     Function         = (GscSpriteType)data.Nybble();
     SightRange       = data.u8();
     ScriptPointer    = data.u16le();
     EventFlag        = data.u16le();
 }
예제 #8
0
    public override int WalkTo(int targetX, int targetY)
    {
        GscMap  map      = Map;
        GscTile current  = Tile;
        GscTile target   = map[targetX, targetY];
        GscWarp warp     = map.Warps[current.X, current.Y];
        bool    original = false;

        if (warp != null)
        {
            original     = warp.Allowed;
            warp.Allowed = true;
        }
        List <Action> path = Pathfinding.FindPath(map, current, 17, map.Tileset.LandPermissions, target);

        if (warp != null)
        {
            warp.Allowed = original;
        }
        return(Execute(path.ToArray()));
    }
예제 #9
0
    public static void BuildGraph()
    {
        Gold gb = new Gold();

        r29         = gb.Maps["Route29"];
        cherrygrove = gb.Maps["CherrygroveCity"];
        r30         = gb.Maps["Route30"];

        cherrygrove.Sprites.Remove(39, 6);

        Pathfinding.GenerateEdges(r29, 0, 17, r29.Tileset.LandPermissions, Action.Left | Action.Right | Action.Up | Action.Down, r29[0, 7]);
        Pathfinding.GenerateEdges(cherrygrove, 0, 17, cherrygrove.Tileset.LandPermissions, Action.Left | Action.Right | Action.Up | Action.Down, cherrygrove[17, 0]);
        Pathfinding.GenerateEdges(r30, 0, 17, r30.Tileset.LandPermissions, Action.Left | Action.Right | Action.Up | Action.Down, PassNum == 1 ? r30[17, 12] : r30[6, 27]);
        r29[0, 6].AddEdge(0, new Edge <GscTile> {
            Action = Action.Left, Cost = 0, NextEdgeset = 0, NextTile = cherrygrove[39, 6]
        });
        r29[0, 6].AddEdge(0, new Edge <GscTile> {
            Action = Action.Left | Action.A, Cost = 0, NextEdgeset = 0, NextTile = cherrygrove[39, 6]
        });
        r29[0, 7].AddEdge(0, new Edge <GscTile> {
            Action = Action.Left, Cost = 0, NextEdgeset = 0, NextTile = cherrygrove[39, 7]
        });
        r29[0, 7].AddEdge(0, new Edge <GscTile> {
            Action = Action.Left | Action.A, Cost = 0, NextEdgeset = 0, NextTile = cherrygrove[39, 7]
        });
        cherrygrove[17, 0].AddEdge(0, new Edge <GscTile> {
            Action = Action.Up, Cost = 0, NextEdgeset = 0, NextTile = r30[7, 53]
        });
        cherrygrove[17, 0].AddEdge(0, new Edge <GscTile> {
            Action = Action.Up | Action.A, Cost = 0, NextEdgeset = 0, NextTile = r30[7, 53]
        });

        cherrygrove[33, 6].RemoveEdge(0, Action.Down | Action.A);
        cherrygrove[30, 4].RemoveEdge(0, Action.Left | Action.A);
        cherrygrove[24, 4].RemoveEdge(0, Action.Left | Action.A);
        gb.Dispose();
    }
예제 #10
0
    public override GscTile WarpCheck()
    {
        GscWarp sourceWarp = Map.Warps[X, Y];

        if (sourceWarp != null && sourceWarp.Allowed)
        {
            GscMap destMap = Map.Game.Maps[sourceWarp.MapId];
            if (destMap != null)
            {
                GscWarp destWarp = destMap.Warps[sourceWarp.DestinationIndex];
                if (destWarp != null)
                {
                    GscTile destTile = destMap[destWarp.X, destWarp.Y];
                    if (destTile.Collision == 113)
                    {
                        destTile = destTile.Neighbor(Action.Down);                           // Door tiles automatically move the player 1 tile down.
                    }
                    return(destTile);
                }
            }
        }

        return(this);
    }
예제 #11
0
    public static void StartSearch(int numThreads)
    {
        bool[]   threadsRunning = new bool[numThreads];
        Thread[] threads        = new Thread[numThreads];
        Gold     dummyGb        = new Gold();
        GscMap   map            = dummyGb.Maps[6149];

        map.Sprites.Remove(5, 3); // Remove police officer (https://gunnermaniac.com/pokeworld2?map=6149#5/3)
        Pathfinding.GenerateEdges <GscMap, GscTile>(dummyGb, 0, map[7, 5], Action.Right | Action.Down | Action.StartB);
        Pathfinding.GenerateEdges <GscMap, GscTile>(dummyGb, 1, map[7, 4], Action.StartB);

        map[4, 5].RemoveEdge(0, Action.Down);
        map[4, 5].RemoveEdge(0, Action.Down | Action.A); // Don't walk into cutscene
        map[5, 5].RemoveEdge(0, Action.Down);
        map[5, 5].RemoveEdge(0, Action.Down | Action.A); // ^
        map[7, 4].RemoveEdge(0, Action.Right);
        map[7, 4].RemoveEdge(0, Action.Right | Action.A);
        map[7, 5].RemoveEdge(0, Action.Right);
        map[7, 5].RemoveEdge(0, Action.Right | Action.A);
        map[4, 2].RemoveEdge(0, Action.Down | Action.A);
        map[5, 3].RemoveEdge(0, Action.Down | Action.A);

        map[7, 5].AddEdge(0, new Edge <GscMap, GscTile>()
        {
            Action      = Action.Up,
            NextTile    = map[7, 4],
            NextEdgeset = 1,
            Cost        = 0,
        });

        GscTile[] startTiles   = { map[4, 2], map[4, 3], map[4, 4], map[5, 3], map[5, 4] };
        byte[]    startHours   = { 10, 8, 2, 18 };
        byte[]    startMinutes = { 51, 59 };
        byte[]    audios       = { 0xc1, 0xe1 };

        int numSavesCompleted = 0;

        Writer = new StreamWriter("gold_toto_" + DateTime.Now.Ticks + ".txt");
        int numSaves = startTiles.Length * startHours.Length * startMinutes.Length * 2 * 2 * 8 * 2 * 10;

        Console.WriteLine(numThreads + " threads, " + (numSaves) + " saves (" + (float)numSaves / (float)numThreads + " iterations)");
        foreach (GscTile tile in startTiles)
        {
            foreach (byte hour in startHours)
            {
                foreach (byte minute in startMinutes)
                {
                    for (byte momStep = 0; momStep <= 1; momStep++)
                    {
                        foreach (byte audio in audios)
                        {
                            for (byte frameType = 0; frameType <= 7; frameType++)
                            {
                                for (byte menuAccount = 0; menuAccount <= 1; menuAccount++)
                                {
                                    for (byte igt = 0; igt < 60; igt += 6)
                                    {
                                        int threadIndex;
                                        while ((threadIndex = Array.IndexOf(threadsRunning, false)) == -1)
                                        {
                                            Thread.Sleep(50);
                                        }
                                        threadsRunning[threadIndex] = true;
                                        new Thread(parameter => {
                                            (int, (GscTile, byte, byte, byte, byte, byte, byte, byte))data = ((int, (GscTile, byte, byte, byte, byte, byte, byte, byte)))parameter;
                                            (GscTile tile, byte hour, byte minute, byte momStep, byte audio, byte frameType, byte menuAccount, byte igt)state = data.Item2;
                                            Gold gb;
                                            lock (startTiles) {
                                                MakeSave(state.tile.X, state.tile.Y, state.hour, state.minute, state.momStep, state.audio, state.frameType, state.menuAccount, state.igt);
                                                gb = new Gold("roms/gold_toto_temp.sav");
                                                gb.SetTimeSec(120);
                                                gb.Hold(Joypad.Left, 0x100);
                                            }
                                            GscStrat.GfSkip.Execute(gb);
                                            GscStrat.TitleSkip.Execute(gb);
                                            byte[] mmbackState = gb.SaveState();
                                            for (int mmBack = 0; mmBack <= 3; mmBack++)
                                            {
                                                GscStrat.Continue.Execute(gb);
                                                byte[] fsbackState = gb.SaveState();
                                                for (int fsBack = 0; fsBack <= 3; fsBack++)
                                                {
                                                    gb.Hold(Joypad.Left, "GetJoypad");
                                                    gb.AdvanceFrame(Joypad.Left);
                                                    byte[] delayState = gb.SaveState();
                                                    for (int delay = 0; delay <= MaxCost; delay++)
                                                    {
                                                        int introCost = mmBack * 83 + fsBack * 101 + delay;
                                                        if (introCost > MaxCost)
                                                        {
                                                            break;
                                                        }
                                                        gb.Hold(Joypad.A, "OWPlayerInput");
                                                        DFParameters <Gold, GscMap, GscTile> parameters = new DFParameters <Gold, GscMap, GscTile>()
                                                        {
                                                            NoEncounterSS          = 1,
                                                            PruneAlreadySeenStates = false,
                                                            MaxCost  = MaxCost - introCost,
                                                            LogStart = string.Format("(x={0}, y={1}, h={2}, m={3}, momStep={4}, audio={5:x02}, frameType={6}, menuAccount={7}, igt={8}, mmback={9}, fsback={10}, delay={11}) ",
                                                                                     state.tile.X, state.tile.Y, state.hour, state.minute, state.momStep, state.audio, state.frameType, state.menuAccount, state.igt, mmBack, fsBack, delay),
                                                            EndTiles      = new GscTile[] { map[7, 4] },
                                                            EndEdgeSet    = 1,
                                                            FoundCallback = state => EvaluateTototdile(gb, state),
                                                        };
                                                        IGTResults results = new IGTResults(1);
                                                        results[0]         = new IGTState(gb, true, 0);
                                                        DepthFirstSearch.StartSearch(new Gold[] { gb }, parameters, tile, 0, results);
                                                        gb.LoadState(delayState);
                                                        gb.AdvanceFrame(Joypad.Left);
                                                        delayState = gb.SaveState();
                                                    }
                                                    gb.LoadState(fsbackState);
                                                    GscStrat.FsBack.Execute(gb);
                                                    GscStrat.Continue.Execute(gb);
                                                    fsbackState = gb.SaveState();
                                                }
                                                gb.LoadState(mmbackState);
                                                GscStrat.MmBack.Execute(gb);
                                                GscStrat.TitleSkip.Execute(gb);
                                                mmbackState = gb.SaveState();
                                            }
                                            Interlocked.Increment(ref numSavesCompleted);
                                            Console.WriteLine("Completed save " + numSavesCompleted + "/" + numSaves);
                                            threadsRunning[threadIndex] = false;
                                        }).Start((threadIndex, (tile, hour, minute, momStep, audio, frameType, menuAccount, igt)));
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }

        while (true)
        {
            Thread.Sleep(10000);
        }
    }