[Patch] Open/Close Airport for Aircraft

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

Moderator: OpenTTD Developers

User avatar
pduthie_au
Engineer
Engineer
Posts: 32
Joined: 31 Aug 2006 01:33

[Patch] Open/Close Airport for Aircraft

Post by pduthie_au »

This post was originally a question about string comparison, but has since changed to be about an open/close option for stations to accept/reject aircraft.

Now works on Aircraft, Ships and Road Vehicles. Trains will be tricky due to possibility of killing networks.

For Aircraft, will check before landing that station is open, otherwise aborts landing and continues to circle airport.

Ships and Road Vehicles will skip closed stations.

Todo :
- Orders window - show stations that are closed
- Only works for new games at the moment as the variable in the Station struct is not saved at the moment, also need to work out the loading issue as well

Future :
- Possibly Trains as well ?
Attachments
closestationtovehicle_patch_miniin_6661_v3.patch
Patch to close stations to road vehicles, ships and planes V3. Aircraft will circle a closed airport until it is reopened. Still incomplete, but works. See above for Todo list. Note - for MiniIN 6661.
(23.36 KiB) Downloaded 367 times
Screenshot showing stations with buttons to turn on/off vehicles. MiniIN version
Screenshot showing stations with buttons to turn on/off vehicles. MiniIN version
Screenshot with multiple stations with vehicle acceptance buttons.png (98.9 KiB) Viewed 1836 times
closestationtovehicle_patch_trunk_6732_v4.patch
Patch to close stations to road vehicles, ships and planes V3. Aircraft will circle a closed airport until it is reopened. Still incomplete, but works. See above for Todo list. Note - for Trunk 6698.
(11.75 KiB) Downloaded 310 times
Last edited by pduthie_au on 11 Oct 2006 08:13, edited 12 times in total.
DaleStan
TTDPatch Developer
TTDPatch Developer
Posts: 10285
Joined: 18 Feb 2004 03:06
Contact:

Post by DaleStan »

This is a generc C programming question, not an OpenTTD question, but try strstr.
To get a good answer, ask a Smart Question. Similarly, if you want a bug fixed, write a Useful Bug Report. No TTDPatch crashlog? Then follow directions.
Projects: NFORenum (download) | PlaneSet (Website) | grfcodec (download) | grfdebug.log parser
Bjarni
Tycoon
Tycoon
Posts: 2088
Joined: 08 Mar 2004 13:10

Re: String Comparison question

Post by Bjarni »

pduthie_au wrote:I want to find out if a station name contains a specific word.
Maybe we can help finding the right solution if you explain what you want to do. We might be able to find a nicer and faster way to solve your issue than comparing strings. It all depends on what you want the end result to be. Thinking about how the string system works, I don't think looking into the string is the right way to do anything.
User avatar
Darkvater
Tycoon
Tycoon
Posts: 3053
Joined: 24 Feb 2003 18:45
Location: Hong Kong

Post by Darkvater »

DaleStan wrote:This is a generc C programming question, not an OpenTTD question, but try strstr.
I think he can't even get the string. You retrieve a string with GetString() or GetStringPtr(). The difference between the two is that GetStringPtr() retrieves the string-template, eg the static string without any dynamic stuff. For example if you have a string 'Train is heading to {STATION}'. GetStringPtr() will get this string, while GetString(), after properly setting up the parameters with SetDParam() will retrieve 'Train is heading to New Fingfield'.

If you just want {STATION} look around strings.c:848 where it says "case 0x9A: { // {STATION}"

Look here for more information about strings: http://wiki.openttd.org/index.php/Strings
TrueLight: "Did you bother to read any of the replies, or you just pressed 'Reply' and started typing?"
<@[R-Dk]FoRbiDDeN> "HELP, this litte arrow thing keeps following my mouse, and I can't make it go away."
User avatar
pduthie_au
Engineer
Engineer
Posts: 32
Joined: 31 Aug 2006 01:33

Post by pduthie_au »

No, I got the string, and even managed to compare it, but ended up with wierd errors when the code ran. It's related to the idea about adding the string CLOSED to an airport name to make aircraft skip it in their orders. I can compare the string, but actually getting the result I want is another thing altogether. It keeps giving errors about an incorrect string. I've given up on it at the moment. I'll revisit it again when I have some time.
Bjarni
Tycoon
Tycoon
Posts: 2088
Joined: 08 Mar 2004 13:10

