Jump to content

Tenho um server offroad de amigos e queria saber se alguém poderia criar a resource de guincho como este


Recommended Posts

  • Other Languages Moderators

Bem difícil...não consigo pensar em nada para simular a corda e muito menos em como fazer o veículo "seguir" o outro veículo dessa forma.
Além disso, duvido que alguém faça isso de graça pra você.
Mas a ideia é boa sim.

Edited by Lord Henry
  • Like 1
Link to comment
3 hours ago, Lord Henry said:

Bem difícil...não consigo pensar em nada para simular a corda e muito menos em como fazer o veículo "seguir" o outro veículo dessa forma.
Além disso, duvido que alguém faça isso de graça pra você.
Mas a ideia é boa sim.

Não precisaria seguir outro veiculo, poderia prender em algum objeto como arvore ou pedras

Link to comment
  • Moderators

Pra fazer seguir o veículo é possível, usando o mesmo método que faz os zumbis seguir o jogador. O problema é que perderia a ideia principal e tenho certeza que não ia funcionar como deve.

A única alternativa que posso te sugerir é usando o carro towtruck, deixá-lo invisível e anexar ao veículo principal usando a função attachTrailerToVehicle.

Eu fiz um teste rápido usando essa alternativa e pelo menos a parte inicial funciona, só algumas coisas como a rotação e offSet do towtruck precisam de ajustes pra funcionar corretamente.

 

Enfim, mais tarde vejo isso mais a fundo pra ter certeza se realmente funciona.

Link to comment
13 hours ago, DNL291 said:

Pra fazer seguir o veículo é possível, usando o mesmo método que faz os zumbis seguir o jogador. O problema é que perderia a ideia principal e tenho certeza que não ia funcionar como deve.

A única alternativa que posso te sugerir é usando o carro towtruck, deixá-lo invisível e anexar ao veículo principal usando a função attachTrailerToVehicle.

Eu fiz um teste rápido usando essa alternativa e pelo menos a parte inicial funciona, só algumas coisas como a rotação e offSet do towtruck precisam de ajustes pra funcionar corretamente.

 

Enfim, mais tarde vejo isso mais a fundo pra ter certeza se realmente funciona.

Ok muito obrigado

 

Link to comment
  • 2 weeks later...
  • Moderators

Não cheguei a fazer desse último modo que você postou porque não entendi bem. Na verdade estava esperando você falar como exatamente deve ser guinchado (se inclui também uma corda, etc).

  • Like 1
Link to comment
  • Moderators

Cheguei a pensar na função https://wiki.multitheftauto.com/wiki/DxDrawLine3D pra simular a corda de uma forma fácil, mas parece que fica longe de parecer uma corda, e a parte da corda imagino que vai tem que ser separada do código que faz o veículo seguir, ou seja, no lado client.

Talvez seja possível só por um meio mais complexo, substituindo uma textura do GTA e atualizando para ele ficar sempre na posição do guinchamento.

Edited by DNL291
Link to comment
  • 2 weeks later...
  • Moderators

Eu tinha feito uma parte do código e acabei esquecendo desse tópico, desculpe a demora na resposta. Fiz o resto hoje, e fiz um teste básico - o ideal é entre dois jogadores, mas tá aqui o código:


local towingVehs = {}
local TOWKEY = "arrow_u"
local disabledControls = { "vehicle_left", "vehicle_right", "accelerate", "brake_reverse", "handbrake"--[[, "enter_exit"]] }

-- veículo de teste
--local vbanshee = createVehicle(429, -2000.75354, 1063.79028, 54.97813, 0,0,88.0069543)

addEventHandler( "onResourceStart", resourceRoot,
	function()
		setTimer( monitoringTowingVehicles, 100, 0 )
	end
)

addCommandHandler( "guinchar", function (sp, cmd, pName)
	if pName and isElement(getPlayerFromPartialName( pName )) then
		local targetPlayer = getPlayerFromPartialName( pName )
		if not (getPedOccupiedVehicle(targetPlayer)) then return end;
	
		local myveh = getPedOccupiedVehicle(sp)
		--local towVeh = getNearestVehicle(veh)
		if not (myveh) then return end;
		setPlayerVehicleTowing( targetPlayer, myveh, true )
	end
end )

