Advertisement
OneNineFour

GameRandomizer.cl

Mar 23rd, 2019
131
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 8.02 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using Ekona;
  6. using System.IO;
  7. using Tinke;
  8.  
  9. namespace Tinke.Randomizer
  10. {
  11.     abstract class GameRandomizer
  12.     {
  13.         //general parameters, shared by all roms
  14.         sFolder gameRoot;
  15.         Random rng;
  16.         string seed;
  17.         Acciones accion;
  18.  
  19.         //these parameters shall be defined per rom
  20.         byte[] puzzleIDs;
  21.         protected string puzzlePath = "";
  22.         protected byte puzzleSeparatorByte = 0xDC;
  23.         protected string eventScriptFolder = "";
  24.         protected string roomScriptFolder = "";
  25.         protected string riddleHutScriptFolder = "";
  26.         protected string riddleHutScriptName = "";
  27.         protected byte riddleScriptFlagByte = 0xE5;
  28.  
  29.         public GameRandomizer(sFolder root, string seed, Acciones accion)
  30.         {
  31.             this.seed = seed;
  32.             this.rng = new Random(seed.GetHashCode());
  33.             this.gameRoot = root;
  34.             this.accion = accion;
  35.         }
  36.  
  37.         public void seedPuzzles(){
  38.             sFolder puzzleFolder = this.findFolder(this.puzzlePath);
  39.             sFile qinfo = this.findFile(puzzleFolder, "qinfo.gds");
  40.  
  41.             int puzzleCounter = 0;
  42.  
  43.             string hexFile = Path.GetTempFileName();
  44.             BinaryReader binr = new BinaryReader(File.OpenRead(qinfo.path));
  45.             binr.BaseStream.Position = qinfo.offset;
  46.  
  47.             byte[] fileBytes = binr.ReadBytes((int)qinfo.size);
  48.  
  49.             for (int b = 0; b < fileBytes.Length; b++) {
  50.                 if (fileBytes[b] == this.puzzleSeparatorByte) {
  51.                     puzzleCounter++;
  52.                 }
  53.             }
  54.  
  55.             this.puzzleIDs = new byte[puzzleCounter];
  56.             for (int index = 0; index < puzzleCounter; index++) {
  57.                 puzzleIDs[index] = (byte)(index + 1);
  58.             }
  59.  
  60.             this.puzzleIDs = this.Shuffle(puzzleIDs);
  61.         }
  62.  
  63.         protected sFile findFile(sFolder folder, string name)
  64.         {
  65.             foreach (sFile tmpFile in folder.files) {
  66.                 if (tmpFile.name == name) {
  67.                     return tmpFile;
  68.                 }
  69.             }
  70.  
  71.             return new sFile();
  72.         }
  73.  
  74.         /*
  75.          * Given an absolute folder path, from root, return pointer to said folder.
  76.          * Throws RandomizerException if not found
  77.          */
  78.         protected sFolder findFolder(string path) {
  79.             sFolder tmp = this.gameRoot;
  80.  
  81.             if(path.StartsWith("/")){
  82.                 path = path.Substring(1);
  83.             }
  84.             string[] pathArray = path.Split('/');
  85.  
  86.             int folderPathIndex = 0;
  87.             while (folderPathIndex < pathArray.Length)
  88.             {
  89.                 foreach (sFolder folder in tmp.folders)
  90.                 {
  91.                     if (folder.name == pathArray[folderPathIndex])
  92.                     {
  93.                         tmp = folder;
  94.                         folderPathIndex++;
  95.                         break;
  96.                     }
  97.                 }
  98.             }
  99.  
  100.             return tmp;
  101.         }
  102.  
  103.         protected T[] Shuffle<T>(T[] array)
  104.         {
  105.             int n = array.Length;
  106.             while (n > 1)
  107.             {
  108.                 int k = this.rng.Next(n--);
  109.                 T temp = array[n];
  110.                 array[n] = array[k];
  111.                 array[k] = temp;
  112.             }
  113.  
  114.             return array;
  115.         }
  116.  
  117.         /**
  118.          * Writes rando data to file system
  119.          */
  120.         public void Write()
  121.         {
  122.             //write event scripts
  123.             sFolder eventRoot = this.findFolder(this.eventScriptFolder);
  124.             for (int fileIndex = 0; fileIndex < eventRoot.files.Count; fileIndex++){
  125.                 sFile file = eventRoot.files[fileIndex];
  126.                 byte[] puzzleMask = { 0x48, 0x00, 0x01, 0x00 };
  127.  
  128.                 string hexFile = Path.GetTempFileName();
  129.                 BinaryReader binr = new BinaryReader(File.OpenRead(file.path));
  130.                 binr.BaseStream.Position = file.offset;
  131.  
  132.                 byte[] fileBytes = binr.ReadBytes((int)file.size);
  133.  
  134.                 for (int b = 0; b < fileBytes.Length - puzzleMask.Length; b++)
  135.                 {
  136.                     bool foundSequence = true;
  137.  
  138.                     for (int c = 0; c < puzzleMask.Length; c++)
  139.                     {
  140.                         if (fileBytes[b + c] != puzzleMask[c])
  141.                         {
  142.                             foundSequence = false;
  143.                         }
  144.                     }
  145.  
  146.                     if (!foundSequence) continue;
  147.  
  148.                     int id_to_replace = fileBytes[b + puzzleMask.Length] - 1;
  149.  
  150.                     //prevent puzzle 001
  151.                     if (this.puzzleIDs[id_to_replace] == 0x24) continue;
  152.  
  153.                     fileBytes[b + puzzleMask.Length] = this.puzzleIDs[id_to_replace];
  154.                 }
  155.  
  156.                 File.WriteAllBytes(hexFile, fileBytes);
  157.                 binr.Close();
  158.  
  159.                 this.accion.Change_File(file.id, hexFile);
  160.             }
  161.  
  162.             //write room scripts
  163.             sFolder roomsRoot = this.findFolder(this.roomScriptFolder);
  164.             for (int fileIndex = 0; fileIndex < roomsRoot.files.Count; fileIndex++)
  165.             {
  166.                 sFile file = roomsRoot.files[fileIndex];
  167.  
  168.                 byte[] puzzleMask = { 0x48, 0x00, 0x01, 0x00 };
  169.  
  170.                 string hexFile = Path.GetTempFileName();
  171.                 BinaryReader binr = new BinaryReader(File.OpenRead(file.path));
  172.                 binr.BaseStream.Position = file.offset;
  173.  
  174.                 byte[] fileBytes = binr.ReadBytes((int)file.size);
  175.  
  176.                 for (int b = 0; b < fileBytes.Length - puzzleMask.Length; b++)
  177.                 {
  178.                     bool foundSequence = true;
  179.  
  180.                     for (int c = 0; c < puzzleMask.Length; c++)
  181.                     {
  182.                         if (fileBytes[b + c] != puzzleMask[c])
  183.                         {
  184.                             foundSequence = false;
  185.                         }
  186.                     }
  187.  
  188.                     if (!foundSequence) continue;
  189.  
  190.                     int id_to_replace = fileBytes[b + puzzleMask.Length] - 1;
  191.  
  192.                     //prevent puzzle 001
  193.                     if (this.puzzleIDs[id_to_replace] == 0x24) continue;
  194.  
  195.                     fileBytes[b + puzzleMask.Length] = this.puzzleIDs[id_to_replace];
  196.                 }
  197.  
  198.                 File.WriteAllBytes(hexFile, fileBytes);
  199.                 binr.Close();
  200.  
  201.                 this.accion.Change_File(file.id, hexFile);
  202.             }
  203.  
  204.             //write riddle hut assignation scripts (experimental)
  205.             sFile riddleHutScript = this.findFile(this.findFolder(this.riddleHutScriptFolder), this.riddleHutScriptName);
  206.  
  207.             string hexF = Path.GetTempFileName();
  208.             BinaryReader binread = new BinaryReader(File.OpenRead(riddleHutScript.path));
  209.             binread.BaseStream.Position = riddleHutScript.offset;
  210.  
  211.             byte[] fileByte = binread.ReadBytes((int)riddleHutScript.size);
  212.             byte[] riddleMask = { this.riddleScriptFlagByte, 0x00, 0x01, 0x00 };
  213.  
  214.             for (int b = 0; b < fileByte.Length - riddleMask.Length; b++)
  215.             {
  216.                 bool foundSequence = true;
  217.  
  218.                 for (int c = 0; c < riddleMask.Length; c++)
  219.                 {
  220.                     if (fileByte[b + c] != riddleMask[c])
  221.                     {
  222.                         foundSequence = false;
  223.                     }
  224.                 }
  225.  
  226.                 if (!foundSequence) continue;
  227.  
  228.                 int id_to_replace = fileByte[b + riddleMask.Length] - 1;
  229.  
  230.                 //prevent puzzle 001
  231.                 if (this.puzzleIDs[id_to_replace] == 0x24) continue;
  232.  
  233.                 fileByte[b + riddleMask.Length] = this.puzzleIDs[id_to_replace];
  234.             }
  235.  
  236.             File.WriteAllBytes(hexF, fileByte);
  237.             binread.Close();
  238.  
  239.             this.accion.Change_File(riddleHutScript.id, hexF);
  240.  
  241.             return;
  242.         }
  243.     }
  244. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement