News:

Simutrans Sites
Know our official sites. Find tools and resources for Simutrans.

pipette tool update request: pick way, pick tram-way

Started by poppo, February 13, 2026, 09:29:40 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

poppo

Pipette tool is one of the wonderful tool to build!
However, we pick only the surface object, so we cannot get object at the base of each ground, especially way or tram-way.
So, I request 2 things:
  • when ctrl key pressed: we get way info if there is (no check halt,roadsign,wayobj)
  • when shift key pressed: we get way_nr(1)'s object (wayobj or way) info if there is (tram_track, crossing etc.)
when we press both ctrl and shift, we can get way_nr(1)'s way.

If you want to test this tool-request, please play OTRPatch v51_2 https://github.com/teamhimeh/simutrans/releases/tag/v51_2

Yona-TYT

It's strange that @prissi didn't reply to this post, perhaps she didn't see it. I hope this message serves as a reminder.  ;)

prissi

There was no patch and I am very stressed with other things right now. Such an expert feature can go in, but I will not dig out the code for that

poppo

// create tool for object under the cursor
const char *tool_pipette_t::work(player_t *pl, koord3d pos)
{
    static cbuffer_t param_str;

    const grund_t *gr = welt->lookup(pos);
    if (!gr) {
        return NULL;
    }

    select_and_check(tunnel_t)
    select_and_check(bruecke_t)

    if (!gr->get_weg_nr(0)||!is_ctrl_pressed()) {
        if (gebaeude_t* gb = gr->find<gebaeude_t>()) {
            if (const char *err = allow_tool_check(gb, gb->get_tile()->get_desc(), pl)) {
                return err;
            }
            const building_desc_t* desc = gb->get_tile()->get_desc();
            if (!pl->is_public_service()) {
                // since we are not allowed to create public infrastructure as normal player, we must forbid this too
                if (desc->is_city_building()  ||  desc->is_attraction()  ||  desc->is_townhall()  ||  desc->is_monument()) {
                    return "Not allowed to copy object.";
                }
            }
            else {
                if (desc->is_depot()  ||  desc->is_headquarters()  ||  desc->is_townhall()) {
                    return "Not allowed to copy object.";
                }
            }
            // here on factories, monuments, town halls, city buildings and more
            if (gb->get_fabrik()) {
                static tool_build_factory_t t = tool_build_factory_t();
                param_str.clear();
                param_str.printf("%i%i%i,%s",
                    1, // with climate
                    gb->get_tile()->get_layout(), /*rotation*/
                    gb->get_fabrik()->get_base_production(),
                    gb->get_fabrik()->get_desc()->get_name());
                t.set_default_param(param_str);
                t.cursor = tool_t::general_tool[TOOL_BUILD_FACTORY]->cursor;
                welt->set_tool(&t, pl);
                return NULL;
            }
            else if (desc->is_attraction()  ||  desc->is_city_building()) {
                static tool_build_house_t t = tool_build_house_t();
                t.cursor = tool_t::general_tool[TOOL_BUILD_HOUSE]->cursor;
                param_str.clear();
                param_str.printf("0%d%s",
                    gb->get_tile()->get_layout(), /*rotation*/
                    gb->get_tile()->get_desc()->get_name());
                t.set_default_param(param_str);
                welt->set_tool(&t, pl);
                return NULL;
            }
            else if (tool_t* t = gb->get_tile()->get_desc()->get_builder()) {
                welt->set_tool(t, pl);
                return NULL;
            }
            return "Not allowed to copy object.";
        }
    }

    if (!is_ctrl_pressed()) {
        // we do not check depot if ctrl pressed(ctrl -> get way info directly)
        if (depot_t *depot=gr->get_depot()) {
            if (pl->is_public_service()) {
                return "Not allowed to copy object.";
            }
            tool_t* t = depot->get_tile()->get_desc()->get_builder();
            welt->set_tool(t, pl);
            return NULL;
        }
    }

    if (gr->get_weg_nr(1)&&is_shift_pressed()) {
        // we check weg_nr(1) only when shift pressed
        if(!is_ctrl_pressed()) {
            // signals > wayobjs > ways
            // if ctrl pressed, we only see way.
            select_and_check(signal_t);
            select_and_check(roadsign_t);
            if(gr->get_wayobj(gr->get_weg_nr(1)->get_waytype())){
                  if(tool_t *wayobj_builder = gr->get_wayobj(gr->get_weg_nr(1)->get_waytype())->get_desc()->get_builder()) {
                    if (const char* err = allow_tool_check(gr->get_wayobj(gr->get_weg_nr(1)->get_waytype()), gr->get_wayobj(gr->get_weg_nr(1)->get_waytype())->get_desc(), pl)) {
                        return err;
                    }
                    welt->set_tool(wayobj_builder, pl);
                    return NULL;
                }
            }
        }
        if (tool_t *way_builder = gr->get_weg_nr(1)->get_desc()->get_builder()) {
            if (const char* err = allow_tool_check(gr->get_weg_nr(1), gr->get_weg_nr(1)->get_desc(), pl)) {
                return err;
            }
            welt->set_tool(way_builder, pl);
            return NULL;
        }
        return "Not allowed to copy object.";
        // here on rivers and city roads
    }

    if (gr->get_weg_nr(0)) {
        if(!is_ctrl_pressed()) {
            // signals > wayobjs > ways
            // if ctrl pressed, we only see way.
            select_and_check(signal_t);
            select_and_check(roadsign_t);
            select_and_check(wayobj_t);
        }
        if (tool_t *way_builder = gr->get_weg_nr(0)->get_desc()->get_builder()) {
            if (const char* err = allow_tool_check(gr->get_weg_nr(0), gr->get_weg_nr(0)->get_desc(), pl)) {
                return err;
            }
            welt->set_tool(way_builder, pl);
            return NULL;
        }
        return "Not allowed to copy object.";
        // here on rivers and city roads
    }

    select_and_check(leitung_t);
    if (gr->find<senke_t>()  ||  gr->find<pumpe_t>()) {
        // missing: check for ownership
        welt->set_tool(tool_t::general_tool[TOOL_TRANSFORMER], pl);
        return NULL;
    }

    if (baum_t* b = gr->find<baum_t>()) {
        static tool_plant_tree_t t;
        param_str.clear();
        param_str.printf("%i%i,%s", 1, 0, b->get_desc()->get_name());
        t.set_default_param(param_str);
        t.cursor = tool_t::general_tool[TOOL_PLANT_TREE]->cursor;
        welt->set_tool(&t, pl);
        return NULL;
    }

    if (groundobj_t* b = gr->find<groundobj_t>()) {
        if (pl->is_public_service()) {
            static tool_plant_groundobj_t t;
            param_str.clear();
            param_str.printf("%i%i,%s", 1, 0, b->get_desc()->get_name());
            t.set_default_param(param_str);
            t.cursor = tool_t::general_tool[TOOL_PLANT_GROUNDOBJ]->cursor;
            welt->set_tool(&t, pl);
            return NULL;
        }
    }

    return gr->obj_count()>0 ? "Not allowed to copy object." : NULL;
}