function setPlayerVehicleTowing(p, v, bool)
	-- p: o jogador que vai guinchar o veículo
	-- v: o veículo que vai guinchar o outro
	-- bool: ativar/desat. o guinchamento vinculado à tecla
	if p and getElementType(p) == "player" and v and getElementType(v) == "vehicle" and type(bool) == "boolean" then
		
		towingVehs[ v ] = bool and p or nil
		
		for i, control in pairs(disabledControls) do
			toggleControl(p, control, bool)
		end
		setVehicleBeingTowed( getPedOccupiedVehicle(p), v, bool )
		
		local driver = getVehicleController( v )
		if bool and driver and not isKeyBound( driver, TOWKEY, "both", funcInput ) then
			bindKey( driver, TOWKEY, "both", funcInput )
		elseif bool == false and driver and isKeyBound( driver, TOWKEY, "both", funcInput ) then
			unbindKey( driver, TOWKEY, "both", funcInput )
		end
		return true
	end
	return false
end

function setVehicleBeingTowed(v, towingVeh, bool)
	if v and isElement(v) and towingVeh and isElement(towingVeh) and type(bool) == "boolean" then
		if bool then
			setElementData( towingVeh, "towSys:VehicleBeingTowed", v, false )
		else
			if getElementData( towingVeh, "towSys:VehicleBeingTowed" ) then
				removeElementData( towingVeh, "towSys:VehicleBeingTowed" )
			end
		end
	end
end

function getVehicleBeingTowed( towingVeh )
	if towingVeh and isElement(towingVeh) then
		return getElementData( towingVeh, "towSys:VehicleBeingTowed" )
	end
end

function funcInput ( player, key, keyState )
	if not (getPedOccupiedVehicle(player)) then return end;
	local tPlayer = towingVehs[ getPedOccupiedVehicle(player) ]
	if tPlayer and getPedOccupiedVehicle(tPlayer) then
		local towedVeh = getPedOccupiedVehicle(tPlayer)
	end
	if key == TOWKEY and keyState == "down" and towedVeh then
		--outputChatBox("down")
		doAcellerateVehicle( towedVeh, true )
	elseif key == TOWKEY and keyState == "up" and towedVeh then
		--outputChatBox("up")
		doAcellerateVehicle( towedVeh, false )
	end
end

function monitoringTowingVehicles(player, v)
	for v, player in pairs(towingVehs) do
		local moveTo = ""
		local _,_,myvehRZ = getElementRotation(v)
		local _,_,towedVRZ = getElementRotation( getPedOccupiedVehicle(player) )--getElementRotation(vbanshee)
		myvehRZ, towedVRZ = math.floor(myvehRZ), math.floor(towedVRZ)
		local rotDiff = ( math.max(myvehRZ, towedVRZ) - math.min(myvehRZ, towedVRZ) )
		--outputChatBox("@rotDiff: "..tostring(rotDiff))
		
		if ( towedVRZ > myvehRZ ) and ( towedVRZ - myvehRZ ) <= 180 then
			moveTo = "left"
		elseif ( towedVRZ > myvehRZ ) and ( towedVRZ - myvehRZ ) > 180 then
			moveTo = "right"
		elseif ( myvehRZ > towedVRZ ) and ( myvehRZ - towedVRZ ) <= 180 then
			moveTo = "right"
		elseif ( myvehRZ > towedVRZ ) and ( myvehRZ - towedVRZ ) > 180 then
			moveTo = "left"
		end
		if rotDiff <= 8 then
			if getControlState( player, "vehicle_right" ) then
				setControlState( player, "vehicle_right", false )
				outputChatBox("right false")
			end
			if getControlState( player, "vehicle_left" ) then
				setControlState( player, "vehicle_left", false )
				outputChatBox("left false")
			end
		elseif moveTo == "left" or moveTo == "right" then
			setControlState( player, "vehicle_" .. moveTo, true )
		end
		--outputChatBox("Mover para: "..moveTo, me, 225, 225, 225)
	end
end