Post by Bjarni »

pduthie_au wrote:It's related to the idea about adding the string CLOSED to an airport name to make aircraft skip it in their orders.
Another (and simpler) solution could be to add a bool (maybe it's possible to add it as a flag in a flag var, didn't check that right now) to the station struct to tell if the airport is closed. This way it's quick to test (checking a bool is somewhat faster than string comparison) and we can even add a CLOSED string, that can be translated.
User avatar
pduthie_au
Engineer
Engineer
Posts: 32
Joined: 31 Aug 2006 01:33

Post by pduthie_au »

Bjarni wrote:
pduthie_au wrote:It's related to the idea about adding the string CLOSED to an airport name to make aircraft skip it in their orders.
Another (and simpler) solution could be to add a bool (maybe it's possible to add it as a flag in a flag var, didn't check that right now) to the station struct to tell if the airport is closed. This way it's quick to test (checking a bool is somewhat faster than string comparison) and we can even add a CLOSED string, that can be translated.
I did some fiddling with that, but I don't fully understand how to add widgets to a window - I did get them to add, but couldn't get the closed/open buttons to correctly enable/disable when the opposing one was clicked. Also, by default what value does a boolean have if it's not set ? I assumed it would be false, but maybe not.

I did actually get it to set the variable after a fashion, but then couldn't work out how to get the aircraft to skip the destination if it was closed. What file/function should I look in for this ?
Bjarni
Tycoon
Tycoon
Posts: 2088
Joined: 08 Mar 2004 13:10

Post by Bjarni »

pduthie_au wrote:I did some fiddling with that, but I don't fully understand how to add widgets to a window - I did get them to add, but couldn't get the closed/open buttons to correctly enable/disable when the opposing one was clicked.
Usually we would just make a "close airport" button and change it to "open airport" when it's closed and then write the closed state somewhere.
If you really want a button to remain pressed... hmm, it would take a bit of GUI work to do, but I guess it can be done, but I would prefer it stay in the style we use in the other windows.
pduthie_au wrote:Also, by default what value does a boolean have if it's not set ? I assumed it would be false, but maybe not.
Always set it to something. Set it when building the airport. It would need to be saved and set if the game is too old to contain this bool, but try to get it to work in a new game first and don't care for savegames until everything else is working.
pduthie_au wrote:I did actually get it to set the variable after a fashion, but then couldn't work out how to get the aircraft to skip the destination if it was closed. What file/function should I look in for this ?
Most likely it would need to be done in ProcessAircraftOrder() in aircraft_cmd.c
User avatar
pduthie_au
Engineer
Engineer
Posts: 32
Joined: 31 Aug 2006 01:33

Post by pduthie_au »

Bjarni wrote: Usually we would just make a "close airport" button and change it to "open airport" when it's closed and then write the closed state somewhere.
If you really want a button to remain pressed... hmm, it would take a bit of GUI work to do, but I guess it can be done, but I would prefer it stay in the style we use in the other windows.
I was thinking along the lines of 2 buttons at the bottom of the window - Open and Closed. When the airport is Open, the open button is disabled and the close button is enabled and vice versa when the airport is closed.
Bjarni wrote:Always set it to something. Set it when building the airport. It would need to be saved and set if the game is too old to contain this bool, but try to get it to work in a new game first and don't care for savegames until everything else is working.
Yeah, that sounds like a good idea. Thanks for your help so far.
Bjarni wrote:Most likely it would need to be done in ProcessAircraftOrder() in aircraft_cmd.c
Thanks, I'll look further into that.
User avatar
pduthie_au
Engineer
Engineer
Posts: 32
Joined: 31 Aug 2006 01:33

Post by pduthie_au »

Ok, here's some options for the GUI. I got the code working {stupid C, requiring a break in a switch statement...:)}.

How do you switch the text on a single button ? I'm leaning towards the single button option, but I need to switch the text on them. Eventually, this could become a multiple option to close the station for other vehicle types, but at the moment it's just for aircraft.

