FlexHour è un sistema di orologi di lusso per FiveM. I giocatori comprano orologi da una commessa in boutique, li configurano, li indossano, li sfoggiano, li portano in assistenza e li scambiano. Accanto gira un intero mercato di falsi.
Il prodotto è composto da due risorse: concept_flexhour (lo script) e flexhour_boutique (l'interno della boutique, in cui si entra a piedi). La boutique ha una sua guida: Boutique FlexHour.
FlexHour usa Cfx Asset Escrow. Dopo il pagamento su Tebex, le risorse compaiono su Keymaster in Granted Assets, sull'account Cfx.re con cui hai effettuato l'accesso al checkout.
concept_flexhour e flexhour_boutique arrivano con lo stesso acquisto, come due download separati. Scaricali e installali entrambi.concept_flexhour. Se rinomini la cartella, ottieni No such export useBox in resource concept_flexhour.config.lua e i file locales/ restano modificabili. Il resto è protetto da escrow.| Risorsa | Note |
|---|---|
ox_lib |
Usata per callback e traduzioni. FlexHour disegna da sé menu, moduli, finestre sì/no e barra di avanzamento. |
oxmysql |
Le tabelle del database vengono create al primo avvio. |
concept_bridge 1.1.0 o successivo |
Testato con 1.1.1. Una risorsa gratuita e separata sotto GPL-3.0: concept_bridge. Non è inclusa in questo prodotto. Usa un solo bridge. |
| Un framework | QBCore, qbx_core, ESX o ox_core |
| Un inventario con metadati per oggetto | Consigliato ox_inventory (vedi sotto) |
| Una risorsa di target | ox_target, qb-target o sleepless_interact |
concept_flexhour e flexhour_boutique nella cartella resources.server.cfg dopo le loro dipendenze. Il bridge carica i suoi moduli da ciò che è già in esecuzione, quindi avvialo dopo framework, inventario e target:ensure ox_lib
ensure oxmysql
ensure your_framework # es_extended / qb-core / qbx_core / ox_core
ensure ox_inventory # or your inventory
ensure ox_target # or your target
ensure concept_bridge
ensure concept_flexhour
ensure flexhour_boutique # the boutique interior, after concept_flexhour
add_ace group.admin flexhour.admin allow
/fhmodels. Elenca i modelli di orologi non in streaming. Se l'elenco è vuoto, la cartella stream/ è completa.Ogni modello di orologio è un oggetto a sé, chiamato fh_. La configurazione è salvata nei metadati dell'oggetto: metallo della cassa, quadrante, lunetta, pietre, numero di serie, incisione e condizione. Negozi, scambi e altri script possono consegnare un modello specifico.
ox_inventory
docs/ox_items.lua (tutti i 23 modelli) in ox_inventory/data/items.lua.['flexhour_box'] = {
label = 'FlexHour Box',
weight = 450,
stack = false,
close = true,
description = 'Something shiny inside.',
client = { export = 'concept_flexhour.useBox' },
},
['flexhour_replica_kit'] = {
label = 'Replica Kit',
weight = 900,
stack = true,
close = true,
description = 'Blank case, cheap movement, dial stencils, gold plating. Not from any boutique.',
},
web/img/*.png e web/img/items/*.png in ox_inventory/web/images/. Ci sono 78 icone di orologi: una per ogni modello e materiale della cassa, più una per ogni edizione limitata. Ogni orologio punta alla propria icona tramite metadata.image.Inventari stile qb
Aggiungi gli oggetti da docs/qb_items.lua (formato QBCore). FlexHour li registra come utilizzabili all'avvio. Su questi inventari l'oggetto mostra nome e immagine del modello. I dettagli della configurazione sono nel campo info dell'oggetto e nella vista di osservazione (I mentre indossi l'orologio).
FlexHour raggiunge il framework (soldi, identità, lavori), l'inventario, il target e le notifiche tramite concept_bridge.
| Parte | Supportati | Stato |
|---|---|---|
| Framework | QBCore, qbx_core, ESX, ox_core | I conti sono cash e bank. Il bridge associa cash al conto money di ESX. |
| Inventario | ox_inventory | Consigliato. Testato in gioco. |
| Inventario | qb-inventory, ps-inventory, qs-inventory, tgiann-inventory, origen_inventory, codem-inventory, core_inventory, one-inventory | Deve conservare i metadati per oggetto. Coperto da test automatici, non ancora testato in gioco. |
| Inventario | L'inventario integrato di ESX | Non supportato. Non ha metadati per oggetto né slot, e un orologio è i suoi metadati. La console ti avvisa all'avvio. |
| Target | ox_target, qb-target, sleepless_interact | Al posto del target puoi usare un prompt con tasto: vedi Config.Interaction. |
config.lua contiene tutte le impostazioni che un server può cambiare. Modifica un valore e riavvia la risorsa. Se ometti un'impostazione, FlexHour usa il suo valore predefinito. Ciò che non è un'impostazione non può essere sovrascritto da config.lua.
| Impostazione | Predefinito | Cosa fa |
|---|---|---|
Config.PayAccounts |
{ 'cash', 'bank' } |
Conti da addebitare, in ordine. Paga il primo che copre il prezzo. |
Config.Delivery |
'box' |
'box': gli acquisti arrivano in scatola e il giocatore li apre. 'direct': l'orologio va direttamente nell'inventario. |
Config.Interaction |
{ mode = 'target', key = 38, keyName = 'E' } |
Come i giocatori usano commesse, vetrine e punti: con il target o con un prompt a tasto. |
Config.Notify |
{ system = 'flexhour', position = 'top-right' } |
Le notifiche di FlexHour, oppure quelle del tuo server (tramite il bridge). |
Config.InspectKey |
'I' |
Tasto per osservare l'orologio indossato. I giocatori possono cambiarlo nelle impostazioni tasti di GTA. |
Config.FlexCommand |
'flex' |
Comando per il flex del polso. |
Config.FlexLoopCommand |
'flex2' |
Comando per il flex in loop. |
Config.AdminAce |
'flexhour.admin' |
Permesso ACE per gli strumenti admin. |
Config.AdminOpenToAll |
false |
true rende admin ogni giocatore. Usalo solo per i test. |
Config.TryOnSeconds |
12 |
Quanto dura una prova dalla commessa. |
Config.Clerks è l'elenco delle commesse della boutique. La commessa inclusa si trova a Vinewood con il modello a_f_y_business_02, lo scenario WORLD_HUMAN_STAND_IMPATIENT, un blip (sprite 617, colore 46, scala 0.8), e vende i livelli budget, mid, luxury e mythic.
Se flexhour_boutique è attiva, la sua commessa sta dietro il bancone della boutique. Quella posizione è salvata in data/clerks.json, che ha la precedenza su config.lua. Se usi FlexHour senza la boutique, apri /fhclerk e scegli Put the config.lua clerks back.
Config.Negotiate)| Impostazione | Predefinito | Cosa fa |
|---|---|---|
enabled |
true |
I giocatori possono contrattare con le commesse. |
rounds |
3 |
Round di minigioco prima dell'offerta finale: leggere la commessa, un indovinello e un gioco di memoria. |
cooldownSeconds |
90 |
Attesa per giocatore dopo ogni trattativa. |
showFloor |
true |
Mostra il prezzo più basso che la commessa accetterebbe. |
onWalkAway |
'list' |
'list': il giocatore può ancora comprare a prezzo di listino. 'abort': la vendita termina. |
Config.Services)| Impostazione | Predefinito | Cosa fa |
|---|---|---|
strapSwap |
1500 |
Costo del cambio cinturino, più la differenza di prezzo tra i cinturini. |
replatePercent |
0.35 |
Costo della ridoratura, come quota del prezzo di listino. |
replateMin |
2500 |
Il prezzo minimo della ridoratura. |
icePerLevel |
0.40 |
Costo di ogni livello di pietre, come quota del prezzo di listino della cassa. |
engrave |
750 |
Incisione (fino a 24 caratteri). |
polish |
400 |
Lucidatura, che ripristina la condizione. |
authenticate |
150 |
Certificato di autenticità. |
authDays |
14 |
Per quanti giorni resta valido il certificato. 0 significa per sempre. |
Config.Limited)Config.Limited stabilisce quanti esemplari di ogni modello limitato possono esistere in tutto. Vedi Edizioni limitate.
Config.Wear)| Impostazione | Predefinito | Cosa fa |
|---|---|---|
keepWorn |
false |
false: un orologio indossato resta un oggetto dell'inventario. true: mentre è indossato, FlexHour lo tiene in una sua tabella così non può andare perso. Vedi Orologi indossati. |
restoreOnSpawn |
true |
L'orologio resta al polso dopo una riconnessione. Vale con keepWorn = false. Un orologio custodito resta sempre al polso. |
gameWatch |
'hide' |
Cosa succede agli accessori da polso di GTA. 'hide': vengono tolti mentre indossi un orologio FlexHour. 'block': lo slot del polso sinistro resta sempre vuoto. 'off': non vengono toccati. |
conditionLossPerHour |
0.5 |
Condizione persa per ora di utilizzo. Le repliche si consumano più in fretta. |
hideInVehicle |
false |
Nascondi gli orologi nei veicoli. |
playerAdjust |
true |
I giocatori possono regolare la propria posizione con /watchfit. Gli altri vedono il risultato. |
allowScale |
true |
Il gizmo di regolazione può anche ridimensionare l'orologio (da 0.75 a 1.25). |
fitPresets |
3 |
Slot di regolazione salvati per giocatore, usati con /watchpreset. |
sleeve.enabled |
true |
I giocatori possono tirare su la manica con /watchsleeve. |
Config.Wear.rob)| Impostazione | Predefinito | Cosa fa |
|---|---|---|
enabled |
true |
Un orologio indossato può essere rapinato. |
seconds |
6 |
Quanto tempo serve per prendere l'orologio. |
when |
{ dead = true, handsUp = true, cuffed = true } |
Gli stati in cui deve trovarsi chi lo indossa. |
cooldownMinutes |
10 |
Quanto aspetta un rapinatore prima di poter rapinare di nuovo. |
protectMinutes |
30 |
Per quanto una vittima è protetta dopo una rapina. |
command |
'stealwatch' |
Comando di rapina. false disattiva il comando. |
handsUpAnims |
{} |
Le animazioni «mani in alto» del tuo server: { { 'dict', 'clip' }, ... }. |
minigame |
false |
Il tuo minigioco: function(victim) return true end. Restituisci true per continuare, false se è fallito. |
Config.Fakes)| Impostazione | Predefinito | Cosa fa |
|---|---|---|
enabled |
true |
Il mercato dei falsi è attivo. |
dealer.coords / dealer.model |
in config.lua / g_m_y_ballaeast_01 |
Dove si trova il venditore di kit e il suo modello di ped. |
dealer.kitPrice |
2500 |
Prezzo base del kit. Il livello del kit lo moltiplica. |
dealer.cooldown |
900 |
Secondi per personaggio tra un kit e l'altro. |
workshop.coords / workshop.prop |
in config.lua / 'prop_tool_bench02' |
Dove si trova il banco. prop = false usa un tavolo della mappa invece di generare un banco. |
fence.coords / fence.model |
in config.lua / s_m_y_dealer_01 |
Dove si trova il ricettatore e il suo modello di ped. |
fence.account |
'cash' |
Conto su cui paga il ricettatore. Usa 'black_money' se il tuo framework lo prevede. |
fence.maxPayout |
30000 |
Il massimo che il ricettatore paga per un singolo orologio. |
fence.cooldown |
600 |
Secondi per personaggio tra una vendita e l'altra. |
fence.alertChance |
0.10 |
Probabilità che una vendita venga segnalata alla polizia. |
fence.alertChanceFake |
0.25 |
La stessa probabilità quando l'orologio è una replica. |
onAlert |
function(src, coords, build) end |
Hook lato server per il tuo script di dispatch. |
Per posizionare i tre punti in gioco, usa /fhfake dealer, /fhfake workshop o /fhfake fence. I punti posizionati vengono salvati in data/fakes.json, che ha la precedenza su config.lua.
Tutto ciò che leggono i giocatori viene da locales/.json: notifiche, menu, la pagina del negozio (ui_*), le carte della trattativa (card_*), gli indizi della commessa (tell_*) e ciò che dicono commesse, ricettatore e venditore di kit (neg_*).
Lingue incluse: inglese (en), ungherese (hu), tedesco (de), spagnolo (es) e francese (fr). FlexHour usa l'impostazione della lingua di ox_lib. Mettila in server.cfg:
setr ox:locale "en" # or "hu", "de", "es", "fr"
Per aggiungere una lingua, copia en.json in .json e traduci i valori. Gli indovinelli della trattativa sono conservati lato server in tutte e cinque le lingue. I nomi di orologi, materiali e cinturini sono nomi di prodotto e non vengono tradotti.
| Comando | Cosa fa |
|---|---|
/watch |
Indossa o togli un orologio. |
/watchfit |
Regola la posizione con un gizmo (vedi sotto). |
/watchhand |
Sposta l'orologio sull'altro polso. |
/watchsleeve |
Tira su o abbassa la manica. |
/watchpreset |
Salva o carica una regolazione. |
/flex |
Flex del polso. |
/flex2 |
Flex in loop. |
I |
Osserva l'orologio indossato. |
X |
Metti via la scatola che stai tenendo. Riassegnabile. |
/stealwatch |
Rapina un orologio indossato (vedi Rapina). |
/fhhelp |
Elenca i comandi in chat. |
Il gizmo di regolazione funziona così:
allowScale è attivo.flexhour.admin)| Comando | Cosa fa |
|---|---|
/fhclerk |
Sposta, rinomina o rimuovi le commesse piazzate, oppure ripristina quelle di config.lua. |
/fhclerk |
Piazza una nuova commessa. Punta il fantasma dove la scatola deve stare sul bancone. |
/fhstand |
Piazza una vetrina dove ti trovi. |
/fhfake [dealer|workshop|fence] |
Gestisci o piazza i punti dei falsi. |
/fhgive [id] |
Consegna un orologio in scatola e scegli la configurazione. |
/fhwrist |
Gizmo di regolazione al polso. G salva la regolazione come predefinita del server per il tuo modello di ped. |
/fhmodels |
Elenca i modelli di orologi non in streaming. |
Gli strumenti admin controllano l'ACE in Config.AdminAce (predefinito flexhour.admin):
add_ace group.admin flexhour.admin allow
Prima che entrino i giocatori, assicurati che Config.AdminOpenToAll sia false. Con true ogni giocatore è admin: può darsi orologi e piazzare commesse e vetrine, e la riga ACE non serve a nulla. Finché è attivo, la console stampa un avviso rosso a ogni avvio.
La commessa apre il negozio. Il giocatore sceglie un modello, poi il metallo della cassa, il quadrante, il cinturino e il suo colore, la lunetta, le lancette e il livello di pietre. Ogni livello ha le sue opzioni. Il giocatore può provare l'orologio per TryOnSeconds, poi comprarlo, o prima contrattare. Con Delivery = 'box' l'orologio arriva in una flexhour_box. Usare la scatola avvia un rituale di unboxing sul bancone, e il giocatore tiene la scatola in mano finché non la mette via con X.
Ogni orologio autentico riceve un numero di serie unico (FH-…), salvato nel registro (flexhour_serials).
A ogni sessione ogni commessa riceve una personalità nascosta fatta di cinque tratti: vanità, avidità, orgoglio, lealtà e nervosismo. Il linguaggio del corpo dà indizi. Il giocatore gioca carte come Complimento, Contanti, Offerta al ribasso, Bluff, Cliente abituale, Concorrente, Pacchetto e Storia, e affronta round misti di lettura della commessa, indovinelli e un gioco di memoria. Il risultato è l'offerta finale. Il venditore di kit e il ricettatore usano allo stesso modo un mazzo da strada.
Gli admin piazzano vetrine con /fhstand e riforniscono ogni cuscino dal menu della vetrina. Le vetrine vendono al prezzo del cartellino, che deve essere tra il 70% e il 160% del prezzo di listino, e hanno scorte illimitate. Con una vetrina entro 30 m da una commessa si può contrattare con quella commessa. In questa versione i giocatori non possono possedere vetrine, e le edizioni limitate non possono esservi esposte.
Un giocatore indossa un orologio alla volta, su uno dei due polsi. Le regolazioni integrate coprono i personaggi freemode. Per i ped personalizzati gli admin salvano una regolazione per modello di ped, e i giocatori possono affinare la propria. Gli altri giocatori vedono l'orologio da vicino: lancette in tempo reale, riflessi e pietre che brillano di notte. Le azioni del giocatore sono flex, osserva e manica.
La commessa offre cambio cinturino, ridoratura, pietre, incisione, lucidatura e autenticazione. L'autenticazione dà a un orologio autentico documenti validi per authDays giorni. Su una replica, l'autenticazione mostra che è falsa.
Esistono 14 pezzi numerati. Ognuno è una configurazione fissa, con un quadrante, una finitura o un cinturino che nessun orologio standard può avere. Il server limita quanti ne esistono, e ogni acquirente riceve il proprio numero (per esempio «No. 3 / 10»). Quando tutti i pezzi sono venduti, l'edizione esce dal negozio. Le commesse le vendono nel gruppo Limited editions dell'elenco.
Su un'edizione limitata sono consentiti pietre, incisione e lucidatura. Cambio cinturino e ridoratura vengono rifiutati, così il pezzo resta originale.
Il mercato dei falsi funziona in tre passaggi:
Una replica sembra vera nell'inventario, ma il suo numero di serie non è nel registro, e più bassa è la qualità, più indizi mostra: stampa del quadrante storta, ora che deriva, lancetta dei secondi che scatta o si ferma, usura più rapida e doratura che si consuma.
Con il predefinito Config.Wear.keepWorn = false, un orologio è sempre un oggetto dell'inventario, anche mentre è indossato. Resta nel suo slot, e tutto ciò che succede all'inventario succede anche all'orologio: svuotamento alla morte, perquisizione o un altro script di rapina.
Con keepWorn = true, indossare un orologio lo toglie dall'inventario e FlexHour lo tiene in flexhour_wrist. Toglierlo lo fa tornare un oggetto. Mentre è indossato, niente di ciò che succede all'inventario può prenderlo: svuotamento alla morte, confisca, perquisizione, abbandono, deposito o bagagliaio. Per vendere, regalare, depositare o portare in assistenza l'orologio, il giocatore deve prima toglierlo con /watch.
Se riporti keepWorn a false, ogni personaggio riceve l'orologio indossato nell'inventario al prossimo accesso.
Un orologio indossato si può prendere in un solo modo: con la rapina di FlexHour. Un giocatore accanto a chi lo indossa ed è morto, ha le mani alzate o è ammanettato può prendere l'orologio con l'opzione del target, il prompt [E] o /stealwatch. Lo stesso orologio, con lo stesso numero di serie, finisce nelle tasche del rapinatore. Altre risorse possono reagire all'evento flexhour:watchRobbed.
I menu dei vestiti del gioco possono mettere un orologio al polso sinistro (slot prop 6) o un bracciale al polso destro (slot 7). Con gameWatch = 'hide', l'accessorio di GTA viene tolto mentre un orologio FlexHour è su quel polso. Se nel frattempo un menu dei vestiti salva l'outfit, questo viene salvato senza quell'accessorio. Togli l'orologio FlexHour prima di salvare un outfit, oppure imposta gameWatch su 'off'.
-- Give a player a watch. build = { base = '', material = ..., dial = ..., strap = ..., iced = 0 }
-- Only base is required; anything you leave out or set to something invalid falls back to that model's defaults.
-- boxed = true (default) delivers it in a flexhour_box. Returns true, serial.
local ok, serial = exports.concept_flexhour:GiveWatch(source, { base = 'timor_basic' }, true)
-- Release the watch a deleted or banned character was wearing (keepWorn = true).
-- identifier = the character id from your framework (the owner column of flexhour_wrist), or an online player's server id.
-- Returns true, serial, or false when nothing was on that wrist.
local released, serial = exports.concept_flexhour:ReleaseWrist(identifier)
Gli id dei modelli sono in shared/catalog.lua (FH.BaseOrder). Funziona anche il nome dell'oggetto senza il prefisso fh_.
concept_flexhour.useBox e concept_flexhour.useWatch sono gli export degli oggetti che l'inventario chiama. Non devi chiamarli tu.
| Evento | Argomenti | Quando |
|---|---|---|
flexhour:purchased |
src, build, price, kind |
Un giocatore ha comprato un orologio. |
flexhour:watchRobbed |
robber, victim, serial, build |
Un orologio indossato è stato rapinato. |
flexhour:fenceAlert |
src, coords, build |
Una vendita al ricettatore è stata segnalata. Chiama anche Config.Fakes.onAlert. |
flexhour:wristReleased |
owner, serial, build |
ReleaseWrist ha rimosso un orologio indossato. |
flexhour:suspect |
src, reason, serial |
Un possibile duplicato ('duplicate', 'watch_twice'). |
AddEventHandler('flexhour:watchRobbed', function(robber, victim, serial, build)
-- log it, alert the police, ...
end)
Le tabelle vengono create al primo avvio:
| Tabella | Contenuto |
|---|---|
flexhour_serials |
Il registro degli orologi autentici (numero di serie, configurazione, proprietario). |
flexhour_wrist |
Gli orologi indossati custoditi da FlexHour (keepWorn = true). |
flexhour_worn |
Cosa indossa ogni personaggio. |
flexhour_fit |
Le regolazioni al polso salvate. |
flexhour_fit_presets |
Le regolazioni salvate dai giocatori. |
flexhour_stands |
Le vetrine e le loro scorte. |
flexhour_meta |
Stato interno. |
FlexHour costruisce solo ciò che puoi effettivamente vedere. I limiti sono fissi:
| Problema | Soluzione |
|---|---|
missing ox_inventory items nella console |
Aggiungi gli oggetti da Oggetti. |
model "fh_…" is not streamed in F8 |
La cartella stream/ è incompleta. Esegui /fhmodels, poi ricopia stream/ dal download. |
| L'orologio galleggia accanto alla mano | Esegui /watchfit. Per un intero modello di ped, un admin salva la regolazione predefinita con G. |
No such export useBox in resource concept_flexhour |
La cartella è stata rinominata. Lasciala concept_flexhour. |
ESX's built-in inventory cannot hold a watch |
Installa un inventario con metadati per oggetto. |
| L'orologio sparisce dall'inventario quando lo indosso | È keepWorn = true: l'orologio è al polso. /watch lo toglie. |
| La commessa o il ricettatore non elenca il mio orologio | È al tuo polso. Toglilo prima. |
| I soldi non vengono presi o pagati | Config.PayAccounts deve usare nomi di conti che il tuo framework conosce tramite il bridge (cash, bank, money). |
| Tutti possono usare i comandi admin | Imposta Config.AdminOpenToAll = false. |
Un inventario non scrive subito ogni modifica nel database, quindi un crash brusco può riportarlo indietro di qualche minuto.
Spegni il server da txAdmin, non chiudendo la finestra.
Config.AdminOpenToAll sia false./fhmodels non elenchi nulla.setr ox:locale).flexhour_boutique parta dopo concept_flexhour.We aim to reply on Discord within 24 hours on business days.
Ti serve aiuto con l'installazione? Entra su Discord o support@conceptstudio.store.