IT/Scrivere una gamemode: Difference between revisions
No edit summary |
No edit summary |
||
Line 45: | Line 45: | ||
createObject ( 1337, posX, posY, posZ ) | createObject ( 1337, posX, posY, posZ ) | ||
-- scrive in chat il team per cui abbiamo creato una base | -- scrive in chat il team per cui abbiamo creato una base | ||
outputChatBox ( "Base creata per il team " .. team .. "!" ) | outputChatBox ( "Base creata per il team ".. team .."!" ) | ||
end | end | ||
</syntaxhighlight> | </syntaxhighlight> | ||
La funzione [[IT/getElementsByType|getElementsByType]] restituisce una tabella contenente tutti gli elementi di un dato tipo (il tipo corrisponde al nome del ''nodo'' [nell'esempio "flag"] nel file .map). Questo funziona sia per i tipi personalizzati sia per quelli di default di MTA (come "vehicle" o "player"). | |||
[[getElementData]] | [[IT/getElementData|getElementData]] è usato per ritrovare gli attributi impostati nell'XML. | ||
In | In questi semplice esempio, un oggetto è creato nella posizione della bandiera e un messaggio viene inviato in cheatbox. In realtà, bisognerà fare ovviamente del lavoro in più durante il caricamento della mappa, come in questo caso creare delle ''forme di collisione'' per determinare quando un player cattura la bandiera. | ||
==Map manager== | ==Map manager== |
Revision as of 08:28, 11 June 2008
Questa guida cerca di definire a grandi linee le regole per scrivere una gamemode ben fatta. Se hai appena iniziato a programmare per MTA, vorrai probabilmente controllare prima gli altri tutorial che troverai nella Pagina principale.
Introduzione
Una gamemode è una risorsa che, una volta avviata, domina l'intero gameplay, dicendo ai giocatori cosa fare, creando oggetti, definendo come i giocatori possono vincere o accumulare punti eccetera eccetera. Alcuni esempi sono le gamemodes Race o Deathmatch.
Cosa si intende per gamemode "ben fatta"?
Per essere semplici, una gamemode "ben fatta" è una gamemode che utilizza appieno le potenzialità delle mappe (.map) di MTA; vale a dire che la gamemode non contiene elementi specifici delle mappe(pickups, oggetti, spawns, veicoli eccetera)hardcodati al loro interno. Questi elementi vanno invece inseriti nelle mappe di MTA(.map) che verranno poi caricate dagli scripts. In questo modo possono essere caricate mappe diverse per la stessa gamemode, o è anche possibile creare delle mappe grazie al map editor di MTA. Un ovvio esempio di una gamemode "ben fatta" è MTA:Race: permette ai giocatori di caricare mappe personalizzate(i file .map). Non c'è bisogno di modificare la gamemode stessa per cambiare gli spawnpoints, i veicoli, eccetera.
Files mappa
Tecnicamente, i file mappa non sono altro che documenti XML con estensione .map; definiscono le basi di gioco di una o più gamemodes, anche se non possono cambiare le "regole del gioco", essendo queste definite dalla gamemode(.lua).
Ogni elemento nel gioco corrisponde ad un nodo nel file .map. C'è una sintassi predefinita per elementi quali oggetti, veicoli eccetera; comunque, per elementi "speciali" delle tue gamemodes, dovrai creare tu una sintassi apposita.
Esempio
Per il nostro esempio, prendiamo in esame la gamemode Capture the Flag. Una mappa per questa gamemode deve sostanzialmente definire gli spawnpoints dei giocatori e la posizione delle bandiere, ed eventualmente la presenza di altri oggetti come i veicoli o i pickups. Un file .map molto semplificato apparirebbe così:
<map> <spawnpoint id="spawnpoint1" posX="1959.5487060547" posY="-1714.4613037109" posZ="877.25219726563" rot="63.350006103516" model="0"/> <pickup id="Armor 1" posX="1911.083984375" posY="-1658.8798828125" posZ="885.40216064453" type="armor" health="50" respawn="60000"/> <flag posX="1959.5487060547" posY="-1714.4613037109" posZ="877.25219726563" team="blue" /> ... </map>
Qui possiamo vedere due elementi di MTA: uno spawnpoint ed un pickup. Ancora più importante, questa mappa ha un nodo chiamato flag che definisce la posizione ed il colore della bandiera. Gli spawnpoints ed i pickups possono essere gestiti da risorse esterne, ma gli elementi personalizzati devono essere processati dalle gamemodes.
Insomma, vogliamo che i giocatori possano creare le proprie mappe senza aver bisogno dello script LUA.
Esempio: come ottenere le informazioni dal file .map
Come detto prima, la tua mode ha bisogno di ritrovare gli elementi personalizzati definiti in un file .map e processarli. Questo è abbastanza facile, come è dimostrato qui sotto.
-- crea una tabella con tutti gli elementi di tipo flag local flagElements = getElementsByType ( "flag" ) -- crea un ciclo per ogni elemento che abbiamo trovato for key, value in pairs(flagElements) do -- ottiene le info di quell'elemento local posX = getElementData ( value, "posX" ) local posY = getElementData ( value, "posY" ) local posZ = getElementData ( value, "posZ" ) local team = getElementData ( value, "team" ) -- crea un oggetto a seconda della posizione della bandiera (flag) createObject ( 1337, posX, posY, posZ ) -- scrive in chat il team per cui abbiamo creato una base outputChatBox ( "Base creata per il team ".. team .."!" ) end
La funzione getElementsByType restituisce una tabella contenente tutti gli elementi di un dato tipo (il tipo corrisponde al nome del nodo [nell'esempio "flag"] nel file .map). Questo funziona sia per i tipi personalizzati sia per quelli di default di MTA (come "vehicle" o "player"). getElementData è usato per ritrovare gli attributi impostati nell'XML. In questi semplice esempio, un oggetto è creato nella posizione della bandiera e un messaggio viene inviato in cheatbox. In realtà, bisognerà fare ovviamente del lavoro in più durante il caricamento della mappa, come in questo caso creare delle forme di collisione per determinare quando un player cattura la bandiera.
Map manager
Having read the section above it should be clear that a gamemode should always consist of two parts:
- The gamemode resource that always stays the same
- Many different maps resources that give the gamemode map-specific information
Now instead of writing a map-loader for every single gamemode, the Map manager provides functions to load gamemodes and maps. Simply put, when you enter the correct command (for example 'gamemode ctf ctf-italy') it will start both resources 'ctf' and 'ctf-italy' while triggering an event (onGamemodeMapStart) to tell the 'ctf' resource that a map was loaded. The 'ctf' resource can then access the information 'ctf-italy' contains and start spawning players etc.
How to use the mapmanager
To use the mapmanager service, your gamemode resource has to be tagged as such first. More specifically you'll be setting the "type" attribute of its <info> tag to "gamemode" inside meta.xml. Also, you can set the "name" attribute to a friendly name (like "Capture the flag") that will be shown on ASE instead of the resource name.
<!-- meta.xml in "cowcatapult" gamemode --> <meta> <info type="gamemode" name="Cow catapulting 2.0"/> </meta>
If your gamemode is going to load custom maps, you should add handlers for
- onGamemodeMapStart
- onGamemodeMapStop (if any unloading is necessary)
These are fired when a map for your gamemode is started or stopped, and pass the map resource as a parameter. Within the handler function for these events you can extract all info you need from the resource's map files and configuration files.
Example
function startCtfMap( startedMap ) -- startedMap contains a reference to the resource of the map local mapRoot = getResourceRootElement( startedMap ) -- get the root node of the started map local flagElements = getElementsByType ( "flag" , mapRoot ) -- get all flags in the map and store them in a table -- go on loading information like in the example above -- spawn players etc. end addEventHandler("onGamemodeMapStart", getRootElement(), startCtfMap)
Making maps compatible
Maps are separate resources. This is done so no editing of the gamemode resource is ever necessary in order to create a custom map, and also allows you to pack map-specific scripts/config files with them.
To make a map compatible with your gamemode, open its resource's meta.xml and tag it as well: the "type" attribute must be set to "map", and the "gamemodes" attribute must be a comma-separated list (no spaces) of gamemode resource names that the map works with.
<!--map's meta.xml--> <meta> <info type="map" gamemodes="cowcatapult,assault,tdm"/> </meta>
Once you have everything set up, admins will use these two commands to start/stop gamemodes: /gamemode gamemodeName [mapName] (optional parameter allows picking an initial map, defaults to none) /changemap mapName [gamemodeName] (optional parameter specifies the gamemode to start the map with, defaults to the current one)
Map manager exports a few more access functions which you don't have to use, but may be useful.
What else should you do
There are several other resources that gamemodes should use/be compliant with.
Helpmanager
The helpmanager is ought to be the standard interface for players when they need help. If you use the helpmanager to display your gamemode's help, every player that used helpmanager before (e.g. in other gamemodes) will immediately know how to get there. It also displays help for different resources running resources in one window, if necessary.
There are basicially two ways to use the helpmanager:
- Provide a simple text that explains how to use your gamemode
- Request a GUI element from the helpmanager that will be displayed in its own tab in the helpmanager window and lets you add any GUI elements to it. This is the recommended way for gamemodes that need to display more complex information that needs its own GUI.
Read the helpmanager page for details on how to do it.
Scoreboard
Scoreboard displays players and teams currently ingame. You add custom columns to it to provide map specific information. For example the column 'points' in the 'ctf' gamemode could represent the player's points gained through kills or captures. As usual, see the scoreboard help page for more information.
Map cycler
The map cycler controls what gamemodes and maps are played on a server. You can specifiy for example how many times in a row a map will be played until it switches to the next. To achieve this, you need to tell the map cycler when your gamemode finished (e.g. when a round ends).