hanf continuation

This commit is contained in:
hydrant
2021-05-25 20:10:58 +02:00
parent a49fcf09c7
commit 3abf2a2d0e
13 changed files with 2681 additions and 8 deletions

View File

@@ -760,7 +760,7 @@ export default function PedCreator() {
hash = tmpHash;
}
mp.gui.chat.push(`adding ped ${hash} (${charHashes[i]}`);
//mp.gui.chat.push(`adding ped ${hash} (${charHashes[i]}`);
let p = mp.peds.new(hash, vector3s[i], headings[i], dimension[i]);
p.freezePosition(true);

View File

@@ -3,8 +3,24 @@ import { createMenuItem } from "../util";
import moneyformat from "../moneyformat";
import { getAnimFromId } from "../util/animationSync";
import { getCreatedPedByName } from "../Ped/PedCreator";
import KeyBinder from 'ragemp-better-bindings';
const hanfPlantObjects = {
stage1: mp.game.joaat('bkr_prop_weed_bud_pruned_01a'),
stage2: mp.game.joaat('bkr_prop_weed_bud_01b'),
stage3: mp.game.joaat('prop_weed_02'),
stage4: mp.game.joaat('prop_weed_01')
};
const minimumPlantDistance = 5;
export default function hanfSystem(globalData: IGlobalData) {
let currentPlantingPreviewObject: ObjectMp = null;
let currentPlantingMarkerPreview: MarkerMp = null;
let currentlyPlanting: boolean = false;
let lastPlantingState = true;
mp.events.add("SERVER:Hanf_BuySeed", price => {
if (globalData.InMenu || globalData.InChat) {
return;
@@ -64,4 +80,155 @@ export default function hanfSystem(globalData: IGlobalData) {
npc.stopAnimTask(anim.dict, anim.name, 3);
}, 1000 * 10);
});
mp.events.add("SERVER:Hanf_StartPlanting", _ => {
let player = mp.players.local;
currentPlantingPreviewObject = mp.objects.new(hanfPlantObjects.stage1, player.position, {
alpha: 255
});
currentPlantingPreviewObject.notifyStreaming = true;
currentlyPlanting = true;
});
mp.events.add(RageEnums.EventKey.RENDER, _ => {
if (!currentlyPlanting) {
return;
}
var player = mp.players.local;
var newPlantState = isAbleToPlant();
var markerColor: [number, number, number, number] = [0, 255, 0, 255];
if (!newPlantState) {
markerColor = [255, 0, 0, 255];
}
if (currentPlantingMarkerPreview) {
currentPlantingMarkerPreview.destroy();
}
var playerPos = player.position;
var objectPos = new mp.Vector3(playerPos.x, playerPos.y, playerPos.z - 1.0);
currentPlantingMarkerPreview = mp.markers.new(25, objectPos, 0.7, {
color: markerColor,
visible: true,
rotation: new mp.Vector3(1, 0, 0)
});
});
mp.events.add(RageEnums.EventKey.ENTITY_STREAM_IN, entity => {
if (entity === currentPlantingPreviewObject) {
currentPlantingPreviewObject.attachTo(Number(mp.players.local.handle), 0, 0, 0.2, -0.95, 0, 0, 0, true, false, false, false, 0, true);
}
});
function isAbleToPlant() {
var player = mp.players.local;
if (isNearPlant()) {
return false;
}
if (!isSurfaceAllowed()) {
return false;
}
if (currentPlantingPreviewObject) {
var objectPos = getPlantPreviewPosition();
var realZ = mp.game.gameplay.getGroundZFor3dCoord(objectPos.x, objectPos.y, objectPos.z + 1, 0, false);
if (realZ > objectPos.z + 1) {
return false;
}
}
if (player.isSwimming() || player.isSwimmingUnderWater() || !player.isOnFoot()) {
return false;
}
return true;
}
const RAYCAST_POINT_TO_POINT_NATIVE = "0x377906D8A31E5586";
const GET_RAYCAST_RESULT_NATIVE = "0x65287525D951F6BE";
function isSurfaceAllowed() {
const player = mp.players.local;
var position = player.position;
var raycast = mp.game.invoke(RAYCAST_POINT_TO_POINT_NATIVE, position.x, position.y, position.z + 5, position.x, position.y, position.z - 5, -1, undefined, 0);
mp.gui.chat.push("raycast = " + raycast);
var hit: boolean, coord: Vector3Mp, surfaceNormal: Vector3Mp, materialHash: number, entityHit: EntityMp;
var raycastResult = mp.game.invoke(GET_RAYCAST_RESULT_NATIVE, raycast, hit, coord, surfaceNormal, materialHash, entityHit);
mp.gui.chat.push("result: " + raycastResult + ", hit = " + hit + ", test = " + materialHash);
return true;
}
KeyBinder.bind('e', _ => {
if (!currentlyPlanting || globalData.InChat) {
return;
}
if (!lastPlantingState) {
mp.game.graphics.notify("~r~Hier kann kein Hanf platziert werden");
return;
}
currentlyPlanting = false;
var player = mp.players.local;
if (currentPlantingPreviewObject) {
currentPlantingPreviewObject.destroy();
}
if (currentPlantingMarkerPreview) {
currentPlantingMarkerPreview.destroy();
}
var position = getPlantPreviewPosition();
var realZ = mp.game.gameplay.getGroundZFor3dCoord(position.x, position.y, position.z + 2, 0, false);
mp.events.callRemote("CLIENT:Hanf_PlantHanf", position.x, position.z, realZ);
});
function getPlantPreviewPosition(): Vector3Mp {
return mp.players.local.getOffsetFromInWorldCoords(0, 0.2, -1);
}
function isNearPlant(): boolean {
var position = getPlantPreviewPosition();
var nearPlant = false;
Object.keys(hanfPlantObjects).forEach(k => {
var hash = hanfPlantObjects[k];
var obj = mp.game.object.getClosestObjectOfType(position.x, position.y, position.z, minimumPlantDistance, hash, false, false, false);
if (obj && obj != currentPlantingPreviewObject.handle) {
nearPlant = true;
}
});
return nearPlant;
}
let currentHanfData: Array<CannabisData> = null;
let hanfDataIdToObjectMap: Map<number, ObjectMp> = null;
mp.events.add("SERVER:Hanf_UpdateHanfData", dataJson => {
var data: Array<CannabisData> = <Array<CannabisData>>JSON.parse(dataJson)
if (currentHanfData == null) {
currentHanfData = data;
}
var newPlants = data.filter(d => currentHanfData.filter(x => x.id === d.id).length == 0);
var removedPlants = currentHanfData.filter(d => data.filter(x => x.id === d.id).length == 0);
var existingPlants = data.filter(d => currentHanfData.filter(x => x.id === d.id).length == 1);
mp.gui.chat.push(`new: ${newPlants.length}, removed: ${removedPlants.length}, existing: ${existingPlants.length}`);
currentHanfData = data;
});
}

