public Data() { list.Add(5); list.Add(2); list.Add(1); list.Add(8); refB = refA; }
internal void AssignHandle(IntPtr handle, bool assignUniqueID) { lock (this) { CheckReleased(); Debug.Assert(handle != IntPtr.Zero, "handle is 0"); Handle = handle; _priorWindowProcHandle = User32.GetWindowLong(this, User32.GWL.WNDPROC); Debug.Assert(_priorWindowProcHandle != IntPtr.Zero); Debug.WriteLineIf( WndProcChoice.TraceVerbose, WndProcShouldBeDebuggable ? "Using debuggable wndproc" : "Using normal wndproc"); _windowProc = new User32.WNDPROC(Callback); AddWindowToTable(handle, this); // Set the NativeWindow window procedure delegate and get back the native pointer for it. User32.SetWindowLong(this, User32.GWL.WNDPROC, _windowProc); _windowProcHandle = User32.GetWindowLong(this, User32.GWL.WNDPROC); // This shouldn't be possible. Debug.Assert(_priorWindowProcHandle != _windowProcHandle, "Uh oh! Subclassed ourselves!!!"); if (assignUniqueID && ((User32.WS)PARAM.ToUInt(User32.GetWindowLong(this, User32.GWL.STYLE))).HasFlag(User32.WS.CHILD) && User32.GetWindowLong(this, User32.GWL.ID) == IntPtr.Zero) { User32.SetWindowLong(this, User32.GWL.ID, handle); } if (_suppressedGC) { GC.ReRegisterForFinalize(this); _suppressedGC = false; } OnHandleChange(); } }
protected override void WndProc(ref Message m) { if (_designer is null) { DefWndProc(ref m); return; } if (m.Msg == (int)User32.WM.DESTROY) { _designer.RemoveSubclassedWindow(m.HWnd); } if (m.Msg == (int)User32.WM.PARENTNOTIFY && PARAM.LOWORD(m.WParam) == (short)User32.WM.CREATE) { _designer.HookChildHandles(m.LParam); // they will get removed from the collection just above } // We want these messages to go through the designer's WndProc method, and we want people to be able // to do default processing with the designer's DefWndProc. So, we stuff ourselves into the designers // window target and call their WndProc. IDesignerTarget designerTarget = _designer.DesignerTarget; _designer.DesignerTarget = this; Debug.Assert(m.HWnd == Handle, "Message handle differs from target handle"); try { _designer.WndProc(ref m); } catch (Exception ex) { _designer.SetUnhandledException(Control.FromChildHandle(m.HWnd), ex); } finally { // make sure the designer wasn't destroyed if (_designer != null && _designer.Component != null) { _designer.DesignerTarget = designerTarget; } } }
public void TextBox_PlaceholderTextAlignmentsInRightToLeft() { using var tb = new TextBox { PlaceholderText = "Enter your name", RightToLeft = RightToLeft.Yes }; HandleRef refHandle = new HandleRef(tb, tb.Handle); //Cover the Placeholder draw code path in RightToLeft scenario User32.SendMessageW(refHandle, User32.WM.PAINT, PARAM.FromBool(false)); tb.TextAlign = HorizontalAlignment.Center; User32.SendMessageW(refHandle, User32.WM.PAINT, PARAM.FromBool(false)); tb.TextAlign = HorizontalAlignment.Right; User32.SendMessageW(refHandle, User32.WM.PAINT, PARAM.FromBool(false)); Assert.False(string.IsNullOrEmpty(tb.PlaceholderText)); }
private void UpdateHelmetWorkStations(DoorDbContext context) { PARAM helmetParam1 = new PARAM(); helmetParam1.Domain = HelmetTypes.Domain; helmetParam1.Label = HelmetTypes.StandartType; helmetParam1.Value = HelmetTypes.StandartTypeValue; HelmetWorkStation station1 = new HelmetWorkStation(); station1.HelmetType = helmetParam1; station1.WorkStationNumber = 1; context.HelmetWorkStations.Add(station1); HelmetWorkStation station3 = new HelmetWorkStation(); station3.HelmetType = helmetParam1; station3.WorkStationNumber = 3; context.HelmetWorkStations.Add(station3); PARAM helmetParam2 = new PARAM(); helmetParam2.Domain = HelmetTypes.Domain; helmetParam2.Label = HelmetTypes.PremiumType; helmetParam2.Value = HelmetTypes.PremiumTypeValue; HelmetWorkStation station2 = new HelmetWorkStation(); station2.HelmetType = helmetParam2; station2.WorkStationNumber = 2; context.HelmetWorkStations.Add(station2); HelmetWorkStation station4 = new HelmetWorkStation(); station4.HelmetType = helmetParam2; station4.WorkStationNumber = 4; context.HelmetWorkStations.Add(station4); }
public static void addParam(SiapTable vot, dataType dt, string name, string desc, int ind) { PARAM p = new PARAM(); p.name = name; p.DESCRIPTION = new anyTEXT(); p.datatype = dt; if (dt == dataType.@char) { p.arraysize = "*"; } p.DESCRIPTION.Any = new System.Xml.XmlNode[1]; XmlDocument doc = new XmlDocument(); p.DESCRIPTION.Any[0] = doc.CreateTextNode("DESCRIPTION"); p.DESCRIPTION.Any[0].InnerText = desc; vot.RESOURCE[0].Items[ind] = p; }
private static PARAM GetParam(BND4 parambnd, string paramfile) { var bndfile = parambnd.Files.Find(x => Path.GetFileName(x.Name) == paramfile); if (bndfile != null) { return(PARAM.Read(bndfile.Bytes)); } // Otherwise the param is a loose param if (File.Exists($@"{AssetLocator.GameModDirectory}\Param\{paramfile}")) { return(PARAM.Read($@"{AssetLocator.GameModDirectory}\Param\{paramfile}")); } if (File.Exists($@"{AssetLocator.GameRootDirectory}\Param\{paramfile}")) { return(PARAM.Read($@"{AssetLocator.GameRootDirectory}\Param\{paramfile}")); } return(null); }
private int DisplayIndexToID(int displayIndex) { Debug.Assert(!owner.VirtualMode, "in virtual mode, this method does not make any sense"); if (owner.IsHandleCreated && !owner.ListViewHandleDestroyed) { // Obtain internal index of the item var lvItem = new LVITEMW { mask = LVIF.PARAM, iItem = displayIndex }; User32.SendMessageW(owner, (User32.WM)LVM.GETITEMW, 0, ref lvItem); return(PARAM.ToInt(lvItem.lParam)); } else { return(this[displayIndex].ID); } }
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); } }
protected void Gridview2_RowDeleting(object sender, GridViewDeleteEventArgs e) { this.PanelNewUser.CssClass = "content-box column-left"; this.PanelEditUser.CssClass = "content-box column-right closed-box"; try { string TittleText = ((TextBox)this.Gridview2.Rows[e.RowIndex].FindControl("EditTittle")).Text; string DescText = ((TextBox)this.Gridview2.Rows[e.RowIndex].FindControl("EditDescription")).Text; List <PARAM> list = (List <PARAM>) this.Application["Params"]; PARAM obj = Enumerable.Single <PARAM>((IEnumerable <PARAM>)list, (Func <PARAM, bool>)(p => p.Description == DescText && p.Tittle == TittleText)); list.Remove(obj); this.Gridview2.DataSource = (object)list; this.Gridview2.DataBind(); this.Application["Params"] = (object)list; } catch { this.Gridview2.DataSource = (object)(List <PARAM>) this.Application["Params"]; this.Gridview2.DataBind(); } }
// Load params from given path, relative to current dir public Dictionary <string, PARAM> LoadParams(string path, Dictionary <string, PARAM.Layout> layouts = null, bool allowError = false) { layouts = layouts ?? LoadLayouts(); return(LoadBnd(path, (data, paramPath) => { PARAM param; try { param = PARAM.Read(data); } catch (Exception e) { if (!allowError) { throw new Exception($"Failed to load param {paramPath}: " + e); } // For DS3 this also includes draw params, so just silently fail // TODO: Find a better way to load all params reliably return null; } if (layouts == null) { return param; } else if (layouts.ContainsKey(param.ParamType)) { PARAM.Layout layout = layouts[param.ParamType]; if (layout.Size == param.DetectedSize) { param.ApplyParamdef(layout.ToParamdef(param.ParamType, out var _)); return param; } else { // Console.WriteLine($"Mismatched size for {path} - {layout.Size} vs {param.DetectedSize} actual"); } } return null; })); }
public PARAM Read(string name, PARAMDEF def) { var worksheet = Spreadsheet.Workbook.Worksheets.First(sheet => sheet.Name.Equals(name)); var rowCount = worksheet.Dimension.Rows; var param = new PARAM(); param.ParamType = def.ParamType; param.Rows = new List <PARAM.Row>(rowCount - 2); param.ApplyParamdef(def); for (var rowIndex = 3; rowIndex <= rowCount; rowIndex++) { var id = int.Parse(worksheet.Cells[rowIndex, 1].Value.ToString()); var rowName = worksheet.Cells[rowIndex, 2].Value ?? string.Empty; var row = new PARAM.Row(id, (string?)rowName, def); for (var cellIndex = 0; cellIndex < def.Fields.Count; cellIndex++) { var value = worksheet.Cells[rowIndex, 3 + cellIndex].Value; if (value is string v && v == "-") { // padding, we don't store this in excel files continue; } if (value is null) { Console.WriteLine($"Row ID {id} and field ${def.Fields[cellIndex].DisplayName} has null value, assuming default"); continue; } row.Cells[cellIndex].Value = value; } param.Rows.Add(row); } return(param); }
public static List <PARAM.Row> GetMatchingParamRowsByID(PARAM param, string rowvalexp, bool lenient, bool failureAllOrNone) { List <PARAM.Row> rlist = new List <PARAM.Row>(); try { Regex rx = lenient ? new Regex(rowvalexp) : new Regex($@"^{rowvalexp}$"); foreach (PARAM.Row row in param.Rows) { string term = row.ID.ToString(); if (rx.Match(term).Success) { rlist.Add(row); } } return(rlist); } catch { return(failureAllOrNone ? param.Rows : rlist); } }
public bool SerializeDS2Regist(PARAM regist) { HashSet <long> ids = new HashSet <long>(); foreach (var o in Objects) { if (o is MapEntity m && m.Type == MapEntity.MapEntityType.DS2GeneratorRegist && m.WrappedObject is PARAM.Row mp) { if (!ids.Contains(mp.ID)) { ids.Add(mp.ID); } else { MessageBox.Show($@"{mp.Name} has an ID that's already used. Please change it to something unique and save again.", "", MessageBoxButtons.OK, MessageBoxIcon.Error); return(false); } regist.Rows.Add(mp); } } return(true); }
public static List <PARAM.Row> GetMatchingParamRowsByName(PARAM param, 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) { string nameToMatch = row.Name == null ? "" : row.Name; if (rownamerx.Match(lenient ? nameToMatch.ToLower() : nameToMatch).Success) { rlist.Add(row); } } return(rlist); } catch { return(failureAllOrNone ? param.Rows : rlist); } }
protected override bool ProcessKeyEventArgs(ref Message m) { switch ((Keys)PARAM.ToInt(m.WParam)) { case Keys.Enter: if (m.Msg == (int)User32.WM.CHAR && !(ModifierKeys == Keys.Shift && Multiline && AcceptsReturn)) { // Ignore the Enter key and don't add it to the textbox content. This happens when failing validation brings // up a dialog box for example. // Shift-Enter for multiline textboxes need to be accepted however. return(true); } break; case Keys.LineFeed: if (m.Msg == (int)User32.WM.CHAR && ModifierKeys == Keys.Control && Multiline && AcceptsReturn) { // Ignore linefeed character when user hits Ctrl-Enter to commit the cell. return(true); } break; case Keys.A: if (m.Msg == (int)User32.WM.KEYDOWN && ModifierKeys == Keys.Control) { SelectAll(); return(true); } break; } return(base.ProcessKeyEventArgs(ref m)); }
public ParamFile(string name, PARAM param, Dictionary <string, PARAM.Layout> layouts) { Name = name; Param = param; string format = Param.ParamType; if (!layouts.ContainsKey(format)) { layouts[format] = new PARAM.Layout(); } try { Layout = layouts[format]; Param.ApplyParamdef(Layout.ToParamdef(param.ParamType, out _)); Rows = Param.Rows; } catch (Exception ex) { Rows = new List <PARAM.Row>(); ShowError($"Error in layout {format}, please try again.\r\n\r\n{ex}"); } }
public ParamWrapper(string name, PARAM param, PARAM.Layout layout, string description) { if (layout.Size != param.DetectedSize) { Console.WriteLine(name); Console.WriteLine(layout.Size); Console.WriteLine(param.DetectedSize); Console.WriteLine(param.DetectedSize - layout.Size); } if (layout == null || layout.Size != param.DetectedSize) { layout = new PARAM.Layout(); layout.Add(new PARAM.Layout.Entry(PARAM.CellType.dummy8, "Unknown", (int)param.DetectedSize, null)); Error = true; } Name = name; Param = param; Layout = layout; Param.SetLayout(layout); Description = description; }
private static void LoadParamFromBinder(IBinder parambnd) { // Load every param in the regulation //_params = new Dictionary<string, PARAM>(); foreach (var f in parambnd.Files) { if (!f.Name.ToUpper().EndsWith(".PARAM") || Path.GetFileNameWithoutExtension(f.Name).StartsWith("default_")) { continue; } if (f.Name.EndsWith("LoadBalancerParam.param")) { continue; } if (_params.ContainsKey(Path.GetFileNameWithoutExtension(f.Name))) { continue; } PARAM p = PARAM.Read(f.Bytes); p.ApplyParamdef(_paramdefs[p.ParamType]); _params.Add(Path.GetFileNameWithoutExtension(f.Name), p); } }
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 void UnpackGameBNDFile() { // Reading an original paramdefbnd paramDefs = new Dictionary <string, PARAMDEF>(); paramDefBnd = BND3.Read(pathToParamDef); foreach (BinderFile file in paramDefBnd.Files) { var paramdef = PARAMDEF.Read(file.Bytes); paramDefs[paramdef.ParamType] = paramdef; } parms = new Dictionary <string, PARAM>(); paramBnd = BND3.Read(pathToParamDataFile); foreach (BinderFile file in paramBnd.Files) { string name = Path.GetFileNameWithoutExtension(file.Name); var param = PARAM.Read(file.Bytes); param.ApplyParamdef(paramDefs[param.ParamType]); parms[name] = param; } }
protected override void WndProc(ref Message m) { if (m.Msg == (int)User32.WM.SHOWWINDOW) { return; } base.WndProc(ref m); switch (m.Msg) { case (int)User32.WM.PARENTNOTIFY: if (PARAM.LOWORD(m.WParam) == (int)User32.WM.DESTROY) { User32.PostMessageW(this, (User32.WM)WM_CHECKDESTROY); } break; case WM_CHECKDESTROY: CheckDestroy(); break; } }
protected override void WndProc(ref Message m) { if (m.Msg == WindowMessages.WM_SHOWWINDOW) { return; } base.WndProc(ref m); switch (m.Msg) { case WindowMessages.WM_PARENTNOTIFY: if (PARAM.LOWORD(m.WParam) == WindowMessages.WM_DESTROY) { UnsafeNativeMethods.PostMessage(new HandleRef(this, Handle), WM_CHECKDESTROY, IntPtr.Zero, IntPtr.Zero); } break; case WM_CHECKDESTROY: CheckDestroy(); break; } }
public bool SerializeDS2Generators(PARAM locations, PARAM generators) { HashSet <long> ids = new HashSet <long>(); foreach (var o in Objects) { if (o is MapEntity m && m.Type == MapEntity.MapEntityType.DS2Generator && m.WrappedObject is MergedParamRow mp) { if (!ids.Contains(mp.ID)) { ids.Add(mp.ID); } else { MessageBox.Show($@"{mp.Name} has an ID that's already used. Please change it to something unique and save again.", "", MessageBoxButtons.OK, MessageBoxIcon.Error); return(false); } var loc = mp.GetRow("generator-loc"); if (loc != null) { // Adjust the location to be relative to the mapoffset var newloc = new PARAM.Row(loc); newloc["PositionX"].Value = (float)loc["PositionX"].Value - MapOffset.Position.X; newloc["PositionY"].Value = (float)loc["PositionY"].Value - MapOffset.Position.Y; newloc["PositionZ"].Value = (float)loc["PositionZ"].Value - MapOffset.Position.Z; locations.Rows.Add(newloc); } var gen = mp.GetRow("generator"); if (gen != null) { generators.Rows.Add(gen); } } } return(true); }
/****************************** ******************************/ void Update() { if (Input.GetKeyDown(KeyCode.Alpha0)) { Debug.Log("Weight=" + StrTest[0, 0].get_Weight() + ", "); SampleDelegate dele = StrTest[0, 0].get_SampleDelegate(); dele(0); } else if (Input.GetKeyDown(KeyCode.Alpha1)) { Debug.Log("Weight=" + StrTest[0, 1].get_Weight() + ", "); SampleDelegate dele; StrTest[0, 1].Copy_SampleDelegate(out dele); dele(0); } else if (Input.GetKeyDown(KeyCode.Alpha2)) { PARAM param = StrTest[0, 0].get_PARAM(); // param.val = 99; // readonlyなのでCompile Error. StrTest[0, 0].print_param(); } }
public void InitiateWindowDrag(IntPtr hWnd, IntPtr lParam) { if (_dragWindowInfo != null) { ReleaseCapture(); _dragWindowInfo.Reset(); var dragPoint = new POINT(); dragPoint.x = PARAM.SignedLOWORD(lParam); dragPoint.y = PARAM.SignedHIWORD(lParam); var windowTopLeftPoint = new POINT(); if (_dragWindowInfo.IsCursorInDraggableRegion(ref dragPoint, ref windowTopLeftPoint)) { SetCapture(hWnd); _dragWindowInfo.DragInitiated = true; _dragWindowInfo.DragPoint = dragPoint; _dragWindowInfo.DragWindowLocation = windowTopLeftPoint; InstallDragMouseHook(); } } }
public static void TriggerDpiMessage(User32.WM message, Control control, int newDpi) { double factor = newDpi / DpiHelper.LogicalDpi; IntPtr wParam = PARAM.FromLowHigh(newDpi, newDpi); _ = message switch { User32.WM.DPICHANGED => SendWmDpiChangedMessage(), User32.WM.DPICHANGED_BEFOREPARENT => User32.SendMessageW(control, message, wParam), User32.WM.DPICHANGED_AFTERPARENT => User32.SendMessageW(control, message), _ => throw new NotImplementedException() }; IntPtr SendWmDpiChangedMessage() { RECT suggestedRect = new(0, 0, (int)Math.Round(control.Width * factor), (int)Math.Round(control.Height * factor)); return(User32.SendMessageW(control, message, wParam, ref suggestedRect)); } } }
private int GetCharIndexFromPosition(Point pt) { int index = (int)User32.SendMessageW(_owningChildEdit, (WM)EM.CHARFROMPOS, 0, PARAM.FromPoint(pt)); index = PARAM.LOWORD(index); if (index < 0) { index = 0; } else { string t = Text; // EM_CHARFROMPOS will return an invalid number if the last character in the RichEdit // is a newline. // if (index >= t.Length) { index = Math.Max(t.Length - 1, 0); } } return(index); }
void Test_Util_Parameter() { string s = new PARAM("field").ToString(); }
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 LocationData FindItems(GameData game) { SortedDictionary <int, List <EntityId> > usedItemLots = FindItemLots(game); PARAM shops = game.Param("ShopLineupParam"); PARAM itemLots = game.Param("ItemLotParam"); PARAM materials = game.Param("EquipMtrlSetParam"); LocationData data = new LocationData(); // Run through all item lots in the game in order, extract all the data. LocationKey prevLocation = null; foreach (KeyValuePair <int, List <EntityId> > entry in usedItemLots) { int itemLot = entry.Key; if (prevLocation != null) { if (!crowLots.Contains(prevLocation.ID)) { prevLocation.MaxSlots = itemLot - prevLocation.ID - 1; if (prevLocation.MaxSlots < 1) { Warn($"Overlapping slots at {itemLot}"); } } prevLocation = null; } List <EntityId> entities = entry.Value; string locs = String.Join(", ", entities.Select(e => game.EntityName(e) + $" {e}")); if (itemLots[itemLot] == null) { string text = game.LotName(itemLot); // These are fine - no-ops to game // Console.WriteLine($"MISSING connected item lot!! {itemLot}: {text} @ {locs}"); continue; } LocationKey baseLocation = null; while (itemLots[itemLot] != null) { bool isBase = itemLot == entry.Key; string text = game.LotName(itemLot); PARAM.Row row = itemLots[itemLot]; int eventFlag = (int)row["getItemFlagId"].Value; int totalPoints = 0; for (int i = 1; i <= 8; i++) { totalPoints += (short)row[$"LotItemBasePoint0{i}"].Value; } for (int i = 1; i <= 8; i++) { int id = (int)row[$"ItemLotId{i}"].Value; if (id != 0) { uint type = (uint)row[$"LotItemCategory0{i}"].Value; int points = (short)row[$"LotItemBasePoint0{i}"].Value; int quantity = (byte)row[$"LotItemNum{i}"].Value; ItemKey item = new ItemKey(LocationData.LotTypes[type], id); string itemText = $"{itemLot}[{locs}]"; // Check out script about CC, btw List <string> info = new List <string>(); if (quantity > 1) { info.Add($"{quantity}"); } if (points != totalPoints) { info.Add($"{100.0 * points / totalPoints}%"); } if (info.Count() > 0) { itemText += $" ({string.Join(",", info)})"; } if (quantity <= 0 && logUnused) { Console.WriteLine($"There is 0! of {itemText}"); } ItemScope scope; if (eventFlag != -1) { if (equivalentEvents.ContainsKey(eventFlag)) { eventFlag = equivalentEvents[eventFlag]; } scope = new ItemScope(ScopeType.EVENT, eventFlag); } else { // One time drops that directly award, that aren't covered by event flags. Mostly crystal lizards. if (entities.Count() == 1 && entityItemLots.ContainsKey(entities[0].EventEntityID) && entityItemLots[entities[0].EventEntityID] == entry.Key) { scope = new ItemScope(ScopeType.ENTITY, entities[0].EventEntityID); } // Non-respawning enemies with drops which can be missed. These are reused between different entities, so can drop multiple times. else if (entities.All(e => nonRespawningEntities.Contains(e.EventEntityID))) { scope = new ItemScope(ScopeType.ENTITY, entities.Select(e => e.EventEntityID).Min()); } else { int model = entities.Select(e => e.GetModelID()).Min(); if (model == -1) { if (logUnused) { // Ideally this should not be randomized, but can't check here Console.WriteLine($"Infinite item {itemLot} with no event flags, entity flags, or models: {itemText}"); } continue; } scope = new ItemScope(ScopeType.MODEL, model); } } LocationKey location = new LocationKey(LocationType.LOT, itemLot, itemText, entities, quantity, baseLocation); data.AddLocation(item, scope, location); if (baseLocation == null) { baseLocation = location; } } } itemLot++; if (crowLots.Contains(itemLot - 1)) { break; } } prevLocation = baseLocation; } foreach (PARAM.Row row in shops.Rows) { int shopID = (int)row.ID; string shopName = shopSplits[GetShopType(shopID)]; if (shopName == null) { continue; } int qwc = (int)row["qwcID"].Value; int type = (byte)row["equipType"].Value; int id = (int)row["EquipId"].Value; int quantity = (short)row["sellQuantity"].Value; int eventFlag = (int)row["EventFlag"].Value; int material = (int)row["mtrlId"].Value; string quantityText = quantity == -1 ? "" : $" ({quantity})"; string qwcText = qwc == -1 ? "" : $" {game.QwcName(qwc)}"; ItemKey item = new ItemKey((ItemType)type, id); string text = $"{shopName}{qwcText}{quantityText}"; text = $"{shopID}[{text}]"; LocationKey location = new LocationKey(LocationType.SHOP, shopID, text, new List <EntityId>(), quantity, null); ItemScope scope; if (eventFlag != -1) { if (equivalentEvents.ContainsKey(eventFlag)) { eventFlag = equivalentEvents[eventFlag]; } if (quantity <= 0) { Warn($"No quantity for event flag shop entry {text}"); } ScopeType scopeType = ScopeType.EVENT; if (restrictiveQwcs.Contains(qwc)) { // In DS3, if item becomes unavailable at some point, that is because it returns in infinite form scopeType = ScopeType.SHOP_INFINITE_EVENT; } scope = new ItemScope(scopeType, eventFlag); } else if (material != -1) { int materialItem = (int)materials[material]["MaterialId01"].Value; scope = new ItemScope(ScopeType.MATERIAL, materialItem); } else { scope = new ItemScope(ScopeType.SHOP_INFINITE, -1); } data.AddLocation(item, scope, location); } // Merge infinite and finite shops. Mostly done via heuristic (when event and infinite both exist) ItemScope infiniteKey = new ItemScope(ScopeType.SHOP_INFINITE, -1); foreach (ItemLocations locations in data.Data.Values) { foreach (ItemLocation restrict in locations.Locations.Values.Where(loc => loc.Scope.Type == ScopeType.SHOP_INFINITE_EVENT).ToList()) { if (locations.Locations.ContainsKey(infiniteKey)) { // Combine infinite shops into event ItemLocation infinite = locations.Locations[infiniteKey]; restrict.Keys.AddRange(infinite.Keys); locations.Locations.Remove(infiniteKey); } else { Warn($"No 1:1 match between event shops and infinite shops for {restrict}"); // No infinite shops, turn this into a regular event shop. (Doesn't happen in base DS3) ItemLocation eventLoc = new ItemLocation(new ItemScope(ScopeType.EVENT, restrict.Scope.ID)); eventLoc.Keys.AddRange(restrict.Keys); locations.Locations[eventLoc.Scope] = eventLoc; locations.Locations.Remove(restrict.Scope); } } } // Now calculate all location scopes - distinct item sources. // This is the main key for the annotations file, so scopes can be marked as missable or not, assigned logical areas, etc. // It is also used as the target for randomizing an item, because if several locations are equivalent, all should contain the same item. List <ScopeType> uniqueTypes = new List <ScopeType> { ScopeType.EVENT, ScopeType.ENTITY, ScopeType.MATERIAL }; foreach (KeyValuePair <ItemKey, ItemLocations> entry in data.Data) { ItemKey item = entry.Key; int unique = 0; foreach (KeyValuePair <ItemScope, ItemLocation> entry2 in entry.Value.Locations) { ItemScope scope = entry2.Key; ItemLocation loc = entry2.Value; int id = uniqueTypes.Contains(scope.Type) ? scope.ID : -1; unique = unique == -1 ? -1 : (id == -1 ? -1 : unique + 1); SortedSet <int> shopIds = new SortedSet <int>(loc.Keys.Where(k => k.Type == LocationType.SHOP).Select(k => GetShopType(k.ID))); SortedSet <int> shopQwcs = new SortedSet <int>(loc.Keys.Where(k => k.Type == LocationType.SHOP).Select(k => ((int)shops[k.ID]["qwcID"].Value, (int)shops[k.ID]["EventFlag"].Value)) .Where(e => e.Item1 != -1 && (!restrictiveQwcs.Contains(e.Item1) || e.Item2 == -1)) .Select(e => e.Item1)); SortedSet <int> allShop = new SortedSet <int>(shopIds.Union(shopQwcs)); if (shopIds.Count() + shopQwcs.Count() != allShop.Count()) { Warn($"Overlapping qwc/shop ids for location {loc}"); } SortedSet <int> modelBase = scope.Type == ScopeType.MODEL ? new SortedSet <int>(loc.Keys.Select(k => k.BaseID)) : new SortedSet <int>(); bool onlyShops = loc.Keys.All(k => k.Type == LocationType.SHOP) && allShop.Count() > 0; LocationScope locationScope = new LocationScope(scope.Type, id, allShop, modelBase, onlyShops); data.AddLocationScope(item, scope, locationScope); } entry.Value.Unique = unique > 0 && item.Type != ItemType.ARMOR; } if (logUnused) { foreach (KeyValuePair <ItemKey, string> entry in game.Names()) { ItemKey item = entry.Key; if (item.Type == 0) { item = new ItemKey(item.Type, item.ID - (item.ID % 10000)); } if (!data.Data.ContainsKey(item)) { // Mostly pulls up old DS1 items and gestures. Console.WriteLine($"Unused item {item.Type}-{entry.Key.ID}: {entry.Value}"); } } } return(data); }
BOOL IMsoComponentManager.FPushMessageLoop( UIntPtr dwComponentID, msoloop uReason, void *pvLoopData) { // Hold onto old state to allow restore before we exit... msocstate currentLoopState = _currentState; BOOL continueLoop = BOOL.TRUE; if (!OleComponents.TryGetValue(dwComponentID, out ComponentHashtableEntry entry)) { return(BOOL.FALSE); } IMsoComponent prevActive = _activeComponent; try { User32.MSG msg = new User32.MSG(); IMsoComponent requestingComponent = entry.component; _activeComponent = requestingComponent; Debug.WriteLineIf( CompModSwitches.MSOComponentManager.TraceInfo, $"ComponentManager : Pushing message loop {uReason}"); Debug.Indent(); while (continueLoop.IsTrue()) { // Determine the component to route the message to IMsoComponent component = _trackingComponent ?? _activeComponent ?? requestingComponent; bool useAnsi = false; BOOL peeked = User32.PeekMessageW(ref msg); if (peeked.IsTrue()) { useAnsi = msg.hwnd != IntPtr.Zero && User32.IsWindowUnicode(msg.hwnd).IsFalse(); if (useAnsi) { peeked = User32.PeekMessageA(ref msg); } } if (peeked.IsTrue()) { continueLoop = component.FContinueMessageLoop(uReason, pvLoopData, &msg); // If the component wants us to process the message, do it. if (continueLoop.IsTrue()) { if (useAnsi) { User32.GetMessageA(ref msg); Debug.Assert(User32.IsWindowUnicode(msg.hwnd).IsFalse()); } else { User32.GetMessageW(ref msg); Debug.Assert(msg.hwnd == IntPtr.Zero || User32.IsWindowUnicode(msg.hwnd).IsTrue()); } if (msg.message == User32.WM.QUIT) { Debug.WriteLineIf( CompModSwitches.MSOComponentManager.TraceInfo, "ComponentManager : Normal message loop termination"); ThreadContext.FromCurrent().DisposeThreadWindows(); if (uReason != msoloop.Main) { User32.PostQuitMessage(PARAM.ToInt(msg.wParam)); } continueLoop = BOOL.FALSE; break; } // Now translate and dispatch the message. // // Reading through the rather sparse documentation, // it seems we should only call FPreTranslateMessage // on the active component. if (component.FPreTranslateMessage(&msg).IsFalse()) { User32.TranslateMessage(ref msg); if (useAnsi) { User32.DispatchMessageA(ref msg); } else { User32.DispatchMessageW(ref msg); } } } } else { // If this is a DoEvents loop, then get out. There's nothing left for us to do. if (uReason == msoloop.DoEvents || uReason == msoloop.DoEventsModal) { break; } // Nothing is on the message queue. Perform idle processing and then do a WaitMessage. bool continueIdle = false; if (OleComponents is not null) { foreach (ComponentHashtableEntry idleEntry in OleComponents.Values) { continueIdle |= idleEntry.component.FDoIdle(msoidlef.All).IsTrue(); } } // Give the component one more chance to terminate the message loop. continueLoop = component.FContinueMessageLoop(uReason, pvLoopData, null); if (continueLoop.IsTrue()) { if (continueIdle) { // If someone has asked for idle time, give it to them. However, // don't cycle immediately; wait up to 100ms. Why? Because we don't // want someone to attach to idle, forget to detach, and then cause // CPU to end up in race condition. For Windows Forms this generally isn't an issue because // our component always returns false from its idle request User32.MsgWaitForMultipleObjectsEx(0, IntPtr.Zero, 100, User32.QS.ALLINPUT, User32.MWMO.INPUTAVAILABLE); } else { // We should call GetMessage here, but we cannot because // the component manager requires that we notify the // active component before we pull the message off the // queue. This is a bit of a problem, because WaitMessage // waits for a NEW message to appear on the queue. If a // message appeared between processing and now WaitMessage // would wait for the next message. We minimize this here // by calling PeekMessage. if (User32.PeekMessageW(ref msg, IntPtr.Zero, 0, 0, User32.PM.NOREMOVE).IsFalse()) { User32.WaitMessage(); } } } } } Debug.Unindent(); Debug.WriteLineIf(CompModSwitches.MSOComponentManager.TraceInfo, $"ComponentManager : message loop {uReason} complete."); } finally { _currentState = currentLoopState; _activeComponent = prevActive; } return(continueLoop.IsFalse() ? BOOL.TRUE : BOOL.FALSE); }