/// <summary> /// Checks if all classic effects map to an implemented IEntityEffect template. /// </summary> /// <param name="spellRecordData">Classic spell record data.</param> /// <returns>True if all classic effects map to an effect template.</returns> public bool AllEffectsImplemented(SpellRecord.SpellRecordData spellRecordData) { // There are up to 3 effects per spell int foundEffects = 0; for (int i = 0; i < spellRecordData.effects.Length; i++) { // Try to get effect template IEntityEffect effectTemplate = GetEffectTemplateFromClassicEffectRecordData(spellRecordData.effects[i]); if (effectTemplate == null) { continue; } // Otherwise effect is implemented and can be counted foundEffects++; } // Must have at least one effect counted (handles all 3 slots being -1/-1) if (foundEffects == 0) { return(false); } return(true); }
private static bool SetSpellTypes(ref SpellRecord.SpellRecordData spell, BinaryReader reader) { if (reader == null) { return(false); } if (spell.effects == null || spell.effects.Length < 3) { spell.effects = new SpellRecord.EffectRecordData[3]; } SpellRecord.EffectRecordData[] effects = spell.effects; for (int i = 0; i < spell.effects.Length; i++) { effects[i].type = reader.ReadSByte(); if (effects[i].type == 0xFF) { continue; } else { effects[i].subType = reader.ReadSByte(); } } return(effects[0].type > -1 || effects[1].type > -1 || effects[2].type > -1); }
/// <summary> /// Generate EffectBundleSettings from classic SpellRecordData. /// </summary> /// <param name="spellRecordData">Classic spell record data.</param> /// <param name="bundleType">Type of bundle to create.</param> /// <param name="effectBundleSettingsOut">Effect bundle created by conversion.</param> /// <returns>True if successful, otherwise false.</returns> public bool ClassicSpellRecordDataToEffectBundleSettings(SpellRecord.SpellRecordData spellRecordData, BundleTypes bundleType, out EffectBundleSettings effectBundleSettingsOut) { // Spell record data must have effect records if (spellRecordData.effects == null || spellRecordData.effects.Length == 0) { effectBundleSettingsOut = new EffectBundleSettings(); return(false); } // Create bundle effectBundleSettingsOut = new EffectBundleSettings() { Version = EntityEffectBroker.CurrentSpellVersion, BundleType = bundleType, TargetType = ClassicTargetIndexToTargetType(spellRecordData.rangeType), ElementType = ClassicElementIndexToElementType(spellRecordData.element), Name = spellRecordData.spellName, IconIndex = spellRecordData.icon, Icon = new SpellIcon(), StandardSpellIndex = spellRecordData.index, }; effectBundleSettingsOut.Icon.index = effectBundleSettingsOut.IconIndex; // Assign effects List <EffectEntry> foundEffects = new List <EffectEntry>(); for (int i = 0; i < spellRecordData.effects.Length; i++) { // Skip unused effect slots if (spellRecordData.effects[i].type == -1) { continue; } // Get entry from effect EffectEntry entry; if (!ClassicEffectRecordToEffectEntry(spellRecordData.effects[i], out entry)) { continue; } // Assign to valid effects foundEffects.Add(entry); } // Must have assigned at least one valid effect if (foundEffects.Count == 0) { return(false); } // Assign effects to bundle effectBundleSettingsOut.Effects = foundEffects.ToArray(); return(true); }
/// <summary> /// Gets classic spell record data. /// </summary> /// <param name="id">ID of spell.</param> /// <param name="spellOut">Spell record data (if found).</param> /// <returns>True if spell found, otherwise false.</returns> public bool GetClassicSpellRecord(int id, out SpellRecord.SpellRecordData spellOut) { if (classicSpells.ContainsKey(id)) { spellOut = classicSpells[id]; return(true); } spellOut = new SpellRecord.SpellRecordData(); return(false); }
/// <summary> /// Creates a spell record /// </summary> /// <param name="reader"></param> /// <param name="spellRecord"></param> /// <returns></returns> public static bool ReadSpellData(BinaryReader reader, out SpellRecord.SpellRecordData spellRecord) { spellRecord = new SpellRecord.SpellRecordData(); try { if (reader == null || reader.BaseStream == null) { DaggerfallUnity.LogMessage("Spell Chunk Array was null", true); return(false); } else if (reader.BaseStream.Position + SPELLRECORDSIZE > reader.BaseStream.Length) { return(false); } if (!SetSpellTypes(ref spellRecord, reader)) { return(false); } spellRecord.element = reader.ReadByte(); spellRecord.rangeType = reader.ReadByte(); spellRecord.cost = reader.ReadUInt16(); reader.BaseStream.Seek(4, SeekOrigin.Current); if (!SetSpellDurations(ref spellRecord, reader)) { return(false); } if (!SetSpellChances(ref spellRecord, reader)) { return(false); } if (!SetSpellMagnitudes(ref spellRecord, reader)) { return(false); } spellRecord.spellName = DaggerfallConnect.Utility.FileProxy.ReadCStringSkip(reader, 0, 25); //spellRecord.spellName = spellRecord.spellName.TrimEnd(new char[] { '\0' }); spellRecord.icon = reader.ReadByte(); spellRecord.index = reader.ReadByte(); reader.BaseStream.Seek(15, SeekOrigin.Current); } catch (Exception ex) { DaggerfallUnity.LogMessage(ex.Message, true); return(false); } return(true); }
static bool FindSpellByID(int id, List <SpellRecord.SpellRecordData> spells, out SpellRecord.SpellRecordData spellRecordDataOut) { spellRecordDataOut = null; foreach (var record in spells) { if (record.index == id) { spellRecordDataOut = record; return(true); } } return(false); }
/// <summary> /// Parses a SPELLS.STD file. /// </summary> /// <param name="filePath">If null, looks for SPELLS.STD in Arena2 path.</param> /// <returns>List of SpellRecordData structs.</returns> public static List <SpellRecord.SpellRecordData> ReadSpellsFile(string filePath = null) { var managedFile = new DaggerfallConnect.Utility.FileProxy(); if (string.IsNullOrEmpty(filePath)) { filePath = Path.Combine(DaggerfallUnity.Instance.Arena2Path, DEFAULT_FILENAME); } if (!File.Exists(filePath)) { Debug.LogError(string.Format("{0} file not found", DEFAULT_FILENAME)); return(null); } else if (!managedFile.Load(filePath, DaggerfallConnect.FileUsage.UseMemory, true)) { Debug.LogError(string.Format("Failed to load {0} file\n{1}", DEFAULT_FILENAME, managedFile.LastException.InnerException)); return(null); } var spells = new List <SpellRecord.SpellRecordData>(100); var fileReader = managedFile.GetReader(); try { while (fileReader.BaseStream.Position + SPELLRECORDSIZE <= fileReader.BaseStream.Length) { SpellRecord.SpellRecordData spellRecord = new SpellRecord.SpellRecordData(); bool succeded = ReadSpellData(fileReader, out spellRecord); if (succeded) { spells.Add(spellRecord); } else { Debug.LogError(string.Format("Failed to read spell at: {0}", fileReader.BaseStream.Position)); } } } catch (Exception ex) { Debug.LogError(string.Format("error while reading {0} : {1}", filePath, ex.Message)); managedFile.Close(); } managedFile.Close(); return(spells); }
//just setting to 0 for now, need to implement a lookup private static bool SetTextIndices(ref SpellRecord.SpellRecordData spell, BinaryReader reader) { if (reader == null) { return(false); } else if (spell.effects == null) { return(false); } for (int i = 0; i < spell.effects.Length; i++) { spell.effects[i].descriptionTextIndex = 0; spell.effects[i].spellMakerTextIndex = 0; } return(true); }
private static bool SetSpellChances(ref SpellRecord.SpellRecordData spell, BinaryReader reader) { if (reader == null) { return(false); } else if (spell.effects == null || spell.effects.Length < 3) { return(false); } SpellRecord.EffectRecordData[] effects = spell.effects; for (int i = 0; i < effects.Length; i++) { effects[i].chanceBase = reader.ReadByte(); effects[i].chanceMod = reader.ReadByte(); effects[i].chancePerLevel = reader.ReadByte(); } return(true); }
/// <summary> /// Creates a spell record from byte array. /// </summary> /// <param name="chunk">Input spell data; this is an array of bytes with length <see cref="SPELLRECORDSIZE"/>.</param> /// <param name="spellRecord">Resulting spell record data.</param> /// <returns>True if succeeded.</returns> public static bool ReadSpellData(byte[] chunk, out SpellRecord.SpellRecordData spellRecord) { spellRecord = new SpellRecord.SpellRecordData(); bool succeeded = false; try { if (chunk == null || chunk.Length < SPELLRECORDSIZE) { return(succeeded); } MemoryStream stream = new MemoryStream(chunk); BinaryReader reader = new BinaryReader(stream); succeeded = ReadSpellData(reader, out spellRecord); } catch (Exception ex) { Debug.LogError(ex.Message); succeeded = false; } return(succeeded); }
/// <summary> /// Serializes spell record to json /// </summary> /// <param name="spell"></param> /// <returns></returns> public static string SerializeSpell(SpellRecord.SpellRecordData spell) { return(DoSerialize <SpellRecord.SpellRecordData>(spell)); }