NML: Multi-tile houses

Discussions about the technical aspects of graphics development, including NewGRF tools and utilities.

Moderator: Graphics Moderators

Post Reply
GojkoG
Engineer
Engineer
Posts: 14
Joined: 06 Dec 2017 18:45

NML: Multi-tile houses

Post by GojkoG »

Here’s an example for making multi-tile houses and objects in NML, because it is a different (but easier) from the NFO byte code, where you define the other tiles as own items. (And I was searching for hours to figure it out.) Big thanks to Bad_Brett whose comment was the hint I needed!
[…] for houses, we have the graphics_[north|west|east|south] callbacks.
(viewtopic.php?p=1247851&hilit=multi+tile#p1247851)

Code: Select all

item (FEAT_HOUSES, item_Stadium, 0xC0, HOUSE_SIZE_2X2) {
	property { … }
	graphics {
		graphics_north: sprtLyt_Stadium_N;
		graphics_east: sprtLyt_Stadium_E;
		graphics_west: sprtLyt_Stadium_W;
		graphics_south: sprtLyt_Stadium_S;
	}
}
You use the house callbacks. (And after figuring it out I now see that I could have read it by combining what is written in the NML tutorial and the things on the “NML:Houses” page. But it’s not obvious to see that “house callbacks” refers to the “graphics” block.)

And for objects:

Code: Select all

switch (FEAT_OBJECTS, SELF, switchObj_Stadium_tiles, relative_pos) {
		0x0000: sprtLyt_Stadium_N;
		0x0100: sprtLyt_Stadium_E;
		0x0001: sprtLyt_Stadium_W;
		0x0101: sprtLyt_Stadium_S;
}	

item (FEAT_OBJECTS, item_Stadium, 0xC0) {
	property { … }
	graphics {
		default: switchObj_Stadium_tiles;
	}
}
temporal8
Route Supervisor
Route Supervisor
Posts: 429
Joined: 17 May 2019 14:15

Re: NML: Multi-tile houses

Post by temporal8 »

Thank you very much for your contribution, it is very useful.

Question, how would you add street detection to that example?

I'm working on a town set and I need to figure out how to add street detection to the 2x1 and 2x2 Houses, I only have it working for 1x1.

This is a working code with road detection for 1x1 house:

Code: Select all

// 1x1 HOUSE

/*Road South West*/

spriteset (spriteset_realhousetown_1X1_001_southwest, "realhousetown.png") {
	[98, 8, 44, 36, -22, 0, NOCROP]
}
alternative_sprites (spriteset_realhousetown_1X1_001_southwest, ZOOM_LEVEL_IN_4X, BIT_DEPTH_32BPP, "gfx/realhousetown_32_005.png") { 
  	[0, 0, 256, 256, -107, -154, NOCROP]
}

spritelayout spritelayout_realhousetown_1X1_001_southwest{
	ground {
		sprite: GROUNDSPRITE_NORMAL;
	}
	building {
		sprite: spriteset_realhousetown_1X1_001_southwest;
		recolour_mode: RECOLOUR_REMAP;
		palette: PALETTE_USE_DEFAULT;
		xextent: 8;
		yextent: 16;
		zextent: 27;
		xoffset: 4;
		yoffset: 2;
		zoffset: 0;
		hide_sprite: 0;
	}
}
/*Road North West*/

spriteset (spriteset_realhousetown_1X1_001_northwest, "realhousetown.png") {
	[98, 8, 44, 36, -22, 0, NOCROP]
}
alternative_sprites (spriteset_realhousetown_1X1_001_northwest, ZOOM_LEVEL_IN_4X, BIT_DEPTH_32BPP, "gfx/realhousetown_32_005.png") { 
  	[265, 0, 256, 256, -107, -154, NOCROP]
}

spritelayout spritelayout_realhousetown_1X1_001_northwest {
	ground {
		sprite: GROUNDSPRITE_NORMAL;
	}
	building {
		sprite: spriteset_realhousetown_1X1_001_northwest;
		recolour_mode: RECOLOUR_REMAP;
		palette: PALETTE_USE_DEFAULT;
		xextent: 8;
		yextent: 16;
		zextent: 27;
		xoffset: 4;
		yoffset: 2;
		zoffset: 0;
		hide_sprite: 0;
	}
}


/*Road North East*/
spriteset (spriteset_realhousetown_1X1_001_northeast, "realhousetown.png") {
	[98, 8, 44, 36, -22, 0, NOCROP]
}
alternative_sprites (spriteset_realhousetown_1X1_001_northeast, ZOOM_LEVEL_IN_4X, BIT_DEPTH_32BPP, "gfx/realhousetown_32_005.png") { 
  	[524, 0, 256, 256, -107, -154, NOCROP]
}

spritelayout spritelayout_realhousetown_1X1_001_northeast {
	ground {
		sprite: GROUNDSPRITE_NORMAL;
	}
	building {
		sprite: spriteset_realhousetown_1X1_001_northeast;
		recolour_mode: RECOLOUR_REMAP;
		palette: PALETTE_USE_DEFAULT;
		xextent: 8;
		yextent: 16;
		zextent: 27;
		xoffset: 4;
		yoffset: 2;
		zoffset: 0;
		hide_sprite: 0;
	}
}
/*Road South East*/

spriteset (spriteset_realhousetown_1X1_001_southeast, "realhousetown.png") {
	[98, 8, 44, 36, -22, 0, NOCROP]
}
alternative_sprites (spriteset_realhousetown_1X1_001_southeast, ZOOM_LEVEL_IN_4X, BIT_DEPTH_32BPP, "gfx/realhousetown_32_005.png") { 
  	[788, 0, 256, 256, -107, -154, NOCROP]
}

spritelayout spritelayout_realhousetown_1X1_001_southeast {
	ground {
		sprite: GROUNDSPRITE_NORMAL;
	}
	building {
		sprite: spriteset_realhousetown_1X1_001_southeast;
		recolour_mode: RECOLOUR_REMAP;
		palette: PALETTE_USE_DEFAULT;
		xextent: 8;
		yextent: 16;
		zextent: 27;
		xoffset: 4;
		yoffset: 2;
		zoffset: 0;
		hide_sprite: 0;
	}
}

/* Switches */

switch (FEAT_HOUSES, SELF, switch_check_road_northeast, nearby_tile_class(-1, 0)) {
	TILE_CLASS_ROAD: 3;
	CB_RESULT_DO_NOTHING;
}

switch (FEAT_HOUSES, SELF, switch_check_road_southeast, nearby_tile_class(0, 1)) {
	TILE_CLASS_ROAD: 2;
	switch_check_road_northeast;
}

switch (FEAT_HOUSES, SELF, switch_check_road_southwest, nearby_tile_class(1, 0)) {
	TILE_CLASS_ROAD: 1;
	switch_check_road_southeast;
}


switch (FEAT_HOUSES, SELF, switch_check_road_northwest, nearby_tile_class(0, -1)) {
	TILE_CLASS_ROAD:  0;
	switch_check_road_southwest;
}

switch (FEAT_HOUSES, SELF, switch_check_road_final, animation_frame) {
	0:  spritelayout_realhousetown_1X1_001_northwest;
	1:  spritelayout_realhousetown_1X1_001_southwest;
	2:  spritelayout_realhousetown_1X1_001_southeast;
	3:  spritelayout_realhousetown_1X1_001_northeast;
	spritelayout_realhousetown_1X1_001_northwest;
}

/* Switches End */

item (FEAT_HOUSES, item_realhousetown_090, -1, HOUSE_SIZE_1X1) {
	property {
		substitute: 24;
		population:                 90;
		mail_multiplier:            30;
		accepted_cargos:            [[PASS, 4], [MAIL, 3], [GOOD, 3]];
		probability: 1;
		years_available:            [1855, 2050];
		name: string(STR_realhousetown_1X1_001_HOUSE);
                availability_mask: [bitmask(TOWNZONE_EDGE, TOWNZONE_OUTSKIRT), bitmask(CLIMATE_TEMPERATE, CLIMATE_ARCTIC, ABOVE_SNOWLINE, CLIMATE_TROPICAL)];
		building_flags    : bitmask(HOUSE_FLAG_ANIMATE);
		animation_info    : [ANIMATION_LOOPING, 1];
	}
	graphics {
    default: switch_check_road_final;
    anim_control: switch_check_road_northwest;
	}
}



How to add the switch to your 2x2 example?


Thanks for sharing.
Real Projects 32bpp releases:

Real Semi Trucks 32bpp: viewtopic.php?t=90996
Real Houses Eyecandy Objects 32bp: viewtopic.php?t=90767
Real Ships 32bpp: viewtopic.php?t=90733
Real Industries 32bpp: viewtopic.php?t=90183
Real Houses Townset 32bp: viewtopic.php?p=1254605
Real Stations 32bpp: viewtopic.php?p=1255635
Real Cars 32bpp: viewtopic.php?p=1249244
Real Vehicles 32bpp: viewtopic.php?p=1253581
Real Bus 32bpp: viewtopic.php?p=1249245
Real Trucks 32bpp: viewtopic.php?p=1254468
Real Parks 32bpp: viewtopic.php?p=1250255
Argentina World Cup 2022 Champions Bus 32bpp viewtopic.php?p=1257026
GojkoG
Engineer
Engineer
Posts: 14
Joined: 06 Dec 2017 18:45

Re: NML: Multi-tile houses

Post by GojkoG »

Hi Temporal8!
Am I reading correctly that you’re using animation frames to save the street positions? That’s a workaround you don’t need, because you simply could check for the roads on the “way” to the spritelayout and then branch it to your four spritelayouts:

Code: Select all

switch (FEAT_HOUSES, SELF, switch_realhousetown_090_road_check, switch_check_road_northwest) {
	3:  spritelayout_realhousetown_1X1_001_northeast;
	2:  spritelayout_realhousetown_1X1_001_southeast;
	1:  spritelayout_realhousetown_1X1_001_southwest;
	spritelayout_realhousetown_1X1_001_northwest;	// you don’t need the zero, because this is the “else”/default in this switch
}

item (FEAT_HOUSES, item_realhousetown_090, -1, HOUSE_SIZE_1X1) {
	property { … }
	graphics {
		default: switch_realhousetown_090_road_check;
	}
}
You’re using your own switch “switch_check_road_northwest” and the ones called by it like functions in other programming languages.

And to have it for multiple tiles you branch the way before that for every tile:

Code: Select all

switch (FEAT_HOUSES, SELF, switch_realhousetown_090_N_road_check, switch_check_road_northwest) {
	3:  spritelayout_realhousetown_N_001_northeast;
	2:  spritelayout_realhousetown_N_001_southeast;
	1:  spritelayout_realhousetown_N_001_southwest;
	spritelayout_realhousetown_N_001_northwest;
}

[…]

switch (FEAT_HOUSES, SELF, switch_realhousetown_090_S_road_check, switch_check_road_northwest) {
	3:  spritelayout_realhousetown_S_001_northeast;
	2:  spritelayout_realhousetown_S_001_southeast;
	1:  spritelayout_realhousetown_S_001_southwest;
	spritelayout_realhousetown_S_001_northwest;
}

item (FEAT_HOUSES, item_realhousetown_090, -1, HOUSE_SIZE_2X2) {
	property { … }
	graphics {
		graphics_north: switch_realhousetown_090_N_road_check;
		graphics_east: switch_realhousetown_090_E_road_check;
		graphics_west: switch_realhousetown_090_W_road_check;
		graphics_south: switch_realhousetown_090_S_road_check
	}
}
PS: You could use the hide_sprite function and check the road directly in the “building” block of spritelayout. I will test it and write an example in the next post.
PS: The code is better arranged if you have one spriteset for all graphics of your house and refer to labels:

Code: Select all

spriteset (spriteset_realhousetown_1X1_001, "realhousetown.png") {
	southwest:	[98, 8, 44, 36, -22, 0, NOCROP]
	northwest:	[98, 8, 44, 36, -22, 0, NOCROP]
	northeast:	[98, 8, 44, 36, -22, 0, NOCROP]
	southeast:	[98, 8, 44, 36, -22, 0, NOCROP]
}
alternative_sprites (spriteset_realhousetown_1X1_001, ZOOM_LEVEL_IN_4X, BIT_DEPTH_32BPP, "gfx/realhousetown_32_005.png") { 
  	southwest:	[0, 0, 256, 256, -107, -154, NOCROP]
	northwest:	[788, 0, 256, 256, -107, -154, NOCROP]
	northeast:	[524, 0, 256, 256, -107, -154, NOCROP]
	southeast:	[788, 0, 256, 256, -107, -154, NOCROP]
}

spritelayout spritelayout_realhousetown_1X1_001_southwest{
	ground { … }
	building {
		sprite: spriteset_realhousetown_1X1_001( southwest );
		[…]
	}
}
Eddi
Tycoon
Tycoon
Posts: 8258
Joined: 17 Jan 2007 00:14

Re: NML: Multi-tile houses

Post by Eddi »

GojkoG wrote: 05 Dec 2021 14:23 Am I reading correctly that you’re using animation frames to save the street positions? That’s a workaround you don’t need, because you simply could check for the roads on the “way” to the spritelayout and then branch it to your four spritelayouts
the point of that is to store the road layout at the moment the building is constructed. so it doesn't magically change shape if roads are removed or built later.
User avatar
jfs
Tycoon
Tycoon
Posts: 1750
Joined: 08 Jan 2003 23:09
Location: Denmark

Re: NML: Multi-tile houses

Post by jfs »

Eddi wrote: 05 Dec 2021 14:49the point of that is to store the road layout at the moment the building is constructed. so it doesn't magically change shape if roads are removed or built later.
Additionally, by saving the built orientation, it's faster to draw the building since the game doesn't need to run the NewGRF callback every time the building comes on screen.
GojkoG
Engineer
Engineer
Posts: 14
Joined: 06 Dec 2017 18:45

Re: NML: Multi-tile houses

Post by GojkoG »

Okay. I see that the NML compiler ignores switch blocks called from within the “building” block as long as they are not referenced from somewhere else.

Here I just want to show other ways to achieve the same, but have less spritelayout blocks:

It could work this way to have less spritelayout blocks. (The switch blocks have to be before that):

Code: Select all

spritelayout sprtLyt_BrickRowHouses {
	ground { … }
	building {	// road northwest
		[…]
		hide_sprite: (switch_check_road_northwest != 0)? 1 : 0;	// hide if result is not "0"
	}
	[…]
	building {	// road northeast
		[…]
		hide_sprite: (switch_check_road_northwest != 3)? 1 : 0;	// hide if result is not "3"
	}
}
You also could save a temp variable and write your road check to that and then check the temp:

Code: Select all

spritelayout spritelayout_realhousetown_S_001{
	ground { … }
	building {	// road northwest
		[…]
		hide_sprite: (LOAD_TEMP(0)!= 0)? 1 : 0;	// hide if value of temp variable 0 is not "0"
	}
	[…]
	building {	// road northeast
		[…]
		hide_sprite: (LOAD_TEMP(0)!= 3)? 1 : 0;	// hide if value of temp variable 0 is not "3"
	}
}

[…]

switch (FEAT_HOUSES, SELF, switch_houses_road_check, [
		STORE_TEMP( switch_check_road_northwest, 0))	// the result of your switch “switch_check_road_northwest” is stored in temp variable 0
	]) {
	spritelayout_realhousetown_S_001;
}
GojkoG
Engineer
Engineer
Posts: 14
Joined: 06 Dec 2017 18:45

Re: NML: Multi-tile houses

Post by GojkoG »

the point of that is to store the road layout at the moment the building is constructed. so it doesn't magically change shape if roads are removed or built later.
Good point! I didn’t think of that.
temporal8
Route Supervisor
Route Supervisor
Posts: 429
Joined: 17 May 2019 14:15

Re: NML: Multi-tile houses

Post by temporal8 »

Thanks for your reply GojkoG, I understand what you say but I have problems applying it, mostly because I know how to detect the street in 1x1 but the 2x1 or 2x2 modules have extra code to detect the 2 tiles of a 2x1 or the 4 tiles of a 2x2 and that's where I get lost.

This is a working code for a 2x2 object from my Real Houses newgrf (i attached the file below if you want to test ingame):

Code: Select all

// define the newgrf
grf {
    grfid:                  "TEM2";
    name:                   string(STR_GRF_NAME);
    desc:                   string(STR_GRF_DESCRIPTION);
    url : string(STR_GRF_WEBSITE);
    version:                2;
    min_compatible_version: 1;
}

//template for the purchase menu
template template_realhouse_purchase(x,y,filename) {
    [x    , y, 128, 96, -95, -45, filename]
    [x+133, y, 128, 96, -95, -45, filename]
    [x+266, y, 128, 96, -95, -45, filename]
    [x+399, y, 128, 96, -95, -45, filename]
	
}

