/// <summary> /// Updates and resigns the save data, writing any changes back to a stream. /// </summary> /// <exception cref="ArgumentException">Thrown if the stream cannot be written to or does not support seeking</exception> public void Update(Stream stream) { if (!stream.CanWrite || !stream.CanSeek) { throw new ArgumentException("Campaign save output streams must be writable and seekable"); } SaveIO.SaveWriter writer = new SaveIO.SaveWriter(stream); // Update each object Player.ResolvePlayerRefs(); foreach (GameObject obj in _objects) { if (obj != null) { obj.Update(writer); } } _objectChunk.Update(writer); // Update player information Player.Update(writer); // Update each squad foreach (Squad squad in _squads) { if (squad != null) { squad.Update(writer); } } // Update each actor foreach (Actor actor in _actors) { if (actor != null) { actor.Update(writer); } } // Gravity writer.Seek(0x68EBF4, SeekOrigin.Begin); writer.WriteFloat(_gravity); // Target locator ammo writer.Seek(0x915E1A, SeekOrigin.Begin); writer.WriteInt16(_targetLocatorAmmo); // Checkpoint message writer.Seek(0x9DF9E0, SeekOrigin.Begin); writer.WriteUTF16(_checkpointMsg); // Resign the file Resign(stream); }
public void Update(SaveIO.SaveWriter writer, GameObject parent) { if (_relative) { // Find the parent object's position in world space float parentX = parent.X, parentY = parent.Y, parentZ = parent.Z; Reach.GameObject obj = parent.Carrier; while (obj != null) { parentX += obj.X; parentY += obj.Y; parentZ += obj.Z; obj = obj.Carrier; } // Transform the coords to world space and write them writer.WriteFloat(Scale * parent.Scale); writer.WriteFloat(Right.X); writer.WriteFloat(-Right.Y); writer.WriteFloat(Right.Z); writer.WriteFloat(-Forward.X); writer.WriteFloat(Forward.Y); writer.WriteFloat(-Forward.Z); writer.WriteFloat(Up.X); writer.WriteFloat(-Up.Y); writer.WriteFloat(Up.Z); writer.WriteFloat(X + parentX); writer.WriteFloat(Y + parentY); writer.WriteFloat(Z + parentZ); } else { // The coords are already absolute, just write them writer.WriteFloat(Scale); writer.WriteFloat(Right.X); writer.WriteFloat(-Right.Y); writer.WriteFloat(Right.Z); writer.WriteFloat(-Forward.X); writer.WriteFloat(Forward.Y); writer.WriteFloat(-Forward.Z); writer.WriteFloat(Up.X); writer.WriteFloat(-Up.Y); writer.WriteFloat(Up.Z); writer.WriteFloat(X); writer.WriteFloat(Y); writer.WriteFloat(Z); } }
/// <summary> /// Override this to write out any changed properties. /// </summary> /// <param name="writer">The SaveWriter to write to</param> /// <param name="start">The start of the object's data</param> protected virtual void DoUpdate(SaveIO.SaveWriter writer, long start) { // If the object's position has changed, awaken it if (_x != _originalX || _y != _originalY || _z != _originalZ || !_velocity.Equals(_originalVelocity)) { IsAwake = true; } writer.Seek(start + 0x4, SeekOrigin.Begin); writer.WriteInt32(_flags.Data); writer.WriteUInt16(_zone); writer.Seek(2, SeekOrigin.Current); if (_nextCarried != null) { writer.WriteUInt32(_nextCarried.ID); } else { writer.WriteUInt32(0xFFFFFFFF); } if (_firstCarried != null) { writer.WriteUInt32(_firstCarried.ID); } else { writer.WriteUInt32(0xFFFFFFFF); } if (_carrier != null) { writer.WriteUInt32(_carrier.ID); } else { writer.WriteUInt32(0xFFFFFFFF); } writer.WriteSByte(_parentNodeIndex); writer.Seek(start + 0x20, SeekOrigin.Begin); writer.WriteFloat(_x); writer.WriteFloat(_y); writer.WriteFloat(_z); /*writer.WriteFloat(_boundsX1); * writer.WriteFloat(_boundsY1); * writer.WriteFloat(_boundsZ1);*/ writer.Seek(4, SeekOrigin.Current); writer.WriteFloat(_x); writer.WriteFloat(_y); writer.WriteFloat(_z); /*writer.WriteFloat(_boundsX2); * writer.WriteFloat(_boundsY2); * writer.WriteFloat(_boundsZ2);*/ writer.Seek(8, SeekOrigin.Current); writer.WriteFloat(_x); writer.WriteFloat(_y); writer.WriteFloat(_z); writer.WriteFloat(_right.X); writer.WriteFloat(-_right.Y); // hax writer.WriteFloat(_right.Z); writer.WriteFloat(_up.X); writer.WriteFloat(-_up.Y); // hax writer.WriteFloat(_up.Z); writer.Seek(start + 0x68, SeekOrigin.Begin); writer.WriteFloat(_velocity.X); writer.WriteFloat(_velocity.Y); writer.WriteFloat(_velocity.Z); writer.Seek(start + 0x80, SeekOrigin.Begin); // Scale is stored twice?? writer.WriteFloat(_scale); writer.WriteFloat(_scale); writer.Seek(start + 0xDC, SeekOrigin.Begin); writer.WriteInt32(_physicsFlags.Data); writer.Seek(start + 0x13C, SeekOrigin.Begin); writer.WriteInt32(_invincibilityFlags.Data); // Write strength info writer.Seek(start + 0x110, SeekOrigin.Begin); _healthInfo.WriteTo(writer); if (_nodeDataOffset != 0xFFFF) { writer.Seek(start + _nodeDataOffset, SeekOrigin.Begin); foreach (ModelNode node in _nodes) { node.Update(writer, this); } } }