...@@ -7,6 +7,7 @@ namespace RopeCreator ...@@ -7,6 +7,7 @@ namespace RopeCreator
{ {
class AttachedRope class AttachedRope
{ {
internal RopeGroup group;
internal Rope rope; internal Rope rope;
internal Entity firstEntity, secondEntity; internal Entity firstEntity, secondEntity;
internal Vector3 firstOffset, secondOffset; internal Vector3 firstOffset, secondOffset;
...@@ -55,6 +56,7 @@ namespace RopeCreator ...@@ -55,6 +56,7 @@ namespace RopeCreator
rope.AttachEntities(firstEntity, firstPos, secondEntity, secondPos, distance); rope.AttachEntities(firstEntity, firstPos, secondEntity, secondPos, distance);
rope.ActivatePhysics(); rope.ActivatePhysics();
this.group = RopeCreator.ropeGroups[Menu.liGroupIndex.SelectedIndex];
this.rope = rope; this.rope = rope;
this.firstEntity = firstEntity; this.firstEntity = firstEntity;
this.firstOffset = firstEntity.GetOffsetFromWorldCoords(firstPos); this.firstOffset = firstEntity.GetOffsetFromWorldCoords(firstPos);
......
using GTA; using GTA;
using GTA.Math; using GTA.Math;
using NativeUI; using LemonUI.Menus;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Windows.Forms; using System.Windows.Forms;
...@@ -39,43 +39,43 @@ namespace RopeCreator ...@@ -39,43 +39,43 @@ namespace RopeCreator
bool attachToPedBone = settingsFile.GetValue("Rope", "DefaultAttachToPedBone", false); bool attachToPedBone = settingsFile.GetValue("Rope", "DefaultAttachToPedBone", false);
Menu.modEnabled = enabled; Menu.modEnabled = enabled;
if (Menu.cbEnabled != default(UIMenuCheckboxItem)) if (Menu.cbEnabled != default(NativeCheckboxItem))
{ {
Menu.cbEnabled.Checked = enabled; Menu.cbEnabled.Checked = enabled;
} }
Menu.showAimMarker = showAimMarker; Menu.showAimMarker = showAimMarker;
if (Menu.cbShowAimMarker != default(UIMenuCheckboxItem)) if (Menu.cbShowAimMarker != default(NativeCheckboxItem))
{ {
Menu.cbShowAimMarker.Checked = showAimMarker; Menu.cbShowAimMarker.Checked = showAimMarker;
} }
Menu.showEditMarkers = showEditMarkers; Menu.showEditMarkers = showEditMarkers;
if (Menu.cbShowEditMarkers != default(UIMenuCheckboxItem)) if (Menu.cbShowEditMarkers != default(NativeCheckboxItem))
{ {
Menu.cbShowEditMarkers.Checked = showEditMarkers; Menu.cbShowEditMarkers.Checked = showEditMarkers;
} }
Menu.type = ropeType; Menu.type = ropeType;
if (Menu.liRopeIndex != default(UIMenuListItem)) if (Menu.liRopeIndex != default(NativeListItem<int>))
{ {
Menu.liRopeIndex.Index = ropeType - 1; Menu.liRopeIndex.SelectedIndex = ropeType - 1;
} }
Menu.breakable = breakable; Menu.breakable = breakable;
if (Menu.cbBreakable != default(UIMenuCheckboxItem)) if (Menu.cbBreakable != default(NativeCheckboxItem))
{ {
Menu.cbBreakable.Checked = breakable; Menu.cbBreakable.Checked = breakable;
} }
Menu.attachObjBone = attachToObjBone; Menu.attachObjBone = attachToObjBone;
if (Menu.cbAttachObjBone != default(UIMenuCheckboxItem)) if (Menu.cbAttachObjBone != default(NativeCheckboxItem))
{ {
Menu.cbAttachObjBone.Checked = attachToObjBone; Menu.cbAttachObjBone.Checked = attachToObjBone;
} }
Menu.attachPedBone = attachToPedBone; Menu.attachPedBone = attachToPedBone;
if (Menu.cbAttachPedBone != default(UIMenuCheckboxItem)) if (Menu.cbAttachPedBone != default(NativeCheckboxItem))
{ {
Menu.cbAttachPedBone.Checked = attachToPedBone; Menu.cbAttachPedBone.Checked = attachToPedBone;
} }
......
using GTA; using GTA;
using GTA.Math; using GTA.Math;
using System; using System;
using System.Collections.Generic;
using System.Drawing; using System.Drawing;
namespace RopeCreator namespace RopeCreator
...@@ -10,7 +11,7 @@ namespace RopeCreator ...@@ -10,7 +11,7 @@ namespace RopeCreator
readonly Vector3 aimMarkerScale = new Vector3(0.05f, 0.05f, 0.05f), ropeMarkerScale = new Vector3(0.2f, 0.2f, 0.2f); readonly Vector3 aimMarkerScale = new Vector3(0.05f, 0.05f, 0.05f), ropeMarkerScale = new Vector3(0.2f, 0.2f, 0.2f);
Vector3 aimMarkerPos = Vector3.Zero; Vector3 aimMarkerPos = Vector3.Zero;
Vector3 ropeMarker1Pos = Vector3.Zero, ropeMarker2Pos = Vector3.Zero; List<Vector3> ropeMarkerPositions = new List<Vector3>();
int nextGetMarkerPos = 0; int nextGetMarkerPos = 0;
...@@ -32,20 +33,39 @@ namespace RopeCreator ...@@ -32,20 +33,39 @@ namespace RopeCreator
private void GetEditRopeMarkerPos() private void GetEditRopeMarkerPos()
{ {
if (Menu.showEditMarkers && Menu.editRopeMenu.Visible) ropeMarkerPositions.Clear();
{
int selectedRopeIndex = (int)Menu.liRopeIndex.Items[Menu.liRopeIndex.Index];
if (selectedRopeIndex > -1) if (Menu.showEditMarkers)
{
if ((Menu.mainMenu.Visible && Menu.mainMenu.SelectedItem == Menu.liGroupIndex) || Menu.editGroupMenu.Visible || Menu.editRopeMenu.Visible)
{ {
var selectedRope = RopeCreator.ropes[selectedRopeIndex]; var group = RopeCreator.ropeGroups[Menu.liGroupIndex.SelectedIndex];
if ((Menu.mainMenu.Visible && Menu.mainMenu.SelectedItem == Menu.liGroupIndex) || Menu.editGroupMenu.Visible)
{
if (group.ropes.Count > 0)
{
foreach (var rope in group.ropes)
{
ropeMarkerPositions.Add(rope.firstEntity.GetOffsetInWorldCoords(rope.firstOffset));
ropeMarkerPositions.Add(rope.secondEntity.GetOffsetInWorldCoords(rope.secondOffset));
}
}
}
else
{
int selectedRopeIndex = Menu.liRopeIndex.SelectedItem;
ropeMarker1Pos = selectedRope.firstEntity.GetOffsetInWorldCoords(selectedRope.firstOffset); if (selectedRopeIndex > -1)
ropeMarker2Pos = selectedRope.secondEntity.GetOffsetInWorldCoords(selectedRope.secondOffset); {
var selectedRope = group.ropes[selectedRopeIndex];
ropeMarkerPositions.Add(selectedRope.firstEntity.GetOffsetInWorldCoords(selectedRope.firstOffset));
ropeMarkerPositions.Add(selectedRope.secondEntity.GetOffsetInWorldCoords(selectedRope.secondOffset));
}
}
} }
else ropeMarker1Pos = ropeMarker2Pos = Vector3.Zero;
} }
else ropeMarker1Pos = ropeMarker2Pos = Vector3.Zero;
} }
private void GetAllMarkerPos() private void GetAllMarkerPos()
...@@ -58,7 +78,7 @@ namespace RopeCreator ...@@ -58,7 +78,7 @@ namespace RopeCreator
nextGetMarkerPos = Game.GameTime + 10; nextGetMarkerPos = Game.GameTime + 10;
} }
} }
private void DrawMarkers() private void DrawMarkers()
{ {
if (Game.IsScreenFadedIn && Game.Player.CanControlCharacter && Menu.modEnabled) if (Game.IsScreenFadedIn && Game.Player.CanControlCharacter && Menu.modEnabled)
...@@ -68,10 +88,12 @@ namespace RopeCreator ...@@ -68,10 +88,12 @@ namespace RopeCreator
World.DrawMarker(MarkerType.DebugSphere, aimMarkerPos, Vector3.Zero, Vector3.Zero, aimMarkerScale, Color.Blue); World.DrawMarker(MarkerType.DebugSphere, aimMarkerPos, Vector3.Zero, Vector3.Zero, aimMarkerScale, Color.Blue);
} }
if (Menu.showEditMarkers && ropeMarker1Pos != Vector3.Zero && ropeMarker2Pos != Vector3.Zero) if (Menu.showEditMarkers && ropeMarkerPositions.Count > 0)
{ {
World.DrawMarker(MarkerType.DebugSphere, ropeMarker1Pos, Vector3.Zero, Vector3.Zero, ropeMarkerScale, Color.Purple); foreach (var pos in ropeMarkerPositions)
World.DrawMarker(MarkerType.DebugSphere, ropeMarker2Pos, Vector3.Zero, Vector3.Zero, ropeMarkerScale, Color.Purple); {
World.DrawMarker(MarkerType.DebugSphere, pos, Vector3.Zero, Vector3.Zero, ropeMarkerScale, Color.Purple);
}
} }
} }
} }
......
This diff is collapsed.
using GTA; using GTA;
using GTA.Math; using GTA.Math;
using System; using System;
using System.Collections.Generic;
using System.Windows.Forms; using System.Windows.Forms;
namespace RopeCreator namespace RopeCreator
{ {
public class RopeCreator : Script public class RopeCreator : Script
{ {
internal static List<AttachedRope> ropes = new List<AttachedRope>(); internal static RopeGroup[] ropeGroups = { new RopeGroup(), new RopeGroup(), new RopeGroup(), new RopeGroup(), new RopeGroup() };
int nextDeleteBadRopes = 0, nextReattachRopes = 0; int nextDeleteBadRopes = 0, nextReattachRopes = 0;
Vector3 firstPos = Vector3.Zero, firstOffset = Vector3.Zero; Vector3 firstPos = Vector3.Zero, firstOffset = Vector3.Zero;
...@@ -24,27 +23,24 @@ namespace RopeCreator ...@@ -24,27 +23,24 @@ namespace RopeCreator
Interval = 1; Interval = 1;
Tick += RopeCreator_Tick; Tick += RopeCreator_Tick;
} }
internal static void DeleteAllRopes() internal static void DeleteAllRopes()
{ {
if (ropes.Count > 0) foreach (var group in ropeGroups)
{ {
foreach (var rope in ropes) group.DeleteRopes();
{
rope.Delete();
}
ropes.Clear();
} }
} }
internal static void DeleteLastRope(bool showSubtitle = false) internal static void DeleteLastRope(bool showSubtitle = false)
{ {
if (ropes.Count > 0) var group = ropeGroups[Menu.liGroupIndex.SelectedIndex];
if (group.ropes.Count > 0)
{ {
int lastIndex = ropes.Count - 1; int lastIndex = group.ropes.Count - 1;
ropes[lastIndex].Delete(); group.ropes[lastIndex].Delete();
ropes.RemoveAt(lastIndex); group.ropes.RemoveAt(lastIndex);
UI.ShowSubtitle("Deleted last rope"); UI.ShowSubtitle("Deleted last rope");
} }
...@@ -52,71 +48,67 @@ namespace RopeCreator ...@@ -52,71 +48,67 @@ namespace RopeCreator
internal static bool AreAllRopesWinding() internal static bool AreAllRopesWinding()
{ {
if (ropes.Count == 0) return false; bool oneNotEmpty = false;
foreach (var rope in ropes) foreach (var group in ropeGroups)
{ {
if (!rope.winding) return false; if (group.ropes.Count == 0) continue; //skip empty groups
oneNotEmpty = true;
if (!group.AreAllRopesWinding()) return false;
} }
return true; //only return true if there is at least one rope
return oneNotEmpty;
} }
internal static bool AreAllRopesUnwinding() internal static bool AreAllRopesUnwinding()
{ {
if (ropes.Count == 0) return false; bool oneNotEmpty = false;
foreach (var rope in ropes) foreach (var group in ropeGroups)
{ {
if (!rope.unwinding) return false; if (group.ropes.Count == 0) continue; //skip empty groups
oneNotEmpty = true;
if (!group.AreAllRopesUnwinding()) return false;
} }
return true; //only return true if there is at least one rope
return oneNotEmpty;
} }
internal static void StartWindAllRopes() internal static void StartWindAllRopes()
{ {
if (ropes.Count > 0) foreach (var group in ropeGroups)
{ {
foreach (var rope in ropes) group.StartWindRopes();
{
rope.StopUnwind();
rope.StartWind();
}
} }
} }
internal static void StartUnwindAllRopes() internal static void StartUnwindAllRopes()
{ {
if (ropes.Count > 0) foreach (var group in ropeGroups)
{ {
foreach (var rope in ropes) group.StartUnwindRopes();
{
rope.StopWind();
rope.StartUnwind();
}
} }
} }
internal static void StopWindAllRopes() internal static void StopWindAllRopes()
{ {
if (ropes.Count > 0) foreach (var group in ropeGroups)
{ {
foreach (var rope in ropes) group.StopWindRopes();
{
rope.StopWind();
}
} }
} }
internal static void StopUnwindAllRopes() internal static void StopUnwindAllRopes()
{ {
if (ropes.Count > 0) foreach (var group in ropeGroups)
{ {
foreach (var rope in ropes) group.StopUnwindRopes();
{
rope.StopUnwind();
}
} }
} }
...@@ -124,22 +116,11 @@ namespace RopeCreator ...@@ -124,22 +116,11 @@ namespace RopeCreator
{ {
if (Game.GameTime >= nextDeleteBadRopes) if (Game.GameTime >= nextDeleteBadRopes)
{ {
if (ropes.Count > 0) foreach (var group in ropeGroups)
{ {
for (int i = 0; i < ropes.Count; i++) group.DeleteRopesWithBadEntity();
{
var rope = ropes[i];
if (rope.firstEntity == null || !rope.firstEntity.Exists() || (rope.firstEntity.Model.IsPed && rope.firstEntity.IsDead) || Yield();
rope.secondEntity == null || !rope.secondEntity.Exists() || (rope.secondEntity.Model.IsPed && rope.secondEntity.IsDead))
{
rope.Delete();
ropes.RemoveAt(i);
i--;
}
Yield();
}
} }
nextDeleteBadRopes = Game.GameTime + 1000; nextDeleteBadRopes = Game.GameTime + 1000;
...@@ -150,16 +131,9 @@ namespace RopeCreator ...@@ -150,16 +131,9 @@ namespace RopeCreator
{ {
if (Game.GameTime >= nextReattachRopes) if (Game.GameTime >= nextReattachRopes)
{ {
if (ropes.Count > 0) foreach (var group in ropeGroups)
{ {
foreach (var rope in ropes) group.ReattachRagdollPeds();
{
if ((rope.firstEntity.Model.IsPed && ((Ped)rope.firstEntity).IsRagdoll) ||
(rope.secondEntity.Model.IsPed && ((Ped)rope.secondEntity).IsRagdoll))
{
rope.Reattach();
}
}
} }
nextReattachRopes = Game.GameTime + 500; nextReattachRopes = Game.GameTime + 500;
...@@ -182,7 +156,7 @@ namespace RopeCreator ...@@ -182,7 +156,7 @@ namespace RopeCreator
{ {
firstEntity = ray.HitEntity; firstEntity = ray.HitEntity;
firstOffset = firstEntity.GetOffsetFromWorldCoords(firstPos); firstOffset = firstEntity.GetOffsetFromWorldCoords(firstPos);
firstAttachBone = !firstEntity.Model.IsVehicle && (Menu.attachPedBone && firstEntity.Model.IsPed) || (Menu.attachObjBone && !firstEntity.Model.IsPed); firstAttachBone = !firstEntity.Model.IsVehicle && ((Menu.attachPedBone && firstEntity.Model.IsPed) || (Menu.attachObjBone && !firstEntity.Model.IsPed));
} }
UI.ShowSubtitle("First position"); UI.ShowSubtitle("First position");
...@@ -199,7 +173,7 @@ namespace RopeCreator ...@@ -199,7 +173,7 @@ namespace RopeCreator
if (secondEntity != null && secondEntity.Exists()) if (secondEntity != null && secondEntity.Exists())
{ {
secondAttachBone = !secondEntity.Model.IsVehicle && (Menu.attachPedBone && secondEntity.Model.IsPed) || (Menu.attachObjBone && !secondEntity.Model.IsPed); secondAttachBone = !secondEntity.Model.IsVehicle && ((Menu.attachPedBone && secondEntity.Model.IsPed) || (Menu.attachObjBone && !secondEntity.Model.IsPed));
} }
} }
...@@ -210,15 +184,17 @@ namespace RopeCreator ...@@ -210,15 +184,17 @@ namespace RopeCreator
var rope = new AttachedRope(firstEntity, firstPos, firstAttachBone, secondEntity, secondPos, secondAttachBone); var rope = new AttachedRope(firstEntity, firstPos, firstAttachBone, secondEntity, secondPos, secondAttachBone);
ropes.Add(rope); var group = ropeGroups[Menu.liGroupIndex.SelectedIndex];
if (ropes.Count > INI.maxRopes) group.ropes.Add(rope);
if (group.ropes.Count > INI.maxRopes)
{ {
ropes[0].Delete(); group.ropes[0].Delete();
ropes.RemoveAt(0); group.ropes.RemoveAt(0);
} }
Menu.ReloadRopeIndices(ropes.Count, ropes.Count - 1); Menu.ReloadRopeIndices(true); //true = select last item
firstPos = Vector3.Zero; firstPos = Vector3.Zero;
firstEntity = null; firstEntity = null;
...@@ -243,8 +219,10 @@ namespace RopeCreator ...@@ -243,8 +219,10 @@ namespace RopeCreator
{ {
if (Helper.AreControlsJustPressed(INI.removeLastControls)) if (Helper.AreControlsJustPressed(INI.removeLastControls))
{ {
var group = ropeGroups[Menu.liGroupIndex.SelectedIndex];
DeleteLastRope(true); DeleteLastRope(true);
Menu.ReloadRopeIndices(ropes.Count); Menu.ReloadRopeIndices();
} }
else if (Game.IsControlJustPressed(0, INI.attachControl)) else if (Game.IsControlJustPressed(0, INI.attachControl))
{ {
...@@ -281,8 +259,10 @@ namespace RopeCreator ...@@ -281,8 +259,10 @@ namespace RopeCreator
} }
else if (e.KeyCode == INI.removeLastKey) else if (e.KeyCode == INI.removeLastKey)
{ {
var group = ropeGroups[Menu.liGroupIndex.SelectedIndex];
DeleteLastRope(true); DeleteLastRope(true);
Menu.ReloadRopeIndices(ropes.Count); Menu.ReloadRopeIndices();
} }
} }
} }
......
...@@ -23,8 +23,9 @@ ...@@ -23,8 +23,9 @@
<Optimize>true</Optimize> <Optimize>true</Optimize>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Reference Include="NativeUI"> <Reference Include="LemonUI.SHVDN2, Version=1.3.0.0, Culture=neutral, processorArchitecture=AMD64">
<HintPath>..\..\..\Downloaded Mods\Scripts\NativeUI-Release\NativeUI.dll</HintPath> <SpecificVersion>False</SpecificVersion>
<HintPath>..\..\..\Downloaded Mods\Scripts\LemonUI_1.3\SHVDN2\LemonUI.SHVDN2.dll</HintPath>
</Reference> </Reference>
<Reference Include="ScriptHookVDotNet2"> <Reference Include="ScriptHookVDotNet2">
<HintPath>..\..\..\Downloaded Mods\Scripts\ScriptHookVDotNet_2.10.10\ScriptHookVDotNet2.dll</HintPath> <HintPath>..\..\..\Downloaded Mods\Scripts\ScriptHookVDotNet_2.10.10\ScriptHookVDotNet2.dll</HintPath>
...@@ -43,10 +44,11 @@ ...@@ -43,10 +44,11 @@
<Compile Include="Menu.cs" /> <Compile Include="Menu.cs" />
<Compile Include="RopeCreator.cs" /> <Compile Include="RopeCreator.cs" />
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="RopeGroup.cs" />
</ItemGroup> </ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<PropertyGroup> <PropertyGroup>
<PostBuildEvent>copy /Y "$(TargetPath)" "C:\Program Files (x86)\Steam\steamapps\common\Grand Theft Auto V\scripts\$(TargetFileName)"</PostBuildEvent> <PostBuildEvent>copy /Y "$(TargetDir)$(TargetName)*" "C:\Games\Grand Theft Auto V\scripts\"</PostBuildEvent>
</PropertyGroup> </PropertyGroup>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it. <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets. Other similar extension points exist, see Microsoft.Common.targets.
......
using GTA;
using System.Collections.Generic;
namespace RopeCreator
{
class RopeGroup
{
internal List<AttachedRope> ropes = new List<AttachedRope>();
internal void StartWindRopes()
{
if (ropes.Count == 0) return;
foreach (var rope in ropes)
{
rope.StopUnwind();
rope.StartWind();
}
}
internal void StopWindRopes()
{
if (ropes.Count == 0) return;
foreach (var rope in ropes)
{
rope.StopWind();
}
}
internal void StartUnwindRopes()
{
if (ropes.Count == 0) return;
foreach (var rope in ropes)
{
rope.StopWind();
rope.StartUnwind();
}
}
internal void StopUnwindRopes()
{
if (ropes.Count == 0) return;
foreach (var rope in ropes)
{
rope.StopUnwind();
}
}
internal void DeleteRopes()
{
if (ropes.Count == 0) return;
foreach (var rope in ropes)
{
rope.Delete();
}
ropes.Clear();
}
internal bool AreAllRopesWinding()
{
if (ropes.Count == 0) return false;
foreach (var rope in ropes)
{
if (!rope.winding) return false;
}
return true;
}
internal bool AreAllRopesUnwinding()
{
if (ropes.Count == 0) return false;
foreach (var rope in ropes)
{
if (!rope.unwinding) return false;
}
return true;
}
internal void DeleteRopesWithBadEntity()
{
if (ropes.Count == 0) return;
for (int i = 0; i < ropes.Count; i++)
{
var rope = ropes[i];
if (rope.firstEntity == null || !rope.firstEntity.Exists() || (rope.firstEntity.Model.IsPed && rope.firstEntity.IsDead) ||
rope.secondEntity == null || !rope.secondEntity.Exists() || (rope.secondEntity.Model.IsPed && rope.secondEntity.IsDead))
{
rope.Delete();
ropes.RemoveAt(i);
i--;
}
}
}
internal void ReattachRagdollPeds()
{
if (ropes.Count == 0) return;
foreach (var rope in ropes)
{
if ((rope.firstEntity.Model.IsPed && ((Ped)rope.firstEntity).IsRagdoll) ||
(rope.secondEntity.Model.IsPed && ((Ped)rope.secondEntity).IsRagdoll))
{
rope.Reattach();
}
}
}
}
}