//template for the purchase menu 32
template template_realhouse_purchase_32(x,y,filename) {
    [x+34, y+7, 519, 387, -345, -247, filename]
    [x+34, y+407, 519, 387, -389, -259, filename]
    [x+34, y+801, 519, 387, -378, -291, filename]
    [x+34, y+1200, 519, 387, -374, -294, filename]	
}

//template for sprite tile.1 (v1.1, v1.2, v1.3, v1.4)
template template_realhouse_t1(x,y,filename) {
    [x+2, y+2, 64, 64, -1, -1, filename]
    [x+2, y+2, 64, 64, -1, -1, filename]
    [x+2, y+2, 64, 64, -1, -1, filename]
    [x+2, y+2, 64, 64, -1, -1, filename]	
}

//template for sprite tile32.1 (v1.1, v1.2, v1.3, v1.4)
template template_realhouse_32_t1(x,y,filename) {
    [x+158, y+3, 264, 264, -130, -135, filename]
    [x+158, y+400, 264, 264, -130, -135, filename]
    [x+158, y+797, 264, 264, -130, -135, filename]
    [x+158, y+1193, 264, 264, -130, -135, filename]	
}

//template for sprite tile.2 
template template_realhouse_t2(x,y,filename) {
    [x+2, y+2, 64, 64, -1, -1, filename]
    [x+2, y+2, 64, 64, -1, -1, filename]
    [x+2, y+2, 64, 64, -1, -1, filename]
    [x+2, y+2, 64, 64, -1, -1, filename]
}

