Jump to content

picks up the last dropped pickup


kewizzle

Recommended Posts

so i have my drop system i fixed it a while ago then i lost everything in a hard drive wipe and cant seem to fix again but it all works except when i kill multiple zombies and theres multiple drops it only picks up the last dropped item and not the one im standing on heres my script:

outputServerLog ( "***Drop System Loaded   ***" )
local state = {}
local function bindState(player)
	bindKey(player, "l", "down", function(player)
	if isElement(getElementData(player,"pickup")) then
        usePickup(getElementData(player,"pickup"),player)
        removeElementData(player,"pickup")
    end
    end)
end

function getElementsWithinMarker(marker)
	if (not isElement(marker) or getElementType(marker) ~= "marker") then
		return false
	end
	local markerColShape = getElementColShape(marker)
	local elements = getElementsWithinColShape(markerColShape)
	return elements
end

addEventHandler("onResourceStart", resourceRoot, function()
	for _, player in pairs(getElementsByType ("player")) do
		bindState(player)
	end
end)

addEventHandler("onPlayerJoin", root, function()
	bindState(source)
end)

function createDeathPickup ( totalammo, killer, killerweapon, bodypart ) --when a player dies
if ( killer ) then
if ( getElementType ( killer ) == "player" ) then
    x, y, z = getElementPosition ( source ) --get the position of the person who died and define it as x, y and z
    dropped = createPickup ( x, y, z, 2, math.random(22, 34), 15000, math.random(1,3))
	dropmarker = createMarker ( x, y, z-0.5, "cylinder", 1, math.random(1, 255), math.random(1, 255), math.random(1, 255), 255)
	addEventHandler("onPickupHit", dropped, HitPick)
	
	addEventHandler("onMarkerHit", dropmarker, function(player)
		if isElement(player) and getElementType(player) == 'player' then
           setElementData(player,"pickup",dropped)
        end
	end)
    
	setTimer(destroyElement, 15000, 1, dropped) 
	setTimer(destroyElement, 15000, 1, dropmarker) 
	end
end
end
addEventHandler("onPedWasted", getRootElement(), createDeathPickup)

function HitPick ( ) 
    if isElement ( dropped ) then 
        cancelEvent()
    end 
end 

i tried some things i think it may have something to do with my onMarkerHit Handler

Edited by kewizzle
Link to comment

Hello kewizzle!

it looks like there are multiple issues with your script. I don't know why but you are using an inconsistent scripting style. At one point you either are using local variables and at the other you are not. Please refresh yourself on coding best practices!

  1. in lines 34, 35 and 36 you are storing data in global variables x, y, z, dropped and dropMarker that is being overwritten each time the createDeathPickup function is called. I suggest you to use local variables for storage instead.
  2. change the way the HitPick function is defined. You could use the source event variable instead of the dropped global variable to cancel the event. Making it depend on the global variable dropped is a bad idea because it does change each call to createDeathPickup. Imagine what happens if there are multiple death pickups at once: if the last created one gets destroyed then your event handler stops working!
  3. If you are hitting multiple pickups in a short time-interval then only one of the pickups would be stored in the element-data variable "pickup". The player has to leave the pickup marker and re-enter it in order to pickup another thing it is supposedly standing on. This could be annoying to the players. I recommend you to instead use a list of pickups that the player is nearby of.
  4. I suppose that the usePickup function is not able to be triggered twice to get health, guns, etc from the same pickup. You should clean-up the marker after the pickup was taken because it would otherwise still collide with pickups that can be taken. The result is an invisible pickup that prevents the other pickups from being taken. Just like the issues above this could prevent your script from working properly.

Suggestions to further improve the script:

  • make use of the onMarkerLeave function to clear the list of nearby pickups of the pickup that the player is nearby.

Proposed fixes for 1, 2 and 4:

outputServerLog ( "***Drop System Loaded   ***" )
local state = {}
local deathpickups = {};
local function bindState(player)
    bindKey(player, "l", "down", function(player)
        local dropped = getElementData(player,"pickup");
        if isElement(dropped) then
            local pickupInfo = deathpickups[dropped];
            usePickup(dropped,player)
            killTimer(pickupInfo.dtimer);
            destroyElement(pickupInfo.dropped);
            destroyElement(pickupInfo.dropmarker);
            removeElementData(player, "pickup")
            deathpickups[dropped] = nil;
        end
    end)
