[FS] Sistema de curar/medico

¿Tienes un FilterScript muy bueno y quieres compartirlo con los demás? ¿Qué esperas? ¡Muéstranoslo aquí!

Moderador: Ayudantes

Reglas del Foro
  • Al liberar un FilterScript, debes informar sobre qué trata el código claramente, imágenes o vídeos y la explicación de cómo usarlo.
  • En caso de que quieras publicar un TextDraw que únicamente cumpla una función estética (como ser un TextDraw que muestra el nombre del servidor), es decir, no cumple ninguna función más que decorativa/visual (a diferencia de un TextDraw que realiza la función de velocímetro y contiene los códigos para ello, por ejemplo), debe ir en la sección Guías y Aportes.
  • Si el link de descarga no funciona, el tema será eliminado.
  • Si no eres el autor del FilterScript o has utilizado códigos de otros autores, recuerda colocar los créditos correspondientes. (El plagio es motivo de sanción).
Responder
Omaretot
Aprendiz
Aprendiz
Mensajes: 95
Registrado: 07 Dic 2015 18:46
Reputación: 7

19 Abr 2018 13:22

Buenas,

Aquí vengo con un FilterScript que trata sobre curar a personas cercanas mediante un comando, para curar a otros jugadores debes ser un medico y cada vez que curaras debes esperar 120 por vez.

Comandos
- /curar [ID]
- /sermedico

Debo aclarar que esto es una forma BASE, ya que no quise extender mucho el FilterScript ya que si querría adaptarlo a un Team DeathMatch debía crear un sistema de clases y deberia crear variables, si lo adaptaba a un Roleplay debía hacer un sistema por lo menos de médico completo, (Guardar información del jugador, o sea, su faccion de médico, cargado de información del jugador, rangos para poder que altos rangos puedan ofrecer contratos, entre muchos factores).

¿Como lo adapto a un servidor RP?
Solamente te ofrecere un mini-ajuste del comando /curar, lo demás quedan en tus manos
Vamos al comando de /curar y en la primera linea cambiamos:
 Codigo Pawno:
1

if(GetPlayerSkin(playerid) != 274) return SendClientMessage(playerid, -1, "No eres medico para utilizar este comando");
  Cantidad de llaves: Abiertas(0)-Cerradas(0) | Lineas Totales: 1
Por:
 Codigo Pawno:
1

if(PlayerInfo[playerid][pMedic] == 0) return SendClientMessage(playerid, -1, "No eres medico para utilizar este comando");
  Cantidad de llaves: Abiertas(0)-Cerradas(0) | Lineas Totales: 1
Cambiaras obviamente las variables de PlayerInfo y la de pMedic por tus variables de la información del jugador y la de la facción de médicos, todo queda bajo tus manos.

Ideas para un FreeRoam
Puedes realizar que cuando spawnee tenga 30 segundos para colocar /sermedico, si el jugador ejecuta el comando que se le asigne el valor de médico y así pueda curar

Bugs conocidos
En su forma base se puede bugear fácilmente con cualquier comando de /skin, ya que puedes hacer /skin 274 y ya eres médicos, este bug tiene 2 soluciones:
1. Hacer que el jugador no se pueda colocar el skin 274
2. Hacer un sistema de clases y poner que si es clase médico pueda usar el comando, algo parecido a la adaptación al RP

Plugins necesarios
- YashaSamaga [IZCMD]
- Maddinat0r [SSCANF2]

Creditos
- Omaretot [FS]
- YashaSamaga [IZCMD]
- Maddinat0r [SSCANF2]

Descarga
Hazme clic!
Avatar de Usuario
Alfon
Baneado
Baneado
Mensajes: 693
Registrado: 17 Ene 2016 18:39
Ubicación: YOVIVOENALGUNAPARTEDEESTE INSIGNIFICANTEMUNDOLLENODE RARITOSYANORMALES PERONOPASANADACARNAL YOLOSAMO
Reputación: 24

19 Abr 2018 14:55