addEventHandler( "onElementDestroy", root,
	function()
		if getElementType(source) == "vehicle" and towingVehs[ source ] then
			local driver = getVehicleController( source )
			if driver then 
				setPlayerVehicleTowing( getVehicleController( getVehicleBeingTowed(source) ), source, false )
			end
		end
	end
)

addEventHandler( "onVehicleExplode", root, 
	function()
		if towingVehs[ source ] then
			local driver = getVehicleController( source )
			if driver then 
				setPlayerVehicleTowing( getVehicleController( getVehicleBeingTowed(source) ), source, false )
			end
		end
	end
)

local SetControlState = setControlState
function setControlState(p, control, state)
	if p and getElementType(p) == "player" and type(control) == "string" and type(state) == "boolean" then
		if getControlState( p, control ) ~= state then
			SetControlState( p, control, state )
		end
	end
end

function doAcellerateVehicle(v, bool)
	local driver = getVehicleController(v)
	if driver then
		if bool and getControlState( driver, "accelerate" ) ~= true then
			setControlState( driver, "accelerate", true )
		elseif bool == false and getControlState( driver, "accelerate" ) ~= false then
			setControlState( driver, "accelerate", false )
		end
	end
end

function getPlayerFromPartialName(name)
    local name = name and name:gsub("#%x%x%x%x%x%x", ""):lower() or nil
    if name then
        for _, player in ipairs(getElementsByType("player")) do
            local name_ = getPlayerName(player):gsub("#%x%x%x%x%x%x", ""):lower()
            if name_:find(name, 1, true) then
                return player
            end
        end
    end
end

--[[
function getNearestVehicle(veh)
	if not (isElement(veh)) then return false end;
	local myVehX, myVehY = getElementPosition(veh)
	local smallestD = 999999
	local nearestVeh
	for i, v in pairs(getElementsByType"vehicle") do
		local vx,vy = getElementPosition(v)
		local _dist = getDistanceBetweenPoints2D(vx,vy,myVehX,myVehY)
		if _dist < smallestD and v ~= veh then
			smallestD = _dist 
			nearestVeh = v
		end
	end
	return nearestVeh or false
end
]]

O guinchamento funciona da seguinte forma:

Você digita o comando guinchar e especifica um nome do jogador no comando (o dono do veículo a ser guinchado).

E o outro jogador deve estar num veículo; esse veículo será guinchado segurando a seta p/ cima. É provável que não esteja da forma que deve funcionar. A parte de clicar num ponto para o veículo ser puxado eu não fiz, se for necessário só falar.

Não testei muita coisa além disso porque só um jogador não dá pra fazer tudo e saber se funciona. Outra coisa, a corda anexada aos veículos eu não fiz (se conseguir encontrar uma textura, ótimo, eu posso adicionar).

  • Like 1
Link to comment
23 hours ago, DNL291 said:

Onde coloco esse código?

 

23 hours ago, DNL291 said:

local towingVehs = {}
local TOWKEY = "arrow_u"
local disabledControls = { "vehicle_left", "vehicle_right", "accelerate", "brake_reverse", "handbrake"--[[, "enter_exit"]] }

-- veículo de teste
--local vbanshee = createVehicle(429, -2000.75354, 1063.79028, 54.97813, 0,0,88.0069543)

addEventHandler( "onResourceStart", resourceRoot,
	function()
		setTimer( monitoringTowingVehicles, 100, 0 )
	end
)

addCommandHandler( "guinchar", function (sp, cmd, pName)
	if pName and isElement(getPlayerFromPartialName( pName )) then
		local targetPlayer = getPlayerFromPartialName( pName )
		if not (getPedOccupiedVehicle(targetPlayer)) then return end;
	
		local myveh = getPedOccupiedVehicle(sp)
		--local towVeh = getNearestVehicle(veh)
		if not (myveh) then return end;
		setPlayerVehicleTowing( targetPlayer, myveh, true )
	end
end )