//template for sprite tile32.2 (v2.1, v2.2, v2.3, v2.4)
template template_realhouse_32_t2(x,y,filename) {
    [x+287, y+65, 264, 264, -129, -137, filename]
    [x+287, y+462, 264, 264, -129, -137, filename]
    [x+287, y+859, 264, 264, -129, -137, filename]
    [x+287, y+1255, 264, 264, -129, -137, filename]	
}

//template for sprite tile.3
template template_realhouse_t3(x,y,filename) {
    [x+2, y+2, 64, 64, -1, -1, filename]
    [x+2, y+2, 64, 64, -1, -1, filename]
    [x+2, y+2, 64, 64, -1, -1, filename]
    [x+2, y+2, 64, 64, -1, -1, filename]
}

//template for sprite tile32.3  (v3.1, v3.2, v3.3, v3.4)
template template_realhouse_32_t3(x,y,filename) {
    [x+33, y+65, 264, 264, -127, -137, filename]
    [x+33, y+462, 264, 264, -127, -137, filename]
    [x+33, y+859, 264, 264, -127, -137, filename]
    [x+1, y+1255, 295, 264, -159, -137, filename]	
}

//template for sprite tile.4
template template_realhouse_t4(x,y,filename) {
    [x+2, y+2, 64, 64, -1, -1, filename]
    [x+2, y+2, 64, 64, -1, -1, filename]
    [x+2, y+2, 64, 64, -1, -1, filename]
    [x+2, y+2, 64, 64, -1, -1, filename]
}

//template for sprite tile32.4 (v4.1, v4.2, v4.3, v4.4)
template template_realhouse_32_t4(x,y,filename) {
    [x+160, y+127, 264, 264, -128, -139, filename]
    [x+160, y+524, 264, 264, -128, -139, filename]
    [x+160, y+921, 264, 264, -128, -139, filename]
    [x+160, y+1317, 264, 264, -128, -139, filename]
	
}

