DimensioneX/it/guildsystem: Difference between revisions
Line 14: | Line 14: | ||
Tutto inizia da una stanza ('''guildroom'''), che è quella dove l'applicazione è concentrata. | Tutto inizia da una stanza ('''guildroom'''), che è quella dove l'applicazione è concentrata. | ||
Per questo ho creato | Per questo ho creato questa stanza apposita (torre sud-ovest) e un personaggio apposito ('''Lord Guilford''') che serve a far arrivare all'utente i messaggi d'errore se per caso sbaglia qualcosa. | ||
ROOM guildroom | ROOM guildroom |
Revision as of 10:01, 7 December 2005
Come funziona il guild system (sistema gilde) in Underworld
Il sistema delle gilde di Underworld è una piccola applicazione inserita nel gioco Underworld e costruita grazie a due caratteristiche di DimensioneX: i SET e le istruzioni SaveSetting/LoadSetting.
Questo articolo si riferisce alla versione 6.9.5 italiana di Underworld, e alla versione 6.0.2a di DimensioneX.
Se avete altre versioni del software potreste incontrare delle inesattezze. Essendo però questo articolo un WIKI potete voi stessi correggerlo dove serve usando la linguetta EDIT o lasciare commenti usando la linguetta DISCUSSION.
Buona lettura.
1 la stanza delle gilde
Tutto inizia da una stanza (guildroom), che è quella dove l'applicazione è concentrata.
Per questo ho creato questa stanza apposita (torre sud-ovest) e un personaggio apposito (Lord Guilford) che serve a far arrivare all'utente i messaggi d'errore se per caso sbaglia qualcosa.
ROOM guildroom NAME nella Torre Sud-Ovest DESCRIPTION Questa è la stanza del capitano delle guardie. Lui conosce tutte le Gilde. IMAGE S armoroom2.jpg PANEL pguilds
In questa stanza si potranno gestire le gilde, ecco perchè nella definizione della stanza specifico che usa un pannello speciale di cui parliamo subito
2 il pannello
Perchè sia possibile gestire il sistema delle gilde, ho creato un apposito set di comandi.
In pratica serve creare un nuovo pannello di comandi, pguilds, che è così definito:
PANEL pguilds VERSION OF default CR CR BUTTON guildcmd, "Do this: ", "Guild action", doGuildOperation DROPDOWN guildop, guildOps, join LABEL "" DROPDOWN guildsel, guildnames, 0
Si tratta, come si vede di una variante del pannello di default a cui sono state aggiunte due liste a tendina (drop-down). Questo è un nuovo controllo che è stato introdotto nella versione 6.0.2 di DimensioneX, che funziona così (vediamo prima la prima lista):
3 la lista a discesa
Il primo id, guildop rappresenta la tendina stessa.
Di questo ID non ce ne dobbiamo preoccupare finché non arriva il momento di leggere l'input dell'utente.
Segue il nome di un SET, guildops. Questo è fondamentale perchè dovrà contenere tutte le scelte disponibili, ovvero i comandi che io decido di far utilizzare agli utenti.
4 il set comandi
Il set dei comandi guildOps potevo definirlo nella sezione SETS, però mi viene più comodo definirlo nell'evento onStart, chiamato al caricamento del gioco. Se andate a controllare scoprirete che questo evento si trova nel file it_underworld.dxw:
guildOps = NewSet("0new=Nuova gilda,1edt_logo=Cambiare logo, 2edt_web=Cambiare pagina web, 3del=Cancellare la gilda, 4-=------(per tutti)------, join=Entrare in questa gilda:, leave=Abbandonare questa gilda:")
Un SET è un array associativo, e la funzione NewSet me lo fa definire con una sintassi molto semplice. Gli elementi sono separati da virgole e sono coppie chiave=valore.
La chiave è un codice mnemonico in cui ho messo un numero per avere un ordinamento ben preciso. Il valore è una stringa che è ciò che l'utente vedrà. La chiave è quella che io dovrò controllare per scoprire che cosa l'utente ha scelto.
bene, grazie al controllo DROPDOWN questo SET viene automaticamente trasformato in una tendina.
5 il set delle gilde
Tornando al pannello pguilds vedete che c'è una seconda tendina. Questo perchè per esempio, se l'utente vuole entrare in una gilda, deve anche dirmi quale.
Allora metto una seconda tendina, con i nomi delle gilde. Qui vedete che il SET usato si chiama guildnames.
guildnames è un set che contiene i nomi delle gilde. Ho pensato di usare come chiavi i nomi dei fondatori, visto che ogni persona può fondare al massimo una gilda. In questo modo mi è semplice, data una persona, vedere se possiede o no una gilda.
guildnames viene creato con questa istruzione:
guildnames = NewSet()
la quale viene sempre richiamata dall'evento onStart.
Per i più pignoli: Questa istruzione la trovate nel file it_commons.dxw nella sub common_onStart.
Questa contiene tutto il codice di inzializzazione comune alle varie aree di Underworld. Le gilde valgono infatti per tutte le aree, mentre le operazioni sulle gilde le consento solo nell'area del castello, ecco spiegato perchè queste inizializzazioni di set stanno in posti diversi. Ma questo comunque non ha molta importanza.
La istruzione di cui sopra crea un set vuoto.
L'applicazione delle gilde, che vedremo fra poco (ma già diciamo che si trova nell'evento doGuildOperation()), semplicemente va ad aggiungere, dietro richiesta dell'utente, nuovi nomi di gilda al set.
6 la permanenza
Per evitare che i dati delle gilde, tra cui i loro nomi contenuti in guildnames, svaniscano nel nulla ogni volta che il gioco o il server viene riavviato è necessario salvare queste informazioni in modo permanente.
Per fare ciò, nella procedura che rappresenta la vera e propria 'applicazione delle gilde', doGuildOperation() - la trovate dentro it_underworld.dxw, viene usata la seguente:
saveSetting "ctx_guildnames",guildnames
Questa saveSetting va a salvare l'insieme guildnames in un setting relativo al contesto del gioco, che poi verrà ricaricato in caso di riavvio. Notate infatti che nell'evento onStart locale abbiamo:
Call LoadContext() ' Reads game saved status from disk
Che è appunto una chiamata a una funzione chiamata una sola volta all'avvio, che contiene una serie di loadSetting. Esse andranno a ricostruire, tra l'altro, i dati delle gilde così com'erano prima del riavvio.
E' interessante osservare che la saveSetting con i dati delle gilde viene eseguita solo quando è necessario, quindi solo quando una operazione sulle gilde è stata eseguita, e non a intervalli regolari di tempo. Questo perchè, notoriamente, la saveSetting implica una operazione su disco che rallenta le prestazioni del gioco, cosa che vogliamo evitare.
7 L'applicazione delle gilde
Come dicevo, l'applicazione della gestione gilde sta in una unica procedura che è suddivisa per le operazioni possibili. Questa procedura è l'evento doGuildOperation() che troviamo in it_underworld.dxw.
Questo evento viene richiamato (vedere il panel pguilds) dal pulsante guildcmd. Questo perchè - almeno nella versione di DimensioneX utilizzata - non basta selezionare un comando dalla lista a tendina perchè i dati vengano inviati al server. Questo può essere fatto solo tramite un pulsante, ecco perchè l'ho dovuto inserire.
Finalmente vediamo il codice:
EVENT doGuildOperation 'Speak guildOps(input("guildOp")) If input("guildOp") = "0new" If input("txtBox") <> "" If guildnames($AGENT.name) <> null Speak guilford,$AGENT,"Avete già fondato una gilda, messere." Return End_If If $AGENT.Esperienza < 14 Speak guilford,$AGENT,"Fondare una gilda richiede maggiore Esperienza, signore. Ritornate più tardi." Return End_If Dim s = guildSubscribed($AGENT) If s <> null Speak guilford,$AGENT,"Dovete lasciare " + guildnames(s) + ", prima." Return End_If SetAdd guildnames,$AGENT.name,input("txtBox") saveSetting "ctx_guildnames",guildnames Else Speak guilford,$AGENT,"Come si chiamerà? Scrivetelo, messere." Return End_If End_If If input("guildOp") = "3del" '... End_If If input("guildOp") = "4-" Return End_If Call guildroom.onReceive saveSetting "ctx_guildnames",guildnames saveSetting "ctx_guildlogos",guildlogos saveSetting "ctx_guildsubscribers",guildsubscribers saveSetting "ctx_guildwebs",guildwebs saveSetting "ctx_guildkills",guildkills END_EVENT
Qui notiamo come funziona il controllo a tendina: il controllo che si chiama guildOp mi arriva in un insieme dal nome predefinito che si chiama input, che contiene tutti i dati inviati dal pannello comandi. Le chiavi dell'insieme sono gli ID dei controlli specificati, e i valori sono i valori immessi - nel caso della tendina, il valore scelto.
Sempre parlando della tendina, il valore che mi ritorna indietro non è la descrizione che l'utente ha visto, ma il codice che io ho usato come chiave. Andiamo a rivedere la sezione "4" qui sopra per un riferimento.
8 La gestione dei set
A questo punto la gestione delle gilde è abbastanza semplice. Ad ogni comando corrisponde un braccio dell'if e una sequenza di operazioni da eseguire, che non sono granché complesse.
Attenzione però: tutti i dati relativi alle gilde stanno in dei SET le cui chiavi sono i nomi dei proprietari delle gilde.
In questa versione di DimensioneX (6.0.2) non è possibile inserire un nuovo elemento in un set in questo modo:
mioset("nuovachiave") = "nuovo valore"
ma deve essere usata la istruzione SetAdd come si vede nel sorgente. Può darsi che questa cosa cambi nelle prossime versioni, ma se modificate il codice dovete ricordarvene perchè usando la sintassi qui sopra non ottenete errori ma nemmeno nessun risultato, e passerete ore a chiedervi perché non funziona.
In definitiva, i set usati dal sistema gilde sono questi (li trovate tutti in LoadContext() definita nel file it_commons.dxl)
- guildnames
- nomi delle gilde
- guildlogos
- loghi delle gilde (URL)
- guildsubscribers
- lista separata da ";" dei nomi degli iscritti per ogni gilda
- guildwebs
- siti web delle gilde (URL)
- guildkills
- conteggio delle uccisioni per ogni gilda
Quest'ultimo, guildkills, viene aggiornato ad ogni uccisione e viene salvato tramite saveSetting ogni 4 minuti sfruttando la onTick.
Da notare che questo aggiornamento fa affidamento sulla proprietà guild che l'utente ha all'ingresso, previo controllo (non è detto che dall'ultima volta che hai giocato la gilda esista ancora!) - vedere evento onNew()
9 mostrare i dati di gilda
I dati delle gilde sono mostrati tramite la funzioncina getGuildBox(), definita in it_commons.dxl. A questa funzione basta dire chi è il proprietario della gilda desiderata e se si vuole o no vedere anche la lista degli iscritti con dati delle uccisioni.
Function getGuildBox(owner,withmembers) Dim txt = "" Dim tmp Dim link1 = "" Dim link0 = "" If guildwebs(owner) <> null link1 = "<A HREF=javascript:top.popupWin('" + guildwebs(owner) + "',-1,-1);>" link0 = "</A>" End_If If guildlogos(owner) <> "" tmp = link1 + "<IMG SRC=" + guildlogos(owner) + " WIDTH=32 HEIGHT=32 ALIGN=MIDDLE BORDER=0>" + link0 End_If txt = txt + tmp + "" + link1 + guildnames(owner) + link0 + " fondata da " + owner + "" If withmembers txt = txt + "
Membri: " + guildsubscribers(owner) txt = txt + "
Combatt. vinti: " + guildkills(owner) End_If Return txt End_Function
Questa funzioncina viene richiamata opportunamente con un bel ciclo ogni volta che si entra nella stanza delle gilde:
EVENT guildroom.onReceive Dim txt="Questa è la stanza del capitano delle guardie. Lui conosce tutte le Gilde."
txt = txt + "
- "
Dim i
Dim owner
For i = 1 To SetLen(guildnames)
owner = SetKey(guildnames,i)
txt = txt + "
- " + getGuildBox(owner,true) Next txt = txt + "
"
guildroom.description = txt END_EVENT
cosicché quando entro ho sempre la situazione aggiornata.
Inoltre la funzione è chiamata anche dal comando Info che restituisce informazioni sul giocatore stesso (definita in it_battlesystem.dxl).
Sub doCheckup() Dim item Dim name Dim s,guild s = guildSubscribed($AGENT) If s=null guild = "Gilda: Nessuna." Else guild = getGuildBox(s,false) End_If Print guild ...
Questa prima di tutto tramite la funzione guildSubscribed() va a vedere a quale gilda sei iscritto poi chiama la getGuildBox per stamparne i dati.
La stessa getGuildBox viene usata nell'evento onLook per fornire questa informazione su di te quando uno ti guarda.
10 conclusioni
Il sistema delle gilde è una mini-applicazione costruita dentro Underworld che dimostra efficacemente come usare le seguenti caratteristiche di DimensioneX:
- tendine drop-down
- SET
- saveSetting/loadSetting
in più la cosa è perfettamente compatibile con la struttura multi-area del gioco, quindi può essere applicabile in tutti i contesti. E' fattibile a questo punto aggiungere altri elementi per rendere la gestione più interessante.
In caso di commentie domande, consiglio di postare sul nostro Forum.
Torna a DimensioneX WIKI Italy