News:

Want to praise Simutrans?
Your feedback is important for us ;D.

[DONE] Control the vehicles in the depot.

Started by Yona-TYT, January 07, 2017, 05:26:25 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Yona-TYT

It would be nice to have a function that looks like "is_schedule_allowed (pl, schedule)", but to control the vehicles that start from  the deposit.

A example is:
is_vehicle_allowed (pl){
    return result = is_vehicle_correct(pl, vehicle_name, load, station_nr)
}

Dwachs

You want to restrict vehicles for a certain player? That is certainly possible.
Parsley, sage, rosemary, and maggikraut.

Yona-TYT

Quote from: Dwachs on January 08, 2017, 10:04:18 AM
You want to restrict vehicles for a certain player? That is certainly possible.
I'm afraid it's not very useful for the tutorial.

The type of load is more useful. Something like "vehicle.accepts_good.good_desc_x (load_type)"

Yona-TYT

I have created a code that allows to check the vehicles in the deposit, I use it with the function "is_schedule_allowed" to prevent the vehicle from leaving the deposit, but I need to check "is_schedule_allowed" when pressing the "start" button so that my Code may function correctly.

I can think of something like this: (1025 in /gui/depot_frame.cc)
   
             if ( scenario_check_schedule(welt, player, schedule, can_use_gui()) )
                    depot->call_depot_tool( tool, cnv, NULL);


You can test here:
Scenario: Tutorial-test3.zip
Savegame: test3.sve

Code to check vehicles:
    function is_convoy_correct(p_depot,cov,veh,good_nr,name)
    {
        local depot  = depot_x(p_depot.x, p_depot.y, p_depot.z)
        local cov_list = depot.get_convoy_list()
        local cov_nr = cov_list.len()
        //Check if there is a convoy
        if (cov_nr==0){
            glcov_name = ""
            return 0
        }
        //Check the number of convoys
        if (cov_nr!=cov)
            return 1
        if (glcov_name==""){
            glcov_name = cov_list[cov-1].get_name()
            persistent.glcov_name = glcov_name
        }

        //To check the name of the locomotive
        local name1_nr = glcov_name.len()
        local name2_nr = name.len()
        if (name2_nr>name1_nr)
            return 2
        local cha = (name1_nr - name2_nr)
        local count = 0
        for(local j=cha;j<name1_nr;j++){
            if (glcov_name[j]!=name[count])
                return 3
            count++
        }
       
        //Check the number of vehicles   
        local veh_nr = cov_list[cov-1].get_vehicles().len()
        if (veh_nr!=veh)
            return 4

        //Check load type
        local good = cov_list[cov-1].get_goods_catg_index()       
        for(local j=0;j<good.len();j++){
            if(good[j]!=good_nr)
                return 5
        }
        return null
    }

//Call
    function is_schedule_allowed(pl, schedule) {
        local result=null    // null is equivalent to 'allowed'
        if ((pl==0)&&(this.step==5)) {

            glcov_name = ""
            persistent.glcov_name = glcov_name

            local p_depot = coord3d(66, 36, -1)
            local cov = 1
            local veh = 10
            local good_nr = 11 //granos
            local name = "EMD-FT"
            result = is_convoy_correct(p_depot,cov,veh,good_nr,name)
            if (result!=null){
                gcount = 0
                reset_glsw()
                if (result==0)
                    return format(translate("You must first buy a locomotive [%s]"),name)

                if (result==1)
                    return translate("Only one train is allowed, press the [Sell] button")

                if (result==2)
                    return 2

                if (result==3)
                    return format(translate("Must choose a locomotive [%s]"),name)

                if (result==4)
                    return format(translate("The number of wagons must be [%d]"),veh-1)

                if (result==5)
                    return translate("All wagons must be for [Grains]")
            }
}


Dwachs

I think it would be better to create a method named is_convoy_allowed, which is called when before convoy is started.
Parsley, sage, rosemary, and maggikraut.

Yona-TYT

Quote from: Dwachs on April 18, 2017, 07:22:56 PM
I think it would be better to create a method named is_convoy_allowed, which is called when before convoy is started.

I already did, check in my github account: https://github.com/Yona-TYT/TYT-Simutrans/commits/master


Yona-TYT


I only need this to be able to release the tutorial v4.  8)

Yona-TYT

