Jump to content

RC mode script causes network troubles for clients


Mini-Me

Recommended Posts

Hello MTA community,

some weeks ago I started to write a gamemode for SA-MP, that should port a singleplayer modification to a multiplayer experience. However once I got to the point where I had to code animated objects in, I noticed SA-MP didn't suit my needs and took a look at MTA:SA. And wow, I've been pretty amazed. It seemed to be a multiplayer modification for GTA:SA that's more solid than SA-MP. Also the Lua scripting seemed more modern to me than SA-MP's Pawn coding. So I now coded what I already had in SA-MP, the object animation is working just fine, and went further. However, now I ran into a different issue:

I need to code an RC mode and checked MTA's wiki for useful functions. However, I didn't find any, so I coded a workaround:

The player is made invisible, put in the car and in his original spot a dummy ped is created. On that ped I loop a function recursively via a timer to copy his health over to the actual player, in case the dummy ped gets hurt.

This works fine if I try to play it locally on my own server, but once other people try to do that the problems begin:

I see them getting into RC mode just normally, however they only drive straight without steering. Then, after some meters the car disappears and it takes some time till it reappears in the place where the dummy also is. And after some more time both, player and car reappear in the spots they have been before.

The other player sees himself driving fine, until the message "*network troubles*" appears on his screen. See an example of that happening in this video:

Now here's the code I scripted for this:

lastVehicleDriven = {} 
function saveLastVehicleDriven(thePlayer, seat, jacker) 
    lastVehicleDriven[thePlayer] = source 
end 
addEventHandler("onVehicleExit", getRootElement(), saveLastVehicleDriven) 
  
rcDummy = {} 
function enterRcMode(keyPresser, key, keyState) 
    if not getPedOccupiedVehicle(keyPresser) and isElement(lastVehicleDriven[keyPresser]) then 
        if not isVehicleBlown(lastVehicleDriven[keyPresser]) and (getElementDimension(keyPresser) == getElementDimension(lastVehicleDriven[keyPresser])) then 
            local posX, posY, posZ = getElementPosition(keyPresser) 
            local rotX, rotY, rotZ = getElementRotation(keyPresser) 
            local dimension = getElementDimension(keyPresser) 
            local playerModel = getElementModel(keyPresser) 
            local health = getElementHealth(keyPresser) 
            setPlayerNametagShowing(keyPresser, false) 
            local r, g, b, a 
            local elements = getAttachedElements(keyPresser) 
            if elements then 
                for k,v in ipairs(elements) do 
                    if (getElementType(v) == "blip") then 
                        r, g, b, a = getBlipColor(v) 
                        destroyElement(v) 
                    end 
                end 
            end 
            local driver = getVehicleOccupant(lastVehicleDriven[keyPresser], 0) -- move the driver to the passenger seat, the car can be "jacked" with the RC 
            local passenger = getVehicleOccupant(lastVehicleDriven[keyPresser], 1) -- if there already is someone in the passengerseat just let MTA kick the driver out of the car 
            if driver and not passenger then 
                warpPedIntoVehicle(driver, lastVehicleDriven[keyPresser], 1) 
            end 
            warpPedIntoVehicle(keyPresser, lastVehicleDriven[keyPresser], 0) 
            setElementAlpha(keyPresser, 0) 
            giveWeapon(keyPresser, 0, 0, true) -- if the player has an SMG it would poke out of the window, we don't want that 
            rcDummy[keyPresser] = createPed(playerModel, posX, posY, posZ) 
            setElementRotation(rcDummy[keyPresser], rotX, rotY, rotZ) 
            setElementDimension(rcDummy[keyPresser], dimension) 
            setElementHealth(rcDummy[keyPresser], health) 
            giveWeapon(rcDummy[keyPresser], 40, 0, true) -- give the dummy ped the remote control 
            observeRcDummy(rcDummy[keyPresser], keyPresser) 
            createBlipAttachedTo(rcDummy[keyPresser], 0, 2, r, g, b, a) 
        end 
    end 
end 
  