function setPlayerVehicleTowing(p, v, bool)
	-- p: o jogador que vai guinchar o veículo
	-- v: o veículo que vai guinchar o outro
	-- bool: ativar/desat. o guinchamento vinculado à tecla
	if p and getElementType(p) == "player" and v and getElementType(v) == "vehicle" and type(bool) == "boolean" then
		
		towingVehs[ v ] = bool and p or nil
		
		for i, control in pairs(disabledControls) do
			toggleControl(p, control, bool)
		end
		setVehicleBeingTowed( getPedOccupiedVehicle(p), v, bool )
		
		local driver = getVehicleController( v )
		if bool and driver and not isKeyBound( driver, TOWKEY, "both", funcInput ) then
			bindKey( driver, TOWKEY, "both", funcInput )
		elseif bool == false and driver and isKeyBound( driver, TOWKEY, "both", funcInput ) then
			unbindKey( driver, TOWKEY, "both", funcInput )
		end
		return true
	end
	return false
end

function setVehicleBeingTowed(v, towingVeh, bool)
	if v and isElement(v) and towingVeh and isElement(towingVeh) and type(bool) == "boolean" then
		if bool then
			setElementData( towingVeh, "towSys:VehicleBeingTowed", v, false )
		else
			if getElementData( towingVeh, "towSys:VehicleBeingTowed" ) then
				removeElementData( towingVeh, "towSys:VehicleBeingTowed" )
			end
		end
	end
end

function getVehicleBeingTowed( towingVeh )
	if towingVeh and isElement(towingVeh) then
		return getElementData( towingVeh, "towSys:VehicleBeingTowed" )
	end
end

function funcInput ( player, key, keyState )
	if not (getPedOccupiedVehicle(player)) then return end;
	local tPlayer = towingVehs[ getPedOccupiedVehicle(player) ]
	if tPlayer and getPedOccupiedVehicle(tPlayer) then
		local towedVeh = getPedOccupiedVehicle(tPlayer)
	end
	if key == TOWKEY and keyState == "down" and towedVeh then
		--outputChatBox("down")
		doAcellerateVehicle( towedVeh, true )
	elseif key == TOWKEY and keyState == "up" and towedVeh then
		--outputChatBox("up")
		doAcellerateVehicle( towedVeh, false )
	end
end

function monitoringTowingVehicles(player, v)
	for v, player in pairs(towingVehs) do
		local moveTo = ""
		local _,_,myvehRZ = getElementRotation(v)
		local _,_,towedVRZ = getElementRotation( getPedOccupiedVehicle(player) )--getElementRotation(vbanshee)
		myvehRZ, towedVRZ = math.floor(myvehRZ), math.floor(towedVRZ)
		local rotDiff = ( math.max(myvehRZ, towedVRZ) - math.min(myvehRZ, towedVRZ) )
		--outputChatBox("@rotDiff: "..tostring(rotDiff))
		
		if ( towedVRZ > myvehRZ ) and ( towedVRZ - myvehRZ ) <= 180 then
			moveTo = "left"
		elseif ( towedVRZ > myvehRZ ) and ( towedVRZ - myvehRZ ) > 180 then
			moveTo = "right"
		elseif ( myvehRZ > towedVRZ ) and ( myvehRZ - towedVRZ ) <= 180 then
			moveTo = "right"
		elseif ( myvehRZ > towedVRZ ) and ( myvehRZ - towedVRZ ) > 180 then
			moveTo = "left"
		end
		if rotDiff <= 8 then
			if getControlState( player, "vehicle_right" ) then
				setControlState( player, "vehicle_right", false )
				outputChatBox("right false")
			end
			if getControlState( player, "vehicle_left" ) then
				setControlState( player, "vehicle_left", false )
				outputChatBox("left false")
			end
		elseif moveTo == "left" or moveTo == "right" then
			setControlState( player, "vehicle_" .. moveTo, true )
		end
		--outputChatBox("Mover para: "..moveTo, me, 225, 225, 225)
	end
end

addEventHandler( "onElementDestroy", root,
	function()
		if getElementType(source) == "vehicle" and towingVehs[ source ] then
			local driver = getVehicleController( source )
			if driver then 
				setPlayerVehicleTowing( getVehicleController( getVehicleBeingTowed(source) ), source, false )
			end
		end
	end
)