end

function getElementsWithinMarker(marker)
    if (not isElement(marker) or getElementType(marker) ~= "marker") then
        return false
    end
    local markerColShape = getElementColShape(marker)
    local elements = getElementsWithinColShape(markerColShape)
    return elements
end

addEventHandler("onResourceStart", resourceRoot, function()
    for _, player in pairs(getElementsByType ("player")) do
        bindState(player)
    end
end)

addEventHandler("onPlayerJoin", root, function()
    bindState(source)
end)

function createDeathPickup ( totalammo, killer, killerweapon, bodypart ) --when a player dies
    if ( killer ) then
        if ( getElementType ( killer ) == "player" ) then
            local x, y, z = getElementPosition ( source ) --get the position of the person who died and define it as x, y and z
            local dropped = createPickup ( x, y, z, 2, math.random(22, 34), 15000, math.random(1,3))
            local dropmarker = createMarker ( x, y, z-0.5, "cylinder", 1, math.random(1, 255), math.random(1, 255), math.random(1, 255), 255)
            addEventHandler("onPickupHit", dropped, HitPick)

            addEventHandler("onMarkerHit", dropmarker, function(player)
                if isElement(player) and getElementType(player) == 'player' then
                    setElementData(player,"pickup",dropped)
                end
            end)

            local dtimer = setTimer(function()
                if (getElementData(player, "pickup") == dropped) then
                    setElementData(player, "pickup", nil);
                end
                destroyElement(dropped);
                destroyElement(dropmarker);
                deathpickups[dropped] = nil;
            end, 15000, 1)
            
            local info = {};
            info.dtimer = dtimer;
            info.dropped = dropped;
            info.dropmarker = dropmarker;
            deathpickups[dropped] = info;
        end
    end
end
addEventHandler("onPedWasted", getRootElement(), createDeathPickup)

function HitPick ( ) 
    -- you don't have to check the source parameter if you just plan to check if it is an element.
    cancelEvent()
end 
Edited by The_GTA
  • Thanks 1
Link to comment
12 hours ago, The_GTA said:

Wow, that is a long time ago! I am happy to see you come back to MTA scripting. It sure is fun ?

okay so buddy check this out i tried to do the same with my 3DText but it doesnt work properly i want them to destroy with weapons but i had to put it on client side also i removed what i tried cuz it didnt work i tried to use a table and your dtimer example again

client

function pickupT()
local x, y, z = getElementPosition ( localPlayer )
    chicken = call(getResourceFromName("texts"), "dxDraw3DText", "Press 'L' to pickup!", x, y, z, 2, "default", 255, 0, 255 )
end
addEvent( "pickuptxt", true )
addEventHandler( "pickuptxt", localPlayer, pickupT )

server

            addEventHandler("onMarkerHit", dropmarker, function(player)
                if isElement(player) and getElementType(player) == 'player' then
				triggerClientEvent("pickuptxt", player)
                    setElementData(player,"pickup",dropped)
                end
            end)

 

Edited by kewizzle
Link to comment
1 hour ago, kewizzle said:

nvm i got it to work using 

dxDrawTextOnElement

Judging from the code above, you are once again using one global variable that would be overwritten multiple times in an event handler, called "chicken". I hope you will not do that again and instead store such things in lists instead.

You have not yet fixed the pickup issue that I mentioned as point number 3.

Other than that, happy to see you scripting around. ?

  • Thanks 1
Link to comment
11 hours ago, The_GTA said:

Judging from the code above, you are once again using one global variable that would be overwritten multiple times in an event handler, called "chicken". I hope you will not do that again and instead store such things in lists instead.

You have not yet fixed the pickup issue that I mentioned as point number 3.

Other than that, happy to see you scripting around. ?

HAHAHA aye everything is working i just rescripted it it was apart of the 2017 version. its looking good.

spacer.png

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