public static SavedD20Action Load(BinaryReader reader) { var result = new SavedD20Action(); result.Type = (D20ActionType)reader.ReadInt32(); // TODO: Think about action type result.Data = reader.ReadInt32(); result.Flags = (D20CAF)reader.ReadInt32(); reader.ReadInt32(); // Padding reader.ReadInt64(); // Performer handle is transient reader.ReadInt64(); // Target handle is transient result.TargetLocation = reader.ReadLocationAndOffsets(); result.DistanceTraveled = reader.ReadSingle(); result.RadialMenuArg = reader.ReadInt32(); result.RollHistoryId0 = reader.ReadInt32(); result.RollHistoryId1 = reader.ReadInt32(); result.RollHistoryId2 = reader.ReadInt32(); result.SpellData = ReadSpellData(reader); result.SpellId = reader.ReadInt32(); result.AnimActionId = reader.ReadInt32(); reader.ReadInt32(); // Path pointer is transient // ToEE saves the actual object id's after the struct it just dumped (which contains transient data) result.Performer = reader.ReadObjectId(); result.Target = reader.ReadObjectId(); return(result); }
public static SavedHotkeys Load(BinaryReader reader) { var hotkeys = new SavedHotkeys(); for (var keyIndex = reader.ReadInt32(); keyIndex != -1; keyIndex = reader.ReadInt32()) { var hotkey = new SavedHotkey(); // Originally it just read the radial menu entry, but that contains so much // stale data it's not even funny. // The hotkey system will search the entire radial menu and compare each entry // against the following fields found in the hotkey system's copied radial menu entry: // - D20 action type // - D20 action data // - D20 spell data, spell enum original // - The upper 16 bit of the metamagic data // - Text Hash for certain action types reader.ReadInt32(); // Stale text pointer reader.ReadInt32(); // Stale text2 pointer hotkey.TextHash = reader.ReadInt32(); // Text elfhash reader.ReadInt32(); // Padding reader.ReadInt32(); // Radial menu entry type reader.ReadInt32(); // min arg reader.ReadInt32(); // max arg reader.ReadInt32(); // Stale actual arg pointer var hotkeyActionType = reader.ReadInt32(); hotkey.ActionData = reader.ReadInt32(); reader.ReadInt32(); // Action CAF hotkey.SpellData = SavedD20Action.ReadSpellData(reader); reader.ReadInt32(); // Dispatcher key reader.ReadInt32(); // Callback pointer reader.ReadInt32(); // Flags reader.ReadInt32(); // Help text hash reader.ReadInt32(); // Spell Id hotkey.Text = reader.ReadFixedString(128); if (keyIndex >= AssignableKeys.Length) { throw new CorruptSaveException($"Hotkey table contains key which is outside range: {keyIndex}"); } hotkey.Key = AssignableKeys[keyIndex]; if (hotkeyActionType == -2) { continue; // Unassigned } hotkey.ActionType = (D20ActionType)hotkeyActionType; if (!hotkeys.Hotkeys.TryAdd(hotkey.Key, hotkey)) { throw new CorruptSaveException($"Duplicate assignment to key {hotkey.Key}"); } } return(hotkeys); }
public void Save(BinaryWriter writer) { foreach (var(key, hotkey) in Hotkeys) { var keyIndex = Array.IndexOf(AssignableKeys, key); if (keyIndex == -1) { Logger.Error("Cannot save hotkey assigned to {0} because the save format doesn't support it.", key); } // Originally it just read the radial menu entry, but that contains so much // stale data it's not even funny. // The hotkey system will search the entire radial menu and compare each entry // against the following fields found in the hotkey system's copied radial menu entry: // - D20 action type // - D20 action data // - D20 spell data, spell enum original // - The upper 16 bit of the metamagic data // - Text Hash for certain action types writer.WriteInt32(0); // Stale text pointer writer.WriteInt32(0); // Stale text2 pointer writer.WriteInt32(hotkey.TextHash); // Text elfhash writer.WriteInt32(0); // Padding writer.WriteInt32(0); // Radial menu entry type writer.WriteInt32(0); // min arg writer.WriteInt32(0); // max arg writer.WriteInt32(0); // Stale actual arg pointer writer.WriteInt32((int)hotkey.ActionType); writer.WriteInt32(hotkey.ActionData); writer.WriteInt32(0); // Action CAF SavedD20Action.WriteSpellData(writer, hotkey.SpellData); writer.WriteInt32(0); // Dispatcher key writer.WriteInt32(0); // Callback pointer writer.WriteInt32(0); // Flags writer.WriteInt32(0); // Help text hash writer.WriteInt32(0); // Spell Id writer.WriteFixedString(128, hotkey.Text); } writer.WriteInt32(-1); // Terminator }
internal static D20Action LoadAction(SavedD20Action savedAction) { var action = new D20Action { d20ActType = savedAction.Type, data1 = savedAction.Data, d20Caf = savedAction.Flags, destLoc = savedAction.TargetLocation, distTraversed = savedAction.DistanceTraveled, radialMenuActualArg = savedAction.RadialMenuArg, rollHistId0 = savedAction.RollHistoryId0, rollHistId1 = savedAction.RollHistoryId1, rollHistId2 = savedAction.RollHistoryId2, d20SpellData = savedAction.SpellData, spellId = savedAction.SpellId, animID = savedAction.AnimActionId }; if (!savedAction.Performer.IsNull) { action.d20APerformer = GameSystems.Object.GetObject(savedAction.Performer); if (action.d20APerformer == null) { throw new CorruptSaveException($"Unable to restore action performer: {savedAction.Performer}"); } } if (!savedAction.Target.IsNull) { action.d20ATarget = GameSystems.Object.GetObject(savedAction.Target); if (action.d20ATarget == null) { throw new CorruptSaveException($"Unable to restore action target: {savedAction.Target}"); } } return(action); }