DimensioneX/it/guildsystem

From DimensioneX
Revision as of 09:34, 7 December 2005 by Cris (talk | contribs) (→‎DA FINIRE)
Jump to navigation Jump to search

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.

1 la stanza delle gilde

Tutto inizia da una stanza (guildroom), che è quella dove l'applicazione è concentrata.

Per questo ho creato una 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.



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"
		If guildnames($AGENT.name) = null
			Speak guilford,$AGENT,"You don't own any Guild, sir."
			Return
		End_If
		If input("txtBox") <> "SI"
			Speak guilford,$AGENT,"Siete sicuro? Scrivete SI e ripetete l'ordine."
		Else
			Speak guilford,$AGENT,"Ok, non ci sarà più " + guildnames($AGENT.name)
			SetRemove guildnames,$AGENT.name
			SetRemove guildlogos,$AGENT.name
			SetRemove guildwebs,$AGENT.name
			SetRemove guildkills,$AGENT.name
			SetRemove guildsubscribers,$AGENT.name
		End_If
	End_If
	If input("guildOp") = "1edt_logo"
		If guildnames($AGENT.name) = null
			Speak guilford,$AGENT,"You don't own any Guild, sir."
			Return
		End_If
		If input("txtBox") = ""
			Speak guilford,$AGENT,"Scrivete l'URL del logo e ripetete l'ordine."
		Else
			Speak guilford,$AGENT,"Ok, nuovo logo per la vostra gilda!"
			SetAdd guildlogos,$AGENT.name,input("txtBox")
		End_If
	End_If
	If input("guildOp") = "2edt_web"
		If guildnames($AGENT.name) = null
			Speak guilford,$AGENT,"Non possedete alcuna gilda, signore."
			Return
		End_If
		If input("txtBox") = ""
			Speak guilford,$AGENT,"Scrivete l'URL della pagina e ripetete l'ordine."
		Else
			Speak guilford,$AGENT,"Ok, " + $AGENT.name + ". Fate che quella pagina spieghi con chiarezza la missione della gilda."
			SetAdd guildwebs,$AGENT.name,input("txtBox")
		End_If
	End_If
	If input("guildOp") = "join"
		If guildnames($AGENT.name) <> null
			Speak guilford,$AGENT,"Non potete entrare in una gilda se ne guidate una."
		Else
			Dim s = guildSubscribed($AGENT)
			If s <> null
				Speak guilford,$AGENT,"Dovete lasciare " + guildnames(s) + ", prima." 
				Return
			End_If
			Call GuildSubscribe(input("guildsel"),$AGENT)
			Speak guilford,$AGENT,"Ora appartenete alla " + guildnames(input("guildsel"))
		End_If
	End_If
	If input("guildOp") = "leave"
		If guildnames($AGENT.name) <> null
			Speak guilford,$AGENT,"You cannot leave a guild if you own one, sir."
		Else
			Speak guilford,$AGENT,GuildUnsubscribe(input("guildsel"),$AGENT)
			$AGENT.guild = null
		End_If
	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


Torna a Italy.gif DimensioneX WIKI Italy