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); }
public GscBGEvent(Gsc game, GscMap map, ByteStream data) { Y = data.u8(); X = data.u8(); Function = (GscBGEventType)data.u8(); ScriptPointer = data.u16le(); }
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); }
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; }
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(); }
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); }
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(); }
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())); }
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(); }
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); }
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); } }