public SequenceQuickEditMenu(EmergencyLighting els, EmergencyLightingMenu parent) { this.ELS = els; this.Parent = parent; Menu = new UIMenuRefreshable("Edit Sequences", parent.Menu.SubtitleText + " > Sequence Quick Edit"); for (int i = 0; i < ELS.Lights.Length; i++) { EmergencyLight siren = ELS.Lights[i]; string sirenId = $"Siren {i + 1}"; UIMenuSequenceItemSelector item = new UIMenuSequenceItemSelector($"{sirenId} Sequence", siren.FlashinessSequence, $"Edit 32-bit sequence for {sirenId}"); Menu.AddMenuDataBinding(item, (x) => siren.FlashinessSequence = x, () => siren.FlashinessSequence); sirenSequenceItems.Add(item); } Menu.AddItem(Parent.LeftHeadlightSequenceItem); sirenSequenceItems.Add(Parent.LeftHeadlightSequenceItem); Menu.AddItem(Parent.RightHeadlightSequenceItem); sirenSequenceItems.Add(Parent.RightHeadlightSequenceItem); Menu.AddItem(Parent.LeftTaillightSequenceItem); sirenSequenceItems.Add(Parent.LeftTaillightSequenceItem); Menu.AddItem(Parent.RightTaillightSequenceItem); sirenSequenceItems.Add(Parent.RightTaillightSequenceItem); buttons.Add(new InstructionalButton("V", "Paste sequence")); buttons.Add(new InstructionalButton("C", "Copy sequence")); buttons.Add(new InstructionalButton("dn", "Move siren down")); buttons.Add(new InstructionalButton("up", "Move siren up")); buttons.Add(new InstructionalButton("R", "Invert sequence")); buttons.Add(new InstructionalButton("E", "Extend sequence")); buttons.Add(new InstructionalButton(GameControl.FrontendRight, "Shift sequence")); buttons.Add(new InstructionalButton(GameControl.FrontendLeft, "Shift sequence")); buttons.Add(new InstructionalButton(GameControl.Duck, "Shift x4")); foreach (InstructionalButton button in buttons) { Menu.AddInstructionalButton(button); } Menu.OnMenuClose += OnMenuClose; }
public static EmergencyLighting GetEL(Vehicle veh, ActiveVehicle activeVeh = null) { DLSModel dlsModel = veh.GetDLS(); if (activeVeh == null) { activeVeh = veh.GetActiveVehicle(); } string name = dlsModel.Name + " | " + activeVeh.LightStage.ToString() + " | " + activeVeh.TAStage.ToString() + " | " + activeVeh.SBOn.ToString(); uint key = Game.GetHashKey(name); EmergencyLighting eL; if (Entrypoint.UsedPool.Count > 0 && Entrypoint.UsedPool.ContainsKey(key)) { eL = Entrypoint.UsedPool[key]; ("Allocated \"" + name + "\" (" + key + ") for " + veh.Handle + " from Used Pool").ToLog(); } else if (Entrypoint.AvailablePool.Count > 0) { eL = Entrypoint.AvailablePool[0]; Entrypoint.AvailablePool.Remove(eL); ("Removed \"" + eL.Name + "\" from Available Pool").ToLog(); ("Allocated \"" + name + "\" (" + key + ") for " + veh.Handle + " from Available Pool").ToLog(); } else { if (EmergencyLighting.GetByName(name) == null) { Model model = new Model("police"); eL = model.EmergencyLighting.Clone(); eL.Name = name; ("Created \"" + name + "\" (" + key + ") for " + veh.Handle).ToLog(); } else { eL = EmergencyLighting.GetByName(name); ("Allocated \"" + name + "\" (" + key + ") for " + veh.Handle + " from Game Memory").ToLog(); } } if (activeVeh.LightStage != LightStage.Off && activeVeh.LightStage != LightStage.Empty) { switch (activeVeh.LightStage) { case LightStage.One: SirenApply.ApplySirenSettingsToEmergencyLighting(dlsModel.Sirens.Stage1Setting, eL); break; case LightStage.Two: SirenApply.ApplySirenSettingsToEmergencyLighting(dlsModel.Sirens.Stage2Setting, eL); break; case LightStage.Three: SirenApply.ApplySirenSettingsToEmergencyLighting(dlsModel.Sirens.Stage3Setting, eL); break; case LightStage.CustomOne: SirenApply.ApplySirenSettingsToEmergencyLighting(dlsModel.Sirens.CustomStage1, eL); break; case LightStage.CustomTwo: SirenApply.ApplySirenSettingsToEmergencyLighting(dlsModel.Sirens.CustomStage2, eL); break; default: SirenApply.ApplySirenSettingsToEmergencyLighting(dlsModel.Sirens.Stage3Setting, eL); break; } } else { SirenApply.ApplySirenSettingsToEmergencyLighting(dlsModel.Sirens.Stage3Setting, eL); eL.LeftHeadLightSequence = "00000000000000000000000000000000"; eL.LeftTailLightSequence = "00000000000000000000000000000000"; eL.RightHeadLightSequence = "00000000000000000000000000000000"; eL.RightTailLightSequence = "00000000000000000000000000000000"; for (int i = 0; i < eL.Lights.Length; i++) { EmergencyLight eLig = eL.Lights[i]; eLig.FlashinessSequence = "00000000000000000000000000000000"; eLig.RotationSequence = "00000000000000000000000000000000"; } } if (!Entrypoint.UsedPool.ContainsKey(key)) { Entrypoint.UsedPool.Add(key, eL); } activeVeh.CurrentHash = key; return(eL); }
private void OnCopyActivated(UIMenu sender, UIMenuItem selectedItem) { (EmergencyLighting source, EmergencyLighting destination) = GetCopySourceAndDestination(); if (source.Exists() && destination.Exists() && destination.IsCustomSetting()) { bool sirenCopyAll = AllSirenPropertiesCheckbox.Checked; bool settingCopyAll = AllGeneralPropertiesCheckbox.Checked; Game.LogTrivial($"Initiating siren setting property copy from \"{source.Name}\" to \"{destination.Name}\""); foreach (int sirenId in DestinationSirens) { // if SourceSiren is -1, signifies 1-to-1 copy with selected target sirens // otherwise, use single selected source siren ID EmergencyLight sourceSiren = source.Lights[((SourceSiren == -1) ? sirenId : SourceSiren) - 1]; EmergencyLight destinationSiren = destination.Lights[sirenId - 1]; Game.LogTrivial($" SIREN {sirenId}:"); if (sirenCopyAll) { // In copy all mode, all siren-specific properties are copied for the selected sirens, no overall settings are copied Game.LogTrivial(" Copying all siren properties"); foreach (PropertyInfo property in sourceSiren.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.GetProperty | BindingFlags.SetProperty)) { try { property.SetValue(destinationSiren, property.GetValue(sourceSiren)); Game.LogTrivialDebug($" {property.Name}"); } catch (TargetInvocationException e) { Game.LogTrivial($" Unable to copy {property.Name}: {e.InnerException?.Message}"); } } } else { if (SequencesCheckbox.Checked) { Game.LogTrivial(" Copying flashiness and rotation sequences and multiples"); destinationSiren.FlashinessSequence = sourceSiren.FlashinessSequence; destinationSiren.RotationSequence = sourceSiren.RotationSequence; destinationSiren.FlashinessMultiples = sourceSiren.FlashinessMultiples; destinationSiren.RotationMultiples = sourceSiren.RotationMultiples; } if (DeltasCheckbox.Checked) { Game.LogTrivial(" Copying flashiness and rotation deltas"); destinationSiren.FlashinessDelta = sourceSiren.FlashinessDelta; destinationSiren.RotationDelta = sourceSiren.RotationDelta; } if (FlashinessCheckbox.Checked) { // All flashiness settings except for sequences, multiples, deltas Game.LogTrivial(" Copying flash toggle and flashiness direction, speed, start, sync to bpm, scale, and scale factor"); destinationSiren.Flash = sourceSiren.Flash; destinationSiren.FlashinessDirection = sourceSiren.FlashinessDirection; destinationSiren.FlashinessSpeed = sourceSiren.FlashinessSpeed; destinationSiren.FlashinessStart = sourceSiren.FlashinessStart; destinationSiren.FlashinessSynchronizeToBpm = sourceSiren.FlashinessSynchronizeToBpm; destinationSiren.Scale = sourceSiren.Scale; destinationSiren.ScaleFactor = sourceSiren.ScaleFactor; } if (RotationCheckbox.Checked) { // All rotation settings except for sequences, multiples, deltas Game.LogTrivial(" Copying rotation toggle and rotation direction, speed, start, and sync to bpm"); destinationSiren.Rotate = sourceSiren.Rotate; destinationSiren.RotationDirection = sourceSiren.RotationDirection; destinationSiren.RotationSpeed = sourceSiren.RotationSpeed; destinationSiren.RotationStart = sourceSiren.RotationStart; destinationSiren.RotationSynchronizeToBpm = sourceSiren.RotationSynchronizeToBpm; } if (EnvLightingCheckbox.Checked) { // All env lighting except color/corona Game.LogTrivial(" Copying siren-specific environmental lighting"); destinationSiren.Light = sourceSiren.Light; destinationSiren.Intensity = sourceSiren.Intensity; destinationSiren.SpotLight = sourceSiren.SpotLight; destinationSiren.CastShadows = sourceSiren.CastShadows; } if (CoronaCheckbox.Checked) { // All corona settings except color Game.LogTrivial(" Copying corona settings"); destinationSiren.CoronaFaceCamera = sourceSiren.CoronaFaceCamera; destinationSiren.CoronaIntensity = sourceSiren.CoronaIntensity; destinationSiren.CoronaPull = sourceSiren.CoronaPull; destinationSiren.CoronaSize = sourceSiren.CoronaSize; } if (ColorCheckbox.Checked) { Game.LogTrivial(" Copying siren color"); destinationSiren.Color = sourceSiren.Color; } } } Game.LogTrivial(" Copying general siren settings"); if (settingCopyAll) { Game.LogTrivial(" Copying all non-siren-specific settings"); foreach (PropertyInfo property in source.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.GetProperty | BindingFlags.SetProperty)) { property.SetValue(destination, property.GetValue(source)); Game.LogTrivialDebug($" {property.Name}"); } } else { if (SettingEnvCheckbox.Checked) { // General env settings (not siren specific) Game.LogTrivial(" Copying general environmental lighting settings including texture hash, falloff, cone angle, and real lights"); destination.TextureHash = source.TextureHash; destination.LightFalloffMax = source.LightFalloffMax; destination.LightFalloffExponent = source.LightFalloffExponent; destination.LightInnerConeAngle = source.LightInnerConeAngle; destination.LightOuterConeAngle = source.LightOuterConeAngle; destination.UseRealLights = source.UseRealLights; } if (SettingSpeedCheckbox.Checked) { // General bpm/multiplier Game.LogTrivial(" Copying BPM and time multiplier"); destination.SequencerBpm = source.SequencerBpm; destination.TimeMultiplier = source.TimeMultiplier; } if (HeadTailCheckbox.Checked) { Game.LogTrivial(" Copying headlight and taillight sequences and multiples"); destination.LeftHeadLightMultiples = source.LeftHeadLightMultiples; destination.RightHeadLightMultiples = source.RightHeadLightMultiples; destination.LeftTailLightMultiples = source.LeftTailLightMultiples; destination.RightTailLightMultiples = source.RightTailLightMultiples; destination.LeftHeadLightSequence = source.LeftHeadLightSequence; destination.RightHeadLightSequence = source.RightHeadLightSequence; destination.LeftTailLightSequence = source.LeftTailLightSequence; destination.RightTailLightSequence = source.RightTailLightSequence; } } // After copying, refresh menus to reflect potentially updated data ParentMenu.Menu.RefreshData(); string info = $"FROM: ~g~{source.Name}~w~"; if (SourceSiren != -1) { info += $", Siren ~b~{SourceSiren}"; } info += $"~w~\n\nTO: ~g~{destination.Name}~w~, Sirens ~b~"; info += string.Join(", ", DestinationSirens); info += "~w~.\n\nCheck log/console for additional details."; Game.DisplayNotification("desktop_pc", "folder", "Copied Siren Settings", "", info); } else { Game.DisplayNotification("~y~Unable to copy settings~w~, check that target is selected and destination is editable"); Game.LogTrivial($"Source valid: {source.Exists()}, Destination valid: {destination.Exists()}, Destination editable: {destination.IsCustomSetting()}"); } }
public static void ApplySirenSettingsToEmergencyLighting(SirenSetting setting, EmergencyLighting els) { els.TimeMultiplier = setting.TimeMultiplier; els.LightFalloffMax = setting.LightFalloffMax; els.LightFalloffExponent = setting.LightFalloffExponent; els.LightInnerConeAngle = setting.LightInnerConeAngle; els.LightOuterConeAngle = setting.LightOuterConeAngle; els.LightOffset = setting.LightOffset; els.TextureHash = setting.TextureHash; els.SequencerBpm = setting.SequencerBPM; els.UseRealLights = setting.UseRealLights; els.LeftHeadLightSequence = setting.LeftHeadLightSequencer; els.LeftHeadLightMultiples = setting.LeftHeadLightMultiples; els.RightHeadLightSequence = setting.RightHeadLightSequencer; els.RightHeadLightMultiples = setting.RightHeadLightMultiples; els.LeftTailLightSequence = setting.LeftTailLightSequencer; els.LeftTailLightMultiples = setting.LeftTailLightMultiples; els.RightTailLightSequence = setting.RightTailLightSequencer; els.RightTailLightMultiples = setting.RightTailLightMultiples; for (int i = 0; i < setting.Sirens.Length; i++) { SirenEntry entry = setting.Sirens[i]; EmergencyLight light = els.Lights[i]; // Main light settings light.Color = entry.LightColor; light.Intensity = entry.Intensity; light.LightGroup = entry.LightGroup; light.Rotate = entry.Rotate; light.Scale = entry.Scale; light.ScaleFactor = entry.ScaleFactor; light.Flash = entry.Flash; light.SpotLight = entry.SpotLight; light.CastShadows = entry.CastShadows; light.Light = entry.Light; // Corona settings light.CoronaIntensity = entry.Corona.CoronaIntensity; light.CoronaSize = entry.Corona.CoronaSize; light.CoronaPull = entry.Corona.CoronaPull; light.CoronaFaceCamera = entry.Corona.CoronaFaceCamera; // Rotation settings light.RotationDelta = entry.Rotation.DeltaDeg; light.RotationStart = entry.Rotation.StartDeg; light.RotationSpeed = entry.Rotation.Speed; light.RotationSequence = entry.Rotation.Sequence; light.RotationMultiples = entry.Rotation.Multiples; light.RotationDirection = entry.Rotation.Direction; light.RotationSynchronizeToBpm = entry.Rotation.SyncToBPM; // Flash settings light.FlashinessDelta = entry.Flashiness.DeltaDeg; light.FlashinessStart = entry.Flashiness.StartDeg; light.FlashinessSpeed = entry.Flashiness.Speed; light.FlashinessSequenceRaw = entry.Flashiness.Sequence; light.FlashinessMultiples = entry.Flashiness.Multiples; light.FlashinessDirection = entry.Flashiness.Direction; light.FlashinessSynchronizeToBpm = entry.Flashiness.SyncToBPM; } }