Script forniti
Questa pagina fa parte di Scrivere script Lua. La distribuzione fornisce questi script sotto
scripts/, e mgctl init li copia nella root: ciascuno è un esempio da leggere e modificare. Come uno
script viene associato a un template è spiegato in Script dei mobile e Script degli oggetti,
dove sono elencati wander.lua e potion.lua.
common/cooldown.lua
Section titled “common/cooldown.lua”Usa local cooldown = require("common.cooldown") per controllare una scadenza con le stesse regole negli script.
Passa item, mobile o npc come archivio per usare le proprietà salvate esistenti; le chiavi restano quelle fornite.
Crea un archivio separato cooldown.memory() per lo stato temporaneo, come l’attesa fra pozioni di cura.
| Funzione | Risultato |
|---|---|
cooldown.ready(store, serial, key, now?) |
True se non c’è una scadenza valida o è stata raggiunta |
cooldown.remaining(store, serial, key, now?) |
Secondi fino alla scadenza, mai sotto zero |
cooldown.start(store, serial, key, seconds, now?) |
Salva now + seconds; true solo se l’archivio accetta la scrittura |
cooldown.clear(store, serial, key) |
Rimuove la scadenza; true solo se l’archivio accetta la scrittura |
cooldown.memory() |
Un nuovo archivio indipendente senza persistenza |
local cooldown = require("common.cooldown")
cooldown.start(mobile, player, "daily.reward.next", 86400)local seconds_left = cooldown.remaining(mobile, player, "daily.reward.next")
local temporary = cooldown.memory()cooldown.start(temporary, player, "heal", 11)local can_heal = cooldown.ready(temporary, player, "heal")Il valore opzionale now è un numero finito per controlli deterministici; altrimenti l’helper usa world.now(),
secondi UTC interi. Alla scadenza esatta è pronto. Le durate devono essere finite e non negative; zero è
pronto subito. I seriali devono essere interi positivi a 32 bit e le chiavi stringhe non vuote né composte solo
da spazi. Gli argomenti non validi generano un errore Lua prima della scrittura. Una scadenza salvata assente,
non numerica o non finita viene considerata pronta. Un seriale valido senza entità può quindi risultare pronto,
mentre start restituisce comunque false se l’archivio nativo non può scrivere: questo helper non verifica
l’accesso agli oggetti o il diritto a una ricompensa.
Le scadenze nelle proprietà seguono la persistenza del salvataggio del mondo. Gli archivi in memoria appartengono
al consumatore che li conserva: un nuovo archivio è vuoto, non viene salvato e non viene svuotato automaticamente
al logout. Chiama clear quando lo stato non serve più. Ricaricare un consumatore che ricrea il proprio archivio
locale azzera quello stato; ricaricare solo l’helper non cancella un archivio esistente. Le correzioni dell’orologio
influiscono sulle scadenze UTC.
Gli script forniti trick_or_treat.lua e fillable.lua mantengono le proprietà esistenti trick_or_treat.next e
fill.next. potion.lua mantiene in memoria l’attesa di cura. Questo helper non programma callback: usa
timer.after o il persistente item.start_timer quando del codice deve essere eseguito più avanti.
common/random.lua
Section titled “common/random.lua”Usa local random = require("common.random") per scegliere valori da liste senza ripetere la logica. L’helper usa
math.random per impostazione predefinita e non ne imposta mai il seed. Ogni chiamata accetta una funzione RNG
opzionale, utile per test deterministici.
| Funzione | Risultato |
|---|---|
random.choice(list, roll?) |
Un valore da una lista contigua; nil se la lista è vuota |
random.chance(probability, roll?) |
True con probabilità da 0 a 1; 0 è sempre false e 1 sempre true |
random.weighted(entries, roll?) |
Un value in base al suo weight intero; nil se il totale è zero |
local random = require("common.random")
local color = random.choice({ "red", "blue" })local succeeds = random.chance(0.25)local weighted_color = random.weighted({ { value = "red", weight = 60 }, { value = "blue", weight = 40 },})local predictable = random.choice({ "red", "blue" }, function(count) return count end)Le liste devono avere chiavi intere consecutive da 1, senza buchi o campi aggiuntivi. I pesi devono essere interi non negativi e il loro totale non deve superare 2.147.483.647. Una voce pesata richiede un valore diverso da nil; false è un valore valido. Le voci con peso zero non vengono mai selezionate. Argomenti o risultati RNG non validi generano un errore Lua.
Per choice e weighted, roll(count) deve restituire un intero da 1 a count inclusi. Per chance, roll() deve
restituire un numero in [0, 1); il successo richiede un valore strettamente inferiore alla probabilità. Liste vuote,
peso totale zero ed estremi della probabilità non effettuano estrazioni. L’RNG predefinito viene risolto a ogni
chiamata, quindi si può sostituire il generatore nei test senza modificare i seed globali.
Halloween usa choice per battute, caramelle e graphic del sangue. Natale usa weighted per la distribuzione
60/24/16 delle decorazioni, mantenendo i limiti delle estrazioni intere originali. Per la notazione dei dadi,
continua a usare il modulo nativo dice.roll e dice.try_roll.
monster.lua
Section titled “monster.lua”Il file scripts/mobiles/monster.lua della distribuzione è lo script dei mostri che attaccano i giocatori,
seguendo l’IA corpo a corpo di ModernUO: insegue un giocatore e lo combatte standogli accanto. Un template lo adotta con
script_id = "monster"; lo fanno le creature il cui NPCAI di UOX3 è malvagio, incantatore malvagio o caotico (gli orchi, gli orchi giganti, i lucertoloni, i draghi, i non morti e gli altri 200 circa template
e quelli basati su di essi; migrazione da UOX3); i buoni combattenti e incantatori, che combattono solo i criminali, no. Gli incantatori, tra cui wraith, spectre e lich,
lanciano da lontano gli incantesimi di Magery (common/caster.lua) quando il loro template imposta
spell_circles. Il comportamento è il modulo
condiviso common/creature.lua, creature.new({ hunts = true }). Un mostro si trova in uno di tre stati:
| Stato | Cosa fa | Termina quando |
|---|---|---|
| wander | Passeggia nella propria casa, l’area della regione di spawn: circa un passo ogni due secondi, soprattutto dritto. Passeggia con npc.wander, che lo riporta dall’esterno, come dopo un inseguimento. Un ciclo di pensiero su venti riposa da 15 a 25 secondi, con il suono idle e un movimento inattivo |
Vede un giocatore |
| chase | Minaccia il giocatore con il suono start_attack e un’animazione, passa in modalità guerra e gli si avvicina con npc.walk_to, un passo ogni ciclo di pensiero, senza correre. Accanto a lui si orienta verso di lui e lo combatte con combat.attack, una volta: colpi, impatti e morte sono del servizio di combattimento |
Il giocatore si nasconde, se ne va, dista più di 32 caselle o non si avvicina per 20 secondi (fuori portata) |
| guard | Smette di combattere, resta in modalità guerra per 10 secondi guardandosi intorno | Vede un giocatore, oppure il tempo termina: torna a wander, in pace |
Un mostro colpito, o mancato, risponde all’attacco (se ne occupa il servizio di combattimento) e si rivolge a chi lo combatte qualunque cosa stesse facendo, passeggiando o facendo la guardia, anche se non lo aveva visto: passa in modalità guerra e lo insegue, senza minacciarlo di nuovo. Uno che già combatte si rivolge a un nuovo aggressore che non gli è nascosto ed è più vicino del suo bersaglio, come decide il servizio di combattimento; una creatura domata mantiene il bersaglio che le è stato ordinato.
Un inseguimento segue la ricerca del percorso, che aggira muri e porte chiuse e, quando la preda non si può raggiungere, porta al punto più vicino; non trova mai una preda che non ha in linea di vista, ma segue una che ha visto entro 32 caselle. Un passo conta solo quando avvicina la creatura alla preda più di quanto lo sia stata in questo inseguimento: 40 think, 20 secondi, senza un passo simile, sia che resti ferma, sia che il passo venga rifiutato, sia che vada avanti e indietro lungo un muro dietro una preda che non può raggiungere (dentro una casa chiusa a chiave, su un tetto, oltre un fiume), le fanno rinunciare alla preda, restare di guardia e poi passeggiare. Una preda che si muove può essere ripresa alla vista successiva, perché è un nuovo inseguimento. Il suo stato non viene salvato: dopo un riavvio una creatura riparte dal passeggiare, e ciò che una mente le aveva lasciato (correre, modalità guerra) viene azzerato.
Cerca una preda ogni due secondi mentre passeggia e ogni secondo quando fa la guardia, tra le prime sei di
npc.mobiles_in_sight: entro 16 caselle e in linea di vista, da occhio a occhio, la più vicina per prima. La sua preda è qualsiasi giocatore
e, tra gli NPC, quelli con il nome blu, i cittadini, mobile.notoriety innocente: un mostro in una città attacca
la gente per strada oltre ai giocatori. Lascia in pace quelli gialli, venditori, banchieri e
guardie, che non si possono ferire, e le altre creature, animali o mostri. Non vede mai un giocatore nascosto, un fantasma, un
game master o un amministratore. Una volta che insegue la preda la segue senza vederla (npc.can_see con
in_sight false), fino al limite di inseguimento. Una preda che non riesce a raggiungere viene lasciata in pace finché non si muove. La sua minaccia e il suo gesto
sono le azioni di un corpo da mostro; una creatura con corpo umano o animale, come un brigante, non ne esegue,
perché quei corpi numerano le azioni in modo diverso. Ciò che un mostro sta facendo è mantenuto in memoria per seriale, non
salvato, e dimenticato quando muore: dopo un riavvio, o quando nessun giocatore è abbastanza vicino da farlo pensare, riparte
dal movimento casuale. I numeri (16, 32, i tempi) sono costanti all’inizio del file.
Le guardie cittadine attaccano i mostri, come in ModernUO: guard.lua considera ricercato qualsiasi NPC il cui
npc.script_id è monster, come un criminale, a meno che sia morto o domato, e ovunque si trovi: una guardia che un game
master ha generato in un cimitero fuori dalle città combatte lì i mostri, senza una postazione da custodire. Un criminale che non
è un mostro è ricercato solo in una regione sorvegliata. La guardia appare accanto a lui, lo colpisce
e lo uccide con un colpo.
guard.lua
Section titled “guard.lua”Il file scripts/mobiles/guard.lua della distribuzione è lo script delle guardie cittadine: quelle presenti nelle
città tramite spawn e quelle chiamate da un giocatore dicendo “guards” (vedi
ultima.crime). Un template lo adotta con script_id = "guard"; lo fanno guard,
m_guard e f_guard. Una guardia uccide con
un colpo un criminale che è un NPC, come quella di ModernUO, e si limita a stargli addosso se è un giocatore: lo script risparmia i giocatori, anche se ora
i giocatori possono morire. Una
guardia si trova in uno di due stati:
| Stato | Cosa fa | Termina quando |
|---|---|---|
| post | Passeggia intorno alla propria postazione, l’area della regione di spawn, circa un passo ogni quattro secondi, con npc.wander, che la riporta anche dall’esterno |
Vede un criminale: passa ad arrest |
| arrest | Passa in modalità guerra; quando non è accanto al criminale appare su una casella libera a un passo da lui (world.spot_beside; sulla sua se nessuna è libera), con uno sbuffo di fumo dove si trovava e dove arriva e il suono del teletrasporto; dice “Rimpiangerai le tue azioni, porco!” (messaggio 30138). Poi resta sul criminale, rivolta verso di lui, e lo rincorre con npc.walk_to quando si muove. Accanto a un NPC criminale colpisce (un’animazione di attacco) e un secondo dopo l’NPC è morto: mobile.kill, con la guardia come uccisore, quindi muore come qualsiasi altro e lascia il cadavere |
L’NPC viene ucciso; oppure il criminale è perdonato o il suo tempo termina, si nasconde, lascia la regione sorvegliata, si allontana oltre 24 caselle dalla guardia o dalla postazione, oppure non può essere raggiunto per 10 secondi: ritorno alla postazione, in pace |
Cerca un criminale ogni secondo: il giocatore o NPC più vicino di npc.nearby entro 12 caselle il cui
mobile.criminal o mobile.is_murderer è true (un nome rosso è ricercato come uno grigio), che si trova in una regione sorvegliata (world.is_guarded; un mostro non domato è ricercato ovunque si trovi) a non più di 24
caselle dalla postazione della guardia (npc.home, nessuna per una guardia generata a mano), e che vede (npc.can_see); solo un criminale costa il
controllo lungo la linea di vista. Il riferimento è la postazione, non la guardia, quindi un criminale non può condurre una guardia
fuori città passo dopo passo. Un criminale che non riesce a raggiungere viene lasciato in pace finché non si muove. Non vede mai un
giocatore nascosto, un game master o un amministratore. Un NPC appena ucciso è ancora presente mentre
cade: la guardia non lo attacca di nuovo. Un teletrasporto rifiutato lascia la guardia dov’è, affinché
corra verso il criminale.
Una guardia chiamata porta la prop guard.summoned: è già arrivata accanto al criminale e ha pronunciato la battuta,
quindi resta su di lui in silenzio senza passeggiare, e quando quel criminale viene lasciato andare non arresta
nessun altro e attende di essere mandata via. Ciò che una guardia sta facendo viene mantenuto in memoria per seriale, non salvato.
I numeri (12, 24, i 10 secondi) sono costanti all’inizio del file.
La guardia arciere, template archerguard (le guardie chiamate a Ilshenar e Malas, sul modello dell’ArcherGuard di ModernUO, senza il suo cavallo e le sue statistiche: sono quelle della guardia con un arco), è
questa guardia con un arco in mano e combat.range di 10. Davanti a un NPC che attacca, un criminale o un mostro, che sia
entro la sua portata e nella sua vista, non gli si avvicina: resta dov’è, lo guarda e avvia lo scontro
(combat.attack), e il servizio di combattimento spara con l’abilità Archery; l’arresto finisce quando il bersaglio è morto.
Fuori portata, o fuori vista, gli si avvicina come ogni guardia, e spara da lì. Con un giocatore è la stessa guardia
delle altre: gli si avvicina e gli sta addosso.
animal.lua e scared_animal.lua
Section titled “animal.lua e scared_animal.lua”Gli animali, secondo l’IA animale di ModernUO, usano lo stesso modulo con hunts = false: passeggiano nella propria casa, ogni tanto si riposano
con il suono di inattività e un’animazione, e non attaccano mai un giocatore. scripts/mobiles/animal.lua (script_id = "animal", le
creature il cui NPCAI di UOX3 è 6: orsi, lupi e simili) reagisce quando viene colpito, come un mostro.
scripts/mobiles/scared_animal.lua (script_id = "scared_animal", NPCAI 12) no: un animale pauroso colpito
smette di combattere e fugge, fino a dodici celle e al massimo dieci secondi, lontano da chi l’ha colpito, poi riprende a passeggiare. Il
servizio di combattimento fa rispondere al colpo ogni NPC colpito tranne uno che fugge: il modulo delle creature imposta la prop
combat.flees su una creatura creata con flees = true, alla sua generazione e di nuovo a ogni think (a una creatura domata
viene tolta: combatte quando è colpita, e così una il cui template non fugge più), e il servizio legge la prop, non
l’id dello script, quindi qualsiasi script con quell’opzione si comporta allo stesso modo.
common/creature.lua
Section titled “common/creature.lua”scripts/common/creature.lua è ciò che i tre script sopra condividono, preso con
local creature = require("common.creature"). creature.new(options) restituisce la tabella che uno script mobile definisce, con il suo
on_think; le opzioni sono hunts (attacca i giocatori che vede), prey (una funzione che dice chi attacca, al posto dei
giocatori e della gente delle città: la usano le guardie delle terre selvagge), flees (fugge da un colpo invece di
rispondere) e flee_at (vedi sotto). Una creatura il cui template imposta spell_circles lancia anche incantesimi, vedi
common/caster.lua. I pezzi di una mente che le guardie condividono con essa sono funzioni del modulo:
creature.is_given_up(mind, who) e creature.give_up(mind, who, there) (un mobile che non si è potuto raggiungere viene
lasciato stare finché non si muove), creature.forget_given_up(mind) (lo dimentica) e creature.clear_stale_war_mode(serial) (un mobile
rimasto in modalità guerra dopo un ricaricamento degli script). pet_orders.is_owned(serial) dice se una creatura ha un
padrone (domata o evocata).
Arcieri. Una creatura che impugna un arco o una balestra ha combat.range di 10 o 8 (Combattimento):
il suo inseguimento si ferma dove la preda è entro quella portata e nella sua linea di vista, npc.can_see, la guarda e avvia
lo scontro, e il servizio di combattimento spara. Troppo lontana, cammina finché la preda è un passo dentro la portata; entro la portata ma
senza linea di vista, si avvicina. Non arretra davanti a una preda che si avvicina: neppure gli arcieri di ModernUO,
a meno che il costruttore lo chieda.
Fuga da feriti, come le creature di ModernUO: una che combatte (non un animale pauroso, che scappa da un colpo) e ha
meno di flee_at percento dei punti vita scappa con una probabilità su dieci a ogni think, per 10-30 secondi,
dritta lontano dalla preda, correndo. La percentuale è il flee_at del template, altrimenti l’opzione dello script: 20 per un
mostro, 10 per un animale; un template con flee_at = -1, come il FLEEAT=-1 di UOX3 dà ai non morti, agli elementali e ai
demoni, non scappa mai. Mentre scappa non risponde a un colpo: imposta la prop dell’NPC combat.passive, che il servizio di
combattimento legge, e quando finisce torna a passeggiare, e quindi a cacciare di nuovo.
Morsi che sanguinano, come il Bleed Attack classico: una creatura il cui template imposta bleed_chance (il
percento) fa sanguinare la vittima di un colpo andato a segno, col modulo bleed — cinque colpi da due secondi, il
danno che rallenta da 5–10 a 1–2 e doppio per un PNG, una pozza di sangue sotto la vittima a ogni colpo, e il quinto
colpo chiude le ferite. La benda la fascia. Il dire wolf sanguina un colpo su cinque, il lupo grigio uno
su dieci.
Calmata da un bardo (Peacemaking): la prop bard.pacified_until tiene il secondo (world.now()) in
cui la calma finisce. Il servizio di combattimento la legge per qualsiasi NPC, con o senza script, quindi una creatura
calmata non risponde a un colpo; finché dura, creature.lua ferma anche il suo combattimento e le impedisce di cacciare,
e passeggia soltanto (una creatura con un padrone continua con i suoi ordini, come la calma di ModernUO che impedisce solo
di prendere un bersaglio). Quando il tempo è scaduto la prop viene tolta. Sopravvive a un ricaricamento degli script e a un
riavvio. Un colpo spezza la calma con una probabilità di (hits_max - hits) * 0.001, una su mille per ogni punto vita
che le manca (on_damage della tabella che crea creature.new: uno script che definisce un proprio on_damage su di essa
lo sostituisce).
Provocata da un bardo (Provocation): le prop bard.provoker, bard.provoke_target e
bard.provoke_until mettono una creatura contro un’altra. Finché durano, creature.lua la fa inseguire e combattere
quella creatura e nessun altro (un combattimento iniziato da chi l’ha colpita viene fermato a ogni think), senza scappare
da un colpo. Come in ModernUO, la provocazione finisce subito quando il bersaglio è perso (ha lasciato il mondo, è morto,
è su un’altra mappa o più lontano delle 16 tile che la creatura vede) e quando il tempo è scaduto e il bardo è perso
(andato, su un’altra mappa o più lontano di 16 tile; un bardo nascosto, o morto, che resta vicino la tiene viva oltre i
30 secondi). La morte toglie le prop.
Una tua creatura lo prende allo stesso modo: mycreature = creature.new({ hunts = true }) in
scripts/mobiles/mycreature.lua. Una root i cui script sono sostituiti manualmente ha bisogno anche di scripts/common/, altrimenti le creature
smettono di pensare.
common/caster.lua
Section titled “common/caster.lua”scripts/common/caster.lua è il modo in cui combatte una creatura il cui template imposta spell_circles (il cerchio più
alto di Magery da cui lancia, da 1 a 8, il SPATTACK di UOX3), secondo le regole del classico mago non intelligente.
common/creature.lua chiama caster.think(serial, mind, target, distance) a ogni think dell’inseguimento di una creatura
che non è domata né evocata; restituisce true quando la creatura mantiene il suo posto. Una creatura senza spell_circles,
o senza Magery, non prende altra strada: caster.highest_circle(serial) è 0 e il mostro combatte come prima.
Dove sta. Entro 12 caselle dalla preda e nella sua linea di vista si ferma, si orienta verso la preda e lancia quando
arriva il suo turno; fuori portata o fuori vista insegue come qualsiasi mostro, e così fa quando il suo mana è sotto quello
di un incantesimo del primo cerchio (la creatura lo rigenera con la sua Intelligence, come ogni NPC, e nel frattempo
combatte in mischia). Accanto alla preda combatte in mischia come un mostro e lancia comunque quando arriva il suo turno.
Mentre il ritardo di un incantesimo corre non si muove (npc.step viene rifiutato e npc.walk_to risponde "blocked"
subito, con il suo percorso conservato), e un colpo non la disturba.
La scelta. Il cerchio più alto è clamp(floor((Magery + 20) / (100 / 7)), 1, 8) e non oltre spell_circles.
Avvelenata, lancia Cure su sé stessa, anche quando la preda è fuori vista; altrimenti, con una probabilità pari a un decimo
del suo Magery come frazione, Greater Heal quando le mancano più di 50 punti vita (Heal quando quel cerchio è fuori dalla sua
portata o il mana non basta) e Heal quando le mancano più di 10. Una creatura selvatica non ha attesa tra una cura e l’altra:
l’attesa del mago classico, sqrt(600 - Intelligence) secondi, è per quelle domate, che qui non lanciano mai. Altrimenti
uno su sedici: Poison (due, a meno che la preda sia avvelenata), un potenziamento su di sé (Bless, Strength, Agility o
Cunning), una maledizione (Curse una volta su quattro da Magery 40, altrimenti Weaken, Clumsy o Feeblemind; due), Paralyze
(Magery sopra 50, una preda non paralizzata), Mana Drain (Mana Vampire una volta su due da Magery 80), e il resto è danno:
uno tra un numero di posti doppio dei cerchi, Magic Arrow, Harm, Fireball, Lightning e Mind Blast due volte ciascuno, poi
Energy Bolt, Explosion e Flame Strike. Un incantesimo oltre i cerchi che ha, o per cui non ha mana, viene sostituito dal
più alto incantesimo di danno che ci sta, oppure non lancia; senza un incantesimo scelto, o con un lancio che il motore ha
rifiutato, la creatura combatte come un mostro (insegue e colpisce) e sceglie di nuovo al think successivo. Vengono scelti
solo incantesimi che colpiscono un mobile: niente evocazioni, campi, Teleport, Recall, Invisibility o Resurrection.
La pausa. Dopo un lancio, contata dal suo inizio, così che il ritardo dell’incantesimo ne fa parte, il successivo non
arriva prima di 6 - 1.25 s o 6 - 0.75 s secondi, s = 3 * Magery / 100: circa da 2,25 a 3,75 secondi a 100 (mai più
breve del ritardo dell’ottavo cerchio, 2,25 secondi). I think sono due al secondo, quindi si conta in think. Un NPC non ha
alcun recupero dopo un lancio nel motore: questa pausa è la sua sola.
Il lancio è spell.cast_at (Magery): gli script degli incantesimi sono quelli del
giocatore, e così sono il mana e il controllo di Magery (un fallimento); niente reagenti e niente parole.
caster.random(count) e caster.chance() sono i dadi, math.random, che un test sostituisce.
orione.lua e vega.lua
Section titled “orione.lua e vega.lua”Il repository fornisce anche due gatti di Moongate v2, orione e vega (templates/mobiles/moongate_cats.toml con scripts/mobiles/orione.lua e vega.lua): generali con .spawn orione o .spawn vega.
door.lua
Section titled “door.lua”La distribuzione fornisce anche scripts/items/door.lua, lo script del template
decoration_door che .decorate assegna a porte e cancelli. Un doppio clic
su una porta chiusa apre lei e la porta collegata (prop door.link): la grafica passa alla
successiva, la porta si sposta di lato secondo la prop facing e riproduce il suono del suo
decoration_type (metallo, legno, cancello o segreta). Un doppio clic su una porta aperta chiude entrambe
quando nessuno si trova in uno dei due vani. Una porta aperta si chiude da sola dopo 20 secondi, poi
riprova ogni 10 secondi mentre il vano è occupato. Una porta che non può spostarsi di lato, come
una al bordo della mappa, resta chiusa. Un NPC che cammina verso un luogo e trova una porta chiusa sulla sua strada la apre tramite on_npc_use(serial, opener): la porta e quella collegata si aprono e si richiudono da sole come per un giocatore, e una porta chiusa a chiave, o una porta doppia con una delle due ante a chiave, resta chiusa senza una parola. Lo stato aperto è la prop door.open, con la
posizione chiusa in door.x, door.y e door.z, salvata con la porta, così come il timer di chiusura automatica (il timer close della porta, avviato con
item.start_timer): una porta lasciata aperta quando il server si arresta si chiude quando torna attivo. Una porta salvata
aperta da una versione precedente non ha timer e resta aperta finché qualcuno la usa. Una porta chiusa con la prop locked non
si apre per i giocatori, che leggono “È chiuso a chiave.” (messaggio 398, nella lingua del server), a meno che
portino in qualsiasi punto dello zaino una chiave la cui prop key.value è il key.value della porta
(messaggio 405: la aprono e resta chiusa a chiave); game master e amministratori la aprono
(messaggio 404). La prop proviene dai dati della decorazione
(props = { facing = "west_cw", locked = true }), come le porte laterali della banca di New Haven.
.lock assegna a una porta un numero di chiave e .key ne crea la chiave.
light.lua
Section titled “light.lua”scripts/items/light.lua accende e spegne candele, candelabri, lanterne, lampioni, applique e
torce: lo usano il template decoration_light e i template delle luci di
templates/items. Un doppio clic su una luce spenta le assegna la grafica accesa (le coppie di ModernUO),
una forma della luce se non ne ha e il suono 0x47; un doppio clic su una accesa le assegna la
grafica spenta e il suono 0x3BE, conservando la forma per la volta successiva. Una luce senza grafica
spenta, come un braciere, resta com’è. Le luci posizionate da .decorate hanno la prop
protected: solo game master e amministratori le accendono o spengono. I lampioni cittadini
si accendono e spengono da soli: ogni 30 secondi il server chiama on_darkness(serial, dark) su un
lampione il cui punto è diventato buio o luminoso (ultima.world.lamp_post_light), e light.lua
cambia la grafica silenziosamente.
kindling.lua e campfire.lua
Section titled “kindling.lua e campfire.lua”scripts/items/kindling.lua è l’abilità Camping, come il Kindling di ModernUO: il bottone
dell’abilità non fa nulla, il legnetto sì. Un doppio clic su un legnetto a portata — portato, o a
terra entro 2 caselle — prova skill.check(user, "camping", 0, 100); un fallimento legge “You
fail to ignite the campfire.” (501696). Al successo un pezzo dello stack è speso e un falò è
acceso dove giace il legnetto, per quello a terra, o sul primo lato del giocatore su cui si può
stare e dove non sta nessuno (world.standing_z e world.can_fit; il fuoco prende l’altezza di
quel pavimento), e senza nessuno la richiesta è rifiutata con “There is not a spot nearby to place
your campfire.” (501695). Un legnetto sollevato sul cursore non si usa. Il fuoco è il template campfire (0xDE3, non
spostabile; il suo script e decays = false sono stati aggiunti al template in
templates/items/building/lighting.toml), acceso con circle300.
scripts/items/campfire.lua accompagna il fuoco alla sua fine, come quello di ModernUO, con i
timer nominali che il legnetto avvia: 60 secondi che brucia, 30 che muore (0xDE9, circle150),
10 spento (0xDEA, nessuna luce), e l’oggetto è cancellato. Mentre brucia o muore è una fonte di
calore per cucinare (common/heat.lua conta entrambe le sue grafiche tra i
fuochi). Il giaciglio e il logout immediato delle ere successive non sono costruiti.
food.lua
Section titled “food.lua”scripts/items/food.lua è lo script di ciò che si può mangiare, come Food di ModernUO: i template
convertiti del cibo contengono script_id = "food". Il doppio clic su un pezzo ne mangia uno: il valore di fame del giocatore aumenta
della prop food.fill dell’oggetto (3 in sua assenza), fino a 20; recupera da 6 a 8 punti di stamina, più uno per ogni 5 punti del riempimento, emette
il suono e, con un corpo di tipo Human (mobile.body_type), il gesto di mangiare, e legge quanto si sente sazio
nella lingua del client (messaggi da 500868 a 500872). Un giocatore sazio legge “Sei semplicemente troppo pieno
per mangiare ancora!” (500867) e non mangia nulla. Una prop poison.level — quella che vi mette
l’abilità Poisoning — avvelena chi mangia il pezzo.
drink.lua
Section titled “drink.lua”scripts/items/drink.lua è lo script di ciò che si può bere, come le bevande di ModernUO: i template
convertiti delle bevande contengono script_id = "drink". Un doppio clic ne beve un sorso: il valore di sete del giocatore aumenta
della prop drink.fill dell’oggetto (3 in sua assenza), fino a 20, ed emette il suono e, con un corpo di
tipo Human, il gesto di bere. La grafica indica quanti sorsi contiene un contenitore pieno: una
brocca o una bottiglia 5, una caraffa 10, un bicchiere o una tazza 1; i sorsi rimasti vengono mantenuti nella prop drink.uses.
Una volta vuota, una brocca, un bicchiere o una tazza passa alla grafica vuota, viene rinominata e resta; una bottiglia o caraffa
scompare. Un giocatore dissetato legge “Sei semplicemente troppo pieno per bere ancora!” e non beve nulla.
Riempimento, versamento e ubriachezza non sono ancora presenti.
Le abilità di osservazione
Section titled “Le abilità di osservazione”Cinque abilità della finestra delle abilità, in scripts/skills/, come in ModernUO. Il giocatore sceglie un bersaglio e
legge i testi del client come messaggi di sistema (ModernUO li mostra sopra chi è esaminato). Ognuna aspetta il delay
di data/skills.toml. La quinta, Arms Lore, legge un oggetto: arms_lore.lua.
anatomy.lua: un mobile entro 8 caselle; il controllo da 0 a 100 che riesce dice quanto sembra forte e agile e, da 65 punti, quanta resistenza gli resta. Ciò che legge è sbagliato fino a 25 meno uno ogni 4 punti dell’abilità. Un controllo fallito legge che non riesce a farsi un’idea delle sue caratteristiche fisiche; se stessi, un PNG invulnerabile e un oggetto hanno testi propri.evaluating_intelligence.lua: lo stesso per la mente: da 0 a 120, “He”, “She” o “It” (mobile.is_female) e, da 76 punti, il mana rimasto; sbagliato fino a 20 meno uno ogni 5 punti.forensic_evaluation.lua: un cadavere entro 10 caselle, da 0 a 100: un cadavere umano dice da chi è stato ucciso (corpse.killerecorpse.killer_name, “no one” se non da qualcuno); quello di un animale o di un mostro legge “You notice nothing unusual.”. Un mobile, da 40 a 100, “You notice nothing unusual.”, perché non c’è una gilda dei ladri. Chi ha disturbato il cadavere e chi lo ha studiato prima non viene ancora registrato.detecting_hidden.lua: un luogo entro 12 caselle, o se stessi: ogni giocatore o PNG nascosto entro un decimo dell’abilità in caselle (la metà se il controllo fallisce, e nessuna sotto 10 punti) viene mostrato se l’abilità del cercatore più un tiro da -10 a 10 non è inferiore al suo Hiding più il proprio; legge “You have been revealed!”. Lo staff viene trovato solo da altro staff; l’abilità aspetta 10 secondi. Un contenitore trappolato scelto direttamente — la proptrap.type— è nominato «[trapped]» (500813), come un’etichetta sopra il forziere, quando il cercatore gli sta entro un decimo della sua abilità in caselle e il controllo da 0 a 100 passa: nominato, non disarmato (lo fa remove_trap). Case e fazioni non ci sono ancora.
arms_lore.lua
Section titled “arms_lore.lua”scripts/skills/arms_lore.lua è l’abilità Arms Lore, come in ModernUO. on_use chiede “What item do you wish to get
information about?” (500349) e dà il cursore: il pezzo deve essere del giocatore, portato o indossato, oppure stare a
terra entro 2 caselle (ciò che item.in_range dice di un oggetto a terra); qualunque altra cosa indicata non dice nulla,
e una cosa che non è né arma né armatura dice “This is neither weapon nor armor.” (500352). Il controllo da 0 a 100 che
fallisce dice “You are not certain…” (500353). Un successo legge la condizione del pezzo e poi il suo valore in
combattimento, con i testi del client:
- La condizione, quando il suo massimo è noto (le prop
durabilityemax_durabilitydel pezzo, almax_hitsdel suo template), è il decimo dei suoi punti rimasti (1038285 + esso): il nono di un pezzo intero, e 1038294 dice “is in perfect condition.” - Il valore di un’arma è la metà tra il suo
damage_mine il suodamage_max(ciò cheitem.combat_statslegge dal suo template), un livello ogni cinque fino a trenta e nessuno sotto tre, uno in più per un’arma a due mani, sulla base del suo tipo: una spada, un’ascia o un’arma in asta taglia (1038220), una mazza schiaccia (1038222), un’arma da scherma trafigge (1038218), un arco, una balestra o un’arma da lancio si scaglia (1038224), un’arma senza tipo ha la base semplice (1038216). - La protezione di un pezzo di armatura è il quinto del suo valore, che i testi fermano a 35 (1038295 + esso).
Non ci sono ancora: i pezzi portati o indossati da un altro, per cui c’è l’abilità Snooping (ModernUO li legge
anch’essa), il veleno di un’arma (Moongate non ne ha da leggere), la barda di un drago di palude e le proprietà degli
oggetti di AOS. L’abilità aspetta il secondo di data/skills.toml.
tracking.lua
Section titled “tracking.lua”scripts/skills/tracking.lua è l’abilità Tracking, come in ModernUO. on_use toglie la freccia dell’ultima ricerca
(arrow.clear), dice “What do you wish to track?” (1011350) e apre il gump track_what
(templates/gumps/track_what.xml): animali, mostri, PNG umani o giocatori. Il gump non si chiama tracking perché un
gump risponde alla tabella di script del proprio id, e quel nome è quello dell’abilità. Il suo script,
scripts/gumps/track_what.lua, prova skill.check(user, "tracking", 0, 21.1): un fallimento dice “You see no evidence
of those in the area.” (1018092), e un successo prova di nuovo l’abilità da 21.1 a 100 (il guadagno passivo di ModernUO).
Un successo guarda fino a 10 tile più 10 per ogni 10 punti di abilità (110 a 100 punti), con world.mobiles_in_range in
sguardi di al più 32 tile. La ricerca parte dai 10 tile del raggio di base e raddoppia il riquadro finché l’elenco non è
pieno di mobile più vicini del suo bordo, così una folla vicina non viene mai scorsa fino al fondo di un raggio di cento
tile; passa per 1500 mobile al massimo, il che la tiene dentro le 150000 istruzioni di una ripresa dello script. Elenca i
12 più vicini del tipo, dal più vicino, con l’immagine del corpo (gump.portrait), il nome e la direzione (i messaggi
30264–30271 di data/messages). I tipi si distinguono con mobile.is_player e mobile.body_type: un animale, un
mostro o un umano che non è un giocatore, oppure un giocatore. Non sono elencati: il cercatore stesso, i morti, un membro
dello staff nascosto che il cercatore non supera di grado (solo un amministratore trova un game master nascosto, nessuno
un amministratore nascosto, come il controllo del livello di accesso di ModernUO) e, per un giocatore, chi ha Hiding e
Stealth troppo alti per il Tracking e il Detecting Hidden del cercatore (la probabilità è il numero intero di 50 * (2 *
tracking + detecting hidden) / (hiding + stealth) contro un tiro da 0 a 99, la regola Samurai Empire di ModernUO).
Nessuno del tipo dice “You see no evidence of animals in the area.” (502991), di creature (502993) o di persone (502995).
Un pulsante dell’elenco mostra la freccia sul posto di quel mobile (arrow.show, con il suo serial per i client dalla
7.0.9.0) e ne dice distanza e direzione (messaggio 30272; messaggio 30273 per un mobile sulla stessa tile, che non ha
direzione). Un mobile che ha lasciato il mondo, è più lontano del doppio del raggio o è un membro dello staff nascosto
fuori dalla portata del cercatore dice “You have lost your quarry.” (503177) e toglie la freccia di quello prima. La
freccia non è provata con un client vero; resta dove è stata messa, il server non segue la sua preda e il clic del
client su di essa (per toglierla) non viene letto. L’abilità aspetta 10 secondi. Non ci sono ancora gli elfi che
richiedono il doppio dell’abilità, i cambi delle forme del negromante e il bonus di pedinamento.
instrument.lua e common/bard.lua
Section titled “instrument.lua e common/bard.lua”scripts/items/instrument.lua è lo script dei nove strumenti musicali (il tamburo, i due tamburelli, l’arpa a colonna e
quella da grembo, i due liuti e i due flauti di bambù; script_id = "instrument", che il convertitore UOX3 assegna dalla
grafica), come il BaseInstrument di ModernUO. Un doppio clic su uno portato addosso, o entro una tile, lo suona: tira
Musicianship (skill.check(user, "musicianship", 0, 120), che insegna l’abilità) e il suono è buono con una probabilità
pari all’abilità su cento, con il suono di quello strumento secondo la sua grafica (il tamburo 0x38 o 0x39, i tamburelli
0x52 o 0x53, l’arpa a colonna 0x43 o 0x44, l’arpa da grembo 0x45 o 0x46, i liuti 0x4C o 0x4D, i flauti di bambù 0x504 o
0x503). Più lontano dice “That is too far away.” (500446), e lo stesso giocatore aspetta 6 secondi prima di suonare di
nuovo (“You must wait to perform another action.” 500119). Suonare a mano non consuma un uso dello strumento, come in
ModernUO; le abilità del bardo sì: uno strumento tira da 350 a 450 usi al suo primo uso in un’abilità (la prop
dell’oggetto instrument.uses), ogni tiro di un’abilità ne consuma uno, e all’ultimo viene detto “The instrument played
its last tune.” (502079) e lo strumento viene eliminato.
scripts/common/bard.lua è ciò che le abilità del bardo condividono. Lo strumento che un giocatore suona è quello su cui
ha fatto doppio clic per ultimo, finché è nello zaino o in una borsa dentro di esso (non nella cassaforte della banca, né sollevato sul cursore);
altrimenti l’abilità chiede “What instrument shall you play?” (500617) e prende quello indicato (500619 per ciò che non
è uno strumento, 1062488 per uno che non è nello zaino). La musica arriva a 8 + skill / 15 tile, con i punti
dell’abilità che si usa (Peacemaking per Peacemaking, non Musicianship). La difficoltà di una creatura, come il
GetBaseDifficulty di ModernUO, è hits * 1.6 + stamina + mana + skill points (la semplice somma dei punti delle sue
abilità), compressa sopra 700 a 700 + (value - 700) * 3 / 11, più 100 per una creatura con incantesimi, divisa per 10
e al massimo 160; i termini di ModernUO per un soffio di fuoco, un’immunità al veleno, la forza di un veleno e un
paragon non ci sono. Un tiro contro di essa è l’abilità tra diff - 25 e diff + 25, con diff abbassata della metà
della Musicianship oltre 100: la durata di ciò che il tiro dà si conta da quello stesso numero. Venditori, banchieri,
guaritori, stallieri e guardie non si possono incantare. Gli strumenti e le abilità del bardo non sono provati con un
client vero; non ci sono strumenti slayer ed eccezionali, la fabbricazione degli strumenti e i bardi tra gli NPC.
peacemaking.lua
Section titled “peacemaking.lua”scripts/skills/peacemaking.lua è l’abilità Peacemaking, come in ModernUO. on_use rivela il bardo, prende lo
strumento (vedi sopra), chiede “Whom do you wish to calm?” (1049525) e un bersaglio. Lo strumento deve essere ancora
nello zaino quando il cursore risponde (altrimenti 1062488), e un bardo morto nel frattempo non fa nulla. Se stessi
è la forma ad area: si tira Musicianship (un suono scadente dice “You play poorly.” 500612), poi l’abilità da 0 a 120
(“You attempt to calm everyone, but fail.” 500613). Un successo ferma il combattimento e la modalità di guerra di ogni
mobile nel raggio tranne il bardo, i morti, gli invulnerabili e chi non si può incantare, dice ai giocatori “You hear
lovely music, and forget to continue battling!” (500616) e calma le creature per un secondo (500615 quando c’era
qualcosa nel raggio, anche una creatura già calma, oppure 1049648 quando non c’era nulla). Un bersaglio che non è un
mobile, o è morto o invulnerabile, dice 1049528; oltre il raggio, “That is too far away.” (500446); fuori vista, “Target can not be seen.” (500237); un
venditore o una guardia, 1049526; una creatura già calma, 1049527. Si tira prima Musicianship, poi l’abilità tra diff - 25 e
diff + 25 con diff la difficoltà del bersaglio meno 10 (anche per un giocatore, dalle sue statistiche e abilità),
abbassata come sopra; un fallimento dice 1049531 e un successo 1049532, e una creatura è calmata per
clamp(100 - diff / 1.5, 10, 120) secondi (vedi common/creature.lua). Un giocatore ha solo il
combattimento fermato. Ogni tiro consuma un uso dello strumento e suona il suono buono o quello cattivo. L’abilità aspetta
10 secondi (delay di data/skills.toml) dalla pressione del pulsante, anche se il cursore viene messo via; i 5 secondi
di ModernUO dopo un successo non ci sono, né le zone sicure.
provocation.lua
Section titled “provocation.lua”scripts/skills/provocation.lua è l’abilità Provocation, come in ModernUO. on_use rivela il bardo, prende lo strumento
(vedi sopra), chiede “Whom do you wish to incite?” (501587) e una creatura, poi “Whom do you wish them to attack?”
(1008085) e una seconda. La prima deve essere una creatura che si può colpire, entro il raggio e in vista (altrimenti
501589, “That is too far away.” 500446, “Target can not be seen.” 500237): un cittadino blu dice solo “Think not that I
fail to see what thou art doing!” (501591) e costa al bardo 75 di karma tramite common/karma.lua, e
non succede altro; una con un padrone dice 501590; altrimenti lo strumento si sente suonato bene subito e non consuma un
uso. La seconda viene rifiutata se non è una creatura (501589), se una delle due non si può incantare (venditori,
banchieri, guaritori, stallieri, guardie) o non usa nessuno degli script costruiti su common/creature.lua (monster,
animal, scared_animal: 1049446), se sono su un’altra mappa o più lontane tra loro del raggio (1049450), se è la
stessa della prima (501593), e se è più lontana dal bardo del raggio o fuori dalla sua vista (500446, 500237). Si tira
prima Musicianship (500612), poi l’abilità da diff - 25 a diff + 25, con diff la difficoltà media delle due meno 5,
abbassata della metà della Musicianship oltre 100 (fallimento 501599, successo 501602). Un successo consuma un uso e
mette le due creature l’una contro l’altra: le prop bard.provoker, bard.provoke_target e bard.provoke_until
(world.now() più 30), e una calma finisce (vedi common/creature.lua). I giocatori non si
possono provocare. L’abilità aspetta 10 secondi dalla pressione del pulsante. Le uccisioni dei provocati sono le loro: il
bardo non ne ha il merito, e i paragon non ci sono.
discordance.lua
Section titled “discordance.lua”scripts/skills/discordance.lua è l’abilità Discordance, come in ModernUO nella forma che ha senza resistenze
(Moongate non ne ha). on_use rivela il bardo, prende lo strumento (vedi sopra), chiede “Choose the target for your
song of discordance.” (1049541) e un bersaglio; un clic a terra non fa nulla. Lo strumento deve essere ancora nello zaino
quando il cursore risponde (1062488). Il bardo stesso e ciò che non è un mobile dicono “A song of discord would have no
effect on that.” (1049535); oltre il raggio, “That is too far away.” (500446); fuori vista, “Target can not be seen.”
(500237). Un giocatore, morto o no, viene solo suonato male: nessun tiro, nessun uso, nessuna parola. Una creatura morta
o invulnerabile, un venditore, banchiere, guaritore, stalliere o guardia dicono 1049535, e una già in discordia 1049537.
Si tira prima Musicianship (“You play poorly, and there is no effect.” 500612), poi l’abilità da diff - 25 a
diff + 25, con diff la difficoltà della creatura meno 10, abbassata della metà della Musicianship oltre 100
(fallimento 1049540, successo 1049539). Un successo consuma un uso e mette una maledizione su forza, destrezza e
intelligenza della creatura: una percentuale di ogni valore di base, tante percento quanto un quinto dei punti di
Discordance (24 percento a 120 punti, 20 a 100). La maledizione (mobile.add_stat_curse con refresh) dura 4 secondi e
un timer della discordia la rinnova ogni 2 secondi. La discordia regge finché il bardo è vivo, non nascosto, sulla mappa
della creatura e entro il raggio della sua musica, misurato in linea retta; 15 secondi dopo che ciò non è più vero (il
conteggio ricomincia se il bardo torna), o subito quando la creatura muore o se ne va, finisce e l’ultima maledizione
sparisce entro 4 secondi. L’abilità aspetta 12 secondi dalla pressione del pulsante, qualunque sia l’esito. Su una
creatura pesa sui suoi colpi solo la forza (punti vita, stamina e mana non seguono le sue statistiche), e
l’abbassamento delle abilità della creatura di ModernUO non c’è, né l’effetto che mostra sulla creatura.
spirit_speak.lua
Section titled “spirit_speak.lua”scripts/skills/spirit_speak.lua è l’abilità Spirit Speak, come in ModernUO prima di AOS. on_use mostra prima il
giocatore (mobile.set_hidden, come fa usare un’abilità in ModernUO) e prova skill.check(user, "spirit_speak", 0, 100):
un fallimento dice “You fail your attempt at contacting the netherworld.” (502443), un successo suona il suono 0x24A,
dice “You establish a connection to the neitherworld.” (502444) e conserva, nella prop spirit_speak.until del mobile,
il secondo world.now() fino al quale il giocatore capisce i morti: un minuto e mezzo ogni 50 punti di abilità, in
secondi interi, almeno 15 (18 a 10 punti, 90 a 50, 180 a 100), come il base / 50 * 90 di ModernUO.
Ciò che la prop fa sta nel gestore del parlato: le parole di un fantasma vengono inviate come sono state dette, e non
come “oOo”, ai morti, allo staff, a un giocatore vivo il cui spirit_speak.until è ancora nel futuro, e a uno il cui
Spirit Speak di base è 100 o più, che capisce i morti per sempre senza usare l’abilità. Un successo spinge la prop più
avanti; un fallimento lascia il tempo che aveva. L’abilità aspetta il secondo di data/skills.toml. La cura di AOS
(10 mana, gratis vicino a un cadavere non canalizzato), la rivelazione degli spiriti nascosti e le lingue razziali di
UOX3 non sono costruite; niente invia un messaggio “la connessione svanisce” quando la prop finisce.
animal_lore.lua
Section titled “animal_lore.lua”scripts/skills/animal_lore.lua è l’abilità Animal Lore: on_use dice “What animal should I look at?” (500328), dà un
cursore e rifiuta una creatura fuori portata o fuori vista (500446, 1049654), una che non è un animale (mobile.body_type; una creatura morta ha lasciato il mondo) e, in base all’abilità, una creatura non
addomesticata sotto i 100 punti o non addomesticabile sotto i 110. Il controllo è skill.check(user, "animal_lore", 0, 120); se riesce costruisce un
gump a due pagine con gump.create da pet.lore, mobile.stats e mobile.skills, con tutte le etichette prese dai cliloc del client. Vedi
Animal taming.
pickaxe.lua e ore.lua
Section titled “pickaxe.lua e ore.lua”scripts/items/pickaxe.lua è lo script dei picconi e delle pale (script_id = "pickaxe") e
scripts/items/ore.lua quello dei quattro mucchi di minerale di ferro (script_id = "ore"): vedi Estrazione e fusione.
Uno scavo sceglie un luogo (target.pick_location), che dà il land della casella e la graphic di uno statico scelto
lì: lo script contiene i terreni che sono roccia e gli statici che sono il pavimento di una grotta. Il personaggio colpisce
(mobile.animate, mobile.play_sound, timer.after), nel luogo deve restare del minerale (harvest.amount), l’abilità
Mining viene provata tra i limiti del metallo del luogo (skill.check; 0 e 100 per il ferro), e uno scavo riuscito toglie dal luogo (harvest.take) e dà
un mucchio (item.give). Una fusione sceglie una forgia, un oggetto (item.item_id, item.in_range) o uno statico, prova l’abilità
tra 25 e 75, e trasforma il mucchio in lingotti (item.consume, poi item.give) oppure ne brucia metà; un singolo minerale di ferro
che fallisce rimpicciolisce, e un metallo sopra l’abilità del minatore viene rifiutato senza prova. Un mucchio su un cursore viene rifiutato (item.is_held). Il metallo di un luogo è la vena della sua zona
(harvest.vein): scripts/common/metals.lua contiene minerale e lingotti di ogni metallo, il Mining richiesto, i limiti di uno scavo
e la difficoltà di una fusione. Le costanti in cima a ogni script sono i suoi numeri e i suoi elenchi.
axe.lua
Section titled “axe.lua”scripts/items/axe.lua è lo script delle asce (script_id = "axe" su nove asce base, da cui le loro asce lo prendono):
vedi Taglio della legna. L’ascia deve essere in mano a chi vi fa doppio clic
(item.worn_by). Il punto scelto deve essere un albero entro 2 caselle: target.pick_location dà la graphic dello
statico scelto, e lo script contiene le grafiche che sono alberi. Il personaggio colpisce da una a tre volte
(mobile.animate, mobile.play_sound, timer.after), nel luogo deve restare della legna (harvest.amount), l’abilità
Lumberjacking viene provata tra i limiti del tipo di legno del luogo (skill.check; vedi sotto), e un taglio riuscito toglie dal luogo
(harvest.take) e dà 10 tronchi (item.give). Le costanti in cima allo script sono la distanza, i colpi
e i tronchi; gli alberi sono in scripts/common/trees.lua, condiviso con scripts/items/blade.lua, lo script di coltelli, pugnali e spade (script_id = "blade"), che stacca un legnetto da un albero e smembra i cadaveri (vedi blade.lua e corpse.lua). Usata sui tronchi nello zaino, l’ascia sega la pila in assi (item.template, item.consume, poi item.give). Un luogo è di un solo tipo di legno, la vena della sua zona (harvest.vein): scripts/common/woods.lua contiene tronchi e assi di ogni tipo, il Lumberjacking richiesto (mobile.skills) e i limiti tra cui il taglio viene provato, condiviso con la falegnameria, e la tabella FINDS ciò che un maestro trova insieme ai tronchi. Chi sta tagliando è tenuto in memoria per seriale: un riavvio libera tutti.
blade.lua e corpse.lua
Section titled “blade.lua e corpse.lua”scripts/items/blade.lua è lo script di coltelli, pugnali e spade (script_id = "blade"). Un giocatore fa doppio
clic su uno che porta con sé e sceglie, entro 2 caselle, un albero (target.pick_location; ne viene staccato un legnetto, al
costo di un taglio del suo legno) o un cadavere, che deve stare anche entro un piano di altezza. Un cadavere viene smembrato da
carve.corpse(corpse, user): si tira la tabella che il cadavere conserva in corpse.carve, on_carving viene chiesto allo
script del cadavere, gli oggetti vengono creati dentro il cadavere, e il cadavere viene segnato corpse.carved; un cadavere
si smembra una sola volta, e viene mostrato di nuovo a chi lo smembra con ciò che è stato trovato (item.show_contents).
Niente di utile, o un cadavere già smembrato, dice il cliloc 500485; il cadavere di un giocatore, di un animale domestico,
o uno che il suo script ha rifiutato, dice 500494. Vedi Smembrare i cadaveri.
scripts/items/corpse.lua è lo script del template del cadavere e non definisce alcun hook proprio: è dove uno script tuo
definisce on_carving per annullare o cambiare ciò che prende un coltello.
crafting.lua e carpentry_tool.lua
Section titled “crafting.lua e carpentry_tool.lua”scripts/common/crafting.lua contiene le regole condivise da tutti i mestieri: vedi Falegnameria. Legge le
ricette con craft.get e gli elenchi di materiali con craft.resource, conta e toglie i materiali dalle pile
che il giocatore porta (item.find, item.amount, item.consume; una pila sul cursore è esclusa con item.is_held),
esegue i due colpi (mobile.play_sound, timer.after), prova le altre abilità della ricetta e poi quella principale
tra il doppio del minimo meno il massimo e il massimo (skill.check), così la probabilità al minimo è una su due, e
crea l’oggetto (item.give, altrimenti item.create ai piedi del giocatore), con il colore del tipo di legno o di metallo
scelto (passandolo a item.give, oppure item.set_hue ai piedi): la tabella MATERIALS del motore lega la risorsa wood
a scripts/common/woods.lua e metal a scripts/common/metals.lua, e il tipo scelto è ricordato per mestiere. Una riuscita può essere eccezionale (crafting.roll, le proprietà quality, crafter_id, crafter_name), e ogni tentativo la cui abilità viene provata toglie un uso all’attrezzo (la proprietà uses_remaining, estratta tra 25 e 75, item.delete all’ultimo). Chi sta creando, il gruppo e il tipo di legno o di metallo scelti da ogni giocatore, per mestiere, e l’ultima ricetta iniziata da ciascuno (crafting.make_last) sono tenuti in memoria.
scripts/items/carpentry_tool.lua (script_id = "carpentry_tool" sugli attrezzi da falegname) apre il gump di creazione
dallo zaino; il gump è templates/gumps/craft_menu.xml con scripts/gumps/craft_menu.lua, uno per tutti i mestieri.
Lo script di attrezzo di ogni mestiere è una tabella con l’id del suo mestiere e una riga, crafting.use_tool(user, serial, CRAFT):
un attrezzo che non è portato viene rifiutato con il testo del client, uno nuovo estrae i suoi usi e il gump si apre. Un
mestiere tuo ha bisogno solo di quella riga.
repair.lua
Section titled “repair.lua”scripts/common/repair.lua, usato dal gump di creazione: repair.mends(craft_id) dice se un mestiere ha il pulsante
Repair item, repair.start(user, craft_id) dà al giocatore un cursore e ripara il pezzo scelto, repair.mend(user, craft_id, serial) è un tentativo (true se il pezzo è stato riparato) e repair.roll() è l’estrazione della probabilità
di indebolire. Legge e scrive i punti con item.durability e item.set_durability, e trova i pezzi che il mestiere fa
nelle ricette (craft.get). Vedi Riparazione per le regole.
smithing_tool.lua e common/smithy.lua
Section titled “smithing_tool.lua e common/smithy.lua”scripts/items/smithing_tool.lua è lo script dei martelli da fabbro, delle mazze e delle tenaglie
(script_id = "smithing_tool"): apre il gump di creazione del fabbro (vedi Fabbro),
con le regole di crafting.lua. scripts/common/smithy.lua contiene le grafiche delle incudini e delle forge e
le trova entro una distanza da un giocatore, tra gli elementi fissi della mappa (world.statics) e gli oggetti a terra
(world.items_in_range, item.item_id); la tabella NEEDS del motore chiede al fabbro un’incudine e una forgia entro
2 caselle, e ore.lua legge le sue forge da lì.
tailoring_tool.lua
Section titled “tailoring_tool.lua”scripts/items/tailoring_tool.lua è lo script dei kit da cucito (script_id = "tailoring_tool"): dallo zaino
apre il gump di creazione della sartoria (vedi Sartoria), con le regole di crafting.lua.
tinkering_tool.lua
Section titled “tinkering_tool.lua”scripts/items/tinkering_tool.lua è lo script degli attrezzi da tinker e delle cassette degli attrezzi (script_id = "tinkering_tool"):
dallo zaino apre il gump di creazione della meccanica (vedi Meccanica), con le regole di
crafting.lua e il metallo scelto.
fletching_tool.lua
Section titled “fletching_tool.lua”scripts/items/fletching_tool.lua è lo script degli attrezzi da fletcher (script_id = "fletching_tool"): dallo
zaino apre il gump di creazione di archi e frecce (vedi Archi e frecce), con le
regole di crafting.lua e il legno scelto.
cooking_tool.lua
Section titled “cooking_tool.lua”scripts/items/cooking_tool.lua è lo script delle padelle, dei setacci per la farina e dei mattarelli
(script_id = "cooking_tool"): dallo zaino apre il gump di creazione della cucina (vedi Cucina),
con le regole di crafting.lua e i forni e fuochi di scripts/common/heat.lua.
map_item.lua
Section titled “map_item.lua”scripts/items/map_item.lua è lo script delle mappe (script_id = "map_item"): dallo zaino o da terra
entro 2 caselle apre la mappa sulla sua area con il modulo map (vedi Mappe); più lontano dice
“That is too far away.”.
cartography_tool.lua
Section titled “cartography_tool.lua”scripts/items/cartography_tool.lua è lo script delle penne (script_id = "cartography_tool"): dallo zaino
apre il gump di creazione della cartografia (vedi Cartografia); una mappa creata viene disegnata da
scripts/common/cartography.lua.
inscription_tool.lua
Section titled “inscription_tool.lua”scripts/items/inscription_tool.lua è lo script di penna e inchiostro (script_id = "inscription_tool"): dallo zaino
apre il gump di creazione dell’inscription (vedi Inscription). scripts/common/crafting.lua
chiede il libro e il mana di una ricetta con i moduli spell e mobile.
potion.lua
Section titled “potion.lua”scripts/items/potion.lua è lo script delle pozioni che un giocatore beve (script_id = "potion"): cura, rinvigorimento,
forza, agilità e visione notturna, scelte dal template nella sua tabella EFFECTS; controlla la distanza e una mano libera,
e lascia una bottiglia vuota (vedi Pozioni).
alchemy_tool.lua
Section titled “alchemy_tool.lua”scripts/items/alchemy_tool.lua è lo script di mortaio e pestello (script_id = "alchemy_tool"): dallo zaino
apre il gump di creazione dell’alchimia (vedi Alchimia). scripts/common/potions.lua dice quale pozione è un
oggetto, comprese le pozioni semplici dei venditori, per potion.lua ed explosion_potion.lua.
test_kit.lua
Section titled “test_kit.lua”scripts/items/test_kit.lua è lo script delle sacche di prova per lo staff (templates/items/test_kits.toml,
script_id = "test_kit"): .add test_kit_alchemy dà una sacca che si riempie, la prima volta che si apre, con l’attrezzo, i
materiali e gli oggetti per provare un mestiere, le pozioni o gli incantesimi di Magery; poi è una sacca normale. Le sacche
sono test_kit_alchemy, test_kit_potions, test_kit_explosion, test_kit_cartography, test_kit_tailoring,
test_kit_tinkering, test_kit_fletching, test_kit_cooking, test_kit_inscription (penna e inchiostro, 100 pergamene vuote, 50 di ogni reagente e un libro completo) e test_kit_magery (un libro completo, 20 di ogni reagente,
tre pergamene per ogni incantesimo costruito dei primi quattro cerchi e due rune di richiamo); la tabella KITS dice cosa contiene ognuna. L’abilità si imposta a
parte, come .set skill alchemy 100.
spellbook.lua e spell_scroll.lua
Section titled “spellbook.lua e spell_scroll.lua”scripts/items/spellbook.lua è lo script dei libri degli incantesimi (script_id = "spellbook"): un doppio clic apre il
libro se il giocatore lo indossa o lo porta nello zaino, altrimenti dice che il libro deve essere portato con sé. Una
pergamena lasciata sul libro viene scritta in esso dal server. scripts/items/spell_scroll.lua è lo script delle pergamene
degli incantesimi (script_id = "spell_scroll"): un doppio clic lancia l’incantesimo della pergamena, che deve stare nello
zaino. Entrambi chiamano soltanto il modulo spell; vedi Magery.
Gli script degli incantesimi e common/magic.lua
Section titled “Gli script degli incantesimi e common/magic.lua”scripts/spells/<key>.lua è lo script di un incantesimo, una tabella globale con il nome della chiave di
spells.toml. cast(caster, target, info) è l’effetto, chiamato quando il lancio è riuscito;
check(caster, target, info) può rifiutare prima che si spenda qualcosa restituendo un numero di cliloc o un testo. Il
bersaglio è { kind = "mobile" | "item", serial }, { kind = "location", map, x, y, z } oppure { kind = "none" }, e info
i dati dell’incantesimo con scroll vero per un lancio da pergamena. Gli script costruiti sono il primo cerchio (clumsy,
create_food, feeblemind, heal, magic_arrow, night_sight, weaken), reactive_armor, il secondo cerchio
(agility, cunning, cure, harm, magic_trap, magic_untrap, protection, strength), il terzo (bless,
fireball, magic_lock, poison, teleport, telekinesis, unlock, wall_of_stone) e il quarto (arch_cure,
arch_protection, curse, fire_field, greater_heal,
lightning, mana_drain, recall), il quinto (blade_spirits, dispel_field, incognito, magic_reflection,
mind_blast, paralyze, poison_field, summon_creature), il sesto (dispel, energy_bolt, explosion,
invisibility, mark, mass_curse, paralyze_field, reveal), il settimo (chain_lightning, energy_field,
flame_strike, gate_travel, mana_vampire, mass_dispel, meteor_swarm, polymorph) e l’ottavo (earthquake,
energy_vortex, resurrection, summon_air_elemental, summon_daemon, summon_earth_elemental,
summon_fire_elemental, summon_water_elemental); un incantesimo senza script dice di essere disabilitato.
Gli incantesimi di Necromancy — la scuola senza cerchi — sono script anche loro, ognuno col proprio mana, la propria
abilità minima e il proprio ritardo in spells.toml (un mana, required_skill, cast_skill, scale_skill e
cast_delay che vincono sulle tabelle dei cerchi): si lanciano con Necromancy, scalano con Spirit Speaking, con i
reagenti dei negromanti e gli incantesimi che il client numera da 100. Sedici dei diciassette sono costruiti
(animate_dead, blood_oath, curse_weapon, evil_omen, exorcism, horrific_beast, lich_form, mind_rot,
pain_spike, poison_strike, strangle, summon_familiar, vampiric_embrace, vengeful_spirit, wither, wraith_form): le
ferite di
Pain Spike e Poison Strike, i round di Strangle, i tre che il
combattimento legge dalle props — un Blood Oath rende il danno del lanciatore contro chi è legato un quinto peggiore e
rimanda la ferita, un Mind Rot fa costare un quarto di mana in più gli incantesimi del maledetto, un’arma maledetta
beve metà delle sue ferite — e le quattro forme di common/necromancy.lua, un corpo ciascuna preso con
mobile.disguise per una settimana e finito da un secondo lancio della stessa forma, un’altra forma, una morte o la
settimana: la Bestia Orribile (746), il Lich (749) che paga un punto vita ogni due secondi e mezzo per il suo corpo, il
Vampiro (745 per una donna, 744 per un uomo, tinta 0x847E) che nessun veleno prende e il Wraith (747 per una donna,
748 per un uomo) che beve dal 5 al 20 percento delle sue ferite come mana. Le tre evocazioni fanno alzare le loro
creature sul sistema dei seguaci (common/summon.lua): Animate Dead indica un cadavere e due secondi dopo ne fa
alzare un non-morto della scala dei negromanti, da Necromancy e Spirit Speaking del lanciatore, un corpo che decade
punto vita per punto vita e del quale il quarto congeda il più vecchio; Summon Familiar apre la lista dei cinque
famigli, uno alla volta accanto al lanciatore per un giorno; Vengeful Spirit manda un revenant, un evocato che non
sente parola di un animale, contro una vittima sola finché non è morta o non è passato il suo tempo. L’Evil Omen maledice il suo
bersaglio per un solo evento dannoso: la prossima ferita un quarto peggiore, il prossimo veleno di un livello più alto,
e il primo dei due lo spende; il Wither è un gelo attorno al lanciatore, cinque caselle di bersagli indiretti validi,
ognuno ferito più forte quanto peggiore è il suo karma. L’Esorcismo, infine, chiede una maestria di Spirit Speaking e un
lanciatore dentro uno spawn di campioni, e porta ogni giocatore morto della portata dell’altare al santuario più vicino
a ciascuno — il modulo Lua champions sopra il servizio degli spawn; Corpse Skin è fuori per sempre, solo offset di
resistenza. Il libro del
negromante (0x2253) si apre
come ogni libro degli incantesimi; i suoi contenuti vanno col pacchetto più nuovo, e le sue pergamene vi cadono dentro
come quelle di magery.
I quattro incantesimi del lucchetto e della trappola leggono le props del forziere, su un contenitore: Magic Trap arma
una trappola magic di potenza 1 (502942 per una cosa che non è un contenitore, un fizzle per una trappola di altro
tipo), Magic Untrap spende una trappola magica (502373 per una cosa non trappata, un fizzle per una trappola di altro
tipo), Magic Lock mette locked con una prop lock.magic — un lucchetto che nessun grimaldello apre, solo Unlock
(501762 per una cosa che non è un contenitore o già chiusa, e 501763 sul lancio) — e Unlock apre un lucchetto fino
alla Magery del lanciatore per 0.8 meno 4 punti (501666 per una cosa che non è un contenitore, 503101 per una non
chiusa, 503099 per una al di sopra, col mana speso).
scripts/common/magic.lua è ciò che condividono: la probabilità che un bersaglio resista, il fattore del danno, la
maledizione e il potenziamento con la loro durata, l’armatura di Protection, il rifiuto di una cura, l’effetto e il suono
di un incantesimo e, per gli incantesimi che colpiscono un punto, chi possono colpire (valid_indirect,
indirect_targets), il danno che arriva dopo (harm_after), la probabilità di un Dispel e aggress, che rende il lanciatore l’aggressore del bersaglio e conosce
l’incantesimo che Magic Reflection ha rimandato indietro (info.reflected, info.reflector): il lanciatore è allora il
suo stesso bersaglio e si ferisce da sé, senza crimine. scripts/common/field.lua
mette a terra la fila di pezzi di un campo: field.cast(caster, target, info, options) suona il suono, mette a terra la
fila e mostra uno sbuffo su ogni pezzo, con options.kind (una chiave di field.kinds: energy, fire, paralyze,
poison, stone) al posto dei due template; field.is_field(template) è ciò che Dispel Field disfa.
Uno script di incantesimo tiene solo ciò che è suo (i suoi numeri, i suoi testi, i suoi extra) e chiama il resto. Un
controllo che rifiuta soltanto un bersaglio morto è X.check = magic.check_alive (una cura, magic.check_healable; un
campo, field.check): l’host degli incantesimi trova check come membro della tabella dell’incantesimo, quindi una
funzione assegnata lì è uguale a una scritta sul posto. Gli altri aiuti di magic.lua: sound_on e sound_at (il suono
dell’incantesimo, niente per uno che non ne ha), select_in_range (i mobile vicino a un punto per cui una funzione dice
sì), refuse_indirect (la città sorvegliata, poi nessuno da colpire), refuse_weight e refuse_landing (niente su cui
stare, un posto pieno e la regola di viaggio della regione, ciascuno con il proprio testo come parametro),
refuse_active (una proprietà di tempo ancora da venire), refuse_disguised e disguise (Incognito e Polymorph),
heal, cure_chance e paralyze_seconds; magic.curse accetta una caratteristica o una lista. Un incantesimo dannoso che rovina quello che il bersaglio stava facendo (Curse e le maledizioni di caratteristica,
Mana Drain, Mana Vampire, Poison) comincia
con magic.begin_assault(caster, who, info): aggress, poi il lancio del bersaglio è disturbato e la sua paralisi
finisce, e false, senza fare altro, per un bersaglio che non può essere colpito (Paralyze, che non toglie paralisi e
disturba solo dopo la resistenza, non lo usa; Mind Blast e gli incantesimi di danno fanno solo aggress). magic.resist_and_tell(caster, who, info, percent) tira la resistenza
del cerchio dell’incantesimo (percent è una probabilità propria dell’incantesimo, come ha Mana Drain) e avvisa un
bersaglio che resiste; quello che l’incantesimo fa di suo resta nello script. I tre dardi (Magic Arrow, Fireball,
Energy Bolt) sono una sola chiamata, magic.bolt(caster, who, info, least, most, delay, rand): aggress (nient’altro,
e nessun dado, per un bersaglio che non può essere colpito), il proiettile dell’incantesimo che vola dal portatore di
una riflessione, o dal lanciatore, al bersaglio, il suono sul lanciatore, poi si tira rand(least, most) (il random
dell’incantesimo), magic.damage lo fa resistere e lo scala, e il danno arriva delay secondi dopo. Un incantesimo che
colpisce più bersagli, o fa i passi in un altro ordine (Lightning, Harm, Flame Strike, Explosion, Meteor Swarm, Chain
Lightning), tiene il proprio lancio. Un incantesimo che legge
o marca una runa di richiamo usa scripts/common/rune.lua: rune.place(serial), rune.mark(serial, here) e
rune.in_pack(caster, serial). Una root i cui script degli incantesimi sono sostituiti a mano ha bisogno di
common/rune.lua con Recall, Gate Travel e Mark.
I testi che gli incantesimi dicono sono numeri del client, tenuti nella tabella magic.cliloc (WONT_WORK, BLOCKED, IN_EFFECT,
RESISTING, CANNOT_DISPEL, CURED_TARGET, NOT_ALLOWED, TOO_ENCUMBERED, CRIMINAL, FIZZLE): uno script di incantesimo dice
magic.cliloc.WONT_WORK, mai il numero. Il suono, l’effetto e il proiettile di un incantesimo sono quelli di
data/spells.toml (info.sound, info.effect, info.projectile); uno script non tiene alcun valore proprio per essi.
Il modulo cliloc
Section titled “Il modulo cliloc”I numeri dei testi del client che molti script dicono sono costanti del modulo cliloc, che il codice C# del server legge
dalla stessa fonte: cliloc.TOO_FAR (500446), cliloc.CANNOT_SEE (500237), cliloc.DEAD (1019048),
cliloc.IN_BACKPACK (1062334), cliloc.USE_ON_WHAT (1010018) e cliloc.NOT_CARRIED (1042010). Passane una a
mobile.message_cliloc, come mobile.message_cliloc(user, cliloc.TOO_FAR). Un numero che dice un solo script resta in quello
script; quelli degli incantesimi sono in magic.cliloc. L’elenco è nel
riferimento API Lua.
common/summon.lua
Section titled “common/summon.lua”scripts/common/summon.lua è ciò che condividono gli incantesimi che chiamano una creatura:
summon.create(caster, template, place, seconds, sound, uncontrollable) chiede la creatura con npc.spawn e, quando c’è,
ne fa un seguace del lanciatore (la proprietà owner, l’ordine di animale guard), imposta summon.until,
summon.difficulty e summon.focus, e avvia il timer che la manda via; con uncontrollable riceve la proprietà
pet.uncontrollable, e common/pet_orders.lua le fa non sentire parole e non prendere cibo (uno spirito di lama, un vortice di energia). summon.refuse e summon.refuse_template dicono, con il cliloc 1049645, che i seguaci del
lanciatore non hanno posto per lei (pet.followers, pet.slots_of). L’incantesimo intero di una creatura chiamata
accanto al lanciatore è summon.check_near(caster, slots_or_template) e summon.cast_near(caster, info, template, options) (gli elementali, il demone, Summon Creature), quello di una creatura chiamata nel punto scelto è
summon.check_at e summon.cast_at (Blade Spirits, Energy Vortex): ogni script tiene il suo template, i suoi secondi e i
suoi extra. summon.tick è chiamato da common/creature.lua a
ogni pensiero di una creatura: manda via quella il cui tempo è scaduto o il cui padrone è morto, se n’è andato o l’ha
lasciata. summon.dismiss la porta via in uno sbuffo (effect.at, npc.delete); lo usa un Dispel. Una creatura evocata che
muore non lascia cadavere (l’on_death di creature.lua). Vedi Magery.
magic_field.lua
Section titled “magic_field.lua”scripts/items/magic_field.lua è lo script dei pezzi dei campi (script_id = "magic_field", template in
templates/items/magic/fields.toml): i timer dell’oggetto expire e tick terminano un pezzo quando field.until è
raggiunto, e un pezzo con field.damage brucia, con combat.harm e il lanciatore come attaccante, chi lo calpesta
(on_move_over, on_npc_move_over) o ci sta dentro a ogni tick, una volta al secondo. Una prova di Resisting Spells riduce
la bruciatura a un punto; un invulnerabile o un mobile morto viene lasciato in pace. Un pezzo con field.effect = "poison"
avvelena, al livello di field.power, e uno con "paralyze" immobilizza per field.power secondi (mobile.paralyze) chi lo
calpesta, quando il lanciatore è nel gioco e può colpirlo (magic.valid_indirect, che risparmia il gruppo del lanciatore), il lanciatore essendone l’aggressore. I
campi di energia e il muro di pietra non hanno altro effetto che il loro peso. Vedi Magery.
fishing_pole.lua
Section titled “fishing_pole.lua”scripts/items/fishing_pole.lua è lo script delle canne da pesca (fishing_pole, fishing_pole_2,
script_id = "fishing_pole"): vedi Pesca. Fai doppio clic sulla canna e scegli dell’acqua entro 4 caselle e
in vista (target.pick_location, world.is_water, world.line_of_sight). Il personaggio lancia (mobile.animate),
l’acqua schizza 1,5 secondi dopo (effect.at, world.play_sound) e il risultato arriva dopo 8 secondi
(timer.after). Nel luogo devono restare dei pesci (harvest.amount), l’abilità Fishing viene provata tra 0 e 100
(skill.check), e la presa viene messa nello zaino (item.give) e tolta dal luogo (harvest.take).
Le costanti in cima allo script sono la distanza, i secondi e ciò che esce. Chi sta pescando è tenuto in
memoria per seriale: un riavvio libera tutti.
bandage.lua
Section titled “bandage.lua”scripts/items/bandage.lua è lo script della benda pulita (clean_bandage, script_id = "bandage"),
come la Healing classica di ModernUO. Si fa doppio clic, si sceglie a chi è destinata e si aspetta: chi è stato
scelto viene curato, o resuscitato.
- Portata: la benda nello zaino, e chi la riceve entro 1 casella; più lontano, il “too far away” del client. Il curatore deve vedere chi riceve la benda: uno nascosto o dietro un muro “can not be seen”. Usare una benda rivela un curatore nascosto. La benda esce dalla pila quando la cura inizia. Una seconda benda dello stesso curatore sostituisce la prima.
- L’attesa: 3 secondi per un curatore con 100 di destrezza o più, 4 da 40, 5 sotto; 5 in più per resuscitare un fantasma; 9,4 + 0,6 × (120 − destrezza) / 10 su sé stessi. Il curatore deve restare entro 1 casella e vivo, altrimenti la cura va persa insieme alla benda.
- Un vivo ferito: riesce con una probabilità di (Healing + 10) %, e cura da Anatomy / 5 + Healing / 5 + 3 fino a Anatomy / 5 + Healing / 2 + 10 punti; un tiro sotto 1 cura 1 e dice che le bende hanno aiutato appena. Una creatura con il corpo di un mostro o di un animale è un caso per Veterinary e Animal Lore, con un punto in più ogni 100 punti vita. Chi non è ferito legge “That being is not damaged!” e la benda resta — a meno che il suo veleno non sia al lavoro, che è un caso per l’antidoto qui sotto.
- Un avvelenato: antidotato, non curato — nessun punto vita torna. La benda parte anche a piena vita. Il curatore legge «You finish applying the bandages.», poi l’antidoto è tirato dietro un cancello di 60 punti di entrambe le abilità del curatore, con una probabilità di (l’abilità principale − 30) / 50 meno un decimo di punto per livello del veleno: un tiro fallito legge «You have failed to cure your target!» (1010060), uno passato cura — «You have cured the target of all poisons.» (1010058) al curatore a meno che curi sé stesso, e «You have been cured of all poisons.» (1010059) al paziente.
- Uno che sanguina: fasciato — le ferite si chiudono e nessun punto vita torna, e nessuna abilità è chiesta. Il curatore legge «You bind the wound and stop the bleeding» (1060088) e il paziente che le sue ferite hanno smesso di sanguinare (1060167). Un paziente avvelenato è antidotato prima, e uno che sanguina è esente dal «That being is not damaged!» come un avvelenato.
- Un fantasma: servono 80 punti di Healing e di Anatomy e una probabilità di (Healing − 68) / 50; poi al fantasma viene chiesto, nel gump degli ankh, se vuole tornare, e gli costa un decimo della fama, come a un ankh.
- Il cadavere di un animale legato: servono 80 punti di Veterinary e di Animal Lore e una probabilità di (Veterinary − 68) / 50, l’attesa è quella di un fantasma (5 secondi in più), e il proprietario deve essere il curatore o stare entro 3 caselle dal cadavere; l’animale rinasce dove giace il cadavere, con il suo proprietario, la lealtà e il legame, e 10 punti vita. Il cadavere di un animale non legato non può essere bendato.
- Abilità: entrambe vengono provate per la crescita dopo una cura, anche se il tiro non è riuscito, e dopo una resurrezione riuscita.
Non ci sono ancora veleno e sanguinamento, quindi nessuna cura per essi; e il terreno dove un fantasma viene resuscitato non viene controllato, come non lo è a un ankh.
stealth.lua
Section titled “stealth.lua”scripts/skills/stealth.lua è lo script di Stealth, come quello classico di ModernUO. Un giocatore nascosto usa
l’abilità e, se il controllo riesce, può fare alcuni passi senza essere mostrato: un decimo della sua Stealth in passi,
almeno uno (mobile.set_stealth_steps; il server li conta in MoveRequestPacketHandler). Correre lo mostra sempre.
Nascondersi o essere mostrati di nuovo azzera i passi.
- Prima del controllo: chi non è nascosto riceve l’invito a nascondersi prima (502725); chi ha meno di 80 punti di
Hiding “non è nascosto abbastanza bene” (502726), e chi ha un valore di armatura (
combat.armor_rating) di 26 o più “non può sperare di muoversi in silenzio” (502727): entrambi vengono mostrati. - Il controllo va da -20 a 80 punti, ciascuno aumentato del doppio del valore di armatura. Un successo legge “You begin to move quietly.” (502730); un fallimento legge “You fail in your attempt to move unnoticed.” (502731) e mostra il giocatore. L’abilità aspetta 10 secondi in ogni caso.
- In sella: chi è in sella viene rifiutato con “You cannot stealth while mounted.” (500837).
- Non c’è ancora: le regole di Stealth delle versioni successive (il costo dei passi per armatura).
snooping.lua
Section titled “snooping.lua”scripts/skills/snooping.lua è lo script di Snooping, come quello di ModernUO. Non si usa dalla finestra delle abilità:
un doppio clic sullo zaino di un altro mobile non lo apre, il server chiama on_snoop(user, owner, container) di questo
script (ISkillScriptService.Call). Lo fa per lo zaino e per un sacco al suo interno, e non per un giocatore morto.
- Lo staff fruga chiunque, sempre: un game master o un amministratore non ha bisogno di distanza, abilità o regole, non
perde karma e non viene notato, e può frugare un proprietario morto e un altro membro dello staff. Il comando
hidelo nasconde prima. - Regole per gli altri: entro una casella dal proprietario; niente se il proprietario è morto; un game master o un amministratore non si può frugare, e nemmeno un giocatore invulnerabile (“You cannot perform negative acts on your target.”; Moongate non ha ancora regole sugli atti dannosi per mappa, che questo sostituisce). Un PNG in una regione sorvegliata di una mappa diversa da Felucca si fruga solo se non è umano, oppure attaccabile, oppure assassino: lo dice il commento di ModernUO, anche se il suo codice lascia frugare chiunque un PNG in una città attiva.
- Un giocatore che non è staff perde 4 di karma, come
AwardKarmadi ModernUO prende una perdita (di più da un buon nome, niente sotto -400, mai sotto -15000, e la perdita viene comunicata), ed è notato dai giocatori entro 8 caselle (“You noticeattempting to peek into ’s belongings.”): sempre sotto 100 punti di Snooping, con una probabilità pari ai punti su cento di passare inosservato. - Il controllo va da 0 a 100 punti: un successo apre lo zaino sul client del giocatore (
item.show_contents); un fallimento legge “You failed to peek into the container.” e mostra il giocatore, più probabilmente quanto meno ha di Hiding. Lo staff vede sempre. - Non c’è ancora: le trappole dei contenitori. Gli oggetti visti non si possono sollevare: il sollevamento di un oggetto che il giocatore non possiede è rifiutato come prima.
stealing.lua
Section titled “stealing.lua”scripts/skills/stealing.lua è l’abilità Stealing, come in ModernUO nella sua modalità classica. on_use chiede “Which
item do you want to steal?” (502698) con entrambe le mani libere (“Both hands must be free to steal.” 1005584; uno scudo
conta, mobile.hands_empty) e rivela il ladro. Il bersaglio è un oggetto dentro un contenitore, oppure un mobile, che
dà un oggetto del suo zaino a caso (uno zaino vuoto non dà nulla). I controlli, in quest’ordine: un oggetto di un
giocatore, il ladro non della gilda dei ladri, 1005596 “You must be in the thieves guild to steal from other players.”;
un ladro della gilda con uccisioni (mobile.murders, il Kills > 0 di ModernUO), 502706; un negoziante invulnerabile,
1005598; un oggetto in una cassa della banca, uno a terra, uno fisso (item.is_movable), uno benedetto o newbie
(item.loot_type), quello in un cadavere, quello di un membro dello staff o di un morto, 502710 “You can’t steal
that!”; uno indossato, 1005585; uno del ladro stesso, 502704; più lontano di una tile, 502703; fuori vista, 500237; più
pesante di 10 stone (item.weight: un contenitore con ciò che contiene, una pila per una unità), 502722; uno zaino che
non lo può contenere (item.can_hold, i limiti di peso, chiesto prima del tiro), 1048147. ModernUO chiede prima la
distanza e il suo ordine differisce in questi casi limite. Il controllo dell’abilità è il peso in stone per 10, da 22.5
in meno a 27.5 in più; una pila viene tagliata a una quantità casuale fino a un decimo dell’abilità sul peso unitario,
e il controllo è di quella quantità. Un successo sposta l’oggetto nello zaino del ladro: una pila viene tagliata con
item.split (il resto tiene il serial e resta al suo proprietario, e la parte presa è un oggetto nuovo) e l’oggetto passa con
item.move_into e il suo ultimo argomento, transfer, di cui un furto ha bisogno per prenderlo da un mobile (502724);
un fallimento dice 502723. L’oggetto viene salvato dall’uscita del nuovo proprietario o dal salvataggio del mondo: un
crollo prima restituisce alla vittima un oggetto intero. Una pila tagliata in due sono due righe, quella della vittima
con il vecchio serial, riscritta più piccola dal suo salvataggio successivo, e quella del ladro con il serial nuovo: un
crollo tra i due salvataggi può far perdere la parte presa, o lasciarla in entrambi gli zaini se è stato salvato prima il
ladro. Un oggetto che il proprietario tiene sul cursore viene rifiutato prima del tiro (502710), e un mobile non lo
sceglie mai tra gli oggetti del suo zaino. Un furto costa 50 di karma comunque finisca
(common/karma.lua), e il ladro viene scoperto con una probabilità di uno su 150 per ogni punto di
abilità che gli manca: diventa un criminale quando la vittima è un mobile innocente (per la sua notorietà, non verso il
ladro) e non della gilda dei ladri, e i giocatori entro 8 tile leggono “You notice
item_identification.lua
Section titled “item_identification.lua”scripts/skills/item_identification.lua è l’abilità Item Identification, come in ModernUO nella sua modalità classica.
on_use chiede “What do you wish to appraise and identify?” (500343) e un bersaglio entro 8 tile (“That is too far
away.” 500446 oltre; un oggetto che il giocatore porta addosso è sempre a portata). Ciò che mostra è ciò che mostra un
singolo clic (item.look): la riga del nome del tooltip sopra l’oggetto o il mobile, con la quantità di una pila, il
nome che gli dà il template e il titolo di un mobile, vista solo da quel giocatore. Un’arma, un pezzo di armatura e un
oggetto con la prop dell’oggetto unidentified vengono provati con skill.check(user, "item_identification", 0, 100),
come gli identificabili di ModernUO, ed è così che l’abilità si allena: un successo toglie la prop (un oggetto che non si
può cambiare resta non identificato) e non dice altro; tutto ciò che non è identificato dice “You are not certain…”
(500353) dopo l’etichetta, un oggetto ordinario compreso, come fa ModernUO. Nulla imposta ancora unidentified: è il
gancio per le bacchette magiche e il bottino a venire, e le proprietà di un tale oggetto non sono nascoste nel suo
tooltip. Il cursore non controlla la linea di vista. L’abilità aspetta il secondo di data/skills.toml.
taste_identification.lua
Section titled “taste_identification.lua”scripts/skills/taste_identification.lua è l’abilità Taste Identification, come in ModernUO. on_use chiede “What would
you like to taste?” (502807) e un bersaglio: un oggetto o un mobile entro 2 tile e in vista (“You are too far away to
taste that.” 502815 oltre, “Target can not be seen.” 500237 fuori vista; un oggetto che il giocatore porta addosso è
sempre a portata). Un mobile dice “You feel that such an action would be inappropriate.” (502816). Il cibo (lo script
food) viene provato con skill.check(user, "taste_identification", 0, 100), ed è così che l’abilità si allena: un
successo dice, come etichetta sopra il cibo, “It appears to have poison smeared on it.” (1038284) quando la sua prop
dell’oggetto poison.level c’è (il veleno minore è il livello 0) e “You detect nothing unusual about this substance.” (1010600) quando non c’è; un
fallimento dice “You cannot discern anything about this substance.” (502823), avvelenato o no. Una pozione (gli script
potion e explosion_potion) è già nota: “You already know what kind of potion that is.” (502813), poi il nome del
client del suo tipo, 1041314 più l’effetto della pozione di ModernUO (così una pozione di cura minore dice “Lesser Heal”,
non la pozione gialla che ogni pozione di cura si chiama; una pozione di tipo non noto mostra il suo nome con
item.look). Un barilotto di pozioni è vuoto, “There is nothing in the keg to taste!” (502228), perché nessun barilotto
contiene ancora pozioni. Tutto il resto dice “That’s not something you can taste.” (502820). L’abilità
Poisoning imposta poison.level sul cibo. Un clic a terra non ha risposta (il cursore non la dà), e i
caschi di banane e la bacca tribale non sono cibo nei dati UOX3, quindi dicono 502820. L’abilità aspetta il secondo di
data/skills.toml.
lockpick.lua e treasure_chest.lua
Section titled “lockpick.lua e treasure_chest.lua”scripts/items/lockpick.lua è lo script dei grimaldelli (0x14fb, 0x14fc, 0x14fd e 0x14fe,
script_id = "lockpick"), come il Lockpick di ModernUO. Si fa doppio clic, si sceglie un oggetto chiuso a chiave entro
una casella, e dopo tre secondi viene provata l’abilità; il giocatore deve restare entro una casella.
Si può scassinare un oggetto con queste prop: locked (true finché è chiuso), lock.level e lock.max, i punti di
Lockpicking da cui la prova può appena riuscire e da cui non fallisce mai, e lock.required, il minimo per provare. Una
serratura senza lock.level “non si può scassinare con mezzi normali”; chi ha meno di lock.required “non vede come si
possa manovrare quella serratura”. Un successo apre l’oggetto per sempre (locked è false, lock.picker è il giocatore);
un fallimento rompe il grimaldello una volta su quattro, che esce dalla sua pila. Lockpicking è un’abilità che sale con
l’uso, come le altre.
scripts/items/treasure_chest.lua è lo script dei quattro forzieri del tesoro dei dungeon
(templates/items/treasure_chests.toml, script_id = "treasure_chest"), come i TreasureChestLevel1 a 4 di ModernUO.
Un forziere nasce chiuso: chiede 57, 72, 84 e 92 punti di Lockpicking per livello, e la prova va da quel valore meno un
tiro da 1 a 10 a quel valore più un tiro da 1 a 10. Un forziere chiuso non si apre (“It appears to be locked.”); un game
master lo apre (“That is locked, but you open it with your godly powers.”); uno scassinato si apre come ogni contenitore.
Nessuno tranne un game master lascia cadere un oggetto in un forziere chiuso (can_insert), e ciò che è già dentro un
forziere aperto su un client si può ancora sollevare. I forzieri creati prima di questa versione non hanno serratura e
restano come erano finché non decadono.
Un forziere è anche armato con la trappola del suo livello (common/trap.lua, come li arma il
FillableContainer di ModernUO): uno di livello 2 sempre, uno di livello 1 quattro volte su cinque, con un veleno per i
forzieri più profondi e un’esplosione altrimenti, e trap.power è il livello per un tiro da 10 a 30. Chi apre un forziere
scassinato la fa scattare — “You set off a trap!” — ne prende lo scoppio entro 3 caselle (un’esplosione rand(10, 30) a
livello, un dardo rand(5, 15) a livello, un veleno del livello, una trappola magica la sua potenza entro 1 casella) e
il forziere resta chiuso quel clic; una trappola scattata è spesa (le tre props se ne vanno). Lo staff apre con i suoi
poteri divini e la trappola resta armata, e una trappola fatta scattare da lontano, come fa il Telecinesi, non raggiunge
nessuno fuori dalle sue caselle.
common/trap.lua
Section titled “common/trap.lua”scripts/common/trap.lua è la trappola di un contenitore, tenuta nelle sue props: trap.type (explosion, dart,
poison o magic), trap.level e trap.power. trap.arm(chest, level) arma il forziere di quel livello (livello 2 e
oltre sempre, livello 1 quattro volte su cinque; un veleno quando il livello batte un tiro di cinque, altrimenti
un’esplosione; la potenza è il livello per un tiro da 10 a 30). trap.spring(chest, who) è chi lo apre: lo staff scende
con i suoi poteri divini e la trappola resta, chiunque altro legge “You set off a trap!” (502999) e prende lo scoppio del
tipo — combat.harm senza attaccante, “as for a trap” — entro le sue caselle, e la trappola è spesa. L’abilità
Remove Trap disarma queste props.
training_dummy.lua
Section titled “training_dummy.lua”scripts/items/training_dummy.lua è lo script dei manichini da allenamento (0x1070 e 0x1071 rivolti a sud, 0x1074
e 0x1075 rivolti a est), come il TrainingDummy di ModernUO: i template hanno script_id = "training_dummy", e così anche
decoration_training_dummy, che .decorate dà ai manichini dei file. Si fa
doppio clic su un manichino con un’arma da mischia in mano, o a mani nude: il giocatore si gira e colpisce
(combat.swing), il manichino mostra la grafica oscillante da un quarto di secondo, con il suono di un colpo, e dopo
tre secondi torna a riposo, e l’abilità dell’arma (Wrestling per i pugni) viene provata da -25 a 25 punti, quindi può
salire fino a 25.
Un arco o una balestra non possono allenarsi su di esso (“You can’t practice ranged weapons on this.”), l’arma deve
raggiungerlo (una casella, combat.range), un manichino che oscilla ancora fa aspettare il giocatore, e un’abilità a
25 legge “Your skill cannot improve any further by simply practicing with a dummy.”. Non c’è alcun controllo per un
giocatore in sella: lo script lascia allenare un cavaliere.
archery_butte.lua
Section titled “archery_butte.lua”scripts/items/archery_butte.lua è lo script dei bersagli per il tiro con l’arco (0x100A rivolto a est, 0x100B
rivolto a sud), come l’ArcheryButte di ModernUO: i template hanno script_id = "archery_butte" e use_range = 6, come
decoration_archery_butte, che .decorate dà ai bersagli dei file, così il giocatore può fare doppio clic da dove tira.
Un mondo decorato prima di questa versione li ha come semplice decorazione: un nuovo .decorate li trasforma in questi.
- Tiro: con un arco o una balestra, ci si mette davanti al bersaglio, in linea con esso, a cinque o sei caselle, e
si fa doppio clic. Una freccia o un dardo viene speso (
combat.spend_ammo), il giocatore tira (combat.swinge la freccia che vola,effect.moving) e l’abilità dell’arma viene provata da -25 a 25 punti: può salire, e il tiro può mancare. Tra due tiri allo stesso bersaglio passano due secondi. I testi dicono che cosa non va quando il giocatore sta dietro, fuori linea, troppo lontano o troppo vicino. - Punteggio: un tiro a segno vale 50 (il centro, uno su dieci), 10, 5 o 2 punti, e al giocatore viene detto il suo totale a quel bersaglio e quanti tiri ha fatto. La freccia può spezzarsi, più probabilmente quante più munizioni sono conficcate nel bersaglio (il 2 per cento ciascuna), e allora vale di più e va persa. I testi sono detti a chi tira, non agli altri.
- Raccolta: doppio clic sul bersaglio entro una casella, quando ci sono frecce o dardi conficcati (prop
butte.arrowsebutte.bolts): vanno nello zaino e i punteggi vengono azzerati.
I bersagli per freccette non esistono ancora.
dyes.lua e dye_tub.lua
Section titled “dyes.lua e dye_tub.lua”scripts/items/dyes.lua e scripts/items/dye_tub.lua tingono i vestiti in due passaggi, come ModernUO;
i template convertiti delle tinture (dyes) e della vasca (dying_tub) contengono
script_id = "dyes" e script_id = "dye_tub".
- Fai doppio clic sulle tinture e scegli una vasca: si apre il selettore di colori del client con la vasca, che assume il colore scelto, da 2 a 1001, come proprio colore.
- Fai doppio clic sulla vasca e scegli cosa tingere: assume il colore della vasca, con il suono della tintura
(
0x23E).
Si può tingere un oggetto il cui template indica dyeable = true, come gli abiti
convertiti da UOX3. Non deve essere indossato, e il giocatore deve raggiungere l’oggetto, la vasca e le tinture:
trasportati, oppure a terra entro 1 casella. Né le tinture né la vasca vengono consumate, e una vasca mai
tinta ha colore 0, che rimuove il colore. Un oggetto tenuto sul cursore non viene tinto (“Non puoi tingere
quello.”), e uno dentro un contenitore a terra conta come troppo lontano: prendilo prima.
I testi sono quelli del client, letti nella sua lingua:
| Testo | Cliloc |
|---|---|
| Seleziona la vasca su cui usare le tinture. | 500856 |
| Usa questo su una vasca per tintura. | 500857 |
| Seleziona gli abiti da tingere. | 500859 |
| Non puoi tingere abiti indossati. | 500861 |
| Non puoi tingere quello. | 1042083 |
| È troppo lontano. | 500446 |
Il giocatore può rispondere al selettore di colori molto più tardi, oppure mai. Quando arriva la risposta lo script controlla
di nuovo che tinture e vasca siano raggiungibili, e il server accetta una risposta solo per il selettore
che ha aperto: gli altri emulatori la accettano come arriva. scripts/common/dye.lua contiene ciò che i due
script condividono (dye.reach, dye.worn, dye.tell). Le vasche speciali (pelle, mobili, nere,
metalliche) e le tinture dei capelli non sono ancora presenti.
hiding.lua
Section titled “hiding.lua”scripts/skills/hiding.lua è lo script dell’abilità Hiding, come quello di ModernUO senza
ciò che richiede un combattimento o una casa. Un giocatore che usa l’abilità viene verificato con
skill.check(user, "hiding", 0, 100): la probabilità è pari ai suoi punti su cento, e il tentativo può aumentare
l’abilità.
- Successo: il giocatore è nascosto (
mobile.set_hidden), fuori dalla modalità guerra, e legge “Ti sei nascosto bene.” (cliloc 501240). - Fallimento: il giocatore viene mostrato, anche se era nascosto, e legge “Non riesci a nasconderti qui.” (501241).
In entrambi i casi attende prima di un’altra abilità il delay di hiding in
data/skills.toml, 10 secondi. Il primo passo lo mostra di nuovo, con “Sei stato
rivelato!” (500814): il server lo fa per ogni giocatore nascosto di un account regolare, a
meno che Stealth non abbia permesso il passo; girarsi sul posto non lo fa. Lo staff si nasconde per osservare e resta nascosto.
Parlare, essere colpiti e la vista di chi sta vicino non lo mostrano ancora.
meditation.lua
Section titled “meditation.lua”scripts/skills/meditation.lua è lo script dell’abilità Meditation, come quello di
ModernUO prima di AOS. on_use mostra prima il giocatore e rifiuta l’uso: al mana pieno (“Sei in
pace.”, 501846), sotto un decimo dei punti vita (“La mente è forte ma il corpo è debole.”, 501849),
con qualunque armatura addosso (“Le forze rigenerative non possono penetrare la tua armatura!”,
500135 — qui non esiste un permesso di meditazione, quindi qualunque armatura indossata blocca la
trance, la regola AOS di ModernUO) e senza una mano libera (“Le tue mani devono essere libere per
lanciare incantesimi o meditare.”, 502626 — la regola del bere di mobile.has_free_hand; il libro
degli incantesimi e il libro delle rune di ModernUO non sono letti). Altrimenti il controllo è
skill.check(user, "meditation", 0, 100): un successo imposta la prop meditating, suona il suono
0xF9 e legge “Entri in una trance meditativa.” (501851); un fallimento legge “Non riesci a
concentrarti.” (501850). L’abilità attende 10 secondi, il delay di
data/skills.toml.
Finché la prop è impostata, il mana torna due volte più in fretta: il ritmo di rigenerazione da intelligenza e Meditation viene dimezzato (l’effetto passivo dell’abilità c’è anche senza la trance). La trance finisce quando la prop viene tolta, come fa un passo, una ferita, un colpo, un incantesimo, indossare un oggetto e l’uso di un’altra abilità, ma non di Meditation stessa; finisce anche quando il mana è pieno (“Sei in pace.”, 501846, controllato ogni secondo dalla rigenerazione) e quando il personaggio entra nel mondo, perché la prop viene salvata con lui. Il rifiuto di ModernUO per un giocatore occupato (501845) non c’è: uno script non può chiedere di un cursore pendente, e l’uso di un’abilità lo sovrascrive.
begging.lua
Section titled “begging.lua”scripts/skills/begging.lua è lo script dell’abilità Begging, come quello di
ModernUO prima di ML. on_use mostra prima il giocatore e chiede “Da chi vuoi supplicare?”
(500397) con un cursore. I rifiuti, ognuno col testo del client: una cosa che non è un essere
vivente e un corpo che non è umano (500399), un giocatore (“Forse chiedere andrebbe meglio.”,
500398), un bersaglio oltre 2 caselle (500401 lui, 500402 lei) e un mendicante a cavallo (500404,
una regola che ModernUO ha lasciato cadere solo con ML). Altrimenti il giocatore si inchina
(HumanAnimationType.Bow) e, due secondi dopo, il tentativo avviene.
- Chi ha fama cattiva: con karma sotto 0, una probabilità di
0.5 - karma/8570che l’NPC rifiuti tutto il tentativo, dicendo “Thou dost not look trustworthy… no gold for thee today!” (500406) sopra la testa. - Il tiro è
skill.check(user, "begging", 0, 100); un fallimento legge “They seem unwilling to give you any money.” (500404) — ModernUO e ServUO mandano questo all’NPC, dove nessuno lo vede, un difetto ereditato da RunUO. - L’oro: un decimo delle monete che l’NPC porta (
item.finddel template dell’oro), limitato da10 + fame/2500da 10 a 14, passa dallo zaino dell’NPC a quello del giocatore (a terra ai suoi piedi se lo zaino non ha posto) col suono della pila (0x2E4 una moneta, 0x2E5 fino a cinque, 0x2E6 oltre). L’NPC dice “I feel sorry for thee…” (500405), o “I have not enough money to give thee any!” (500407) senza monete; un NPC senza zaino riceve invece il rifiuto 500404. - Il karma: ricevuto l’oro, ciò che il mendicante ha sopra -3000, al massimo 40, attraverso
common/karma.lua, che dice quanto è stato perso. L’oro coniato dal nulla di UOX3 e la Begging di Sphere (che non dà nulla) non sono seguiti.
L’abilità attende 10 secondi, il delay di data/skills.toml —
l’attesa effettiva di ModernUO dal bottone; il suo segnaposto di 30 secondi del cursore non è
tenuto. Il tiro del rifiuto di chi ha fama cattiva è begging.chance, che un test sostituisce.
shepherds_crook.lua
Section titled “shepherds_crook.lua”scripts/items/shepherds_crook.lua è l’abilità Herding, come lo ShepherdsCrook di ModernUO: il
bottone dell’abilità non fa nulla, il bastone sì. Un doppio clic su un bastone a portata (i
template base_crook e base_shepherds_crook, che ogni bastone eredita) chiede “Target the
animal you wish to herd.” (502464). I rifiuti: una cosa che non è un essere vivente (502472), un
animale oltre 10 caselle (500446), uno che non può essere addomesticato — pet.lore non nomina
alcuna min_skill (502468) — e uno che appartiene già a un giocatore (502467). Poi il posto:
“Click where you wish the animal to go.” (502475), e il tiro tra la difficoltà di addomesticamento
dell’animale meno 30 e quella più 30 e un tiro da 0 a 9 punti; quando perfino il culmine della
finestra è sotto l’abilità del pastore legge comunque “That wasn’t even challenging.” (502471).
L’animale è controllato di nuovo quando il posto è scelto: uno morto o addomesticato nel frattempo
è rifiutato con gli stessi testi. Al successo le prop herding.x e herding.y sono impostate sull’animale e il pastore legge “The
animal walks where it was instructed to.” (502479); un fallimento legge la 502472.
La camminata è dell’animale: common/creature.lua fa camminare una
creatura con le prop un passo a think (npc.walk_to), finché non è arrivata o nessuna via vi
conduce, e allora le pulisce; un passo rifiutato (blocked) è solo un ritardo e le conserva, fino
a 20 think di fila (il conteggio herding.blocked), poi l’ordine è lasciato; un combattimento o
una fuga vengono prima, e la camminata riprende dopo, e un animale addomesticato la lascia. La regola di UOX3 di condurre l’animale verso te
(ti segue) non è tenuta.
poisoning.lua
Section titled “poisoning.lua”scripts/skills/poisoning.lua è lo script dell’abilità Poisoning, come quello di ModernUO prima
di AOS. Il giocatore sceglie il veleno da usare (502137) — una delle quattro pozioni di veleno
dell’alchimia (potions.kind), portata o entro 2 caselle; ogni altra cosa non è una pozione di
veleno (502139). Poi sceglie cosa avvelenare (502142): un’arma a una mano che taglia o buca — una
spada, un’ascia, un’arma in asta o un’arma da scherma (item.combat_stats), come chiede ModernUO
prima di AOS — oppure del cibo (un template con script_id = "food"); ogni altra cosa è rifiutata (502145). Il veleno suona (0x4F), la
pozione è spesa e una bottiglia vuota torna indietro, e due secondi dopo l’abilità è provata tra
il minimo e il massimo della finestra della pozione: minore 0-60, normale 30-70, maggiore
60-100, mortale 95-100 punti.
La pozione è ricontrollata alla seconda scelta (ancora a portata, non sul cursore), e il bersaglio quando arriva la prova: uno sparito, fuori portata o tenuto sul cursore non prende nulla (“You fail to apply a sufficient dose of poison”, 1010518, e la dose è persa), e un avvelenatore morto o uscito dal mondo non riceve nessun messaggio.
Al successo il veleno cavalca il bersaglio: la prop poison.level, il livello che conta il
PoisonService — e un’arma anche poison.charges, 18 meno due per
ogni livello — e il giocatore legge “You apply the poison” (1010517) e perde 20 karma attraverso
common/karma.lua. Ogni colpo che va a segno
spende una carica e il veleno passa a chi è colpito una volta su due (CombatService), come vuole la regola classica;
entrambe le props spariscono all’ultima carica. Lo passano solo una spada e un’arma da scherma: un’ascia e un’arma in asta
prendono il veleno ma lo tengono; un pezzo di cibo
avvelenato avvelena chi lo mangia (food.lua). A un fallimento un avvelenatore sotto
80 punti commette un errore grave una volta su venti (poisoning.mistake, un test la
sostituisce): lo legge (502148) e si avvelena da solo; altrimenti una lama legge la 1010516 e il
resto la 1010518. L’abilità attende 10 secondi, il delay di data/skills.toml.
Niente dardi fukiya né shuriken (niente ninjitsu), niente colpo infettivo di AOS.
remove_trap.lua
Section titled “remove_trap.lua”scripts/skills/remove_trap.lua è lo script dell’abilità Remove Trap, come quello di ModernUO.
Chiede un fabbro delle serrature e uno scout: 50 punti di Lockpicking (502366) e 50 di Detect
Hidden (502367) prima del cursore, e chi ne ha di meno è mandato ad allenarla. Il giocatore
sceglie la trappola da disarmare (502368) — un mobile è “inappropriato” (502816), una cosa né
trasportata dal giocatore né entro 2 caselle troppo lontana, e una senza la prop
trap.type «doesn’t appear to be trapped» (502373).
Il lavoro suona (0x241) — un forziere che il giocatore porta viene prima guardato dall’alto,
come la regola Direction di ModernUO gira verso la cosa che si ha in mano — e l’abilità è
provata tra la potenza della trappola e quella più 30 punti (trap.power): al successo le tre props della trappola spariscono — la prossima apertura
del forziere non fa scoppiare nulla — e il giocatore legge «You successfully render the trap
harmless» (502377); al fallimento legge «You fail to disarm the trap… but you don’t set it off»
(502372). Un disarmo fallito non fa mai scattare la trappola, come in ModernUO. L’abilità
attende 10 secondi, il delay di data/skills.toml. Niente trappole
delle fazioni.
Props di rigenerazione
Section titled “Props di rigenerazione”Punti vita, mana e stamina tornano da soli (vedi
ultima.regeneration). Uno script cambia il ritmo di un mobile con le sue
props, in secondi per punto: mobile.set_prop(who, "regen.hits", 2) lo cura cinque volte più velocemente del
valore predefinito; nil gli restituisce il ritmo configurato. Le props sono regen.hits, regen.mana e
regen.stamina.
Muoversi sottrae stamina a un giocatore (vedi fatigue_enabled in
ultima.regeneration): correndo, e a ogni passo quando trasporta più di
mobile.max_weight. Uno script che dà o toglie oggetti cambia subito ciò che il mobile trasporta; la
barra di stato del giocatore segue al prossimo aggiornamento dello stato.
common/teleport.lua
Section titled “common/teleport.lua”I due script di teletrasporto sotto condividono scripts/common/teleport.lua, un modulo Lua che prendono con
local teleport = require("common.teleport"): teleport.send(serial, who) manda un mobile dove indicano le
props dell’oggetto (teleport.x, teleport.y, teleport.z, teleport.map), con il fumo di
source_effect e dest_effect e il suono di sound_id, e teleport.is_on(value) legge un flag
che i file di decorazione contengono come testo. Un tuo script che teletrasporta può prenderlo allo stesso modo.
Uno script conserva il modulo acquisito: dopo script reload common/teleport.lua, ricarica anche gli script che
lo usano (vedi Ricaricamento e appartenenza). mgctl init aggiunge scripts/common/ a una
root esistente e conserva gli script già presenti; una root i cui script degli oggetti vengono sostituiti manualmente richiede
anche scripts/common/, altrimenti i suoi teletrasporti smettono di funzionare.
common/numbers.lua
Section titled “common/numbers.lua”scripts/common/numbers.lua è il modo in cui gli script forniti scrivono un numero letto dal giocatore:
numbers.with_thousands(1234567) restituisce "1,234,567". Il banchiere e l’assegno bancario lo prendono con
local numbers = require("common.numbers"), e un tuo script può fare lo stesso. numbers.in_ranges(list, value)
dice se un numero sta in una delle coppie { first, last } di un elenco, ed è come la fucina, il forno e i fuochi, gli
alberi e il piccone riconoscono un grafico. Una root i cui script sono sostituiti manualmente ne ha bisogno,
altrimenti banchieri, assegni bancari e gli script che riconoscono un grafico smettono di funzionare.
common/karma.lua
Section titled “common/karma.lua”scripts/common/karma.lua toglie a un giocatore il karma di un atto, come Titles.AwardKarma di ModernUO per una
perdita: karma.lose(user, cost) toglie cost e un centesimo del karma posseduto quando è positivo (un buon nome paga
di più, uno cattivo paga meno, e nulla quando il suo karma è sotto -cost * 100), mai sotto -15000, e dice al
giocatore quanto ha perso (“You have lost a little / some / good / a lot of karma”: da 1019063 a 1019066), “a little”
quando la perdita è nulla. Snooping (4) e
Provocation (75) lo usano.
common/geo.lua, speech.lua e skill_points.lua
Section titled “common/geo.lua, speech.lua e skill_points.lua”Tre piccoli moduli tengono ciò che molti script scrivevano ognuno per sé. scripts/common/geo.lua conta le caselle come il
raggio di visuale, la maggiore delle due differenze di coordinata: geo.distance(a, b) per due posti { x, y, map }
(math.huge quando uno è nil o le mappe differiscono, così > range è vero per entrambi), geo.within(a, b, range) per
lo stesso come booleano, geo.near(serial_a, serial_b, range) per due serial, sopra world.distance, che è falso quando
non c’è una distanza, geo.same_storey(a, b) per sapere se due posti distano al più 16 in altezza, quindi stanno su un solo piano,
geo.top_container(serial) per il contenitore più in alto in cui un oggetto sta (l’oggetto stesso quando non sta in
nessuno) e geo.place_of(serial) per dove si trova un oggetto: dove sta il mobile che lo porta, o dove sta a terra il
contenitore in cui si trova. scripts/common/speech.lua ha speech.has_keyword(keywords, wanted) per le parole chiave che il
client ha sentito e speech.addressed(serial, text), vero quando le parole cominciano con il nome dell’NPC, senza badare
alle maiuscole. scripts/common/skill_points.lua ha skill_points.of(who, name), i punti di un’abilità con il nome che le
danno i file di dati (magery, evaluating_intelligence), 0 per una mai allenata e un errore per un nome che non è
un’abilità; uno script che ha già l’abilità in mano scrive mobile.skill_points(who, SkillType.Mining).
Le tre funzioni sotto di loro stanno nei moduli: world.distance(a, b) dà le caselle tra due mobile o oggetti a terra per
serial (nil per uno sconosciuto, un oggetto in un contenitore o due mappe), mobile.skill_points(serial, skill) dà
un’abilità come numero senza costruire una tabella, e pet.owner(serial) dà il proprietario di una creatura, nil se non ne
ha (una prop a 0 non è un proprietario). Una root i cui script sono sostituiti manualmente ha bisogno di
scripts/common/geo.lua, speech.lua e skill_points.lua insieme agli script che li chiedono, altrimenti quegli script
smettono di funzionare.
common/gump_util.lua, skill_ui.lua e il menu di common/shop.lua
Section titled “common/gump_util.lua, skill_ui.lua e il menu di common/shop.lua”Altri tre moduli tengono ciò che i gump, le abilità che fanno scegliere qualcosa e i venditori scrivevano ognuno per sé.
scripts/common/gump_util.lua è per gli script che riempiono uno slot di un gump: gump_util.guard_staff(player, admin) è
il controllo del grado in cima a uno script (un amministratore quando admin è impostato), gump_util.staff_only(fn, admin) e
gump_util.staff_button(g, spec, fn) fanno controllarlo di nuovo a un bottone al clic, perché il grado può essere
sparito mentre il gump era aperto, e passano tutti gli argomenti del clic. gump_util.row(g, y, text, on_click, opts) è il
bottone con il suo testo tagliato accanto, con la grafica gump_util.ART.pick, act, release o back;
gump_util.paged(g, list, opts, fn) imposta il paginatore e chiama fn(entry, y, index) per ogni voce di un elenco
impaginato, e gump_util.page_arrows disegna n / m e le frecce di un elenco che si pagina riaprendo il gump.
gump_util.text(response, index, trim) legge ciò che è stato digitato in un campo, tagliato alle estremità solo quando
trim è impostato. I gump go, pages, pages_detail, gmtools, jail_sentence, stable_claim, items, npcs e
craft_menu li usano; l’elenco del tutorial conserva il solo builder, come esempio del tutorial dei gump.
scripts/common/skill_ui.lua è per le abilità che chiedono al giocatore di scegliere: skill_ui.pick_object(user, prompt, fn)
dice il testo del client, dà il cursore e chiama fn(serial) con ciò che è stato scelto. skill_ui.pick_living(user, opts, fn)
aggiunge i controlli di Anatomy ed Evaluating Intelligence, in quest’ordine e ognuno con il suo testo: il giocatore stesso,
una cosa che non è viva, una invulnerabile e una più lontana di opts.sight, che non dice nulla.
skill_ui.margin(points, base, step) e skill_ui.read_tenth(value, margin) sfumano un numero letto per ciò che manca
all’abilità. scripts/common/shop.lua ha anche shop.menu(serial, player, range), le voci Buy e Sell seguite dalle voci
Train di training.lua, e shop.select_any(serial, player, id), che passa la scelta prima al negozio e poi alle lezioni:
il bottegaio, il guaritore e lo stalliere usano le due. Una root i cui script sono sostituiti manualmente ha bisogno di
scripts/common/gump_util.lua e skill_ui.lua insieme agli script che li chiedono, e di training.lua insieme a shop.lua.
teleporter.lua
Section titled “teleporter.lua”scripts/items/teleporter.lua è lo script del template decoration_teleporter che
.decorate assegna al Teleporter di ModernUO: su on_move_over
teletrasporta il giocatore alle props teleport.x, teleport.y e teleport.z con
mobile.teleport, mostra uno sbuffo di fumo dove il giocatore è partito (prop source_effect) e
arrivato (prop dest_effect), poi vi riproduce la prop sound_id quando il teletrasporto ne ha una. La prop
active = false disattiva un teletrasporto, e la prop deny_mounted gli fa rifiutare un cavaliere (“You must dismount before proceeding.”, 1077252). Viaggiano solo i giocatori, a meno che la prop creatures sia true: allora viaggia anche un NPC che vi cammina sopra. Un teletrasporto con la prop teleport.map, un numero MapType,
porta il giocatore su quella mappa: il client cambia mappa, poi riceve la stagione quando differisce
da quella mostrata, la luce, il meteo e la musica del luogo; quando la mappa non è caricata non succede nulla. Il template ha visibility = "game_master": un oggetto a terra viene inviato solo agli
account consentiti dalla sua visibilità, quindi i giocatori camminano su un teletrasporto che non vedono mai.
keyword_teleport.lua
Section titled “keyword_teleport.lua”scripts/items/keyword_teleport.lua è lo script del template decoration_keyword_teleporter
che .decorate assegna al KeywordTeleporter di ModernUO, come il mantra di un
santuario: su on_speech teletrasporta il giocatore che dice la prop substring (trovata ovunque nel
testo, senza distinzione di maiuscole) o il cui client invia la parola chiave del parlato della prop keyword, trovandosi
entro range caselle (0, il valore predefinito, è la casella stessa del teletrasporto). Con un delay
("0:0:1" o un numero di secondi) il teletrasporto avviene più tardi, se il giocatore è ancora
entro la portata. Destinazione, fumo, suono e active sono quelli del teletrasporto semplice.
public_moongate.lua
Section titled “public_moongate.lua”scripts/items/public_moongate.lua è lo script del template decoration_public_moongate
che .decorate posiziona su ogni destinazione di moongates.toml, come
il PublicMoongate di ModernUO: su on_move_over, e su on_use dalla casella accanto, costruisce un
gump con gump.create, una pagina per mappa di moongates.facets() e un pulsante per città, prima la
pagina della mappa del giocatore, e riproduce il suono 0x20E. Un pulsante teletrasporta il giocatore
con mobile.teleport, anche su un’altra mappa, e vi riproduce 0x1FE. Un giocatore che si è allontanato più
di una casella mentre il gump era aperto viene avvisato e resta; scegliere la città del portale
stesso non fa nulla.
healer.lua
Section titled “healer.lua”scripts/mobiles/healer.lua è lo script dei guaritori (script_id = "healer"): a ogni think chiede a
npc.ghosts_in_sight(serial, 4) i fantasmi entro 4 celle nella sua linea di vista. Un fantasma che non c’era
al think precedente viene guardato (npc.look_at), riceve il suono 0x1F2 e le scintille SparkleHeal, e
il gump resurrect con l’argomento healer, come il BaseHealer di ModernUO. Un guaritore aspetta 2 secondi (4 think)
tra due offerte, e un fantasma incontrato durante l’attesa riceve l’offerta quando finisce. Un criminale viene rifiutato con il
testo del client 501222, e un assassino (rosso) con 501223, e un giocatore con karma negativo si sente dire 501224 e riceve comunque l’offerta. Un guaritore malvagio, il cui id di template inizia con evil (evilhealer, evilwhealer), non rifiuta nessuno e non dice nulla. Un guaritore di un
template che finisce con whealer, uno errante, fa un passo con npc.wander a ogni quarto think. Un guaritore con un negozio vende e compra come un venditore, tramite scripts/common/shop.lua: bende, pozioni, ginseng e aglio. Insegna anche le abilità che possiede, tramite scripts/common/training.lua (vedi Istruttori).
ethereal_mount.lua
Section titled “ethereal_mount.lua”scripts/items/ethereal_mount.lua è lo script delle statuette eteree (script_id = "ethereal_mount"): il suo
on_use chiama mount.ride_ethereal(user, serial), che dice con le parole del client perché rifiuta, e restituisce true
così il doppio clic non apre nient’altro. Vedi Cavalcature.
mount_stone.lua
Section titled “mount_stone.lua”scripts/items/mount_stone.lua è lo script delle pietre della cavalcatura (script_id = "mount_stone"): il suo
on_use chiama mount.toggle_stone(user, serial), che cavalca la cavalcatura della pietra oppure, quando il
giocatore sta già sulla cavalcatura di questa stessa pietra, scende; la pietra resta nello zaino. Dove il giocatore sale o scende compaiono una nuvola di fumo e il suo suono
(0x1FE). Restituisce true
così il doppio clic non apre nient’altro. Vedi Cavalcature.
engraved_stone.lua
Section titled “engraved_stone.lua”scripts/items/engraved_stone.lua è lo script della pietra incisa (script_id = "engraved_stone"). on_use apre il
gump di sola lettura stone_read (templates/gumps/stone_read.xml) con il titolo e le righe conservati nelle prop
stone.title e stone.text, oppure dice che non c’è ancora scritto nulla; restituisce true. can_pick_up lascia
sollevare la pietra al proprietario (la prop owner, assegnata all’acquirente dal venditore) e allo staff, e dice a
chiunque altro che non è sua. can_drop rifiuta un rilascio in un contenitore che chi rilascia non porta con sé, così la
pietra non può andarsene dentro una borsa. I limiti e le regole che lo script e i gump condividono sono in
scripts/common/engraved_stone.lua. Il gump per scrivere, stone_write (templates/gumps/stone_write.xml, aperto da
.write), ha i campi costruiti da stone_write.rows in scripts/gumps/stone_write.lua, che
ricontrolla il proprietario e ripulisce i testi quando salva. Vedi Pietre incise.
engraved_ring.lua e common/engraving.lua
Section titled “engraved_ring.lua e common/engraving.lua”scripts/items/engraved_ring.lua è lo script degli anelli che un gioielliere incide (script_id = "engraved_ring"). Il
testo è conservato nella prop ring.text: on_tooltip aggiunge con esso la riga “Engraved: …” del client, e on_use
lo dice al giocatore. scripts/common/engraving.lua è ciò che i gioiellieri condividono: la voce “Engraving:” del menu
contestuale, la parola “engrave” detta a un gioielliere per nome entro 4 caselle, l’ordine preso dal gump ring_engrave
(templates/gumps/ring_engrave.xml, costruito da scripts/gumps/ring_engrave.lua) e l’oro esatto lasciato sul
gioielliere che lo paga: 500 monete d’oro per un anello, 1000 per una fede nuziale. shopkeeper.lua e common/shop.lua lo
richiamano. Vedi Anelli incisi.
stablemaster.lua e stable_claim.lua
Section titled “stablemaster.lua e stable_claim.lua”scripts/mobiles/stablemaster.lua è lo script degli addestratori di animali (script_id = "stablemaster"). Le parole
stable e claim, dette entro 12 celle, e le voci Stable e Claim All del menu contestuale guidano il modulo
stable: stable dà un cursore (target.pick) e chiama stable.stable sull’animale scelto, rispondendo con
il testo del client per ogni StableResultType; claim dice l’introduzione dell’elenco e apre il gump stable_claim
(templates/gumps/stable_claim.xml), oppure dice che non ci sono animali; Claim All chiama stable.claim sul primo posto
finché l’elenco non è vuoto. Più addestratori sentono le stesse parole e stable.attend ne fa rispondere uno. Un addestratore di animali
mantiene il suo negozio e le sue lezioni tramite scripts/common/shop.lua e training.lua.
scripts/gumps/stable_claim.lua riempie il gump con un pulsante e il nome dell’animale per ogni animale di stable.pets,
otto per pagina; un pulsante controlla che il giocatore sia entro 12 celle dall’addestratore e chiama stable.claim; un elenco
cambiato da quando è stato mostrato viene mostrato di nuovo.
hireling.lua
Section titled “hireling.lua”scripts/mobiles/hireling.lua è lo script dei dieci mercenari di Jhelom (script_id = "hireling"), fatto con
common/creature.lua, di cui avvolge on_think, on_speech, on_drag_drop e on_death. Uno libero risponde alle parole
hire, servant e a un saluto (SpeechKeywordType.Hire, Servant, Greeting) entro 6 celle, e alla voce Hire
(cliloc 6120) del suo menu contestuale, con la sua paga: le dieci skill del suo template sommate, diviso 35, più 1. L’oro
rilasciato su di lui (item.item_id 0x0EED) per almeno quella paga chiama pet.hire, prende l’oro con item.consume e lo
tiene nella prop hire.gold, con hire.next_pay portata avanti di pet.hire_period() secondi. Il suo on_think salda in
un passo i periodi trascorsi, secondo world.now(), e chiude il contratto con npc.delete e il testo 503235 del client quando
l’oro non copre il periodo seguente; on_release azzera le due prop e on_death tiene fuori dal cadavere ciò che indossava. Uno
assunto ha un padrone (pet_orders.is_owned), quindi le parole del padrone sono quelle di un animale. Vedi
Mercenari.
pet_orders.lua e pet_release.lua
Section titled “pet_orders.lua e pet_release.lua”scripts/common/pet_orders.lua è ciò che common/creature.lua esegue per una creatura che ha un owner: is_owned(serial)
dice se ne ha uno (domata o evocata); think segue
l’ordine nella prop pet.order (follow, come, stay o guard; follow se non ne ha), e listen, dall’
on_speech degli script delle creature, legge le parole del proprietario (SpeechKeywordType.PetCome, AllStay e le altre)
entro 14 tile. Delle parole “all” solo all kill è eseguita dal primo animale che chiama pet.attend(owner), per ogni animale del
proprietario a portata, dato che c’è un solo cursore; ogni altro ordine “all” è obbedito da ogni animale per conto suo; kill chiede un bersaglio con target.pick; release apre il gump pet_release
(templates/gumps/pet_release.xml), il cui pulsante Release chiama pet.release dopo aver verificato che l’animale sia ancora del giocatore e
entro 14 tile. Ogni ordine tranne release tira prima pet.obey(owner, pet) (la probabilità è pet.control_chance): un animale che
rifiuta ringhia e si agita e non esegue l’ordine. feed(serial, giver, given) è ciò che gli script delle creature restituiscono da
on_drag_drop: il cibo del proprietario va a pet.feed, che prende la pila e aumenta la lealtà (pet.loyalty); il cibo che la
creatura non mangia viene restituito. Il cibo può anche legare l’animale (al proprietario viene detto 1049666). menu(serial, player) e
select(serial, player, id) sono ciò che creature.new restituisce da on_context_menu e on_context_menu_select: i
nove comandi del padrone (Kill, Follow, Guard, Stop, Stay, Rename, Add Friend, Remove Friend, Release) e i tre di un
amico, ognuno uguale alla sua parola; Rename dice solo di modificare il nome nella barra di stato. Gli amici sono la
prop pet.friends (seriali interi separati da virgole, al massimo cinque); is_friend(serial, who) la legge e listen
ascolta un amico solo per follow, stay e stop, con il tiro di pet.obey sulle skill dell’amico; il follow di un amico
tiene l’amico nella prop pet.follow, che think segue al posto del padrone finché un ordine del padrone non la toglie. Vedi Animal taming e
lealtà, cibo e obbedienza.
animal_taming.lua
Section titled “animal_taming.lua”scripts/skills/animal_taming.lua è l’abilità Animal Taming: on_use dice “Tame which animal?” (502789), dà un cursore
(target.pick) e restituisce un’attesa di 1 secondo. La scelta viene rifiutata con il testo del client se non è una creatura, è un giocatore,
non è in taming.toml (pet.info), ha un padrone, ci sono troppi seguaci (pet.followers e pet.max_followers), supera l’abilità
o è a più di 3 caselle. Poi tre o quattro volte ogni 3 secondi (timer.after) ricontrolla la distanza (7), che il domatore sia
vivo, la linea di vista (world.line_of_sight), che la creatura sia ancora selvatica e non ferita (mobile.stats), e dice una
frase gentile; l’ultima tira skill.check(user, "animal_taming", min - 0.1, min + 49.9) e pet.tame. Vedi
Domatura degli animali.
polymorph_forms.lua
Section titled “polymorph_forms.lua”scripts/gumps/polymorph_forms.lua è lo script dell’elenco di forme dell’incantesimo Polymorph
(templates/gumps/polymorph_forms.xml). Ognuno dei suoi 18 pulsanti chiama la funzione con il suo nome (chicken, dog,
wolf, panther, gorilla, black_bear, grizzly_bear, polar_bear, human_male, slime, orc, lizardman,
gargoyle, ogre, troll, ettin, daemon, human_female), che conserva il corpo nelle proprietà
magic.polymorph_body e magic.polymorph_until (quindici secondi) e lancia di nuovo l’incantesimo, dal libro o da una
pergamena dello zaino. Lo script dell’incantesimo scripts/spells/polymorph.lua cambia poi il corpo con
mobile.disguise. Vedi Magery.
ankh.lua e resurrect.lua
Section titled “ankh.lua e resurrect.lua”scripts/items/ankh.lua è lo script del template decoration_ankh, i due pezzi di ogni
AnkhWest e AnkhNorth che .decorate posiziona. Non ha on_use: i vivi non hanno nulla da fare
con un ankh. La sua on_ghost_use viene eseguita quando un giocatore morto lo usa con un doppio clic (Morte e
resurrezione): da più di 2 celle dice “È troppo lontano.”
(testo del client 500446), altrimenti apre il gump resurrect (templates/gumps/resurrect.xml). Il suo
pulsante Continue chiama resurrect.accept in scripts/gumps/resurrect.lua, che, se il giocatore è
ancora morto ed entro 2 celle dall’ankh (8 dal guaritore, se ha offerto un guaritore),
chiama mobile.resurrect, riproduce il suono 0x214 e l’effetto SparkleHeal sul giocatore e gli toglie un
decimo della fama; da cinque omicidi a breve termine toglie anche abilità e statistiche (Conteggi degli omicidi).
Cancel non fa nulla.
moongate.lua
Section titled “moongate.lua”scripts/items/moongate.lua è lo script del template moongate, il portale con una
destinazione che il comando moongate posiziona ai piedi di un game master, come
il Moongate di ModernUO. Su on_move_over, e su on_use dalla casella accanto, attende un secondo
con timer.after, poi porta il giocatore, se è ancora lì, alle props teleport.x,
teleport.y e teleport.z, sulla mappa della prop teleport.map (un numero MapType o il suo
nome; la mappa del giocatore in sua assenza), e riproduce 0x1FE. Un portale senza i tre
numeri, con una mappa inesistente o non caricata, o con un punto fuori dalla mappa dice al
giocatore “Questo moongate non sembra portare da nessuna parte.” (messaggio 30114). Toccare nuovamente il portale
durante quel secondo non avvia nulla. Quando il portale
si trova in una regione sorvegliata e la destinazione no (world.is_guarded), chiede prima conferma: un
gump con OKAY e CANCEL e il suono 0x20E; OKAY da più di una casella di distanza dice “È
troppo lontano.” (messaggio 393) con mobile.message. Le regole ModernUO su sigilli, giovani
giocatori, assassini e lancio di incantesimi non sono ancora presenti; i seguaci del giocatore entro 3 caselle passano
con lui (mobile.teleport con l’ultimo argomento true). I portali dell’incantesimo Gate Travel sono del
template magic_gate, che usa questo script: il suo timer di oggetto expire (on_timer) porta via il portale dopo 30
secondi, e l’incantesimo Dispel Field lo porta via, con il portale all’altro capo (la prop gate.partner).
bulletin_board.lua
Section titled “bulletin_board.lua”scripts/items/bulletin_board.lua è lo script delle bacheche
(il template di oggetto decoration_bulletin_board posizionato da .decorate, e bulletin_board e
bulletin_board_2 per una bacheca aggiunta manualmente). Il suo on_use chiama board.open(serial, user)
e restituisce true: il client del giocatore riceve la bacheca e l’elenco dei messaggi, e da
lì legge, pubblica, risponde e rimuove i propri. Qualsiasi template di oggetto con questo script è una bacheca,
ciascun oggetto con i propri messaggi.
clock.lua
Section titled “clock.lua”scripts/items/clock.lua è lo script degli orologi (template degli oggetti clock e
clock_2, e decoration_clock per quelli posizionati da .decorate), come il Clock di ModernUO: su
on_use il giocatore legge sopra l’orologio la parte del giorno (“È pomeriggio”) e l’ora al
minuto (“1:07 per l’esattezza”) del luogo in cui si trova, da world.time, come testi del client inviati
con item.message_cliloc.
fillable.lua
Section titled “fillable.lua”scripts/items/fillable.lua è lo script del template decoration_fillable che .decorate
assegna ai contenitori cittadini, il FillableContainer di ModernUO: casse, scatole, forzieri e barili
dei negozi e librerie delle biblioteche. Su on_use, prima dell’apertura del contenitore, un
contenitore il cui tempo è arrivato (prop fill.next, secondo il conteggio di world.now()) e che contiene due cose
o meno, una pila contando per la propria quantità, riceve fino al doppio di ciò che manca per arrivare a tre, ciascuna
un’estrazione della tabella del bottino del proprio tipo con item.add_loot; una libreria si riempie fino a cinque libri. Poi attende da 60 a 90 minuti; un riempimento che non ha potuto aggiungere nulla viene riprovato all’apertura successiva.
Non viene eseguito nulla mentre nessuno apre il contenitore, e i tempi sopravvivono al riavvio. Il tipo è la
prop content_type, come baker per la tabella fillable_baker di
templates/loots/fillable_containers.toml; in sua assenza il contenitore assume il tipo del venditore più vicino
entro 20 caselle, indicato da mobile.template, e lo conserva. Senza venditori intorno resta
vuoto e cerca di nuovo cinque minuti dopo. ModernUO inizia l’attesa quando viene estratto un oggetto e
chiude a chiave e mette trappole al contenitore: questi aspetti non sono ancora presenti. Le tabelle cittadine usano
templates/loots/randomshields.toml (uno scudo semplice, Loot.ShieldTypes di ModernUO) e i due prodotti di
templates/items/town_goods.toml (mazzuolo e scalpello, aste per frecce) mancanti nei file di oggetti convertiti.
gmtools.lua
Section titled “gmtools.lua”scripts/gumps/gmtools.lua è lo script del gump degli strumenti del game master
(templates/gumps/gmtools.xml), aperto da .gmtools. Il gump ha due
slot, riempiti da due funzioni: tools disegna la barra laterale, un pulsante per ogni voce della tabella
tools nello script, e panel disegna il pannello di quello selezionato (args.tool, il primo quando
non viene fornito o è sconosciuto). Un clic sulla barra laterale riapre il gump su quello strumento.
Ci sono quattro strumenti, meteo, stagione, ora ed eventi. Il pannello meteo legge world.weather_profile e world.weather e
ha un pulsante per ciascun tipo, none, rain, snow e storm, che chiama world.set_weather sul
giocatore, gli dice The weather of temperate is now storm until the next hour. e riapre il gump.
Il pannello stagione legge world.season_here e la stagione della mappa del giocatore
(world.season di mobile.location(player).map) e ha un pulsante per ogni stagione e uno per
auto, che chiamano world.set_season o world.clear_season, dicono al giocatore The season of your map is now winter. e riaprono il gump. Il pannello ora legge world.time, world.moon,
world.light_here e world.global_light e ha un pulsante per ciascuno di quattro livelli di luce e uno per
auto, che chiamano world.set_global_light o world.clear_global_light e dicono al giocatore The global light is now 26.. Il pannello eventi (una voce con admin = true, quindi solo per gli amministratori) legge schedule.events e ha pulsanti auto, on e off per ogni evento, che chiamano schedule.set_event, dicono al giocatore Halloween is now off. e riaprono il gump. Solo staff: gli slot sono vuoti per chiunque altro, e ogni
pulsante ricontrolla world.is_staff, e world.is_administrator per gli eventi.
Per aggiungere uno strumento, scrivi una funzione pannello con firma function(g, player) e aggiungi
{ id = "...", title = "...", panel = ... } a tools.
items.lua
Section titled “items.lua”scripts/gumps/items.lua è lo script del gump della ricerca degli oggetti (templates/gumps/items.xml), che apre
.items. Il gump ha uno slot, riempito da body(g, player, args): un titolo, un campo di testo
legato a query con un pulsante Search che riapre il gump con esso, e poi le corrispondenze di item.search (le prime 40;
il titolo dice quando ce ne sono di più), cinque per pagina scelta da args.page, ciascuna disegnata con g:item della sua
grafica, il suo nome e id, e due pulsanti che chiamano item.give e item.create a mobile.location(player). Le frecce e
n / m riaprono il gump sulla pagina prima o dopo, così un Give mantiene la pagina. Un ${name} digitato viene mostrato
com’è digitato. Solo per lo staff: lo slot è vuoto per chiunque altro, e ogni pulsante ricontrolla world.is_staff.
npcs.lua
Section titled “npcs.lua”scripts/gumps/npcs.lua è lo script del gump della ricerca degli NPC (templates/gumps/npcs.xml), che apre
.npcs, costruito come items.lua. Il suo slot contiene un titolo, un campo di testo
legato a query con un pulsante Search, e poi le corrispondenze di npc.search (le prime 40, il titolo dice quando ce ne
sono di più), cinque per pagina scelta da args.page, ciascuna disegnata con g:portrait del suo corpo e con un pulsante
Spawn che chiama npc.spawn a mobile.location(player). Le frecce riaprono il gump sulla pagina prima o dopo, così uno
Spawn mantiene la pagina. Solo per lo staff: lo slot è vuoto per chiunque altro, e ogni pulsante ricontrolla
world.is_staff.
guard_outsider.lua
Section titled “guard_outsider.lua”scripts/mobiles/guard_outsider.lua è lo script delle guardie delle terre selvagge, per i luoghi fuori dalle città
sorvegliate: lo usano i template guard_outsider (un’alabarda) e guard_outsider_archer (un arco) con
script_id = "guard_outsider", e un game master ne mette a terra una con .npcs. A differenza delle
guardie cittadine di guard.lua, che uccidono un mostro con un colpo e non si possono ferire, queste combattono
sul serio: hanno il nome blu (notoriety = "innocent"), così i mostri le attaccano come fanno con i cittadini, da 151 a 191
punti vita, danno da 10 a 24 (prima dei bonus delle sue abilità e della forza), armatura 20, abilità di combattimento da 85 a
95, e colpi, impatti e morte sono del servizio di combattimento: un NPC combatte con la sua abilità di wrestling e il danno
del suo template, l’alabarda e l’armatura che indossa sono solo scenografia (e cadono con il suo cadavere), e l’arciere spara
con il suo arco. Lo script è common/creature.lua con la sua opzione prey: attacca i mostri selvatici che vede entro 16
caselle (gli NPC con lo script monster che nessuno ha domato, che non sono morti e non hanno il nome blu: un combattente o
un paladino delle città ha anch’esso lo script dei mostri), e non inizia mai uno scontro con un giocatore, un cittadino, un
animale o un animale domestico; risponde a un colpo come qualsiasi creatura, e il suo template imposta flee_at = -1,
quindi non scappa mai. Uno con un arco si ferma dove l’arco arriva e spara.
help_menu.lua
Section titled “help_menu.lua”scripts/gumps/help_menu.lua è lo script del menu di aiuto
(templates/gumps/help_menu.xml), che si apre con il pulsante Help del paperdoll. stuck è il pulsante
«Sono bloccato»: rifiuta un personaggio in prigione (jail.sentence) o in combattimento (combat.target),
uno che sta già aspettando e uno la cui pausa (la proprietà help.stuck_until, secondi dal 1970 da
world.now) non è finita, escluso lo staff; prende la città di partenza più vicina da help.nearest_city,
dice l’attesa da help.settings e, dopo timer.after di quei secondi, sposta il personaggio con
mobile.teleport se è dove era e se ha ancora il permesso. commands esegue help con
commands.execute_as, rules dice il messaggio 30200 e call apre help_page_kind.
help_page_kind.lua
Section titled “help_page_kind.lua”scripts/gumps/help_page_kind.lua è lo script del secondo passo di Call a game master
(templates/gumps/help_page_kind.xml). question, bug, suggestion e harassment interrogano help.can_page;
a un giocatore che non può viene detto perché (messaggi 30213 e 30214) prima che scriva qualcosa. Altrimenti
gli viene detto di scrivere una riga (30211), prompt.ask la aspetta e help.create_page manda la richiesta
con l’HelpPageKindType del pulsante; Esc o una riga vuota dice 30215, un rifiuto alla fine ripete il suo
motivo e una richiesta inviata dice 30212. Può chiamare anche un giocatore in prigione.
pages.lua
Section titled “pages.lua”scripts/gumps/pages.lua è lo script della coda dello staff (templates/gumps/pages.xml, aperta da
.pages). rows riempie lo slot con help.pages(), dalla più vecchia, dieci per pagina,
un pulsante e una riga per richiesta (#1 Gino, Bug, 3 min, open); una riga apre pages_detail su quella
richiesta. Solo per lo staff: lo slot resta vuoto per chiunque altro, e ogni pulsante ricontrolla world.is_staff.
pages_detail.lua
Section titled “pages_detail.lua”scripts/gumps/pages_detail.lua è lo script di una richiesta (templates/gumps/pages_detail.xml). go porta il
game master dal giocatore (mobile.location) o, se è offline, dove ha chiesto; take chiama help.take;
answer prende il testo del campo (response.text[1]), rifiuta un campo vuoto e altrimenti chiama
help.answer e torna alla coda; close chiama help.close. Una richiesta chiusa nel frattempo lo dice e non
cambia nulla.
common/help_pages.lua
Section titled “common/help_pages.lua”scripts/common/help_pages.lua è il modulo Lua che i due gump dello staff condividono, preso con
require("common.help_pages"): le parole per un genere, una mappa, un’età e uno stato, la riga di una richiesta
e gli argomenti del suo gump di dettaglio.
jail_sentence.lua
Section titled “jail_sentence.lua”scripts/gumps/jail_sentence.lua è lo script del gump della prigione
(templates/gumps/jail_sentence.xml), aperto da .jail senza bersaglio,
e da .jail <name> sul giocatore con quel nome.
La sua funzione rows riempie lo slot: prima un pulsante che fornisce il cursore con target.pick e riapre
il gump sul personaggio selezionato, poi le celle di jail.cells(), dieci per pagina. Con un
personaggio selezionato, una cella libera ha un pulsante che legge i giorni digitati nel gump e chiama
jail.send(target, cell, days, who, reason), il motivo è ciò che viene digitato nel secondo campo; giorni vuoti, non numerici, frazionari o oltre
jail.max_days() non incarcerano nessuno, e il gump si riapre con il motivo. Una cella occupata
mostra il nome, il tempo rimanente come 2d 4h, 5h 10m o 12m, e un pulsante che chiama
jail.release. Ogni cella ha un pulsante che vi porta il game master con
mobile.teleport(who, cell.x, cell.y, cell.z, cell.map), sulla mappa della prigione. Un bersaglio già
in prigione ha il proprio rilascio su una riga separata in alto.
Un bersaglio fuori dal mondo, un giocatore trovato da .jail <name>, viene mostrato come (offline):
mobile.name è nil per lui. jail.send risponde allora JailResultType.Pending e il game master
viene informato che la cella è riservata fino al login; una cella così mostra waits for login, dal pending
di jail.cells(). Quando il gump viene aperto con candidates, più giocatori con lo stesso nome, la
funzione li elenca, al massimo dieci, con account e stato online, ciascuno con un
pulsante che apre il gump su di lui, e omette le celle finché non ne viene scelto uno.
Ogni pulsante ricontrolla world.is_staff: il grado potrebbe essere stato rimosso mentre il gump era aperto.
jail_note.lua
Section titled “jail_note.lua”scripts/items/jail_note.lua è lo script del template jail_release_note, la nota che un
prigioniero trova nello zaino alla fine della pena. Su on_use delega a
book.open, mostrando book.content salvato o il vecchio jail.text: giorni scontati, cella, date
e multa pagata. La pergamena condivisa esegue l’escape del testo semplice e scorre i testi lunghi. Una nota senza
testo, come una creata con .add, non mostra nulla.
readable_scroll.lua
Section titled “readable_scroll.lua”scripts/items/readable_scroll.lua delega il doppio clic a book.open. Il template non impilabile
readable_scroll è usato dal catalogo dei testi.
Crea una lettera personalizzata con book.give(player, "welcome_letter", { contact_name = "Vega" }).
Titolo, autore e corpo salvati restano fissi quando un altro giocatore la legge.
readable_book.lua
Section titled “readable_book.lua”scripts/items/readable_book.lua delega il doppio clic a book.open come la pergamena; per un
oggetto del template readable_book, book.open invia il libro del client, la copertina e ogni pagina,
invece della pergamena (libri e pergamene).
I testi importati da ModernUO lo usano: book.give(player, "grammar_of_orcish").
bank_check.lua
Section titled “bank_check.lua”scripts/items/bank_check.lua è lo script degli assegni della banca, che un banchiere scrive per l’oro della banca (“check
5000”). Un doppio clic su un assegno dentro il forziere aperto della banca lo trasforma di nuovo in monete del forziere, in
pile da 60000. Un forziere con spazio per una parte dell’oro prende ciò che ci sta e l’assegno tiene il resto. Fuori dal
forziere della banca un assegno è soltanto un pezzo di carta che vale quanto dice il suo suggerimento. Vedi Banca.
snow_pile.lua
Section titled “snow_pile.lua”scripts/items/snow_pile.lua è la palla di neve dell’evento di Natale. Un doppio clic su una pila nello zaino chiede un
bersaglio; la palla vola verso un mobile che porta a sua volta una pila, lo colpisce, ed entrambi lo leggono. Un giocatore
aspetta 5 secondi tra due palle di neve e non può lanciarne una in sella. Un template di oggetto la usa con
script_id = "snow_pile".
banker.lua
Section titled “banker.lua”scripts/mobiles/banker.lua è lo script dei banchieri. Un giocatore entro 12 caselle dice una parola e il banchiere apre il
suo forziere (“bank”), dice il saldo (“balance”), consegna oro (“withdraw 500”), lo prende (“deposit 500”) o scrive un assegno
(“check 5000”). Il client trasforma la maggior parte di queste parole in parole chiave del discorso in qualsiasi lingua;
“deposit” è solo in inglese. L’oro e gli assegni lasciati sul banchiere vanno in banca (on_drag_drop). Un banchiere non fa
affari con un criminale. Quanto consegna in una volta è l’impostazione ultima.bank.max_withdraw. Vedi Banca.
quest_giver.lua
Section titled “quest_giver.lua”scripts/mobiles/quest_giver.lua è lo script degli NPC che danno le quest migrate da ModernUO (script_id = "quest_giver" del template
ml_questgiver, vedi Quest): stanno dove sono (lo script non ha on_think). on_mobile_in_range
passa il mobile che si è avvicinato a quest.on_near di scripts/events/quest.lua, che interroga common/quest_shout.lua: un giocatore
vivo e visto dall’NPC quando entra in ultima.npcs.sense_range (8 tile di default, come il raggio delle grida di ModernUO), che ha una
quest disponibile dal template dell’NPC, lo fa voltare e dire, con npc.say_cliloc_to, a quel giocatore soltanto, uno dei numeri che il suo
template ha in scripts/quests/ml_shouts.lua, e l’NPC tace per un minuto (60 secondi di world.now()). Un NPC senza frasi costa l’hook in
coda, una chiamata Lua e una ricerca del template per ogni mobile che si avvicina. Insegna le abilità che ha tramite common/training.lua,
come shopkeeper: on_speech (la parola train, a cui un NPC che non ha nulla da insegnare non risponde), on_context_menu e
on_context_menu_select (le voci Train) e on_drag_drop (l’oro per una lezione). Le voci di quest del menu contestuale e il doppio clic sono del motore.
shopkeeper.lua
Section titled “shopkeeper.lua”scripts/mobiles/shopkeeper.lua è lo script dei venditori PNG. Un giocatore sceglie Buy o Sell nel menu contestuale del
venditore, oppure dice “vendor buy” o “vendor sell” entro 4 caselle, e si apre la finestra del negozio. Cosa vende un
venditore è il suo negozio in templates/shops; la finestra, i prezzi e l’acquisto sono lavoro del server (il modulo
vendor), non dello script. I venditori insegnano anche abilità (common/training.lua), i gioiellieri incidono anelli (common/engraving.lua), e
mentre l’evento halloween è attivo rispondono a “trick or treat” (common/trick_or_treat.lua). Vedi Venditori.
common/guild.lua
Section titled “common/guild.lua”scripts/common/guild.lua è ciò che condividono gli script dei maestri di gilda. Un giocatore entro 2 celle dice il nome del
maestro di gilda e “join” o “member” per sapere il prezzo della sua gilda (500 monete d’oro), lascia esattamente quell’oro
su di lui per entrare, e dice il suo nome e “resign” o “quit” per uscire, al più presto una settimana dopo essere entrato. Il
server tiene l’iscrizione (il modulo npcguild). guild.listen(serial, speaker, text, keywords) gestisce le parole e
guild.drop(serial, giver, item) l’oro.
guildstone_deed.lua, guildstone.lua e gumps/guild_menu.lua
Section titled “guildstone_deed.lua, guildstone.lua e gumps/guild_menu.lua”Le gilde dei giocatori, come quelle dello shard classico, contro i maestri di gilda PNG qui sopra: una gilda si fonda su una
pietra, non si entra con l’oro. scripts/items/guildstone_deed.lua spende l’atto, portato o a terra entro 2 caselle: a un giocatore
senza gilda è chiesto il nome (da 30275 a 30279 dicono del problema) e sceglie il terreno, un punto entro 3 caselle su cui si può
stare e libero (30293 quando non lo è), e vi è posata una guildstone che tiene la gilda con le sue prop guild e
guild_founded, il fondatore suo primo membro; la gilda è fatta dopo la pietra, e un rifiuto lascia l’atto e nessuna pietra.
scripts/items/guildstone.lua apre guild_menu a un membro della gilda della pietra entro 2 caselle; a un estraneo è detto 30281 e a
una pietra sciolta 30280. Quando un’altra pietra sta entro 5 caselle il gump è aperto con l’altra gilda, così il capo può dichiarare
su di essa. scripts/gumps/guild_menu.lua riempie il gump: l’elenco dei membri a pagine, il capo per primo, un clic dà fedeltà, il
capo scrive lo statuto, il sito e il colore e dà titoli ed espulsione, e i pulsanti di guerra e alleanza lavorano l’altra gilda. Il
gump prende il nome dal menu, non dal modulo: uno script di gump possiede la tabella globale del proprio nome. Vedi
Gilde.
common/holiday_decor.lua
Section titled “common/holiday_decor.lua”scripts/common/holiday_decor.lua mette le decorazioni di un evento festivo intorno al centro delle città principali, su
Felucca e su Trammel. place(event_id, templates) viene eseguita quando un evento inizia, remove(event_id) quando finisce.
I serial sono conservati nella prop del mondo holiday.<event_id>.items, quindi gli oggetti spariscono anche dopo un
riavvio, e posizionare due volte non mette nulla due volte.
common/trick_or_treat.lua
Section titled “common/trick_or_treat.lua”scripts/common/trick_or_treat.lua è il gioco di Halloween. Mentre l’evento halloween è attivo (data/schedule.toml), un
giocatore che dice “trick or treat” entro 4 caselle da un negoziante riceve una caramella, o uno scherzo. Ogni negoziante
riposa da 5 a 10 minuti dopo aver risposto, e una frase viene raccolta da un solo negoziante. shopkeeper.lua chiama
listen dal suo on_speech.
events/christmas.lua e events/halloween.lua
Section titled “events/christmas.lua e events/halloween.lua”Gli hook degli eventi stagionali di data/schedule.toml: on_start(id, name) decora le città
(common/holiday_decor.lua) e avvisa tutti, on_end(id, name) toglie le decorazioni e avvisa tutti. Halloween ha solo questi due; il gioco in sé è
common/trick_or_treat.lua. Natale ha anche on_login(id, name, player): un personaggio che entra durante l’evento riceve
un regalo una volta (due pile di neve, una candela festiva e una decorazione), e non di nuovo per 200 giorni. Vedi
Programmazione.
common/quest.lua, common/quest_ui.lua e events/quest.lua
Section titled “common/quest.lua, common/quest_ui.lua e events/quest.lua”Il motore delle quest, i suoi gump e lo script che lo avvia e risponde al server; vedi Quest per il formato di una quest e come funzionano i pezzi.
gumps/go.lua
Section titled “gumps/go.lua”scripts/gumps/go.lua è lo script del gump dei luoghi con nome (templates/gumps/go.xml) che .go
apre. rows(g, player, args) riempie lo slot “rows” con un livello di data/locations.toml, prima le categorie e poi i
luoghi, dodici per pagina. Una categoria apre il gump un livello più in basso, un luogo porta lì il viaggiatore. Solo per lo
staff: chiunque altro vede un gump vuoto.
definitions.lua
Section titled “definitions.lua”Tra gli script distribuiti non c’è nessun definitions.lua: il motore lo genera all’avvio, per il completamento
dell’editor, dai moduli, dalle funzioni e dalle enum registrati (vedi Scrivere un modulo Lua). Non
modificarlo.
Creato con ❤️ da Tom