/* template_realhouse_001 */

//spritesets with 4 directions and the PURCHASE-menu
spriteset (spriteset_template_realhouse_001_t1) {
    template_realhouse_t1(0,0,"realhouse/gfx/template_realhouse_001.png")
}
alternative_sprites (spriteset_template_realhouse_001_t1, ZOOM_LEVEL_IN_4X, BIT_DEPTH_32BPP) { 
    template_realhouse_32_t1(0,0,"realhouse/gfx/template_realhouse_32_001.png")
}

spriteset (spriteset_template_realhouse_001_t2) {
    template_realhouse_t2(0,0,"realhouse/gfx/template_realhouse_001.png")
}

alternative_sprites (spriteset_template_realhouse_001_t2, ZOOM_LEVEL_IN_4X, BIT_DEPTH_32BPP) { 
    template_realhouse_32_t2(0,0,"realhouse/gfx/template_realhouse_32_001.png")
}

spriteset (spriteset_template_realhouse_001_t3) {
    template_realhouse_t3(0,0,"realhouse/gfx/template_realhouse_001.png")
}

alternative_sprites (spriteset_template_realhouse_001_t3, ZOOM_LEVEL_IN_4X, BIT_DEPTH_32BPP) { 
    template_realhouse_32_t3(0,0,"realhouse/gfx/template_realhouse_32_001.png")
}

spriteset (spriteset_template_realhouse_001_t4) {
    template_realhouse_t4(0,0,"realhouse/gfx/template_realhouse_001.png")
}

alternative_sprites (spriteset_template_realhouse_001_t4, ZOOM_LEVEL_IN_4X, BIT_DEPTH_32BPP) { 
    template_realhouse_32_t4(0,0,"realhouse/gfx/template_realhouse_32_001.png")
}

spriteset (spriteset_template_realhouse_001_PURCHASE) {
    template_realhouse_purchase(0,0,"realhouse/gfx/template_realhouse_001_PURCHASE.png")
}
alternative_sprites (spriteset_template_realhouse_001_PURCHASE, ZOOM_LEVEL_IN_4X, BIT_DEPTH_32BPP) { 
    template_realhouse_purchase_32(0,0,"realhouse/gfx/template_realhouse_32_001.png")
}

//View_1
spritelayout spritelayout_template_realhouse_001_t1_view1 {
    ground {
      // normal ground sprite - always draw
      sprite: LOAD_TEMP(0) + LOAD_TEMP(1);
   }
    
    building {
        sprite: spriteset_template_realhouse_001_t1(0);
        hide_sprite: nearby_tile_height(0, 0) >= snowline_height;
        xoffset: 0; //from NE edge
        yoffset: 0; //from NW edge
        zoffset: 0;
        xextent: 16;
        yextent: 16;
        zextent: 16;
    }

}

spritelayout spritelayout_template_realhouse_001_t2_view1 {
    ground {
      // normal ground sprite - always draw
      sprite: LOAD_TEMP(0) + LOAD_TEMP(1);
   }
    
    building {
        sprite: spriteset_template_realhouse_001_t2(0);
        hide_sprite: nearby_tile_height(0, 0) >= snowline_height;
        xoffset: 0; //from NE edge
        yoffset: 0; //from NW edge
        zoffset: 0;
        xextent: 16;
        yextent: 16;
        zextent: 16;
    }

}

spritelayout spritelayout_template_realhouse_001_t3_view1 {
    ground {
      // normal ground sprite - always draw
      sprite: LOAD_TEMP(0) + LOAD_TEMP(1);
   }
    
    building {
        sprite: spriteset_template_realhouse_001_t3(0);
        hide_sprite: nearby_tile_height(0, 0) >= snowline_height;
        xoffset: 0; //from NE edge
        yoffset: 0; //from NW edge
        zoffset: 0;
        xextent: 16;
        yextent: 16;
        zextent: 16;
    }

}

spritelayout spritelayout_template_realhouse_001_t4_view1 {
    ground {
      // normal ground sprite - always draw
      sprite: LOAD_TEMP(0) + LOAD_TEMP(1);
   }
    
    building {
        sprite: spriteset_template_realhouse_001_t4(0);
        hide_sprite: nearby_tile_height(0, 0) >= snowline_height;
        xoffset: 0; //from NE edge
        yoffset: 0; //from NW edge
        zoffset: 0;
        xextent: 16;
        yextent: 16;
        zextent: 16;
    }

}

spritelayout spritelayout_template_realhouse_001_view1_purchase {
	ground {
        sprite: GROUNDSPRITE_NORMAL;
	}
	building {
		sprite: spriteset_template_realhouse_001_PURCHASE(0);
		xoffset: 0; //from NE edge
                yoffset: 16; //from NW edge
                zoffset: 0;
                xextent: 16;
                yextent: 16;
                zextent: 16;
	}
}

