GUÍA BÁSICA DE SA-MP Y PAWN
![[Image: YPOK9Or.png]](https://i.imgur.com/YPOK9Or.png)
INTRO:
Esta guía esta basada en diversas guías y en mi propia experiencia. Guía creada especialmente para nuevos scripters y usuarios a los que les gustaría aprender sobre el lenguaje Pawn en SA-MP; explicando solo lo básico y cómo empezar.
* Nota: es importante que el usuario tenga el mayor conocimiento posible del idioma inglés, dado que el lenguaje de programación Pawn está basado en este idioma.
Esta guía está basada en una publicación que hice para el foro SA-MP a inicios del año 2015, si usted lee esto en otro tiempo es probable que algunos elementos hayan cambiado y/o actualizado.
Basado en:
Nicholas tutorial
Kwarde tutorial
Wiki SA-MP
Conocimiento propio.
ÍNDICE:
INICIANDO
Explicando cada archivo y carpeta (solo los básicos)
scriptfiles
plugins
pawno
npcmodes
include
gamemodes
filterscripts
announce.exe
samp-npc.exe
samp-server.exe
server.cfg
CONFIGURACIÓN
PAWN SCRIPTING
Publics
public OnGameModeInit()
public OnGameModeExit()
public OnPlayerRequestClass(playerid, classid)
public OnPlayerConnect(playerid)
public OnPlayerSpawn(playerid)
public OnPlayerDeath(playerid)
public OnPlayerDisconnect(playerid, reason)
public OnPlayerText(playerid)
public OnPlayerUpdate(playerid)
Funciones
SetPlayerPos(playerid, X, Y, Z);
TextDrawCreate(X, Y, text[])
Dialogs (menús & otros)
ShowPlayerDialog(playerid, dialogid, style, caption[], info[], button1[], button2[]);
Dialog de cuadro (envía un mensaje al jugador)
Dialog de texto (permite a los jugadores colocar texto en el dialog)
Dialog de lista (menú, muestra a los jugadores una lista de opciones)
Dialog de contraseña (permite a los jugadores colocar texto en el dialog, sin revelar el texto)
CREANDO Y REMOVIENDO OBJETOS
Map editor (1 & 2)
Empezando
Creando objectos
Removiendo objectos
MTA editor
Empezando
Delux GTA Map Converter v2
Creando Objectos
Instalar Streamer
EMPIECE A PRACTICAR
INICIANDO:
Primero debe descargar el archivo SA-MP Windows Server desde SA-MP.com
Después de descargarlo y descomprimirlo, veremos estos archivos...
Archivos y carpetas básicos:
scriptfiles, plugins, pawno, npcmodes, include, gamemodes, filterscripts, announce.exe, samp-npc.exe, samp-server.exe & server.cfg
Otros archivos:
Textos que incluyen términos de servicio y una guía de configuración (samp-license.txt & server-readme.txt respectivamente).
Explicando cada archivo y carpeta (solo los básicos):
scriptfiles: esta carpeta contiene información llamada dentro del script o logs producidos por el script. Normalmente es usada como base de datos.
plugins: esta carpeta contiene códigos adicionales que dan más opciones en la programación, usualmente programados en otros lenguajes de programación. Esta guía no dará información detallada sobre plugins debido a que es más avanzado.
pawno: contiene el programa básico para empezar a programar en SA-MP; también tiene la carpeta include que contiene los includes básicos de SA-MP para empezar nuestro script (funciones básicas de SA-MP). También podemos crear nuestros propios includes y añadirlos al script.
npcmodes: contiene información sobre NPCs (script & rec); esta guía no dará información detallada sobre NPCs debido a que es más avanzado.
include: contiene códigos que pueden ser incluidos en el script.
gamemodes: contiene los modos de juego básicos y si creamos uno debemos colocar aquí también.
filterscripts: contiene códigos adicionales, separados del gamemode, no están incluidos dentro de él y pueden ser llamados al usar comandos rcon.
announce.exe: este archivo nos permitirá mostrar nuestro servidor en la lista de Internet.
samp-npc.exe: nos permitirá usar NPCs.
samp-server.exe: con este archivo iniciamos el servidor.
server.cfg: configuración del servidor.
CONFIGURACIÓN:
Primero debemos abrir el archivo "server.cfg" y editar la configuración del servidor.
Al abrirlo encontraremos:
Code:
echo Executing Server Config...
lanmode 0
rcon_password changeme
maxplayers 50
port 7777
hostname SA-MP 0.3 Server
gamemode0 grandlarc 1
filterscripts gl_actions gl_realtime gl_property gl_mapicon ls_mall ls_elevator attachments skinchanger vspawner
announce 0
query 1
chatlogging 0
weburl www.sa-mp.com
onfoot_rate 40
incar_rate 40
weapon_rate 40
stream_distance 300.0
stream_rate 1000
maxnpc 0
logtimeformat [%H:%M:%S]
Puede editar la configuración basado en esto:
Code:
echo Executing Server Config...
lanmode 0 (lan mode activada "1" o desactivada "0")
rcon_password changeme (la contraseña que usará al colocar "/Rcon login"; debe editar esto)
maxplayers 50 (cantidad permitida de jugadores, slots)
port 7777 (el puerto que usará; por ejemplo: 127.0.0.1:7777)
hostname SA-MP 0.3 Server (el nombre de su servidor)
gamemode0 grandlarc 1 (el nombre del gamemode que usará, puede añadir un gamemode si usted crea o descarga uno)
filterscripts gl_actions gl_realtime gl_property gl_mapicon ls_mall ls_elevator attachments skinchanger vspawner (los "filterscripts" que usará)
announce 0 (servidor visible en la lista de Internet; "1" para activar y "0" para desactivar)
query 1 (información del servidor visible "1"; "0" no enviará información del servidor a los jugadores externos)
chatlogging 0 (guardar conversaciones en el archivo server_log.txt; para guardarlas use "1", para no guardarlas use "0")
weburl www.sa-mp.com (página web del servidor)
onfoot_rate 40 (no se explicará en esta guía, es avanzado)
incar_rate 40 (no se explicará en esta guía, es avanzado)
weapon_rate 40 (no se explicará en esta guía, es avanzado)
stream_distance 300.0 (no se explicará en esta guía, es avanzado)
stream_rate 1000 (no se explicará en esta guía, es avanzado)
maxnpc 0 (máximo número de NPCs que pueden entrar al servidor)
logtimeformat [%H:%M:%S]
También puede leer más sobre el archivo server.cfg y su configuración.
Ejemplo de configuración (la guía está basada en esta configuración):
Code:
echo Executing Server Config...
lanmode 0
rcon_password Pawn
maxplayers 100
port 7777
hostname SA-MP Server [0.3z]
gamemode0 Basic 1
filterscripts gl_actions gl_realtime gl_property gl_mapicon ls_mall ls_elevator attachments skinchanger vspawner
announce 1
query 1
chatlogging 1
weburl www.sa-mp.com
onfoot_rate 40
incar_rate 40
weapon_rate 40
stream_distance 300.0
stream_rate 1000
maxnpc 0
logtimeformat [%H:%M:%S]
PAWN SCRIPTING:
Después de editar la configuración empezaremos a programar el modo de juego.
En este caso usaremos un gamemode básico que pueden descargar aquí.
Deben colocarlo dentro de la carpeta gamemodes.
Después de hacer esto deben abrir la carpeta pawno, dentro de su servidor, y abrir el archivo "pawno.exe".
Presione "File/Open" (o simplemente CTRL + O) y abra su gamemode, colocado dentro de la carpeta gamemodes.
Dentro tenemos esto:
Code:
#include <a_samp>
Este es el include básico de SA-MP, debe estar incluido en cada script que usted cree en el ámbito de SA-MP.
Este es el mensaje que será mostrado en consola al abrir el archivo samp-server.exe:
Code:
main()
{
print("Script desarrollado por Ygzeb.");
}
El texto azul es el mensaje que será mostrado.
Puede editar el texto que será mostrado en consola al encender su servidor, simplemente cambiando el texto azul; por ejemplo:
Code:
main()
{
print("¡Mi primer script!");
}
* Nota: Todos los códigos deben tener llaves abiertas y cerradas al empezar y terminar la función.
Ejemplo:
Llaves abiertas = Rojo
Llaves cerradas = Verde
main()
{
print("¡Mi primer script!");
}
* Nota: ¡Es muy importante que después de realizar un cambio en el script presione F5! Esto actualizará el archivo AMX y los cambios realizados quedarán guardados ("si no hay error alguno", aunque en casos especiales hay errores de programación que no figurarán y afectarán al servidor internamente). Si todo anda bien verá algo parecido a esto:
![[Image: Gobeslv.jpg]](https://i.imgur.com/Gobeslv.jpg)
De lo contrario significa que el script tiene errores, hizo algo mal y debe corregirlo.
Publics:
Los publics son funciones básicas que son llamadas mientras su servidor está encendido, en momentos precisos.
SA-MP cuenta con publics básicos que son llamados en la mayoría de servidores. Normalmente el nombre de un public describe cuándo se ejecuta el public.
Algunos publics son llamados en momentos especiales, por ejemplo al spawnear; puede añadir una función a ese momento en específico.
Por ejemplo, si queremos cambiar la vida de los jugadores a 50 al spawnear, usaríamos algo como:
Code:
public OnPlayerSpawn(playerid)
{
SetPlayerHealth(playerid, 50);
return 1;
}
* Nota: no podemos usar publics idénticos en un mismo script; por ejemplo dos publics OnPlayerSpawn. Si queremos añadir una función adicional debemos agregarla en el mismo public o en un filterscript. Basándonos en el ejemplo anterior, añadiremos un mensaje al spawnear:
Code:
public OnPlayerSpawn(playerid)
{
SetPlayerHealth(playerid, 50);
SendClientMessage(playerid, -1, "¡Spawneaste!"); // Función añadida.
return 1;
}
Algunos publics que son usados comúnmente:
public OnGameModeInit() - Llamado al iniciar el gamemode.
Información adicional: https://sampwiki.blast.hk/wiki/OnGameModeInit
Estructura básica:
Code:
public OnGameModeInit()
{
// Aquí va el código.
return 1;
}
Ejemplo:
Code:
public OnGameModeInit()
{
UsePlayerPedAnims(); // Permite a los jugadores correr como CJ.
SetGameModeText("Blank"); // Nombre del modo, será mostrado en la lista de servidores.
AddPlayerClass(115, 1958.3783, 1343.1572, 15.3746, 269.1425, 0, 0, 0, 0, 0, 0);
AddPlayerClass(122, 1958.3783, 1343.1572, 15.3746, 269.1425, 0, 0, 0, 0, 0, 0);
AddPlayerClass(166, 1958.3783, 1343.1572, 15.3746, 269.1425, 0, 0, 0, 0, 0, 0);
AddPlayerClass(270, 1958.3783, 1343.1572, 15.3746, 269.1425, 0, 0, 0, 0, 0, 0);
return 1;
}
AddPlayerClass es una función que permite añadir personajes en la selección de personaje; por ejemplo si queremos añadir el personaje de Sweet, debemos añadir esto en nuestro gamemode:
Code:
AddPlayerClass(270, 1958.3783, 1343.1572, 15.3746, 269.1425, 0, 0, 0, 0, 0, 0);
El número "270" el ID del personaje de Sweet.
public OnGameModeExit() - Llamado al finalizar el gamemode; no es obligatorio en el script (opcional en la mayoría de casos).
Información adicional: https://sampwiki.blast.hk/wiki/OnGameModeExit
Estructura básica:
Code:
public OnGameModeExit()
{
// Aquí va el código.
return 1;
}
Ejemplo:
Code:
public OnGameModeExit()
{
print("Mode ended."); // Mensaje a la consola.
return 1;
}
public OnPlayerRequestClass(playerid, classid) - Llamado en la selección de personaje.
Información adicional: https://sampwiki.blast.hk/wiki/OnPlayerRequestClass
Estructura básica:
Code:
public OnPlayerRequestClass(playerid, classid)
{
// Aquí va el código.
return 1;
}
Ejemplo:
Code:
public OnPlayerRequestClass(playerid, classid)
{
SetPlayerPos(playerid, 2294.2810, 558.2053, 7.7813); // Posición del personaje.
SetPlayerCameraPos(playerid, 2294.3071, 560.6948, 8.7324); // Posición de la cámara.
SetPlayerCameraLookAt(playerid, 2294.2810, 558.2053, 7.7813); // Lugar a donde la cámara señala.
SetPlayerFacingAngle(playerid, 0);
return 1;
}
SetPlayerFacingAngle cambia el ángulo hacia donde el personaje observa; su estructura es:
Code:
playerid = ID del jugador
0 = ángulo (en este caso norte).
norte (0)
|
(90) oeste- -este (270)
|
sur (180)
Mayor información sobre SetPlayerFacingAngle.
public OnPlayerConnect(playerid) - Llamado cuando un jugador se conecta.
Información adicional: https://sampwiki.blast.hk/wiki/OnPlayerConnect
Estructura básica:
Code:
public OnPlayerConnect(playerid)
{
// Aquí va el código.
return 1;
}
Ejemplo:
Code:
public OnPlayerConnect(playerid)
{
PlayAudioStreamForPlayer(playerid, "http://s1.radio.ge/Music/AcDc/1980_Back_In_Black/06_Back_In_Black.mp3"); // Iniciará la canción Back in Black, AC/DC
return 1;
}
PlayAudioStreamForPlayer es una función que reproduce un sonido externo al jugador. Su estructura es:
Code:
playerid = ID del jugador
"http://s1.radio.ge/Music/AcDc/1980_Back_In_Black/06_Back_In_Black.mp3" = link del audio
* Nota: el audio debe estar en un formato en específico para funcionar, por ejemplo este link.
Puede encontrar música en muchas páginas. Por ejemplo en esta web.
public OnPlayerSpawn(playerid) - Llamado después de seleccionar personaje, al spawnear. Estas funciones afectarán al jugador al spawnear.
Información adicional: https://sampwiki.blast.hk/wiki/OnPlayerSpawn
Estructura básica:
Code:
public OnPlayerSpawn(playerid)
{
// Aquí va el código.
return 1;
}
Ejemplo:
Code:
public OnPlayerSpawn(playerid)
{
SendClientMessage(playerid, -1, "¡Spawn!"); // Envía un mensaje al jugador.
return 1;
}
SendClientMessage es una función que envía un mensaje al jugador; su estructura es:
Code:
playerid = ID del jugador
-1 = Color, -1 es blanco
"¡Spawn!" = mensaje
Mayor información sobre SendClientMessage.
public OnPlayerDeath(playerid) - Llamado al morir. Esta función afectará al jugador al morir.
Información adicional: https://sampwiki.blast.hk/wiki/OnPlayerDeath
Estructura básica:
Code:
public OnPlayerDeath(playerid)
{
// Aquí va el código.
return 1;
}
Ejemplo:
Code:
public OnPlayerDeath(playerid)
{
GameTextForPlayer(playerid, "Asesinado", 5000, 2); // Envía un mensaje en pantalla al jugador.
return 1;
}
GameTextForPlayer envía un mensaje en pantalla al jugador; su estructura es:
Code:
playerid = ID del jugador
"Asesinado" = mensaje
5000 = tiempo en mili-segundos; en este caso 5 segundos.
2 = tipo de mensaje
Mayor información sobre GameTextForPlayer.
public OnPlayerDisconnect(playerid, reason) - Llamado al desconectarse el jugador.
Información adicional: https://sampwiki.blast.hk/wiki/OnPlayerDisconnect
Estructura básica:
Code:
public OnPlayerDisconnect(playerid, reason)
{
// Aquí va el código.
return 1;
}
Ejemplo:
Code:
public OnPlayerDisconnect(playerid, reason)
{
// Enviando un mensaje a todos que el jugador se desconectó.
new String[64], // Variable asignada al mensaje. 64 es el número de caracteres que usará el mensaje (tal vez más que el mensaje).
Nombre[MAX_PLAYER_NAME]; // Variable asignada al nombre del jugador; normalmente definida como MAX_PLAYER_NAME.
GetPlayerName(playerid, Nombre, MAX_PLAYER_NAME); // Obteniendo el nombre del jugador (Nombre) y el número de caracteres que usa, normalmente definido como MAX_PLAYER_NAME (definido por SA-MP por defecto).
format(String, sizeof String, "%s salió.", Nombre); // Aplicando un formato al mensaje.
SendClientMessageToAll(-1, String); // Enviando un mensaje a todos los jugadores; String es el formato que tendrá el mensaje.
return 1;
}
public OnPlayerText(playerid) - Llamado cuando el jugador envía un mensaje (chat).
Información adicional: https://sampwiki.blast.hk/wiki/OnPlayerText
Estructura básica:
Code:
public OnPlayerText(playerid, text[])
{
// Aquí va el código.
return 1;
}
Ejemplo:
Code:
public OnPlayerText(playerid, text[])
{
new Nombre[MAX_PLAYER_NAME], String[175];
GetPlayerName(playerid, Nombre, sizeof(Nombre));
format(String, sizeof(String), "%s [%d]: {FFFFFF}%s", Nombre, playerid, text); // Aplicando formato.
SendClientMessageToAll(GetPlayerColor(playerid), String); // Enviando el mensaje con GetPlayerColor, que es el color actual del jugador.
return 0; // Ignorando el texto por defecto, terminando la función.
}
Esta función es el formato aplicado a SendClientMessageToAll. Cuando sea enviado seguirá el formato:
Code:
format(String, sizeof(String), "%s [%d]: {FFFFFF}%s", Name, playerid, text);
Code:
%s y %d son valores asignados dependiendo del jugador.
%s es un valor textual (en este caso el nombre del jugador y el texto).
%d es un valor numérico (ID del jugador).
Code:
format(String, sizeof(String), "%s [%d]: {FFFFFF}%s", Name, playerid, text);
Nombre, ID & texto son los valores asignados a %s, %d y %s.
public OnPlayerUpdate(playerid) - Llamado cada vez que el usuario envía su estado al servidor.
Información adicional: https://sampwiki.blast.hk/wiki/OnPlayerUpdate
Estructura básica:
Code:
public OnPlayerUpdate(playerid)
{
// Aquí va el código.
return 1; // Si retorna 0, el cliente no será actualizado para los demás jugadores (como si estuviese pausado).
}
Ejemplo:
Code:
public OnPlayerUpdate(playerid)
{
if(GetPlayerWeapon(playerid) == 38) return Kick(playerid); // Expulsará al jugador si usa una minigun.
return 1;
}
"if" para detectar si una situación en especial está ocurriendo; en caso de ser así el servidor ejecutará una función determinada.
Traduciendo esto a nuestro idioma, sería algo como:
¡Si está usando minigun, expúlsalo!
* Nota: usar "if" en OnPlayerUpdate puede causar lag, esto es solo un ejemplo.
Usar la función return con "Kick(playerid);" significa que la función termina ahí. Si tiene otro código bajo esta función, no será ejecutado si esta función es llamada.
Por ejemplo:
Code:
public OnPlayerUpdate(playerid)
{
if(GetPlayerWeapon(playerid) == 38) return Kick(playerid);
SendClientMessage(playerid, -1, "¡Actualizado!"); // Esta función no será ejecutada si el jugador está usando minigun.
return 1;
}
Funciones:
Básicamente, la mayoría de funciones (funciones nativas/básicas de SA-MP) describen lo que hacen en su nombre; puede encontrar muchas de ellas aquí.
Algunas funciones básicas que son usadas mayormente:
SetPlayerPos(playerid, X, Y, Z); - Cambia la posición del jugador (X, Y & Z son los puntos donde moverá al jugador).
Información adicional: https://sampwiki.blast.hk/wiki/SetPlayerPos
Ejemplo:
Code:
SetPlayerPos(playerid, 0.0, 0.0, 3.0); // Cambia la posición del jugador al campo.
Puede guardar su posición actual usando /Save dentro del juego (comando por defecto de SA-MP). Después de esto debe ir a "\GTA San Andreas User Files\SAMP" y abrir el archivo "savedpositions.txt". Dentro encontrará algo parecido a:
Code:
AddPlayerClass(270, 700, 700, 5, 0, 0, 0, 0, 0, 0, 0);
Luego simplemente copie los valores en rojo:
Code:
AddPlayerClass(270, 700, 700, 5, 0, 0, 0, 0, 0, 0, 0);
* Nota: obviamente los valores no son rojos, solo es un ejemplo.
Luego pegue los valores dentro de la función SetPlayerPos; así:
Code:
SetPlayerPos(playerid, 700, 700, 5);
También puede usar este sistema que lo programará por usted.
TextDrawCreate(X, Y, text[]) - Crea un textdraw (X & Y son las coordenadas de la pantalla y "text" es el texto que mostrará).
Información adicional: https://sampwiki.blast.hk/wiki/TextDrawCreate
Ejemplo de textdraw:
Code:
new Text:Textdraw0;
public OnGameModeInit()
{
Textdraw0 = TextDrawCreate(240.0, 580.0, "SA-MP 0.3z"); // Esto crea un textdraw sin modificar.
return 1;
}
Una forma sencilla de usar esta función es con un Editor de Textdraw.
Para mostrar un textdraw al jugador debe usar la función TextDrawShowForPlayer.
Ejemplo de uso (basado en el ejemplo anterior):
Code:
public OnPlayerConnect(playerid)
{
TextDrawShowForPlayer(playerid, Textdraw0);
}
Para esconder el textdraw del jugador debe usar la función TextDrawHideForPlayer.
Ejemplo:
Code:
public OnPlayerDisconnect(playerid, reason)
{
TextDrawHideForPlayer(playerid, Textdraw0);
return 1;
}
Y para destruir el textdraw debe usar TextDrawDestroy.
Ejemplo:
Code:
public OnGameModeInit()
{
TextDrawDestroy(Textdraw0);
return 1;
}
Dialogs (menús & otros):
ShowPlayerDialog(playerid, dialogid, style, caption[], info[], button1[], button2[]); - Muestra al jugador un dialog.
Información adicional: https://sampwiki.blast.hk/wiki/ShowPlayerDialog
* Nota: Todo dialog necesita un ID único (dialogid); a no ser que no use dicho ID en el public OnDialogResponse (los dialogs de filterscripts e includes debe usar también un ID único).
Hay cuatro tipos de dialogs:
Dialog de cuadro (envía un mensaje al jugador):
![[Image: Dialog_style_msgbox.png]](http://wiki.sa-mp.com/wroot/images2/a/a1/Dialog_style_msgbox.png)
Ejemplo (con el botón de cancelar):
Code:
if(!strcmp(cmdtext, "/Ayuda", true))
{
new Menu[187]; // Número de caracteres que usará dentro del dialog (todos los caracteres).
Menu[0]='\0'; // Variable del dialog, definida antes.
strcat(Menu, "Este es el texto que será mostrado dentro del dialog. Puede añadir otra\n", 73); // 73 es el número de caracteres en esta línea.
strcat(Menu, "línea usando el símbolo de la línea anterior (n). No necesita\n", 137); // 137 es el número de caracteres en otras líneas sumado a esta línea.
strcat(Menu, "colocar el símbolo en la última línea del dialog.", 187); // Estos son todos los caracteres usados en el dialog.
ShowPlayerDialog(playerid, 1, DIALOG_STYLE_MSGBOX, "Ayuda de dialog", Menu, "Aceptar", "Cancelar");
return 1;
}
Cada línea tiene caracteres; la primera línea tiene 73 caracteres así que ponemos 73 al final.
En la segunda y todas las líneas posteriores debemos contar los caracteres de dicha línea sumado con los caracteres de las otras líneas. En el caso de la segunda línea es 137 por lo que pondremos eso al final.
Ejemplo (sin el botón de cancelar):
Code:
if(!strcmp(cmdtext, "/Ayuda", true))
{
new Menu[187]; // Número de caracteres que usará dentro del dialog (todos los caracteres).
Menu[0]='\0'; // Variable del dialog, definida antes.
strcat(Menu, "Este es el texto que será mostrado dentro del dialog. Puede añadir otra\n", 73); // strcat junta el string de Menu, sumado con el string del texto.
strcat(Menu, "línea usando el símbolo de la línea anterior (n). No necesita\n", 137); // Todas las líneas usan strcat.
strcat(Menu, "colocar el símbolo en la última línea del dialog.", 187);
ShowPlayerDialog(playerid, 1, DIALOG_STYLE_MSGBOX, "Ayuda de dialog", Menu, "Aceptar", ""); // En lugar de cancelar, dejamos el segundo botón solo con "".
return 1;
}
La función strcat junta el string de Menu, sumado con el string del texto.
* Nota: Puede usar páginas para contar caracteres.
Cuando cuenta los caracteres solo debe tomar en cuenta los que están entre ""; por ejemplo:
Code:
if(!strcmp(cmdtext, "/Ayuda", true))
{
new Menu[187];
Menu[0]='\0';
strcat(Menu, "Este es el texto que será mostrado dentro del dialog. Puede añadir otra\n", 73);
strcat(Menu, "línea usando el símbolo de la línea anterior (n). No necesita\n", 137);
strcat(Menu, "colocar el símbolo en la última línea del dialog.", 187);
ShowPlayerDialog(playerid, 1, DIALOG_STYLE_MSGBOX, "Ayuda de dialog", Menu, "Aceptar", "");
return 1;
}
La \n también cuenta.
También podemos añadir una función al presionar "Aceptar" o "Cancelar" dentro del public OnDialogResponse.
Por ejemplo:
Code:
if(!strcmp(cmdtext, "/Ayuda", true))
{
new Menu[187];
Menu[0]='\0';
strcat(Menu, "Este es el texto que será mostrado dentro del dialog. Puede añadir otra\n", 73);
strcat(Menu, "línea usando el símbolo de la línea anterior (n). No necesita\n", 137);
strcat(Menu, "colocar el símbolo en la última línea del dialog.", 187);
ShowPlayerDialog(playerid, 1, DIALOG_STYLE_MSGBOX, "Ayuda de dialog", Menu, "Aceptar", "");
return 1;
}
Añadimos un mensaje (la función) dentro del public OnDialogResponse:
Code:
public OnDialogResponse(playerid, dialogid, response, listitem, inputtext[])
{
if(dialogid == 1) // El número 1 es el número de nuestro dialog anterior.
{
if(response) // Si presionaron 'Aceptar'.
{
SendClientMessage(playerid, -1, "¡Gracias por leer!");
}
return 1; // Cerrando dialog response del dialog # 1!
}
return 1; // Cerrando public.
}
* Nota: Al usar OnDialogResponse cada dialog debe tener un número. En este caso usamos el número 1:
Code:
ShowPlayerDialog(playerid, 1, DIALOG_STYLE_MSGBOX, "Ayuda de dialog", Menu, "Aceptar", "");
return 1;
}
Dialog de texto (permite a los jugadores colocar texto en el dialog)
![[Image: Dialog_style_input.png]](http://wiki.sa-mp.com/wroot/images2/d/d5/Dialog_style_input.png)
Ejemplo:
Code:
ShowPlayerDialog(playerid, 2, DIALOG_STYLE_INPUT, "Texto", "¡Escriba un texto a todos los jugadores", "Aceptar", "Cancelar");
Después de crear nuestro código debemos crear una función al código; para ello usaremos public OnDialogResponse:
Ejemplo:
Code:
public OnDialogResponse(playerid, dialogid, response, listitem, inputtext[])
{
if(dialogid == 2)
{
if(!response) // Si presionaron 'Cancelar'.
{
SendClientMessage(playerid, -1, "¡Mensaje cancelado!");
}
else // Si presionaron 'Aceptar'.
{
new String[200], Nombre[MAX_PLAYER_NAME]; // Definiendo variables.
GetPlayerName(playerid, Nombre, MAX_PLAYER_NAME); // Obteniendo el nombre del jugador (asignando un valor a la variable).
format(String, sizeof(String), "[<!>] Anuncio de %s: %s", Nombre, inputtext); // Usando un formato para el mensaje.
SendClientMessageToAll(-1, String);
}
return 1; // Cerrando respuesta del dialog # 2!
}
return 1; // Cerrando public.
}
Dialog de lista (menú, muestra a los jugadores una lista de opciones):
![[Image: Dialog_style_list.png]](http://wiki.sa-mp.com/wroot/images2/b/b1/Dialog_style_list.png)
Ejemplo (creando un menú de armas):
Code:
if(!strcmp(cmdtext, "/Weapon", true))
{
ShowPlayerDialog(playerid, 3, DIALOG_STYLE_LIST, "Armas", "Desert Eagle\n AK-47\n Combat Shotgun", "Seleccionar", "Cerrar");
return 1;
}
Code:
"Armas" = Título de la lista
"Desert Eagle\n AK-47\n Combat Shotgun" = Lista.
"Seleccionar" = Seleccionar un ítem (arma).
"Cerrar" = Cerrar lista.
El símbolo \n es usado para separar los elementos de la lista (en filas).
Para dar el arma usamos public OnDialogResponse:
Code:
public OnDialogResponse(playerid, dialogid, response, listitem, inputtext[])
{
if(dialogid == 3)
{
if(response) // Si presionaron 'Seleccionar' o dieron doble clic a un arma.
{
switch(listitem) // Creamos swith a todos los elementos de la lista; cada caso representa un elemento.
{
case 0:
{
GivePlayerWeapon(playerid, 24, 14); // Dar un arma Desert Eagle con 14 balas.
}
case 1:
{
GivePlayerWeapon(playerid, 30, 120); // Dar un arma AK-47 con 120 balas.
}
case 2:
{
GivePlayerWeapon(playerid, 27, 28); // Dar un arma Combat Shotgun con 28 balas.
}
}
}
return 1; // Cerrando dialog response del dialog # 3!
}
return 1; // Cerrando public.
}
Estructura de la función GivePlayerWeapon:
Code:
GivePlayerWeapon(playerid, weaponid, ammo);
Información adicional sobre la función: https://sampwiki.blast.hk/wiki/GivePlayerWeapon
Dialog de contraseña (permite a los jugadores colocar texto en el dialog, sin revelar el texto):
![[Image: Dialog_style_password.png]](http://wiki.sa-mp.com/wroot/images2/f/f8/Dialog_style_password.png)
Tiene la misma estructura que "Dialog de contraseña"; mayormente usado en sistemas de registro (lo cual es ligeramente avanzado para ser explicado en esta guía).
Si quiere ver cómo crear sistemas de registro puede visitar:
TheChaoz, cómo crear un sistema de registro.
Kush account system guide (Y_INI).
Lorenc_ account system guide (SQLite using rBits).
CREANDO Y REMOVIENDO OBJETOS:
Hay muchos programas para modificar el mapa del servidor; los más conocidos son:
Map editor 1 (inglés)
Map editor 2 (inglés)
MTA editor
Lista de objetos: https://sampwiki.blast.hk/wiki/Model_ID
Map editor (1 & 2):
Ambos tienen una estructura parecida; esta es una explicación para ambos casos.
Empezando:
- Después de descargarlo, debe abrir el archivo "editor.exe" y presionar el botón "LOAD".
- Cargará el mapa del juego (GTA-SA); puede mover la cámara moviendo el mouse mientras presiona clic derecho. Puede mover por el mapa con el scroll o usando las teclas "W, A, S y D" mientras presiona clic derecho.
Creando objetos:
- Muévase al lugar donde quiere añadir el mapa, presione el botón "Objects" dentro del menú (el menú al lado derecho de la ventana).
- Presione "+Add" y busque el objeto que quiere añadir (ID o nombre); luego haga doble clic en él y presione el botón "Add".
- Después de hacerlo presione en el objeto mostrado en el lado derecho de la venta, luego presione "insert".
- Puede mover el objeto usando el panel "Movement".
- Después de mapear puede obtener el código y añadirlo a su GM presionando "Show Code". Copa el código y lo pega en OnGameModeInit.
Ejemplo:
Code:
public OnGameModeInit()
{
CreateObject(2587, 2001.195679, 1547.113892, 14.283400, 0.0, 0.0, 96.0); // El objeto cargará a su distancia por defecto (GTA-SA).
return 1;
}
Información adicional: https://sampwiki.blast.hk/wiki/CreateObject
Removiendo objetos:
- Muévase alrededor del mapa y busque el objeto que desea borrar.
- Haga clic en él y presione la tecla "Supr".
- Después de borrarlo presione "Show Code". Debe pegar el código en public OnPlayerConnect.
Ejemplo:
Code:
public OnPlayerConnect(playerid)
{
RemoveBuildingForPlayer(playerid, 3782, 1803.0859, -1294.2031, 34.3438, 0.25);
return 1;
}
Información adicional: https://sampwiki.blast.hk/wiki/RemoveBuildingForPlayer
MTA editor:
Este programa es más sencillo de usar (para los nuevos) que el otro editor.
Puede descargarlo aquí.
* Nota: El programa puede crear objetos pero no eliminarlos.
Empezando:
- Después de descargarlo, abra el archivo MTA.exe
- Haga clic en el editor de mapas.
- Muévase por el mapa, use la cámara y las teclas "W, A, S y D".
- Para crear objetos presione "F" y haga clic en el cubo (parte inferior):
![[Image: uwz65v3.jpg]](https://i.imgur.com/uwz65v3.jpg)
- Busque el objeto y colóquelo en el mapa.
* Nota: Puede mover arriba y abajo haciendo clic en el objecto y usando las teclas "Avpag" y "Repag" (o también conocidas como "Page Down (pg dn)" y "Page Up (pg up)"). Para rotarlo use "Shift + Scroll". Para cambiar el ángulo use "CTRL + Avpag/Repag" o "CTRL + Flechas".
- Para guardar el mapa use el botón de guardado:
![[Image: bROE6FQ.jpg]](https://i.imgur.com/bROE6FQ.jpg)
- Para obtener el código use un convertidor de mapas MTA:
Delux GTA Map Converter v2 (2015)
Delux GTA Map Converter v2:
- En vez de IPL file format escoja PAWN Code for SA-MP. Busque el mapa dentro de la carpeta MTA; usualmente se encuentra dentro de \mods\deathmatch\resources.
- Copie el código.
Creando Objetos:
Después de obtener el código de objeto, debe añadirlo dentro de public OnGameModeInit o OnFilterScriptInit.
Ejemplo:
Code:
public OnGameModeInit()
{
CreateObject(2587, 2001.195679, 1547.113892, 14.283400, 0.0, 0.0, 96.0); // El objeto cargará a su distancia original.
CreateObject(2587, 2001.195679, 1547.113892, 14.283400, 0.0, 0.0, 96.0, 250.0); //El objeto será visible a 250 unidades.
return 1;
}
Sin embargo, SA-MP tiene un límite de 1000 objetos. Si quiere optimizar el script o hacerlo más rápido, debe usar el plugin Streamer.
Instalación de Streamer:
- Puede descargarlo desde el tema del plugin.
- Después de descargarlo, pegue el archivo "streamer.so" o "streamer.dll" dentro de la carpeta plugins (o simplemente pegue la carpeta plugins contenida en la descarga dentro de la carpeta del servidor).
- Copie el include "streamer.inc" dentro de la carpeta includes, dentro de la carpeta pawno.
- Edite el archivo "server.cfg" dentro de la carpeta de su servidor y agregue esta línea si está usando Windows:
Code:
plugins streamer.dll
Si usa Linux agregue:
Code:
plugins streamer.so
- Copie este código dentro debajo de todos los includes (ejemplo de include: #include <a_samp>) de cada script que use el plugin streamer:
Code:
#include <streamer>
#define STREAMER_TYPE_OBJECT (0)
#define STREAMER_TYPE_PICKUP (1)
#define STREAMER_TYPE_CP (2)
#define STREAMER_TYPE_RACE_CP (3)
#define STREAMER_TYPE_MAP_ICON (4)
#define STREAMER_TYPE_3D_TEXT_LABEL (5)
#define STREAMER_TYPE_AREA (6)
#define STREAMER_AREA_TYPE_CIRCLE (0)
#define STREAMER_AREA_TYPE_CYLINDER (1)
#define STREAMER_AREA_TYPE_SPHERE (2)
#define STREAMER_AREA_TYPE_RECTANGLE (3)
#define STREAMER_AREA_TYPE_CUBOID (4)
#define STREAMER_AREA_TYPE_POLYGON (5)
#define STREAMER_OBJECT_TYPE_GLOBAL (0)
#define STREAMER_OBJECT_TYPE_PLAYER (1)
#define STREAMER_OBJECT_TYPE_DYNAMIC (2)
enum
{
E_STREAMER_ATTACHED_OBJECT,
E_STREAMER_ATTACHED_PLAYER,
E_STREAMER_ATTACHED_VEHICLE,
E_STREAMER_ATTACH_OFFSET_X,
E_STREAMER_ATTACH_OFFSET_Y,
E_STREAMER_ATTACH_OFFSET_Z,
E_STREAMER_ATTACH_R_X,
E_STREAMER_ATTACH_R_Y,
E_STREAMER_ATTACH_R_Z,
E_STREAMER_ATTACH_X,
E_STREAMER_ATTACH_Y,
E_STREAMER_ATTACH_Z,
E_STREAMER_COLOR,
E_STREAMER_DRAW_DISTANCE,
E_STREAMER_EXTRA_ID,
E_STREAMER_INTERIOR_ID,
E_STREAMER_MAX_X,
E_STREAMER_MAX_Y,
E_STREAMER_MAX_Z,
E_STREAMER_MIN_X,
E_STREAMER_MIN_Y,
E_STREAMER_MIN_Z,
E_STREAMER_MODEL_ID,
E_STREAMER_MOVE_R_X,
E_STREAMER_MOVE_R_Y,
E_STREAMER_MOVE_R_Z,
E_STREAMER_MOVE_SPEED,
E_STREAMER_MOVE_X,
E_STREAMER_MOVE_Y,
E_STREAMER_MOVE_Z,
E_STREAMER_NEXT_X,
E_STREAMER_NEXT_Y,
E_STREAMER_NEXT_Z,
E_STREAMER_PLAYER_ID,
E_STREAMER_R_X,
E_STREAMER_R_Y,
E_STREAMER_R_Z,
E_STREAMER_SIZE,
E_STREAMER_STREAM_DISTANCE,
E_STREAMER_STYLE,
E_STREAMER_TEST_LOS,
E_STREAMER_TYPE,
E_STREAMER_WORLD_ID,
E_STREAMER_X,
E_STREAMER_Y,
E_STREAMER_Z
}
* Nota: Este código está basado en la actualización del plugin Streamer, 2015 (v2.7.4).
- Después de hacerlo edite el código del objeto que desea añadir. En vez de usar "CreateObject" use "CreateDynamicObject".
Ejemplo:
En vez de usar un código normal...
Code:
public OnGameModeInit()
{
CreateObject(2587, 2001.195679, 1547.113892, 14.283400, 0.0, 0.0, 96.0);
return 1;
}
Use:
Code:
public OnGameModeInit()
{
CreateDynamicObject(2587, 2001.195679, 1547.113892, 14.283400, 0.0, 0.0, 96.0);
return 1;
}
* Nota: Puede editar más rápido el código "CreateObject" usando un bloc de notas (.txt). Pegue el código dentro; y presione "CTRL + R", busque "CreateObject" y lo reemplaza por "CreateDynamicObject" (use esto si el mapa es muy grande).
- Después de hacer esto abra el archivo PWN donde quiere añadir los objetos (usualmente dentro del gamemode) y pegue su código.
Ejemplo:
Code:
public OnGameModeInit()
{
CreateDynamicObject(2587, 2001.195679, 1547.113892, 14.283400, 0.0, 0.0, 96.0);
return 1;
}
Información adicional sobre Streamer.
EMPIECE A PRACTICAR:
Ahora que sabe esto, usted puede practicar editando otros script o puede intentar crear su propio script.
¡Una buena forma de empezar es editando otros gamemodes!
Si hay algún error en esta guía o algo debería ser añadido, simplemente comente.
* Nota: esta es una pequeña guía comparada con toda la información básica de SA-MP que un nuevo scripter debe conocer; este tema será actualizado de acuerdo a las sugerencias de los usuarios y sus comentarios.
Créditos de esta guía: Ygzeb (David Talledo)
Agradecimientos especiales a:
Kwarde que ayudó a actualizar algunos enlaces que estaban rotos (2021) :)
Complemento (2021) .- Es posible que algunos enlaces o imágenes simplemente no funcionen ahora o en el futuro; igualmente, es posible que sean reparados en el futuro o no. Sin embargo, espero que esta guía aún sea de ayuda.