/// <summary> /// Reads link data out of a SaveReader from its current position. /// </summary> /// <param name="reader">The SaveReader to read link data from.</param> public ObjectLinkData(SaveIO.SaveReader reader) { Size = reader.ReadUInt32(); ID = reader.ReadUInt32(); NextLinkOffset = reader.ReadUInt32(); PreviousLinkOffset = reader.ReadUInt32(); }
protected override void DoLoad(SaveIO.SaveReader reader, long start) { base.DoLoad(reader, start); reader.Seek(start + 0x388, SeekOrigin.Begin); _driverObjectId = (ushort)(reader.ReadUInt32() & 0xFFFF); _controllerObjectId = (ushort)(reader.ReadUInt32() & 0xFFFF); }
internal ObjectEntry(Chunk chunk, SaveIO.SaveReader reader, uint datumIndex, ushort flags, long offset) { _chunk = chunk; _id = datumIndex; _flags = new BitVector32((int)flags); _tagGroup = (TagGroup)(reader.ReadUInt16() >> 8); _type = reader.ReadUInt16(); _poolOffset = reader.ReadUInt32(); _memAddress = reader.ReadUInt32(); _offset = offset; }
/// <summary> /// Constructs a new Chunk object, reading header data out of a SaveReader. /// </summary> /// <param name="reader">The SaveReader to read from.</param> public Chunk(SaveIO.SaveReader reader, ChunkOffset offset) { long baseAddress = (long)offset; reader.Seek(baseAddress, SeekOrigin.Begin); // Read header data _name = reader.ReadAscii(32); _entrySize = reader.ReadUInt32(); reader.Seek(baseAddress + 0x28, SeekOrigin.Begin); _entryCount = reader.ReadUInt32(); reader.Seek(baseAddress + 0x34, SeekOrigin.Begin); _firstDeleted = reader.ReadUInt32(); _nextFree = reader.ReadUInt32(); _activeEntries = reader.ReadUInt32(); reader.Seek(baseAddress + 0x50, SeekOrigin.Begin); int entryListSize = reader.ReadInt32() - 0x54; _entryListStart = baseAddress + 0x54; }
public void ReadFrom(SaveIO.SaveReader reader) { long baseOffset = reader.Position; string saveType = reader.ReadAscii(SaveTypeSize); if (saveType != "non compressed save") { throw new ArgumentException("Invalid save header - expected a non-compressed HCEX save"); } if (reader.ReadUInt32() != Magic1) { throw new ArgumentException("Invalid save header - bad magic number 1 (expected 0x92F7E104)"); } _map = reader.ReadAscii(); reader.SeekTo(baseOffset + Magic2Offset); if (reader.ReadUInt32() != Magic2) { throw new ArgumentException("Invalid save header - bad magic number 2 (expected 0xDEADBEEF)"); } }
protected override void DoLoad(SaveIO.SaveReader reader, long start) { base.DoLoad(reader, start); // Vehicle seat? reader.Seek(start + 0x32E, SeekOrigin.Begin); _seatIndex = reader.ReadUInt16(); // Equipment reader.Seek(start + 0x36E, SeekOrigin.Begin); _armorAbilityId = reader.ReadUInt16(); // Grenade counts reader.Seek(start + 0x378, SeekOrigin.Begin); _fragGrenades = reader.ReadSByte(); _plasmaGrenades = reader.ReadSByte(); // Vehicle reader.Seek(start + 0xA00, SeekOrigin.Begin); _currentVehicleId = reader.ReadUInt32(); _controlledVehicleId = reader.ReadUInt32(); }
/// <summary> /// Constructs a new Table and reads the header. /// </summary> /// <param name="reader"> /// The SaveReader to read from. It should be positioned at the start of the table header. /// When the function finishes, it will point to the first entry in the entry list (see the HeaderSize constant). /// </param> public Table(SaveIO.SaveReader reader) { _name = reader.ReadAscii(0x1E); reader.Skip(2); // Index of last entry - 1, not needed _entryCount = reader.ReadUInt16(); _entrySize = reader.ReadUInt16(); reader.Skip(2 + 2 + 4); // 2 unknown uint16's + uint32 magic number _firstDeleted = reader.ReadUInt16(); _nextFree = reader.ReadUInt16(); _activeEntries = reader.ReadUInt16(); _nextSalt = reader.ReadUInt16(); _memAddress = reader.ReadUInt32(); }
public Squad(SaveIO.SaveReader reader, uint datumIndex, long offset) { _dataPosition = offset; _datumIndex = datumIndex; reader.SeekTo(offset + 2); _flags = new BitVector32((int)reader.ReadInt16()); reader.SeekTo(offset + 0xA0); _actorIndex = reader.ReadUInt32(); reader.SeekTo(offset + 0xE7); _team = reader.ReadByte(); }
protected override void DoLoad(SaveIO.SaveReader reader, long start) { base.DoLoad(reader, start); reader.Seek(start + 0xD4, SeekOrigin.Begin); _usageInfo = reader.ReadUInt32(); // Is this value present in other objects as well? reader.Seek(start + 0x1A8, SeekOrigin.Begin); _weaponFlags = reader.ReadUInt32(); // User ID reader.Seek(start + 0x1B6, SeekOrigin.Begin); _userId = reader.ReadUInt16(); reader.Seek(start + 0x1E0, SeekOrigin.Begin); _plasmaUsage = reader.ReadFloat(); // Ammo reader.Seek(start + 0x2C6, SeekOrigin.Begin); _ammo = reader.ReadInt16(); reader.Seek(2, SeekOrigin.Current); _clipAmmo = reader.ReadInt16(); }
public void ReadFrom(SaveIO.SaveReader reader) { // Ignore the CRC32 but read everything else reader.Skip(CRC32Size); _unknown = reader.ReadUInt32(); _cfgSize = reader.ReadInt32(); _dataBlock1Size = reader.ReadInt32(); _dataBlock2Size = reader.ReadInt32(); _saveDataSize = reader.ReadInt32(); if (_saveDataSize == 0) { throw new ArgumentException("The save file is empty. Please get a different save and ensure that you reach a checkpoint first."); } // Skip the CFG CRC32 and read the CFG text reader.Skip(CRC32Size); CFGText = reader.ReadAscii(_cfgSize - CRC32Size); // Parse the CFG data CFGData = new SaveCFG(CFGText); }
/// <summary> /// Reads the object list from a Chunk. /// </summary> /// <param name="reader">The SaveReader to read from.</param> /// <param name="chunk">The "object" chunk to read from.</param> private void ReadObjects(SaveIO.SaveReader reader, Chunk chunk) { if (chunk.EntrySize != 16) { throw new ArgumentException("The file format is invalid: bad object entry size\r\nExpected 0x10 but got 0x" + chunk.EntrySize.ToString("X")); } // Check that the object pool exists // 0x706F6F6C = 'pool' in hex reader.Seek(_objectPoolStart, SeekOrigin.Begin); if (reader.ReadUInt32() != 0x706F6F6C) { throw new ArgumentException("The file format is invalid: the object pool is missing or is at the wrong offset"); } // Process the entries _objectChunk = chunk; chunk.EnumEntries(reader, ProcessObjectEntry); // Resolve any object references inside each object foreach (GameObject obj in _objects) { if (obj != null) { obj.ResolveObjectRefs(_objects); } } // Convert all of the nodes to use relative coordinates // Object references need to be resolved before this occurs foreach (GameObject obj in _objects) { if (obj != null) { obj.Nodes.MakeRelative(obj); } } }
/*public override void PickUp(GameObject obj) * { * base.PickUp(obj); * * WeaponObject weapon = obj as WeaponObject; * if (weapon != null && _weapons.Count < 4) * _weapons.Add(weapon); * }*/ protected override void DoLoad(SaveIO.SaveReader reader, long start) { base.DoLoad(reader, start); reader.Seek(start + 0x1BE, SeekOrigin.Begin); _actorId = reader.ReadUInt16(); reader.Seek(start + 0x1C4, SeekOrigin.Begin); _unitFlags = new BitVector32(reader.ReadInt32()); reader.Seek(start + 0x1C8, SeekOrigin.Begin); _team = reader.ReadByte(); reader.Seek(start + 0x342, SeekOrigin.Begin); _currentWeaponIndex = reader.ReadSByte(); reader.Seek(start + 0x346, SeekOrigin.Begin); _backupWeaponIndex = reader.ReadSByte(); reader.Seek(start + 0x348, SeekOrigin.Begin); for (int i = 0; i < 4; i++) { _weaponId[i] = (ushort)(reader.ReadUInt32() & 0xFFFF); } }
/// <summary> /// Reads a DatumIndex from a SaveReader and returns it. /// </summary> /// <param name="reader">The SaveReader to read from.</param> /// <returns>The DatumIndex that was read.</returns> public static DatumIndex ReadFrom(SaveIO.SaveReader reader) { return(new DatumIndex(reader.ReadUInt32())); }
/// <summary> /// Override this to load any extra properties the object might have. /// </summary> /// <param name="reader">The SaveReader to read from</param> /// <param name="start">The start of the object's data</param> protected virtual void DoLoad(SaveIO.SaveReader reader, long start) { // Link data reader.Seek(start - 16, SeekOrigin.Begin); _linkData = new ObjectLinkData(reader); // Resource ID _mapId = reader.ReadUInt32(); // Flags _flags = new BitVector32(reader.ReadInt32()); // Zone? _zone = (ushort)((reader.ReadUInt32() & 0xFFFF0000) >> 16); // Carry info _nextCarriedId = (ushort)(reader.ReadUInt32() & 0xFFFF); _firstCarriedId = (ushort)(reader.ReadUInt32() & 0xFFFF); _carrierId = (ushort)(reader.ReadUInt32() & 0xFFFF); _parentNodeIndex = reader.ReadSByte(); // Position data reader.Seek(start + 0x20, SeekOrigin.Begin); _boundsX1 = reader.ReadFloat(); _boundsY1 = reader.ReadFloat(); _boundsZ1 = reader.ReadFloat(); reader.Seek(4, SeekOrigin.Current); _boundsX2 = reader.ReadFloat(); _boundsY2 = reader.ReadFloat(); _boundsZ2 = reader.ReadFloat(); reader.Seek(8, SeekOrigin.Current); _x = reader.ReadFloat(); _y = reader.ReadFloat(); _z = reader.ReadFloat(); _originalX = _x; _originalY = _y; _originalZ = _z; // Rotation data _right.X = reader.ReadFloat(); _right.Y = -reader.ReadFloat(); // hax _right.Z = reader.ReadFloat(); _up.X = reader.ReadFloat(); _up.Y = -reader.ReadFloat(); // hax _up.Z = reader.ReadFloat(); // Velocity reader.Seek(start + 0x68, SeekOrigin.Begin); _velocity.X = reader.ReadFloat(); _velocity.Y = reader.ReadFloat(); _velocity.Z = reader.ReadFloat(); _originalVelocity = _velocity; // Calculate the forward vector with a cross product _forward = MathUtil.Vector3.Cross(_up, _right); // Scale reader.Seek(start + 0x80, SeekOrigin.Begin); _scale = reader.ReadFloat(); // Flags reader.Seek(start + 0xDC, SeekOrigin.Begin); _physicsFlags = new BitVector32(reader.ReadInt32()); // Health info reader.Seek(start + 0x110, SeekOrigin.Begin); _healthInfo = new HealthInfo(reader, DefaultNoble6HealthModifier, DefaultNoble6ShieldModifier); // Invincibility data reader.Seek(start + 0x13C, SeekOrigin.Begin); _invincibilityFlags = new BitVector32(reader.ReadInt32()); // Node data reader.Seek(start + 0x17C, SeekOrigin.Begin); ushort _nodeDataSize = reader.ReadUInt16(); _nodeDataOffset = reader.ReadUInt16(); if (_nodeDataOffset != 0xFFFF) { reader.Seek(start + _nodeDataOffset, SeekOrigin.Begin); // Read all of the nodes into a list List <ModelNode> nodes = new List <ModelNode>(); for (ushort i = 0; i < _nodeDataSize; i += ModelNode.DataSize) { nodes.Add(ModelNode.FromSaveReader(reader)); } // Now make a NodeCollection out of them _nodes = new NodeCollection(nodes); } // Previous/next object ID's if (_linkData.PreviousLinkOffset != 0) { reader.Seek(0x76844C + _linkData.PreviousLinkOffset + 6, SeekOrigin.Begin); _previousObjectId = reader.ReadUInt16(); } if (_linkData.NextLinkOffset != 0) { reader.Seek(0x76844C + _linkData.NextLinkOffset + 6, SeekOrigin.Begin); _nextObjectId = reader.ReadUInt16(); } }