Simple y interesante, esto puede servir de base para el que le interese, a mi en este caso no me sirve porque no estoy creando un server con clases o RP, igual se ve interesante -hi felicidades.
Avatar de Usuario
MrDave
Ayudante
Ayudante
Mensajes: 1049
Registrado: 05 Oct 2017 12:13
Reputación: 113

19 Abr 2018 15:20

Buen aporte amigo; sin embargo la subrutina "GetTickCount" devuelve el tiempo en milisegundos desde que la computadora está encendida y después de los 24 días retornará un valor tan grade que sobrepasará la cantidad máxima de dígitos que puede almacenar una variable de 4 bytes (hasta 10 dígitos puede guardar).
Aquí es donde sucede un desbordamiento numérico en la memoria, esto quiere decir que dará un valor erróneo al momento de exceder el límite.
Según "wiki-samp" ya hay una solución: https://gist.github.com/ziggi/5d7d8dc42 ... 924c608e73
Aunque para mí, sería mejor usar la función "gettime()", me devuelve la hora actual de la computadora en segundos, así no tengo que dividir entre 1000 como hacíamos en "GetTickCount()"; sin embargo esté subalgoritmo dejará de funcionar en el año del 2038 (según por lo que he escuchado).
Algunos ejemplos:
Ejemplo 1:
 Codigo Pawno:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

#include <a_samp.inc>
#include <Pawn.CMD>

#undef MAX_PLAYERS
#define MAX_PLAYERS \
	(10) //Editable

new Tiempo[MAX_PLAYERS];

public OnPlayerConnect(playerid)
{
	Tiempo[playerid] = 0;
	return 1;
}

cmd:micomando(playerid)
{
	if(Tiempo[playerid] > gettime())
	{
	    new str[64];
	    format(str, sizeof(str), "* Faltan %d segundos para volver a usar de nuevo este comando.", (Tiempo[playerid]-gettime()));
	    SendClientMessage(playerid, -1, str);
	    return 1;
	}
	Tiempo[playerid] = gettime() + (60 * 2);
	//Otras instrucciones...
	return 1;
}
  Cantidad de llaves: Abiertas(3)-Cerradas(3) | Lineas Totales: 28
Ejemplo 2: (Usando la librería "y_timers" creada por Y_Less)
 Codigo Pawno:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52

#include <a_samp.inc>
#include <pawncmd.inc>
#include <YSI\y_timers.inc>

#undef MAX_PLAYERS
#define MAX_PLAYERS \
	(10) //Editable
#define MINUTOS \
	(0)
#define SEGUNDOS \
	(1)

new Tiempo[MAX_PLAYERS][2];
new Timer:ID_Tiempo[MAX_PLAYERS];

public OnPlayerConnect(playerid)
{
	Tiempo[playerid][MINUTOS] = 0;
	Tiempo[playerid][SEGUNDOS] = 0;
	return 1;
}

cmd:micomando(playerid)
{
	if((Tiempo[playerid][MINUTOS] != 0) || (Tiempo[playerid][SEGUNDOS] != 0))
	{
 		new str[69];
	    format(str, sizeof(str), "* Debes esperar 2 minutos para usar este comando, tú tiempo: [%02d:%02d]", Tiempo[playerid][MINUTOS], Tiempo[playerid][SEGUNDOS]);
	    SendClientMessage(playerid, -1, str);
	    return 1;
	}
	ID_Tiempo[playerid] = repeat TiempoDeUso_CMD(playerid);
	//Otras instrucciones...
	return 1;
}

timer TiempoDeUso_CMD[1000](playerid)
{
	Tiempo[playerid][SEGUNDOS]++;
	if(Tiempo[playerid][SEGUNDOS] == 0)
	{
		Tiempo[playerid][MINUTOS]++;
		Tiempo[playerid][SEGUNDOS] = 0;
		if(Tiempo[playerid][MINUTOS] == 2)
		{
			Tiempo[playerid][MINUTOS] = 0;
			Tiempo[playerid][SEGUNDOS] = 0;
			stop ID_Tiempo[playerid];
		}
	}
	return 1;
}
  Cantidad de llaves: Abiertas(6)-Cerradas(6) | Lineas Totales: 52
