Buildings by Town Population?

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

Moderator: Graphics Moderators

Post Reply
temporal8
Route Supervisor
Route Supervisor
Posts: 429
Joined: 17 May 2019 14:15

Buildings by Town Population?

Post by temporal8 »

Hello, how can I make certain buildings appear only when a city reaches "X" number of inhabitants?

Thanks in advance.
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
User avatar
jfs
Tycoon
Tycoon
Posts: 1750
Joined: 08 Jan 2003 23:09
Location: Denmark

Re: Buildings by Town Population?

Post by jfs »

Put them in the appropriate town zone. The higher level zones appear from the centre of the town gradually as the town grows larger.

If that isn't enough for what you want, implement callback 0x17 (house construction check) and test town variable 0x82 (population) to allow/deny construction.
temporal8
Route Supervisor
Route Supervisor
Posts: 429
Joined: 17 May 2019 14:15

Re: Buildings by Town Population?

Post by temporal8 »

jfs wrote: 12 Jan 2022 13:02 Put them in the appropriate town zone. The higher level zones appear from the centre of the town gradually as the town grows larger.

If that isn't enough for what you want, implement callback 0x17 (house construction check) and test town variable 0x82 (population) to allow/deny construction.
Thanks for reply, and how would this be in NML? sorry im not a coder, i understand some things, copy and paste, but i can´t create some things from scratch.

And to make myself more difficult, I already have a construction_check to allow only 1 building per city,
What would the combined switch be like?:

Code: Select all

switch(FEAT_HOUSES, SELF, number_realhousetown_188, same_house_count_town >= 1) {
 1: return 0;
 return 1;
}

.....................

	}
	graphics {
    default: switch_check_road_final_188;
    anim_control: switch_check_road_northwest_188;
    construction_check: number_realhousetown_188;
	}
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
User avatar
jfs
Tycoon
Tycoon
Posts: 1750
Joined: 08 Jan 2003 23:09
Location: Denmark

Re: Buildings by Town Population?

Post by jfs »

You'd need to chain the two switches, I think.

Code: Select all

switch(FEAT_HOUSES, PARENT, town_population_188, population >= 1000) {
  1: return 1;
  return 0;
}

switch(FEAT_HOUSES, SELF, number_realhousetown_188, same_house_count_town >= 1) {
 1: return 0;
 return town_population_188;
}
Totally untested.
This should check first if there is already one or more of the same house in the town. Return 0 (reject building) if there is already one.
If there is not one, call town_population_188 in chain to check if the population of the town is 1000 or more. Succeed if it is, fail if it's less.
You would still use the number_realhousetown_188 callback for the construction_check callback in the house definition, so no changes to that.

The town_population_188 switch uses PARENT instead of SELF to be able to look at the town's properties instead of the house's properties. The town is the parent of a house.
User avatar
2TallTyler
Route Supervisor
Route Supervisor
Posts: 495
Joined: 11 Aug 2019 18:15
Contact:

Re: Buildings by Town Population?

Post by 2TallTyler »

The need to chain switches disappeared when we got the ability to use NML switches like functions in a regular programming language. You can now have the house check multiple switches which return boolean results (true or false, 1 or 0 in NML), and additionally pass arguments to switches, like the population required for the house. This lets you reuse code, which is a crucial programming concept for ease of maintenance.

You can also just use `return` to return the calculated value, instead of having to specify `1: return 1; return 0;`

For this example, here's the callback on the house:

Code: Select all

graphics {
	construction_check: IsUniqueHouse() && HasPopulation(1000);
}
And the functions themselves are below. As usual with NML, they need to be defined before the house which calls them. Personally, I keep them in `functions.nml` which is merged into my big NML file somewhere below the header but above any houses.

Code: Select all

switch (FEAT_HOUSES, SELF, IsUniqueHouse, same_house_count_town == 0) {return;}

/* Note: Check population is inaccurate when generating towns. This will only work properly when growing towns in-game. */
switch (FEAT_HOUSES, PARENT, HasPopulation, required, population >= required) {return;}
You might find more useful checks in my `functions.nml` for Improved Town Layouts. Sorry, they're not currently documented as I've been doing in my newer sets like Lumberjack Industries (obviously, this industry code won't work for houses, but I do recommend documenting your functions like this to make your own life easier!).
Wahazar
Tycoon
Tycoon
Posts: 1451
Joined: 18 Jan 2014 18:10

Re: Buildings by Town Population?

Post by Wahazar »

2TallTyler wrote: 12 Jan 2022 17:42 construction_check: IsUniqueHouse() && HasPopulation(1000);
Wow, nice to know! It should decrease number of switches chains in my project by factor of 10 :)
temporal8
Route Supervisor
Route Supervisor
Posts: 429
Joined: 17 May 2019 14:15

Re: Buildings by Town Population?

Post by temporal8 »

Thanks a lot jfs and 2TallTyler, I'm going to check it to see what I can do. :bow:
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
Wahazar
Tycoon
Tycoon
Posts: 1451
Joined: 18 Jan 2014 18:10

Re: Buildings by Town Population?

Post by Wahazar »

2TallTyler wrote: 12 Jan 2022 17:42 The need to chain switches disappeared when we got the ability to use NML switches like functions in a regular programming language.
You can now have the house check multiple switches which return boolean results [...]
How switch functions with && operator are resolved? From left or right side, or both are checked regardless of their result?
I would like to check simply switch first and proceed to more complicated (for example circular check) only if necessary to fulfill whole condition.
User avatar
jfs
Tycoon
Tycoon
Posts: 1750
Joined: 08 Jan 2003 23:09
Location: Denmark

Re: Buildings by Town Population?

Post by jfs »

Usually && is a left-to-right short-circuiting operator.
That means it evaluates the left side first, if the left side is false then the entire expression must be false, and it "short-circuits" the evaluation to ignore the right side entirely.
If the left side instead is true, then the result will depend on the right side, so only then is the right side evaluated, and the result will be what the right side evaluates to.

Additionally, it's left-associative, meaning that a chain such as "a && b && c" will start by evaluating a, if that's true then evaluate b, if that's also true then evaluate c. If a is false then b and c are never evaluated, and if b is false then c is never evaluated.

If you wanted to add an alternative condition that could allow the building regardless, then you could use an "or" expression with the || operator.

Code: Select all

switch (FEAT_HOUSES, PARENT, IsCity, is_city == 1) {return;}

graphics {
	construction_check: ( IsUniqueHouse() && HasPopulation(1000) ) || IsCity();
}
That would let cities build as many of that house they want, and regardless their population.
Post Reply

Return to “NewGRF Technical Discussions”

Who is online

Users browsing this forum: No registered users and 3 guests