NML House with check road position complete example??

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

Moderator: Graphics Moderators

temporal8
Engineer
Engineer
Posts: 115
Joined: 17 May 2019 14:15

NML House with check road position complete example??

Post by temporal8 »

Hello, I want to do tests with towns and my Real Houses graphics, is there a complete example in NML of houses that includes the detection of adjacent streets?

Otherwise how do I start from scratch or from some existing base? i'm looking at the forum and wiki but i see scattered documentation.

I tried looking for the Swedish Houses source code but only found nfo, not nml.

Thanks in advance.
temporal8
Engineer
Engineer
Posts: 115
Joined: 17 May 2019 14:15

Re: NML House with check road position complete example??

Post by temporal8 »

Code so far... At the moment it replaces an existing building and it does not have construction states (I will include that in a later version).

- I have to figure out how to add it without replacing anything. (remove the override line??)
- How to detect adjacent streets for the correct orientation of the building?

Code: Select all

grf {
	grfid: "NML\44";
	name: string(STR_REALHOUSETOWN_NAME);
	desc: string(STR_REALHOUSETOWN_DESC);
	version: 0;
	min_compatible_version: 0;
}

/* CargoTable for other good acceptance*/
cargotable {
	GOOD, PASS, MAIL
}

spriteset (spriteset_realhousetown, "realhousetown.png") {
	[98, 8, 44, 36, -22, 0, NOCROP]
}
alternative_sprites (spriteset_realhousetown, ZOOM_LEVEL_IN_4X, BIT_DEPTH_32BPP, "realhousetown_32.png") { 
  	[0, 0, 259, 219, -109, -110, NOCROP]
}

spritelayout spritelayout_realhousetown {
	ground {
		sprite: GROUNDSPRITE_NORMAL;
	}
	building {
		sprite: spriteset_realhousetown;
		recolour_mode: RECOLOUR_REMAP;
		palette: PALETTE_USE_DEFAULT;
		xextent: 8;
		yextent: 16;
		zextent: 27;
		xoffset: 4;
		yoffset: 2;
		zoffset: 0;
		hide_sprite: 0;
	}
}
item (FEAT_HOUSES, item_realhousetown, -1, HOUSE_SIZE_1X1) {
	property {
		substitute: 2;
                override: 2;
		name: string(STR_REALHOUSETOWN_HOUSE);
       /* do not replace (override) any original house type */
		population: 7;
		mail_multiplier: 5;
		local_authority_impact: 30;
		removal_cost_multiplier: 30;
		probability: 10;
		years_available: [1800,2050];
		minimum_lifetime: 15;
		availability_mask: [bitmask(TOWNZONE_EDGE, TOWNZONE_OUTSKIRT), bitmask(ALL_CLIMATES)];
		random_colours: [COLOUR_RED, COLOUR_BLUE, COLOUR_GREEN, COLOUR_YELLOW];	
        refresh_multiplier: 0;

	}

	graphics {
		default: spritelayout_realhousetown;
	}
}
User avatar
Andrew350
Director
Director
Posts: 605
Joined: 19 Dec 2011 07:54
Location: Washington State, USA
Contact:

Re: NML House with check road position complete example??

Post by Andrew350 »

I don't have any existing example code to offer, but I can show you how to do it :)

To change the graphics depending on road placement you're going to use a series of switches querying the nearby_tile_class, and point to a different sprite layout depending on the result. Something like this:

Code: Select all

