Jump to content

[Tutorial] Crear un lanzagranadas simple


Rose

Recommended Posts

Introducción

      Voy a enseñar a hacer un lanzagranadas simple para las armas: MP5, M4 y AK47 ( si quieres puedes poner más ); con máximo de balas 3 y un delay para disparar de nuevo la bala de 2 segundos.

Contenido

  • Introducción
  • Contenido
  • Creación de variables
  • Creación de un dxText con información sobre balas, activado/desactivado.
  • Creación del lanzagranadas 
  • Función para comprar más balas
  • Función para evitar lanzagranadas en armas no disponibles
  • Código completo & Resource

Creación de variables

Spoiler

  Lo primero que vamos a hacer es crear las variables que vamos a utilizar en el script, entre ellas, van a estar: tipo de bala, armas válidas, variable para saber si está activado el launcher, máximo de balas permitidas, precio de las balas y un tiempo para poder disparar las balas.

Bien... Empezaremos creándolas:


local types = {16, 17} -- [16] Granada, [17] bomba de humo
local allowedWeapons = { [29] = true, [30] = true,[31] = true} -- [29] MP5, [30] M4 y [31] AK47
local grenadeLauncher = false -- Variable para saber si está activo o no el launcher
local maxBullets = 3 -- Número máximo de balas 
local priceBullets = 5000 -- Precio de las balas de launcher
local delayTime = 2000 -- Tiempo para volver a disparar un misil
  1. types: Los tipos de misil que vamos a usar, ahí solo puse la granada y la bomba de humo para que se vea más real. Para más información: createProjectile
  2. allowedWeapon: Las armas permitidas para el lanzagranadas (puedes agregar más poniendo [ID] = true,)
  3. grenadeLauncher: Para saber si está activado o no el lanzagranadas.
  4. maxBullets: Máximo de balas para poder disparar, al disparar 3 balas de lanzagranadas no podrás disparar más.
  5. priceBullets: Precio de la bala de un lanzagranada
  6. delayTime: Anti spam de lanzagranadas de 2 segundos

Creación de un dxText con información sobre balas, activado/desactivado.

Spoiler

Ahora crearemos algo sencillo, un dxDrawText para saber cuando (no) tenemos activado el lanzagranadas. Yo crearé el mío primero, pero ustedes usen la posición que quieran.


addEventHandler("onClientRender", root,
    function()
		local state = not grenadeLauncher -- Con esto obtenemos el estado de la variable grenadeLauncher, para más adelante solo usar... 
        dxDrawText("Launcher: "..(state and "#FF0000OFF" or "#00ff00ON").." #FFFFFF| Ammo: "..(state and "#ffffff"..getPedAmmoInClip(localPlayer) or "#00cbff"..maxBullets), 50, 428, 143, 443, tocolor(255, 255, 255, 255), 1.00, "default-bold", "left", "top", false, false, false, true, false)
    end
)

Bien, el ..(state and "#ff0000OFF" or "00FF00ON").."" es solo para que el texto de adentro cambie según el estado de la variable, es decir, si la variable es falsa, saldrá "OFF", si es verdadera, saldrá "ON"; pero eso depende también de como los agrupes, porque si no pones el "#00ff00ON" primero que el "#FF0000OFF" Obviamente saldrá OFF cuando esté activado  y ON cuando esté desactivado, depende de cuál sea el valor que le dimos a la variable inicialmente. 

Creación del lanzagranadas

Spoiler

Lo primero que crearemos para que el lanzagranadas quede funcional, es una función para activarlo. Para ello usaremos bindKey seguido de unas condicionales para verificar que el lanzagranadas está desactivado y el jugador tiene las armas ya escritas en la tabla(allowedWeapons).

Quedaría así:


-- Activar lanzagranadas
function onLauncher()
	if (not grenadeLauncher) and (allowedWeapons[getPedWeapon(localPlayer)]) then -- Si el launcher no está activado y tiene las armas de allowedWeapons...
		grenadeLauncher = true -- Se activa
		toggleControl("fire", false) -- Le desactivamos el disparo al jugador
	else -- lo contrario
		grenadeLauncher = false -- Se desactiva
		toggleControl("fire", true) -- Le activamos el disparo al jugador
	end
end
bindKey("3", "down", onLauncher)--Tecla numero 3 se activa

Ahora bien, lo siguiente que haremos es crear la función para lanzar las granadas; usaremos igualmente un bindKey pero este se activará dándole click al mouse, también usaremos una condicional para verificar que: tienes las armas disponibles, el lanzagranadas está activado y las balas del lanzagranadas son mayores a 0... Para ello, tenemos que usar esto:


if (allowedWeapons[getPedWeapon(localPlayer)]) and (grenadeLauncher == true) and (maxBullets > 0) then

Ahora, usaremos getTickCount para que haya un limite de tiempo para poder disparar otra bala del lanzagranada. También usaremos la variable ya mencionada "delayTime". Así estaría quedando:


function fireLauncher(button, statep)
	if (allowedWeapons[getPedWeapon(localPlayer)]) and (grenadeLauncher == true) and (maxBullets > 0) then -- Si tienes las armas disponibles, el lanzagranadas está activado y las balas del lanzagranadas son mayores a 0...
		if (getTickCount() - delayTime > 2000) then -- Si es mayor a 2000 el conteo...
			delayTime = getTickCount() -- Esto es para que se repita, o sea, si no lo ponemos el delay servirá pero solo una vez, con esto indicamos que vuelva a hacer el conteo al pasar los 2000 milisegundos sin irse tan lejos el conteo.
		end
	end
end
bindKey("mouse1", "down", fireLauncher)

Y para terminar esta parte, sacaremos la posición por donde dispara el arma usando getPedWeaponMuzzlePosition, después crearemos el projectil con createProjectile y en sus argumentos x,y,z pondremos los que devuelve getPedWeaponMuzzlePosition (recomiendo una variable para esto); luego, le restaremos 1 (-1) a las balas, de esta forma: maxBullets = maxBullets - 1; y por último, usaremos una condicional para verificar que si el jugador tiene 0 de balas y quiere disparar, no lo deje hacerlo y le saldrá un mensaje de que ya no tiene balas.

Así terminaríamos esta parte:


function fireLauncher(button, statep)
	if (allowedWeapons[getPedWeapon(localPlayer)]) and (grenadeLauncher == true) and (maxBullets > 0) then -- Si tienes las armas disponibles, el lanzagranadas está activado y las balas del lanzagranadas son mayores a 0...
		if (getTickCount() - delayTime > 2000) then -- Si es mayor a 2000 el conteo...
            if (getPedTargetStart(localPlayer)) then 
				local x, y, z =  getPedWeaponMuzzlePosition ( localPlayer ) -- Obtenemos el 'cañón' (no sé como se le dice :[) por donde sale la bala
				createProjectile(getLocalPlayer(),types[1],x,y,z,1)  -- Creamos el projectil. el types[1] es porque estamos sacando el valor 1 de la tabla types.
				maxBullets = maxBullets - 1 -- Le restamos 1 a las balas
				if (maxBullets == 0) then -- Si las balas son igual a 0
					outputChatBox("No tienes más balas, ve a comprar más") -- Mensaje de que ya no tiene más balas
					toggleControl("fire", false) -- Le desactivamos el disparo al jugador para evitar bugs...
				end
			end
			delayTime = getTickCount() -- Esto es para que se repita, o sea, si no lo ponemos el delay servirá pero solo una vez, con esto indicamos que vuelva a hacer el conteo al pasar los 2000 milisegundos sin irse tan lejos el conteo.
		end
	end
end
bindKey("mouse1", "down", fireLauncher)

 

Función para comprar más balas

Spoiler

Lo que falta en este momento es que puedas comprar más balas cuando se te acaben, para lograr esto es sencillo, verificaremos si el jugador tiene el dinero (priceBullets) de la variable ya antes escrita y el lanzagranadas está activado, se hace la compra. Luego, una condicional para que si el jugador tiene ya 3 balas no pueda comprar más, y por último, un trigger para que le quite el dinero desde server-side  y sume las balas.Recordemos que en client [ takePlayerMoney ] te pone el dinero que quieres que quite, un ejemplo:

           - takePlayerMoney(player, 500) -- Esto le pondría el dinero en 500, no le restaría -500 a su dinero.                                              

Quedaría así:

                                                                                 Función para comprar balas

Client:



function buyBullets()
	if (getPlayerMoney(localPlayer) >= tonumber(priceBullets)) and (grenadeLauncher == true)  then -- Si el dinero del jugador es mayor a priceBullets (5000) y el lanzagranadas está activado...
		if (maxBullets == 3)  then -- Si tienes 3 balas...
			outputChatBox("No puedes comprar más balas, 3 es el máximo", 255,0,0,false)
		else -- sino las tienes...
			maxBullets = maxBullets + 1 -- Te suma una bala
			triggerServerEvent("onBuyGrenadeLauncher", getLocalPlayer(), priceBullets) 
			outputChatBox("Has comprado 1 bala de lanzagranadas por "..priceBullets, 0, 255,0,false)
		end
	end
end
addCommandHandler("buy", buyBullets)

Server:


--
addEvent("onBuyGrenadeLauncher", true)
addEventHandler("onBuyGrenadeLauncher", root, function(price)
	takePlayerMoney(source, tonumber(price))
end)

 

Función para evitar lanzagranadas en armas no disponibles.

Spoiler

function change()
	if not (allowedWeapons[getPedWeapon(localPlayer)]) then  -- Si no tienes las armas disponibles al cambiar el arma
		grenadeLauncher = false -- Se le desactiva el lanzagrandas
	end
end
addEventHandler("onClientPlayerWeaponSwitch", getLocalPlayer(), change)

 

            Código completo: 

Spoiler

--Client
-- Test lanzagranadas
local types = {16, 17} -- [16] Granada, [17] bomba de humo
local allowedWeapons = { [29] = true, [30] = true,[31] = true} -- [29] MP5, [30] M4 y [31] AK47
local grenadeLauncher = false -- Variable para saber si está activo o no el launcher
local maxBullets = 3 -- Número máximo de balas 
local priceBullets = 5000 -- Precio de las balas de launcher
local delayTime = 2000 -- Tiempo para volver a disparar un misil

addEventHandler("onClientRender", root,
    function()
		local state = not grenadeLauncher -- Con esto sacaremos el estado de la variable grenadeLauncher, para más adelante solo usar... 
        dxDrawText("Launcher: "..(state and "#FF0000OFF" or "#00ff00ON").." #FFFFFF| Ammo: "..(state and "#ffffff"..getPedAmmoInClip(localPlayer) or "#00cbff"..maxBullets), 50, 428, 143, 443, tocolor(255, 255, 255, 255), 1.00, "default-bold", "left", "top", false, false, false, true, false)
    end
)

-- Activar lanzagranadas
function onLauncher()
	if (not grenadeLauncher) and (allowedWeapons[getPedWeapon(localPlayer)]) then -- Si el launcher no está activado y tiene las armas de allowedWeapons...
		grenadeLauncher = true -- Se activa
		toggleControl("fire", false) -- Le desactivamos el disparo al jugador
	else -- lo contrario
		grenadeLauncher = false -- Se desactiva
		toggleControl("fire", true) -- Le activamos el disparo al jugador
	end
end
bindKey("3", "down", onLauncher)



function fireLauncher(button, statep)
	if (allowedWeapons[getPedWeapon(localPlayer)]) and (grenadeLauncher == true) and (maxBullets > 0) then -- Si tienes las armas disponibles, el lanzagranadas está activado y las balas del lanzagranadas son mayores a 0...
		if (getTickCount() - delayTime > 2000) then
			if (getPedTargetStart(localPlayer)) then 
				local x, y, z =  getPedWeaponMuzzlePosition ( localPlayer ) -- Obtenemos el 'cañón' (no sé como se le dice :[) por donde sale la bala
				createProjectile(getLocalPlayer(),types[1],x,y,z,1)  -- Creamos el projectil. el types[1] es porque estamos sacando el valor 1 de la tabla types.
				maxBullets = maxBullets - 1 -- Le restamos 1 a las balas
				if (maxBullets == 0) then 
					outputChatBox("No tienes más balas, ve a comprar más") -- Mensaje de que ya no tiene más balas
					toggleControl("fire", false) -- Le desactivamos el disparo al jugador para evitar bugs...
				end
			end
		delayTime = getTickCount()
		end
	end
end
bindKey("mouse1", "down", fireLauncher)

function fireLauncher(button, statep)
	if (allowedWeapons[getPedWeapon(localPlayer)]) and (grenadeLauncher == true) and (maxBullets > 0) then -- Si tienes las armas disponibles, el lanzagranadas está activado y las balas del lanzagranadas son mayores a 0...
		if (getTickCount() - delayTime > 2000) then -- Si es mayor a 2000 el conteo...
			delayTime = getTickCount() -- Esto es para que se repita, o sea, si no lo ponemos el delay servirá pero solo una vez, con esto indicamos que vuelva a hacer el conteo sin irse tan lejos el conteo.
		end
	end
end
bindKey("mouse1", "down", fireLauncher)

function buyBullets()
	if (getPlayerMoney(localPlayer) >= tonumber(priceBullets)) and (grenadeLauncher == true)  then -- Si el dinero del jugador es mayor a priceBullets (5000) y el lanzagranadas está activado...
		if (maxBullets == 3)  then -- Si tienes 3 balas...
			outputChatBox("No puedes comprar más balas, 3 es el máximo", 255,0,0,false)
		else -- sino las tienes...
			maxBullets = maxBullets + 1 -- Te suma una bala
			triggerServerEvent("onBuyGrenadeLauncher", getLocalPlayer(), priceBullets) 
			outputChatBox("Has comprado 1 bala de lanzagranadas por "..priceBullets, 0, 255,0,false)
		end
	end
end
addCommandHandler("buy", buyBullets)

function change()
	if not (allowedWeapons[getPedWeapon(localPlayer)]) then 
		grenadeLauncher = false
	end
end
addEventHandler("onClientPlayerWeaponSwitch", getLocalPlayer(), change)

--Server
--
addEvent("onBuyGrenadeLauncher", true)
addEventHandler("onBuyGrenadeLauncher", root, function(price)
	takePlayerMoney(source, tonumber(price))
end)

 

Resource: https://community.multitheftauto.com/index.php?p=resources&s=details&id=13899 (Voy a tratar de mejorarlo)

 

Si tienen dudas o saben alguna forma de hacerlo más eficiente (o algún error que hayan visto) pueden decirlas, gracias.

 

 

Edited by Hit+
Ninguna
  • Like 1
Link to comment

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...