I will post some code, but at the moment I'm working on a really old version of the code, and it has some other mods in it as well (such as bulldozing an airport leaves the ground underneath owned by the player) I'll download the latest source (would people prefer this in the MiniIN or in a format for the main trunk ?) and put it into this.

Could a mod also prune out some of the replies that where originally for the string comparison stuff. I'll fix up the first post with some more detail shortly.
Attachments
Single button on same row as options button
Single button on same row as options button
SameRowAsOptions.png (47.2 KiB) Viewed 1713 times
Buttons on Bottom row
Buttons on Bottom row
BottomRow.png (48.86 KiB) Viewed 1730 times
User avatar
pduthie_au
Engineer
Engineer
Posts: 32
Joined: 31 Aug 2006 01:33

Post by pduthie_au »

How do I save the stations with the open/closed variable ? If i load a game that doesn't have the variable in station struct, what will happen then ? Can I set it to default to false in this situation ?
Mateo
Engineer
Engineer
Posts: 11
Joined: 04 Aug 2006 23:21
Location: Espoo, Finland

Post by Mateo »

If the airport is closed, will outcoming traffic be also blocked then? I would prefer "Deny/Allow incoming traffic" button. And to make things consistent, this button should be available for all stations, not just airports.
User avatar
pduthie_au
Engineer
Engineer
Posts: 32
Joined: 31 Aug 2006 01:33

Post by pduthie_au »

I don't think it will affect outgoing traffic, as all it does is check if the current order is to a station that is closed to aircraft, and if it is it skips to the next order. I do want to extend it to all stations, but need to consider for trains what will happen to transport routes when a train is sent to another destination. Ships and Road vehicles should be fine. Also, the button does appear for all station types, but is only enabled for airports.
Bjarni
Tycoon
Tycoon
Posts: 2088
Joined: 08 Mar 2004 13:10

Post by Bjarni »

pduthie_au wrote:How do you switch the text on a single button ? I'm leaning towards the single button option, but I need to switch the text on them.

Code: Select all

w->widget[widget number].data          = STR_BUTTON;
w->widget[DEPOT_WIDGET_BUILD].tooltips = STR_BUTTON_TOOLTIP;
Depending on how you create the click event for the button, you can also (in WE_PAINT) type

Code: Select all

if (closed) {
   HideWindowWidget(w, button_a);
   ShowWindowWidget(w, button_b);
} else {
   HideWindowWidget(w, button_b);
   ShowWindowWidget(w, button_a);
}
Then you can create two buttons in the widget array at the same location and it will only show one of them at a time. The benefit from this would be that they don't have the same widget number and click actions can be based on the widget number in WE_CLICK.
You can try to look in depot_gui.c to see how to modify a window to make it show stuff, that's not in the widget array, but some of it is likely too complex for what you are doing (resizing widgets, moving widgets and so on), so it's ok if you don't get everything in that file. One adwiseable thing is to make an enum with widget names as this would make the code more readable and make it easier to add widgets without messing with code that's hardcoded to the current order of the widgets. Later additions will just have to deal with the enum and the rest of the code will be ok.