//View_2
spritelayout spritelayout_template_realhouse_001_t1_view2 {
    ground {
      // normal ground sprite - always draw
      sprite: LOAD_TEMP(0) + LOAD_TEMP(1);
   }
    
    building {
        sprite: spriteset_template_realhouse_001_t1(1);
        hide_sprite: nearby_tile_height(0, 0) >= snowline_height;
        xoffset: 0; //from NE edge
        yoffset: 0; //from NW edge
        zoffset: 0;
        xextent: 16;
        yextent: 16;
        zextent: 16;
    }

}

spritelayout spritelayout_template_realhouse_001_t2_view2 {
    ground {
      // normal ground sprite - always draw
      sprite: LOAD_TEMP(0) + LOAD_TEMP(1);
   }
    
    building {
        sprite: spriteset_template_realhouse_001_t2(1);
        hide_sprite: nearby_tile_height(0, 0) >= snowline_height;
        xoffset: 0; //from NE edge
        yoffset: 0; //from NW edge
        zoffset: 0;
        xextent: 16;
        yextent: 16;
        zextent: 16;
    }

}

spritelayout spritelayout_template_realhouse_001_t3_view2 {
    ground {
      // normal ground sprite - always draw
      sprite: LOAD_TEMP(0) + LOAD_TEMP(1);
   }
    
    building {
        sprite: spriteset_template_realhouse_001_t3(1);
        hide_sprite: nearby_tile_height(0, 0) >= snowline_height;
        xoffset: 0; //from NE edge
        yoffset: 0; //from NW edge
        zoffset: 0;
        xextent: 16;
        yextent: 16;
        zextent: 16;
    }

}

spritelayout spritelayout_template_realhouse_001_t4_view2 {
    ground {
      // normal ground sprite - always draw
      sprite: LOAD_TEMP(0) + LOAD_TEMP(1);
   }
    
    building {
        sprite: spriteset_template_realhouse_001_t4(1);
        hide_sprite: nearby_tile_height(0, 0) >= snowline_height;
        xoffset: 0; //from NE edge
        yoffset: 0; //from NW edge
        zoffset: 0;
        xextent: 16;
        yextent: 16;
        zextent: 16;
    }

}

spritelayout spritelayout_template_realhouse_001_view2_purchase {
	ground {
        sprite: GROUNDSPRITE_NORMAL;
	}
	building {
		sprite: spriteset_template_realhouse_001_PURCHASE(1);
		xoffset: 0; //from NE edge
                yoffset: 16; //from NW edge
                zoffset: 0;
                xextent: 16;
                yextent: 16;
                zextent: 16;
	}
}


//View_3
spritelayout spritelayout_template_realhouse_001_t1_view3 {
    ground {
      // normal ground sprite - always draw
      sprite: LOAD_TEMP(0) + LOAD_TEMP(1);
   }
    
    building {
        sprite: spriteset_template_realhouse_001_t1(2);
        hide_sprite: nearby_tile_height(0, 0) >= snowline_height;
        xoffset: 0; //from NE edge
        yoffset: 0; //from NW edge
        zoffset: 0;
        xextent: 16;
        yextent: 16;
        zextent: 16;
    }

}

spritelayout spritelayout_template_realhouse_001_t2_view3 {
    ground {
      // normal ground sprite - always draw
      sprite: LOAD_TEMP(0) + LOAD_TEMP(1);
   }
    
    building {
        sprite: spriteset_template_realhouse_001_t2(2);
        hide_sprite: nearby_tile_height(0, 0) >= snowline_height;
        xoffset: 0; //from NE edge
        yoffset: 0; //from NW edge
        zoffset: 0;
        xextent: 16;
        yextent: 16;
        zextent: 16;
    }

}

spritelayout spritelayout_template_realhouse_001_t3_view3 {
    ground {
      // normal ground sprite - always draw
      sprite: LOAD_TEMP(0) + LOAD_TEMP(1);
   }
    
    building {
        sprite: spriteset_template_realhouse_001_t3(2);
        hide_sprite: nearby_tile_height(0, 0) >= snowline_height;
        xoffset: 0; //from NE edge
        yoffset: 0; //from NW edge
        zoffset: 0;
        xextent: 16;
        yextent: 16;
        zextent: 16;
    }

}

spritelayout spritelayout_template_realhouse_001_t4_view3 {
    ground {
      // normal ground sprite - always draw
      sprite: LOAD_TEMP(0) + LOAD_TEMP(1);
   }
    
    building {
        sprite: spriteset_template_realhouse_001_t4(2);
        hide_sprite: nearby_tile_height(0, 0) >= snowline_height;
        xoffset: 0; //from NE edge
        yoffset: 0; //from NW edge
        zoffset: 0;
        xextent: 16;
        yextent: 16;
        zextent: 16;
    }
}

spritelayout spritelayout_template_realhouse_001_view3_purchase {
	ground {
        sprite: GROUNDSPRITE_NORMAL;
	}
	building {
		sprite: spriteset_template_realhouse_001_PURCHASE(2);
		xoffset: 0; //from NE edge
                yoffset: 16; //from NW edge
                zoffset: 0;
                xextent: 16;
                yextent: 16;
                zextent: 16;
	}
}


