[Patch] Open/Close Airport for Aircraft
Moderator: OpenTTD Developers
- pduthie_au
- Engineer
- Posts: 32
- Joined: 31 Aug 2006 01:33
[Patch] Open/Close Airport for Aircraft
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 ?
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 with multiple stations with vehicle acceptance buttons.png (98.9 KiB) Viewed 1837 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.
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
Projects: NFORenum (download) | PlaneSet (Website) | grfcodec (download) | grfdebug.log parser
Re: String Comparison question
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.pduthie_au wrote:I want to find out if a station name contains a specific word.
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'.DaleStan wrote:This is a generc C programming question, not an OpenTTD question, but try strstr.
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."
<@[R-Dk]FoRbiDDeN> "HELP, this litte arrow thing keeps following my mouse, and I can't make it go away."
- pduthie_au
- Engineer
- Posts: 32
- Joined: 31 Aug 2006 01:33
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.
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.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.
- pduthie_au
- Engineer
- Posts: 32
- Joined: 31 Aug 2006 01:33
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.Bjarni wrote: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.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.
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 ?
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.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.
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.
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:Also, by default what value does a boolean have if it's not set ? I assumed it would be false, but maybe not.
Most likely it would need to be done in ProcessAircraftOrder() in aircraft_cmd.cpduthie_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 ?
- pduthie_au
- Engineer
- Posts: 32
- Joined: 31 Aug 2006 01:33
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: 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.
Yeah, that sounds like a good idea. Thanks for your help so far.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.
Thanks, I'll look further into that.Bjarni wrote:Most likely it would need to be done in ProcessAircraftOrder() in aircraft_cmd.c
- pduthie_au
- Engineer
- Posts: 32
- Joined: 31 Aug 2006 01:33
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.

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
- SameRowAsOptions.png (47.2 KiB) Viewed 1714 times
-
- Buttons on Bottom row
- BottomRow.png (48.86 KiB) Viewed 1731 times
- pduthie_au
- Engineer
- Posts: 32
- Joined: 31 Aug 2006 01:33
- pduthie_au
- Engineer
- Posts: 32
- Joined: 31 Aug 2006 01:33
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.
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;
Code: Select all
if (closed) {
HideWindowWidget(w, button_a);
ShowWindowWidget(w, button_b);
} else {
HideWindowWidget(w, button_b);
ShowWindowWidget(w, button_a);
}
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.
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 bypduthie_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.
Code: Select all
HASBIT(byte, v->type - VEH_Train)
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).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.
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).
I could, but it's against the forum policypduthie_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.
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.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 ?
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.
- pduthie_au
- Engineer
- Posts: 32
- Joined: 31 Aug 2006 01:33
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: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 bypduthie_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.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.Code: Select all
HASBIT(byte, v->type - VEH_Train)
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.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.
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.
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.hpduthie_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.
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.pduthie_au wrote: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.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 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.
- pduthie_au
- Engineer
- Posts: 32
- Joined: 31 Aug 2006 01:33
Should this work ? This is from station_gui.c
along with this from aircraft_cmd.c
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
to
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
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;
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++;
}
EDIT:
I fixed it. I changed
Code: Select all
if (HASBIT(st->closed_to_vehicletype,v->type-VEH_Aircraft)) {
Code: Select all
if (HASBIT(st->closed_to_vehicletype,VEH_Close_Aircraft)) {
Last edited by pduthie_au on 06 Oct 2006 12:39, edited 1 time in total.
- Born Acorn
- Tycoon
- Posts: 7596
- Joined: 10 Dec 2002 20:36
- Skype: bornacorn
- Location: Wrexham, Wales
- Contact:
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.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 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
- pduthie_au
- Engineer
- Posts: 32
- Joined: 31 Aug 2006 01:33
Who is online
Users browsing this forum: No registered users and 22 guests