function observeRcDummy(rcDummy, assignedPlayer) 
    if isElement(rcDummy) and isElement(assignedPlayer) then 
        local health = getElementHealth(rcDummy) 
        setElementHealth(assignedPlayer, health) -- if the dummy gets hurt, hurt the player it belongs to 
        if not (getElementDimension(rcDummy) == getElementDimension(assignedPlayer)) then 
            exitRcMode(assignedPlayer) -- end RC mode if the dummy and the player it belongs to go to different dimensions. Players can easily switch dimensions on our server 
        end 
        setTimer(observeRcDummy, 100, 1, rcDummy, assignedPlayer) -- loop this until the dummy or the car disappear 
    end 
end 
  
function isPlayerInRcMode(thePlayer) 
    if isElement(rcDummy[thePlayer]) then-- and getPedOccupiedVehicle(thePlayer) then 
        return true 
    end 
    return false 
end 
  
function exitRcMode(keyPresser, key, keyState) 
    if isPlayerInRcMode(keyPresser) then 
        local rotX, rotY, rotZ = getElementRotation(rcDummy[keyPresser]) 
        local posX, posY, posZ = getElementPosition(rcDummy[keyPresser]) 
        local dimension = getElementDimension(rcDummy[keyPresser]) 
        local r, g, b, a 
        local elements = getAttachedElements(rcDummy[keyPresser]) 
        if elements then 
            for k,v in ipairs(elements) do 
                if (getElementType(v) == "blip") then 
                    r, g, b, a = getBlipColor(v) 
                    destroyElement(v) 
                end 
            end 
        end 
        destroyElement(rcDummy[keyPresser]) 
        removePedFromVehicle(keyPresser) 
        getElementRotation(keyPresser, rotX, rotY, rotZ) 
        setElementPosition(keyPresser, posX, posY, posZ) 
        setElementDimension(keyPresser, dimension) 
        setElementAlpha(keyPresser, 255) 
        setPlayerNametagShowing(keyPresser, true) 
        createBlipAttachedTo(keyPresser, 0, 2, r, g, b, a) 
    end 
end 
  
function joinHandler() 
    spawnPlayer(source, 1959.55, -1714.46, 17) 
    fadeCamera(source, true) 
    setCameraTarget(source, source) 
    bindKey(source, "r", "down", enterRcMode) 
    bindKey(source, "enter_exit", "down", exitRcMode) 
end 
addEventHandler("onPlayerJoin", getRootElement(), joinHandler) 

Other resources I have running with this are the following:

admin, ajax, defaultstats, helpmanager, joinquit, killmessages, mapcycler, mapmanager, parachute, playerblips, resourcebrowser, resourcemanager, scoreboard, spawnmanager, votemanager, webadmin

They are in their default state as they come with MTA:SA.

Soo, can anybody help me out and tell me why it is doing that to us?

Link to comment

Hm, that's an unusual bug, won't be an easy fix I guess. It sounds like a clientside bug, but you're running it serverside.

Try removing all non-essential code, like creating dummy/destroying the blip/passenger part/health sync, and test it again.

Option 2: instead of moving the player in the vehicle and creating a dummy ped, you could do/try it the other way around. Put a ped in the vehicle, and make it remote controlled. The_GTA made a script for that a while ago. (It's for controlling other players, but that shouldn't be a problem since players are ped's)

Link to comment
Hm, that's an unusual bug, won't be an easy fix I guess. It sounds like a clientside bug, but you're running it serverside.

Try removing all non-essential code, like creating dummy/destroying the blip/passenger part/health sync, and test it again.

Option 2: instead of moving the player in the vehicle and creating a dummy ped, you could do/try it the other way around. Put a ped in the vehicle, and make it remote controlled. The_GTA made a script for that a while ago. (It's for controlling other players, but that shouldn't be a problem since players are ped's)

Players are peds, but peds are not players.

Link to comment

It appears that the quite short time interval of the timer struggled the server. As soon as I commented out the call of the observeRcDummy function the network troubles stopped appearing. I now increased the time interval and it seems to work better.

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