public HeroEditor(CharacterFile characterFile, FileManager fileManager) { _characterFile = characterFile; _heroUnit = characterFile.Character; _fileManager = fileManager; //_panel = new CompletePanelControl(); //_statsTable = _excelTables.GetTable("stats") as Stats; //_itemFunctions = new UnitHelpFunctions(_dataSet); _itemFunctions.LoadCharacterValues(_heroUnit); //_itemFunctions.GenerateUnitNameStrings(); //_itemFunctions.PopulateItems(ref _heroUnit); //_wrapper = new UnitWrapper(_dataSet, heroFile); InitializeComponent(); }
public void AddItem(UnitObject item) { // get inventory type that the item uses TradeInventoryTypes type = TradeInventoryTypes.Inventory; if (item.InventoryLocationIndex == (int)InventoryTypes.Cube) { type = TradeInventoryTypes.Cube; } else if (item.InventoryLocationIndex == (int)InventoryTypes.Stash) { type = TradeInventoryTypes.Stash; } else if (item.InventoryLocationIndex == (int)InventoryTypes.Inventory) { type = TradeInventoryTypes.Inventory; } else { return; } AddOrRemoveItem(type, item, false); }
public void RemoveItem(UnitObject item) { UnitObject.Items.Remove(item); CharacterItems tmpItem = _items.Find(tmp => tmp.UnitObject == item); _items.Remove(tmpItem); }
public static UnitObjectStats.Stat GetComplexValue(UnitObject unit, string valueName) { foreach (UnitObjectStats.Stat unitStats in unit.Stats.Stats.Values) { if (unitStats.Name.Equals(valueName, StringComparison.OrdinalIgnoreCase)) { return unitStats; } } //for (int counter = 0; counter < unit.Stats.Stats.Count; counter++) //{ // UnitObjectStats.Stat unitStats = unit.Stats[counter]; // if (unitStats.Name.Equals(valueName, StringComparison.OrdinalIgnoreCase)) // { // return unitStats; // } //} return null; }
public void AddItem(UnitObject item) { UnitObject.Items.Add(item); // todo: rewrite _items.Add(new CharacterItems(item, _dataSet)); }
//// todo: rewrite private void ShowInvInfo(Unit unit) //{ // //save currently selected item // _currentlySelectedItem = unit; // DataTable items = _dataSet.GetExcelTableFromCode(27953); // DataRow[] itemRow = items.Select("code = '" + unit.unitCode + "'"); // if (itemRow.Length > 0) // { // int value = (int)itemRow[0]["unitType"]; // DataTable unitTypes = _dataSet.GetExcelTableFromCode(21040); // DataRow[] unitRow = unitTypes.Select("Index = '" + value + "'"); // if (unitRow.Length > 0) // { // tb_itemType.Text = unitRow[0]["type"].ToString(); // } // } // else // { // tb_itemType.Text = "unknown"; // } // tb_itemLevel.Text = (UnitHelpFunctions.GetSimpleValue(_currentlySelectedItem, ItemValueNames.level.ToString()) - 8).ToString(); // tb_itemName.Text = unit.Name; // tb_invLoc.Text = unit.inventoryType.ToString(); // nud_invPosX.Value = unit.inventoryPositionX; // nud_invPosY.Value = unit.inventoryPositionY; // tb_itemWidth.Text = GetItemWidth(unit).ToString(); // tb_itemHeight.Text = GetItemHeight(unit).ToString(); // int quantity = UnitHelpFunctions.GetSimpleValue(unit, ItemValueNames.item_quantity.ToString()); // if (quantity <= 0) // { // quantity = 1; // } // nud_itemQuantity.Value = quantity; // ShowItemMods(unit.Items.ToArray()); //} private void ShowItemMods(UnitObject[] items) { cb_availableMods.Items.Clear(); if (items.Length > 0) { cb_availableMods.Enabled = true; cb_availableMods.Items.AddRange(items); cb_availableMods.SelectedIndex = 0; } else { cb_availableMods.Enabled = false; } }
public static int GetSimpleValue(UnitObject unit, string valueName) { foreach (UnitObjectStats.Stat unitStats in unit.Stats.Stats.Values) { if (unitStats.Name == valueName) { return unitStats.Values[0].Value; } } //for (int counter = 0; counter < unit.Stats.Stats.Count; counter++) //{ // UnitObjectStats.Stat unitStats = unit.Stats[counter]; // if (unitStats.Name == valueName) // { // return unitStats.Values[0].Value; // } //} //MessageBox.Show("Field \"" + valueName + "\" not present in unit " + unit.Name + "!"); return 0; }
public CharacterValues(UnitObject unitObject, FileManager fileManager) : base(unitObject, fileManager) { try { //could also use "stat" column and "gold" entry DataRow[] goldRow = statsTable.Select("code = " + (int)ItemValueNames.gold); int maxPalladium = (int)goldRow[0]["maxSet"]; _maxPalladium = maxPalladium; DataTable playersTable = fileManager.GetDataTable("PLAYERS"); DataRow[] playerRows = playersTable.Select("code = " + UnitObject.UnitCode); int maxLevel = (int)playerRows[0]["maxLevel"]; _maxLevel = maxLevel; } catch (Exception ex) { MessageBox.Show(ex.Message, "CharacterValues"); } }
private static int GetItemHeight(UnitObject item) { int height = UnitHelpFunctions.GetSimpleValue(item, ItemValueNames.inventory_height.ToString()); if (height <= 0) { height = 1; } return height; }
//public static Unit OpenCharacterFile(TableFiles tableFiles, string fileName) //// todo: rewrite public static Unit OpenCharacterFile(TableDataSet tableDataSet, string fileName) //{ // Unit unit = null; // const string excelError = "You must have all excel tables loaded to load characters!"; // if (tableDataSet == null) // { // MessageBox.Show(excelError, "OpenCharacterFile", MessageBoxButtons.OK, MessageBoxIcon.Error); // return null; // } // //if (!tableFiles.AllExcelFilesLoaded || !tableFiles.AllStringsFilesLoaded) // //{ // // MessageBox.Show(excelError, "OpenCharacterFile", MessageBoxButtons.OK, MessageBoxIcon.Error); // // return null; // //} // FileStream heroFile; // try // { // heroFile = new FileStream(fileName, FileMode.Open); // } // catch (Exception e) // { // MessageBox.Show("Failed to open file: " + fileName + "\n\n" + e, "OpenCharacterFile", MessageBoxButtons.OK, MessageBoxIcon.Error); // return null; // } // BitBuffer bitBuffer = new BitBuffer(FileTools.StreamToByteArray(heroFile)) {DataByteOffset = 0x2028}; // unit = new Unit(bitBuffer); // unit.ParseUnit(); // heroFile.Close(); // return unit; //} private void PopulateItems(UnitObject unitObject) { try { bool canGetItemNames = true; DataTable itemsTable = _fileManager.GetDataTable("ITEMS"); DataTable affixTable = _fileManager.GetDataTable("AFFIXES"); DataTable affixNames = _fileManager.GetDataTable("Strings_Affix"); if (itemsTable != null && affixTable != null) { if (!itemsTable.Columns.Contains("code") || !itemsTable.Columns.Contains("String_string")) canGetItemNames = false; if (!affixTable.Columns.Contains("code") || !affixTable.Columns.Contains("setNameString_string") || !affixTable.Columns.Contains("magicNameString_string")) canGetItemNames = false; } else { canGetItemNames = false; } List<UnitObject> items = unitObject.Items; for (int i = 0; i < items.Count; i++) { UnitObject item = items[i]; if (item == null) continue; //It's an engineer and his drone if (item.UnitCode == (int)SpecialItems.Drone) { item.Name = "Drone"; continue; } // assign default name item.Name = "Item Id: " + item.UnitCode; if (!canGetItemNames) { continue; } if (item.UnitCode == 25393) { //string a; } // get item name DataRow[] itemsRows = itemsTable.Select(String.Format("code = '{0}'", item.UnitCode)); if (itemsRows.Length == 0) { continue; } item.Name = itemsRows[0]["String_string"] as String; // does it have an affix/prefix String affixString = String.Empty; foreach (UnitObjectStats.Stat stat in item.Stats.Stats.Values) { //for (int s = 0; s < item.Stats.NameCount; s++) //{ // "applied_affix" if (stat.Code == (int)ItemValueNames.applied_affix) { int affixCode = stat.Values[0].Value; DataRow[] affixRows = affixTable.Select(String.Format("code = '{0}'", affixCode)); if (affixRows.Length > 0) { //String replaceString = affixRows[0]["setNameString_String"] as String; int index = (int)affixRows[0]["setNameString"]; if (index < 0) { index = (int)affixRows[0]["magicNameString"]; //replaceString = affixRows[0]["magicNameString"] as String; if (index < 0) { break; } } DataRow[] stringRows = affixNames.Select(String.Format("ReferenceId = '{0}'", index)); String replaceString = stringRows[0]["String"] as String; affixString = replaceString; } } // "item_quality" if (stat.Code == (int)ItemValueNames.item_quality) { // is unique || is mutant then no affix int itemQualityCode = stat.Values[0].Value; if (itemQualityCode == (int)ItemQuality.Unique || itemQualityCode == (int)ItemQuality.Mutant) { affixString = String.Empty; break; } } } if (affixString.Length > 0) { item.Name = affixString.Replace("[item]", item.Name); } if (item.Items.Count > 0) { PopulateItems(item); } } } catch (Exception ex) { ExceptionLogger.LogException(ex, true); } }
public CharacterWrapper(UnitObject character, FileManager fileManager) : base(character, fileManager) { itemsTable = fileManager.GetDataTable("ITEMS"); DataTable players = fileManager.GetDataTable("PLAYERS"); DataRow[] playerRow = players.Select("code = " + character.UnitCode); if (playerRow.Length > 0) { int playerType = (int)playerRow[0]["unitType"]; List<int> skillTabs = new List<int>(); for (int counter = 1; counter < 8; counter++) { int skillTab = (int)playerRow[0]["SkillTab" + counter]; if (skillTab >= 0) { skillTabs.Add(skillTab); } } unitType = playerType - 3; characterSkills = new CharacterSkills(character, fileManager, skillTabs.ToArray()); } characterClass = GetCharacterClass(character); characterGameMode = new CharacterGameMode(character, fileManager); characterValues = new CharacterValues(character, fileManager); gender = characterClass.ToString().EndsWith("_Male") ? Gender.Male : Gender.Female; weaponSlots = new WeaponSlots(character, fileManager); characterInventory = new CharacterInventory(character, fileManager); if (characterClass == CharacterClass.Engineer_Male || characterClass == CharacterClass.Engineer_Female) { //drone = new EngineerDrone(character, fileManager); } }
public static bool SetSimpleValue(UnitObject unit, int valueId, int value) { //if (!initialized) return; foreach (UnitObjectStats.Stat unitStats in unit.Stats.Stats.Values) { if (unitStats.Code != valueId) continue; unitStats.Values[0].Value = value; return true; } //for (int counter = 0; counter < unit.Stats.Stats.Count; counter++) //{ // UnitObjectStats.Stat unitStats = unit.Stats[counter]; // if (unitStats.Code != valueId) continue; // unitStats.Values[0].Value = value; // return true; //} return false; }
public void LoadCharacterValues(UnitObject unit) { //GenerateUnitNameStrings(new[] { unit }, null); PopulateItems(unit); }
public static bool SetComplexValue(UnitObject unit, string valueName, UnitObjectStats.Stat stat) { //if (!initialized) return; foreach (UnitObjectStats.Stat unitStats in unit.Stats.Stats.Values) { if (unitStats.Name != valueName) continue; return true; } //for (int counter = 0; counter < unit.Stats.Stats.Count; counter++) //{ // UnitObjectStats.Stat unitStats = unit.Stats[counter]; // if (unitStats.Name != valueName) continue; // unitStats = stat; // return true; //} return false; }
public static void SaveCharacterFile(UnitObject unit, string filePath) { DialogResult dr = DialogResult.Retry; while (dr == DialogResult.Retry) { try { using (FileStream saveFile = new FileStream(filePath, FileMode.Create, FileAccess.ReadWrite)) { // main header MainHeader mainHeader; mainHeader.Flag = 0x484D4752; // "RGMH" mainHeader.Version = 1; mainHeader.DataOffset1 = 0x2028; mainHeader.DataOffset2 = 0x2028; byte[] data = FileTools.StructureToByteArray(mainHeader); saveFile.Write(data, 0, data.Length); // hellgate string (is this needed?) const string hellgateString = "Hellgate: London"; byte[] hellgateStringBytes = FileTools.StringToUnicodeByteArray(hellgateString); saveFile.Seek(0x28, SeekOrigin.Begin); saveFile.Write(hellgateStringBytes, 0, hellgateStringBytes.Length); // char name (not actually used in game though I don't think) (is this needed?) string charString = unit.Name; byte[] charStringBytes = FileTools.StringToUnicodeByteArray(charString); saveFile.Seek(0x828, SeekOrigin.Begin); saveFile.Write(charStringBytes, 0, charStringBytes.Length); // no detail string (is this needed?) const string noDetailString = "No detail"; byte[] noDetailStringBytes = FileTools.StringToUnicodeByteArray(noDetailString); saveFile.Seek(0x1028, SeekOrigin.Begin); saveFile.Write(noDetailStringBytes, 0, noDetailStringBytes.Length); // load char string (is this needed?) const string loadCharacterString = "Load this Character"; byte[] loadCharacterStringBytes = FileTools.StringToUnicodeByteArray(loadCharacterString); saveFile.Seek(0x1828, SeekOrigin.Begin); saveFile.Write(loadCharacterStringBytes, 0, loadCharacterStringBytes.Length); // main character data saveFile.Seek(0x2028, SeekOrigin.Begin); byte[] saveData = null;// todo: update me unit.GenerateSaveData(charStringBytes); saveFile.Write(saveData, 0, saveData.Length); } MessageBox.Show("Character saved successfully!", "Saved", MessageBoxButtons.OK, MessageBoxIcon.Information); break; } catch (Exception e) { dr = MessageBox.Show("Failed to save character file!Try again?\n\n" + e, "Error", MessageBoxButtons.RetryCancel); } } }
public static int GetSimpleValue(UnitObject unit, int valueId) { foreach (UnitObjectStats.Stat unitStats in unit.Stats.Stats.Values) { if (unitStats.Code != valueId) continue; UnitObjectStats.Stat.StatValue entry = unitStats.Values[0]; // if all atributes are 0 the value is most likely a simple value if (entry.Param1 == 0 && entry.Param2 == 0 && entry.Param3 == 0) { return entry.Value; } ExceptionLogger.LogException(new Exception("IsComplexAttributeException"), false, unitStats.Code + " is of type ComplexValue"); } //for (int counter = 0; counter < unit.Stats.Stats.Count; counter++) //{ // UnitObjectStats.Stat unitStats = unit.Stats[counter]; // if (unitStats.Code == valueId) // { // UnitObjectStats.Stat.StatValue entry = unitStats.Values[0]; // // if all atributes are 0 the value is most likely a simple value // if (entry.Param1 == 0 && entry.Param2 == 0 && entry.Param3 == 0) // { // return entry.Value; // } // ExceptionLogger.LogException(new Exception("IsComplexAttributeException"), "GetSimpleValue", unitStats.Code + " is of type ComplexValue", false); // } //} //MessageBox.Show("Field \"" + valueName + "\" not present in unit " + unit.Name + "!"); return 0; }
public CharacterProperty(UnitObject unitObject, FileManager fileManager) { this.unitObject = unitObject; this.fileManager = fileManager; statsTable = fileManager.GetDataTable("STATS"); }
public CharacterInventory(UnitObject unitObject, FileManager fileManager) : base(unitObject, fileManager) { _inventoryList = new List<CharacterInventoryType>(); foreach (UnitObject unit in unitObject.Items) { CharacterItems item = new CharacterItems(unit, fileManager); // get the matching inventory entry CharacterInventoryType inv = _inventoryList.Find(tmp => tmp.InventoryType == (int)item.InventoryType); if (inv == null) { inv = new CharacterInventoryType((int)item.InventoryType); _inventoryList.Add(inv); } inv.Items.Add(item); } }
public CharacterSkills(UnitObject unitObject, FileManager fileManager, IEnumerable<int> skillTabs) : base(unitObject, fileManager) { _skillTabs = new List<SkillTab>(); //to make things easier, let's add all available character skills to the list List<UnitObjectStats.Stat.StatValue> availableSkills = new List<UnitObjectStats.Stat.StatValue>(); ////get the skills the character already knows UnitObjectStats.Stat skills = UnitHelpFunctions.GetComplexValue(unitObject, ItemValueNames.skill_level); ////add them to the complete skill list availableSkills.AddRange(skills.Values); DataTable skillTable = fileManager.GetDataTable("SKILLS"); //let's add all the skills the character doesn't know yet foreach (int skillTab in skillTabs) { DataRow[] skillRows = skillTable.Select("skillTab = " + skillTab); SkillTab skillsInSkillTab = CreateSkillsFromRow(availableSkills, skillTable, skillRows); if (skillsInSkillTab.Skills.Count > 0) { _skillTabs.Add(skillsInSkillTab); } } // select the general skill tab DataRow[] generalSkillRows = skillTable.Select("skillTab = " + 0); _generalSkills = CreateSkillsFromRow(availableSkills, skillTable, generalSkillRows); //add all skills back to the savegame availableSkills.Clear(); foreach (Skill skill in _generalSkills.Skills) { availableSkills.Add(skill.SkillBlock); } foreach (SkillTab skillTab in _skillTabs) { foreach (Skill skill in skillTab.Skills) { availableSkills.Add(skill.SkillBlock); } } //skills.repeatCount = availableSkills.Count; //skills.Values = availableSkills; skills.Values.Clear(); skills.Values.AddRange(availableSkills); }
private void ParseCharacter(UnitObject unitObject) { UnitHelpFunctions unitHelp = new UnitHelpFunctions(fileManager); unitHelp.LoadCharacterValues(baseCharacter.Character); characterWrapper = new CharacterWrapper(baseCharacter.Character, fileManager); }
private CharacterClass GetCharacterClass(UnitObject _hero) { return (CharacterClass)Enum.Parse(typeof(CharacterClass), _hero.UnitCode.ToString()); }
private void PopulateGeneral(UnitObject heroUnit) { try { name_TextBox.Text = heroUnit.Name; string job; switch (heroUnit.UnitCode) { case (0x7679): job = "Male Summoner"; _characterClass = CharacterClass.Summoner; break; case (0x7579): job = "Female Summoner"; _characterClass = CharacterClass.Summoner; break; case (0x7A7A): job = "Male Guardian"; _characterClass = CharacterClass.Guardian; break; case (0x797A): job = "Female Guardian"; _characterClass = CharacterClass.Guardian; break; case (0x7678): job = "Male Marksman"; _characterClass = CharacterClass.Marksman; break; case (0x7578): job = "Female Marksman"; _characterClass = CharacterClass.Marksman; break; case (0x7879): job = "Male Evoker"; _characterClass = CharacterClass.Evoker; break; case (0x7779): job = "Female Evoker"; _characterClass = CharacterClass.Evoker; break; case (0x787A): job = "Male Blademaster"; _characterClass = CharacterClass.Blademaster; break; case (0x777A): job = "Female Blademaster"; _characterClass = CharacterClass.Blademaster; break; case (0x7878): job = "Male Engineer"; _characterClass = CharacterClass.Engineer; break; case (0x7778): job = "Female Engineer"; _characterClass = CharacterClass.Engineer; break; default: job = "Unknown"; break; } class_TextBox.Text = job; SetStateCheckBoxes(); SetCharacterValues(); DisplayFlags(); } catch (Exception ex) { MessageBox.Show(ex.Message, "PopulateGeneral"); } }
private static int GetItemWidth(UnitObject item) { int width = UnitHelpFunctions.GetSimpleValue(item, ItemValueNames.inventory_width.ToString()); if (width <= 0) { width = 1; } return width; }
private void PopulateStats(UnitObject unit) { try { stats_ListBox.Items.Clear(); foreach (UnitObjectStats.Stat stat in unit.Stats.Stats.Values) { stats_ListBox.Items.Add(stat); } } catch (Exception ex) { MessageBox.Show(ex.Message, "PopulateStats"); } }
public WeaponSlots(UnitObject unitObject, FileManager fileManager) : base(unitObject, fileManager) { }
public static UnitObjectStats.Stat GetComplexValue(UnitObject unit, ItemValueNames valueName) { foreach (UnitObjectStats.Stat unitStats in unit.Stats.Stats.Values) { if (unitStats.Code == (int)valueName) { return unitStats; } } //for (int counter = 0; counter < unit.Stats.Stats.Count; counter++) //{ // UnitObjectStats.Stat unitStats = unit.Stats[counter]; // if (unitStats.Code == (int)valueName) // { // return unitStats; // } //} return null; }
private void PopulateItemDropDown(UnitObject unit) { foreach (UnitObject item in unit.Items) { currentlyEditing_ComboBox.Items.Add(item); } }
public CharacterItems(UnitObject unitObject, FileManager fileManager) : base(unitObject, fileManager) { _itemTable = fileManager.GetDataTable("ITEMS"); DataRow[] itemRow = _itemTable.Select("code = " + unitObject.UnitCode); //DataTable colorTable = _dataSet.GetExcelTableFromStringId("ITEMQUALITY"); //DataRow[] colorRow = colorTable.Select("code = " + _hero.unitCode); if (itemRow.Length > 0) { _isItem = true; uint bitMask = (uint)itemRow[0]["bitmask02"]; _isQuestItem = (bitMask >> 13 & 1) == 1; string maxStackSize = (string)itemRow[0]["stackSize"]; string[] splitResult = maxStackSize.Split(new char[] { ',' }); if (splitResult.Length == 3) { _maxStackSize = int.Parse(splitResult[1]); } if (_maxStackSize <= 0) { _maxStackSize = 1; } _stackSize = UnitHelpFunctions.GetSimpleValue(unitObject, ItemValueNames.item_quantity.ToString()); if (_stackSize <= 0) { _stackSize = 1; } _itemImagePath = CreateImagePath(); _numberOfAugmentations = UnitHelpFunctions.GetSimpleValue(unitObject, ItemValueNames.item_augmented_count.ToString()); _numberOfUpgrades = UnitHelpFunctions.GetSimpleValue(unitObject, ItemValueNames.item_upgraded_count.ToString()); DataTable gameGlobals = fileManager.GetDataTable("GAME_GLOBALS"); //DataRow[] globalsRow = gameGlobals.Select("name = " + "max_item_upgrades"); DataRow[] globalsRow = gameGlobals.Select("Index = " + 16); _maxNumberOfUpgrades = (int)globalsRow[0]["intValue"]; //globalsRow = gameGlobals.Select("name = " + "max_item_augmentations"); globalsRow = gameGlobals.Select("Index = " + 17); _maxNumberOfAffixes = (int)globalsRow[0]["intValue"]; UnitObjectStats.Stat affixes = UnitHelpFunctions.GetComplexValue(unitObject, ItemValueNames.applied_affix.ToString()); if (affixes != null) { _numberOfAffixes = affixes.Values.Count; } int numberOfInherentAffixes = _numberOfAffixes - _numberOfAugmentations; _numberOfAugmentationsLeft = _maxNumberOfAffixes - numberOfInherentAffixes; if (_numberOfAugmentationsLeft < 0) { _numberOfAugmentationsLeft = 0; } _maxNumberOfAugmentations = _numberOfAugmentations + _numberOfAugmentationsLeft; if (_maxNumberOfAugmentations > _maxNumberOfAffixes) { _maxNumberOfAugmentations = _maxNumberOfAffixes; } } _items = new List<CharacterItems>(); foreach (UnitObject item in unitObject.Items) { CharacterItems wrapper = new CharacterItems(item, fileManager); _items.Add(wrapper); } }
/// <summary> /// Reads a UnitObject from the internal serialised byte array. /// </summary> private void _ReadUnit() { //// start of header // unit object versions _version = _bitBuffer.ReadInt16(); _context = (ObjectContext)_bitBuffer.ReadByte(); if (_version != 0x00BF && _version != 0x00CD && _version != 0x00CF) throw new Exceptions.NotSupportedVersionException("0x00BF or 0x00CD or 0x00CF", "0x" + _version.ToString("X4")); if (_context != ObjectContext.Save && _context != ObjectContext.CharSelect && _context != ObjectContext.CharStats && _context != ObjectContext.ItemDrop) { throw new Exceptions.NotSupportedVersionException("0x00 or 0x02 or 0x03 or 0x04", "0x" + _context.ToString("X2")); } if (_debugOutputLoadingProgress) { Debug.WriteLine(String.Format("Version = {0} (0x{0:X4}), Context = {1} (0x{2:X2})", _version, _context, (int)_context)); } // content bit fields _bitFieldCount = _bitBuffer.ReadBits(8); if (_bitFieldCount == 1) _bitField = _bitBuffer.ReadUInt32(); if (_bitFieldCount == 2) _bitField = _bitBuffer.ReadUInt64(); if (_debugOutputLoadingProgress) { Debug.WriteLine(String.Format("BitField = {0} (0x{1:X16})", _DebugBinaryFormat(_bitField), _bitField)); } // total bit count if (_TestBit(Bits.Bit1DBitCountEof)) { _bitCount = _bitBuffer.ReadBits(32); if (_debugOutputLoadingProgress) { Debug.WriteLine(String.Format("Total BitCount = {0}", _bitCount)); } } // begin data magic word if (_TestBit(Bits.Bit00FlagAlignment)) { _beginFlag = (uint)_bitBuffer.ReadBits(32); if (_debugOutputLoadingProgress) { Debug.WriteLine(String.Format("BeginFlag = 0x{0}", _beginFlag.ToString("X8"))); } if (_beginFlag != ObjectMagicWord && _beginFlag != ItemMagicWord) throw new Exceptions.UnexpectedTokenException(ObjectMagicWord, _beginFlag); } // dunno what these are exactly if (_TestBit(Bits.Bit1CTimeStamps)) { _timeStamp1 = _bitBuffer.ReadBits(32); _timeStamp2 = _bitBuffer.ReadBits(32); _timeStamp3 = _bitBuffer.ReadBits(32); if (_debugOutputLoadingProgress) { Debug.WriteLine(String.Format("TimeStamp1 = {0}, TimeStamp2 = {1}, TimeStamp3 = {2}", _timeStamp1, _timeStamp2, _timeStamp3)); } } // last station visited save/respawn location if (_TestBit(Bits.Bit1FSaveLocations)) { int saveLocationsCount = _bitBuffer.ReadBitsShift(4); if (_debugOutputLoadingProgress) { Debug.WriteLine(String.Format("SaveLocationsCount = {0}", saveLocationsCount)); } for (int i = 0; i < saveLocationsCount; i++) { ushort levelCode = _bitBuffer.ReadUInt16(); // table 0x6D (LEVEL) ushort difficultyCode = _bitBuffer.ReadUInt16(); // table 0xB2 (DIFFICULTY) SaveLocation saveLocation = new SaveLocation { Level = (LevelRow)FileManager.GetRowFromCode(Xls.TableCodes.LEVEL, (short)levelCode), Difficulty = (DifficultyRow)FileManager.GetRowFromCode(Xls.TableCodes.DIFFICULTY, (short)difficultyCode) }; SaveLocations.Add(saveLocation); if ((SaveLocations[i].Level == null && SaveLocations[i].Difficulty != null) || (SaveLocations[i].Level != null && SaveLocations[i].Difficulty == null)) { throw new Exceptions.UnitObjectException(String.Format("Invalid SaveLocation encountered. Level = {0:X4}, Difficulty = {1:X4}", levelCode, difficultyCode)); } if (!_debugOutputLoadingProgress) continue; if (SaveLocations[i].Level == null || SaveLocations[i].Difficulty == null) { Debug.WriteLine(String.Format("SaveLocations[{0}].LevelCode = {1} (0x{1:X4}), SaveLocations[{0}].DifficultyCode = {2} (0x{2:X4})", i, levelCode, difficultyCode)); } else { Debug.WriteLine(String.Format("SaveLocations[{0}].Level = {1}, SaveLocations[{0}].Difficulty = {2}", i, SaveLocations[i].Level.levelName, SaveLocations[i].Difficulty.name)); } } } // character flags if (_TestBit(Bits.Bit20States1)) { int statCount = _bitBuffer.ReadBits(8); if (_debugOutputLoadingProgress) { Debug.WriteLine(String.Format("StateCode1Count = {0}", statCount)); } for (int i = 0; i < statCount; i++) { int state = _bitBuffer.ReadInt16(); AddState1(state); // table 0x4B (STATES) if (_debugOutputLoadingProgress) { Debug.WriteLine(String.Format("StateCodes1[{0}] = {1}({2:X})", i, StateCodes1[i], (short)(StateCodes1[i]))); } } } //// end of header // bit offsets to bookmarks (only 1 bookmark though - "hotkeys") if (_TestBit(Bits.Bit1BBookmarks)) { BookmarkCount = _bitBuffer.ReadBits(5); if (_debugOutputLoadingProgress) { Debug.WriteLine(String.Format("BookmarkCount = {0}", BookmarkCount)); } if (BookmarkCount > 1) { throw new Exceptions.UnitObjectNotImplementedException("Unexpected BookmarkCount (> 1)!\nNot-Implemented cases. Please report this error and supply the offending file."); } for (int i = 0; i < BookmarkCount; i++) { Bookmark bookmark = new Bookmark { Code = _bitBuffer.ReadUInt16(), Offset = _bitBuffer.ReadInt32() }; if (_debugOutputLoadingProgress) { Debug.WriteLine(String.Format("Bookmarks[{0}].Code = {1} (0x{1:X4}), Bookmarks[{0}].Offset = {2}", i, bookmark.Code, bookmark.Offset)); } Bookmarks.Add(bookmark); } } // dunno... if (_TestBit(Bits.Bit05Unknown)) { UnitObjectId = _bitBuffer.ReadInt32(); if (_debugOutputLoadingProgress) { Debug.WriteLine(String.Format("UnitObjectId = {0} (0x{0:X4})", UnitObjectId)); } } // unit type/code // if unit type == 1, table = 0x91 (PLAYERS) // 2, table = 0x77 (MONSTERS) // 3? (table = 0x72; MISSILES at a guess. For memory, MISSILES doesn't use code values - probably why not seen in ASM) // 4, table = 0x67 (ITEMS) // 5, table = 0x7B (OBJECTS) UnitType = (UnitTypes)_bitBuffer.ReadBits(4); if (_debugOutputLoadingProgress) { Debug.WriteLine(String.Format("UnitType = {0}", UnitType)); } UnitCode = _bitBuffer.ReadUInt16(); if (_debugOutputLoadingProgress) { Debug.Write(String.Format("UnitCode = {0} (0x{0:X4}), ", UnitCode)); } Xls.TableCodes tableCode = Xls.TableCodes.Null; switch (UnitType) { case UnitTypes.Player: tableCode = Xls.TableCodes.PLAYERS; break; case UnitTypes.Monster: tableCode = Xls.TableCodes.MONSTERS; break; case UnitTypes.Missile: tableCode = Xls.TableCodes.MISSILES; break; case UnitTypes.Item: tableCode = Xls.TableCodes.ITEMS; break; case UnitTypes.Object: tableCode = Xls.TableCodes.OBJECTS; break; } if (tableCode == Xls.TableCodes.Null) throw new Exceptions.UnitObjectException("The unit object data has an unknown UnitType."); UnitData = FileManager.GetUnitDataRowFromCode(tableCode, (short)UnitCode); if (UnitData == null) Debug.WriteLine(String.Format("Warning: UnitCode {0} (0x{0:X4}) not found!", UnitCode)); if (_debugOutputLoadingProgress && UnitData != null) { ExcelFile unitDataTable = FileManager.GetExcelTableFromCode(tableCode); String rowName = unitDataTable.ReadStringTable(UnitData.name); Debug.WriteLine(String.Format("UnitDataName = " + rowName)); } // unit object id if (_TestBit(Bits.Bit17ObjectId)) { if (_version > 0xB2) { ObjectId = _bitBuffer.ReadUInt64(); if (_debugOutputLoadingProgress) { Debug.WriteLine(String.Format("ObjectId = {0} (0x{0:X16})", ObjectId)); } if (ObjectId == 0) { throw new Exceptions.UnitObjectNotImplementedException("if (ObjectId == 0)"); } } } // item positioning stuff if (_TestBit(Bits.Bit01Unknown) || _TestBit(Bits.Bit03Unknown)) { IsInventory = _bitBuffer.ReadBool(); if (_debugOutputLoadingProgress) { Debug.WriteLine(String.Format("IsInventory = {0}, Bits.Bit01Unknown = {1}, Bits.Bit03Unknown = {2}", IsInventory, _TestBit(Bits.Bit01Unknown), _TestBit(Bits.Bit03Unknown))); } if (IsInventory) // item is in inventory { if (_TestBit(Bits.Bit02Unknown)) { Unknown02 = _bitBuffer.ReadBits(32); if (_debugOutputLoadingProgress) { Debug.WriteLine(String.Format("Unknown02 = {0}", Unknown02)); } } InventoryLocationIndex = _bitBuffer.ReadBits(12); InventoryPositionX = _bitBuffer.ReadBits(12); InventoryPositionY = _bitBuffer.ReadBits(12); Unknown04 = _bitBuffer.ReadBits(4); if (_debugOutputLoadingProgress) { Debug.WriteLine(String.Format("InventoryLocationIndex = {0}, InventoryPositionX = {1}, InventoryPositionY = {2}, Unknown04 = {3}", InventoryLocationIndex, InventoryPositionX, InventoryPositionY, Unknown04)); } Unknown0103Int64 = _bitBuffer.ReadNonStandardFunc(); if (_debugOutputLoadingProgress) { Debug.WriteLine(String.Format("Unknown0103Int64 = {0} (0x{0:X16})", Unknown0103Int64)); } } else // item is a "world drop" { RoomId = _bitBuffer.ReadInt32(); Position.X = _bitBuffer.ReadFloat(); Position.Y = _bitBuffer.ReadFloat(); Position.Z = _bitBuffer.ReadFloat(); Unknown0103Float21 = _bitBuffer.ReadFloat(); Unknown0103Float22 = _bitBuffer.ReadFloat(); Unknown0103Float23 = _bitBuffer.ReadFloat(); Normal.X = _bitBuffer.ReadFloat(); Normal.Y = _bitBuffer.ReadFloat(); Normal.Z = _bitBuffer.ReadFloat(); Unknown0103Int2 = _bitBuffer.ReadBits(10); Unknown0103Float4 = _bitBuffer.ReadFloat(); Unknown0103Float5 = _bitBuffer.ReadFloat(); if (_debugOutputLoadingProgress) { Debug.WriteLine(String.Format("RoomId = {0}", RoomId)); Debug.WriteLine(String.Format("Position.X = {0}, Position.Y = {1}, Position.Z = {2}", Position.X, Position.Y, Position.Z)); Debug.WriteLine(String.Format("Unknown0103Float21 = {0}, Unknown0103Float22 = {1}, Unknown0103Float23 = {2}", Unknown0103Float21, Unknown0103Float22, Unknown0103Float23)); Debug.WriteLine(String.Format("NormalX = {0}, NormalY = {1}, NormalZ = {2}", Normal.X, Normal.Y, Normal.Z)); Debug.WriteLine(String.Format("Unknown0103Int2 = {0}", Unknown0103Int2)); Debug.WriteLine(String.Format("Unknown0103Float4 = {0}", Unknown0103Float4)); Debug.WriteLine(String.Format("Unknown0103Float5 = {0}", Unknown0103Float5)); } } } // I think this has something to do with the Monsters table +46Ch, bit 0x55 = 4 bits or bit 0x47 = 2 bits. Or Objects table +46Ch, bit 0x55 = 2 bits... Something like that if (_TestBit(Bits.Bit06Unknown)) { UnknownBool06 = _bitBuffer.ReadBool(); if (_debugOutputLoadingProgress) { Debug.WriteLine(String.Format("UnknownBool06 = {0}", UnknownBool06)); } if (!UnknownBool06) { throw new Exceptions.UnitObjectNotImplementedException("if (UnknownBool06 != 1)"); } } if (_TestBit(Bits.Bit09ItemLookGroup)) { ItemLookGroupCode = _bitBuffer.ReadBits(8); if (_debugOutputLoadingProgress) { Debug.WriteLine(String.Format("ItemLookGroupCode = {0} (0x{0:X2})", ItemLookGroupCode)); } } // on character only if (_TestBit(Bits.Bit07CharacterShape)) { CharacterHeight = _bitBuffer.ReadByte(); CharacterBulk = _bitBuffer.ReadByte(); if (_debugOutputLoadingProgress) { Debug.WriteLine(String.Format("CharacterHeight = {0}, CharacterBulk = {1}", CharacterHeight, CharacterBulk)); } } // object id for older versions - they moved it? if (_TestBit(Bits.Bit17ObjectId)) { if (_version <= 0xB2) { throw new Exceptions.UnitObjectNotImplementedException("if (_TestBit(0x17) && Version <= 0xB2)"); } } // on character only if (_TestBit(Bits.Bit08CharacterName)) { int unicodeCharCount = _bitBuffer.ReadBits(8); if (unicodeCharCount > 0) { int byteCount = unicodeCharCount * 2; // is Unicode string without \0 _charNameBytes = new byte[byteCount]; for (int i = 0; i < byteCount; i++) { _charNameBytes[i] = _bitBuffer.ReadByte(); } Name = Encoding.Unicode.GetString(_charNameBytes, 0, byteCount); if (_debugOutputLoadingProgress) { Debug.WriteLine(String.Format("Name = {0}", Name)); } } } // on both character and items - appears to be always zero for items if (_TestBit(Bits.Bit0AStates2)) { int stateCount = _bitBuffer.ReadBits(8); if (_debugOutputLoadingProgress) { Debug.WriteLine(String.Format("StateCode2Count = {0}", stateCount)); } for (int i = 0; i < stateCount; i++) { int state = _bitBuffer.ReadInt16(); AddState2(state); if (_debugOutputLoadingProgress) { Debug.WriteLine(String.Format("StateCodes2[{0}] = {1}({2:X})", i, StateCodes2[i], (short)(StateCodes2[i]))); } // this section looks like it has more reading if Bit14 is flagged (CharSelectStats) } } if (_context > ObjectContext.CharSelect && (_context <= ObjectContext.Unknown6 || _context != ObjectContext.Unknown7)) // so if == 0, 1, 2, 7, then *don't* do this { ContextBool = _bitBuffer.ReadBool(); if (ContextBool) { ContextBoolValue = _bitBuffer.ReadBits(4); // invlocidx?? } if (_debugOutputLoadingProgress) { Debug.WriteLine(String.Format("UsageBool = {0}, UsageBoolValue = {1}", ContextBool, ContextBoolValue)); } } // <unknown bitfield 0x11th bit> - only seen as false anyways IsDead = _bitBuffer.ReadBool(); if (_debugOutputLoadingProgress) { Debug.WriteLine(String.Format("IsDead = {0}", IsDead)); } // unit stats if (_TestBit(Bits.Bit0DStats)) { Stats.ReadStats(_bitBuffer, true); } else if (_TestBit(Bits.Bit14CharSelectStats)) { int characterLevel = _bitBuffer.ReadByte(); // stats row 0x000 (level) Stats.SetStat("level", characterLevel); int characterPvpRankRowIndex = _bitBuffer.ReadByte(); // stats row 0x347 (player_rank) Stats.SetStat("player_rank", characterPvpRankRowIndex); if (_debugOutputLoadingProgress) { Debug.WriteLine(String.Format("LevelRowIndex = {0}, PlayerRankRowIndex = {1}", characterLevel, characterPvpRankRowIndex)); } if (_TestBit(Bits.Bit1ECharSelectStatsMaxDifficulty)) { int maxDifficultyRowIndex = _bitBuffer.ReadBits(3); // stats row 0x347 (difficulty_max) Stats.SetStat("difficulty_max", maxDifficultyRowIndex); if (_debugOutputLoadingProgress) { Debug.WriteLine(String.Format("MaxDifficultyRowIndex = {0}, ", maxDifficultyRowIndex)); } } } HasAppearanceDetails = _bitBuffer.ReadBool(); if (_debugOutputLoadingProgress) { Debug.WriteLine(String.Format("HasAppearanceDetails = {0}", HasAppearanceDetails)); } if (HasAppearanceDetails) { _ReadAppearance(); } if (_TestBit(Bits.Bit12Items)) { ItemEndBitOffset = _bitBuffer.ReadInt32(); ItemCount = _bitBuffer.ReadBits(10); if (_debugOutputLoadingProgress) { Debug.WriteLine(String.Format("ItemEndBitOffset = {0}, ItemCount = {1}", ItemEndBitOffset, ItemCount)); } for (int i = 0; i < ItemCount; i++) { UnitObject item = new UnitObject(_bitBuffer, _debugOutputLoadingProgress); item._ReadUnit(); Items.Add(item); } } if (_TestBit(Bits.Bit1AHotkeys)) { HotkeyFlag = _bitBuffer.ReadUInt32(); if (_debugOutputLoadingProgress) { Debug.WriteLine(String.Format("HotkeyFlag = {0} (0x{0:X8})", HotkeyFlag)); } if (HotkeyFlag != HotkeysMagicWord) { throw new Exceptions.UnexpectedTokenException(HotkeysMagicWord, HotkeyFlag); } EndFlagBitOffset = _bitBuffer.ReadBits(32); // to end flag if (_debugOutputLoadingProgress) { Debug.WriteLine(String.Format("EndFlagBitOffset = {0}", EndFlagBitOffset)); } HotkeyCount = _bitBuffer.ReadBits(6); if (_debugOutputLoadingProgress) { Debug.WriteLine(String.Format("HotkeyCount = {0}", HotkeyCount)); } for (int i = 0; i < HotkeyCount; i++) { Hotkey hotkey = new Hotkey { Code = _bitBuffer.ReadUInt16(), // code from TAG table }; Hotkeys.Add(hotkey); if (_debugOutputLoadingProgress) { Debug.WriteLine(String.Format("hotkey.Code = 0x{0:X4}", hotkey.Code)); } hotkey.UnknownCount = _bitBuffer.ReadBits(4); if (_debugOutputLoadingProgress) { Debug.WriteLine(String.Format("hotkey.UnknownCount = " + hotkey.UnknownCount)); } if (hotkey.UnknownCount > 0x02) { throw new Exceptions.UnitObjectNotImplementedException("if (hotkey.UnknownCount > 0x02)"); } hotkey.UnknownExists = new bool[hotkey.UnknownCount]; hotkey.UnknownValues = new int[hotkey.UnknownCount]; for (int j = 0; j < hotkey.UnknownCount; j++) { hotkey.UnknownExists[j] = _bitBuffer.ReadBool(); if (hotkey.UnknownExists[j]) { hotkey.UnknownValues[j] = _bitBuffer.ReadBits(32); // under some condition this will be ReadFromOtherFunc thingy } if (_debugOutputLoadingProgress) { Debug.WriteLine(String.Format("hotkey.UnknownExists[{0}] = {1}, hotkey.UnknownValues[{0}] = 0x{2:X8}", j, hotkey.UnknownExists[j], hotkey.UnknownValues[j])); } } hotkey.SkillCount = _bitBuffer.ReadBits(4); hotkey.SkillExists = new bool[hotkey.SkillCount]; hotkey.SkillCode = new int[hotkey.SkillCount]; for (int j = 0; j < hotkey.SkillCount; j++) { hotkey.SkillExists[j] = _bitBuffer.ReadBool(); if (hotkey.SkillExists[j]) { hotkey.SkillCode[j] = _bitBuffer.ReadBits(32); // code from SKILLS table } if (_debugOutputLoadingProgress) { Debug.WriteLine(String.Format("hotkey.SkillExists[{0}] = {1}, hotkey.SkillCode[{0}] = 0x{2:X8}", j, hotkey.SkillExists[j], hotkey.SkillCode[j])); } } hotkey.UnitTypeCode = _bitBuffer.ReadBits(32); // code from UNITTYPES table if (_debugOutputLoadingProgress) { Debug.WriteLine(String.Format("hotkey.UnitTypeCode = 0x{0:X8}", hotkey.UnitTypeCode)); } } } // end flag EndFlag = _bitBuffer.ReadBits(32); if (_debugOutputLoadingProgress) { Debug.WriteLine(String.Format("EndFlag = {0} (0x{0:X8})", EndFlag)); } if (EndFlag != _beginFlag && EndFlag != ItemMagicWord) { int bitOffset = _bitCount - _bitBuffer.BitOffset; int byteOffset = (_bitBuffer.Length - _bitBuffer.Offset) - (_bitBuffer.BytesUsed); throw new Exceptions.InvalidFileException("Flags not aligned!\nBit Offset: " + _bitBuffer.BitOffset + "\nExpected: " + _bitCount + " (+" + bitOffset + ")\nBytes Used: " + (_bitBuffer.BytesUsed) + "\nExpected: " + (_bitBuffer.Length - _bitBuffer.Offset) + " (+" + byteOffset + ")"); } if (_TestBit(Bits.Bit1DBitCountEof)) // no reading is done in here { // todo: do check that we're at the EoF bit count etc } }
public CharacterGameMode(UnitObject unitObject, FileManager fileManager) : base(unitObject, fileManager) { }