Posts by Enzojz

Willkommen in der Transport Fever Community

Welcome to the fan community of Transport Fever and Train Fever, the economic simulators of Urban Games. The community is free for you to share and inform yourself about the game. We cultivate a friendly and objective interaction with each other and our team will be happy to answer any questions you may have.

 

Registration and use is of course free for you.

 

We wish you a lot of fun and hope for active participation.

The Team of the Transport-Fever Community

    with a specific layout?


    Hello dear community! Today I wanted to place the Underground Station in my map when I pressed the left mouse button came this:

    I have activated both the underpass and the shader and everything on the latest version.

    Make sure you have timetable mod update to date.

    It's not necessary be a signal, just assets. Putting a signal on the track in the game actually removes the old track and replace with new ones, put them as assets comes with less problems. But in the API a function to calculate coordinate and vector of a certain point of track is offically missing so I prefer to wait a little.

    Quote

    At first I thought id could be a number. But meanwhile I think I must use a string like you did. Do the "__" mean anything or is it only for you?

    Nothing special, it's a discrimator, just need to be as much as different to possible ones (from other mods and game vanilla ones)


    Quote




    By the way, I'm not so happy with upgradeConstruction as I thought before. The disadvantage is error handling! If an error arises - and there will be errors - it will crash, because it does not handle errors by working around like a proposal does. So I invented a special error handler to cope with this thing. ?( But for this I have to use a proposal structure again. ^^ It's a little redundant, but I found no other way. :/

    Try pcall or xpcall of lua, I don't know if it works but it worth trying

    First in script there are two indepdent environement: gui part and game engine part, they don't have access to each other


    Quote

    I found it, but now I do not know:

    - Where do I get the Id from I have to put in? Can it be my own random Id, e.g. "1" ?

    - The same with the name: Can I use a random name?

    - And which are the params? The only params I know are those of my construction. I think that they are not meant. :/


    The usual way I use guiInit is to send an event to game engine so the game engine process an event at the first cycle of the game.

    I don't know what you refer to "name" and "params", I don't think you need them, since your operation is for all edges on the map.


    Quote


    Deadlocking would be exactly what I want in my special case :love::D - because I want the user to start my mod only one time and then never again unless it will be resetted. So I just tried out the thing with the flag but It does not even work. ^^

    But also when he wants to use it the second time, it won't work.



    Quote


    You may notice that local done is outside of any functions although it is read by them - but in a test it was not stored, neither in the savegame. Up to now I anyway thougt that values would only be stored in the state table being used in the load and save functions? For this reason I even had created a second flag state.selfDestruction which works wonderful inside load and save, but if I remove this and leave the job alone to done as used above, it does not work. :/ This is very interesting ...


    I have never tried other variable name other than state but I suppose the saved things are the thing you return from save function.

    Are you sure that guiInit is not only for initializing GUI elements? I don't have any GUI elements in my script because it works fully independent from the GUI. And I cannot find an example what code I must insert there. :/ I also could not find eventHandle - do you mean handleEvent? Or guiHandleEvent?


    For making update working once I use a done flag which is changed after the first pass. I don't know whether there are any disadvantages.

    guiInit is called when the map is loaded and it's called once. You can find usage of it in my zero height bridge mod.


    If you use flags, you can only use it once, from time to time, since once you set the flag, they are saved in the gamesave.lua, it's loaded at the next load, so you deadlock your code.

    Still the question remains: What is "seed" actually good for? The UG wiki does not really tell ... ;)

    in tpf1 seed was an alternative id, for example if you remove a station then add another at the same place in a short while, they will get a same id but not same seed, but I found it not 100% relaiable and it seems in tpf2 they have changed its meaning

    the load function is to reload data from engine to graphics, so they are called each engine cycle and the data in it is what you returned in save function.


    if you want to execut it once, should sent a event in guiInitHandle and treat it in eventHandle.

    You need to remove seed from the params, for upgradeContrsuction and buildConstruction, i've been doing it since tpf1 and it works always like this

    I don't know if params.seed = nil works sometimes you may get read only variables (not sure) so better to check it before use


    the following code comes from my underground station:


    local pure = function(pa)
        local params = {}
        for key, value in pairs(pa) do
            if (key ~= "seed") then
                params[key] = value
            end
        end
        return params
    end

    local script = {
        handleEvent = function(src, id, name, param)
            if (id == "__musEvent__") then
                if (name == "new") then
                    local id = param.id
                    local e = game.interface.getEntity(id)
                    game.interface.upgradeConstruction(
                        id,
                        "station/rail/mus.con",
                        pure(e.params)
    )
                end
            end
        end,
        guiHandleEvent = function(id, name, param)
            if name == "builder.apply" then
                local toAdd = param.proposal.toAdd
                if toAdd and #toAdd > 0 then
                    for i = 1, #toAdd do
                        local con = toAdd[i]
                        if (con.fileName == [[station/rail/mus_cargo.con]]) then
                            if(con.params.isFinalized == 0) then
                                game.interface.sendScriptEvent("__musEvent__", "new", {id = param.result[1]})
                                game.interface.sendScriptEvent("__underpassEvent__", "new", {id = param.result[1], isStation = true})
                            end
                        end
                    end
                end
            end
        end
    }

    function data()
        return script
    end


    Quote


    So I will go on with the other method and try to find out if and how I could reconnect the nodes. The question is if I am allowed to write directly into some param structures - and which. I think not ... my last chance is to find some examples elsewhere. Otherwise the changing of the constructions is not so important for the things I want to do.

    You may keep the nodes from construction side and rebuild edges from free side and using the nodes from construction side so they should get connected.


    Quote


    [OT] A very simple way to understand my project is to replace the vanilla track types by such with reduced top speed by a mod or a modifier. Now load an old map with already laid tracks. If you press [NUM]-[4] you will see that the top speed has not changed. :(. But if you lay new tracks, you get the right speed for them. So you would have to replace every single laid track by itself. For certain things (like streets with no developement) even the magic wand will not work! :( And this is exactly what I want to have automatized by a mod - but I cannot yet do it for stations, switch modules and so on ... I would be glad if I did not have to write such a difficult mod if the game would at least offer something like the F5-"update"-key in browsers or windows. ;):D If someone could tell me there is a hidden key I would be very happy because then I could program other much more exciting stuff. :S

    More likely a bug of the game, have you reported to UG first?

    I think the decisive one is api.type.SimpleProposal.ConstructionEntity.new(), since in last week replay you showed you constructed a construction proposal in lua, and the transf required in fact is a POD array, you would never get it work. Also the way you assign the playerId was not correct, but it should not be blocking since that just blocks you from editing a construction


    for nodes thing, if in construction node is marked as snapNodes it should catch the neighboring edges (at least it works for game.interface.buildConstruction and game.interface.upgradeConstruction), if you try to modify edges in a construction via api, it will crash (sometimes when your cursors points at it). Normally you should not touche edges in a construction


    The notion of connection is just node, if two edges share the same node they are connected if not they are not connected.


    And I feel disapointed that you didn't do any comment on my last replay, since I took two hours last weekend to find you a working solution and summerize the essential part.


    Doesn't track/street upgrading tool exist in vanilla game? of course you can replace street/tracks without a mod, why do you want to double the function? or you just don't know that exists already?

    I have just made a check in the api, in fact for mdls without bbox they are recalculated and written in the repo, I don't know if at postRunFn stage but at least they do exists in the gameplay.


    You can make a test yourself by printing the data out.

    MaikC - obviously - the entire lod would need to be processed to get a reliable bounding box of a vehicle. For my purposes that would suffice.


    VacuumTube - I can't modify a vehicle in postRunFn, now can I. So even if that worked, then It would, at least, introduce two-stage model loading. Which is very not customer friendly.


    Enzojz - For my purposes I need to read and process the files during mod-loading in runFn. I can write c++ ( actually, I am pro programmer who actually does c++ ), but that would not fit my use-case. Unless I would be willing to off-line process all the mods ever produced for this game.


    Of course you can write in lua but just not that simple since I think in lua you need to use some loop to read each float one by one, but I think you don't have choice since written in c++ means you need to deal with platforms.

    Anyway it's not hard neither, since you are c++ programmer, it should be easy to understand. the data in .msh no more than a table of offset and count to guide to read blob. (read the vertices first then read the indices to find the vertices, it's general 3d data structure which you use in graphics buffer)

    The problem is the efficiency, since you need to read every mesh, apply the transf on every vertex then get the bbox, then sum up with other bbox to get the global bbox of an mdl, I think it will take a lot of time.


    I have F# code of my tpfmc on github, if you understand f# or ocaml or scalar maybe that would help

    TpFMC/Core.fs at master · Enzojz/TpFMC (github.com)


    Also livetext in F#

    LivetextTool/Output.fs at master · Enzojz/LivetextTool (github.com)

    Did some attempt and I succed to remove a station then bring it back via api.


    There are some key things:


    I retrived the old params by:

    Code
    1. params = game.interface.getEntity(id).params

    then create the construction proposal by

    Code
    1. po = api.type.SimpleProposal.ConstructionEntity.new()


    I need also copy the old tranfs by

    Code
    1. co = api.engine.getComponent(id, api.type.ComponentType.CONSTRUCTION)
    2. for i = 1, 16 do
    3. po.transf[i] = co.transf[i]
    4. end

    then create a simple proposal and make the cmd of it then send it


    However, it seems the command is send directly to the updateFn of the construction so you need to change the module table to change things such as number of tracks etc..


    I think the way above is too complicated comparing to game.interface, which you can do thing in the fly, the only drawback is you can call the game.interface functions only from engine loop not gui loop.

    At least you
    can use game.interface.upgradeConstruction and game.interface.bulldoze which comes from tpf1 (and documented in tpf1
    wiki)
    For a removal example of Simple Proposal I did one in track design pattern mod. For modifying or creating, I think it's more or less the same to edges, you just create a similar proposal like what you see in the guievent

    I have developped an FBX model importer during the christmas, which adapts 3dsmax's fbx export. Here I create this thread to let more to know about this.


    Tpf2 FBX Model Converter - Transport Fever Community


    The main advantage of this one is it supports correctly the animation export from 3dsmax, also a correct pivot. It support also the bone export even the automatic vertex weight calculate which is recently introduced in tpf2 for bridges (so seamless bridges)


    Hope you like it.

    If they are not documented, are not in examples, are not stable and do not even use UG themselves, I wonder why they exist at all. :D

    is probably the best variant, but you just can't expect from every modder. And if I have to write a Lib first, I can end up focusing less on the essentials and producing fewer mods.

    Beginner modders will then take the direct format and copy it from the examples, which firstly takes longer and leads to confusion, poor extensibility and higher bug probability.


    I just wanted to do that, there are certain "interface gaps" (as already mentioned with the parameters) with the modding interfaces, which lead to unnecessary overhead. If this is reconsidered in the future, everyone can end up achieving more and creating more mods.

    Some code and resources in the game dates back Train fever, so if you see them not used, that may bacause they were used.

    But the edge principal never changes, I feel the function provided by UG not so handly so I created my own arch lib to process all edges, unless it's really simple by hand.

    After a little trying, I understood the principle. In fact, it can be used to produce .B. curved track segments. This is awesome, you could build .B. finished curves for switches. ;) It is just a pity that there is no plan figure, that would make everything a little more transparent. But I've drawn one now and just ask if ;) that's the right thing to do. The black would be the resulting curve, in magenta the two "handles", i.e. the tangential vectors, are drawn. The endpoints of the vectors, i.e. the second values in the curly brackets, have their axis origin but not in the origin of the construction, but in each of the two start and end points (light green)?? And the next question would be, how long do the vectors have to be in each case, so that I can get a real circle segment that has the same radius at every point, i.e. no klothoids or anything else "Eiriges"?


    The length of the vector is exactly the length the arc, if it's shorter, you get visually an arch but the game will compute as shorter, if it's longer, you get a nested curve

    You will observe this on a bus or a car, take a straight for a test, you can teleport a bus, or make it very slow, by changing the vector length.