void UpdateMapObject(ObjectSlotData objData, ObjectSlot objSlot, BehaviorCriteria behaviorCriteria) { if (ActiveTab != TabType.Map || !Config.MapManager.IsLoaded) { return; } var objAddress = objData.Address; // Update image var mapObjImage = Config.ObjectAssociations.GetObjectMapImage(behaviorCriteria); var mapObjRotates = Config.ObjectAssociations.GetObjectMapRotates(behaviorCriteria); if (!_mapObjects.ContainsKey(objAddress)) { var mapObj = new MapObject(mapObjImage); mapObj.UsesRotation = mapObjRotates; _mapObjects.Add(objAddress, mapObj); Config.MapManager.AddMapObject(mapObj); } else if (_mapObjects[objAddress].Image != mapObjImage) { Config.MapManager.RemoveMapObject(_mapObjects[objAddress]); var mapObj = new MapObject(mapObjImage); mapObj.UsesRotation = mapObjRotates; _mapObjects[objAddress] = mapObj; Config.MapManager.AddMapObject(mapObj); } if (objData.Behavior == (Config.ObjectAssociations.MarioBehavior & 0x00FFFFFF) + Config.ObjectAssociations.BehaviorBankStart) { _mapObjects[objAddress].Show = false; } else { // Update map object coordinates and rotation var mapObj = _mapObjects[objAddress]; mapObj.Show = SelectedOnMapSlotsAddresses.Contains(objAddress); objSlot.Show = _mapObjects[objAddress].Show; mapObj.X = Config.Stream.GetSingle(objAddress + ObjectConfig.XOffset); mapObj.Y = Config.Stream.GetSingle(objAddress + ObjectConfig.YOffset); mapObj.Z = Config.Stream.GetSingle(objAddress + ObjectConfig.ZOffset); mapObj.IsActive = objData.IsActive; mapObj.Transparent = !mapObj.IsActive; ushort objYaw = Config.Stream.GetUInt16(objAddress + ObjectConfig.YawFacingOffset); mapObj.Rotation = (float)MoreMath.AngleUnitsToDegrees(objYaw); mapObj.UsesRotation = Config.ObjectAssociations.GetObjectMapRotates(behaviorCriteria); } }
void UpdateObjectManager(ObjectSlot objSlot, BehaviorCriteria behaviorCriteria, ObjectSlotData objData) { var objAssoc = Config.ObjectAssociations.FindObjectAssociation(behaviorCriteria); var newBehavior = objAssoc != null ? objAssoc.BehaviorCriteria : behaviorCriteria; if (_lastSelectedBehavior != newBehavior || SelectedSlotsAddresses.Count == 0) { Config.ObjectManager.Behavior = String.Format("0x{0}", (behaviorCriteria.BehaviorAddress & 0xffffff).ToString("X4")); Config.ObjectManager.Name = Config.ObjectAssociations.GetObjectName(behaviorCriteria); Config.ObjectManager.SetBehaviorWatchVariables(Config.ObjectAssociations.GetWatchVarControls(behaviorCriteria), objSlot.BackColor.Lighten(0.8)); _lastSelectedBehavior = newBehavior; } Config.ObjectManager.Image = objSlot.ObjectImage; Config.ObjectManager.BackColor = objSlot.BackColor; int slotPos = objData.ObjectProcessGroup == VacantGroup ? objData.VacantSlotIndex.Value : objData.ProcessIndex; Config.ObjectManager.SlotIndex = (_memoryAddressSlotIndex[objData.Address] + (OptionsConfig.SlotIndexsFromOne ? 1 : 0)).ToString(); Config.ObjectManager.SlotPos = (objData.ObjectProcessGroup == VacantGroup ? "VS " : "") + (slotPos + (OptionsConfig.SlotIndexsFromOne ? 1 : 0)).ToString(); }
private void UpdateSlot(ObjectSlotData objData, ObjectSlot objSlot) { uint objAddress = objData.Address; BehaviorCriteria behaviorCriteria; objSlot.IsActive = objData.IsActive; objSlot.Address = objAddress; // Update Overlays objSlot.DrawSelectedOverlay = SelectedSlotsAddresses.Contains(objAddress); objSlot.DrawStoodOnOverlay = OverlayConfig.ShowOverlayStoodOnObject && objAddress == _stoodOnObject; objSlot.DrawInteractionOverlay = OverlayConfig.ShowOverlayInteractionObject && objAddress == _interactionObject; objSlot.DrawHeldOverlay = OverlayConfig.ShowOverlayHeldObject && objAddress == _heldObject; objSlot.DrawUsedOverlay = OverlayConfig.ShowOverlayUsedObject && objAddress == _usedObject; objSlot.DrawClosestOverlay = OverlayConfig.ShowOverlayClosestObject && objAddress == _closestObject; objSlot.DrawCameraOverlay = OverlayConfig.ShowOverlayCameraObject && objAddress == _cameraObject; objSlot.DrawCameraHackOverlay = OverlayConfig.ShowOverlayCameraHackObject && objAddress == _cameraHackObject; objSlot.DrawModelOverlay = objAddress == _modelObject; objSlot.DrawFloorOverlay = OverlayConfig.ShowOverlayFloorObject && objAddress == _floorObject; objSlot.DrawWallOverlay = OverlayConfig.ShowOverlayWallObject && objAddress == _wallObject; objSlot.DrawCeilingOverlay = OverlayConfig.ShowOverlayCeilingObject && objAddress == _ceilingObject; objSlot.DrawParentOverlay = OverlayConfig.ShowOverlayParentObject && objAddress == _parentObject; objSlot.DrawParentUnusedOverlay = OverlayConfig.ShowOverlayParentObject && objAddress == _parentUnusedObject; objSlot.DrawParentNoneOverlay = OverlayConfig.ShowOverlayParentObject && objAddress == _parentNoneObject; objSlot.DrawMarkedOverlay = MarkedSlotsAddresses.Contains(objAddress); if (objData.IsActive) { _activeObjectCount++; } var gfxId = Config.Stream.GetUInt32(objAddress + ObjectConfig.BehaviorGfxOffset); var subType = Config.Stream.GetInt32(objAddress + ObjectConfig.BehaviorSubtypeOffset); var appearance = Config.Stream.GetInt32(objAddress + ObjectConfig.BehaviorAppearanceOffset); uint segmentedBehavior = 0x13000000 + objData.Behavior - Config.ObjectAssociations.BehaviorBankStart; if (objData.Behavior == 0) // uninitialized object { segmentedBehavior = 0; } behaviorCriteria = new BehaviorCriteria() { BehaviorAddress = Config.SwitchRomVersion(segmentedBehavior, Config.ObjectAssociations.AlignJPBehavior(segmentedBehavior)), GfxId = gfxId, SubType = subType, Appearance = appearance }; if (Config.ObjectAssociations.RecognizedBehavior(behaviorCriteria)) { objSlot.Behavior = behaviorCriteria; } else { behaviorCriteria = objSlot.Behavior; // skip update, bad behavior } var processGroup = objData.ObjectProcessGroup; objSlot.ProcessGroup = processGroup; var newColor = objData.ObjectProcessGroup == VacantGroup ? ObjectSlotsConfig.VacantSlotColor : ObjectSlotsConfig.ProcessingGroupsColor[objData.ObjectProcessGroup]; objSlot.BackColor = newColor; if (!_labelsLocked) { _lastSlotLabel[objAddress] = new Tuple <int?, int?>(objData.ProcessIndex, objData.VacantSlotIndex); } string labelText = ""; switch (LabelMethod) { case SlotLabelType.Recommended: if (SortMethod == SortMethodType.MemoryOrder) { goto case SlotLabelType.SlotIndex; } goto case SlotLabelType.SlotPosVs; case SlotLabelType.SlotIndex: labelText = String.Format("{0}", (objData.Address - ObjectSlotsConfig.LinkStartAddress) / ObjectConfig.StructSize + (OptionsConfig.SlotIndexsFromOne ? 1 : 0)); break; case SlotLabelType.SlotPos: labelText = String.Format("{0}", _lastSlotLabel[objAddress].Item1 + (OptionsConfig.SlotIndexsFromOne ? 1 : 0)); break; case SlotLabelType.SlotPosVs: var vacantSlotIndex = _lastSlotLabel[objAddress].Item2; if (!vacantSlotIndex.HasValue) { goto case SlotLabelType.SlotPos; } labelText = String.Format("VS{0}", vacantSlotIndex.Value + (OptionsConfig.SlotIndexsFromOne ? 1 : 0)); break; } objSlot.TextColor = _labelsLocked ? Color.Blue : Color.Black; objSlot.Text = labelText; // Update object manager image if (SelectedSlotsAddresses.Count <= 1 && SelectedSlotsAddresses.Contains(objAddress)) { UpdateObjectManager(objSlot, behaviorCriteria, objData); } // Update the map UpdateMapObject(objData, objSlot, behaviorCriteria); }
private List <ObjectSlotData> GetProcessedObjects() { var newObjectSlotData = new ObjectSlotData[ObjectSlotsConfig.MaxSlots]; // Loop through each processing group int currentSlot = 0; foreach (var objectProcessGroup in ObjectSlotsConfig.ProcessingGroups) { uint processGroupStructAddress = ObjectSlotsConfig.FirstGroupingAddress + objectProcessGroup * ObjectSlotsConfig.ProcessGroupStructSize; // Calculate start and ending objects uint currentGroupObject = Config.Stream.GetUInt32(processGroupStructAddress + ObjectConfig.ProcessedNextLinkOffset); // Loop through every object within the group while ((currentGroupObject != processGroupStructAddress && currentSlot < ObjectSlotsConfig.MaxSlots)) { // Validate current object if (Config.Stream.GetUInt16(currentGroupObject + ObjectConfig.HeaderOffset) != 0x18) { return(null); } // Get data newObjectSlotData[currentSlot] = new ObjectSlotData() { Address = currentGroupObject, ObjectProcessGroup = objectProcessGroup, ProcessIndex = currentSlot, VacantSlotIndex = null }; // Move to next object currentGroupObject = Config.Stream.GetUInt32(currentGroupObject + ObjectConfig.ProcessedNextLinkOffset); // Mark next slot currentSlot++; } } var vacantSlotStart = currentSlot; // Now calculate vacant addresses uint currentObject = Config.Stream.GetUInt32(ObjectSlotsConfig.VactantPointerAddress); for (; currentSlot < ObjectSlotsConfig.MaxSlots; currentSlot++) { // Validate current object if (Config.Stream.GetUInt16(currentObject + ObjectConfig.HeaderOffset) != 0x18) { return(null); } newObjectSlotData[currentSlot] = new ObjectSlotData() { Address = currentObject, ObjectProcessGroup = VacantGroup, ProcessIndex = currentSlot, VacantSlotIndex = currentSlot - vacantSlotStart }; currentObject = Config.Stream.GetUInt32(currentObject + ObjectConfig.ProcessedNextLinkOffset); } return(newObjectSlotData.ToList()); }
private void UpdateSlot(ObjectSlotData objectData, int index) { var objSlot = ObjectSlots[index]; uint currentAddress = objectData.Address; objSlot.IsActive = objectData.IsActive; objSlot.Address = currentAddress; // Update Overlays objSlot.DrawSelectedOverlay = _selectedSlotsAddresses.Contains(currentAddress); objSlot.DrawStandingOnOverlay = Config.ShowOverlays && currentAddress == _standingOnObject; objSlot.DrawInteractingOverlay = Config.ShowOverlays && currentAddress == _interactingObject; objSlot.DrawHoldingOverlay = Config.ShowOverlays && currentAddress == _holdingObject; objSlot.DrawUsingOverlay = Config.ShowOverlays && currentAddress == _usingObject; objSlot.DrawClosestOverlay = Config.ShowOverlays && currentAddress == _closestObject; if (objectData.IsActive) { activeObjCnt++; } var gfxId = BitConverter.ToUInt32(_stream.ReadRam(currentAddress + Config.ObjectSlots.BehaviorGfxOffset, 4), 0); var subType = BitConverter.ToInt32(_stream.ReadRam(currentAddress + Config.ObjectSlots.BehaviorSubtypeOffset, 4), 0); var appearance = BitConverter.ToInt32(_stream.ReadRam(currentAddress + Config.ObjectSlots.BehaviorAppearance, 4), 0); var behaviorCriteria = new BehaviorCriteria() { BehaviorAddress = objectData.Behavior, GfxId = gfxId, SubType = subType, Appearance = appearance }; ObjectSlots[index].Behavior = behaviorCriteria; var processGroup = objectData.ObjectProcessGroup; ObjectSlots[index].ProcessGroup = processGroup; var newColor = objectData.ObjectProcessGroup == VacantGroup ? Config.ObjectGroups.VacantSlotColor : Config.ObjectGroups.ProcessingGroupsColor[objectData.ObjectProcessGroup]; ObjectSlots[index].BackColor = newColor; string labelText = ""; switch ((SlotLabelType)ManagerGui.LabelMethodComboBox.SelectedItem) { case SlotLabelType.Recommended: var sortMethod = (SortMethodType)ManagerGui.SortMethodComboBox.SelectedItem; if (sortMethod == SortMethodType.MemoryOrder) { goto case SlotLabelType.SlotIndex; } goto case SlotLabelType.SlotPosVs; case SlotLabelType.SlotIndex: labelText = String.Format("{0}", (objectData.Address - Config.ObjectSlots.LinkStartAddress) / Config.ObjectSlots.StructSize); break; case SlotLabelType.SlotPos: labelText = String.Format("{0}", objectData.ProcessIndex + (Config.SlotIndexsFromOne ? 1 : 0)); break; case SlotLabelType.SlotPosVs: if (!objectData.VacantSlotIndex.HasValue) { goto case SlotLabelType.SlotPos; } labelText = String.Format("VS{0}", objectData.VacantSlotIndex.Value + (Config.SlotIndexsFromOne ? 1 : 0)); break; } if (ManagerGui.LockLabelsCheckbox.Checked) { if (!_lastSlotLabel.ContainsKey(currentAddress)) { _lastSlotLabel.Add(currentAddress, labelText); } else { _lastSlotLabel[currentAddress] = labelText; } } ObjectSlots[index].Text = ManagerGui.LockLabelsCheckbox.Checked ? _lastSlotLabel[currentAddress] : labelText; // Update object manager image if (_selectedSlotsAddresses.Contains(currentAddress)) { var objAssoc = ObjectAssoc.FindObjectAssociation(behaviorCriteria); var newBehavior = objAssoc != null ? objAssoc.BehaviorCriteria : (BehaviorCriteria?)null; if (_lastSelectedBehavior != newBehavior) { _objManager.Behavior = (objectData.Behavior + ObjectAssoc.RamOffset) & 0x00FFFFFF; _objManager.Name = ObjectAssoc.GetObjectName(behaviorCriteria); _objManager.SetBehaviorWatchVariables(ObjectAssoc.GetWatchVariables(behaviorCriteria), newColor.Lighten(0.8)); _lastSelectedBehavior = newBehavior; } _objManager.Image = ObjectSlots[index].ObjectImage; _objManager.BackColor = newColor; int slotPos = objectData.ObjectProcessGroup == VacantGroup ? objectData.VacantSlotIndex.Value : objectData.ProcessIndex; _objManager.SlotIndex = _memoryAddressSlotIndex[currentAddress] + (Config.SlotIndexsFromOne ? 1 : 0); _objManager.SlotPos = (objectData.ObjectProcessGroup == VacantGroup ? "VS " : "") + (slotPos + (Config.SlotIndexsFromOne ? 1 : 0)).ToString(); } // Update the map if (ManagerGui.TabControl.SelectedTab.Text == "Map" && _mapManager.IsLoaded) { // Update image var mapObjImage = ObjectAssoc.GetObjectMapImage(behaviorCriteria, !objectData.IsActive); var mapObjRotates = ObjectAssoc.GetObjectMapRotates(behaviorCriteria); if (!_mapObjects.ContainsKey(currentAddress)) { _mapObjects.Add(currentAddress, new MapObject(mapObjImage)); _mapManager.AddMapObject(_mapObjects[currentAddress]); _mapObjects[currentAddress].UsesRotation = mapObjRotates; } else if (_mapObjects[currentAddress].Image != mapObjImage) { _mapManager.RemoveMapObject(_mapObjects[currentAddress]); _mapObjects[currentAddress] = new MapObject(mapObjImage); _mapManager.AddMapObject(_mapObjects[currentAddress]); _mapObjects[currentAddress].UsesRotation = mapObjRotates; } if (objectData.Behavior == (ObjectAssoc.MarioBehavior & 0x0FFFFFFF)) { _mapObjects[currentAddress].Show = false; } else { // Update map object coordinates and rotation _mapObjects[currentAddress].Show = !_toggleMapBehaviors.Contains(behaviorCriteria) && !_toggleMapGroups.Contains(processGroup) && !_toggleMapSlots.Contains(currentAddress); _mapObjects[currentAddress].X = BitConverter.ToSingle(_stream.ReadRam(currentAddress + Config.ObjectSlots.ObjectXOffset, 4), 0); _mapObjects[currentAddress].Y = BitConverter.ToSingle(_stream.ReadRam(currentAddress + Config.ObjectSlots.ObjectYOffset, 4), 0); _mapObjects[currentAddress].Z = BitConverter.ToSingle(_stream.ReadRam(currentAddress + Config.ObjectSlots.ObjectZOffset, 4), 0); _mapObjects[currentAddress].IsActive = objectData.IsActive; _mapObjects[currentAddress].Rotation = (float)((UInt16)(BitConverter.ToUInt32( _stream.ReadRam(currentAddress + Config.ObjectSlots.ObjectRotationOffset, 4), 0)) / 65536f * 360f); _mapObjects[currentAddress].UsesRotation = ObjectAssoc.GetObjectMapRotates(behaviorCriteria); } } }
private List <ObjectSlotData> GetProcessedObjects(ObjectGroupsConfig groupConfig, ObjectSlotsConfig slotConfig) { var newObjectSlotData = new ObjectSlotData[slotConfig.MaxSlots]; // Loop through each processing group int currentSlot = 0; foreach (var objectProcessGroup in groupConfig.ProcessingGroups) { uint processGroupStructAddress = groupConfig.FirstGroupingAddress + objectProcessGroup * groupConfig.ProcessGroupStructSize; // Calculate start and ending objects uint currentGroupObject = BitConverter.ToUInt32(_stream.ReadRam(processGroupStructAddress + groupConfig.ProcessNextLinkOffset, 4), 0); // Make sure there are objects within the group if (currentGroupObject == processGroupStructAddress) { continue; } // Loop through every object within the group while ((currentGroupObject != processGroupStructAddress && currentSlot < slotConfig.MaxSlots)) { // Validate current object if (BitConverter.ToUInt16(_stream.ReadRam(currentGroupObject + Config.ObjectSlots.HeaderOffset, 2), 0) != 0x18) { return(null); } // Get data newObjectSlotData[currentSlot] = new ObjectSlotData() { Address = currentGroupObject, ObjectProcessGroup = objectProcessGroup, ProcessIndex = currentSlot, VacantSlotIndex = null }; // Move to next object currentGroupObject = BitConverter.ToUInt32( _stream.ReadRam(currentGroupObject + groupConfig.ProcessNextLinkOffset, 4), 0); // Mark next slot currentSlot++; } } var vacantSlotStart = currentSlot; // Now calculate vacant addresses uint currentObject = BitConverter.ToUInt32(_stream.ReadRam(groupConfig.VactantPointerAddress, 4), 0); for (; currentSlot < slotConfig.MaxSlots; currentSlot++) { // Validate current object if (BitConverter.ToUInt16(_stream.ReadRam(currentObject + Config.ObjectSlots.HeaderOffset, 2), 0) != 0x18) { return(null); } newObjectSlotData[currentSlot] = new ObjectSlotData() { Address = currentObject, ObjectProcessGroup = VacantGroup, ProcessIndex = currentSlot, VacantSlotIndex = currentSlot - vacantSlotStart }; currentObject = BitConverter.ToUInt32( _stream.ReadRam(currentObject + groupConfig.ProcessNextLinkOffset, 4), 0); } // Calculate distance to Mario return(newObjectSlotData.ToList()); }