//View_4
spritelayout spritelayout_template_realhouse_001_t1_view4 {
    ground {
      // normal ground sprite - always draw
      sprite: LOAD_TEMP(0) + LOAD_TEMP(1);
   }
    
    building {
        sprite: spriteset_template_realhouse_001_t1(3);
        hide_sprite: nearby_tile_height(0, 0) >= snowline_height;
        xoffset: 0; //from NE edge
        yoffset: 0; //from NW edge
        zoffset: 0;
        xextent: 16;
        yextent: 16;
        zextent: 16;
    }
}

spritelayout spritelayout_template_realhouse_001_t2_view4 {
    ground {
      // normal ground sprite - always draw
      sprite: LOAD_TEMP(0) + LOAD_TEMP(1);
   }
    
    building {
        sprite: spriteset_template_realhouse_001_t2(3);
        hide_sprite: nearby_tile_height(0, 0) >= snowline_height;
        xoffset: 0; //from NE edge
        yoffset: 0; //from NW edge
        zoffset: 0;
        xextent: 16;
        yextent: 16;
        zextent: 16;
    }
}

spritelayout spritelayout_template_realhouse_001_t3_view4 {
    ground {
      // normal ground sprite - always draw
      sprite: LOAD_TEMP(0) + LOAD_TEMP(1);
   }
    
    building {
        sprite: spriteset_template_realhouse_001_t3(3);
        hide_sprite: nearby_tile_height(0, 0) >= snowline_height;
        xoffset: 0; //from NE edge
        yoffset: 0; //from NW edge
        zoffset: 0;
        xextent: 16;
        yextent: 16;
        zextent: 16;
    }

}

spritelayout spritelayout_template_realhouse_001_t4_view4 {
    ground {
      // normal ground sprite - always draw
      sprite: LOAD_TEMP(0) + LOAD_TEMP(1);
   }
    
    building {
        sprite: spriteset_template_realhouse_001_t4(3);
        hide_sprite: nearby_tile_height(0, 0) >= snowline_height;
        xoffset: 0; //from NE edge
        yoffset: 0; //from NW edge
        zoffset: 0;
        xextent: 16;
        yextent: 16;
        zextent: 16;
    }

}

spritelayout spritelayout_template_realhouse_001_view4_purchase {
	ground {
        sprite: GROUNDSPRITE_NORMAL;
	}
	building {
		sprite: spriteset_template_realhouse_001_PURCHASE(3);
		xoffset: 0; //from NE edge
                yoffset: 16; //from NW edge
                zoffset: 0;
                xextent: 16;
                yextent: 16;
                zextent: 16;
	}
}

//select correct sprites for position of the tiles for the four views
switch (FEAT_OBJECTS, SELF, switch_template_realhouse_001_position_view1, relative_pos) {
	relative_coord(0, 0): spritelayout_template_realhouse_001_t1_view1;
	relative_coord(0, 1): spritelayout_template_realhouse_001_t2_view1;
	relative_coord(1, 0): spritelayout_template_realhouse_001_t3_view1;
	relative_coord(1, 1): spritelayout_template_realhouse_001_t4_view1;
    spritelayout_template_realhouse_001_t1_view1;
    }

switch (FEAT_OBJECTS, SELF, switch_template_realhouse_001_position_view2, relative_pos) {
	relative_coord(0, 0): spritelayout_template_realhouse_001_t1_view2;
	relative_coord(0, 1): spritelayout_template_realhouse_001_t2_view2;
	relative_coord(1, 0): spritelayout_template_realhouse_001_t3_view2;
	relative_coord(1, 1): spritelayout_template_realhouse_001_t4_view2;
    spritelayout_template_realhouse_001_t1_view2;
    }

switch (FEAT_OBJECTS, SELF, switch_template_realhouse_001_position_view3, relative_pos) {
	relative_coord(0, 0): spritelayout_template_realhouse_001_t1_view3;
	relative_coord(0, 1): spritelayout_template_realhouse_001_t2_view3;
	relative_coord(1, 0): spritelayout_template_realhouse_001_t3_view3;
	relative_coord(1, 1): spritelayout_template_realhouse_001_t4_view3;
    spritelayout_template_realhouse_001_t1_view3;
    }

switch (FEAT_OBJECTS, SELF, switch_template_realhouse_001_position_view4, relative_pos) {
	relative_coord(0, 0) : spritelayout_template_realhouse_001_t1_view4;
	relative_coord(0, 1) : spritelayout_template_realhouse_001_t2_view4;
	relative_coord(1, 0) : spritelayout_template_realhouse_001_t3_view4;
	relative_coord(1, 1) : spritelayout_template_realhouse_001_t4_view4;
    spritelayout_template_realhouse_001_t1_view4;
    }
 
//decide spritelayout for each of the 4 directions
switch (FEAT_OBJECTS, SELF, switch_template_realhouse_001_view, view) {
    1:  switch_template_realhouse_001_position_view2;
    2:  switch_template_realhouse_001_position_view3;
    3:  switch_template_realhouse_001_position_view4;
    switch_template_realhouse_001_position_view1;
}

