Auto-sync 2026-04-15 22:30

This commit is contained in:
root 2026-04-15 22:30:01 +02:00
parent a8225bd0dd
commit 76924ef4e2
5 changed files with 250 additions and 69 deletions

File diff suppressed because one or more lines are too long

View File

@ -2,15 +2,12 @@
// MercyV Bike NUI Script
// ═══════════════════════════════════════════════════
const { createApp } = Vue;
function postNUI(event, data) {
return $.post(`https://${GetParentResourceName()}/${event}`, JSON.stringify(data || {}));
}
const app = createApp({
data() {
return {
const app = new Vue({
data: {
show: false, // WICHTIG: immer false beim Start
showAdmin: false,
isAdmin: false,
@ -67,7 +64,8 @@ const app = createApp({
postNUI('saveNPC', { ...this.npc });
},
},
}).mount('#app');
el: '#app'
});
// ── Message Handler ────────────────────────────────

View File

@ -0,0 +1,98 @@
function postNUI(event, data) {
$.post('https://' + GetParentResourceName() + '/' + event, JSON.stringify(data || {}));
}
var app = new Vue({
el: '#app',
data: {
show: false,
showAdmin: false,
isAdmin: false,
bikes: [],
selected: null,
claimed: false,
claimedModel: null,
npc: {
model: 'a_m_m_beach_01',
x: 0,
y: 0,
z: 0,
heading: 0
}
},
methods: {
close: function() {
this.show = false;
this.showAdmin = false;
this.selected = null;
postNUI('close');
},
claimBike: function() {
if (!this.selected) return;
postNUI('claimBike', { model: this.selected });
},
selectBike: function(model) {
this.selected = this.selected === model ? null : model;
},
openAdmin: function() {
this.showAdmin = true;
},
closeAdmin: function() {
this.showAdmin = false;
postNUI('close');
},
capturePos: function() {
postNUI('capturePos', {});
},
saveNPC: function() {
postNUI('saveNPC', {
model: this.npc.model,
x: this.npc.x,
y: this.npc.y,
z: this.npc.z,
heading: this.npc.heading
});
}
}
});
window.addEventListener('message', function(event) {
var msg = event.data;
switch (msg.action) {
case 'OPEN':
app.show = true;
app.showAdmin = false;
app.bikes = msg.bikes || [];
app.isAdmin = msg.isAdmin || false;
app.selected = null;
break;
case 'OPEN_ADMIN':
app.show = true;
app.showAdmin = true;
app.isAdmin = true;
if (msg.captured) {
app.npc.x = Math.round(msg.captured.x * 100) / 100;
app.npc.y = Math.round(msg.captured.y * 100) / 100;
app.npc.z = Math.round(msg.captured.z * 100) / 100;
app.npc.heading = Math.round(msg.captured.heading * 100) / 100;
}
break;
case 'CLOSE':
app.show = false;
app.showAdmin = false;
break;
case 'SET_ADMIN':
app.isAdmin = msg.isAdmin;
break;
case 'SET_CLAIM_STATUS':
app.claimed = msg.claimed;
app.claimedModel = msg.model || null;
break;
}
});
document.addEventListener('keydown', function(e) {
if (e.key === 'Escape' && app.show) {
app.close();
}
});

View File

@ -50,7 +50,18 @@ local NPCData = nil -- wird aus DB oder Config geladen
AddEventHandler('onResourceStart', function(res)
if res ~= GetCurrentResourceName() then return end
Wait(1500)
-- NPC-Position aus DB laden falls gespeichert
-- Tabelle ZUERST anlegen
MySQL.query.await([[
CREATE TABLE IF NOT EXISTS `mercyv_bike_npc` (
`id` INT AUTO_INCREMENT PRIMARY KEY,
`model` VARCHAR(100) DEFAULT 'a_m_m_beach_01',
`x` FLOAT DEFAULT 0,
`y` FLOAT DEFAULT 0,
`z` FLOAT DEFAULT 0,
`heading` FLOAT DEFAULT 0
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
]])
-- Dann lesen
local r = MySQL.query.await("SELECT * FROM mercyv_bike_npc LIMIT 1")
if r and r[1] then
NPCData = r[1]
@ -63,19 +74,7 @@ AddEventHandler('onResourceStart', function(res)
heading = Config.NPC.heading,
}
end
-- NPC-Tabelle anlegen falls nicht vorhanden
MySQL.query.await([[
CREATE TABLE IF NOT EXISTS `mercyv_bike_npc` (
`id` INT AUTO_INCREMENT PRIMARY KEY,
`model` VARCHAR(100) DEFAULT 'a_m_m_beach_01',
`x` FLOAT DEFAULT 0,
`y` FLOAT DEFAULT 0,
`z` FLOAT DEFAULT 0,
`heading` FLOAT DEFAULT 0
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
]])
print('^2[mercyv-bike]^0 NPC-Daten geladen.')
-- Kein Broadcast hier - jeder Client bekommt die Daten beim clientReady
end)
-- ── Client ready ───────────────────────────────────────────────

View File

@ -380,7 +380,7 @@ AddEventHandler('mercyv-deathscreen:server:npcReviveOther', function(targetId)
local src = source
if IsEMSOnDuty() then
TriggerClientEvent('esx:showNotification', src, 'Es sind Sanitäter im Dienst! Bitte rufe den Notruf.')
exports['hex_4_hud']:Notify(EMS, 'Es sind Sanitäter im Dienst! Bitte rufe den Notruf.', error, 5000)
return
end