Although in those 20+ years, sometimes something gets added. You can actually build individual buildings now, although it's not the same as zoning for Res/Com/Ind and wathing the cities grow. But I will often play in -freeplay mode and use it as a sort of virtual railroad layout, and my goal is to make fun freeways, but also to transport as many goods/passengers as I can (regardless of profit). heh.
// 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;
}
Quote from: Aureus on February 24, 2026, 06:04:22 AMBut I found no text for pak choosing interface or SettingsIt is not possible to show translated texts in the "pak choosing interface"because it is no language selected at this state of the program.
Parsed simuconf.tab for directory layout; multiuser = 1
Pak found: pak192.comic-extended/
FATAL ERROR: obj_reader_t::resolve_xrefs() - cannot resolve 'GOOD-deceased'
Aborting program execution ...
For help with this error or to file a bug report please see the Simutrans forum at
https://forum.simutrans.com
Aborted (core dumped)
