Jump to content

Train System?


jkub

Recommended Posts

I and another developer are working on a train system for my server and I have really gotten fed up with the failures I've encountered. I can get the train to move and even at a constant speed no problem. But I place markers at each station so when they are hit the train stops, problem is the markers never detect the trains. I'm thinking this is because a client event is used to move the train (setPedControlState) for a ped I place in the train.

The big problem is that the train never seems to hit the markers at each station.

Later on I really scrutinized the script (for hours) and this is what I thought could be the problem.

The train moves on everyones screen but to the server the train never moves (I verified this by checking the position and area name of where the train is every several seconds and it always returns where the train started).

I completely trashed and restarted the scripts 3 times now and I'm no further then I was before. Please I need some ideas on how to structure the script. I already have all the station locations and settings inside an xml file, but I need to know things like rather or not to make the train, vehicle and ped server or client side. Rather I need to use collision spheres or markers to detect the trains, or rather I should make the cols or markers client or server. Please someone with great scripting knowledge step forward I am about to tear my face off.

I'm not asking for spoon fed code, I just want some answers and some help please.

Thanks.

EDIT: Here is some starting initiating code that I am using server side to load up all the information from the xml file.

stations = {} 
options = {} 
  
function onResourceStart() 
    --]] 
    configFile = xmlLoadFile ( "train settings.xml" ) 
    stationMasterNode = xmlFindChild ( configFile, "stations", 0 ) 
    optionMasterNode = xmlFindChild ( configFile, "options", 0 ) 
    --]] 
    stationNodes = xmlNodeGetChildren ( stationMasterNode ) 
    optionNodes = xmlNodeGetChildren ( optionMasterNode ) 
    --]] 
    for i, optionNode in ipairs ( optionNodes ) do 
        local nodeName = xmlNodeGetName ( optionNode ) 
        if nodeName == "tickets" then 
            options["tickets"] = xmlNodeGetAttribute ( optionNode, "price" ) 
        elseif nodeName == "times" then 
            options["times"] = xmlNodeGetAttribute ( optionNode, "station_wait_time" ) 
        elseif nodeName == "init" then 
            options["init"] = xmlNodeGetAttribute ( optionNode, "start_station" ) 
        elseif nodeName == "train" then 
            options["train"] = xmlNodeGetAttribute ( optionNode, "maxSpeed" ) 
        end 
    end 
    for i, stationNode in ipairs ( stationNodes ) do 
        stations[i] = {} 
        stations[i].x = xmlNodeGetAttribute ( stationNode, "x" ) 
        stations[i].y = xmlNodeGetAttribute ( stationNode, "y" ) 
        stations[i].z = xmlNodeGetAttribute ( stationNode, "z" ) 
        stations[i].name = xmlNodeGetAttribute ( stationNode, "name" ) 
        stations[i].col = createColSphere ( stations[i].x, stations[i].y, stations[i].z, 25 ) 
        stations[i].blip = createBlipAttachedTo ( stations[i].col, 58, 2, 255, 255, 255, 255, 0, 250, getRootElement() ) 
        stations[i].id = i 
    end 
end 
  
addEventHandler ( "onResourceStart", getResourceRootElement ( getThisResource() ), onResourceStart ) 

Link to comment

Well, it depends on what you want to achieve

If you want it fully synced then everything should be done serverside

As a consequence, you won't be able to use setPedControlState anymore. I suggest: https://wiki.multitheftauto.com/wiki/SetElementSpeed

Example: set the element speed to 40 km/h and with a timer every 1000 ms, check that the speed is still 40 and if it's not, apply it again (https://wiki.multitheftauto.com/wiki/GetElementSpeed)

When it hits the serverside colshapes @ stations, simply decrease the speed until it's fully stopped

Link to comment

Thanks for the suggestion. We want it to be an automated train system that players can use for transportation.

I never seen that setElementSpeed function before, I'm sure it will be useful. I've been making the train cruise at a certain speed by using code tooken from my cruise control script.

I will reply back later on how it turns out.

Link to comment

I have something going now but the big problem now is that the train actually doesn't start moving until a player is close by to sync it. I tried using setElementSyncer but that does nothing. I tried using setElementStreamable client side but that doesn't fix it either.

Link to comment
I have something going now but the big problem now is that the train actually doesn't start moving until a player is close by to sync it. I tried using setElementSyncer but that does nothing. I tried using setElementStreamable client side but that doesn't fix it either.

How do you expect help without posting any code?

We have no idea what you did there, or if it's correct at all.

Link to comment

setElementSyncer can only set syncer who is near enough to the element. So you need to sync it yourself. You can send train position data from client to server using triggerServerEvent and use that data server-side to set position of the train. Train will need to be always synced for the syncing player, so don't forget to use setElementStreamable.

Link to comment

do I need to sync the cols too?

some server code

function onColShapeHit ( hitElement ) 
    if hitElement == train["engine"] then 
        for i, station in ipairs ( stations ) do 
            if source == stations[i].col then 
                if speedWatcher then killTimer ( speedWatcher ) speedWatcher = nil end 
                setTrainSpeed ( train["engine"], 0 ) 
                setTimer ( setTrainSpeed, options["times"], 1, train["engine"], 0.1 )  
                speedWatcher = setTimer ( checkTrainSpeed, 1000, 0 ) 
                outputChatBox ( "Departing "..stations[i].name.." shortly...", getRootElement(), 0, 255, 0 ) 
            end 
        end 
        for i, player in ipairs ( getElementsByType ( "player" ) ) do 
            triggerClientEvent ( player, "sync_train", player, train ) 
        end 
    end 
end 
  
function client_callTrainSync() 
    triggerClientEvent ( client, "sync_train", client, train ) 
    for k, station in ipairs ( stations ) do 
        triggerClientEvent ( client, "sync_cols", client, stations[k].col, client ) 
    end 
end 

some client code

addEvent ( "sync_train", true ) 
addEvent ( "sync_cols", true ) 
  
function onClientResourceStart() 
    triggerServerEvent ( "client_callTrainSync", getLocalPlayer() ) 
end 
  
function sync_train ( trainTable, stations ) 
    setElementStreamable ( trainTable["engine"], false ) 
end 
  
function sync_cols ( col, player ) 
    setElementStreamable ( col, player ) 
end 
  
addEventHandler ( "sync_train", getRootElement(), sync_train ) 
addEventHandler ( "onClientResourceStart", getResourceRootElement ( getThisResource() ), onClientResourceStart ) 
addEventHandler ( "sync_cols", getRootElement(), sync_cols ) 

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