addEventHandler( "onVehicleExplode", root, 
	function()
		if towingVehs[ source ] then
			local driver = getVehicleController( source )
			if driver then 
				setPlayerVehicleTowing( getVehicleController( getVehicleBeingTowed(source) ), source, false )
			end
		end
	end
)

local SetControlState = setControlState
function setControlState(p, control, state)
	if p and getElementType(p) == "player" and type(control) == "string" and type(state) == "boolean" then
		if getControlState( p, control ) ~= state then
			SetControlState( p, control, state )
		end
	end
end

function doAcellerateVehicle(v, bool)
	local driver = getVehicleController(v)
	if driver then
		if bool and getControlState( driver, "accelerate" ) ~= true then
			setControlState( driver, "accelerate", true )
		elseif bool == false and getControlState( driver, "accelerate" ) ~= false then
			setControlState( driver, "accelerate", false )
		end
	end
end

function getPlayerFromPartialName(name)
    local name = name and name:gsub("#%x%x%x%x%x%x", ""):lower() or nil
    if name then
        for _, player in ipairs(getElementsByType("player")) do
            local name_ = getPlayerName(player):gsub("#%x%x%x%x%x%x", ""):lower()
            if name_:find(name, 1, true) then
                return player
            end
        end
    end
end

--[[
function getNearestVehicle(veh)
	if not (isElement(veh)) then return false end;
	local myVehX, myVehY = getElementPosition(veh)
	local smallestD = 999999
	local nearestVeh
	for i, v in pairs(getElementsByType"vehicle") do
		local vx,vy = getElementPosition(v)
		local _dist = getDistanceBetweenPoints2D(vx,vy,myVehX,myVehY)
		if _dist < smallestD and v ~= veh then
			smallestD = _dist 
			nearestVeh = v
		end
	end
	return nearestVeh or false
end
]]

O guinchamento funciona da seguinte forma:

Você digita o comando guinchar e especifica um nome do jogador no comando (o dono do veículo a ser guinchado).

E o outro jogador deve estar num veículo; esse veículo será guinchado segurando a seta p/ cima. É provável que não esteja da forma que deve funcionar. A parte de clicar num ponto para o veículo ser puxado eu não fiz, se for necessário só falar.

Não testei muita coisa além disso porque só um jogador não dá pra fazer tudo e saber se funciona. Outra coisa, a corda anexada aos veículos eu não fiz (se conseguir encontrar uma textura, ótimo, eu posso adicionar).

 

Link to comment
  • Moderators
5 hours ago, Luiz Filipe said:

Onde coloco esse código?

Leia isto por favor: https://wiki.multitheftauto.com/wiki/PT-BR/Introdução_ao_Scripting

Como mostra na página, só abrir um editor de texto (como o notepad), colar o código e salvar com a extensão .lua (nome_do_script.lua).

O meta.xml precisa ser salvo exatamente com esse nome e extensão: https://wiki.multitheftauto.com/wiki/PT-BR/Introdução_ao_Scripting#Identificando_seu_recurso

Dentro do meta, em script src coloque o nome do script (.lua). Aqui está o meta.xml:

<meta>
	<script src="nome_do_script.lua" type="server" />
</meta>

Salva esses dois dentro duma pasta zipada ou numa pasta padrão (como qualquer resource que você encontra).

Link to comment

ok, muito obrigado pela ajuda

 

19 hours ago, DNL291 said:

Leia isto por favor: https://wiki.multitheftauto.com/wiki/PT-BR/Introdução_ao_Scripting

Como mostra na página, só abrir um editor de texto (como o notepad), colar o código e salvar com a extensão .lua (nome_do_script.lua).

O meta.xml precisa ser salvo exatamente com esse nome e extensão: https://wiki.multitheftauto.com/wiki/PT-BR/Introdução_ao_Scripting#Identificando_seu_recurso

Dentro do meta, em script src coloque o nome do script (.lua). Aqui está o meta.xml:


<meta>	<script src="nome_do_script.lua" type="server" /></meta>

Salva esses dois dentro duma pasta zipada ou numa pasta padrão (como qualquer resource que você encontra).

Pra fazer funcionar é só fazer tipo: /guinchargordo4x4 assim?

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...