switch (FEAT_HOUSES, SELF, switch_check_road_north, nearby_tile_class(-1, 0) {
	TILE_CLASS_ROAD:  spritelayout_realhousetown_road_north;
	switch_check_road_south;
}
This switch tests the tile -1 in the "x" direction (upper right) from your house (I call it north but it could be east/west/whatever). If it finds a road tile (TILE_CLASS_ROAD) it points to the sprite layout for that direction, otherwise it passes to the next switch to check the next direction:

Code: Select all

switch (FEAT_HOUSES, SELF, switch_check_road_south, nearby_tile_class(1, 0) {
	TILE_CLASS_ROAD:  spritelayout_realhousetown_road_south;
	switch_check_road_east;
}
This does the same but instead checks the tile +1 in the "x" direction (lower left). Continue this for the other directions to get something like this:

Code: Select all

switch (FEAT_HOUSES, SELF, switch_check_road_west, nearby_tile_class(0, -1) {
	TILE_CLASS_ROAD:  spritelayout_realhousetown_road_west;
	spritelayout_default;
}

switch (FEAT_HOUSES, SELF, switch_check_road_east, nearby_tile_class(0, 1) {
	TILE_CLASS_ROAD:  spritelayout_realhousetown_road_east;
	switch_check_road_west;
}

switch (FEAT_HOUSES, SELF, switch_check_road_south, nearby_tile_class(1, 0) {
	TILE_CLASS_ROAD:  spritelayout_realhousetown_road_south;
	switch_check_road_east;
}

switch (FEAT_HOUSES, SELF, switch_check_road_north, nearby_tile_class(-1, 0) {
	TILE_CLASS_ROAD:  spritelayout_realhousetown_road_north;
	switch_check_road_south;
}
Notice the last switch in the chain still has to point to a spritelayout even if it finds no road, so it can be whichever layout you choose (this would only happen in the relatively rare case where a house is built on the outside corner of a road)

Note that this is just the very basic setup; you can of course make it more complicated if you wanted to, say, make a special layout for a corner lot, or check for similar nearby buildings, etc. The possibilities are endless, but hopefully this gets you started :)

Oh and of course make sure you change the "default" callback to point to these new switches:

Code: Select all

graphics {
		default: switch_check_road_north;
	}
Eddi
Tycoon
Tycoon
Posts: 7530
Joined: 17 Jan 2007 00:14

Re: NML House with check road position complete example??

Post by Eddi »

i would suggest not to query the nearby tiles in the default graphics chain, that leads to houses magically changing shape if new roads are built or removed next to existing houses

instead you can query the road layout during construction, and store it as "animation frame" (make sure to not use cyclic animation in that case)
You might not exactly be interested in Ferion, but if you are, have fun :)
temporal8
Engineer
Engineer
Posts: 115
Joined: 17 May 2019 14:15

Re: NML House with check road position complete example??

Post by temporal8 »

Thank you guys, I will see what I can do and if I have problems I will ask again. :bow:
temporal8
Engineer
Engineer
Posts: 115
Joined: 17 May 2019 14:15

Re: NML House with check road position complete example??

Post by temporal8 »

Hello, I have checked the code over and over again and I can't find the error, can you give me a hand?

It gives me this error: ←[Knmlc ERROR: "realhousetown.nml", line 113: Syntax error, unexpected token "{"

Thanks in advance.

Code: Select all

grf {
	grfid: "NML\44";
	name: string(STR_REALHOUSETOWN_NAME);
	desc: string(STR_REALHOUSETOWN_DESC);
	version: 0;
	min_compatible_version: 0;
}

//Road North East
spriteset (spriteset_realhousetown_northeast, "realhousetown.png") {
	[98, 8, 44, 36, -22, 0, NOCROP]
}
alternative_sprites (spriteset_realhousetown_northeast, ZOOM_LEVEL_IN_4X, BIT_DEPTH_32BPP, "realhousetown_32.png") { 
  	[0, 0, 259, 219, -109, -110, NOCROP]
}

spritelayout spritelayout_realhousetown_northeast {
	ground {
		sprite: GROUNDSPRITE_NORMAL;
	}
	building {
		sprite: spriteset_realhousetown_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_southeast, "realhousetown.png") {
	[98, 8, 44, 36, -22, 0, NOCROP]
}
alternative_sprites (spriteset_realhousetown_southeast, ZOOM_LEVEL_IN_4X, BIT_DEPTH_32BPP, "realhousetown_32.png") { 
  	[259, 0, 259, 219, -109, -110, NOCROP]
}

spritelayout spritelayout_realhousetown_southeast {
	ground {
		sprite: GROUNDSPRITE_NORMAL;
	}
	building {
		sprite: spriteset_realhousetown_southeast;
		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 West

spriteset (spriteset_realhousetown_southwest, "realhousetown.png") {
	[98, 8, 44, 36, -22, 0, NOCROP]
}
alternative_sprites (spriteset_realhousetown_southwest, ZOOM_LEVEL_IN_4X, BIT_DEPTH_32BPP, "realhousetown_32.png") { 
  	[518, 0, 259, 219, -109, -110, NOCROP]
}

spritelayout spritelayout_realhousetown_southwest {
	ground {
		sprite: GROUNDSPRITE_NORMAL;
	}
	building {
		sprite: spriteset_realhousetown_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_northwest, "realhousetown.png") {
	[98, 8, 44, 36, -22, 0, NOCROP]
}
alternative_sprites (spriteset_realhousetown_northwest, ZOOM_LEVEL_IN_4X, BIT_DEPTH_32BPP, "realhousetown_32.png") { 
  	[777, 0, 259, 219, -109, -110, NOCROP]
}

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

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

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

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

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


item (FEAT_HOUSES, item_realhousetown, -1, HOUSE_SIZE_1X1) {
	property {
		substitute: 2;
		override: 2;
		probability: 10;
		name: string(STR_REALHOUSETOWN_HOUSE);
                availability_mask: [ALL_TOWNZONES, ALL_CLIMATES];
	}
	graphics {
    default: switch_check_road_northeast;
	}
}
Eddi
Tycoon
Tycoon
Posts: 7530
Joined: 17 Jan 2007 00:14

Re: NML House with check road position complete example??

Post by Eddi »

well, look very carefully at your line 113:

Code: Select all

switch (FEAT_HOUSES, SELF, switch_check_road_northeast, nearby_tile_class(-1, 0) {
you have two opening "(" but only one closing ")"
You might not exactly be interested in Ferion, but if you are, have fun :)
temporal8
Engineer
Engineer
Posts: 115
Joined: 17 May 2019 14:15

Re: NML House with check road position complete example??

Post by temporal8 »

Thank you! With problems again, I am not a programmer, with some things like objects or vehicles I had no problems because I was guided by previous help in the forum, but about this there is very little or no information, can you help me again?

New error:
←[Knmlc ERROR: "realhousetown.nml", line 120: Unrecognized identifier 'switch_check_road_southwest' encountered

Code: Select all

grf {
	grfid: "NML\44";
	name: string(STR_REALHOUSETOWN_NAME);
	desc: string(STR_REALHOUSETOWN_DESC);
	version: 0;
	min_compatible_version: 0;
}

/*Road North East*/
spriteset (spriteset_realhousetown_northeast, "realhousetown.png") {
	[98, 8, 44, 36, -22, 0, NOCROP]
}
alternative_sprites (spriteset_realhousetown_northeast, ZOOM_LEVEL_IN_4X, BIT_DEPTH_32BPP, "realhousetown_32.png") { 
  	[0, 0, 259, 219, -109, -110, NOCROP]
}

spritelayout spritelayout_realhousetown_northeast {
	ground {
		sprite: GROUNDSPRITE_NORMAL;
	}
	building {
		sprite: spriteset_realhousetown_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_southeast, "realhousetown.png") {
	[98, 8, 44, 36, -22, 0, NOCROP]
}
alternative_sprites (spriteset_realhousetown_southeast, ZOOM_LEVEL_IN_4X, BIT_DEPTH_32BPP, "realhousetown_32.png") { 
  	[259, 0, 259, 219, -109, -110, NOCROP]
}

spritelayout spritelayout_realhousetown_southeast {
	ground {
		sprite: GROUNDSPRITE_NORMAL;
	}
	building {
		sprite: spriteset_realhousetown_southeast;
		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 West*/

spriteset (spriteset_realhousetown_southwest, "realhousetown.png") {
	[98, 8, 44, 36, -22, 0, NOCROP]
}
alternative_sprites (spriteset_realhousetown_southwest, ZOOM_LEVEL_IN_4X, BIT_DEPTH_32BPP, "realhousetown_32.png") { 
  	[518, 0, 259, 219, -109, -110, NOCROP]
}

spritelayout spritelayout_realhousetown_southwest {
	ground {
		sprite: GROUNDSPRITE_NORMAL;
	}
	building {
		sprite: spriteset_realhousetown_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_northwest, "realhousetown.png") {
	[98, 8, 44, 36, -22, 0, NOCROP]
}
alternative_sprites (spriteset_realhousetown_northwest, ZOOM_LEVEL_IN_4X, BIT_DEPTH_32BPP, "realhousetown_32.png") { 
  	[777, 0, 259, 219, -109, -110, NOCROP]
}

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

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

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

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

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


item (FEAT_HOUSES, item_realhousetown, -1, HOUSE_SIZE_1X1) {
	property {
		substitute: 2;
		override: 2;
		probability: 10;
		name: string(STR_REALHOUSETOWN_HOUSE);
                availability_mask: [ALL_TOWNZONES, ALL_CLIMATES];
	}
	graphics {
    default: switch_check_road_northeast;
	}
}
Eddi
Tycoon
Tycoon
Posts: 7530
Joined: 17 Jan 2007 00:14

Re: NML House with check road position complete example??

Post by Eddi »

you can only reference switches that are defined ABOVE, but switch_check_road_southwest is defined BELOW, you probably meant northeast? otherwise you get an infinite loop, and that is not allowed
You might not exactly be interested in Ferion, but if you are, have fun :)
temporal8
Engineer
Engineer
Posts: 115
Joined: 17 May 2019 14:15

Re: NML House with check road position complete example??

Post by temporal8 »

Thanks a lot, :bow:
Some progress... i added some things to the code, it does not give an error but the house does not turn, it does not detect the street,

I suspect the problem is in building_flags / anim_next_frame?
I keep working, learning and researching.

Code: Select all

grf {
	grfid: "NML\44";
	name: string(STR_REALHOUSETOWN_NAME);
	desc: string(STR_REALHOUSETOWN_DESC);
	version: 0;
	min_compatible_version: 0;
}

/*Road North East*/
spriteset (spriteset_realhousetown_northeast, "realhousetown.png") {
	[98, 8, 44, 36, -22, 0, NOCROP]
}
alternative_sprites (spriteset_realhousetown_northeast, ZOOM_LEVEL_IN_4X, BIT_DEPTH_32BPP, "realhousetown_32.png") { 
  	[0, 0, 259, 219, -109, -110, NOCROP]
}

spritelayout spritelayout_realhousetown_northeast {
	ground {
		sprite: GROUNDSPRITE_NORMAL;
	}
	building {
		sprite: spriteset_realhousetown_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_southeast, "realhousetown.png") {
	[98, 8, 44, 36, -22, 0, NOCROP]
}
alternative_sprites (spriteset_realhousetown_southeast, ZOOM_LEVEL_IN_4X, BIT_DEPTH_32BPP, "realhousetown_32.png") { 
  	[259, 0, 259, 219, -109, -110, NOCROP]
}

spritelayout spritelayout_realhousetown_southeast {
	ground {
		sprite: GROUNDSPRITE_NORMAL;
	}
	building {
		sprite: spriteset_realhousetown_southeast;
		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 West*/

spriteset (spriteset_realhousetown_southwest, "realhousetown.png") {
	[98, 8, 44, 36, -22, 0, NOCROP]
}
alternative_sprites (spriteset_realhousetown_southwest, ZOOM_LEVEL_IN_4X, BIT_DEPTH_32BPP, "realhousetown_32.png") { 
  	[518, 0, 259, 219, -109, -110, NOCROP]
}

spritelayout spritelayout_realhousetown_southwest{
	ground {
		sprite: GROUNDSPRITE_NORMAL;
	}
	building {
		sprite: spriteset_realhousetown_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_northwest, "realhousetown.png") {
	[98, 8, 44, 36, -22, 0, NOCROP]
}
alternative_sprites (spriteset_realhousetown_northwest, ZOOM_LEVEL_IN_4X, BIT_DEPTH_32BPP, "realhousetown_32.png") { 
  	[777, 0, 259, 219, -109, -110, NOCROP]
}

spritelayout spritelayout_realhousetown_northwest {
	ground {
		sprite: GROUNDSPRITE_NORMAL;
	}
	building {
		sprite: spriteset_realhousetown_northwest;
		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:  spritelayout_realhousetown_northeast;
	spritelayout_realhousetown_northeast;
}

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

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

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

/* Switches End */

item (FEAT_HOUSES, item_realhousetown, -1, HOUSE_SIZE_1X1) {
	property {
		substitute: 2;
		override: 2;
		probability: 10;
		name: string(STR_REALHOUSETOWN_HOUSE);
                availability_mask: [ALL_TOWNZONES, ALL_CLIMATES];
		building_flags    : bitmask(HOUSE_FLAG_ANIMATE);
		animation_info    : [ANIMATION_LOOPING, 4];
	}
	graphics {
    default: switch_check_road_northeast;
    anim_next_frame: switch_check_road_northwest;
	}
}
User avatar
Andrew350
Director
Director
Posts: 605
Joined: 19 Dec 2011 07:54
Location: Washington State, USA
Contact:

Re: NML House with check road position complete example??

Post by Andrew350 »

Eddi wrote: 30 Oct 2020 19:28 instead you can query the road layout during construction, and store it as "animation frame" (make sure to not use cyclic animation in that case)
Honest question: do you know of any NewGRF (even not released) that ever actually did this?

This idea intrigued me, so I did a bit of experimentation trying to make it work, but of course failed. The only way I could figure to stop the animation callbacks from constantly changing the data read by the graphics callback was to store a value into permanent storage, however NML seems to not like this and throws an error about an invalid feature number:

Code: Select all

nmlc ERROR: nmlc: An internal error has occurred:
nmlc-version: 0.5.3
Error:    (AssertionError) "Invalid feature number".
Command:  ['nmlc', '-c', '--grf', 'objects.grf', 'objects.nml']
Location: File "nml\ast\general.py", line 56, in feature_name
Accessing the regular town variables works fine, but trying to read or write to the town registers fails. I've read both the "real" specs and NML docs, but I'm not totally clear whether I'm doing something invalid here, or I'm just not doing it correctly, or it's a problem with NML. Either way, without being able to store a value somehow, I don't see any way to achieve this using animation frames, as the animation callback will be continuously changing the data (read: house flip-flops) otherwise. Hopefully I'm just dumb and missing something obvious and someone can point me in the right direction :)



On a related note, after giving up on the code I did a little playtesting of various house sets to see if I could work out how others had done this, and I can't come up with a single example* of any working NewGRF which does this behavior (houses which face a road but don't change when it moves). The few house sets I found that actually bother to make houses face towards the road seem content to allow them to flip-flop when the road changes.

*Only one relatively obscure and incomplete set seems to have houses that permanently stay fixed to a road without changing, but I suspect they "cheated" by (ab)using the construction_check callback and having multiple houses for different views. Of course I didn't try every town NewGRF ever, mostly the ones easily accessible and/or noteworthy, so maybe there's a gem hidden somewhere deep in the forums or on a special site I've overlooked, but it almost starts to look like I'm chasing a ghost :)

So anyway, now I'm curious how such a thing works myself :P I usually overlook something so if you've got even a hint where to look for an example that would be helpful :)
User avatar
2TallTyler
Traffic Manager
Traffic Manager
Posts: 203
Joined: 11 Aug 2019 18:15
Contact:

Re: NML House with check road position complete example??

Post by 2TallTyler »

NML currently doesn’t support houses accessing their parent town’s storage registers. Here’s a relevant (abandoned) PR.

Improved Town Layouts has houses that change when roads are built or destroyed. I don’t see a problem with this, personally.
User avatar
Andrew350
Director
Director
Posts: 605
Joined: 19 Dec 2011 07:54
Location: Washington State, USA
Contact:

Re: NML House with check road position complete example??

Post by Andrew350 »

2TallTyler wrote: 08 Nov 2020 14:48 NML currently doesn’t support houses accessing their parent town’s storage registers. Here’s a relevant (abandoned) PR.
Ah good, it's not just me then :lol:

I even looked on GitHub but must have have missed that, so thanks for pointing it out :)
Eddi
Tycoon
Tycoon
Posts: 7530
Joined: 17 Jan 2007 00:14

Re: NML House with check road position complete example??

Post by Eddi »

Andrew350 wrote: 08 Nov 2020 09:21
Eddi wrote: 30 Oct 2020 19:28 instead you can query the road layout during construction, and store it as "animation frame" (make sure to not use cyclic animation in that case)
Honest question: do you know of any NewGRF (even not released) that ever actually did this?
i'm pretty sure i made that suggestion before, but i don't remember how far that person got last time.

the basic gist is that you use the "animation control" callback instead of the "next animation frame" callback, and then use "stop animation"
You might not exactly be interested in Ferion, but if you are, have fun :)
User avatar
Andrew350
Director
Director
Posts: 605
Joined: 19 Dec 2011 07:54
Location: Washington State, USA
Contact:

Re: NML House with check road position complete example??

Post by Andrew350 »

Eddi wrote: 08 Nov 2020 18:00 i'm pretty sure i made that suggestion before, but i don't remember how far that person got last time.
Well then it seems that whatever they were working on wasn't released (yet), so probably not far ;)
Eddi wrote: 08 Nov 2020 18:00 the basic gist is that you use the "animation control" callback instead of the "next animation frame" callback, and then use "stop animation"
Yep, I got that part ok, but not being able to access permanent storage seems like kind of a killer for doing this properly in NML, at least until it's fixed.

So, temporal8, it seems you have three options:
1) Live with the fact that houses will occasionally flip directions when a road is changed (for now)
2) Implement a really dirty, hacky version of the correct behavior (no-flipping), but only for houses greater than construction_state 0 and built during the game, not on initial map gen (no idea why I can't get it to work for houses on map gen, it seems like it should but doesn't, so eh, it's ugly anyway)
3) Learn NFO

Personally I think option 1 is a good compromise here, as far as I can tell it pretty much follows what other house sets have done so far, without being too complicated. Option 3 potentially offers the "correct" path to making this work properly, but may not be advisable for just getting started ;) Option 2 is ugly, but closest to intended behavior I could manage without storage access (I probably wouldn't choose this option).

Option 1 will work following Eddi's suggestion to use "anim_control" instead of "next_animation_frame". Instead of returning a spritelayout though, it must return an animation frame (or other callback result):

Code: Select all

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;
}
You will also need a new switch for the "default" callback to tie your graphics to the animation frames, something like so:

Code: Select all

switch (FEAT_HOUSES, SELF, switch_check_road_final, animation_frame) {
	0:  spritelayout_house_1;
	1:  spritelayout_house_2;
	2:  spritelayout_house_3;
	3:  spritelayout_house_4;
	spritelayout_house_1;
}
Also make sure to change ANIMATION_LOOPING to ANIMATION_NON_LOOPING in animation_info property. I think that's it? At least that was basically enough to get it working on my end, you may need to tweak it some :)

EDIT: Just looked at my test file again, you may need to change the number of frames in animation_info to 1, or do as Eddi says and use the "stop animation" result somewhere, otherwise the frames will instantly cycle to the end. Also I'm not sure if setting HOUSE_FLAG_ANIMATE is necessary here, at least it seems to work fine for me without it.
temporal8
Engineer
Engineer
Posts: 115
Joined: 17 May 2019 14:15

Re: NML House with check road position complete example??

Post by temporal8 »

Thanks, it already detects the roads, now I am trying to detect the corners, it already tries with the coordinates of N, S, E and O and although it works it does it wrong, since it detects the next piece of road in a straight line.

To avoid this, what should be done would be to detect the two adjacent axes, that is ... instead of detecting N (-1, -1) it should detect NW (0, -1) and NE (-1,0) ,
this makes sense?

This it´s a working code that detects the streets in NW, NE, SE and SW:

Code: Select all

grf {
	grfid: "NML\44";
	name: string(STR_REALHOUSETOWN_NAME);
	desc: string(STR_REALHOUSETOWN_DESC);
	version: 0;
	min_compatible_version: 0;
}

cargotable { 
	PASS, MAIL, GOOD, FOOD , RCYC
		
}

/*Road North East*/
spriteset (spriteset_realhousetown_northeast, "realhousetown.png") {
	[98, 8, 44, 36, -22, 0, NOCROP]
}
alternative_sprites (spriteset_realhousetown_northeast, ZOOM_LEVEL_IN_4X, BIT_DEPTH_32BPP, "realhousetown_32.png") { 
  	[0, 0, 259, 219, -109, -110, NOCROP]
}

spritelayout spritelayout_realhousetown_northeast {
	ground {
		sprite: GROUNDSPRITE_NORMAL;
	}
	building {
		sprite: spriteset_realhousetown_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_southeast, "realhousetown.png") {
	[98, 8, 44, 36, -22, 0, NOCROP]
}
alternative_sprites (spriteset_realhousetown_southeast, ZOOM_LEVEL_IN_4X, BIT_DEPTH_32BPP, "realhousetown_32.png") { 
  	[259, 0, 259, 219, -109, -110, NOCROP]
}

spritelayout spritelayout_realhousetown_southeast {
	ground {
		sprite: GROUNDSPRITE_NORMAL;
	}
	building {
		sprite: spriteset_realhousetown_southeast;
		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 West*/

spriteset (spriteset_realhousetown_southwest, "realhousetown.png") {
	[98, 8, 44, 36, -22, 0, NOCROP]
}
alternative_sprites (spriteset_realhousetown_southwest, ZOOM_LEVEL_IN_4X, BIT_DEPTH_32BPP, "realhousetown_32.png") { 
  	[518, 0, 259, 219, -109, -110, NOCROP]
}

spritelayout spritelayout_realhousetown_southwest{
	ground {
		sprite: GROUNDSPRITE_NORMAL;
	}
	building {
		sprite: spriteset_realhousetown_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_northwest, "realhousetown.png") {
	[98, 8, 44, 36, -22, 0, NOCROP]
}
alternative_sprites (spriteset_realhousetown_northwest, ZOOM_LEVEL_IN_4X, BIT_DEPTH_32BPP, "realhousetown_32.png") { 
  	[777, 0, 259, 219, -109, -110, NOCROP]
}

spritelayout spritelayout_realhousetown_northwest {
	ground {
		sprite: GROUNDSPRITE_NORMAL;
	}
	building {
		sprite: spriteset_realhousetown_northwest;
		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_northwest;
	1:  spritelayout_realhousetown_southwest;
	2:  spritelayout_realhousetown_southeast;
	3:  spritelayout_realhousetown_northeast;
	spritelayout_realhousetown_northwest;
}


/* Switches End */

item (FEAT_HOUSES, item_realhousetown, -1, HOUSE_SIZE_1X1) {
	property {
		substitute: 2;
		override: 2;
		population:                 90;
		mail_multiplier:            30;
		accepted_cargos:            [[PASS, 4], [MAIL, 3], [GOOD, 3]];
		probability: 10;
		years_available:            [1855, 2050];
		name: string(STR_REALHOUSETOWN_HOUSE);
                availability_mask: [ALL_TOWNZONES, ALL_CLIMATES];
		building_flags    : bitmask(HOUSE_FLAG_ANIMATE);
		animation_info    : [ANIMATION_LOOPING, 1];
	}
	graphics {
    default: switch_check_road_final;
    anim_control: switch_check_road_northwest;
	}
}


And this is the code where I add the corners, but while it works, it does it in an unwanted way, because in a straight street, it takes the next portion of the road as diagonal to the tile and shows the graph of the corner.


Image

Code: Select all

grf {
	grfid: "NML\44";
	name: string(STR_REALHOUSETOWN_NAME);
	desc: string(STR_REALHOUSETOWN_DESC);
	version: 0;
	min_compatible_version: 0;
}

cargotable { 
	PASS, MAIL, GOOD, FOOD , RCYC
		
}

/*Road North East*/
spriteset (spriteset_realhousetown_northeast, "realhousetown.png") {
	[98, 8, 44, 36, -22, 0, NOCROP]
}
alternative_sprites (spriteset_realhousetown_northeast, ZOOM_LEVEL_IN_4X, BIT_DEPTH_32BPP, "realhousetown_32.png") { 
  	[0, 0, 259, 219, -109, -110, NOCROP]
}

spritelayout spritelayout_realhousetown_northeast {
	ground {
		sprite: GROUNDSPRITE_NORMAL;
	}
	building {
		sprite: spriteset_realhousetown_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_southeast, "realhousetown.png") {
	[98, 8, 44, 36, -22, 0, NOCROP]
}
alternative_sprites (spriteset_realhousetown_southeast, ZOOM_LEVEL_IN_4X, BIT_DEPTH_32BPP, "realhousetown_32.png") { 
  	[259, 0, 259, 219, -109, -110, NOCROP]
}

spritelayout spritelayout_realhousetown_southeast {
	ground {
		sprite: GROUNDSPRITE_NORMAL;
	}
	building {
		sprite: spriteset_realhousetown_southeast;
		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 West*/

spriteset (spriteset_realhousetown_southwest, "realhousetown.png") {
	[98, 8, 44, 36, -22, 0, NOCROP]
}
alternative_sprites (spriteset_realhousetown_southwest, ZOOM_LEVEL_IN_4X, BIT_DEPTH_32BPP, "realhousetown_32.png") { 
  	[518, 0, 259, 219, -109, -110, NOCROP]
}

spritelayout spritelayout_realhousetown_southwest{
	ground {
		sprite: GROUNDSPRITE_NORMAL;
	}
	building {
		sprite: spriteset_realhousetown_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_northwest, "realhousetown.png") {
	[98, 8, 44, 36, -22, 0, NOCROP]
}
alternative_sprites (spriteset_realhousetown_northwest, ZOOM_LEVEL_IN_4X, BIT_DEPTH_32BPP, "realhousetown_32.png") { 
  	[777, 0, 259, 219, -109, -110, NOCROP]
}

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

/* North, South... */

/* North Corner */
spriteset (spriteset_realhousetown_northcorner, "realhousetown.png") {
	[98, 8, 44, 36, -22, 0, NOCROP]
}
alternative_sprites (spriteset_realhousetown_northcorner, ZOOM_LEVEL_IN_4X, BIT_DEPTH_32BPP, "realhousetown_32.png") { 
  	[0, 220, 259, 219, -109, -110, NOCROP]
}

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

spriteset (spriteset_realhousetown_eastcorner, "realhousetown.png") {
	[98, 8, 44, 36, -22, 0, NOCROP]
}
alternative_sprites (spriteset_realhousetown_eastcorner, ZOOM_LEVEL_IN_4X, BIT_DEPTH_32BPP, "realhousetown_32.png") { 
  	[259, 220, 259, 219, -109, -110, NOCROP]
}

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

spriteset (spriteset_realhousetown_southcorner, "realhousetown.png") {
	[98, 8, 44, 36, -22, 0, NOCROP]
}
alternative_sprites (spriteset_realhousetown_southcorner, ZOOM_LEVEL_IN_4X, BIT_DEPTH_32BPP, "realhousetown_32.png") { 
  	[518, 220, 259, 219, -109, -110, NOCROP]
}

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

spriteset (spriteset_realhousetown_westcorner, "realhousetown.png") {
	[98, 8, 44, 36, -22, 0, NOCROP]
}
alternative_sprites (spriteset_realhousetown_westcorner, ZOOM_LEVEL_IN_4X, BIT_DEPTH_32BPP, "realhousetown_32.png") { 
  	[777, 220, 259, 219, -109, -110, NOCROP]
}

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



/* Switches */

/* intentando corners */

switch (FEAT_HOUSES, SELF, switch_check_road_northcorner, nearby_tile_class(-1, -1)) {
	TILE_CLASS_ROAD: 7;
	CB_RESULT_DO_NOTHING;
}

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

switch (FEAT_HOUSES, SELF, switch_check_road_eastcorner, nearby_tile_class(-1, 1)) {
	TILE_CLASS_ROAD: 5;
	switch_check_road_northeast;
}

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

switch (FEAT_HOUSES, SELF, switch_check_road_southcorner, nearby_tile_class(1, 1)) {
	TILE_CLASS_ROAD: 3;
	switch_check_road_southeast;
}

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

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


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

switch (FEAT_HOUSES, SELF, switch_check_road_final, animation_frame) {
	0:  spritelayout_realhousetown_northwest;
	1:  spritelayout_realhousetown_westcorner;
	2:  spritelayout_realhousetown_southwest;
	3:  spritelayout_realhousetown_southcorner;
	4:  spritelayout_realhousetown_southeast;
	5:  spritelayout_realhousetown_eastcorner;
	6:  spritelayout_realhousetown_northeast;
	7:  spritelayout_realhousetown_northcorner;
	spritelayout_realhousetown_northwest;
}


/* intentando corners end */

/* Switches End */

item (FEAT_HOUSES, item_realhousetown, -1, HOUSE_SIZE_1X1) {
	property {
		substitute: 2;
		override: 2;
		population:                 90;
		mail_multiplier:            30;
		accepted_cargos:            [[PASS, 4], [MAIL, 3], [GOOD, 3]];
		probability: 10;
		years_available:            [1855, 2050];
		name: string(STR_REALHOUSETOWN_HOUSE);
                availability_mask: [ALL_TOWNZONES, ALL_CLIMATES];
		building_flags    : bitmask(HOUSE_FLAG_ANIMATE);
		animation_info    : [ANIMATION_LOOPING, 1];
	}
	graphics {
    default: switch_check_road_final;
    anim_control: switch_check_road_northwest;
	}
}
Attachments
west.png
(424.42 KiB) Not downloaded yet
Eddi
Tycoon
Tycoon
Posts: 7530
Joined: 17 Jan 2007 00:14

Re: NML House with check road position complete example??

Post by Eddi »

temporal8 wrote: 15 Nov 2020 04:45And this is the code where I add the corners, but while it works, it does it in an unwanted way, because in a straight street, it takes the next portion of the road as diagonal to the tile and shows the graph of the corner.
that's because the checks are executed from bottom to top, so you check "west" first, and "southwest" later, but you never arrive at "southwest" because it ends at the first one that is true.
You might not exactly be interested in Ferion, but if you are, have fun :)
temporal8
Engineer
Engineer
Posts: 115
Joined: 17 May 2019 14:15

Re: NML House with check road position complete example??

Post by temporal8 »

Ok, I understand, but then how do I make the code keep executing and not finish in the first true? (sorry, I'm not a coder, I'm trying my best).

I tried to change the order but obviously it doesn't work, so here I am missing something that allows me to read to the end and just decide which one is true from all the avaivable options.

Example:
Here it will read northwest and southwest but it will never get to westcorner because either northwest or southwest will be true before, so how do I get it to read all three and then decide which one is true?

Thank you very much in advance and for the time to teach me.
switch (FEAT_HOUSES, SELF, switch_check_road_westcorner, nearby_tile_class(1, -1)) {
TILE_CLASS_ROAD: 2;
switch_check_road_southeast;
}

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


switch (FEAT_HOUSES, SELF, switch_check_road_northwest, nearby_tile_class(0, -1)) {
TILE_CLASS_ROAD: 0;
switch_check_road_southwest;
}
Eddi
Tycoon
Tycoon
Posts: 7530
Joined: 17 Jan 2007 00:14

Re: NML House with check road position complete example??

Post by Eddi »

Ok, I understand, but then how do I make the code keep executing and not finish in the first true? (sorry, I'm not a coder, I'm trying my best).
you can test more than one tile in the same switch, by combining the checks with logic operators.

for example (pseudocode)

Code: Select all

switch (FEAT_HOUSES, SELF, switch_combined,
    nearby_tile_class( 0, -1) == TILE_CLASS_ROAD |
    nearby_tile_class(-1,  0) == TILE_CLASS_ROAD << 1 |
    nearby_tile_class( 0,  1) == TILE_CLASS_ROAD << 2 |
    nearby_tile_class( 1,  0) == TILE_CLASS_ROAD << 3
) {
	0: // none
	1: // one
	2:
	4:
	8:
	3: // two
	5:
	6:
	9:
	10:
	12:
	7: // three
	11:
	13:
	14:
	15: // four
}
Last edited by Eddi on 15 Nov 2020 20:47, edited 3 times in total.
You might not exactly be interested in Ferion, but if you are, have fun :)
temporal8
Engineer
Engineer
Posts: 115
Joined: 17 May 2019 14:15

Re: NML House with check road position complete example??

Post by temporal8 »

I do not understand this, Obviously. :D :D

My thought was, I detect NW, I detect NE, so I show the NorthCorner graph, obviously I'm not doing it right, I'm not a programmer and I don't know the structure or the programming language, but I do my best to keep going. There are many things in the NML guide that take for granted that you are a programmer and already know certain things.
switch (FEAT_HOUSES, SELF, switch_combined_northcorner,
nearby_tile_class(0, -1) == TILE_CLASS_ROAD |
nearby_tile_class(-1, 0) == TILE_CLASS_ROAD << 1
) {
TILE_CLASS_ROAD: 0;
switch_combined_eastcorner;
}

Code: Select all

grf {
	grfid: "NML\44";
	name: string(STR_REALHOUSETOWN_NAME);
	desc: string(STR_REALHOUSETOWN_DESC);
	version: 0;
	min_compatible_version: 0;
}

cargotable { 
	PASS, MAIL, GOOD, FOOD , RCYC
		
}

/*Road North East*/
spriteset (spriteset_realhousetown_northeast, "realhousetown.png") {
	[98, 8, 44, 36, -22, 0, NOCROP]
}
alternative_sprites (spriteset_realhousetown_northeast, ZOOM_LEVEL_IN_4X, BIT_DEPTH_32BPP, "realhousetown_32.png") { 
  	[0, 0, 256, 256, -109, -154, NOCROP]
}

spritelayout spritelayout_realhousetown_northeast {
	ground {
		sprite: GROUNDSPRITE_NORMAL;
	}
	building {
		sprite: spriteset_realhousetown_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_southeast, "realhousetown.png") {
	[98, 8, 44, 36, -22, 0, NOCROP]
}
alternative_sprites (spriteset_realhousetown_southeast, ZOOM_LEVEL_IN_4X, BIT_DEPTH_32BPP, "realhousetown_32.png") { 
  	[259, 0, 256, 256, -109, -154, NOCROP]
}

spritelayout spritelayout_realhousetown_southeast {
	ground {
		sprite: GROUNDSPRITE_NORMAL;
	}
	building {
		sprite: spriteset_realhousetown_southeast;
		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 West*/

spriteset (spriteset_realhousetown_southwest, "realhousetown.png") {
	[98, 8, 44, 36, -22, 0, NOCROP]
}
alternative_sprites (spriteset_realhousetown_southwest, ZOOM_LEVEL_IN_4X, BIT_DEPTH_32BPP, "realhousetown_32.png") { 
  	[518, 0, 256, 256, -109, -154, NOCROP]
}

spritelayout spritelayout_realhousetown_southwest{
	ground {
		sprite: GROUNDSPRITE_NORMAL;
	}
	building {
		sprite: spriteset_realhousetown_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_northwest, "realhousetown.png") {
	[98, 8, 44, 36, -22, 0, NOCROP]
}
alternative_sprites (spriteset_realhousetown_northwest, ZOOM_LEVEL_IN_4X, BIT_DEPTH_32BPP, "realhousetown_32.png") { 
  	[777, 0, 256, 256, -109, -154, NOCROP]
}

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

/* North, South... */

/* North Corner */
spriteset (spriteset_realhousetown_northcorner, "realhousetown.png") {
	[98, 8, 44, 36, -22, 0, NOCROP]
}
alternative_sprites (spriteset_realhousetown_northcorner, ZOOM_LEVEL_IN_4X, BIT_DEPTH_32BPP, "realhousetown_32.png") { 
  	[0, 259, 256, 256, -109, -154, NOCROP]
}

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

spriteset (spriteset_realhousetown_eastcorner, "realhousetown.png") {
	[98, 8, 44, 36, -22, 0, NOCROP]
}
alternative_sprites (spriteset_realhousetown_eastcorner, ZOOM_LEVEL_IN_4X, BIT_DEPTH_32BPP, "realhousetown_32.png") { 
  	[259, 259, 256, 256, -109, -154, NOCROP]
}

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

spriteset (spriteset_realhousetown_southcorner, "realhousetown.png") {
	[98, 8, 44, 36, -22, 0, NOCROP]
}
alternative_sprites (spriteset_realhousetown_southcorner, ZOOM_LEVEL_IN_4X, BIT_DEPTH_32BPP, "realhousetown_32.png") { 
  	[518, 259, 256, 256, -109, -154, NOCROP]
}

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

spriteset (spriteset_realhousetown_westcorner, "realhousetown.png") {
	[98, 8, 44, 36, -22, 0, NOCROP]
}
alternative_sprites (spriteset_realhousetown_westcorner, ZOOM_LEVEL_IN_4X, BIT_DEPTH_32BPP, "realhousetown_32.png") { 
  	[777, 259, 256, 256, -109, -154, NOCROP]
}

spritelayout spritelayout_realhousetown_westcorner {
	ground {
		sprite: GROUNDSPRITE_NORMAL;
	}
	building {
		sprite: spriteset_realhousetown_westcorner;
		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: 7;
	CB_RESULT_DO_NOTHING;
}

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

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


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

switch (FEAT_HOUSES, SELF, switch_combined_westcorner, 
    nearby_tile_class(1, 0) == TILE_CLASS_ROAD |
    nearby_tile_class(0, -1) == TILE_CLASS_ROAD << 1
) {
	TILE_CLASS_ROAD:  3;
	switch_check_road_northwest;
}

switch (FEAT_HOUSES, SELF, switch_combined_southcorner, 
    nearby_tile_class(0, 1) == TILE_CLASS_ROAD |
    nearby_tile_class(1, 0) == TILE_CLASS_ROAD << 1
) {
	TILE_CLASS_ROAD: 2;
	switch_combined_westcorner;
}

switch (FEAT_HOUSES, SELF, switch_combined_eastcorner, 
    nearby_tile_class(-1, 0) == TILE_CLASS_ROAD |
    nearby_tile_class(0, 1) == TILE_CLASS_ROAD << 1
) {
	TILE_CLASS_ROAD: 1;
	switch_combined_southcorner;
}

switch (FEAT_HOUSES, SELF, switch_combined_northcorner, 
   nearby_tile_class(0, -1) == TILE_CLASS_ROAD |
   nearby_tile_class(-1, 0) == TILE_CLASS_ROAD << 1
) {
	TILE_CLASS_ROAD: 0;
	switch_combined_eastcorner;
}


switch (FEAT_HOUSES, SELF, switch_check_road_final, animation_frame) {
	0:  spritelayout_realhousetown_northcorner;
	1:  spritelayout_realhousetown_eastcorner;
	2:  spritelayout_realhousetown_southcorner;
	3:  spritelayout_realhousetown_westcorner;
	4:  spritelayout_realhousetown_northwest;
	5:  spritelayout_realhousetown_southwest;
	6:  spritelayout_realhousetown_southeast;
	7:  spritelayout_realhousetown_northeast;
	spritelayout_realhousetown_northcorner;
}

/* Switches End */

item (FEAT_HOUSES, item_realhousetown, -1, HOUSE_SIZE_1X1) {
	property {
		substitute: 2;
		override: 2;
		population:                 90;
		mail_multiplier:            30;
		accepted_cargos:            [[PASS, 4], [MAIL, 3], [GOOD, 3]];
		probability: 10;
		years_available:            [1855, 2050];
		name: string(STR_REALHOUSETOWN_HOUSE);
                availability_mask: [ALL_TOWNZONES, ALL_CLIMATES];
		building_flags    : bitmask(HOUSE_FLAG_ANIMATE);
		animation_info    : [ANIMATION_LOOPING, 1];
	}
	graphics {
    default: switch_check_road_final;
    anim_control: switch_combined_northcorner;
	}
}
Image
Attachments
no_corners.jpg
(1.98 MiB) Not downloaded yet
Post Reply

Return to “NewGRF Technical Discussions”

Who is online

Users browsing this forum: No registered users and 4 guests