Skip to content

Commit

Permalink
PR #245 improvements
Browse files Browse the repository at this point in the history
Use the common functions vehicle spawner instead when spawning vehicles using the entity spawner. Do not throw an exception but show a notification error instead and just return. Some code formatting changes.
  • Loading branch information
TomGrobbe committed May 25, 2021
1 parent d615b89 commit ff4c66b
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 60 deletions.
45 changes: 22 additions & 23 deletions vMenu/CommonFunctions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1108,7 +1108,7 @@ public static void CycleThroughSeats()
/// <param name="vehicleName">Vehicle model name. If "custom" the user will be asked to enter a model name.</param>
/// <param name="spawnInside">Warp the player inside the vehicle after spawning.</param>
/// <param name="replacePrevious">Replace the previous vehicle of the player.</param>
public static async void SpawnVehicle(string vehicleName = "custom", bool spawnInside = false, bool replacePrevious = false)
public static async Task<int> SpawnVehicle(string vehicleName = "custom", bool spawnInside = false, bool replacePrevious = false)
{
if (vehicleName == "custom")
{
Expand All @@ -1119,21 +1119,18 @@ public static async void SpawnVehicle(string vehicleName = "custom", bool spawnI
{
// Convert it into a model hash.
uint model = (uint)GetHashKey(result);
SpawnVehicle(vehicleHash: model, spawnInside: spawnInside, replacePrevious: replacePrevious, skipLoad: false, vehicleInfo: new VehicleInfo(),
return await SpawnVehicle(vehicleHash: model, spawnInside: spawnInside, replacePrevious: replacePrevious, skipLoad: false, vehicleInfo: new VehicleInfo(),
saveName: null);
}
// Result was invalid.
else
{
Notify.Error(CommonErrors.InvalidInput);
return 0;
}
}
// Spawn the specified vehicle.
else
{
SpawnVehicle(vehicleHash: (uint)GetHashKey(vehicleName), spawnInside: spawnInside, replacePrevious: replacePrevious, skipLoad: false,
return await SpawnVehicle(vehicleHash: (uint)GetHashKey(vehicleName), spawnInside: spawnInside, replacePrevious: replacePrevious, skipLoad: false,
vehicleInfo: new VehicleInfo(), saveName: null);
}
}
#endregion

Expand All @@ -1147,7 +1144,7 @@ public static async void SpawnVehicle(string vehicleName = "custom", bool spawnI
/// <param name="skipLoad">Does not attempt to load the vehicle, but will spawn it right a way.</param>
/// <param name="vehicleInfo">All information needed for a saved vehicle to re-apply all mods.</param>
/// <param name="saveName">Used to get/set info about the saved vehicle data.</param>
public static async void SpawnVehicle(uint vehicleHash, bool spawnInside, bool replacePrevious, bool skipLoad, VehicleInfo vehicleInfo, string saveName = null)
public static async Task<int> SpawnVehicle(uint vehicleHash, bool spawnInside, bool replacePrevious, bool skipLoad, VehicleInfo vehicleInfo, string saveName = null, float x = 0f, float y = 0f, float z = 0f, float heading = -1f)
{
float speed = 0f;
float rpm = 0f;
Expand All @@ -1158,13 +1155,11 @@ public static async void SpawnVehicle(uint vehicleHash, bool spawnInside, bool r
rpm = tmpOldVehicle.CurrentRPM;
}


//var vehClass = GetVehicleClassFromName(vehicleHash);
int modelClass = GetVehicleClassFromName(vehicleHash);
if (!VehicleSpawner.allowedCategories[modelClass])
{
Notify.Alert("You are not allowed to spawn this vehicle, because it belongs to a category which is restricted by the server owner.");
return;
return 0;
}

if (!skipLoad)
Expand All @@ -1174,15 +1169,21 @@ public static async void SpawnVehicle(uint vehicleHash, bool spawnInside, bool r
{
// Vehicle model is invalid.
Notify.Error(CommonErrors.InvalidModel);
return;
return 0;
}
}

Log("Spawning of vehicle is NOT cancelled, if this model is invalid then there's something wrong.");

// Get the heading & position for where the vehicle should be spawned.
Vector3 pos = (spawnInside) ? GetEntityCoords(Game.PlayerPed.Handle, true) : GetOffsetFromEntityInWorldCoords(Game.PlayerPed.Handle, 0f, 8f, 0f);
float heading = GetEntityHeading(Game.PlayerPed.Handle) + (spawnInside ? 0f : 90f);
Vector3 pos = new Vector3(x, y, z);
if (pos.IsZero)
{
pos = (spawnInside) ? GetEntityCoords(Game.PlayerPed.Handle, true) : GetOffsetFromEntityInWorldCoords(Game.PlayerPed.Handle, 0f, 8f, 0f);
pos += new Vector3(0f, 0f, 1f);
}

heading = heading == -1 ? GetEntityHeading(Game.PlayerPed.Handle) + (spawnInside ? 0f : 90f) : heading;

// If the previous vehicle exists...
if (_previousVehicle != null)
Expand All @@ -1204,11 +1205,7 @@ public static async void SpawnVehicle(uint vehicleHash, bool spawnInside, bool r
{
if (!vMenuShared.ConfigManager.GetSettingsBool(vMenuShared.ConfigManager.Setting.vmenu_keep_spawned_vehicles_persistent))
{
// Set the vehicle to be no longer needed. This will make the game engine decide when it should be removed (when all players get too far away).
SetEntityAsMissionEntity(_previousVehicle.Handle, false, false);
//_previousVehicle.IsPersistent = false;
//_previousVehicle.PreviouslyOwnedByPlayer = false;
//_previousVehicle.MarkAsNoLongerNeeded();
}
}
_previousVehicle = null;
Expand All @@ -1217,7 +1214,7 @@ public static async void SpawnVehicle(uint vehicleHash, bool spawnInside, bool r

if (Game.PlayerPed.IsInVehicle() && (replacePrevious || !IsAllowed(Permission.VSDisableReplacePrevious)))
{
if (GetVehicle().Driver == Game.PlayerPed)// && IsVehiclePreviouslyOwnedByPlayer(GetVehicle()))
if (GetVehicle().Driver == Game.PlayerPed)
{
var tmpveh = GetVehicle();
SetVehicleHasBeenOwnedByPlayer(tmpveh.Handle, false);
Expand All @@ -1238,11 +1235,11 @@ public static async void SpawnVehicle(uint vehicleHash, bool spawnInside, bool r
if (_previousVehicle != null)
_previousVehicle.PreviouslyOwnedByPlayer = false;

if (Game.PlayerPed.IsInVehicle())
pos = GetOffsetFromEntityInWorldCoords(Game.PlayerPed.Handle, 0, 8f, 0.1f);
if (Game.PlayerPed.IsInVehicle() && x == 0f && y == 0f && z == 0f)
pos = GetOffsetFromEntityInWorldCoords(Game.PlayerPed.Handle, 0, 8f, 0.1f) + new Vector3(0f, 0f, 1f);

// Create the new vehicle and remove the need to hotwire the car.
Vehicle vehicle = new Vehicle(CreateVehicle(vehicleHash, pos.X, pos.Y, pos.Z + 1f, heading, true, false))
Vehicle vehicle = new Vehicle(CreateVehicle(vehicleHash, pos.X, pos.Y, pos.Z, heading, true, false))
{
NeedsToBeHotwired = false,
PreviouslyOwnedByPlayer = true,
Expand Down Expand Up @@ -1292,12 +1289,14 @@ public static async void SpawnVehicle(uint vehicleHash, bool spawnInside, bool r
vehicle.CurrentRPM = rpm;

await Delay(1); // Mandatory delay - without it radio station will not set properly

// Set the radio station to default set by player in Vehicle Menu
vehicle.RadioStation = (RadioStation)UserDefaults.VehicleDefaultRadio;

// Discard the model.
SetModelAsNoLongerNeeded(vehicleHash);

return vehicle.Handle;
}

/// <summary>
Expand Down
70 changes: 33 additions & 37 deletions vMenu/EntitySpawner.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,13 @@ public class EntitySpawner : BaseScript
private float rotateSpeed = 20f;

private const float RayDistance = 25f;

/// <summary>
/// Constructor.
/// </summary>
public EntitySpawner()
{
#if DEBUG
#if DEBUG
RegisterCommand("testEntity", new Action<int, List<object>>((source, args) =>
{
string prop = (string)args[0];
Expand All @@ -34,7 +34,7 @@ public EntitySpawner()
{
FinishPlacement();
}), false);
#endif
#endif
}

#region PublicMethods
Expand All @@ -48,7 +48,7 @@ public EntitySpawner()
/// <returns>true spawn was succesful</returns>
public static void SpawnEntity(string model, Vector3 coords)
{
SpawnEntity((uint) GetHashKey(model), coords);
SpawnEntity((uint)GetHashKey(model), coords);
}

/// <summary>
Expand All @@ -68,11 +68,11 @@ public static async void SpawnEntity(uint model, Vector3 coords)

if (CurrentEntity != null)
{
Notify.Error("One entity is currently beeing processed");
Notify.Error("One entity is currently being processed.");
return;
}

int handle = 0;
int handle;
RequestModel(model);
while (!HasModelLoaded(model))
{
Expand All @@ -81,31 +81,27 @@ public static async void SpawnEntity(uint model, Vector3 coords)
if (IsModelAPed(model))
{
handle = CreatePed(4, model, coords.X, coords.Y, coords.Z, Game.PlayerPed.Heading, true, true);
} else if (IsModelAVehicle(model))
}
else if (IsModelAVehicle(model))
{
int modelClass = GetVehicleClassFromName(model);
if (!VehicleSpawner.allowedCategories[modelClass])
{
Notify.Alert("You are not allowed to spawn this vehicle, because it belongs to a category which is restricted by the server owner.");
return;
}
handle = CreateVehicle(model, coords.X, coords.Y, coords.Z, Game.PlayerPed.Heading, true, true);
handle = await CommonFunctions.SpawnVehicle(model, false, false, skipLoad: false, vehicleInfo: new CommonFunctions.VehicleInfo(), saveName: null, coords.X, coords.Y, coords.Z, Game.PlayerPed.Heading);
}
else
{
handle = CreateObject((int)model, coords.X, coords.Y, coords.Z, true, true, true);
}

SetEntityAsMissionEntity(handle, true, true); // Set As mission to prevent despawning

CurrentEntity = Entity.FromHandle(handle);

if (!CurrentEntity.Exists())
throw new Exception("Failed to create entity");

if (!CurrentEntity.Exists())
{
Notify.Error("Failed to create entity");
return;
}

SetEntityAsMissionEntity(handle, true, true); // Set As mission to prevent despawning

if (!Active)
Active = true;
Active = true;
}

/// <summary>
Expand All @@ -119,7 +115,7 @@ public static async void FinishPlacement(bool duplicate = false)
Vector3 position = CurrentEntity.Position;
CurrentEntity = null;
await Delay(1); // Mandatory
SpawnEntity((uint) hash, position);
SpawnEntity((uint)hash, position);
}
else
{
Expand Down Expand Up @@ -152,7 +148,7 @@ private void DrawButtons() //TODO: Right keys

DrawScaleformMovieFullscreen(scaleform, 255, 255, 255, 255, 0);
}

/// <summary>
/// Used internally for getting direction vector from rotation vector
/// </summary>
Expand All @@ -161,18 +157,18 @@ private void DrawButtons() //TODO: Right keys
private Vector3 RotationToDirection(Vector3 rotation)
{
Vector3 adj = new Vector3(
(float)Math.PI / 180f * rotation.X,
(float)Math.PI / 180f * rotation.Y,
(float)Math.PI / 180f * rotation.Z
(float)Math.PI / 180f * rotation.X,
(float)Math.PI / 180f * rotation.Y,
(float)Math.PI / 180f * rotation.Z
);

return new Vector3(
(float)(-Math.Sin(adj.Z) * Math.Abs(Math.Cos(adj.X))),
(float)(Math.Cos(adj.Z) * Math.Abs(Math.Cos(adj.X))),
(float)Math.Sin(adj.X)
(float)(-Math.Sin(adj.Z) * Math.Abs(Math.Cos(adj.X))),
(float)(Math.Cos(adj.Z) * Math.Abs(Math.Cos(adj.X))),
(float)Math.Sin(adj.X)
);
}

/// <summary>
/// Used to get coords of reycast from player camera;
/// </summary>
Expand All @@ -190,7 +186,7 @@ private Vector3 GetCoordsPlayerIsLookingAt()
);

RaycastResult res = World.Raycast(camCoords, dest, IntersectOptions.Everything, Game.PlayerPed);

#if DEBUG
DrawLine(Game.PlayerPed.Position.X, Game.PlayerPed.Position.Y,Game.PlayerPed.Position.Z, dest.X, dest.Y, dest.Z, 255, 0, 0, 255);
#endif
Expand Down Expand Up @@ -218,7 +214,7 @@ private async Task MoveHandler()
{
if (scaleform != 0)
{
SetScaleformMovieAsNoLongerNeeded(ref scaleform); //Unload scaleform if there is no need to draw it
SetScaleformMovieAsNoLongerNeeded(ref scaleform); // Unload scaleform if there is no need to draw it
scaleform = 0;
}
}
Expand All @@ -235,7 +231,7 @@ private async Task MoveHandler()
int handle = CurrentEntity.Handle;

DrawButtons();

FreezeEntityPosition(handle, true);
SetEntityInvincible(handle, true);
SetEntityCollision(handle, false, false);
Expand All @@ -256,13 +252,13 @@ private async Task MoveHandler()
PlaceObjectOnGroundProperly(CurrentEntity.Handle);
}
}

// Controls

// Controls
if (Game.IsControlPressed(0, Control.VehicleFlyRollLeftOnly))
{
headingOffset += rotateSpeed * Game.LastFrameTime;
} else if (Game.IsControlPressed(0, Control.VehicleFlyRollRightOnly))
}
else if (Game.IsControlPressed(0, Control.VehicleFlyRollRightOnly))
{
headingOffset -= rotateSpeed * Game.LastFrameTime;
}
Expand Down

0 comments on commit ff4c66b

Please sign in to comment.