Quote from: Yona-TYT on April 18, 2017, 07:40:16 PM
I already did, check in my github account: https://github.com/Yona-TYT/TYT-Simutrans/commits/master


Maybe it is necessary to change something ?. ???

gui/depot_frame.cc

+#include "../dataobj/scenario.h"

             if(  cnv.is_bound()  ) {
                 //first: close schedule (will update schedule on clients)
                 destroy_win( (ptrdiff_t)cnv->get_schedule() );
                 // only then call the tool to start
                 char tool = event_get_last_control_shift() == 2 ? 'B' : 'b'; // start all with CTRL-click
-                depot->call_depot_tool( tool, cnv, NULL);
+                scenario_t *scen = welt->get_scenario();
+                player_t *player = welt->get_active_player();
+                if ( scen->scenario_check_convoy(welt,  player, true) )
+                    depot->call_depot_tool( tool, cnv, NULL);
             }


====================================================================================================================

dataobj/scenario.h

+   
+    /**
+     * Checks if  convoy in the depot is correct.
+     *
+     * @param player player
+     *
+     * @return null if allowed, an error message otherwise
+     */
+    const char* is_convoy_allowed(const player_t* player);
+   
+    bool scenario_check_convoy(karte_t *welt, const player_t* player, bool local);


====================================================================================================================

dataobj/scenario.cc

+#include "../gui/messagebox.h"

+#define is_scenario()  welt->get_scenario()->is_scripted()

+bool scenario_t::scenario_check_convoy(karte_t *welt, const player_t* player, bool local)
+{
+    if (!is_scenario()) {
+        return true;
+    }
+    const char* err = welt->get_scenario()->is_convoy_allowed(player);
+    if (err) {
+        if (*err  &&  local) {
+            koord pos = message_t::get_coord_from_text(err);
+            if (pos != koord::invalid) {
+                create_win( new news_loc(err, pos), w_time_delete, magic_none);
+            }
+            else {
+                create_win( new news_img(err), w_time_delete, magic_none);
+            }
+        }
+        return false;
+    }
+    return true;
+}
+
+const char* scenario_t::is_convoy_allowed(const player_t* player)
+{
+
+    if (env_t::server) {
+        // networkgame: allowed
+        return NULL;
+    }
+    // call script
+    if (what_scenario == SCRIPTED) {
+        static plainstring msg;
+        const char *err = script->call_function(script_vm_t::FORCE, "is_convoy_allowed", msg, (uint8)(player  ?  player->get_player_nr() : PLAYER_UNOWNED));
+
+        return err == NULL ? msg.c_str() : NULL;
+    }
+    return NULL;
+}
+

====================================================================================================================

script/api/api_skeleton.cc

+/**
+ * Called when a convoy is started from the depot.
+ *
+ * @warning Function will NOT be called in network games.
+ *
+ * @param pl player number
+ *
+ * @return null if allowed, an error message otherwise
+ * @typemask string(integer)
+ * @ingroup scen_skel
+ * @ingroup quick_return_func
+ */
+register_function("is_convoy_allowed");
+

====================================================================================================================

simutrans/script/scenario_base.nut

+function is_convoy_allowed(pl)
+{
+    return null
+}

Yona-TYT


Dwachs

Sorry, did not have much time to work on this. I do not understand your choice of parameter of the is_convoy_allowed function: I would expect that this function gets at least the convoy in question as argument. Something like

is_convoy_allowed(player, convoy, depot)
Parsley, sage, rosemary, and maggikraut.

Dwachs

This is now in r8222: When player wants to start convoy at depot the method

is_convoy_allowed(pl, cnv, depot)

is called. See http://dwachs.github.io/simutrans-sqapi-doc/group__quick__return__func.html#gac19c629dee5fbff4680ffe0ffde000fd
Parsley, sage, rosemary, and maggikraut.

Yona-TYT

I've tried it and it works very well, thank you very much ... now I can continue with the tutorial.  ;D ;D ;D

Yona-TYT

@Dwachs
A little detail, when I press [Ctrl] +  button [Start] does not show any message.  ???

Dwachs

That is true. This is the same behavior as if you ctrl+click on [start] and have vehicles without schedule in the depot.

Parsley, sage, rosemary, and maggikraut.

Yona-TYT

It would be nice to display the vehicle image in the popup window.  ;D ;D ;D