También faltó declarar la variable local o automática "szString".
 Codigo Pawno:
1

new szString[128];
  Cantidad de llaves: Abiertas(0)-Cerradas(0) | Lineas Totales: 1
Tampoco es necesario usar tanta celdas para una cadena tan corta.

Código: Seleccionar todo

Curaste a %s
Así no más:
 Codigo Pawno:
1

new szString[17 + MAX_PLAYER_NAME];
  Cantidad de llaves: Abiertas(0)-Cerradas(0) | Lineas Totales: 1
Con respecto al funcionamiento del sistema, se podría crear un "array" para detectar sí es médico o no, porqué sí se lo hace mediante "GetPlayerSkin", posiblemente cause problemas en el modo de juego, ya que cualquier jugador que tenga la id de ese "skin" podrá usar la instrucción "/curar".
Algo así se podría efectuar:
 Codigo Pawno:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

#define IsPlayerMedic(%0) (EsMedico[%0] == true)
new bool:EsMedico[MAX_PLAYERS];

public OnPlayerConnect(playerid)
{
	EsMedico[playerid] = false;
	return 1;
}

CMD:curar(playerid, params[])
{
    if(!IsPlayerMedic(playerid))
		return SendClientMessage(playerid, -1, "No eres médico para utilizar este comando");
	//Otras sentencias...
    return 1;
}

CMD:sermedico(playerid, params[])
{
	if(IsPlayerMedic(playerid))
	    return SendClientMessage(playerid, -1, "ERROR: Usted ya es médico");
	EsMedico[playerid] = true;
    SetPlayerSkin(playerid, 274);
    ResetPlayerWeapons(playerid);
    GivePlayerWeapon(playerid, 23, 100);
    GivePlayerWeapon(playerid, 4, 1);
    SendClientMessage(playerid, -1, "Te has convertido en un médico!");
    return 1;
}
  Cantidad de llaves: Abiertas(3)-Cerradas(3) | Lineas Totales: 29

- Temporalmente estoy retirado de SA-MP; por lo tanto no me envíen propuestas de proyectos.
- No respondo dudas por privado, usa la sección de preguntas.
Omaretot
Aprendiz
Aprendiz
Mensajes: 95
Registrado: 07 Dic 2015 18:46
Reputación: 7

19 Abr 2018 20:05

Spoiler:
MrDave escribió:
19 Abr 2018 15:20
Buen aporte amigo; sin embargo la subrutina "GetTickCount" devuelve el tiempo en milisegundos desde que la computadora está encendida y después de los 24 días retornará un valor tan grade que sobrepasará la cantidad máxima de dígitos que puede almacenar una variable de 4 bytes (hasta 10 dígitos puede guardar).
Aquí es donde sucede un desbordamiento numérico en la memoria, esto quiere decir que dará un valor erróneo al momento de exceder el límite.
Según "wiki-samp" ya hay una solución: https://gist.github.com/ziggi/5d7d8dc42 ... 924c608e73
Aunque para mí, sería mejor usar la función "gettime()", me devuelve la hora actual de la computadora en segundos, así no tengo que dividir entre 1000 como hacíamos en "GetTickCount()"; sin embargo esté subalgoritmo dejará de funcionar en el año del 2038 (según por lo que he escuchado).
Algunos ejemplos:
Ejemplo 1:
 Codigo Pawno:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

#include <a_samp.inc>
#include <Pawn.CMD>

#undef MAX_PLAYERS
#define MAX_PLAYERS \
	(10) //Editable

new Tiempo[MAX_PLAYERS];

public OnPlayerConnect(playerid)
{
	Tiempo[playerid] = 0;
	return 1;
}

cmd:micomando(playerid)
{
	if(Tiempo[playerid] > gettime())
	{
	    new str[64];
	    format(str, sizeof(str), "* Faltan %d segundos para volver a usar de nuevo este comando.", (Tiempo[playerid]-gettime()));
	    SendClientMessage(playerid, -1, str);
	    return 1;
	}
	Tiempo[playerid] = gettime() + (60 * 2);
	//Otras instrucciones...
	return 1;
}
  Cantidad de llaves: Abiertas(3)-Cerradas(3) | Lineas Totales: 28
