Where is rock placement defined?

Forum for technical discussions regarding development. If you have a general suggestion, problem or comment, please use one of the other forums.

Moderator: OpenTTD Developers

Post Reply
Gigigonzalez
Engineer
Engineer
Posts: 91
Joined: 12 Jun 2014 14:24

Where is rock placement defined?

Post by Gigigonzalez »

Hi all.

Ive been searching through the source files for an hour but so far i havent got a clue where the rock tiles are generated upon map generation. Anyone have some pointers?

Thanks!
User avatar
planetmaker
OpenTTD Developer
OpenTTD Developer
Posts: 9432
Joined: 07 Nov 2007 22:44
Location: Sol d

Re: Where is rock placement defined?

Post by planetmaker »

I doubt many, if anyone, knows where something is in the source by heart. It's always a matter of effectively finding it. So this is how I find the place where things are done: Let's search the whole source for 'rock', ignoring subdirs for now:

Code: Select all

~/ottd/trunk> grep -i 'rock' src/*
src/clear_cmd.cpp:		PR_CLEAR_ROCKS,
src/clear_cmd.cpp:		case CLEAR_ROCKS:
src/clear_cmd.cpp:			DrawGroundSprite(SPR_FLAT_ROCKY_LAND_1 + SlopeToSpriteOffset(ti->tileh), PAL_NONE);
src/clear_cmd.cpp:	SetGeneratingWorldProgress(GWP_ROUGH_ROCKY, gi + i);
src/clear_cmd.cpp:		IncreaseGeneratingWorldProgress(GWP_ROUGH_ROCKY);
src/clear_cmd.cpp:	/* add rocky tiles */
src/clear_cmd.cpp:		IncreaseGeneratingWorldProgress(GWP_ROUGH_ROCKY);
src/clear_cmd.cpp:				SetClearGroundDensity(tile, CLEAR_ROCKS, 3);
src/clear_cmd.cpp:	STR_LAI_CLEAR_DESCRIPTION_ROCKS,
src/clear_map.h:	CLEAR_ROCKS  = 2, ///< 3
src/disaster_cmd.cpp: * 1: If within 15 tiles, fire away rockets and destroy industry
src/economy_type.h:	PR_CLEAR_ROCKS,
src/genworld.h:	GWP_ROUGH_ROCKY, ///< Make rough and rocky areas
src/smallmap_gui.cpp:	MS(PC_GREY,            STR_SMALLMAP_LEGENDA_ROCKS),
src/smallmap_gui.cpp:	MKCOLOUR_XXXX(PC_GREY),       ///< rocks
src/terraform_gui.cpp:/** Scenario editor command that generates rocky areas */
src/terraform_gui.cpp:static void GenerateRockyArea(TileIndex end, TileIndex start)
src/terraform_gui.cpp:				MakeClear(tile, CLEAR_ROCKS, 3);
src/terraform_gui.cpp:		case DDSP_CREATE_ROCKS:
src/terraform_gui.cpp:			GenerateRockyArea(end_tile, start_tile);
src/terraform_gui.cpp:			NWidget(WWT_IMGBTN, COLOUR_GREY, WID_ETT_PLACE_ROCKS), SetMinimalSize(22, 22),
src/terraform_gui.cpp:										SetFill(0, 1), SetDataTip(SPR_IMG_ROCKS, STR_TERRAFORM_TOOLTIP_PLACE_ROCKY_AREAS_ON_LANDSCAPE),
src/terraform_gui.cpp:			case WID_ETT_PLACE_ROCKS: // Place rocks button
src/terraform_gui.cpp:				HandlePlacePushButton(this, WID_ETT_PLACE_ROCKS, SPR_CURSOR_ROCKY_AREA, HT_RECT);
src/terraform_gui.cpp:			case WID_ETT_PLACE_ROCKS: // Place rocks button
src/terraform_gui.cpp:				VpStartPlaceSizing(tile, VPM_X_AND_Y, DDSP_CREATE_ROCKS);
src/terraform_gui.cpp:				case DDSP_CREATE_ROCKS:
src/terraform_gui.cpp:	Hotkey('R', "rocky", WID_ETT_PLACE_ROCKS),
src/tile_type.h:	MP_CLEAR,               ///< A tile without any structures, i.e. grass, rocks, farm fields etc.
src/tree_cmd.cpp: * This is true for clear ground without farms or rocks.
src/tree_cmd.cpp:			return !IsBridgeAbove(tile) && !IsClearGround(tile, CLEAR_FIELDS) && GetRawClearGround(tile) != CLEAR_ROCKS &&
src/tree_cmd.cpp:		/* Clear tile, no farm-tiles or rocks */
src/tree_cmd.cpp:					/* Remove fields or rocks. Note that the ground will get barrened */
src/tree_cmd.cpp:						case CLEAR_ROCKS: {
src/viewport_type.h:	DDSP_CREATE_ROCKS,         ///< Fill area with rocks
Ok, so we want to find it somewhere in the genworld context, it has obviously the generation stage with the name 'GWP_ROUGH_ROCKY'. So let's search for that. But wait, that is already found in clear_cmd.cpp as the first lines of output indicate. So maybe we start looking there, especially for SetGeneratingWorldProgress, IncreaseGeneratingWorldProgress and SetClearGroundDensity.

And voilà, the first entry of IncreaseGeneratingWorldProgress ends up in void GenerateClearTile() which seems to do the job:

Code: Select all

void GenerateClearTile()
{
        uint i, gi;
        TileIndex tile;

        /* add rough tiles */
        i = ScaleByMapSize(GB(Random(), 0, 10) + 0x400);
        gi = ScaleByMapSize(GB(Random(), 0, 7) + 0x80);

        SetGeneratingWorldProgress(GWP_ROUGH_ROCKY, gi + i);
        do {
                IncreaseGeneratingWorldProgress(GWP_ROUGH_ROCKY);
                tile = RandomTile();
                if (IsTileType(tile, MP_CLEAR) && !IsClearGround(tile, CLEAR_DESERT)) SetClearGroundDensity(tile, CLEAR_ROUGH, 3);
        } while (--i);

        /* add rocky tiles */
        i = gi;
        do {
                uint32 r = Random();
                tile = RandomTileSeed(r);

                IncreaseGeneratingWorldProgress(GWP_ROUGH_ROCKY);
                if (IsTileType(tile, MP_CLEAR) && !IsClearGround(tile, CLEAR_DESERT)) {
                        uint j = GB(r, 16, 4) + 5;
                        for (;;) {
                                TileIndex tile_new;

                                SetClearGroundDensity(tile, CLEAR_ROCKS, 3);
                                do {
                                        if (--j == 0) goto get_out;
                                        tile_new = tile + TileOffsByDiagDir((DiagDirection)GB(Random(), 0, 2));
                                } while (!IsTileType(tile_new, MP_CLEAR) || IsClearGround(tile_new, CLEAR_DESERT));
                                tile = tile_new;
                        }
get_out:;
                }
        } while (--i);
}
So finding it took me 5 minutes and another 5 writing this posting. Thus this way it took you at least 104 minutes while you wait for an answer someone finds for you.
Wahazar
Tycoon
Tycoon
Posts: 1451
Joined: 18 Jan 2014 18:10

Re: Where is rock placement defined?

Post by Wahazar »

BTW, currently rock are scattered randomly over whole map.
I changed clear_cmd.cpp algorithm slightly to:

Code: Select all

if (IsTileType(tile, MP_CLEAR) && !IsClearGround(tile, CLEAR_DESERT) && (TileHeight(tile) >= 2+RandomRange(14))) {
			uint j = GB(r, 16, 4) + 5;
			for (;;) {
				TileIndex tile_new;
				SetClearGroundDensity(tile, CLEAR_ROCKS, 3);
				do {
and now rocky areas are clustered in mountains, whereas they are rare in lower part of the map.
It not only look nice, but with appropriate base cost setting, it provide additional challenge during transport network construction trough mountain area.

PS. 16 height levels are hard-coded, it should be fixed in future.
Formerly known as: McZapkie
Projects: Reproducible Map Generation patch, NewGRFs: Manpower industries, PolTrams, Polroad, 600mm narrow gauge, wired, ECS industry extension, V4 CEE train set, HotHut.
Another favorite games: freeciv longturn, OHOL/2HOL.
Auge
Director
Director
Posts: 636
Joined: 23 Oct 2006 02:07
Location: Berlin

Re: Where is rock placement defined?

Post by Auge »

Hello
McZapkie wrote:PS. 16 height levels are hard-coded, it should be fixed in future.
It should be fixed by now, because mhl hitted the trunk. :-)

Tschö, Auge
Alberth
OpenTTD Developer
OpenTTD Developer
Posts: 4763
Joined: 09 Sep 2007 05:03
Location: home

Re: Where is rock placement defined?

Post by Alberth »

McZapkie wrote:and now rocky areas are clustered in mountains, whereas they are rare in lower part of the map.
It not only look nice, but with appropriate base cost setting, it provide additional challenge during transport network construction trough mountain area.
Any reason why building near sea level should not have such a challenge?
Being a retired OpenTTD developer does not mean I know what I am doing.
Gigigonzalez
Engineer
Engineer
Posts: 91
Joined: 12 Jun 2014 14:24

Re: Where is rock placement defined?

Post by Gigigonzalez »

planetmaker wrote:I doubt many, if anyone, knows where something is in the source by heart. It's always a matter of effectively finding it. So this is how I find the place where things are done: Let's search the whole source for 'rock', ignoring subdirs for now:

Code: Select all

~/ottd/trunk> grep -i 'rock' src/*
src/clear_cmd.cpp:		PR_CLEAR_ROCKS,
src/clear_cmd.cpp:		case CLEAR_ROCKS:
src/clear_cmd.cpp:			DrawGroundSprite(SPR_FLAT_ROCKY_LAND_1 + SlopeToSpriteOffset(ti->tileh), PAL_NONE);
src/clear_cmd.cpp:	SetGeneratingWorldProgress(GWP_ROUGH_ROCKY, gi + i);
src/clear_cmd.cpp:		IncreaseGeneratingWorldProgress(GWP_ROUGH_ROCKY);
src/clear_cmd.cpp:	/* add rocky tiles */
src/clear_cmd.cpp:		IncreaseGeneratingWorldProgress(GWP_ROUGH_ROCKY);
src/clear_cmd.cpp:				SetClearGroundDensity(tile, CLEAR_ROCKS, 3);
src/clear_cmd.cpp:	STR_LAI_CLEAR_DESCRIPTION_ROCKS,
src/clear_map.h:	CLEAR_ROCKS  = 2, ///< 3
src/disaster_cmd.cpp: * 1: If within 15 tiles, fire away rockets and destroy industry
src/economy_type.h:	PR_CLEAR_ROCKS,
src/genworld.h:	GWP_ROUGH_ROCKY, ///< Make rough and rocky areas
src/smallmap_gui.cpp:	MS(PC_GREY,            STR_SMALLMAP_LEGENDA_ROCKS),
src/smallmap_gui.cpp:	MKCOLOUR_XXXX(PC_GREY),       ///< rocks
src/terraform_gui.cpp:/** Scenario editor command that generates rocky areas */
src/terraform_gui.cpp:static void GenerateRockyArea(TileIndex end, TileIndex start)
src/terraform_gui.cpp:				MakeClear(tile, CLEAR_ROCKS, 3);
src/terraform_gui.cpp:		case DDSP_CREATE_ROCKS:
src/terraform_gui.cpp:			GenerateRockyArea(end_tile, start_tile);
src/terraform_gui.cpp:			NWidget(WWT_IMGBTN, COLOUR_GREY, WID_ETT_PLACE_ROCKS), SetMinimalSize(22, 22),
src/terraform_gui.cpp:										SetFill(0, 1), SetDataTip(SPR_IMG_ROCKS, STR_TERRAFORM_TOOLTIP_PLACE_ROCKY_AREAS_ON_LANDSCAPE),
src/terraform_gui.cpp:			case WID_ETT_PLACE_ROCKS: // Place rocks button
src/terraform_gui.cpp:				HandlePlacePushButton(this, WID_ETT_PLACE_ROCKS, SPR_CURSOR_ROCKY_AREA, HT_RECT);
src/terraform_gui.cpp:			case WID_ETT_PLACE_ROCKS: // Place rocks button
src/terraform_gui.cpp:				VpStartPlaceSizing(tile, VPM_X_AND_Y, DDSP_CREATE_ROCKS);
src/terraform_gui.cpp:				case DDSP_CREATE_ROCKS:
src/terraform_gui.cpp:	Hotkey('R', "rocky", WID_ETT_PLACE_ROCKS),
src/tile_type.h:	MP_CLEAR,               ///< A tile without any structures, i.e. grass, rocks, farm fields etc.
src/tree_cmd.cpp: * This is true for clear ground without farms or rocks.
src/tree_cmd.cpp:			return !IsBridgeAbove(tile) && !IsClearGround(tile, CLEAR_FIELDS) && GetRawClearGround(tile) != CLEAR_ROCKS &&
src/tree_cmd.cpp:		/* Clear tile, no farm-tiles or rocks */
src/tree_cmd.cpp:					/* Remove fields or rocks. Note that the ground will get barrened */
src/tree_cmd.cpp:						case CLEAR_ROCKS: {
src/viewport_type.h:	DDSP_CREATE_ROCKS,         ///< Fill area with rocks
Ok, so we want to find it somewhere in the genworld context, it has obviously the generation stage with the name 'GWP_ROUGH_ROCKY'. So let's search for that. But wait, that is already found in clear_cmd.cpp as the first lines of output indicate. So maybe we start looking there, especially for SetGeneratingWorldProgress, IncreaseGeneratingWorldProgress and SetClearGroundDensity.

And voilà, the first entry of IncreaseGeneratingWorldProgress ends up in void GenerateClearTile() which seems to do the job:

Code: Select all

void GenerateClearTile()
{
        uint i, gi;
        TileIndex tile;

        /* add rough tiles */
        i = ScaleByMapSize(GB(Random(), 0, 10) + 0x400);
        gi = ScaleByMapSize(GB(Random(), 0, 7) + 0x80);

        SetGeneratingWorldProgress(GWP_ROUGH_ROCKY, gi + i);
        do {
                IncreaseGeneratingWorldProgress(GWP_ROUGH_ROCKY);
                tile = RandomTile();
                if (IsTileType(tile, MP_CLEAR) && !IsClearGround(tile, CLEAR_DESERT)) SetClearGroundDensity(tile, CLEAR_ROUGH, 3);
        } while (--i);

        /* add rocky tiles */
        i = gi;
        do {
                uint32 r = Random();
                tile = RandomTileSeed(r);

                IncreaseGeneratingWorldProgress(GWP_ROUGH_ROCKY);
                if (IsTileType(tile, MP_CLEAR) && !IsClearGround(tile, CLEAR_DESERT)) {
                        uint j = GB(r, 16, 4) + 5;
                        for (;;) {
                                TileIndex tile_new;

                                SetClearGroundDensity(tile, CLEAR_ROCKS, 3);
                                do {
                                        if (--j == 0) goto get_out;
                                        tile_new = tile + TileOffsByDiagDir((DiagDirection)GB(Random(), 0, 2));
                                } while (!IsTileType(tile_new, MP_CLEAR) || IsClearGround(tile_new, CLEAR_DESERT));
                                tile = tile_new;
                        }
get_out:;
                }
        } while (--i);
}
So finding it took me 5 minutes and another 5 writing this posting. Thus this way it took you at least 104 minutes while you wait for an answer someone finds for you.
Well I actually did search in the whole map for 'rock', (including inside files), I believe i skipped the *_cmd.cpp files as i was under the full assumption these were mainly for manual object placement (Docommands etC)
Last edited by Gigigonzalez on 15 Oct 2014 16:29, edited 1 time in total.
Gigigonzalez
Engineer
Engineer
Posts: 91
Joined: 12 Jun 2014 14:24

Re: Where is rock placement defined?

Post by Gigigonzalez »

McZapkie wrote:BTW, currently rock are scattered randomly over whole map.
I changed clear_cmd.cpp algorithm slightly to:

Code: Select all

if (IsTileType(tile, MP_CLEAR) && !IsClearGround(tile, CLEAR_DESERT) && (TileHeight(tile) >= 2+RandomRange(14))) {
			uint j = GB(r, 16, 4) + 5;
			for (;;) {
				TileIndex tile_new;
				SetClearGroundDensity(tile, CLEAR_ROCKS, 3);
				do {
and now rocky areas are clustered in mountains, whereas they are rare in lower part of the map.
It not only look nice, but with appropriate base cost setting, it provide additional challenge during transport network construction trough mountain area.

PS. 16 height levels are hard-coded, it should be fixed in future.
Very interesting, I tried it though but there seem too little rocks still, same as without this trick. Ill try and adjust some numbers :)

Edit: In addition to this, I'm actually wondering whether some algorithm can like automatically place rocks on straight lines, like detect a straight line on a specific height, lets say 10 tiles long at least, and an almost seamless straight line without any deviations, and then apply rocks on that whole line.
Post Reply

Return to “OpenTTD Development”

Who is online

Users browsing this forum: Google [Bot] and 17 guests