public static T PerformBasicOperation <T>(PARAM.Cell c, string op, double opparam) where T : struct, IFormattable { try { dynamic val = c.Value; dynamic opp = opparam; if (op.Equals("=")) { return((T)(opp)); } else if (op.Equals("+")) { return((T)(val + opp)); } else if (op.Equals("-")) { return((T)(val - opp)); } else if (op.Equals("*")) { return((T)(val * opp)); } else if (op.Equals("/")) { return((T)(val / opp)); } } catch { // Operation error } return(default(T)); }
public static List <PARAM.Row> GetMatchingParamRowsByPropVal(PARAM param, string rowfield, string rowvalexp, bool lenient, bool failureAllOrNone) { List <PARAM.Row> rlist = new List <PARAM.Row>(); try { Regex rx = lenient ? new Regex(rowvalexp.ToLower()) : new Regex($@"^{rowvalexp}$"); foreach (PARAM.Row row in param.Rows) { PARAM.Cell c = row[rowfield.Replace(@"\s", " ")]; if (c == null) { continue; } string term = c.Value.ToString(); if (c != null && rx.Match(term).Success) { rlist.Add(row); } } return(rlist); } catch { return(failureAllOrNone ? param.Rows : rlist); } }
private void dgvCells_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e) { PARAM.Cell cell = (PARAM.Cell)dgvCells.Rows[e.RowIndex].DataBoundItem; if (e.ColumnIndex == 1) { if (cell.Type == CellType.x8) { e.Value = $"0x{e.Value:X2}"; } if (cell.Type == CellType.x16) { e.Value = $"0x{e.Value:X4}"; } if (cell.Type == CellType.x32) { e.Value = $"0x{e.Value:X8}"; } } }
private void dgvCells_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e) { PARAM.Cell cell = (PARAM.Cell)dgvCells.Rows[e.RowIndex].DataBoundItem; if (e.ColumnIndex == 1) { var type = cell.Def.DisplayType; if (type == DefType.u8) { e.Value = $"0x{e.Value:X2}"; } if (type == DefType.u16) { e.Value = $"0x{e.Value:X4}"; } if (type == DefType.u32) { e.Value = $"0x{e.Value:X8}"; } } }
public static List <PARAM.Row> GetMatchingParamRowsByPropRef(PARAM param, string rowfield, string namerx, bool lenient, bool failureAllOrNone) { List <PARAM.Row> rlist = new List <PARAM.Row>(); try { Regex rownamerx = lenient ? new Regex(namerx.ToLower()) : new Regex($@"^{namerx}$"); foreach (PARAM.Row row in param.Rows) { PARAM.Cell c = row[rowfield.Replace(@"\s", " ")]; if (c == null) { continue; } int val = (int)c.Value; foreach (string rt in FieldMetaData.Get(c.Def).RefTypes) { if (!ParamBank.Params.ContainsKey(rt)) { continue; } PARAM.Row r = ParamBank.Params[rt][val]; if (r == null) { continue; } string nameToMatch = r.Name == null ? "" : r.Name; if (r != null && rownamerx.Match(lenient ? nameToMatch.ToLower() : nameToMatch).Success) { rlist.Add(row); break; } } } return(rlist); } catch { return(failureAllOrNone ? param.Rows : rlist); } }
public static List <PARAM.Row> GetMatchingParamRowsByPropVal(PARAM param, string rowfield, string rowvalexp, bool lenient, bool failureAllOrNone) { List <PARAM.Row> rlist = new List <PARAM.Row>(); try { Regex rx = new Regex(rowvalexp); foreach (PARAM.Row row in param.Rows) { PARAM.Cell c = row[rowfield]; string term = lenient ? $@".*{c.Value.ToString()}.*" : c.Value.ToString(); if (c != null && rx.Match(term).Success) { rlist.Add(row); } } return(rlist); } catch { return(failureAllOrNone ? param.Rows : rlist); } }
private SortedDictionary <int, List <EntityId> > FindItemLots(GameData game) { PARAM itemLots = game.Param("ItemLotParam"); PARAM npcs = game.Param("NpcParam"); SortedDictionary <int, List <EntityId> > usedItemLots = new SortedDictionary <int, List <EntityId> >(); // TODO: Merge in Sekiro map scraper, which is a fair bit more sophisticated. Dictionary <EntityId, EntityId> objects = new Dictionary <EntityId, EntityId>(); Dictionary <int, List <EntityId> > usedNpcs = new Dictionary <int, List <EntityId> >(); Dictionary <int, List <EntityId> > usedEntities = new Dictionary <int, List <EntityId> >(); foreach (KeyValuePair <string, MSB3> entry in game.Maps) { string location = game.Locations[entry.Key]; foreach (MSB3.Part.Object part in entry.Value.Parts.Objects) { EntityId id = new EntityId(location, part.Name, part.EventEntityID); objects[id] = id; if (part.EventEntityID > 0) { AddMulti(usedEntities, part.EventEntityID, id); } } foreach (MSB3.Part.Enemy enemy in entry.Value.Parts.Enemies) { EntityId id = new EntityId(location, enemy.Name, enemy.EventEntityID, enemy.NPCParamID, enemy.CharaInitID); objects[id] = id; if (enemy.NPCParamID > 0) { AddMulti(usedNpcs, enemy.NPCParamID, id); } if (enemy.EventEntityID > 0) { AddMulti(usedEntities, enemy.EventEntityID, id); } } } foreach (KeyValuePair <string, MSB3> entry in game.Maps) { string location = game.Locations[entry.Key]; foreach (MSB3.Event.Treasure treasure in entry.Value.Events.Treasures) { if (treasure.PartName2 != null) { EntityId id = new EntityId(location, treasure.PartName2); if (!objects.ContainsKey(id)) { if (logUnused) { Console.WriteLine($"Missing entity for treasure {treasure.Name} with entity {treasure.PartName2} and lot {treasure.ItemLot1}"); } continue; } AddMulti(usedItemLots, treasure.ItemLot1, objects[id]); } } } foreach (PARAM.Row row in npcs.Rows) { int npcID = (int)row.ID; PARAM.Cell cell = row["ItemLotId1"]; if (cell == null || (int)cell.Value == -1) { continue; } int itemLot = (int)cell.Value; if (itemLots[itemLot] == null) { if (logUnused) { Console.WriteLine($"Invalid NPC lot item for {npcID} with lot {itemLot}"); } continue; } if (!usedNpcs.ContainsKey(npcID)) { if (logUnused) { Console.WriteLine($"Unused NPC: {npcID}"); } continue; } AddMulti(usedItemLots, itemLot, usedNpcs[npcID]); } foreach (KeyValuePair <int, int> entry in entityItemLots) { int entityId = entry.Key; List <int> itemLot = new List <int> { entry.Value }; if (additionalEntityItemLots.ContainsKey(entityId)) { itemLot.AddRange(additionalEntityItemLots[entityId]); } if (!usedEntities.ContainsKey(entityId)) { Warn($"Missing NPC {entityId} with item lot {String.Join(", ", itemLot)}"); continue; } List <EntityId> id = usedEntities[entityId]; foreach (int lot in itemLot) { if (logUnused && (int)itemLots[lot]["getItemFlagId"].Value == -1 && id[0].GetModelID() != 2150) { Warn($"Eventless entity drop, not crystal lizard, for {String.Join(", ", id)} item lot {lot}"); } AddMulti(usedItemLots, lot, id); } } foreach (int itemLot in Enumerable.Concat(talkLots, crowLots)) { if ((int)itemLots[itemLot]["getItemFlagId"].Value == -1) { Warn($"No event id attached to talk event {itemLot}"); } AddMulti(usedItemLots, itemLot, new EntityId("", "from talk")); } if (logUnused) { int lastLot = 0; foreach (PARAM.Row lot in itemLots.Rows) { int itemLot = (int)lot.ID; if (itemLot == lastLot + 1) { // Don't require groups of item lots to be connected, only the base lot lastLot = itemLot; continue; } if (!usedItemLots.ContainsKey(itemLot)) { Console.WriteLine($"Unconnected item lot {itemLot}: {game.LotName(itemLot)}"); } lastLot = itemLot; } } return(usedItemLots); }
public static MassEditResult PerformSingleMassEdit(string csvString, ActionManager actionManager, string param, string field, bool useSpace) { try { PARAM p = ParamBank.Params[param]; if (p == null) { return(new MassEditResult(MassEditResultType.PARSEERROR, "No Param selected")); } string[] csvLines = csvString.Split('\n'); int changeCount = 0; List <EditorAction> actions = new List <EditorAction>(); foreach (string csvLine in csvLines) { if (csvLine.Trim().Equals("")) { continue; } string[] csvs = csvLine.Split(useSpace ? ' ' : ',', 2, StringSplitOptions.RemoveEmptyEntries); if (csvs.Length != 2) { return(new MassEditResult(MassEditResultType.PARSEERROR, "CSV has wrong number of values")); } int id = int.Parse(csvs[0]); string value = csvs[1]; PARAM.Row row = p[id]; if (row == null) { return(new MassEditResult(MassEditResultType.OPERATIONERROR, $@"Could not locate row {id}")); } if (field.Equals("Name")) { if (row.Name == null || !row.Name.Equals(value)) { actions.Add(new PropertiesChangedAction(row.GetType().GetProperty("Name"), -1, row, value)); } } else { PARAM.Cell cell = row[field]; if (cell == null) { return(new MassEditResult(MassEditResultType.OPERATIONERROR, $@"Could not locate field {field}")); } // Array types are unhandled if (cell.Value.GetType().IsArray) { continue; } object newval = PerformOperation(cell, "=", value); if (newval == null) { return(new MassEditResult(MassEditResultType.OPERATIONERROR, $@"Could not assign {value} to field {cell.Def.InternalName}")); } if (!cell.Value.Equals(newval)) { actions.Add(new PropertiesChangedAction(cell.GetType().GetProperty("Value"), -1, cell, newval)); } } } changeCount = actions.Count; if (changeCount != 0) { actionManager.ExecuteAction(new CompoundAction(actions)); } return(new MassEditResult(MassEditResultType.SUCCESS, $@"{changeCount} rows affected")); } catch { return(new MassEditResult(MassEditResultType.PARSEERROR, "Unable to parse CSV into correct data types")); } }
public static object PerformOperation(PARAM.Cell cell, string op, string opparam) { try { if (op.Equals("ref")) { if (cell.Value.GetType() == typeof(int)) { foreach (string reftype in FieldMetaData.Get(cell.Def).RefTypes) { PARAM p = ParamBank.Params[reftype]; if (p == null) { continue; } foreach (PARAM.Row r in p.Rows) { if (r.Name == null) { continue; } if (r.Name.Equals(opparam)) { return((int)r.ID); } } } } } if (op.Equals("=")) { if (cell.Value.GetType() == typeof(bool)) { return(bool.Parse(opparam)); } else if (cell.Value.GetType() == typeof(string)) { return(opparam); } } if (cell.Value.GetType() == typeof(long)) { return(PerformBasicOperation <long>(cell, op, double.Parse(opparam))); } if (cell.Value.GetType() == typeof(ulong)) { return(PerformBasicOperation <ulong>(cell, op, double.Parse(opparam))); } else if (cell.Value.GetType() == typeof(int)) { return(PerformBasicOperation <int>(cell, op, double.Parse(opparam))); } else if (cell.Value.GetType() == typeof(uint)) { return(PerformBasicOperation <uint>(cell, op, double.Parse(opparam))); } else if (cell.Value.GetType() == typeof(short)) { return(PerformBasicOperation <short>(cell, op, double.Parse(opparam))); } else if (cell.Value.GetType() == typeof(ushort)) { return(PerformBasicOperation <ushort>(cell, op, double.Parse(opparam))); } else if (cell.Value.GetType() == typeof(sbyte)) { return(PerformBasicOperation <sbyte>(cell, op, double.Parse(opparam))); } else if (cell.Value.GetType() == typeof(byte)) { return(PerformBasicOperation <byte>(cell, op, double.Parse(opparam))); } else if (cell.Value.GetType() == typeof(float)) { return(PerformBasicOperation <float>(cell, op, double.Parse(opparam))); } else if (cell.Value.GetType() == typeof(double)) { return(PerformBasicOperation <double>(cell, op, double.Parse(opparam))); } } catch { } return(null); }
private void PropEditorPropRow(object oldval, ref int id, string internalName, FieldMetaData cellMeta, Type propType, PropertyInfo proprow, PARAM.Cell nullableCell, PARAM.Row nullableRow) { List <string> RefTypes = cellMeta == null ? null : cellMeta.RefTypes; string VirtualRef = cellMeta == null ? null : cellMeta.VirtualRef; ParamEnum Enum = cellMeta == null ? null : cellMeta.EnumType; string Wiki = cellMeta == null ? null : cellMeta.Wiki; bool IsBool = cellMeta == null ? false : cellMeta.IsBool; object newval = null; ImGui.PushID(id); ImGui.AlignTextToFramePadding(); PropertyRowName(ref internalName, cellMeta); PropertyRowNameContextMenu(internalName, cellMeta); if (Wiki != null) { if (UIHints.AddImGuiHintButton(internalName, ref Wiki)) { cellMeta.Wiki = Wiki; } } if (ParamEditorScreen.HideReferenceRowsPreference == false && RefTypes != null) { ImGui.TextColored(new Vector4(1.0f, 1.0f, 0.0f, 1.0f), @$ " <{String.Join(',', RefTypes)}>"); } if (ParamEditorScreen.HideEnumsPreference == false && Enum != null) { ImGui.TextColored(new Vector4(1.0f, 1.0f, 0.0f, 1.0f), @$ " {Enum.name}"); } //PropertyRowMetaDefContextMenu(); ImGui.NextColumn(); ImGui.SetNextItemWidth(-1); bool changed = false; bool matchDefault = nullableCell != null && nullableCell.Def.Default.Equals(oldval); if (matchDefault) { ImGui.PushStyleColor(ImGuiCol.Text, new Vector4(0.75f, 0.75f, 0.75f, 1.0f)); } else if ((ParamEditorScreen.HideReferenceRowsPreference == false && RefTypes != null) || (ParamEditorScreen.HideEnumsPreference == false && Enum != null) || VirtualRef != null) { ImGui.PushStyleColor(ImGuiCol.Text, new Vector4(1.0f, 0.5f, 1.0f, 1.0f)); } changed = PropertyRow(propType, oldval, out newval, IsBool); bool committed = ImGui.IsItemDeactivatedAfterEdit(); if ((ParamEditorScreen.HideReferenceRowsPreference == false && RefTypes != null) || (ParamEditorScreen.HideEnumsPreference == false && Enum != null) || VirtualRef != null || matchDefault) { ImGui.PopStyleColor(); } PropertyRowValueContextMenu(internalName, VirtualRef, oldval); if (ParamEditorScreen.HideReferenceRowsPreference == false && RefTypes != null) { PropertyRowRefs(RefTypes, oldval); } if (ParamEditorScreen.HideEnumsPreference == false && Enum != null) { ImGui.TextColored(new Vector4(1.0f, 0.5f, 0.5f, 1.0f), Enum.values.GetValueOrDefault(oldval.ToString(), "Not Enumerated")); } if ((ParamEditorScreen.HideReferenceRowsPreference == false || ParamEditorScreen.HideEnumsPreference == false) && PropertyRowMetaValueContextMenu(oldval, ref newval, RefTypes, Enum)) { changed = true; committed = true; } UpdateProperty(proprow, nullableCell != null ? (object)nullableCell : nullableRow, newval, changed, committed); ImGui.NextColumn(); ImGui.PopID(); id++; }
private void PropEditorPropCellRow(PARAM.Cell cell, ref int id) { PropEditorPropRow(cell.Value, ref id, cell.Def.InternalName, FieldMetaData.Get(cell.Def), cell.Value.GetType(), cell.GetType().GetProperty("Value"), cell, null); }
private ItemLocs FindItemLocs(GameData game) { PARAM itemLots = game.Param("ItemLotParam"); PARAM npcs = game.Param("NpcParam"); ItemLocs ret = new ItemLocs { usedItemLots = new SortedDictionary <int, List <EntityId> >(), usedBaseShops = new SortedDictionary <int, List <EntityId> >(), baseLotsToCreate = new Dictionary <int, int>(), // TODO: See if we can have a reasaonable processing step newEntityLots = new Dictionary <int, int>(), }; Dictionary <EntityId, EntityId> objects = new Dictionary <EntityId, EntityId>(); Dictionary <int, List <EntityId> > usedNpcs = new Dictionary <int, List <EntityId> >(); Dictionary <int, List <EntityId> > usedEntities = new Dictionary <int, List <EntityId> >(); Dictionary <int, List <EntityId> > usedEsds = new Dictionary <int, List <EntityId> >(); // Map from item lot to ESD id, hackily extracted from ESD. Dictionary <int, HashSet <int> > talkItemLocations = new Dictionary <int, HashSet <int> >(); // This is a bit intensive. Ideally just dump this somewhere else HashSet <int> debugEsd = new HashSet <int>(); IEnumerable <ESD.Condition> GetCommands(List <ESD.Condition> condList) => Enumerable.Concat(condList, condList.SelectMany(cond => GetCommands(cond.Subconditions))); foreach (KeyValuePair <string, Dictionary <string, ESD> > entry in game.Talk) { string location = game.Locations.ContainsKey(entry.Key) ? game.Locations[entry.Key] : ""; // 62210 foreach (KeyValuePair <string, ESD> esdEntry in entry.Value) { ESD esd = esdEntry.Value; int esdId = int.Parse(esdEntry.Key.Substring(1)); foreach ((int, int, ESD.State)stateDesc in esd.StateGroups.SelectMany(stateGroup => stateGroup.Value.Select(state => (stateGroup.Key, state.Key, state.Value)))) { (int groupId, int id, ESD.State state) = stateDesc; foreach (ESD.CommandCall cmd in new[] { state.EntryCommands, state.WhileCommands, state.ExitCommands, GetCommands(state.Conditions).SelectMany(c => c.PassCommands) }.SelectMany(c => c)) { foreach (byte[] arg in cmd.Arguments) { if (arg.Length == 6 && arg[0] == 0x82 && arg[5] == 0xA1) { int opt = BitConverter.ToInt32(arg, 1); if (opt >= 60000 && opt <= 69900 && itemLots[opt] != null) { AddMulti(talkItemLocations, opt, esdId); } } } } } } } bool logEntities = false; foreach (KeyValuePair <string, MSBS> entry in game.Smaps) { string location = game.Locations[entry.Key]; MSBS msb = entry.Value; Dictionary <string, int> partEsds = new Dictionary <string, int>(); List <MSBS.Part.Enemy> enemies = msb.Parts.Enemies; // TODO: Update SoulsFormat and migrate to new names foreach (MSBS.Event.Talk ev in entry.Value.Events.Talks) { for (int i = 0; i < 2; i++) { string part = ev.EnemyNames[i]; int esdId = ev.TalkIDs[i]; if (esdId < 0 || part == null) { continue; } partEsds[part] = esdId; } } foreach (MSBS.Entry obj in entry.Value.Parts.GetEntries()) { MSBS.Part part = obj as MSBS.Part; if (part == null) { continue; } EntityId id; int esdId = 0; List <int> groupIDs = part.EntityGroupIDs.Where(groupID => groupID > 0).ToList(); if (part is MSBS.Part.Enemy enemy) { esdId = partEsds.ContainsKey(enemy.Name) ? partEsds[enemy.Name] : -1; id = new EntityId(location, enemy.Name, enemy.EntityID, enemy.NPCParamID, enemy.CharaInitID, groupIDs); } else if (part is MSBS.Part.Object || logEntities) { id = new EntityId(location, part.Name, part.EntityID, GroupIds: groupIDs); } else { continue; } objects[id] = id; if (id.EventEntityID > 0) { AddMulti(usedEntities, id.EventEntityID, id); } foreach (int groupID in groupIDs) { AddMulti(usedEntities, groupID, id); } if (id.NPCParamID > 0) { AddMulti(usedNpcs, id.NPCParamID, id); } if (esdId > 0) { if (debugEsd.Contains(esdId)) { Console.WriteLine($"ESD {esdId} belongs to {game.EntityName(id, true)} in {location}, entity id {id.EventEntityID}"); } AddMulti(usedEsds, esdId, id); } } } if (logEntities) { foreach (KeyValuePair <int, List <EntityId> > entry in usedEntities.OrderBy(e => e.Key)) { Console.WriteLine($"{entry.Key}: {string.Join(", ", entry.Value.Select(e => $"{game.EntityName(e, true)} in {e.MapName}"))}"); } } List <EntityId> unusedEsd = new List <EntityId> { new EntityId("", "Unknown Dialogue") }; foreach (KeyValuePair <int, HashSet <int> > entry in talkItemLocations) { List <EntityId> talkIds; if (addUnused) { talkIds = entry.Value.SelectMany(esd => usedEsds.ContainsKey(esd) ? usedEsds[esd] : unusedEsd).ToList(); } else { talkIds = entry.Value.Where(esd => usedEsds.ContainsKey(esd)).SelectMany(esd => usedEsds[esd]).ToList(); if (talkIds.Count == 0) { continue; } } AddMulti(ret.usedItemLots, entry.Key, talkIds); } foreach (KeyValuePair <int, int> entry in shopEsds) { if (!usedEsds.ContainsKey(entry.Value) && !addUnused) { continue; } AddMulti(ret.usedBaseShops, entry.Key, usedEsds.ContainsKey(entry.Value) ? usedEsds[entry.Value] : unusedEsd); } foreach (KeyValuePair <string, MSBS> entry in game.Smaps) { string location = game.Locations[entry.Key]; foreach (MSBS.Event.Treasure treasure in entry.Value.Events.Treasures) { if (treasure.TreasurePartName != null) { EntityId id = new EntityId(location, treasure.TreasurePartName); if (!objects.ContainsKey(id)) { if (logUnused) { Console.WriteLine($"Missing entity for treasure {treasure.Name} with entity {treasure.TreasurePartName} and lot {treasure.ItemLotID}"); } continue; } AddMulti(ret.usedItemLots, treasure.ItemLotID, objects[id]); } } } foreach (PARAM.Row row in npcs.Rows) { int npcID = (int)row.ID; PARAM.Cell cell = row["ItemLotId1"]; if (cell == null || (int)cell.Value == -1) { continue; } int itemLot = (int)cell.Value; if (itemLots[itemLot] == null) { if (logUnused) { Console.WriteLine($"Invalid NPC lot item for {npcID} with lot {itemLot}"); } continue; } if (!usedNpcs.ContainsKey(npcID)) { if (logUnused) { Console.WriteLine($"Unused NPC: {npcID}"); } if (addUnused) { AddMulti(ret.usedItemLots, itemLot, new EntityId("", "Unused NPC")); } continue; } AddMulti(ret.usedItemLots, itemLot, usedNpcs[npcID]); } foreach (KeyValuePair <int, int> entry in entityItemLots) { int entityId = entry.Key; List <int> itemLot = new List <int> { entry.Value }; if (additionalEntityItemLots.ContainsKey(entityId)) { itemLot.AddRange(additionalEntityItemLots[entityId]); } List <EntityId> id; if (usedEntities.ContainsKey(entityId)) { id = usedEntities[entityId]; } else { Console.WriteLine($"XX Missing entity {entityId} with item lot {String.Join(", ", itemLot)}"); id = new List <EntityId> { new EntityId("", "from entity") }; } foreach (int lot in itemLot) { if (logUnused && (int)itemLots[lot]["getItemFlagId"].Value == -1 && id[0].GetModelID() != 2150) { Console.WriteLine($"Eventless entity drop, not crystal lizard, for {String.Join(", ", id)} item lot {lot}"); } AddMulti(ret.usedItemLots, lot, id); } } Dictionary <int, int> syntheticLotBase = new Dictionary <int, int>(); foreach (KeyValuePair <int, int> entry in treasureCarpDrops) { int entityId = entry.Key; int baseLot = entry.Value; List <EntityId> id; if (usedEntities.ContainsKey(entityId)) { id = usedEntities[entityId]; } else { Console.WriteLine($"XX Missing entity {entityId} with item lot {baseLot}"); id = new List <EntityId> { new EntityId("", "from entity") }; } if (syntheticLotBase.ContainsKey(baseLot)) { syntheticLotBase[baseLot] += 5; } else { syntheticLotBase[baseLot] = baseLot; } int itemLot = syntheticLotBase[baseLot]; ret.baseLotsToCreate[itemLot] = baseLot; // TODO: See if this info can be extracted anywhere else ret.newEntityLots[entityId] = itemLot; AddMulti(ret.usedItemLots, itemLot, id); } foreach (KeyValuePair <int, string> entry in scriptLots) { int itemLot = entry.Key; if ((int)itemLots[itemLot]["getItemFlagId"].Value == -1) { // TODO: Make sure there are all classified... // Console.WriteLine($"XX No event id attached to script event {itemLot}"); } AddMulti(ret.usedItemLots, itemLot, new EntityId(entry.Value, "Scripted")); } foreach (int itemLot in talkLots) { if ((int)itemLots[itemLot]["getItemFlagId"].Value == -1) { Console.WriteLine($"XX No event id attached to talk event {itemLot}"); } AddMulti(ret.usedItemLots, itemLot, new EntityId("", "from talk")); } int lastLot = 0; bool lastConnected = false; foreach (PARAM.Row lot in itemLots.Rows) { int itemLot = (int)lot.ID; bool connected = (byte)lot["LotItemNum1"].Value == 1; if (itemLot == lastLot + 1) { // Don't require groups of item lots to be connected, only the base lot } else if (connected && lastConnected && (itemLot - lastLot) % 10 == 0 && (itemLot - lastLot) <= 40) { // This is also fine.... aaaa. Bell Demon drops. } else { if (!ret.usedItemLots.ContainsKey(itemLot)) { if (logUnused) { Console.WriteLine($"Unconnected item lot {itemLot}: {game.LotName(itemLot)}"); } if (addUnused) { AddMulti(ret.usedItemLots, itemLot, new EntityId("", "unknown")); } } } lastLot = itemLot; lastConnected = connected; } return(ret); }
private static int WriteMemoryCell(PARAM.Cell cell, IntPtr CellDataPtr, ref int bitFieldPos, ref BitArray bits, SoulsMemoryHandler memoryHandler) { PARAMDEF.DefType displayType = cell.Def.DisplayType; // If this can be simplified, that would be ideal. Currently we have to reconcile DefType, a numerical size in bits, and the Type used for the bitField array if (cell.Def.BitSize != -1) { if (displayType == SoulsFormats.PARAMDEF.DefType.u8) { if (bitFieldPos == 0) { bits = new BitArray(8); } bits.Set(bitFieldPos, Convert.ToBoolean(cell.Value)); bitFieldPos++; if (bitFieldPos == 8) { byte valueRead = 0; memoryHandler.ReadProcessMemory(CellDataPtr, ref valueRead); byte[] bitField = new byte[1]; bits.CopyTo(bitField, 0); bitFieldPos = 0; byte bitbuffer = bitField[0]; if (valueRead != bitbuffer) { memoryHandler.WriteProcessMemory(CellDataPtr, ref bitbuffer); } return(sizeof(byte)); } return(0); } else if (displayType == SoulsFormats.PARAMDEF.DefType.u16) { if (bitFieldPos == 0) { bits = new BitArray(16); } bits.Set(bitFieldPos, Convert.ToBoolean(cell.Value)); bitFieldPos++; if (bitFieldPos == 16) { ushort valueRead = 0; memoryHandler.ReadProcessMemory(CellDataPtr, ref valueRead); ushort[] bitField = new ushort[1]; bits.CopyTo(bitField, 0); bitFieldPos = 0; ushort bitbuffer = bitField[0]; if (valueRead != bitbuffer) { memoryHandler.WriteProcessMemory(CellDataPtr, ref bitbuffer); } return(sizeof(UInt16)); } return(0); } else if (displayType == SoulsFormats.PARAMDEF.DefType.u32) { if (bitFieldPos == 0) { bits = new BitArray(32); } bits.Set(bitFieldPos, Convert.ToBoolean(cell.Value)); bitFieldPos++; if (bitFieldPos == 32) { uint valueRead = 0; memoryHandler.ReadProcessMemory(CellDataPtr, ref valueRead); uint[] bitField = new uint[1]; bits.CopyTo(bitField, 0); bitFieldPos = 0; uint bitbuffer = bitField[0]; if (valueRead != bitbuffer) { memoryHandler.WriteProcessMemory(CellDataPtr, ref bitbuffer); } return(sizeof(UInt32)); } return(0); } } if (displayType == SoulsFormats.PARAMDEF.DefType.f32) { float valueRead = 0f; memoryHandler.ReadProcessMemory(CellDataPtr, ref valueRead); float value = Convert.ToSingle(cell.Value); if (valueRead != value) { memoryHandler.WriteProcessMemory(CellDataPtr, ref value); } return(sizeof(float)); } else if (displayType == SoulsFormats.PARAMDEF.DefType.s32) { int valueRead = 0; memoryHandler.ReadProcessMemory(CellDataPtr, ref valueRead); int value = Convert.ToInt32(cell.Value); if (valueRead != value) { memoryHandler.WriteProcessMemory(CellDataPtr, ref value); } return(sizeof(Int32)); } else if (displayType == SoulsFormats.PARAMDEF.DefType.s16) { short valueRead = 0; memoryHandler.ReadProcessMemory(CellDataPtr, ref valueRead); short value = Convert.ToInt16(cell.Value); if (valueRead != value) { memoryHandler.WriteProcessMemory(CellDataPtr, ref value); } return(sizeof(Int16)); } else if (displayType == SoulsFormats.PARAMDEF.DefType.s8) { sbyte valueRead = 0; memoryHandler.ReadProcessMemory(CellDataPtr, ref valueRead); sbyte value = Convert.ToSByte(cell.Value); if (valueRead != value) { memoryHandler.WriteProcessMemory(CellDataPtr, ref value); } return(sizeof(sbyte)); } else if (displayType == SoulsFormats.PARAMDEF.DefType.u32) { uint valueRead = 0; memoryHandler.ReadProcessMemory(CellDataPtr, ref valueRead); uint value = Convert.ToUInt32(cell.Value); if (valueRead != value) { memoryHandler.WriteProcessMemory(CellDataPtr, ref value); } return(sizeof(UInt32)); } else if (displayType == SoulsFormats.PARAMDEF.DefType.u16) { ushort valueRead = 0; memoryHandler.ReadProcessMemory(CellDataPtr, ref valueRead); ushort value = Convert.ToUInt16(cell.Value); if (valueRead != value) { memoryHandler.WriteProcessMemory(CellDataPtr, ref value); } return(sizeof(UInt16)); } else if (displayType == SoulsFormats.PARAMDEF.DefType.u8) { byte valueRead = 0; memoryHandler.ReadProcessMemory(CellDataPtr, ref valueRead); byte value = Convert.ToByte(cell.Value); if (valueRead != value) { memoryHandler.WriteProcessMemory(CellDataPtr, ref value); } return(sizeof(byte)); } else if (displayType == SoulsFormats.PARAMDEF.DefType.dummy8 || displayType == SoulsFormats.PARAMDEF.DefType.fixstr || displayType == SoulsFormats.PARAMDEF.DefType.fixstrW) { return(cell.Def.ArrayLength); } else { throw new Exception("Unexpected Field Type"); } }
private void PropEditorPropCellRow(PARAM.Cell cell, PARAM.Cell vcell, ref int id, Regex propSearchRx) { PropEditorPropRow(cell.Value, vcell == null?null:vcell.Value, ref id, cell.Def.InternalName, FieldMetaData.Get(cell.Def), cell.Value.GetType(), cell.GetType().GetProperty("Value"), cell, null, propSearchRx); }