//calculate ground sprite for object
switch (FEAT_OBJECTS, SELF, switch_template_realhouse_001_object, [
    STORE_TEMP(GROUNDSPRITE_NORMAL, 1),
    STORE_TEMP( (nearby_tile_terrain_type(0,0) == TILETYPE_DESERT) * GROUNDSPRITE_DESERT, 1),
    STORE_TEMP( LOAD_TEMP(1) + (LOAD_TEMP(1) == 0) * 4512 * (nearby_tile_terrain_type( 1, 0) == TILETYPE_DESERT), 1),
    STORE_TEMP( LOAD_TEMP(1) + (LOAD_TEMP(1) == 0) * 4512 * (nearby_tile_terrain_type(-1, 0) == TILETYPE_DESERT), 1),
    STORE_TEMP( LOAD_TEMP(1) + (LOAD_TEMP(1) == 0) * 4512 * (nearby_tile_terrain_type( 0, 1) == TILETYPE_DESERT), 1),
    STORE_TEMP( LOAD_TEMP(1) + (LOAD_TEMP(1) == 0) * 4512 * (nearby_tile_terrain_type( 0,-1) == TILETYPE_DESERT), 1),
    STORE_TEMP( LOAD_TEMP(1) + (LOAD_TEMP(1) == 0) * GROUNDSPRITE_NORMAL, 1),
    STORE_TEMP(terrain_type == TILETYPE_SNOW   ? GROUNDSPRITE_SNOW : LOAD_TEMP(1), 1),
    STORE_TEMP(snowline_height == 0xFF ? 0xFF : nearby_tile_height(0,0) - snowline_height, 255),
    STORE_TEMP((LOAD_TEMP(255) == -1) ? GROUNDSPRITE_SNOW_1_4 : LOAD_TEMP(1), 1),
    STORE_TEMP((LOAD_TEMP(255) ==  0) ? GROUNDSPRITE_SNOW_2_4 : LOAD_TEMP(1), 1),
    STORE_TEMP((LOAD_TEMP(255) ==  1) ? GROUNDSPRITE_SNOW_3_4 : LOAD_TEMP(1), 1)
        ]) {
    switch_template_realhouse_001_view;
}

//calculate ground sprite for purchase menu
switch (FEAT_OBJECTS, SELF, switch_template_realhouse_001_purchase, view) {
    1:  spritelayout_template_realhouse_001_view2_purchase;
    2:  spritelayout_template_realhouse_001_view3_purchase;
    3:  spritelayout_template_realhouse_001_view4_purchase;
    spritelayout_template_realhouse_001_view1_purchase;
}

switch (FEAT_OBJECTS, SELF, switch_add_text_template_realhouse_001, view) {
1: string(STR_template_realhouse_001_purchase_view2);
2: string(STR_template_realhouse_001_purchase_view3);
3: string(STR_template_realhouse_001_purchase_view4);
default: string(STR_template_realhouse_001_purchase_view1);
}

item (FEAT_OBJECTS, template_realhouse_001, 000) {
    property {
        class: "RH2S";
        classname: string(STR_RH2S);
        name: string(STR_template_realhouse_001);
        climates_available: ALL_CLIMATES;
        size: [2,2];
        build_cost_multiplier: 0;
        remove_cost_multiplier: 0;
        introduction_date: date(1700,1,1);
        end_of_life_date: 0xFFFFFFFF;
        object_flags: bitmask(OBJ_FLAG_ALLOW_BRIDGE, OBJ_FLAG_ON_WATER, OBJ_FLAG_DRAW_WATER, OBJ_FLAG_ANYTHING_REMOVE, OBJ_FLAG_REMOVE_IS_INCOME);
        height: 0;
        num_views: 4;
     }
    graphics {
        default: switch_template_realhouse_001_object;
        purchase: switch_template_realhouse_001_purchase;
        additional_text: switch_add_text_template_realhouse_001;
      }
}
I want to convert these 2x2 object to a 2x2 house! originally i was doing a newgrf eyecandy of houses and buildings, but for a while i have been converting it to a town set, i mean houses instead of eyecandy, I only achieved it with 1x1 houses with the generous guidance and help of other forum members since I am not a coder.

The working code of a 1x1 house is the one I posted above, how can I do it in this 2x2 code?

I know I can add a swicth for the address / street detection but again, I don't know how to convert home the part of detecting that a house has several tiles.
Attachments
m2x2road.grf
(4.08 MiB) Downloaded 59 times
Real Projects 32bpp releases:

Real Semi Trucks 32bpp: viewtopic.php?t=90996
Real Houses Eyecandy Objects 32bp: viewtopic.php?t=90767
Real Ships 32bpp: viewtopic.php?t=90733
Real Industries 32bpp: viewtopic.php?t=90183
Real Houses Townset 32bp: viewtopic.php?p=1254605
Real Stations 32bpp: viewtopic.php?p=1255635
Real Cars 32bpp: viewtopic.php?p=1249244
Real Vehicles 32bpp: viewtopic.php?p=1253581
Real Bus 32bpp: viewtopic.php?p=1249245
Real Trucks 32bpp: viewtopic.php?p=1254468
Real Parks 32bpp: viewtopic.php?p=1250255
Argentina World Cup 2022 Champions Bus 32bpp viewtopic.php?p=1257026
Post Reply

Return to “NewGRF Technical Discussions”

Who is online

Users browsing this forum: No registered users and 3 guests