private bool LoadZelda(CString levelData, string fileVersion) { // Get the appropriate filesystem. //CFileSystem* fileSystem = server->getFileSystem(); //if (server->getSettings()->getBool("nofoldersconfig", false) == false) // fileSystem = server->getFileSystem(FS_LEVEL); // Path-To-File //actualLevelName = levelName = pLevelName; //fileName = fileSystem->find(pLevelName); //modTime = fileSystem->getModTime(pLevelName); // Check if it is actually a .graal level. The 1.39-1.41r1 client actually // saved .zelda as .graal. if (fileVersion.Substring(0, 2) == "GR") return this.LoadGraal(levelData, fileVersion); int v = -1; if (fileVersion == "Z3-V1.03") v = 3; else if (fileVersion == "Z3-V1.04") v = 4; if (v == -1) return false; #region Load tiles. bool layerExists = false; foreach (KeyValuePair<int, GraalLevelTileList> l in this.layers) if (l.Key == 0) layerExists = true; if (!layerExists) this.layers[0] = new GraalLevelTileList(); { int bits = (v > 4 ? 13 : 12); int read = 0; uint buffer = 0; long code = 0; int[] tiles = new int[2] { -1, -1 }; int boardIndex = 0; int count = 1; bool doubleMode = false; // Read the tiles. while (boardIndex < 64 * 64 && levelData.BytesLeft != 0) { // Every control code/tile is either 12 or 13 bits. WTF. // Read in the bits. while (read < bits) { buffer += ((uint)levelData.ReadGByte1()) << read; read += 8; } // Pull out a single 12/13 bit code from the buffer. code = buffer & (bits == 12 ? 0xFFF : 0x1FFF); buffer >>= bits; read -= bits; Console.WriteLine("Code&bits: " + (code & (bits == 12 ? 0x800 : 0x1000))); // See if we have an RLE control code. // Control codes determine how the RLE scheme works. if ((code & (bits == 12 ? 0x800 : 0x1000)) != 0) { // If the 0x100 bit is set, we are in a double repeat mode. // {double 4}56 = 56565656 if ((code & 0x100) != 0) doubleMode = true; // How many tiles do we count? count = (int)(code & 0xFF); continue; } // If our count is 1, just read in a tile. This is the default mode. if (count == 1) { GraalLevelTile tile = this.layers[0].AddTile(boardIndex++, (int)code); continue; } // If we reach here, we have an RLE scheme. // See if we are in double repeat mode or not. if (doubleMode) { // Read in our first tile. if (tiles[0] == -1) { tiles[0] = (int)code; continue; } // Read in our second tile. tiles[1] = (int)code; // Add the tiles now. for (int i = 0; i < count && boardIndex < 64 * 64 - 1; ++i) { GraalLevelTile tile = this.layers[0].AddTile(boardIndex++, tiles[0]); GraalLevelTile tile2 = this.layers[0].AddTile(boardIndex++, tiles[1]); } // Clean up. tiles[0] = tiles[1] = -1; doubleMode = false; count = 1; } // Regular RLE scheme. else { GraalLevelTile tile = null; for (int i = 0; i < count && boardIndex < 64 * 64; ++i) tile = this.layers[0].AddTile(boardIndex++, (int)code); count = 1; } } } #endregion #region Load the links. { while (levelData.BytesLeft != 0) { CString line = levelData.ReadString('\n'); if (line.Length == 0 || line.Text == "#") break; // Assemble the level string. CStringList vline = new CStringList(); vline.Load(line.Text, ' '); CString level = vline.Get(0); if (vline.Count > 7) { for (int i = 0; i < vline.Count - 7; ++i) level += " " + vline.Get(1 + i); } int offset = vline.Count - 7; //GraalLevelLink link = new GraalLevelLink(vline.Get(0).Text, vline.Get(1).ToInt(), vline.Get(2).ToInt(), vline.Get(3).ToInt(), vline.Get(4).ToInt(),vline.Get(5).Text, vline.Get(6).Text); //this.LinkList.Add(this.LinkList.Count + 1, link); } } #endregion #region Load the baddies. { while (levelData.BytesLeft != 0) { int x = levelData.ReadGUByte1(); int y = levelData.ReadGUByte1(); int type = levelData.ReadGUByte1(); // Ends with an invalid baddy. if (x == -1 && y == -1 && type == -1) { levelData.ReadString('\n'); // Empty verses. break; } /* // Add the baddy. TLevelBaddy* baddy = addBaddy((float)x, (float)y, type); if (baddy == 0) continue; // Only v1.04+ baddies have verses. if (v > 3) { // Load the verses. std::vector<CString> bverse = fileData.readString("\n").tokenize("\\"); CString props; for (char j = 0; j < (char)bverse.size(); ++j) props >> (char)(BDPROP_VERSESIGHT + j) >> (char)bverse[j].length() << bverse[j]; if (props.length() != 0) baddy->setProps(props); } */ } } #endregion #region Load signs. { while (levelData.BytesLeft != 0) { CString line = levelData.ReadString('\n'); if (line.Length == 0) break; byte x = line.ReadGUByte1(); byte y = line.ReadGUByte1(); CString text = line.ReadString(); this.SignList.Add(this.SignList.Count + 1, new GraalLevelSign(x, y, text.Text)); } } #endregion return true; }
/// <summary> /// Set Properties /// </summary> /// <param name="Packet"></param> internal void SetProps(CString Packet) { bool compileScript = false; while (Packet.BytesLeft > 0) { Int32 PropId = Packet.ReadGUByte1(); switch ((Properties)PropId) { case Properties.IMAGE: // 0 this.Image = Packet.ReadChars(Packet.ReadGUByte1()); break; case Properties.SCRIPT: // 1 this.Script = Packet.ReadChars((int)Packet.ReadGUByte5()).Replace("\xa7", "\n"); if (this.Script.IndexOf("void") > 0 || this.Script.IndexOf("join(") > 0) compileScript = true; break; case Properties.NPCX: // 2 - obsolete Packet.ReadGByte1(); break; case Properties.NPCY: // 3 - obsolete Packet.ReadGByte1(); break; case Properties.NPCPOWER: // 4 Packet.ReadGUByte1(); break; case Properties.NPCRUPEES: // 5 this.Gralats = (int)Packet.ReadGUByte3(); break; case Properties.ARROWS: // 6 this.Arrows = Packet.ReadGUByte1(); break; case Properties.BOMBS: // 7 this.Bombs = Packet.ReadGUByte1(); break; case Properties.GLOVEPOWER: // 8 Packet.ReadGUByte1(); break; case Properties.BOMBPOWER: // 9 Packet.ReadGUByte1(); break; case Properties.GANI: // 12 Packet.ReadChars(Packet.ReadGUByte1()); break; case Properties.VISFLAGS: // 13 this.VisFlags = Packet.ReadGByte1(); break; case Properties.BLOCKFLAGS: // 14 this.BlockFlags = Packet.ReadGByte1(); break; case Properties.MESSAGE: // 15 this.Chat = Packet.ReadChars(Packet.ReadGUByte1()); break; case Properties.NPCID: // 17 Packet.ReadGUByte3(); break; case Properties.SPRITE: // 18 Packet.ReadGUByte1(); break; case Properties.COLORS: // 19 Packet.ReadGUByte5(); break; case Properties.NICKNAME: // 20 this.Nickname = Packet.ReadChars(Packet.ReadGUByte1()); break; case Properties.HORSEIMG: // 21 Packet.ReadChars(Packet.ReadGUByte1()); break; case Properties.HEADIMG: // 22 { Int32 len = Packet.ReadGUByte1(); this.HeadImage = (len < 100 ? "head" + len + ".png" : Packet.ReadChars(len - 100)); break; } case Properties.SAVE0: // 23 this.Save[0] = Packet.ReadGUByte1(); break; case Properties.SAVE1: // 24 this.Save[1] = Packet.ReadGUByte1(); break; case Properties.SAVE2: // 25 this.Save[2] = Packet.ReadGUByte1(); break; case Properties.SAVE3: // 26 this.Save[3] = Packet.ReadGUByte1(); break; case Properties.SAVE4: // 27 this.Save[4] = Packet.ReadGUByte1(); break; case Properties.SAVE5: // 28 this.Save[5] = Packet.ReadGUByte1(); break; case Properties.SAVE6: // 29 this.Save[6] = Packet.ReadGUByte1(); break; case Properties.SAVE7: // 30 this.Save[7] = Packet.ReadGUByte1(); break; case Properties.SAVE8: // 31 this.Save[8] = Packet.ReadGUByte1(); break; case Properties.SAVE9: // 32 this.Save[9] = Packet.ReadGUByte1(); break; case Properties.ALIGNMENT: // 33 Packet.ReadGUByte1(); break; case Properties.IMAGEPART: // 34 this.ImagePart = Packet.Read(6); break; case Properties.BODYIMG: // 35 this.BodyImage = Packet.ReadChars(Packet.ReadGUByte1()); break; case Properties.GMAPLVLX: // 41 this.GMapX = Packet.ReadGUByte1(); break; case Properties.GMAPLVLY: // 42 this.GMapY = Packet.ReadGUByte1(); break; case Properties.PIXELX: // 75 { int tmp = this.PixelX = Packet.ReadGUByte2(); // If the first bit is 1, our position is negative. this.PixelX >>= 1; if ((tmp & 0x0001) != 0) this.PixelX = -this.PixelX; break; } case Properties.PIXELY: // 76 { int tmp = this.PixelY = Packet.ReadGUByte2(); // If the first bit is 1, our position is negative. this.PixelY >>= 1; if ((tmp & 0x0001) != 0) this.PixelY = -this.PixelY; break; } default: System.Console.WriteLine("Unknown NPC Prop: " + PropId); return; } } // Compile script if script changed. if (compileScript) Server.Compiler.CompileAdd(this); }