Ejemplo 2: (Usando la librería "y_timers" creada por Y_Less)
 Codigo Pawno:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52

#include <a_samp.inc>
#include <pawncmd.inc>
#include <YSI\y_timers.inc>

#undef MAX_PLAYERS
#define MAX_PLAYERS \
	(10) //Editable
#define MINUTOS \
	(0)
#define SEGUNDOS \
	(1)

new Tiempo[MAX_PLAYERS][2];
new Timer:ID_Tiempo[MAX_PLAYERS];

public OnPlayerConnect(playerid)
{
	Tiempo[playerid][MINUTOS] = 0;
	Tiempo[playerid][SEGUNDOS] = 0;
	return 1;
}

cmd:micomando(playerid)
{
	if((Tiempo[playerid][MINUTOS] != 0) || (Tiempo[playerid][SEGUNDOS] != 0))
	{
 		new str[69];
	    format(str, sizeof(str), "* Debes esperar 2 minutos para usar este comando, tú tiempo: [%02d:%02d]", Tiempo[playerid][MINUTOS], Tiempo[playerid][SEGUNDOS]);
	    SendClientMessage(playerid, -1, str);
	    return 1;
	}
	ID_Tiempo[playerid] = repeat TiempoDeUso_CMD(playerid);
	//Otras instrucciones...
	return 1;
}

timer TiempoDeUso_CMD[1000](playerid)
{
	Tiempo[playerid][SEGUNDOS]++;
	if(Tiempo[playerid][SEGUNDOS] == 0)
	{
		Tiempo[playerid][MINUTOS]++;
		Tiempo[playerid][SEGUNDOS] = 0;
		if(Tiempo[playerid][MINUTOS] == 2)
		{
			Tiempo[playerid][MINUTOS] = 0;
			Tiempo[playerid][SEGUNDOS] = 0;
			stop ID_Tiempo[playerid];
		}
	}
	return 1;
}
  Cantidad de llaves: Abiertas(6)-Cerradas(6) | Lineas Totales: 52
También faltó declarar la variable local o automática "szString".
 Codigo Pawno:
1

new szString[128];
  Cantidad de llaves: Abiertas(0)-Cerradas(0) | Lineas Totales: 1
Tampoco es necesario usar tanta celdas para una cadena tan corta.

Código: Seleccionar todo

Curaste a %s
Así no más:
 Codigo Pawno:
1

new szString[17 + MAX_PLAYER_NAME];
  Cantidad de llaves: Abiertas(0)-Cerradas(0) | Lineas Totales: 1
Con respecto al funcionamiento del sistema, se podría crear un "array" para detectar sí es médico o no, porqué sí se lo hace mediante "GetPlayerSkin", posiblemente cause problemas en el modo de juego, ya que cualquier jugador que tenga la id de ese "skin" podrá usar la instrucción "/curar".
Algo así se podría efectuar:
 Codigo Pawno:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

#define IsPlayerMedic(%0) (EsMedico[%0] == true)
new bool:EsMedico[MAX_PLAYERS];

public OnPlayerConnect(playerid)
{
	EsMedico[playerid] = false;
	return 1;
}

CMD:curar(playerid, params[])
{
    if(!IsPlayerMedic(playerid))
		return SendClientMessage(playerid, -1, "No eres médico para utilizar este comando");
	//Otras sentencias...
    return 1;
}

CMD:sermedico(playerid, params[])
{
	if(IsPlayerMedic(playerid))
	    return SendClientMessage(playerid, -1, "ERROR: Usted ya es médico");
	EsMedico[playerid] = true;
    SetPlayerSkin(playerid, 274);
    ResetPlayerWeapons(playerid);
    GivePlayerWeapon(playerid, 23, 100);
    GivePlayerWeapon(playerid, 4, 1);
    SendClientMessage(playerid, -1, "Te has convertido en un médico!");
    return 1;
}
  Cantidad de llaves: Abiertas(3)-Cerradas(3) | Lineas Totales: 29
Muy buenas observaciones amigo.
Responder