1
Fork 0
mirror of https://github.com/thegeneralist01/Scene-Manager-DevRepo synced 2026-01-12 08:00:30 +01:00

Refactored to implement RNUIMouseInputHandler class.

This commit is contained in:
Rich Dunne 2020-11-08 11:15:15 -07:00
parent f0af9b6207
commit 467ca54c39
7 changed files with 431 additions and 1031 deletions

View file

@ -1,7 +1,6 @@
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Windows.Forms;
using Rage;
using RAGENativeUI;
using RAGENativeUI.Elements;
@ -10,13 +9,18 @@ namespace SceneManager
{
class BarrierMenu
{
private static List<TrafficLight> trafficLightList = new List<TrafficLight>() { TrafficLight.Green, TrafficLight.Red, TrafficLight.Yellow, TrafficLight.None };
internal static UIMenu barrierMenu = new UIMenu("Scene Manager", "~o~Barrier Management");
internal static List<Barrier> barriers = new List<Barrier>();
private static UIMenuListScrollerItem<string> barrierList = new UIMenuListScrollerItem<string>("Spawn Barrier", "", Settings.barrierKeys);
private static UIMenuNumericScrollerItem<int> rotateBarrier = new UIMenuNumericScrollerItem<int>("Rotate Barrier", "", 0, 350, 10);
private static UIMenuCheckboxItem invincible = new UIMenuCheckboxItem("Indestructible", false);
private static UIMenuNumericScrollerItem<int> barrierTexture = new UIMenuNumericScrollerItem<int>("Change Texture", "", 0, 15, 1);
private static UIMenuCheckboxItem setBarrierLights = new UIMenuCheckboxItem("Enable Barrier Lights", false);
private static UIMenuListScrollerItem<TrafficLight> setBarrierTrafficLight = new UIMenuListScrollerItem<TrafficLight>("Set Barrier Traffic Light", "", trafficLightList);
private static UIMenuListScrollerItem<string> removeBarrierOptions = new UIMenuListScrollerItem<string>("Remove Barrier", "", new[] { "Last Barrier", "Nearest Barrier", "All Barriers" });
private static UIMenuItem resetBarriers = new UIMenuItem("Reset Barriers", "Reset all spawned barriers to their original position and rotation");
internal static Rage.Object shadowBarrier;
internal static Object shadowBarrier;
internal static void InstantiateMenu()
{
@ -24,89 +28,133 @@ namespace SceneManager
MenuManager.menuPool.Add(barrierMenu);
barrierMenu.OnItemSelect += BarrierMenu_OnItemSelected;
barrierMenu.OnScrollerChange += BarrierMenu_OnScrollerChange;
barrierMenu.OnMenuOpen += BarrierMenu_OnMouseDown;
barrierMenu.OnScrollerChange += BarrierMenu_OnScrollerChanged;
barrierMenu.OnCheckboxChange += BarrierMenu_OnCheckboxChanged;
barrierMenu.OnMenuOpen += BarrierMenu_OnMenuOpen;
}
internal static void BuildBarrierMenu()
{
barrierMenu.AddItem(resetBarriers);
resetBarriers.ForeColor = Color.Gold;
resetBarriers.Enabled = false;
barrierMenu.AddItem(barrierList);
barrierList.ForeColor = Color.Gold;
barrierMenu.AddItem(removeBarrierOptions, 0);
barrierMenu.AddItem(rotateBarrier);
barrierMenu.AddItem(invincible);
if (Settings.EnableAdvancedBarricadeOptions)
{
barrierMenu.AddItem(barrierTexture);
barrierTexture.Index = 0;
barrierMenu.AddItem(setBarrierLights);
barrierMenu.AddItem(setBarrierTrafficLight);
setBarrierTrafficLight.Index = 3;
}
barrierMenu.AddItem(removeBarrierOptions);
removeBarrierOptions.ForeColor = Color.Gold;
removeBarrierOptions.Enabled = false;
barrierMenu.AddItem(rotateBarrier, 0);
barrierMenu.AddItem(barrierList, 0);
barrierList.ForeColor = Color.Gold;
barrierMenu.AddItem(resetBarriers);
resetBarriers.ForeColor = Color.Gold;
resetBarriers.Enabled = false;
}
internal static void CreateShadowBarrier(UIMenu barrierMenu)
internal static void CreateShadowBarrier()
{
Hints.Display($"~o~Scene Manager ~y~[Hint]\n~w~The shadow cone will disappear if you aim too far away.");
if (shadowBarrier)
{
shadowBarrier.Delete();
}
shadowBarrier = new Object(Settings.barrierValues[barrierList.Index], GetMousePositionInWorld(), rotateBarrier.Value);
shadowBarrier = new Object(Settings.barrierValues[barrierList.Index], MousePositionInWorld.GetPosition, rotateBarrier.Value);
if (!shadowBarrier)
{
barrierMenu.Close();
Game.DisplayNotification($"~o~Scene Manager ~r~[Error]\n~w~Something went wrong creating the shadow barrier. Please try again.");
return;
}
Rage.Native.NativeFunction.Natives.SET_ENTITY_TRAFFICLIGHT_OVERRIDE(shadowBarrier, setBarrierTrafficLight.Index);
Rage.Native.NativeFunction.Natives.PLACE_OBJECT_ON_GROUND_PROPERLY(shadowBarrier);
shadowBarrier.IsGravityDisabled = true;
shadowBarrier.IsCollisionEnabled = false;
shadowBarrier.Opacity = 0.7f;
GameFiber ShadowConeLoopFiber = new GameFiber(() => LoopToDisplayShadowBarrier());
ShadowConeLoopFiber.Start();
void LoopToDisplayShadowBarrier()
// Start with lights off for Parks's objects
if (Settings.EnableAdvancedBarricadeOptions)
{
while (barrierMenu.Visible && shadowBarrier)
Rage.Native.NativeFunction.Natives.x971DA0055324D033(shadowBarrier, barrierTexture.Value);
SetBarrierLights();
}
}
private static void LoopToDisplayShadowBarrier()
{
while (barrierMenu.Visible)
{
if (barrierList.Selected || rotateBarrier.Selected || invincible.Selected || barrierTexture.Selected || setBarrierLights.Selected || setBarrierTrafficLight.Selected)
{
if (barrierList.Selected || rotateBarrier.Selected)
if (shadowBarrier)
{
shadowBarrier.IsVisible = true;
UpdateShadowBarrierPosition();
}
else if(MousePositionInWorld.GetPositionForBarrier.DistanceTo2D(Game.LocalPlayer.Character.Position) <= Settings.BarrierPlacementDistance)
{
CreateShadowBarrier();
}
}
else
{
if (shadowBarrier)
{
shadowBarrier.Delete();
}
}
GameFiber.Yield();
}
if (shadowBarrier)
{
shadowBarrier.Delete();
}
void UpdateShadowBarrierPosition()
{
DisableBarrierMenuOptionsIfShadowConeTooFar();
if (shadowBarrier)
{
shadowBarrier.Delete();
CreateShadowBarrier();
//shadowBarrier.Heading = rotateBarrier.Value;
//shadowBarrier.Position = MousePositionInWorld.GetPositionForBarrier;
//Rage.Native.NativeFunction.Natives.PLACE_OBJECT_ON_GROUND_PROPERLY(shadowBarrier);
//Rage.Native.NativeFunction.Natives.SET_ENTITY_TRAFFICLIGHT_OVERRIDE(shadowBarrier, setBarrierTrafficLight.Index);
}
void DisableBarrierMenuOptionsIfShadowConeTooFar()
{
if (!shadowBarrier && MousePositionInWorld.GetPositionForBarrier.DistanceTo2D(Game.LocalPlayer.Character.Position) <= Settings.BarrierPlacementDistance)
{
CreateShadowBarrier();
}
else if (shadowBarrier && shadowBarrier.Position.DistanceTo2D(Game.LocalPlayer.Character.Position) > Settings.BarrierPlacementDistance)
{
barrierList.Enabled = false;
rotateBarrier.Enabled = false;
shadowBarrier.Delete();
}
else if (shadowBarrier && shadowBarrier.Position.DistanceTo2D(Game.LocalPlayer.Character.Position) <= Settings.BarrierPlacementDistance && barrierList.SelectedItem == "Flare")
{
barrierList.Enabled = true;
rotateBarrier.Enabled = false;
}
else
{
shadowBarrier.IsVisible = false;
}
GameFiber.Yield();
}
if (shadowBarrier)
shadowBarrier.Delete();
void UpdateShadowBarrierPosition()
{
DisableBarrierMenuOptionsIfShadowConeTooFar();
shadowBarrier.SetPositionWithSnap(GetMousePositionInWorld());
void DisableBarrierMenuOptionsIfShadowConeTooFar()
{
if (shadowBarrier.Position.DistanceTo2D(Game.LocalPlayer.Character.Position) > Settings.BarrierPlacementDistance)
{
barrierList.Enabled = false;
rotateBarrier.Enabled = false;
}
else if (shadowBarrier.Position.DistanceTo2D(Game.LocalPlayer.Character.Position) <= Settings.BarrierPlacementDistance && barrierList.SelectedItem == "Flare")
{
barrierList.Enabled = true;
rotateBarrier.Enabled = false;
}
else
{
barrierList.Enabled = true;
rotateBarrier.Enabled = true;
}
barrierList.Enabled = true;
rotateBarrier.Enabled = true;
}
}
}
@ -114,39 +162,79 @@ namespace SceneManager
private static void SpawnBarrier()
{
var barrier = new Rage.Object(shadowBarrier.Model, shadowBarrier.Position, rotateBarrier.Value);
barrier.SetPositionWithSnap(shadowBarrier.Position);
Rage.Native.NativeFunction.Natives.SET_ENTITY_DYNAMIC(barrier, true);
barrier.IsPositionFrozen = false;
Rage.Native.NativeFunction.Natives.SET_DISABLE_FRAG_DAMAGE(barrier, true);
barriers.Add(new Barrier(barrier, barrier.Position, barrier.Heading));
removeBarrierOptions.Enabled = true;
resetBarriers.Enabled = true;
}
private static void SpawnFlare()
{
var flare = new Weapon("weapon_flare", shadowBarrier.Position, 1);
Rage.Native.NativeFunction.Natives.SET_ENTITY_DYNAMIC(flare, true);
GameFiber.StartNew(() =>
if(barrierList.SelectedItem == "Flare")
{
while (flare && flare.HeightAboveGround > 0.05f)
SpawnFlare();
}
else
{
var barrier = new Object(shadowBarrier.Model, shadowBarrier.Position, rotateBarrier.Value);
barrier.SetPositionWithSnap(shadowBarrier.Position);
Rage.Native.NativeFunction.Natives.SET_ENTITY_DYNAMIC(barrier, true);
barrier.IsPositionFrozen = false;
if (invincible.Checked)
{
GameFiber.Yield();
Rage.Native.NativeFunction.Natives.SET_DISABLE_FRAG_DAMAGE(barrier, true);
if(barrier.Model.Name != "prop_barrier_wat_03a")
{
Rage.Native.NativeFunction.Natives.SET_DISABLE_BREAKING(barrier, true);
}
}
GameFiber.Sleep(1000);
if (flare)
if (Settings.EnableAdvancedBarricadeOptions)
{
flare.IsPositionFrozen = true;
}
});
Rage.Native.NativeFunction.Natives.x971DA0055324D033(barrier, barrierTexture.Value);
if (setBarrierLights.Checked)
{
Rage.Native.NativeFunction.Natives.SET_ENTITY_LIGHTS(barrier, false);
}
else
{
Rage.Native.NativeFunction.Natives.SET_ENTITY_LIGHTS(barrier, true);
}
barriers.Add(new Barrier(flare, flare.Position, flare.Heading));
removeBarrierOptions.Enabled = true;
Rage.Native.NativeFunction.Natives.SET_ENTITY_TRAFFICLIGHT_OVERRIDE(barrier, setBarrierTrafficLight.Index);
barrier.IsPositionFrozen = true;
GameFiber.Sleep(50);
if (barrier)
{
barrier.IsPositionFrozen = false;
}
}
barriers.Add(new Barrier(barrier, barrier.Position, barrier.Heading));
removeBarrierOptions.Enabled = true;
resetBarriers.Enabled = true;
}
void SpawnFlare()
{
var flare = new Weapon("weapon_flare", shadowBarrier.Position, 1);
Rage.Native.NativeFunction.Natives.SET_ENTITY_DYNAMIC(flare, true);
GameFiber.Sleep(1);
GameFiber.StartNew(() =>
{
while (flare && flare.HeightAboveGround > 0.05f)
{
GameFiber.Yield();
}
GameFiber.Sleep(1000);
if (flare)
{
flare.IsPositionFrozen = true;
}
});
barriers.Add(new Barrier(flare, flare.Position, flare.Heading));
removeBarrierOptions.Enabled = true;
}
}
internal static void RotateBarrier()
{
shadowBarrier.Heading = rotateBarrier.Value;
shadowBarrier.Position = MousePositionInWorld.GetPositionForBarrier;
Rage.Native.NativeFunction.Natives.PLACE_OBJECT_ON_GROUND_PROPERLY(shadowBarrier);
}
private static void RemoveBarrier()
{
switch (removeBarrierOptions.Index)
@ -189,6 +277,13 @@ namespace SceneManager
Rage.Native.NativeFunction.Natives.SET_ENTITY_DYNAMIC(newBarrier, true);
newBarrier.IsPositionFrozen = false;
Rage.Native.NativeFunction.Natives.SET_DISABLE_FRAG_DAMAGE(newBarrier, true);
Rage.Native.NativeFunction.Natives.SET_ENTITY_TRAFFICLIGHT_OVERRIDE(newBarrier, setBarrierTrafficLight.Index);
newBarrier.IsPositionFrozen = true;
GameFiber.Sleep(50);
if (newBarrier)
{
newBarrier.IsPositionFrozen = false;
}
barriers.Add(new Barrier(newBarrier, newBarrier.Position, newBarrier.Heading));
@ -201,11 +296,37 @@ namespace SceneManager
currentBarriers.Clear();
}
private static void BarrierMenu_OnScrollerChange(UIMenu sender, UIMenuScrollerItem scrollerItem, int oldIndex, int newIndex)
private static void SetBarrierLights()
{
if (setBarrierLights.Checked)
{
Rage.Native.NativeFunction.Natives.SET_ENTITY_LIGHTS(shadowBarrier, false);
}
else
{
Rage.Native.NativeFunction.Natives.SET_ENTITY_LIGHTS(shadowBarrier, true);
}
Rage.Native.NativeFunction.Natives.SET_ENTITY_TRAFFICLIGHT_OVERRIDE(shadowBarrier, setBarrierTrafficLight.Index);
}
private static void BarrierMenu_OnCheckboxChanged(UIMenu sender, UIMenuCheckboxItem checkbox, bool @checked)
{
if(checkbox == setBarrierLights)
{
SetBarrierLights();
}
}
private static void BarrierMenu_OnScrollerChanged(UIMenu sender, UIMenuScrollerItem scrollerItem, int oldIndex, int newIndex)
{
if (scrollerItem == barrierList)
{
CreateShadowBarrier(barrierMenu);
if (shadowBarrier)
{
shadowBarrier.Delete();
}
barrierTexture.Index = 0;
if(barrierList.SelectedItem == "Flare")
{
@ -219,9 +340,19 @@ namespace SceneManager
barrierMenu.Width = SetMenuWidth();
}
if (scrollerItem == barrierTexture)
{
Rage.Native.NativeFunction.Natives.x971DA0055324D033(shadowBarrier, barrierTexture.Value);
}
if (scrollerItem == setBarrierTrafficLight)
{
Rage.Native.NativeFunction.Natives.SET_ENTITY_TRAFFICLIGHT_OVERRIDE(shadowBarrier, setBarrierTrafficLight.Index);
}
if (scrollerItem == rotateBarrier)
{
shadowBarrier.Heading = rotateBarrier.Value;
RotateBarrier();
}
}
@ -229,17 +360,7 @@ namespace SceneManager
{
if (selectedItem == barrierList)
{
// Attach some invisible object to the cone which the AI try to drive around
// Barrier rotates with cone and becomes invisible similar to ASC when created
if(barrierList.SelectedItem == "Flare")
{
SpawnFlare();
}
else
{
SpawnBarrier();
}
SpawnBarrier();
}
if (selectedItem == removeBarrierOptions)
@ -253,166 +374,27 @@ namespace SceneManager
}
}
private static void BarrierMenu_OnMouseDown(UIMenu menu)
private static void BarrierMenu_OnMenuOpen(UIMenu menu)
{
GameFiber.StartNew(() =>
var scrollerItems = new List<UIMenuScrollerItem> { barrierList, barrierTexture, setBarrierTrafficLight, rotateBarrier, removeBarrierOptions };
var checkboxItems = new Dictionary<UIMenuCheckboxItem, RNUIMouseInputHandler.Function>() { { invincible, null }, {setBarrierLights, SetBarrierLights} };
var selectItems = new Dictionary<UIMenuItem, RNUIMouseInputHandler.Function>()
{
while (menu.Visible)
{
var selectedScroller = menu.MenuItems.Where(x => (x == barrierList || x == rotateBarrier || x == removeBarrierOptions) && x.Selected).FirstOrDefault();
if (selectedScroller != null)
{
HandleScrollerItemsWithMouseWheel(selectedScroller);
}
{ barrierList, SpawnBarrier },
{ removeBarrierOptions, RemoveBarrier },
{ resetBarriers, ResetBarriers },
};
// Add waypoint if menu item is selected and user left clicks
if (Game.IsKeyDown(Keys.LButton))
{
OnMenuItemClicked();
}
GameFiber.Yield();
}
});
Hints.Display($"~o~Scene Manager ~y~[Hint]\n~w~The shadow barrier will disappear if you aim too far away.");
CreateShadowBarrier();
void OnMenuItemClicked()
{
if (barrierList.Selected)
{
if (barrierList.SelectedItem == "Flare")
{
SpawnFlare();
}
else
{
SpawnBarrier();
}
}
else if (removeBarrierOptions.Selected)
{
RemoveBarrier();
}
else if (resetBarriers.Selected)
{
ResetBarriers();
}
}
GameFiber ShadowConeLoopFiber = new GameFiber(() => LoopToDisplayShadowBarrier());
ShadowConeLoopFiber.Start();
void HandleScrollerItemsWithMouseWheel(UIMenuItem selectedScroller)
{
var menuScrollingDisabled = false;
var menuItems = menu.MenuItems.Where(x => x != selectedScroller);
while (Game.IsShiftKeyDownRightNow)
{
menu.ResetKey(Common.MenuControls.Up);
menu.ResetKey(Common.MenuControls.Down);
menuScrollingDisabled = true;
ScrollMenuItem();
GameFiber.Yield();
}
if (menuScrollingDisabled)
{
menuScrollingDisabled = false;
menu.SetKey(Common.MenuControls.Up, GameControl.CursorScrollUp);
menu.SetKey(Common.MenuControls.Up, GameControl.CellphoneUp);
menu.SetKey(Common.MenuControls.Down, GameControl.CursorScrollDown);
menu.SetKey(Common.MenuControls.Down, GameControl.CellphoneDown);
}
void ScrollMenuItem()
{
if (Game.GetMouseWheelDelta() > 0)
{
if (selectedScroller == barrierList)
{
barrierList.ScrollToNextOption();
CreateShadowBarrier(barrierMenu);
if (barrierList.SelectedItem == "Flare")
{
rotateBarrier.Enabled = false;
}
else
{
rotateBarrier.Enabled = true;
}
barrierMenu.Width = SetMenuWidth();
}
else if (selectedScroller == rotateBarrier)
{
rotateBarrier.ScrollToNextOption();
shadowBarrier.Heading = rotateBarrier.Value;
}
else if (selectedScroller == removeBarrierOptions)
{
removeBarrierOptions.ScrollToNextOption();
}
}
else if (Game.GetMouseWheelDelta() < 0)
{
if (selectedScroller == barrierList)
{
barrierList.ScrollToPreviousOption();
CreateShadowBarrier(barrierMenu);
if (barrierList.SelectedItem == "Flare")
{
rotateBarrier.Enabled = false;
}
else
{
rotateBarrier.Enabled = true;
}
barrierMenu.Width = SetMenuWidth();
}
else if (selectedScroller == rotateBarrier)
{
rotateBarrier.ScrollToPreviousOption();
shadowBarrier.Heading = rotateBarrier.Value;
}
else if(selectedScroller == removeBarrierOptions)
{
removeBarrierOptions.ScrollToPreviousOption();
}
}
}
}
RNUIMouseInputHandler.Initialize(menu, scrollerItems, checkboxItems, selectItems);
}
private static Vector3 GetMousePositionInWorld()
{
HitResult TracePlayerView(float maxTraceDistance = 30f, TraceFlags flags = TraceFlags.IntersectWorld) => TracePlayerView2(out Vector3 v1, out Vector3 v2, maxTraceDistance, flags);
HitResult TracePlayerView2(out Vector3 start, out Vector3 end, float maxTraceDistance, TraceFlags flags)
{
Vector3 direction = GetPlayerLookingDirection(out start);
end = start + (maxTraceDistance * direction);
return World.TraceLine(start, end, flags);
}
Vector3 GetPlayerLookingDirection(out Vector3 camPosition)
{
if (Camera.RenderingCamera)
{
camPosition = Camera.RenderingCamera.Position;
return Camera.RenderingCamera.Direction;
}
else
{
float pitch = Rage.Native.NativeFunction.Natives.GET_GAMEPLAY_CAM_RELATIVE_PITCH<float>();
float heading = Rage.Native.NativeFunction.Natives.GET_GAMEPLAY_CAM_RELATIVE_HEADING<float>();
camPosition = Rage.Native.NativeFunction.Natives.GET_GAMEPLAY_CAM_COORD<Vector3>();
return (Game.LocalPlayer.Character.Rotation + new Rotator(pitch, 0, heading)).ToVector().ToNormalized();
}
}
return TracePlayerView(Settings.BarrierPlacementDistance, TraceFlags.IntersectWorld).HitPosition;
}
private static float SetMenuWidth()
internal static float SetMenuWidth()
{
float defaultWidth = UIMenu.DefaultWidth;
float width = barrierMenu.Width;