Also it's ok not to get all of the GUI stuff overnight, so nobody will kill you for asking for more help if you fail to figure out something.
pduthie_au wrote:Eventually, this could become a multiple option to close the station for other vehicle types, but at the moment it's just for aircraft.
Then make this a byte right away so we only have to modify savegames once and solve the issue where we need to figure out how to load a bool and put it in a byte (it should be possible, but it's easier not to create that problem in the first place), then make it a bitmask. I would say it would be best to give bit 0 to trains, 1 to road vehicles, 2 to ships and 3 to aircrafts because then we can check if the bit is set for a particular type by

Code: Select all

HASBIT(byte, v->type - VEH_Train)
The types are actually numbered 16 to 19, but with the VEH_Train offset, we can call them 0 to 3, which will then do as the bit numbers in the byte.
pduthie_au wrote:I will post some code, but at the moment I'm working on a really old version of the code, and it has some other mods in it as well (such as bulldozing an airport leaves the ground underneath owned by the player) I'll download the latest source (would people prefer this in the MiniIN or in a format for the main trunk ?) and put it into this.
When writing anything, always work from an svn checkout of the trunk. This will make it way easier to apply the code to the trunk as stuff have changed since 0.4.8 (like we got a new widget system).

Also about owning the land of the bulldozed airport. There is another option. Automatic removal of the airport when building another one (like with train stations).
pduthie_au wrote:Could a mod also prune out some of the replies that where originally for the string comparison stuff. I'll fix up the first post with some more detail shortly.
I could, but it's against the forum policy
pduthie_au wrote:How do I save the stations with the open/closed variable ? If i load a game that doesn't have the variable in station struct, what will happen then ? Can I set it to default to false in this situation ?
First you increase the savegame version by one in the top of saveload.c, then you edit _station_desc[] in station_cmd.c to save/load this bool if the savegame version if the new version or newer.

Setting the variable in savegames, that are too old to have this bool is done in AfterLoadGame() in openttd.c. I presume you need to loop all stations and set this bool to false.


Have you considered what to do if the airport is closed? If we got X planes flying between two airports and we close one of them, then we block the other one with X planes. In that case it would be best to head for the hangar in the airport previous to the closed one and stay in there until the next airport is reopened.
User avatar
pduthie_au
Engineer
Engineer
Posts: 32
Joined: 31 Aug 2006 01:33

Post by pduthie_au »

Bjarni wrote:
pduthie_au wrote:Eventually, this could become a multiple option to close the station for other vehicle types, but at the moment it's just for aircraft.
Then make this a byte right away so we only have to modify savegames once and solve the issue where we need to figure out how to load a bool and put it in a byte (it should be possible, but it's easier not to create that problem in the first place), then make it a bitmask. I would say it would be best to give bit 0 to trains, 1 to road vehicles, 2 to ships and 3 to aircrafts because then we can check if the bit is set for a particular type by

Code: Select all

HASBIT(byte, v->type - VEH_Train)
The types are actually numbered 16 to 19, but with the VEH_Train offset, we can call them 0 to 3, which will then do as the bit numbers in the byte.
Ok, so I can check that when I'm dealing with a vehicle, what about when I'm dealing with the station gui stuff ? I'm not exactly sure on how to deal with bitmasks. I know the logic behind them, but the last time I really programmed in C was in 1991 ! Since then I've been mainly a VB programmer.
Bjarni wrote:Have you considered what to do if the airport is closed? If we got X planes flying between two airports and we close one of them, then we block the other one with X planes. In that case it would be best to head for the hangar in the airport previous to the closed one and stay in there until the next airport is reopened.
I thought there was an issue with stopping vehicles in Hangars using code ? I seem to remember someone saying that you could send an Aircraft to a Hangar for replacement or service, but not make it stop. I could be wrong on this though, and probably am.

Thanks for all your help so far, it's actually starting to take shape. The Rail vehicles skipping stations might be an issue, and we may need to have seperate buttons to stop vehicles of different types as well.
Bjarni
Tycoon
Tycoon
Posts: 2088
Joined: 08 Mar 2004 13:10

Post by Bjarni »

pduthie_au wrote:Ok, so I can check that when I'm dealing with a vehicle, what about when I'm dealing with the station gui stuff ? I'm not exactly sure on how to deal with bitmasks. I know the logic behind them, but the last time I really programmed in C was in 1991 ! Since then I've been mainly a VB programmer.
In our case, it's not that tricky. To make readable code, we got some macros to do this for us, so we use HASBIT(), CLRBIT(), SETBIT() ang TOGGLEBIT(). All of those take two arguments. The first is the variable to work on and the last is the bitnumber to do the action to (0 to 7 for bytes). HASBIT() acts as a bool. We also got macros to handle more than one bit at a time, but I don't think you need those. They are all defined in macros.h
pduthie_au wrote:
Bjarni wrote:Have you considered what to do if the airport is closed? If we got X planes flying between two airports and we close one of them, then we block the other one with X planes. In that case it would be best to head for the hangar in the airport previous to the closed one and stay in there until the next airport is reopened.
I thought there was an issue with stopping vehicles in Hangars using code ? I seem to remember someone saying that you could send an Aircraft to a Hangar for replacement or service, but not make it stop. I could be wrong on this though, and probably am.
I said that a while ago, but it was in a specific case. When a vehicle entered a depot/hangar, the owner sent a command to autoreplace it. Because of lag in multiplayer, the command would not be executed before the vehicle had left the depot again. In this case (and in autoreplace as it is today) all clients will have the code to figure out if the vehicle should be stopped so we can stop it if needed on all clients right awaty in sync without sending a command to do it as doing something locally do not have the network lag issue. I hope you get what I mean here, otherwise I will have to give a longer explanation with examples and stuff.

I don't think stopping is the right thing to do. It should instead still have the green flag (not setting the stopped flag for the vehicle) and instead it should reject moving out of the depot/hangar if the current order is a goto station and that station got the closed bit set.
User avatar
pduthie_au
Engineer
Engineer
Posts: 32
Joined: 31 Aug 2006 01:33

Post by pduthie_au »

Should this work ? This is from station_gui.c

Code: Select all

		case WIDGET_CLOSE_AIRCRAFT: { /* Open-Close station for road */
			Station *st = GetStation(w->window_number);
			if (HASBIT(st->closed_to_vehicletype,VEH_Close_Aircraft)) {
				CLRBIT(st->closed_to_vehicletype,VEH_Close_Aircraft);
				w->widget[WIDGET_CLOSE_AIRCRAFT].data=STR_STATION_OPEN_AIRCRAFT;
				w->widget[WIDGET_CLOSE_AIRCRAFT].tooltips=STR_STATION_OPEN_AIRCRAFT_TIP;
			}
			else {
				SETBIT(st->closed_to_vehicletype,VEH_Close_Aircraft);
				w->widget[WIDGET_CLOSE_AIRCRAFT].data=STR_STATION_CLOSED_AIRCRAFT;
				w->widget[WIDGET_CLOSE_AIRCRAFT].tooltips=STR_STATION_CLOSED_AIRCRAFT_TIP;
			}
			SetWindowDirty(w);
			break;
along with this from aircraft_cmd.c

Code: Select all

	Station *st;

	st = GetStation(v->current_order.dest);
	if (HASBIT(st->closed_to_vehicletype,v->type-VEH_Aircraft)) {
		v->cur_order_index++;
	}
The first section works, because the text strings STR_CLOSED_AIRCRAFT and STR_OPEN_AIRCRAFT are Red and Black respectively, and when the button is clicked, the text changes colour. However, the second section doesn't appear to work correctly as the aircraft ignores the closed flag and doesn't skip to the next order. Any ideas, anyone ? The boolean works great, but the byte doesn't seem to.

EDIT:

I fixed it. I changed

Code: Select all

	if (HASBIT(st->closed_to_vehicletype,v->type-VEH_Aircraft)) {
to

Code: Select all

	if (HASBIT(st->closed_to_vehicletype,VEH_Close_Aircraft)) {
and it now works. It must have been getting the wrong value from v->type-VEH_Aircraft. That should give 3, if v->type =19
Last edited by pduthie_au on 06 Oct 2006 12:39, edited 1 time in total.
User avatar
Born Acorn
Tycoon
Tycoon
Posts: 7596
Joined: 10 Dec 2002 20:36
Skype: bornacorn
Location: Wrexham, Wales
Contact:

Post by Born Acorn »

Hmm. You should do what Bjarni did with Depots and use the red/green flag icons to close or open the airport.
Image
Bjarni
Tycoon
Tycoon
Posts: 2088
Joined: 08 Mar 2004 13:10

Post by Bjarni »

pduthie_au wrote:It must have been getting the wrong value from v->type-VEH_Aircraft. That should give 3, if v->type =19
The problem is that you should always use VEH_Train to set the offset because we want the numbers 0 to 3, not 16 to 19 as the VEH_ actually is. VEH_Train is 16 and hence the first in the line and should be 0.

The following are for aircraft only.
v->type - VEH_Aircraft means 19 - 19 = 0
it should have been:
v->type - VEH_Train, which is 19 - 16 = 3
User avatar
pduthie_au
Engineer
Engineer
Posts: 32
Joined: 31 Aug 2006 01:33

Post by pduthie_au »

Got it. Ok, now to work out how to send an Aircraft to the nearest hangar, but leave the current destination correct even if the station is closed, so when it opens it immediately goes to the correct station.
Post Reply

Return to “OpenTTD Development”

Who is online

Users browsing this forum: Baidu [Spider], Semrush [Bot] and 17 guests