View File

@@ -97,6 +97,14 @@ declare type RentcarProperty = {
Price: number;
}
declare type CannabisData = {
id: number;
x: number;
y: number;
z: number;
time: Date;
}
declare type PlayerCharacterData = {
Gender: boolean;
Father: number;

View File

@@ -0,0 +1,30 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Text;
namespace ReallifeGamemode.Database.Entities
{
public class CannabisPlant
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public long Id { get; set; }
public DateTime PlantDate { get; set; }
public float X { get; set; }
public float Y { get; set; }
public float Z { get; set; }
public bool Harvested { get; set; }
public User PlantedBy { get; set; }
[ForeignKey(nameof(PlantedBy))]
public int PlantedById { get; set; }
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,47 @@
using System;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
namespace ReallifeGamemode.Database.Migrations
{
public partial class AddCannabisPlants : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "CannabisPlants",
columns: table => new
{
Id = table.Column<long>(nullable: false)
.Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
PlantDate = table.Column<DateTime>(nullable: false),
X = table.Column<float>(nullable: false),
Y = table.Column<float>(nullable: false),
Z = table.Column<float>(nullable: false),
Harvested = table.Column<bool>(nullable: false),
PlantedById = table.Column<int>(nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_CannabisPlants", x => x.Id);
table.ForeignKey(
name: "FK_CannabisPlants_Users_PlantedById",
column: x => x.PlantedById,
principalTable: "Users",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateIndex(
name: "IX_CannabisPlants_PlantedById",
table: "CannabisPlants",
column: "PlantedById");
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "CannabisPlants");
}
}
}

View File

@@ -154,6 +154,37 @@ namespace ReallifeGamemode.Database.Migrations
b.ToTable("BusinessData");
});
modelBuilder.Entity("ReallifeGamemode.Database.Entities.CannabisPlant", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
b.Property<bool>("Harvested")
.HasColumnType("tinyint(1)");
b.Property<DateTime>("PlantDate")
.HasColumnType("datetime(6)");
b.Property<int>("PlantedById")
.HasColumnType("int");
b.Property<float>("X")
.HasColumnType("float");
b.Property<float>("Y")
.HasColumnType("float");
b.Property<float>("Z")
.HasColumnType("float");
b.HasKey("Id");
b.HasIndex("PlantedById");
b.ToTable("CannabisPlants");
});
modelBuilder.Entity("ReallifeGamemode.Database.Entities.Character", b =>
{
b.Property<int>("Id")
@@ -1931,6 +1962,15 @@ namespace ReallifeGamemode.Database.Migrations
.HasForeignKey("BusRouteId");
});
modelBuilder.Entity("ReallifeGamemode.Database.Entities.CannabisPlant", b =>
{
b.HasOne("ReallifeGamemode.Database.Entities.User", "PlantedBy")
.WithMany()
.HasForeignKey("PlantedById")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("ReallifeGamemode.Database.Entities.Character", b =>
{
b.HasOne("ReallifeGamemode.Database.Entities.User", "User")

View File

@@ -179,6 +179,8 @@ namespace ReallifeGamemode.Database.Models
//Server Variablen
public DbSet<Entities.ServerVariable> ServerVariables { get; set; }
public DbSet<Entities.CannabisPlant> CannabisPlants { get; set; }
}
public class DesignTimeDbContextFactory : IDesignTimeDbContextFactory<DatabaseContext>

View File

@@ -88,6 +88,8 @@ namespace ReallifeGamemode.Server.Events
NAPI.World.RequestIpl("ferris_finale_Anim"); // Riesenrad
NAPI.World.RequestIpl("Carwash_with_spinners"); // Carwash
HanfManager.UpdateHanfForPlayer(player);
TimeSpan currentTime = TimeManager.CurrentTime;
bool disableLightMode = currentTime > LightModeTimeFrom && currentTime < LightModeTimeTo;

View File

@@ -1,10 +1,15 @@
using System;
using System.Collections.Generic;
using System.Text;
using GTANetworkAPI;
using ReallifeGamemode.Database.Entities;
using ReallifeGamemode.Database.Models;
using ReallifeGamemode.Server.Extensions;
using ReallifeGamemode.Server.Managers;
namespace ReallifeGamemode.Server.Inventory.Items
{
public class CannabisSeeds : BaseItem
public class CannabisSeeds : UseItem
{
public override int Id { get; } = 109;
public override string Name { get; } = "Cannabis Samen";
@@ -13,5 +18,18 @@ namespace ReallifeGamemode.Server.Inventory.Items
public override string Einheit { get; } = "g";
public override int Price { get; } = 0;
public override bool Legal => false;
public override uint Object { get; }
public override bool RemoveWhenUsed { get; } = false;
public override bool Use(Player player, User user, DatabaseContext databaseContext)
{
if(!player.IsInVehicle)
{
HanfManager.StartCannabisPlanting(player);
}
return true;
}
}
}

View File

@@ -5,6 +5,7 @@ using System.Text;
using System.Timers;
using GTANetworkAPI;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using ReallifeGamemode.Database.Entities;
using ReallifeGamemode.Database.Models;
using ReallifeGamemode.Server.Extensions;
@@ -47,8 +48,18 @@ namespace ReallifeGamemode.Server.Managers
/// </summary>
private const string _manufacturerAnim = "manufacturJoint";
/// <summary>
/// Data-Key, ob der Spieler grade eine Pflanze anpflanzt
/// </summary>
private const string PLAYER_CURRENTLY_PLANTING_DATA_KEY = "isPlantingCannabis";
/// <summary>
/// Timer der den Status des Verarbeiters zurücksetzt
/// </summary>
private static Timer _manufacturerDoneTimer = new Timer(TimeSpan.FromSeconds(10).TotalMilliseconds);
private static List<CannabisData> _currentCannabisData = new List<CannabisData>();
static HanfManager()
{
_manufacturerDoneTimer.Elapsed += ManufacturerDoneTimerCallback;
@@ -72,11 +83,29 @@ namespace ReallifeGamemode.Server.Managers
colShape = NAPI.ColShape.CreateSphereColShape(buyPoint, 20.0f);
colShape.OnEntityEnterColShape += OnSeedBuyRangeColShapeEnter;
}
UpdateHanfWorldData(new DatabaseContext());
Timer updateHanfDataTimer = new Timer(TimeSpan.FromMinutes(1).TotalMilliseconds);
updateHanfDataTimer.Elapsed += UpdateHanfDataTimer_Elapsed;
updateHanfDataTimer.Start();
}
private static void UpdateHanfDataTimer_Elapsed(object sender, ElapsedEventArgs e)
{
using var dbContext = new DatabaseContext();
UpdateHanfWorldData(dbContext);
}
private static void OnSeedBuyRangeColShapeEnter(ColShape colShape, Player player)
{
ChatService.SendMessage(player, $"Fremder sagt: Pssst.. Willst paar Samen erwerben?");
var user = player.GetUser();
if (user.Faction.StateOwned)
{
return;
}
ChatService.SendMessage(player, $"Fremder sagt: Pssst.. Willst du Samen kaufen?");
}
internal static bool IsPlayerNearSeedBuyPoint(Player player)
@@ -89,6 +118,95 @@ namespace ReallifeGamemode.Server.Managers
return _jointManufacturerPoint.DistanceTo(player.Position) <= 2.5f;
}
internal static void StartCannabisPlanting(Player player)
{
player.ToggleInventory(InventoryToggleOption.HIDE);
if (!player.IsAlive())
{
return;
}
var dbContext = new DatabaseContext();
var user = player.GetUser(dbContext);
if (user.Faction?.StateOwned ?? false)
{
player.SendNotification("~r~Du darfst keine Hanfsamen einfplanzen");
return;
}
if (player.HasData(PLAYER_CURRENTLY_PLANTING_DATA_KEY) && player.GetData<bool>(PLAYER_CURRENTLY_PLANTING_DATA_KEY))
{
player.SendNotification("~r~Du pflanzt aktuell schon einen Hanfsamen ein");
return;
}
player.SetData(PLAYER_CURRENTLY_PLANTING_DATA_KEY, true);
player.TriggerEvent("SERVER:Hanf_StartPlanting");
}
[RemoteEvent("CLIENT:Hanf_PlantHanf")]
public void HanfManagerPlantHanf(Player player, float x, float y, float z)
{
player.ResetData(PLAYER_CURRENTLY_PLANTING_DATA_KEY);
IItem cannabisSeedItem = InventoryManager.GetItem<CannabisSeeds>();
UserItem userCannabisSeedsItem = InventoryManager.UserHasThisItem(player, cannabisSeedItem.Id);
if (userCannabisSeedsItem == null)
{
player.SendNotification("~r~Du hast keine Samen mehr");
return;
}
logger.LogInformation("Player {0} planted a cannabis plant at x: {1}, y: {2}, z: {3}", player.Name, x, y, z);
using var dbContext = new DatabaseContext();
var user = player.GetUser(dbContext);
InventoryManager.RemoveUserItem(user, userCannabisSeedsItem, 1);
CannabisPlant newPlant = new CannabisPlant()
{
X = x,
Y = y,
Z = z,
PlantedBy = user,
PlantDate = DateTime.Now,
};
dbContext.CannabisPlants.Add(newPlant);
dbContext.SaveChanges();
UpdateHanfWorldData(dbContext);
}
public static void UpdateHanfWorldData(DatabaseContext dbContext)
{
var activePlants = dbContext.CannabisPlants.Where(p => !p.Harvested).Select(p => new CannabisData()
{
Id = p.Id,
Time = p.PlantDate,
X = p.X,
Y = p.Y,
Z = p.Z
}).ToList();
_currentCannabisData = activePlants;
NAPI.Pools.GetAllPlayers().ForEach(p =>
{
UpdateHanfForPlayer(p, activePlants);
});
}
public async static void UpdateHanfForPlayer(Player player, List<CannabisData> cannabisData = null)
{
cannabisData ??= _currentCannabisData;
var x = await NAPI.Task.WaitForMainThread();
player.TriggerEvent("SERVER:Hanf_UpdateHanfData", JsonConvert.SerializeObject(cannabisData));
}
[RemoteEvent("CLIENT:Hanf_BuySeeds")]
public void HanfManagerBuySeeds(Player player, int amount)
{

View File

@@ -563,12 +563,11 @@ namespace ReallifeGamemode.Server.Managers
if (usableItemObj.RemoveWhenUsed)
{
RemoveUserItem(user, fItem, 1);
}
SetBackpackItems(player);
player.TriggerEvent("aproveUse", 1, iItem.Name);
}
}
}
else player.TriggerEvent("Error", "Du kannst dieses Item nicht benutzen.");
break;

View File

@@ -0,0 +1,19 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace ReallifeGamemode.Server.Util
{
public class CannabisData
{
public long Id { get; set; }
public float X { get; set; }
public float Y { get; set; }
public float Z { get; set; }
public DateTime Time { get; set; }
}
}