mirror of https://github.com/OpenTTD/OpenTTD
(svn r257) Hopefully now the 0.3.4 tag is correct
commit
e8c8a3f397
680
COPYING
680
COPYING
|
@ -1,340 +1,340 @@
|
|||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Library General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Library General
|
||||
Public License instead of this License.
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Library General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Library General
|
||||
Public License instead of this License.
|
||||
|
|
1174
changelog.txt
1174
changelog.txt
File diff suppressed because it is too large
Load Diff
|
@ -110,7 +110,6 @@ Section "!OpenTTD" Section1
|
|||
File ${PATH_ROOT}changelog.txt
|
||||
File ${PATH_ROOT}COPYING
|
||||
File ${PATH_ROOT}readme.txt
|
||||
File ${PATH_ROOT}known-bugs.txt
|
||||
|
||||
; Copy executable
|
||||
File /oname=openttd.exe ${PATH_ROOT}Release\openttd.exe
|
||||
|
@ -145,7 +144,6 @@ Section "!OpenTTD" Section1
|
|||
CreateShortCut "$SMPROGRAMS\$SHORTCUTS\Uninstall.lnk" "$INSTDIR\uninstall.exe"
|
||||
CreateShortCut "$SMPROGRAMS\$SHORTCUTS\Readme.lnk" "$INSTDIR\Readme.txt"
|
||||
CreateShortCut "$SMPROGRAMS\$SHORTCUTS\Changelog.lnk" "$INSTDIR\Changelog.txt"
|
||||
CreateShortCut "$SMPROGRAMS\$SHORTCUTS\Known-bugs.lnk" "$INSTDIR\known-bugs.txt"
|
||||
!insertmacro MUI_STARTMENU_WRITE_END
|
||||
SectionEnd
|
||||
|
||||
|
@ -215,7 +213,6 @@ Section Uninstall
|
|||
Delete "$INSTDIR\openttd.exe"
|
||||
Delete "$INSTDIR\strgen.exe"
|
||||
Delete "$INSTDIR\COPYING"
|
||||
Delete "$INSTDIR\known-bugs.txt"
|
||||
Delete "$INSTDIR\INSTALL.LOG"
|
||||
Delete "$INSTDIR\crash.log"
|
||||
Delete "$INSTDIR\openttd.cfg"
|
||||
|
|
478
readme.txt
478
readme.txt
|
@ -1,239 +1,239 @@
|
|||
OpenTTD README
|
||||
Last updated: $LastChangedDate: 2004-07-25 21:22:11 +0200 (Sun, 25 Jul 2004) $
|
||||
Release version: 0.3.4
|
||||
------------------------------------------------------------------------
|
||||
|
||||
|
||||
Table of Contents:
|
||||
------------------
|
||||
1.0) About
|
||||
2.0) Contacting
|
||||
* 2.1 Reporting Bugs
|
||||
3.0) Supported Platforms
|
||||
4.0) Running OpenTTD
|
||||
5.0) OpenTTD features
|
||||
6.0) Configuration File
|
||||
7.0) Compiling
|
||||
8.0) Translating
|
||||
* 8.1 Guidelines
|
||||
* 8.2 Translation
|
||||
* 8.3 Previewing
|
||||
X.X) Credits
|
||||
|
||||
|
||||
1.0) About:
|
||||
---- ------
|
||||
OpenTTD is a clone of Transport Tycoon Deluxe, a popular game originally
|
||||
written by Chris Sawyer. It attempts to mimic the original game as closely
|
||||
as possible while extending it with new features.
|
||||
|
||||
|
||||
2.0) Contacting:
|
||||
---- ----------
|
||||
The easiest way to contact the OpenTTD team is by submitting bug reports or
|
||||
posting comments in our forums. You can also chat with us on IRC (#openttd
|
||||
on irc.freenode.net).
|
||||
|
||||
The OpenTTD homepage is http://www.openttd.org/.
|
||||
|
||||
You can find a forum for OpenTTD at
|
||||
http://www.tt-forums.net/index.php?c=20
|
||||
|
||||
|
||||
2.1) Reporting Bugs:
|
||||
---- ---------------
|
||||
To report a bug, please create a SourceForge account and follow the bugs
|
||||
link from our homepage. Please make sure the bug is reproducible and
|
||||
still occurs in the latest daily build or the current SVN version. Also
|
||||
please look through the existing bug reports briefly to see whether the bug
|
||||
is not already known.
|
||||
|
||||
The SourceForge project page URL is: http://sourceforge.net/projects/openttd/
|
||||
Click on "Bugs" to see the bug tracker.
|
||||
|
||||
Please include the following information in your bug report:
|
||||
- OpenTTD version (PLEASE test the latest SVN/daily build)
|
||||
- Bug details, including instructions how to reproduce it
|
||||
- Platform and compiler (Win32, Linux, FreeBSD, ...)
|
||||
- Attach a save game or a screenshot if possible
|
||||
- If this bug only occurred recently please note the last
|
||||
version without the bug and the first version including
|
||||
the bug. That way we can fix it quicker by looking at the
|
||||
changes made.
|
||||
|
||||
|
||||
3.0) Supported Platforms:
|
||||
---- --------------------
|
||||
OpenTTD has been ported to several platforms and operating systems. It shouldn't
|
||||
be very difficult to port it to a new platform. The currently working platforms
|
||||
are:
|
||||
|
||||
Windows - Win32 GDI (faster) or SDL
|
||||
Linux - SDL
|
||||
FreeBSD - SDL
|
||||
MacOS - SDL
|
||||
BeOS - SDL
|
||||
MorphOS - SDL
|
||||
|
||||
|
||||
4.0) Running OpenTTD:
|
||||
---- ----------------
|
||||
|
||||
Before you run OpenTTD, you need to put the game's datafiles into the data/
|
||||
subdirectory. You need the following files from the original Windows version
|
||||
of TTD as OpenTTD makes use of the original TTD artwork.
|
||||
|
||||
IMPORTANT! You need the files from the WINDOWS version of TTD.
|
||||
|
||||
List of the required files:
|
||||
sample.cat
|
||||
trg1r.grf
|
||||
trgcr.grf
|
||||
trghr.grf
|
||||
trgir.grf
|
||||
trgtr.grf
|
||||
|
||||
If you want music you need to copy the gm/ folder from Windows TTD into your OpenTTD folder, not your data folder.
|
||||
|
||||
You can change the data path (which contains savegames as well) in Makefile.config by setting DATA_DIR_PREFIX and USE_HOMEDIR.
|
||||
|
||||
|
||||
5.0) OpenTTD features:
|
||||
---- -----------------
|
||||
|
||||
OpenTTD has a lot of features going beyond the original TTD emulation.
|
||||
Currently there is unfortunately no comprehensive list of features. You could
|
||||
check the features list on the web, and some optional features can be
|
||||
controlled through the Configure patches dialog. We also implement some
|
||||
features known from TTDPatch (http://www.ttdpatch.net/).
|
||||
|
||||
Several important non-standard controls:
|
||||
|
||||
* Use Ctrl to place presignals
|
||||
* Ctrl-d toggles double mode on win32
|
||||
|
||||
|
||||
6.0) Configuration File:
|
||||
---- -------------------
|
||||
The configuration file for OpenTTD (openttd.cfg) is in a simple windows-like
|
||||
.INI format. It's mostly undocumented.
|
||||
|
||||
|
||||
7.0) Compiling:
|
||||
---- ----------
|
||||
Windows:
|
||||
You need Microsoft Visual Studio 6 or .NET. Open the project file
|
||||
and it should build automatically. In case you don't build with SDL,
|
||||
you need to remove WITH_SDL from the project settings.
|
||||
(see also docs/Readme_Windows_MSVC6.0.txt)
|
||||
|
||||
You can also build it using the Makefile with MSys/MingW or Cygwin/MingW.
|
||||
Please read the Makefile for more information.
|
||||
|
||||
Unix:
|
||||
OpenTTD can be built either with "make" or with "jam". To build with
|
||||
"make", just type "make", or "gmake" on non-gnu systems. To build with "jam",
|
||||
first run "./configure" and then "jam". Note that you need SDL to compile
|
||||
OpenTTD.
|
||||
(see also docs/Readme_Mandrake_Linux.txt)
|
||||
|
||||
MacOS:
|
||||
Use "make".
|
||||
|
||||
BeOS:
|
||||
Use "jam".
|
||||
|
||||
FreeBSD
|
||||
Use "gmake".
|
||||
|
||||
MorphOS
|
||||
Use "make". Note that you need the MorphOS SDK and the
|
||||
powersdl.library SDK.
|
||||
|
||||
8.0) Translating:
|
||||
---- -------------------
|
||||
See http://www.openttd.org/translating.php for up-to-date information.
|
||||
|
||||
The use of the online Translator service, located at http://translator.openttd.org.
|
||||
For a username password combo you should contact the development team, either by mail, irc
|
||||
or the forums. The system is straight-forward to use, if you have any troubles, read the
|
||||
online help located there.
|
||||
|
||||
If for some reason the website is down for a longer period of time, the information below
|
||||
might be of help.
|
||||
|
||||
8.1) Guidelines:
|
||||
---- -------------------
|
||||
Here are some translation guidelines which you should follow closely.
|
||||
|
||||
* Please contact the development team before begining the translation process!
|
||||
This avoids double work, as someone else may have already started translating to the same language.
|
||||
* Translators must use the charater set "Windows latin-1", also known as ISO 8859-1.
|
||||
Otherwise, some characters will not display correctly in the game.
|
||||
|
||||
8.2) Translation:
|
||||
---- -------------------
|
||||
So, now that you've notified the development team about your intention to translate
|
||||
(You did, right? Of course you did.) you can pick up english.txt (found in the SVN repository
|
||||
under /lang) and translate.
|
||||
|
||||
You must change the first two lines of the file appropriately:
|
||||
|
||||
##name English-Name-Of-Language
|
||||
##ownname Native-Name-Of-Language
|
||||
|
||||
Note: Do not alter the following parts of the file:
|
||||
|
||||
* String identifiers (the first word on each line)
|
||||
* Parts of the strings which are in curly braces (such as {STRING})
|
||||
* Lines beginning with ## (such as ##id), other than the first two lines of the file
|
||||
|
||||
8.3) Previewing:
|
||||
---- -------------------
|
||||
In order to view the translation in the game, you need to compile your language file
|
||||
with the strgen utility, which is now bundled with the game.
|
||||
|
||||
strgen is a command-line utility. It takes the language filename as parameter.
|
||||
Example:
|
||||
|
||||
strgen lang/german.txt
|
||||
|
||||
This results in compiling german.txt and produces another file named german.lng.
|
||||
Any missing strings are replaced with the english strings. Note that it looks for english.txt
|
||||
in the lang subdirectory, which is where your language file should also be.
|
||||
|
||||
That's all! You should now be able to select the language in the game options.
|
||||
|
||||
|
||||
X.X) Credits:
|
||||
---- --------
|
||||
The OpenTTD team:
|
||||
Ludvig Strigeus (ludde) - OpenTTD author, main coder (0.1 - 0.3.3)
|
||||
Serge Paquet (vurlix) - Assistant project manager, coder
|
||||
Dominik Scherer (dominik81) - Coder
|
||||
Tamas Farago (Darkvater) - Coder
|
||||
Patric Stout (TrueLight) - Coder, SVN-repository and website host
|
||||
Stefan Meißner (sign_de) - Network and Console coder
|
||||
Owen Rudge (orudge) - Contributor, forum host
|
||||
Bjarni Corfitzen (Bjarni) - MacOS port
|
||||
Kerekes Miham (MiHaMiX) - Maintainer of translator service, and host of nightlies
|
||||
Cian Duffy (MYOB) - BeOS port / manual writing
|
||||
Christian Rosentreter (tokaiz) - MorphOS/AmigaOS port
|
||||
|
||||
Thanks to:
|
||||
Josef Drexler - For his great work on TTDPatch.
|
||||
Marcin Grzegorczyk - For his TTDPatch work and documentation of TTD internals and graphics (signals and track foundations).
|
||||
Mike Ragsdale - OpenTTD installer
|
||||
Celestar - for his many patches, suggestions and fixes
|
||||
blathijs - for his many patches, suggestions and code documentation
|
||||
pasky - Many patches, newgrf support, etc.
|
||||
Tron - relentless correcting of the code
|
||||
mivlad - some patches
|
||||
truesatan - Some patches
|
||||
Michael Polnick - Some patches
|
||||
Michael Blunck - Nice graphics
|
||||
George - Canal graphics
|
||||
All Translators - For their support to make OpenTTD a truly international game
|
||||
Bug Reporters - Thanks for all bug reports.
|
||||
Moriarty - for the tons of (annoying) bugreports
|
||||
Chris Sawyer - For an amazing game!.
|
||||
OpenTTD README
|
||||
Last updated: $LastChangedDate: 2004-07-25 21:22:11 +0200 (Sun, 25 Jul 2004) $
|
||||
Release version: 0.3.4
|
||||
------------------------------------------------------------------------
|
||||
|
||||
|
||||
Table of Contents:
|
||||
------------------
|
||||
1.0) About
|
||||
2.0) Contacting
|
||||
* 2.1 Reporting Bugs
|
||||
3.0) Supported Platforms
|
||||
4.0) Running OpenTTD
|
||||
5.0) OpenTTD features
|
||||
6.0) Configuration File
|
||||
7.0) Compiling
|
||||
8.0) Translating
|
||||
* 8.1 Guidelines
|
||||
* 8.2 Translation
|
||||
* 8.3 Previewing
|
||||
X.X) Credits
|
||||
|
||||
|
||||
1.0) About:
|
||||
---- ------
|
||||
OpenTTD is a clone of Transport Tycoon Deluxe, a popular game originally
|
||||
written by Chris Sawyer. It attempts to mimic the original game as closely
|
||||
as possible while extending it with new features.
|
||||
|
||||
|
||||
2.0) Contacting:
|
||||
---- ----------
|
||||
The easiest way to contact the OpenTTD team is by submitting bug reports or
|
||||
posting comments in our forums. You can also chat with us on IRC (#openttd
|
||||
on irc.freenode.net).
|
||||
|
||||
The OpenTTD homepage is http://www.openttd.org/.
|
||||
|
||||
You can find a forum for OpenTTD at
|
||||
http://www.tt-forums.net/index.php?c=20
|
||||
|
||||
|
||||
2.1) Reporting Bugs:
|
||||
---- ---------------
|
||||
To report a bug, please create a SourceForge account and follow the bugs
|
||||
link from our homepage. Please make sure the bug is reproducible and
|
||||
still occurs in the latest daily build or the current SVN version. Also
|
||||
please look through the existing bug reports briefly to see whether the bug
|
||||
is not already known.
|
||||
|
||||
The SourceForge project page URL is: http://sourceforge.net/projects/openttd/
|
||||
Click on "Bugs" to see the bug tracker.
|
||||
|
||||
Please include the following information in your bug report:
|
||||
- OpenTTD version (PLEASE test the latest SVN/daily build)
|
||||
- Bug details, including instructions how to reproduce it
|
||||
- Platform and compiler (Win32, Linux, FreeBSD, ...)
|
||||
- Attach a save game or a screenshot if possible
|
||||
- If this bug only occurred recently please note the last
|
||||
version without the bug and the first version including
|
||||
the bug. That way we can fix it quicker by looking at the
|
||||
changes made.
|
||||
|
||||
|
||||
3.0) Supported Platforms:
|
||||
---- --------------------
|
||||
OpenTTD has been ported to several platforms and operating systems. It shouldn't
|
||||
be very difficult to port it to a new platform. The currently working platforms
|
||||
are:
|
||||
|
||||
Windows - Win32 GDI (faster) or SDL
|
||||
Linux - SDL
|
||||
FreeBSD - SDL
|
||||
MacOS - SDL
|
||||
BeOS - SDL
|
||||
MorphOS - SDL
|
||||
|
||||
|
||||
4.0) Running OpenTTD:
|
||||
---- ----------------
|
||||
|
||||
Before you run OpenTTD, you need to put the game's datafiles into the data/
|
||||
subdirectory. You need the following files from the original Windows version
|
||||
of TTD as OpenTTD makes use of the original TTD artwork.
|
||||
|
||||
IMPORTANT! You need the files from the WINDOWS version of TTD.
|
||||
|
||||
List of the required files:
|
||||
sample.cat
|
||||
trg1r.grf
|
||||
trgcr.grf
|
||||
trghr.grf
|
||||
trgir.grf
|
||||
trgtr.grf
|
||||
|
||||
If you want music you need to copy the gm/ folder from Windows TTD into your OpenTTD folder, not your data folder.
|
||||
|
||||
You can change the data path (which contains savegames as well) in Makefile.config by setting DATA_DIR_PREFIX and USE_HOMEDIR.
|
||||
|
||||
|
||||
5.0) OpenTTD features:
|
||||
---- -----------------
|
||||
|
||||
OpenTTD has a lot of features going beyond the original TTD emulation.
|
||||
Currently there is unfortunately no comprehensive list of features. You could
|
||||
check the features list on the web, and some optional features can be
|
||||
controlled through the Configure patches dialog. We also implement some
|
||||
features known from TTDPatch (http://www.ttdpatch.net/).
|
||||
|
||||
Several important non-standard controls:
|
||||
|
||||
* Use Ctrl to place presignals
|
||||
* Ctrl-d toggles double mode on win32
|
||||
|
||||
|
||||
6.0) Configuration File:
|
||||
---- -------------------
|
||||
The configuration file for OpenTTD (openttd.cfg) is in a simple windows-like
|
||||
.INI format. It's mostly undocumented.
|
||||
|
||||
|
||||
7.0) Compiling:
|
||||
---- ----------
|
||||
Windows:
|
||||
You need Microsoft Visual Studio 6 or .NET. Open the project file
|
||||
and it should build automatically. In case you don't build with SDL,
|
||||
you need to remove WITH_SDL from the project settings.
|
||||
(see also docs/Readme_Windows_MSVC6.0.txt)
|
||||
|
||||
You can also build it using the Makefile with MSys/MingW or Cygwin/MingW.
|
||||
Please read the Makefile for more information.
|
||||
|
||||
Unix:
|
||||
OpenTTD can be built either with "make" or with "jam". To build with
|
||||
"make", just type "make", or "gmake" on non-gnu systems. To build with "jam",
|
||||
first run "./configure" and then "jam". Note that you need SDL to compile
|
||||
OpenTTD.
|
||||
(see also docs/Readme_Mandrake_Linux.txt)
|
||||
|
||||
MacOS:
|
||||
Use "make".
|
||||
|
||||
BeOS:
|
||||
Use "jam".
|
||||
|
||||
FreeBSD
|
||||
Use "gmake".
|
||||
|
||||
MorphOS
|
||||
Use "make". Note that you need the MorphOS SDK and the
|
||||
powersdl.library SDK.
|
||||
|
||||
8.0) Translating:
|
||||
---- -------------------
|
||||
See http://www.openttd.org/translating.php for up-to-date information.
|
||||
|
||||
The use of the online Translator service, located at http://translator.openttd.org.
|
||||
For a username password combo you should contact the development team, either by mail, irc
|
||||
or the forums. The system is straight-forward to use, if you have any troubles, read the
|
||||
online help located there.
|
||||
|
||||
If for some reason the website is down for a longer period of time, the information below
|
||||
might be of help.
|
||||
|
||||
8.1) Guidelines:
|
||||
---- -------------------
|
||||
Here are some translation guidelines which you should follow closely.
|
||||
|
||||
* Please contact the development team before begining the translation process!
|
||||
This avoids double work, as someone else may have already started translating to the same language.
|
||||
* Translators must use the charater set "Windows latin-1", also known as ISO 8859-1.
|
||||
Otherwise, some characters will not display correctly in the game.
|
||||
|
||||
8.2) Translation:
|
||||
---- -------------------
|
||||
So, now that you've notified the development team about your intention to translate
|
||||
(You did, right? Of course you did.) you can pick up english.txt (found in the SVN repository
|
||||
under /lang) and translate.
|
||||
|
||||
You must change the first two lines of the file appropriately:
|
||||
|
||||
##name English-Name-Of-Language
|
||||
##ownname Native-Name-Of-Language
|
||||
|
||||
Note: Do not alter the following parts of the file:
|
||||
|
||||
* String identifiers (the first word on each line)
|
||||
* Parts of the strings which are in curly braces (such as {STRING})
|
||||
* Lines beginning with ## (such as ##id), other than the first two lines of the file
|
||||
|
||||
8.3) Previewing:
|
||||
---- -------------------
|
||||
In order to view the translation in the game, you need to compile your language file
|
||||
with the strgen utility, which is now bundled with the game.
|
||||
|
||||
strgen is a command-line utility. It takes the language filename as parameter.
|
||||
Example:
|
||||
|
||||
strgen lang/german.txt
|
||||
|
||||
This results in compiling german.txt and produces another file named german.lng.
|
||||
Any missing strings are replaced with the english strings. Note that it looks for english.txt
|
||||
in the lang subdirectory, which is where your language file should also be.
|
||||
|
||||
That's all! You should now be able to select the language in the game options.
|
||||
|
||||
|
||||
X.X) Credits:
|
||||
---- --------
|
||||
The OpenTTD team:
|
||||
Ludvig Strigeus (ludde) - OpenTTD author, main coder (0.1 - 0.3.3)
|
||||
Serge Paquet (vurlix) - Assistant project manager, coder
|
||||
Dominik Scherer (dominik81) - Coder
|
||||
Tamas Farago (Darkvater) - Coder
|
||||
Patric Stout (TrueLight) - Coder, SVN-repository and website host
|
||||
Stefan Meißner (sign_de) - Network and Console coder
|
||||
Owen Rudge (orudge) - Contributor, forum host
|
||||
Bjarni Corfitzen (Bjarni) - MacOS port
|
||||
Kerekes Miham (MiHaMiX) - Maintainer of translator service, and host of nightlies
|
||||
Cian Duffy (MYOB) - BeOS port / manual writing
|
||||
Christian Rosentreter (tokaiz) - MorphOS/AmigaOS port
|
||||
|
||||
Thanks to:
|
||||
Josef Drexler - For his great work on TTDPatch.
|
||||
Marcin Grzegorczyk - For his TTDPatch work and documentation of TTD internals and graphics (signals and track foundations).
|
||||
Mike Ragsdale - OpenTTD installer
|
||||
Celestar - for his many patches, suggestions and fixes
|
||||
blathijs - for his many patches, suggestions and code documentation
|
||||
pasky - Many patches, newgrf support, etc.
|
||||
Tron - relentless correcting of the code
|
||||
mivlad - some patches
|
||||
truesatan - Some patches
|
||||
Michael Polnick - Some patches
|
||||
Michael Blunck - Nice graphics
|
||||
George - Canal graphics
|
||||
All Translators - For their support to make OpenTTD a truly international game
|
||||
Bug Reporters - Thanks for all bug reports.
|
||||
Moriarty - for the tons of (annoying) bugreports
|
||||
Chris Sawyer - For an amazing game!.
|
||||
|
|
340
trunk/COPYING
340
trunk/COPYING
|
@ -1,340 +0,0 @@
|
|||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Library General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Library General
|
||||
Public License instead of this License.
|
|
@ -1,163 +0,0 @@
|
|||
CFILES = ai.c aircraft_cmd.c aircraft_gui.c airport_gui.c
|
||||
bridge_gui.c clear_cmd.c command.c disaster_cmd.c
|
||||
dock_gui.c dummy_land.c economy.c engine.c engine_gui.c
|
||||
fileio.c gfx.c graph_gui.c industry_cmd.c industry_gui.c
|
||||
intro_gui.c landscape.c main_gui.c minilzo.c misc.c
|
||||
misc_cmd.c misc_gui.c music_gui.c namegen.c network.c
|
||||
news_gui.c oldloader.c order_cmd.c order_gui.c pathfind.c
|
||||
player_gui.c players.c rail_cmd.c rail_gui.c road_cmd.c
|
||||
road_gui.c roadveh_cmd.c roadveh_gui.c saveload.c sdl.c
|
||||
settings.c settings_gui.c ship_cmd.c ship_gui.c smallmap_gui.c
|
||||
sound.c spritecache.c station_cmd.c station_gui.c
|
||||
strings.c subsidy_gui.c texteff.c town_cmd.c town_gui.c
|
||||
train_cmd.c train_gui.c tree_cmd.c ttd.c
|
||||
tunnelbridge_cmd.c unmovable_cmd.c vehicle.c
|
||||
viewport.c water_cmd.c widget.c window.c screenshot.c
|
||||
airport.c grfspecial.c terraform_gui.c ;
|
||||
|
||||
|
||||
LANGFILES = english.txt swedish.txt french.txt german.txt italian.txt slovak.txt hungarian.txt norwegian.txt danish.txt czech.txt galician.txt polish.txt romanian.txt;
|
||||
|
||||
####################
|
||||
# On UNIX we use gcc
|
||||
####################
|
||||
if $(UNIX) {
|
||||
SDL_CONFIG_CFLAGS = `XX_SDL_CONFIG_PLACEHOLDER_XX --cflags` ;
|
||||
SDL_CONFIG_LIBS = `XX_SDL_CONFIG_PLACEHOLDER_XX --libs` ;
|
||||
|
||||
LINKFLAGS += $(SDL_CONFIG_LIBS) ;
|
||||
CC = gcc ;
|
||||
CCFLAGS += -Wall -Wno-multichar -DUNIX -DWITH_SDL ;
|
||||
|
||||
OPTIMFLAGS = -O2 -fomit-frame-pointer ;
|
||||
DEBUGFLAGS = -g ;
|
||||
|
||||
# also include extmidi
|
||||
CFILES += extmidi.c unix.c ;
|
||||
|
||||
# compile in PNG support?
|
||||
if $(WITH_PNG) {
|
||||
CCFLAGS += -DWITH_PNG -I$(WITH_PNG) ;
|
||||
LINKFLAGS += -lpng ;
|
||||
}
|
||||
|
||||
# compile in zlib support?
|
||||
if $(WITH_ZLIB) {
|
||||
CCFLAGS += -DWITH_ZLIB ;
|
||||
LINKFLAGS += -lz ;
|
||||
}
|
||||
# compile for BeOS 5.1 and higher
|
||||
if $(WITH_BONE_NETWORKING) {
|
||||
CCFLAGS += -DENABLE_NETWORK ;
|
||||
LINKFLAGS += -lsocket -lbind ;
|
||||
}
|
||||
# link in BeOS MIDI and Be API libraries
|
||||
if $(BEOS_MIDI) {
|
||||
CCFLAGS += -DBEOS_MIDI ;
|
||||
LINKFLAGS += -lbe -lmidi ;
|
||||
CFILES += bemidi.cpp ;
|
||||
}
|
||||
}
|
||||
|
||||
####################
|
||||
# MSVC on Win32
|
||||
####################
|
||||
|
||||
actions ActWin32Res {
|
||||
$(VISUALC)\\..\\common\\msdev98\\bin\\rc /r /i $(STDHDRS) /fo $(<) $(>)
|
||||
}
|
||||
|
||||
rule Win32Res { ActWin32Res $(<) : $(>) ; DEPENDS $(<) : $(>) ; }
|
||||
|
||||
if $(TOOLSET) = VISUALC {
|
||||
OPTIMFLAGS = /Oa /Os /Ow /Oy /Oi /Og /Ox /Gr /Gf /Gy /Zp4 /J /WX /W3 -DNDEBUG ;
|
||||
|
||||
CCFLAGS += -DWIN32 -DWIN32_EXCEPTION_TRACKER ;
|
||||
CFILES += win32.c ;
|
||||
LINKFLAGS += /opt:nowin98 /LIBPATH:$(VISUALC)\\lib ;
|
||||
|
||||
LINKLIBS = ws2_32.lib winmm.lib user32.lib gdi32.lib ;
|
||||
|
||||
# compile resources too
|
||||
EOBJ = ttd.res ;
|
||||
Win32Res ttd.res : ttd.rc ;
|
||||
|
||||
# png screenshots?
|
||||
if $(WITH_PNG) {
|
||||
CCFLAGS += -DWITH_PNG -I$(WITH_PNG) ;
|
||||
LINKLIBS += libpng.lib ;
|
||||
}
|
||||
|
||||
# zlib savegames?
|
||||
if $(WITH_ZLIB) {
|
||||
CCFLAGS += -DWITH_ZLIB ;
|
||||
LINKLIBS += zlibstat.lib ;
|
||||
}
|
||||
|
||||
# build release by default
|
||||
RELEASE = 1 ;
|
||||
}
|
||||
|
||||
|
||||
####################
|
||||
# Common
|
||||
####################
|
||||
rule MyObjects {
|
||||
local _i _t _s ;
|
||||
|
||||
_t = $(OUTDIR)/$(>:S=$(SUFOBJ)) ;
|
||||
OPTIM on $(_t) = $(3) ;
|
||||
|
||||
MkDir $(OUTDIR) ;
|
||||
Depends $(_t) : $(OUTDIR) ;
|
||||
|
||||
for _i in $(>) {
|
||||
_s = $(OUTDIR)/$(_i:S=$(SUFOBJ)) ;
|
||||
Object $(_s) : $(_i) ;
|
||||
|
||||
# special handling for sdl.c and unix.c
|
||||
if $(_i) = sdl.c || $(_i) = unix.c { CCFLAGS on $(_s) += $(SDL_CONFIG_CFLAGS) ; }
|
||||
}
|
||||
MainFromObjects $(OUTDIR)/$(<) : $(_t) $(EOBJ) ;
|
||||
}
|
||||
|
||||
rule MyMain {
|
||||
if $(RELEASE) {
|
||||
OUTDIR = release ;
|
||||
MyObjects ttd : $(>) : $(OPTIMFLAGS) ;
|
||||
} else {
|
||||
OUTDIR = debug ;
|
||||
MyObjects ttd : $(>) : -D_DEBUG $(DEBUGFLAGS) ;
|
||||
}
|
||||
}
|
||||
|
||||
actions CompileLang {
|
||||
strgen$(SLASH)strgen $(>)
|
||||
}
|
||||
|
||||
rule LangFile {
|
||||
if $(>) = lang/english.txt {
|
||||
CompileLang $(<) table/strings.h : ;
|
||||
DEPENDS table/string.h : $(>) ;
|
||||
} else {
|
||||
CompileLang $(<) : $(>) ;
|
||||
}
|
||||
|
||||
Clean clean : $(<) ;
|
||||
DEPENDS $(<) : $(>) ;
|
||||
DEPENDS all : $(<) ;
|
||||
DEPENDS $(<) : strgen/strgen ;
|
||||
}
|
||||
|
||||
rule LangFiles {
|
||||
local _i ;
|
||||
for _i in $(<) { LangFile $(_i:S=.lng) : $(_i) ; }
|
||||
Clean clean : table/strings.h ;
|
||||
}
|
||||
|
||||
LangFiles lang/$(LANGFILES) ;
|
||||
|
||||
Main strgen/strgen : strgen/strgen.c ;
|
||||
|
||||
MyMain ttd : $(CFILES) ;
|
||||
|
662
trunk/Makefile
662
trunk/Makefile
|
@ -1,662 +0,0 @@
|
|||
# This Makefile is partially based on "a completely generic Makefile",
|
||||
# originally created by Justin Husted <husted@cs>
|
||||
#
|
||||
# Rewrite and sane dependencies support by Petr Baudis <pasky@ucw.cz>
|
||||
# Cygwin support and configuration by Jaen Saul <slowbyte@hot.ee>
|
||||
# A lot of modifications by Bjarni Corfitzen <bjarni@openttd.com>
|
||||
#
|
||||
# Last modified by: $Author: strigeus $
|
||||
# On: $Date: 2004/03/11 19:15:06 $
|
||||
|
||||
|
||||
##############################################################################
|
||||
#
|
||||
# Usage
|
||||
#
|
||||
|
||||
# Synopsis:
|
||||
#
|
||||
# make WITH_ZLIB=1 UNIX=1 MANUAL_CONFIG=1
|
||||
#
|
||||
# (See below for the list of possible options.)
|
||||
#
|
||||
# Alternately, you can run make without the MANUAL_CONFIG part. It then
|
||||
# generates Makefile.config, where you can customize all the options.
|
||||
# However beware that for all subsequent calls the option values from
|
||||
# Makefile.config take precedence to the commandline options.
|
||||
#
|
||||
# (That means that you probably want to either specify the options on command
|
||||
# line together with MANUAL_CONFIG=1 or you want to specify no commandline
|
||||
# options at all.)
|
||||
|
||||
# Targets:
|
||||
#
|
||||
# Defaults to building binary
|
||||
# clean: remove intermediate build files
|
||||
# mrproper: remove intermediate files and makefile configuration
|
||||
# upgradeconf: add new options to old Makefile.config
|
||||
# osx: OS X application
|
||||
|
||||
# Options:
|
||||
#
|
||||
# Summary of OS choice defines
|
||||
# WIN32: building on Windows
|
||||
# UNIX: building on *nix derivate (Linux, FreeBSD)
|
||||
# OSX: building on Mac OS X
|
||||
# MORPHOS: building on MorphOS
|
||||
#
|
||||
# Summary of library choice defines
|
||||
# WITH_ZLIB: savegames using zlib
|
||||
# WITH_PNG: screenshots using PNG
|
||||
# WITH_SDL: SDL video driver support
|
||||
#
|
||||
# Summary of other defines:
|
||||
# MANUAL_CONFIG: do not use Makefile.config, config options set manually
|
||||
# DEBUG: build in debug mode
|
||||
# PROFILE: build in profile mode, disables -s and -fomit-frame-pointer
|
||||
# DISPLAY_WARNINGS: when off, some errors are not displayed while compiling
|
||||
# TRANSLATOR: build in translator mode (untranslated strings are prepended by
|
||||
# a <TODO> mark)
|
||||
# RELEASE: this will be the released version number. It replaces all places
|
||||
# where it normally would print the revision number
|
||||
# MIDI: if set, it will use it as custom path to midi player.
|
||||
# If unset, it will use the hardcoded path in the c code
|
||||
# NOVERBOSE: supress all warnings and errors during compilation.
|
||||
# It looks nicer, but you will not know what went wrong. Use it on released (stable) sources only
|
||||
#
|
||||
# DATA_DIR_PREFIX: This sets the dir OpenTTD looks for the needed files.
|
||||
# MUST END WITH / if defined
|
||||
#
|
||||
# STATIC: link statically
|
||||
# CYGWIN: build in Cygwin environment
|
||||
# MINGW: build with MingW compiler, link with MingW libraries
|
||||
#
|
||||
# Experimental (does not work properly):
|
||||
# WITH_NETWORK: enable networking
|
||||
# WITH_DIRECTMUSIC: enable DirectMusic MIDI support
|
||||
|
||||
|
||||
##############################################################################
|
||||
#
|
||||
# Configuration
|
||||
#
|
||||
|
||||
# Makefile version tag
|
||||
# it checks if the version tag in makefile.config is the same and force update outdated config files
|
||||
MAKEFILE_VERSION:=1
|
||||
|
||||
# CONFIG_WRITER have to be found even for manual configuration
|
||||
CONFIG_WRITER=makefiledir/Makefile.config_writer
|
||||
|
||||
ifndef MANUAL_CONFIG
|
||||
# Automatic configuration
|
||||
MAKE_CONFIG:=Makefile.config
|
||||
MAKEFILE:=Makefile
|
||||
LIB_DETECTION=makefiledir/Makefile.libdetection
|
||||
CONFIG_WRITER=makefiledir/Makefile.config_writer
|
||||
|
||||
# Apply automatic configuration
|
||||
# See target section for how this is built, suppress errors
|
||||
# since first time it isn't found but make reads this twice
|
||||
-include $(MAKE_CONFIG)
|
||||
else
|
||||
CONFIG_INCLUDED:=1
|
||||
endif
|
||||
|
||||
# updates makefile.config if it's outdated
|
||||
ifneq ($(MAKEFILE_VERSION),$(CONFIG_VERSION))
|
||||
ifndef MANUAL_CONFIG # manual config should not check this
|
||||
UPDATECONFIG:=upgradeconf
|
||||
CONFIG_INCLUDED:=
|
||||
else
|
||||
# this should define SDL-CONFIG for manual configuration
|
||||
ifeq ($(shell uname),FreeBSD)
|
||||
SDL-CONFIG:=sdl11-config
|
||||
else
|
||||
SDL-CONFIG:=sdl-config
|
||||
endif
|
||||
endif
|
||||
else
|
||||
# this should define SDL-CONFIG for manual configuration
|
||||
ifeq ($(shell uname),FreeBSD)
|
||||
SDL-CONFIG:=sdl11-config
|
||||
else
|
||||
SDL-CONFIG:=sdl-config
|
||||
endif
|
||||
endif
|
||||
|
||||
# this is used if there aren't any makefile.config
|
||||
ifndef CONFIG_INCLUDED
|
||||
ENABLE_NETWORK:=1 # sets network on by default if there aren't any config file
|
||||
-include $(LIB_DETECTION)
|
||||
endif
|
||||
|
||||
# Verbose filter
|
||||
|
||||
ifdef NOVERBOSE
|
||||
VERBOSE_FILTER = >/dev/null 2>&1
|
||||
else
|
||||
VERBOSE_FILTER =
|
||||
endif
|
||||
|
||||
ifdef DISPLAY_WARNINGS
|
||||
WARNING_DISPLAY:=-fstrict-aliasing
|
||||
VERBOSE_FILTER =
|
||||
else
|
||||
WARNING_DISPLAY:=-fno-strict-aliasing
|
||||
endif
|
||||
|
||||
ifdef SUPRESS_LANG_ERRORS
|
||||
ifndef VERBOSE_FILTER
|
||||
LANG_ERRORS = >/dev/null 2>&1
|
||||
endif
|
||||
endif
|
||||
|
||||
ifdef STATIC
|
||||
ifndef WIN32
|
||||
ifndef OSX
|
||||
ifndef MORPHOS
|
||||
ifndef SKIP_STATIC_CHECK
|
||||
$(error Static is only known to work on MorphOS and MacOSX!!! --- Check makefile.config for more info and howto bypass this check)
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
|
||||
# Force SDL on UNIX platforms
|
||||
ifndef WITH_SDL
|
||||
ifdef UNIX
|
||||
$(error You need to have SDL installed in order to run OpenTTD on UNIX.)
|
||||
endif
|
||||
endif
|
||||
|
||||
|
||||
|
||||
##############################################################################
|
||||
#
|
||||
# Compiler configuration
|
||||
#
|
||||
CC=gcc
|
||||
CXX=g++
|
||||
|
||||
ifdef MORPHOS
|
||||
CC += -noixemul -pipe
|
||||
CXX += -noixemul -pipe
|
||||
endif
|
||||
|
||||
# Executable file extension
|
||||
ifdef WIN32
|
||||
EXE=.exe
|
||||
else
|
||||
EXE=
|
||||
endif
|
||||
|
||||
# Set output executable names
|
||||
TTD=openttd$(EXE)
|
||||
ENDIAN_CHECK=endian_check$(EXE)
|
||||
STRGEN=strgen/strgen$(EXE)
|
||||
OSXAPP="OpenTTD.app"
|
||||
|
||||
# What revision are we compiling, if we have an idea?
|
||||
REV_NUMBER := $(shell if test -d .svn; then svnversion . | tr -dc 0-9; fi)
|
||||
|
||||
ifdef RELEASE
|
||||
REV:=$(RELEASE)
|
||||
else
|
||||
REV := $(shell if test -d .svn; then echo -n r; svnversion .; fi)
|
||||
tmp_test:=$(shell echo "$(REV)" | grep "M" )
|
||||
ifdef tmp_test
|
||||
REV_NUMBER:=1
|
||||
endif
|
||||
endif
|
||||
|
||||
ifndef REV_NUMBER
|
||||
REV_NUMBER:=0
|
||||
endif
|
||||
|
||||
# MorphOS needs builddate
|
||||
BUILDDATE=`date +%d.%m.%y`
|
||||
|
||||
# AMD64 needs a little more settings to work
|
||||
ifeq ($(shell uname -m), x86_64)
|
||||
endwarnings:=endwarnings
|
||||
64_bit_warnings:=64_bit_warnings
|
||||
BASECFLAGS += -m64
|
||||
endif
|
||||
|
||||
|
||||
# When calling the compiler, use these flags
|
||||
# -g debugging symbols
|
||||
# -Wall all warnings
|
||||
# -s automatic strip
|
||||
#
|
||||
# You may also want:
|
||||
# -O optimize or -O2 fully optimize (O's above 2 are not recommended)
|
||||
# -pg profile - generate profiling data. See "man gprof" to use this.
|
||||
|
||||
CFLAGS=-Wall -Wno-multichar
|
||||
CDEFS=-DWITH_REV
|
||||
LDFLAGS=
|
||||
LIBS=
|
||||
|
||||
ifdef DEBUG
|
||||
# Debug mode
|
||||
CDEFS += -D_DEBUG
|
||||
BASECFLAGS += -g
|
||||
else
|
||||
ifdef PROFILE
|
||||
BASECFLAGS += -pg
|
||||
else
|
||||
# Release mode
|
||||
ifndef MORPHOS
|
||||
# automatical strip breaks under morphos
|
||||
BASECFLAGS += -s
|
||||
LDFLAGS += -s
|
||||
endif
|
||||
endif
|
||||
|
||||
ifdef OSX
|
||||
# these compilerflags makes the app run as fast as possible without making the app unstable. It works on G3 or newer
|
||||
BASECFLAGS += -O3 -funroll-loops -fsched-interblock -falign-loops=16 -falign-jumps=16 -falign-functions=16 -falign-jumps-max-skip=15 -falign-loops-max-skip=15 -mdynamic-no-pic -mpowerpc-gpopt -force_cpusubtype_ALL $(WARNING_DISPLAY)
|
||||
else
|
||||
ifdef MORPHOS
|
||||
BASECFLAGS += -O2 -funroll-loops -fexpensive-optimizations -mstring -mmultiple $(WARNING_DISPLAY)
|
||||
else
|
||||
BASECFLAGS += -O2 $(WARNING_DISPLAY)
|
||||
endif
|
||||
ifndef PROFILE
|
||||
BASECFLAGS += -fomit-frame-pointer
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
ifdef STATIC
|
||||
ifndef OSX # OSX can't build static if -static flag is used
|
||||
LDFLAGS += -static
|
||||
endif
|
||||
endif
|
||||
|
||||
# If building on Cygwin/MingW don't link with Cygwin libs
|
||||
ifdef WIN32
|
||||
ifdef MINGW
|
||||
ifdef CYGWIN
|
||||
BASECFLAGS += -mno-cygwin
|
||||
LDFLAGS += -mno-cygwin
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
CFLAGS += $(BASECFLAGS)
|
||||
|
||||
ifdef UNIX
|
||||
CDEFS += -DUNIX
|
||||
endif
|
||||
|
||||
# SDL config
|
||||
ifdef WITH_SDL
|
||||
CDEFS += -DWITH_SDL
|
||||
CFLAGS += `$(SDL-CONFIG) --cflags`
|
||||
ifdef STATIC
|
||||
LIBS += `$(SDL-CONFIG) --static-libs`
|
||||
else
|
||||
LIBS += `$(SDL-CONFIG) --libs`
|
||||
endif
|
||||
endif
|
||||
|
||||
|
||||
# zlib config
|
||||
ifdef WITH_ZLIB
|
||||
CDEFS += -DWITH_ZLIB
|
||||
ifdef STATIC
|
||||
ifdef OSX
|
||||
# zlib is default on OSX, so everybody have it. No need for static linking
|
||||
LIBS += -lz
|
||||
else
|
||||
ifndef STATIC_ZLIB_PATH
|
||||
ifndef MANUAL_CONFIG
|
||||
# updates makefile.config with the zlib path
|
||||
UPDATECONFIG:=upgradeconf
|
||||
endif
|
||||
TEMP:=$(shell ls /lib 2>/dev/null | grep "zlib.a")$(shell ls /lib 2>/dev/null | grep "libz.a")
|
||||
ifdef TEMP
|
||||
STATIC_ZLIB_PATH:=/lib/$(TEMP)
|
||||
else
|
||||
TEMP:=$(shell ls /usr/lib 2>/dev/null | grep "zlib.a")$(shell ls /usr/lib 2>/dev/null | grep "libz.a")
|
||||
ifdef TEMP
|
||||
STATIC_ZLIB_PATH:=/usr/lib/$(TEMP)
|
||||
else
|
||||
TEMP:=$(shell ls /usr/local/lib 2>/dev/null | grep "zlib.a")$(shell ls /usr/local/lib 2>/dev/null | grep "libz.a")
|
||||
ifdef TEMP
|
||||
STATIC_ZLIB_PATH:=/usr/local/lib/$(TEMP)
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
LIBS += $(STATIC_ZLIB_PATH)
|
||||
endif
|
||||
else
|
||||
LIBS += -lz
|
||||
endif
|
||||
endif
|
||||
|
||||
# libpng config
|
||||
ifdef WITH_PNG
|
||||
CDEFS += -DWITH_PNG
|
||||
# FreeBSD doesn't use libpng-config
|
||||
ifdef FREEBSD
|
||||
LIBS += -lpng
|
||||
else
|
||||
CFLAGS += `libpng-config --cflags`
|
||||
ifdef OSX
|
||||
ifdef STATIC
|
||||
# Seems like we need a tiny hack for OSX static to work
|
||||
LIBS += `libpng-config --prefix`/lib/libpng.a
|
||||
else
|
||||
LIBS += `libpng-config --libs`
|
||||
endif
|
||||
else
|
||||
# seems like older libpng versions are broken and need this
|
||||
PNGCONFIG_FLAGS = --ldflags --libs
|
||||
ifdef STATIC
|
||||
LIBS += `libpng-config --static $(PNGCONFIG_FLAGS)`
|
||||
else
|
||||
LIBS += `libpng-config $(PNGCONFIG_FLAGS)`
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
|
||||
ifdef TRANSLATOR
|
||||
STRGEN_FLAGS=-t
|
||||
else
|
||||
STRGEN_FLAGS=
|
||||
endif
|
||||
|
||||
# file paths setup
|
||||
ifdef GAME_DATA_DIR
|
||||
CDEFS += -DGAME_DATA_DIR=\"$(GAME_DATA_DIR)\"
|
||||
endif
|
||||
|
||||
ifdef PERSONAL_DIR
|
||||
CDEFS += -DPERSONAL_DIR=\"$(PERSONAL_DIR)\"
|
||||
endif
|
||||
|
||||
ifdef USE_HOMEDIR
|
||||
CDEFS += -DUSE_HOMEDIR
|
||||
endif
|
||||
|
||||
# MIDI setup
|
||||
ifdef OSX
|
||||
ifndef MIDI
|
||||
MIDI:=$(OSXAPP)/contents/macos/track_starter
|
||||
endif
|
||||
endif
|
||||
|
||||
ifdef MIDI
|
||||
CDEFS += -DEXTERNAL_PLAYER=\"$(MIDI)\"
|
||||
ifdef MIDI_ARG
|
||||
CDEFS += -DMIDI_ARG=\"$(MIDI_ARG)\"
|
||||
endif
|
||||
endif
|
||||
|
||||
# Experimental
|
||||
ifdef WITH_NETWORK
|
||||
CDEFS += -DENABLE_NETWORK
|
||||
ifdef UNIX
|
||||
ifndef OSX
|
||||
ifndef MORPHOS
|
||||
# this have caused problems on many platforms and disabling it didn't break anything
|
||||
# now we test if disabling it as a general breaks it for anybody
|
||||
#LIBS += -lresolv
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
ifdef WITH_DIRECTMUSIC
|
||||
CDEFS += -DWIN32_ENABLE_DIRECTMUSIC_SUPPORT
|
||||
endif
|
||||
|
||||
ifdef WIN32
|
||||
LIBS += -lws2_32 -lwinmm -lgdi32 -ldxguid -lole32 -lstdc++
|
||||
TTDLDFLAGS += -Wl,--subsystem,windows
|
||||
endif
|
||||
|
||||
# sets up the paths for use for make install
|
||||
ifdef BINARY_DIR
|
||||
BINARY_INSTALL:=$(BINARY_DIR)$(TTD)
|
||||
else
|
||||
BINARY_INSTALL:=$(INSTALL_DIR)$(TTD)
|
||||
endif
|
||||
ifdef DATA_DIR_PREFIX
|
||||
DATA_DIR:=$(DATA_DIR_PREFIX)
|
||||
else
|
||||
DATA_DIR:=$(INSTALL_DIR)
|
||||
endif
|
||||
|
||||
##############################################################################
|
||||
#
|
||||
# What to compile
|
||||
# (users do not want to modify anything below)
|
||||
#
|
||||
|
||||
|
||||
### Sources
|
||||
|
||||
ttd_SOURCES = \
|
||||
ai.c ai_build.c ai_new.c ai_pathfinder.c ai_shared.c aircraft_cmd.c \
|
||||
aircraft_gui.c airport.c airport_gui.c aystar.c bridge_gui.c \
|
||||
clear_cmd.c command.c console.c console_cmds.c disaster_cmd.c dock_gui.c dummy_land.c economy.c \
|
||||
engine.c engine_gui.c fileio.c gfx.c graph_gui.c grfspecial.c \
|
||||
industry_cmd.c industry_gui.c intro_gui.c landscape.c main_gui.c \
|
||||
minilzo.c misc.c misc_cmd.c misc_gui.c music_gui.c namegen.c network.c \
|
||||
network_gui.c news_gui.c oldloader.c order_cmd.c order_gui.c \
|
||||
pathfind.c player_gui.c players.c queue.c rail_cmd.c rail_gui.c rev.c \
|
||||
road_cmd.c road_gui.c roadveh_cmd.c roadveh_gui.c saveload.c \
|
||||
screenshot.c settings.c settings_gui.c ship_cmd.c ship_gui.c \
|
||||
smallmap_gui.c sound.c spritecache.c station_cmd.c station_gui.c \
|
||||
strings.c subsidy_gui.c terraform_gui.c texteff.c town_cmd.c \
|
||||
town_gui.c train_cmd.c train_gui.c tree_cmd.c ttd.c tunnelbridge_cmd.c \
|
||||
unmovable_cmd.c vehicle.c vehicle_gui.c viewport.c water_cmd.c widget.c window.c \
|
||||
|
||||
ifdef WITH_SDL
|
||||
ttd_SOURCES += sdl.c
|
||||
endif
|
||||
|
||||
ifdef WIN32
|
||||
ttd_SOURCES += win32.c w32dm.c
|
||||
else
|
||||
ttd_SOURCES += extmidi.c unix.c
|
||||
endif
|
||||
|
||||
ttd_OBJS = $(ttd_SOURCES:%.c=%.o)
|
||||
|
||||
ifdef WIN32
|
||||
# Resource file
|
||||
ttd_OBJS += winres.o
|
||||
endif
|
||||
|
||||
ifdef WITH_DIRECTMUSIC
|
||||
ttd_SOURCES += w32dm2.cpp
|
||||
ttd_OBJS += w32dm2.o
|
||||
endif
|
||||
|
||||
ttd_DEPS1 = $(foreach obj,$(ttd_OBJS),.deps/$(obj))
|
||||
ttd_DEPS = $(ttd_DEPS1:%.o=%.P)
|
||||
|
||||
LANG_TXT = $(filter-out %.unfinished.txt,$(wildcard lang/*.txt))
|
||||
LANGS = $(LANG_TXT:%.txt=%.lng)
|
||||
|
||||
C_COMPILE = $(CC) $(CFLAGS) $(CDEFS)
|
||||
CXX_COMPILE = $(CXX) $(CFLAGS) $(CDEFS)
|
||||
|
||||
C_BUILD = $(C_COMPILE) -c
|
||||
CXX_BUILD = $(CXX_COMPILE) -c
|
||||
|
||||
C_LINK = $(CC) $(LDFLAGS) -o
|
||||
|
||||
|
||||
|
||||
##############################################################################
|
||||
#
|
||||
# Targets
|
||||
#
|
||||
|
||||
|
||||
### Normal build rules
|
||||
|
||||
|
||||
ifdef OSX
|
||||
OSX:=OSX
|
||||
endif
|
||||
|
||||
|
||||
all: endian.h $(UPDATECONFIG) $(TTD) $(OSX) $(endwarnings)
|
||||
|
||||
endian.h: $(ENDIAN_CHECK)
|
||||
@# Check if system is LITTLE_ENDIAN or BIG_ENDIAN
|
||||
@echo 'Running endian_check'; \
|
||||
./$(ENDIAN_CHECK) > $@
|
||||
|
||||
$(ENDIAN_CHECK): endian_check.c
|
||||
@echo 'Compiling and Linking $@'; \
|
||||
$(CC) $(BASECFLAGS) $(CDEFS) endian_check.c -o $@
|
||||
|
||||
|
||||
$(TTD): table/strings.h $(ttd_OBJS) $(LANGS) $(MAKE_CONFIG)
|
||||
@echo 'Compiling and Linking $@'; \
|
||||
$(C_LINK) $@ $(TTDLDFLAGS) $(ttd_OBJS) $(LIBS) $(VERBOSE_FILTER)
|
||||
|
||||
$(OSX):
|
||||
@mkdir -p $(OSXAPP)/Contents/MacOS
|
||||
@mkdir -p $(OSXAPP)/Contents/Resources
|
||||
@echo "APPL????" > $(OSXAPP)/Contents/PkgInfo
|
||||
@cp os/macos/ttd.icns $(OSXAPP)/Contents/Resources/openttd.icns
|
||||
@os/macos/plistgen.sh $(OSXAPP) $(REV)
|
||||
@cp os/macos/track_starter $(OSXAPP)/contents/macos
|
||||
@ls os/macos | grep -q "\.class" || \
|
||||
javac os/macos/OpenTTDMidi.java
|
||||
@cp os/macos/OpenTTDMidi.class $(OSXAPP)/contents/macos
|
||||
@cp $(TTD) $(OSXAPP)/Contents/MacOS/$(TTD)
|
||||
|
||||
$(endwarnings): $(64_bit_warnings)
|
||||
|
||||
$(64_bit_warnings):
|
||||
$(warning 64 bit CPUs will get some 64 bit specific bugs!)
|
||||
$(warning If you see any bugs, include in your bug report that you use a 64 bit CPU)
|
||||
|
||||
$(STRGEN): strgen/strgen.c rev.o
|
||||
@echo 'Compiling and Linking $@'; \
|
||||
$(CC) $(BASECFLAGS) $(CDEFS) -o $@ $^ $(VERBOSE_FILTER)
|
||||
|
||||
lang/english.lng: lang/english.txt $(STRGEN)
|
||||
@echo 'Generating $@'; \
|
||||
$(STRGEN)
|
||||
|
||||
table/strings.h: lang/english.lng
|
||||
|
||||
lang/%.lng: lang/%.txt $(STRGEN)
|
||||
@echo 'Generating $@'; \
|
||||
$(STRGEN) $(STRGEN_FLAGS) $< $(VERBOSE_FILTER) $(LANG_ERRORS)
|
||||
|
||||
winres.o: ttd.rc
|
||||
windres -o $@ $<
|
||||
|
||||
|
||||
rev.c: FORCE
|
||||
@# setting the revision number in a place, there the binary can read it
|
||||
@echo 'const char _openttd_revision[] = "'$(REV)'";' >>rev.c.new
|
||||
@echo 'const int _revision_number = $(REV_NUMBER);' >>rev.c.new
|
||||
@# some additions for MorphOS versions tag
|
||||
@echo '#ifdef __MORPHOS__' >>rev.c.new
|
||||
@echo 'const char morphos_versions_tag[] = "\\0$$VER: OpenTTD '$(REV)' ('${BUILDDATE}') © OpenTTD Team [MorphOS, PowerPC]";' >>rev.c.new
|
||||
@echo '#endif' >>rev.c.new
|
||||
@# Only update the real rev.c if it actually changed, to prevent
|
||||
@# useless rebuilds.
|
||||
@cmp -s rev.c rev.c.new 2>/dev/null || mv rev.c.new rev.c
|
||||
@rm -f rev.c.new
|
||||
|
||||
FORCE:
|
||||
|
||||
|
||||
# ttd$(EXE) is removed just to make sure people execute the right binary (openttd$(EXE))
|
||||
# remove this for next release!
|
||||
clean:
|
||||
@echo 'Cleaning up...'; \
|
||||
rm -rf .deps *~ $(TTD) $(STRGEN) core table/strings.h $(LANGS) $(ttd_OBJS) endian.h $(ENDIAN_CHECK) ttd$(EXE)
|
||||
|
||||
mrproper: clean
|
||||
rm -rf $(MAKE_CONFIG)
|
||||
|
||||
ifndef OSX
|
||||
ifndef MORPHOS
|
||||
install:
|
||||
@if [ "$(INSTALL)" == "" ]; then $(error make install is highly experimental at his state and not\
|
||||
tested very much - use at your own risk - to use run \"make install INSTALL:=1\" - make sure makefile.config\
|
||||
is set correctly up - run \"make upgradeconf\")
|
||||
@if [ "$(DATA_DIR)" == "" ]; then $(error no install path set - check makefile.config)
|
||||
mkdir -p $(DATA_DIR)/lang
|
||||
mkdir -p $(DATA_DIR)/data
|
||||
cp $(TTD) $(BINARY_INSTALL)
|
||||
cp lang/*.lng $(DATA_DIR)/lang
|
||||
cp data/*.grf $(DATA_DIR)/data
|
||||
else #MorphOS
|
||||
install:
|
||||
$(error make install is not supported on MorphOS)
|
||||
endif
|
||||
else # OSX
|
||||
install:
|
||||
$(error make install is not supported on MacOSX)
|
||||
endif
|
||||
|
||||
|
||||
love:
|
||||
@echo "YES! I thought you would never ask. We will have a great time. You can keep me turned on all night"
|
||||
|
||||
.PHONY: clean all $(OSX) install $(64_bit_warnings) $(endwarnings) love
|
||||
|
||||
|
||||
### Automatic configuration
|
||||
-include $(CONFIG_WRITER)
|
||||
|
||||
|
||||
# Export all variables set to subprocesses (a bit dirty)
|
||||
.EXPORT_ALL_VARIABLES:
|
||||
upgradeconf: $(MAKE_CONFIG)
|
||||
rm $(MAKE_CONFIG)
|
||||
$(MAKE) $(MAKE_CONFIG)
|
||||
|
||||
.PHONY: upgradeconf
|
||||
|
||||
|
||||
### Internal build rules
|
||||
|
||||
# This makes sure the .deps dir is always around.
|
||||
DEPS_MAGIC := $(shell mkdir .deps > /dev/null 2>&1 || :)
|
||||
|
||||
# Introduce the dependencies
|
||||
-include $(ttd_DEPS)
|
||||
|
||||
# This compiles the object file as well as silently updating its dependencies
|
||||
# list at the same time. It is not an issue that they aren't around during the
|
||||
# first compilation round as we just build everything at that time anyway,
|
||||
# therefore we do not need to watch deps.
|
||||
|
||||
#@echo '$(C_BUILD) $<'; \
|
||||
|
||||
|
||||
%.o: %.c $(MAKE_CONFIG)
|
||||
@echo 'Compiling $(*F).o'; \
|
||||
$(C_BUILD) $< -Wp,-MD,.deps/$(*F).pp $(VERBOSE_FILTER)
|
||||
@-cp .deps/$(*F).pp .deps/$(*F).P; \
|
||||
tr ' ' '\012' < .deps/$(*F).pp \
|
||||
| sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
|
||||
>> .deps/$(*F).P; \
|
||||
rm .deps/$(*F).pp
|
||||
|
||||
# For DirectMusic build
|
||||
%.o: %.cpp $(MAKE_CONFIG)
|
||||
$(CXX_BUILD) $<
|
|
@ -1,8 +0,0 @@
|
|||
// stdafx.cpp : source file that includes just the standard includes
|
||||
// ttd.pch will be the pre-compiled header
|
||||
// stdafx.obj will contain the pre-compiled type information
|
||||
|
||||
#include "stdafx.h"
|
||||
|
||||
// TODO: reference any additional headers you need in STDAFX.H
|
||||
// and not in this file
|
3961
trunk/ai.c
3961
trunk/ai.c
File diff suppressed because it is too large
Load Diff
271
trunk/ai.h
271
trunk/ai.h
|
@ -1,271 +0,0 @@
|
|||
#ifndef AI_H
|
||||
#define AI_H
|
||||
|
||||
#include "aystar.h"
|
||||
|
||||
/*
|
||||
* These defines can be altered to change the behavoir of the AI
|
||||
*
|
||||
* WARNING:
|
||||
* This can also alter the AI in a negative way. I will never claim these settings
|
||||
* are perfect, but don't change them if you don't know what the effect is.
|
||||
*/
|
||||
|
||||
// How many times it the H multiplied. The higher, the more it will go straight to the
|
||||
// end point. The lower, how more it will find the route with the lowest cost.
|
||||
// also: the lower, the longer it takes before route is calculated..
|
||||
#define AI_PATHFINDER_H_MULTIPLER 100
|
||||
|
||||
// How many loops may AyStar do before it stops
|
||||
// 0 = infinite
|
||||
#define AI_PATHFINDER_LOOPS_PER_TICK 5
|
||||
|
||||
// How long may the AI search for one route?
|
||||
// 0 = infinite
|
||||
// This number is the number of tiles tested.
|
||||
// It takes (AI_PATHFINDER_MAX_SEARCH_NODES / AI_PATHFINDER_LOOPS_PER_TICK) ticks
|
||||
// to get here.. with 5000 / 10 = 500. 500 / 74 (one day) = 8 days till it aborts
|
||||
// (that is: if the AI is on VERY FAST! :p
|
||||
#define AI_PATHFINDER_MAX_SEARCH_NODES 5000
|
||||
|
||||
// If you enable this, the AI is not allowed to make 90degree turns
|
||||
#define AI_PATHFINDER_NO_90DEGREES_TURN
|
||||
|
||||
// Below are defines for the g-calculation
|
||||
|
||||
// Standard penalty given to a tile
|
||||
#define AI_PATHFINDER_PENALTY 150
|
||||
// The penalty given to a tile that is going up
|
||||
#define AI_PATHFINDER_TILE_GOES_UP_PENALTY 450
|
||||
// Changing direction is a penalty, to prevent curved ways (with that: slow ways)
|
||||
#define AI_PATHFINDER_DIRECTION_CHANGE_PENALTY 200
|
||||
// Same penalty, only for when road already exists
|
||||
#define AI_PATHFINDER_DIRECTION_CHANGE_ON_EXISTING_ROAD_PENALTY 50
|
||||
// A diagonal track cost the same as a straigh, but a diagonal is faster... so give
|
||||
// a bonus for using diagonal track
|
||||
#ifdef AI_PATHFINDER_NO_90DEGREES_TURN
|
||||
#define AI_PATHFINDER_DIAGONAL_BONUS 95
|
||||
#else
|
||||
#define AI_PATHFINDER_DIAGONAL_BONUS 75
|
||||
#endif
|
||||
// If a roadblock already exists, it gets a bonus
|
||||
#define AI_PATHFINDER_ROAD_ALREADY_EXISTS_BONUS 140
|
||||
// To prevent 3 direction changes in 3 tiles, this penalty is given in such situation
|
||||
#define AI_PATHFINDER_CURVE_PENALTY 200
|
||||
|
||||
// Penalty a bridge gets per length
|
||||
#define AI_PATHFINDER_BRIDGE_PENALTY 180
|
||||
// The penalty for a bridge going up
|
||||
#define AI_PATHFINDER_BRIDGE_GOES_UP_PENALTY 1000
|
||||
|
||||
// Tunnels are expensive...
|
||||
// Because of that, every tile the cost is increased with 1/8th of his value
|
||||
// This is also true if you are building a tunnel yourself
|
||||
#define AI_PATHFINDER_TUNNEL_PENALTY 350
|
||||
|
||||
/*
|
||||
* Ai_New defines
|
||||
*/
|
||||
|
||||
// How long may we search cities and industry for a new route?
|
||||
#define AI_LOCATE_ROUTE_MAX_COUNTER 200
|
||||
|
||||
// How many days must there be between building the first station and the second station
|
||||
// within one city. This number is in days and should be more then 4 months.
|
||||
#define AI_CHECKCITY_DATE_BETWEEN 180
|
||||
|
||||
// How many cargo is needed for one station in a city?
|
||||
#define AI_CHECKCITY_CARGO_PER_STATION 60
|
||||
// How much cargo must there not be used in a city before we can build a new station?
|
||||
#define AI_CHECKCITY_NEEDED_CARGO 50
|
||||
// When there is already a station which takes the same good and the rating of that
|
||||
// city is higher then this numer, we are not going to attempt to build anything
|
||||
// there
|
||||
#define AI_CHECKCITY_CARGO_RATING 50
|
||||
// But, there is a chance of 1 out of this number, that we do ;)
|
||||
#define AI_CHECKCITY_CARGO_RATING_CHANCE 5
|
||||
// If a city is too small to contain a station, there is a small chance
|
||||
// that we still do so.. just to make the city bigger!
|
||||
#define AI_CHECKCITY_CITY_CHANCE 5
|
||||
|
||||
// This number indicates for every unit of cargo, how many tiles two stations maybe be away
|
||||
// from eachother. In other words: if we have 120 units of cargo in one station, and 120 units
|
||||
// of the cargo in the other station, both stations can be 96 units away from eachother, if the
|
||||
// next number is 0.4.
|
||||
#define AI_LOCATEROUTE_BUS_CARGO_DISTANCE 0.4
|
||||
#define AI_LOCATEROUTE_TRUCK_CARGO_DISTANCE 0.7
|
||||
// In whole tiles, the minimum distance for a truck route
|
||||
#define AI_LOCATEROUTE_TRUCK_MIN_DISTANCE 30
|
||||
|
||||
// The amount of tiles in a square from -X to +X that is scanned for a station spot
|
||||
// (so if this number is 10, 20x20 = 400 tiles are scanned for _the_ perfect spot
|
||||
// Safe values are between 15 and 5
|
||||
#define AI_FINDSTATION_TILE_RANGE 10
|
||||
|
||||
// Building on normal speed goes very fast. Idle this amount of ticks between every
|
||||
// building part. It is calculated like this: (4 - competitor_speed) * num + 1
|
||||
// where competitor_speed is between 0 (very slow) to 4 (very fast)
|
||||
#define AI_BUILDPATH_PAUSE 10
|
||||
|
||||
// Minimum % of reliabilty a vehicle has to have before the AI buys it
|
||||
#define AI_VEHICLE_MIN_RELIABILTY 60
|
||||
|
||||
// The minimum amount of money a player should always have
|
||||
#define AI_MINIMUM_MONEY 15000
|
||||
|
||||
// If the most cheap route is build, how much is it going to cost..
|
||||
// This is to prevent the AI from trying to build a route which can not be paid for
|
||||
#define AI_MINIMUM_BUS_ROUTE_MONEY 25000
|
||||
#define AI_MINIMUM_TRUCK_ROUTE_MONEY 35000
|
||||
|
||||
// The minimum amount of money before we are going to repay any money
|
||||
#define AI_MINIMUM_LOAN_REPAY_MONEY 40000
|
||||
// How many repays do we do if we have enough money to do so?
|
||||
// Every repay is 10000
|
||||
#define AI_LOAN_REPAY 2
|
||||
// How much income must we have before paying back a loan? Month-based (and looked at the last month)
|
||||
#define AI_MINIMUM_INCOME_FOR_LOAN 7000
|
||||
|
||||
// If there is <num> time as much cargo in the station then the vehicle can handle
|
||||
// reuse the station instead of building a new one!
|
||||
#define AI_STATION_REUSE_MULTIPLER 2
|
||||
|
||||
// No more then this amount of vehicles per station..
|
||||
#define AI_CHECK_MAX_VEHICLE_PER_STATION 10
|
||||
|
||||
// How many thick between building 2 vehicles
|
||||
#define AI_BUILD_VEHICLE_TIME_BETWEEN DAY_TICKS
|
||||
|
||||
// How many days must there between vehicle checks
|
||||
// The more often, the less non-money-making lines there will be
|
||||
// but the unfair it may seem to a human player
|
||||
#define AI_DAYS_BETWEEN_VEHICLE_CHECKS 30
|
||||
|
||||
// How money profit does a vehicle needs to make to stay in order
|
||||
// This is the profit of this year + profit of last year
|
||||
// But also for vehicles that are just one year old. In other words:
|
||||
// Vehicles of 2 years do easier meet this setting then vehicles
|
||||
// of one year. This is a very good thing. New vehicles are filtered,
|
||||
// while old vehicles stay longer, because we do get less in return.
|
||||
#define AI_MINIMUM_ROUTE_PROFIT 1000
|
||||
|
||||
// A vehicle is considered lost when he his cargo is more then 180 days old
|
||||
#define AI_VEHICLE_LOST_DAYS 180
|
||||
|
||||
// How many times may the AI try to find a route before it gives up
|
||||
#define AI_MAX_TRIES_FOR_SAME_ROUTE 8
|
||||
|
||||
/*
|
||||
* End of defines
|
||||
*/
|
||||
|
||||
// This stops 90degrees curves
|
||||
static const byte _illegal_curves[6] = {
|
||||
255, 255, // Horz and vert, don't have the effect
|
||||
5, // upleft and upright are not valid
|
||||
4, // downright and downleft are not valid
|
||||
2, // downleft and upleft are not valid
|
||||
3, // upright and downright are not valid
|
||||
};
|
||||
|
||||
static const TileIndexDiff _tiles_around[4] = {
|
||||
TILE_XY(-1,0),
|
||||
TILE_XY(0,1),
|
||||
TILE_XY(1,0),
|
||||
TILE_XY(0,-1),
|
||||
};
|
||||
|
||||
enum {
|
||||
AI_STATE_STARTUP = 0,
|
||||
AI_STATE_FIRST_TIME,
|
||||
AI_STATE_NOTHING,
|
||||
AI_STATE_WAKE_UP,
|
||||
AI_STATE_LOCATE_ROUTE,
|
||||
AI_STATE_FIND_STATION,
|
||||
AI_STATE_FIND_PATH,
|
||||
AI_STATE_FIND_DEPOT,
|
||||
AI_STATE_VERIFY_ROUTE,
|
||||
AI_STATE_BUILD_STATION,
|
||||
AI_STATE_BUILD_PATH,
|
||||
AI_STATE_BUILD_DEPOT,
|
||||
AI_STATE_BUILD_VEHICLE,
|
||||
AI_STATE_GIVE_ORDERS,
|
||||
AI_STATE_START_VEHICLE,
|
||||
AI_STATE_REPAY_MONEY,
|
||||
AI_STATE_CHECK_ALL_VEHICLES,
|
||||
AI_STATE_ACTION_DONE,
|
||||
AI_STATE_STOP, // Temporary function to stop the AI
|
||||
};
|
||||
|
||||
// Used for tbt (train/bus/truck)
|
||||
enum {
|
||||
AI_TRAIN = 0,
|
||||
AI_BUS,
|
||||
AI_TRUCK,
|
||||
};
|
||||
|
||||
enum {
|
||||
AI_ACTION_NONE = 0,
|
||||
AI_ACTION_BUS_ROUTE,
|
||||
AI_ACTION_TRUCK_ROUTE,
|
||||
AI_ACTION_REPAY_LOAN,
|
||||
AI_ACTION_CHECK_ALL_VEHICLES,
|
||||
};
|
||||
|
||||
// Used for from_type/to_type
|
||||
enum {
|
||||
AI_NO_TYPE = 0,
|
||||
AI_CITY,
|
||||
AI_INDUSTRY,
|
||||
};
|
||||
|
||||
// Flags for in the vehicle
|
||||
enum {
|
||||
AI_VEHICLEFLAG_SELL = 1,
|
||||
// Remember, flags must be in power of 2
|
||||
};
|
||||
|
||||
#define AI_NO_CARGO 0xFF // Means that there is no cargo defined yet (used for industry)
|
||||
#define AI_NEED_CARGO 0xFE // Used when the AI needs to find out a cargo for the route
|
||||
#define AI_STATION_RANGE TILE_XY(TILE_X_MAX, TILE_Y_MAX)
|
||||
|
||||
#define AI_PATHFINDER_NO_DIRECTION (byte)-1
|
||||
|
||||
// Flags used in user_data
|
||||
#define AI_PATHFINDER_FLAG_BRIDGE 1
|
||||
#define AI_PATHFINDER_FLAG_TUNNEL 2
|
||||
|
||||
// A macro for mp_street, where 0x20 is depot
|
||||
// mp_tunnelbridge, where 0xf0 is a bridge, and 0x4/0x2 means: roadtunnel/bridge
|
||||
#define AI_PATHFINDER_IS_ROAD(tile) ((IS_TILETYPE(tile, MP_STREET) && !(_map5[tile] & 0x20)) || \
|
||||
(IS_TILETYPE(tile, MP_TUNNELBRIDGE) && \
|
||||
(((_map5[tile] & 0x80) == 0 && (_map5[tile] & 0x4) == 0x4) || \
|
||||
((_map5[tile] & 0x80) != 0 && (_map5[tile] & 0x2) == 0x2))))
|
||||
|
||||
typedef void AiNew_StateFunction(Player *p);
|
||||
|
||||
// ai_new.c
|
||||
void AiNewDoGameLoop(Player *p);
|
||||
|
||||
// ai_pathfinder.c
|
||||
AyStar *new_AyStar_AiPathFinder(int max_tiles_around, Ai_PathFinderInfo *PathFinderInfo);
|
||||
void clean_AyStar_AiPathFinder(AyStar *aystar, Ai_PathFinderInfo *PathFinderInfo);
|
||||
|
||||
// ai_shared.c
|
||||
int AiNew_GetRailDirection(uint tile_a, uint tile_b, uint tile_c);
|
||||
int AiNew_GetRoadDirection(uint tile_a, uint tile_b, uint tile_c);
|
||||
int AiNew_GetDirection(uint tile_a, uint tile_b);
|
||||
bool AiNew_SetSpecialVehicleFlag(Player *p, Vehicle *v, uint flag);
|
||||
uint AiNew_GetSpecialVehicleFlag(Player *p, Vehicle *v);
|
||||
|
||||
// ai_build.c
|
||||
bool AiNew_Build_CompanyHQ(Player *p, uint tile);
|
||||
int AiNew_Build_Station(Player *p, byte type, uint tile, byte length, byte numtracks, byte direction, byte flag);
|
||||
int AiNew_Build_Bridge(Player *p, uint tile_a, uint tile_b, byte flag);
|
||||
int AiNew_Build_RoutePart(Player *p, Ai_PathFinderInfo *PathFinderInfo, byte flag);
|
||||
int AiNew_PickVehicle(Player *p);
|
||||
int AiNew_Build_Vehicle(Player *p, uint tile, byte flag);
|
||||
int AiNew_Build_Depot(Player *p, uint tile, byte direction, byte flag);
|
||||
|
||||
|
||||
#endif
|
257
trunk/ai_build.c
257
trunk/ai_build.c
|
@ -1,257 +0,0 @@
|
|||
#include "stdafx.h"
|
||||
#include "ttd.h"
|
||||
#include "command.h"
|
||||
#include "ai.h"
|
||||
#include "engine.h"
|
||||
|
||||
// Build HQ
|
||||
// Params:
|
||||
// tile : tile where HQ is going to be build
|
||||
bool AiNew_Build_CompanyHQ(Player *p, uint tile) {
|
||||
if (DoCommandByTile(tile, 0, 0, DC_AUTO | DC_NO_WATER, CMD_BUILD_COMPANY_HQ) == CMD_ERROR)
|
||||
return false;
|
||||
DoCommandByTile(tile, 0, 0, DC_EXEC | DC_AUTO | DC_NO_WATER, CMD_BUILD_COMPANY_HQ);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Build station
|
||||
// Params:
|
||||
// type : AI_TRAIN/AI_BUS/AI_TRUCK : indicates the type of station
|
||||
// tile : tile where station is going to be build
|
||||
// length : in case of AI_TRAIN: length of station
|
||||
// numtracks : in case of AI_TRAIN: tracks of station
|
||||
// direction : the direction of the station
|
||||
// flag : flag passed to DoCommand (normally 0 to get the cost or DC_EXEC to build it)
|
||||
int AiNew_Build_Station(Player *p, byte type, uint tile, byte length, byte numtracks, byte direction, byte flag) {
|
||||
if (type == AI_TRAIN)
|
||||
return DoCommandByTile(tile, direction + (numtracks << 8) + (length << 16), 0, flag | DC_AUTO | DC_NO_WATER, CMD_BUILD_RAILROAD_STATION);
|
||||
else if (type == AI_BUS)
|
||||
return DoCommandByTile(tile, direction, 0, flag | DC_AUTO | DC_NO_WATER, CMD_BUILD_BUS_STATION);
|
||||
else
|
||||
return DoCommandByTile(tile, direction, 0, flag | DC_AUTO | DC_NO_WATER, CMD_BUILD_TRUCK_STATION);
|
||||
}
|
||||
|
||||
// Builds a brdige. The second best out of the ones available for this player
|
||||
// Params:
|
||||
// tile_a : starting point
|
||||
// tile_b : end point
|
||||
// flag : flag passed to DoCommand
|
||||
int AiNew_Build_Bridge(Player *p, uint tile_a, uint tile_b, byte flag) {
|
||||
int bridge_type, bridge_len, type, type2;
|
||||
|
||||
// Find a good bridgetype (the best money can buy)
|
||||
bridge_len = GetBridgeLength(tile_a, tile_b);
|
||||
type = type2 = 0;
|
||||
for (bridge_type = MAX_BRIDGES-1; bridge_type >= 0; bridge_type--) {
|
||||
if (CheckBridge_Stuff(bridge_type, bridge_len)) {
|
||||
type2 = type;
|
||||
type = bridge_type;
|
||||
// We found two bridges, exit
|
||||
if (type2 != 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
// There is only one bridge that can be build..
|
||||
if (type2 == 0 && type != 0) type2 = type;
|
||||
|
||||
// Now, simply, build the bridge!
|
||||
if (p->ainew.tbt == AI_TRAIN)
|
||||
return DoCommandByTile(tile_a, tile_b, (0<<8) + type2, flag | DC_AUTO, CMD_BUILD_BRIDGE);
|
||||
else
|
||||
return DoCommandByTile(tile_a, tile_b, (0x80 << 8) + type2, flag | DC_AUTO, CMD_BUILD_BRIDGE);
|
||||
}
|
||||
|
||||
|
||||
// Build the route part by part
|
||||
// Basicly what this function do, is build that amount of parts of the route
|
||||
// that go in the same direction. It sets 'part' to the last part of the route builded.
|
||||
// The return value is the cost for the builded parts
|
||||
//
|
||||
// Params:
|
||||
// PathFinderInfo : Pointer to the PathFinderInfo used for AiPathFinder
|
||||
// part : Which part we need to build
|
||||
//
|
||||
// TODO: skip already builded road-pieces (e.g.: cityroad)
|
||||
int AiNew_Build_RoutePart(Player *p, Ai_PathFinderInfo *PathFinderInfo, byte flag) {
|
||||
int part = PathFinderInfo->position;
|
||||
byte *route_extra = PathFinderInfo->route_extra;
|
||||
TileIndex *route = PathFinderInfo->route;
|
||||
int dir;
|
||||
int old_dir = -1;
|
||||
int cost = 0;
|
||||
int res;
|
||||
// We need to calculate the direction with the parent of the parent.. so we skip
|
||||
// the first pieces and the last piece
|
||||
if (part < 1) part = 1;
|
||||
// When we are done, stop it
|
||||
if (part >= PathFinderInfo->route_length - 1) { PathFinderInfo->position = -2; return 0; }
|
||||
|
||||
|
||||
if (PathFinderInfo->rail_or_road) {
|
||||
// Tunnel code
|
||||
if ((AI_PATHFINDER_FLAG_TUNNEL & route_extra[part]) != 0) {
|
||||
cost += DoCommandByTile(route[part], 0, 0, flag, CMD_BUILD_TUNNEL);
|
||||
PathFinderInfo->position++;
|
||||
// TODO: problems!
|
||||
if (cost == CMD_ERROR) {
|
||||
DEBUG(ai,0)("[AiNew - BuildPath] We have a serious problem: tunnel could not be build!");
|
||||
return 0;
|
||||
}
|
||||
return cost;
|
||||
}
|
||||
// Bridge code
|
||||
if ((AI_PATHFINDER_FLAG_BRIDGE & route_extra[part]) != 0) {
|
||||
cost += AiNew_Build_Bridge(p, route[part], route[part-1], flag);
|
||||
PathFinderInfo->position++;
|
||||
// TODO: problems!
|
||||
if (cost == CMD_ERROR) {
|
||||
DEBUG(ai,0)("[AiNew - BuildPath] We have a serious problem: bridge could not be build!");
|
||||
return 0;
|
||||
}
|
||||
return cost;
|
||||
}
|
||||
|
||||
// Build normal rail
|
||||
// Keep it doing till we go an other way
|
||||
if (route_extra[part-1] == 0 && route_extra[part] == 0) {
|
||||
while (route_extra[part] == 0) {
|
||||
// Get the current direction
|
||||
dir = AiNew_GetRailDirection(route[part-1], route[part], route[part+1]);
|
||||
// Is it the same as the last one?
|
||||
if (old_dir != -1 && old_dir != dir) break;
|
||||
old_dir = dir;
|
||||
// Build the tile
|
||||
res = DoCommandByTile(route[part], 0, dir, flag, CMD_BUILD_SINGLE_RAIL);
|
||||
if (res == CMD_ERROR) {
|
||||
// Problem.. let's just abort it all!
|
||||
p->ainew.state = AI_STATE_NOTHING;
|
||||
return 0;
|
||||
}
|
||||
cost += res;
|
||||
// Go to the next tile
|
||||
part++;
|
||||
// Check if it is still in range..
|
||||
if (part >= PathFinderInfo->route_length - 1) break;
|
||||
}
|
||||
part--;
|
||||
}
|
||||
// We want to return the last position, so we go back one
|
||||
PathFinderInfo->position = part;
|
||||
} else {
|
||||
// Tunnel code
|
||||
if ((AI_PATHFINDER_FLAG_TUNNEL & route_extra[part]) != 0) {
|
||||
cost += DoCommandByTile(route[part], 0x200, 0, flag, CMD_BUILD_TUNNEL);
|
||||
PathFinderInfo->position++;
|
||||
// TODO: problems!
|
||||
if (cost == CMD_ERROR) {
|
||||
DEBUG(ai,0)("[AiNew - BuildPath] We have a serious problem: tunnel could not be build!");
|
||||
return 0;
|
||||
}
|
||||
return cost;
|
||||
}
|
||||
// Bridge code
|
||||
if ((AI_PATHFINDER_FLAG_BRIDGE & route_extra[part]) != 0) {
|
||||
cost += AiNew_Build_Bridge(p, route[part], route[part+1], flag);
|
||||
PathFinderInfo->position++;
|
||||
// TODO: problems!
|
||||
if (cost == CMD_ERROR) {
|
||||
DEBUG(ai,0)("[AiNew - BuildPath] We have a serious problem: bridge could not be build!");
|
||||
return 0;
|
||||
}
|
||||
return cost;
|
||||
}
|
||||
|
||||
// Build normal road
|
||||
// Keep it doing till we go an other way
|
||||
// EnsureNoVehicle makes sure we don't build on a tile where a vehicle is. This way
|
||||
// it will wait till the vehicle is gone..
|
||||
if (route_extra[part-1] == 0 && route_extra[part] == 0 && (flag != DC_EXEC || EnsureNoVehicle(route[part]))) {
|
||||
while (route_extra[part] == 0 && (flag != DC_EXEC || EnsureNoVehicle(route[part]))) {
|
||||
// Get the current direction
|
||||
dir = AiNew_GetRoadDirection(route[part-1], route[part], route[part+1]);
|
||||
// Is it the same as the last one?
|
||||
if (old_dir != -1 && old_dir != dir) break;
|
||||
old_dir = dir;
|
||||
// There is already some road, and it is a bridge.. don't build!!!
|
||||
if (!IS_TILETYPE(route[part], MP_TUNNELBRIDGE)) {
|
||||
// Build the tile
|
||||
res = DoCommandByTile(route[part], dir, 0, flag | DC_NO_WATER, CMD_BUILD_ROAD);
|
||||
// Currently, we ignore CMD_ERRORs!
|
||||
if (res == CMD_ERROR && flag == DC_EXEC && !IS_TILETYPE(route[part], MP_STREET) && !EnsureNoVehicle(route[part])) {
|
||||
// Problem.. let's just abort it all!
|
||||
DEBUG(ai,0)("Darn, the route could not be builded.. aborting!");
|
||||
p->ainew.state = AI_STATE_NOTHING;
|
||||
return 0;
|
||||
} else {
|
||||
if (res != CMD_ERROR)
|
||||
cost += res;
|
||||
}
|
||||
}
|
||||
// Go to the next tile
|
||||
part++;
|
||||
// Check if it is still in range..
|
||||
if (part >= PathFinderInfo->route_length - 1) break;
|
||||
}
|
||||
part--;
|
||||
// We want to return the last position, so we go back one
|
||||
}
|
||||
if (!EnsureNoVehicle(route[part]) && flag == DC_EXEC) part--;
|
||||
PathFinderInfo->position = part;
|
||||
}
|
||||
|
||||
return cost;
|
||||
}
|
||||
|
||||
// This functions tries to find the best vehicle for this type of cargo
|
||||
// It returns vehicle_id or -1 if not found
|
||||
int AiNew_PickVehicle(Player *p) {
|
||||
if (p->ainew.tbt == AI_TRAIN) {
|
||||
// Not supported yet
|
||||
return -1;
|
||||
} else {
|
||||
int start, count, i, r = CMD_ERROR;
|
||||
start = _cargoc.ai_roadveh_start[p->ainew.cargo];
|
||||
count = _cargoc.ai_roadveh_count[p->ainew.cargo];
|
||||
|
||||
// Let's check it backwards.. we simply want to best engine available..
|
||||
for (i=start+count-1;i>=start;i--) {
|
||||
// Is it availiable?
|
||||
// Also, check if the reliability of the vehicle is above the AI_VEHICLE_MIN_RELIABILTY
|
||||
if (!HASBIT(_engines[i].player_avail, _current_player) || _engines[i].reliability * 100 < AI_VEHICLE_MIN_RELIABILTY << 16) continue;
|
||||
// Can we build it?
|
||||
r = DoCommandByTile(0, i, 0, DC_QUERY_COST, CMD_BUILD_ROAD_VEH);
|
||||
if (r != CMD_ERROR) break;
|
||||
}
|
||||
// We did not find a vehicle :(
|
||||
if (r == CMD_ERROR) { return -1; }
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
// Builds the best vehicle possible
|
||||
int AiNew_Build_Vehicle(Player *p, uint tile, byte flag) {
|
||||
int i = AiNew_PickVehicle(p);
|
||||
if (i == -1) return CMD_ERROR;
|
||||
|
||||
if (p->ainew.tbt == AI_TRAIN) {
|
||||
return CMD_ERROR;
|
||||
} else {
|
||||
return DoCommandByTile(tile, i, 0, flag, CMD_BUILD_ROAD_VEH);
|
||||
}
|
||||
}
|
||||
|
||||
int AiNew_Build_Depot(Player *p, uint tile, byte direction, byte flag) {
|
||||
static const byte _roadbits_by_dir[4] = {2,1,8,4};
|
||||
int r, r2;
|
||||
if (p->ainew.tbt == AI_TRAIN) {
|
||||
return DoCommandByTile(tile, 0, direction, flag | DC_AUTO | DC_NO_WATER, CMD_BUILD_TRAIN_DEPOT);
|
||||
} else {
|
||||
r = DoCommandByTile(tile, direction, 0, flag | DC_AUTO | DC_NO_WATER, CMD_BUILD_ROAD_DEPOT);
|
||||
if (r == CMD_ERROR) return r;
|
||||
// Try to build the road from the depot
|
||||
r2 = DoCommandByTile(tile + _tileoffs_by_dir[direction], _roadbits_by_dir[direction], 0, flag | DC_AUTO | DC_NO_WATER, CMD_BUILD_ROAD);
|
||||
// If it fails, ignore it..
|
||||
if (r2 == CMD_ERROR) return r;
|
||||
return r + r2;
|
||||
}
|
||||
}
|
1302
trunk/ai_new.c
1302
trunk/ai_new.c
File diff suppressed because it is too large
Load Diff
|
@ -1,457 +0,0 @@
|
|||
#include "stdafx.h"
|
||||
#include "ttd.h"
|
||||
#include "command.h"
|
||||
#include "ai.h"
|
||||
|
||||
#define TEST_STATION_NO_DIR 0xFF
|
||||
|
||||
// Tests if a station can be build on the given spot
|
||||
// TODO: make it train compatible
|
||||
bool TestCanBuildStationHere(uint tile, byte dir) {
|
||||
Player *p = DEREF_PLAYER(_current_player);
|
||||
if (dir == TEST_STATION_NO_DIR) {
|
||||
// TODO: currently we only allow spots that can be access from al 4 directions...
|
||||
// should be fixed!!!
|
||||
for (dir=0;dir<4;dir++) {
|
||||
int res = AiNew_Build_Station(p, p->ainew.tbt, tile, 1, 1, dir, DC_QUERY_COST);
|
||||
if (res != CMD_ERROR)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
} else {
|
||||
int res = AiNew_Build_Station(p, p->ainew.tbt, tile, 1, 1, dir, DC_QUERY_COST);
|
||||
if (res == CMD_ERROR)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Checks if a tile 'a' is between the tiles 'b' and 'c'
|
||||
#define TILES_BETWEEN(a,b,c) (GET_TILE_X(a) >= GET_TILE_X(b) && GET_TILE_X(a) <= GET_TILE_X(c) && GET_TILE_Y(a) >= GET_TILE_Y(b) && GET_TILE_Y(a) <= GET_TILE_Y(c))
|
||||
|
||||
// Check if the current tile is in our end-area
|
||||
int32 AyStar_AiPathFinder_EndNodeCheck(AyStar *aystar, OpenListNode *current) {
|
||||
Ai_PathFinderInfo *PathFinderInfo = (Ai_PathFinderInfo*)aystar->user_target;
|
||||
// It is not allowed to have a station on the end of a bridge or tunnel ;)
|
||||
if (current->path.node.user_data[0] != 0) return AYSTAR_DONE;
|
||||
if (TILES_BETWEEN(current->path.node.tile, PathFinderInfo->end_tile_tl, PathFinderInfo->end_tile_br))
|
||||
if (IS_TILETYPE(current->path.node.tile, MP_CLEAR) || IS_TILETYPE(current->path.node.tile, MP_TREES))
|
||||
if (current->path.parent == NULL || TestCanBuildStationHere(current->path.node.tile,AiNew_GetDirection(current->path.parent->node.tile, current->path.node.tile)))
|
||||
return AYSTAR_FOUND_END_NODE;
|
||||
|
||||
return AYSTAR_DONE;
|
||||
}
|
||||
|
||||
// Calculates the hash
|
||||
// Currently it is a 10 bit hash, so the hash array has a max depth of 6 bits (so 64)
|
||||
uint AiPathFinder_Hash(uint key1, uint key2) {
|
||||
return (GET_TILE_X(key1) & 0x1F) + ((GET_TILE_Y(key1) & 0x1F) << 5);
|
||||
}
|
||||
|
||||
// Clear the memory of all the things
|
||||
void AyStar_AiPathFinder_Free(AyStar *aystar) {
|
||||
AyStarMain_Free(aystar);
|
||||
free(aystar);
|
||||
}
|
||||
|
||||
static int32 AyStar_AiPathFinder_CalculateG(AyStar *aystar, AyStarNode *current, OpenListNode *parent);
|
||||
static int32 AyStar_AiPathFinder_CalculateH(AyStar *aystar, AyStarNode *current, OpenListNode *parent);
|
||||
static void AyStar_AiPathFinder_FoundEndNode(AyStar *aystar, OpenListNode *current);
|
||||
static void AyStar_AiPathFinder_GetNeighbours(AyStar *aystar, OpenListNode *current);
|
||||
|
||||
// This creates the AiPathFinder
|
||||
AyStar *new_AyStar_AiPathFinder(int max_tiles_around, Ai_PathFinderInfo *PathFinderInfo) {
|
||||
PathNode start_node;
|
||||
uint x,y;
|
||||
// Create AyStar
|
||||
AyStar *result = malloc(sizeof(AyStar));
|
||||
init_AyStar(result, AiPathFinder_Hash, 1 << 10);
|
||||
// Set the function pointers
|
||||
result->CalculateG = AyStar_AiPathFinder_CalculateG;
|
||||
result->CalculateH = AyStar_AiPathFinder_CalculateH;
|
||||
result->EndNodeCheck = AyStar_AiPathFinder_EndNodeCheck;
|
||||
result->FoundEndNode = AyStar_AiPathFinder_FoundEndNode;
|
||||
result->GetNeighbours = AyStar_AiPathFinder_GetNeighbours;
|
||||
|
||||
result->free = AyStar_AiPathFinder_Free;
|
||||
|
||||
// Set some information
|
||||
result->loops_per_tick = AI_PATHFINDER_LOOPS_PER_TICK;
|
||||
result->max_path_cost = 0;
|
||||
result->max_search_nodes = AI_PATHFINDER_MAX_SEARCH_NODES;
|
||||
|
||||
// Set the user_data to the PathFinderInfo
|
||||
result->user_target = PathFinderInfo;
|
||||
|
||||
// Set the start node
|
||||
start_node.parent = NULL;
|
||||
start_node.node.direction = 0;
|
||||
start_node.node.user_data[0] = 0;
|
||||
|
||||
// Now we add all the starting tiles
|
||||
for (x=GET_TILE_X(PathFinderInfo->start_tile_tl);x<=GET_TILE_X(PathFinderInfo->start_tile_br);x++) {
|
||||
for (y=GET_TILE_Y(PathFinderInfo->start_tile_tl);y<=GET_TILE_Y(PathFinderInfo->start_tile_br);y++) {
|
||||
start_node.node.tile = TILE_XY(x,y);
|
||||
result->addstart(result, &start_node.node);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// To reuse AyStar we sometimes have to clean all the memory
|
||||
void clean_AyStar_AiPathFinder(AyStar *aystar, Ai_PathFinderInfo *PathFinderInfo) {
|
||||
PathNode start_node;
|
||||
uint x,y;
|
||||
|
||||
aystar->clear(aystar);
|
||||
|
||||
// Set the user_data to the PathFinderInfo
|
||||
aystar->user_target = PathFinderInfo;
|
||||
|
||||
// Set the start node
|
||||
start_node.parent = NULL;
|
||||
start_node.node.direction = 0;
|
||||
start_node.node.user_data[0] = 0;
|
||||
start_node.node.tile = PathFinderInfo->start_tile_tl;
|
||||
|
||||
// Now we add all the starting tiles
|
||||
for (x=GET_TILE_X(PathFinderInfo->start_tile_tl);x<=GET_TILE_X(PathFinderInfo->start_tile_br);x++) {
|
||||
for (y=GET_TILE_Y(PathFinderInfo->start_tile_tl);y<=GET_TILE_Y(PathFinderInfo->start_tile_br);y++) {
|
||||
if (!(IS_TILETYPE(TILE_XY(x,y), MP_CLEAR) || IS_TILETYPE(TILE_XY(x,y), MP_TREES))) continue;
|
||||
if (!TestCanBuildStationHere(TILE_XY(x,y),TEST_STATION_NO_DIR)) continue;
|
||||
start_node.node.tile = TILE_XY(x,y);
|
||||
aystar->addstart(aystar, &start_node.node);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The h-value, simple calculation
|
||||
static int32 AyStar_AiPathFinder_CalculateH(AyStar *aystar, AyStarNode *current, OpenListNode *parent) {
|
||||
Ai_PathFinderInfo *PathFinderInfo = (Ai_PathFinderInfo*)aystar->user_target;
|
||||
int r, r2;
|
||||
if (PathFinderInfo->end_direction != AI_PATHFINDER_NO_DIRECTION) {
|
||||
// The station is pointing to a direction, add a tile towards that direction, so the H-value is more accurate
|
||||
r = GetTileDist(current->tile, PathFinderInfo->end_tile_tl + _tiles_around[PathFinderInfo->end_direction]);
|
||||
r2 = GetTileDist(current->tile, PathFinderInfo->end_tile_br + _tiles_around[PathFinderInfo->end_direction]);
|
||||
} else {
|
||||
// No direction, so just get the fastest route to the station
|
||||
r = GetTileDist(current->tile, PathFinderInfo->end_tile_tl);
|
||||
r2 = GetTileDist(current->tile, PathFinderInfo->end_tile_br);
|
||||
}
|
||||
// See if the bottomright is faster then the topleft..
|
||||
if (r2 < r) r = r2;
|
||||
return r * AI_PATHFINDER_H_MULTIPLER;
|
||||
}
|
||||
|
||||
// We found the end.. let's get the route back and put it in an array
|
||||
static void AyStar_AiPathFinder_FoundEndNode(AyStar *aystar, OpenListNode *current) {
|
||||
Ai_PathFinderInfo *PathFinderInfo = (Ai_PathFinderInfo*)aystar->user_target;
|
||||
int i = 0;
|
||||
PathNode *parent = ¤t->path;
|
||||
|
||||
do {
|
||||
PathFinderInfo->route_extra[i] = parent->node.user_data[0];
|
||||
PathFinderInfo->route[i++] = parent->node.tile;
|
||||
if (i > lengthof(PathFinderInfo->route)) {
|
||||
// We ran out of space for the PathFinder
|
||||
DEBUG(ai,0)("[AiPathFinder] Ran out of spacein the route[] array!!!");
|
||||
PathFinderInfo->route_length = -1; // -1 indicates out of space
|
||||
return;
|
||||
}
|
||||
parent = parent->parent;
|
||||
} while (parent != NULL);
|
||||
PathFinderInfo->route_length = i;
|
||||
DEBUG(ai,1)("[Ai-PathFinding] Found route of %d nodes long in %d nodes of searching",i,Hash_Size(&aystar->ClosedListHash));
|
||||
}
|
||||
|
||||
// What tiles are around us.
|
||||
static void AyStar_AiPathFinder_GetNeighbours(AyStar *aystar, OpenListNode *current) {
|
||||
int i, r, dir;
|
||||
Ai_PathFinderInfo *PathFinderInfo = (Ai_PathFinderInfo*)aystar->user_target;
|
||||
|
||||
aystar->num_neighbours = 0;
|
||||
|
||||
// Go through all surrounding tiles and check if they are within the limits
|
||||
for (i=0;i<4;i++) {
|
||||
if (GET_TILE_X(_tiles_around[i] + current->path.node.tile) > 1 && GET_TILE_X(_tiles_around[i] + current->path.node.tile) < TILE_X_MAX - 1 &&
|
||||
GET_TILE_Y(_tiles_around[i] + current->path.node.tile) > 1 && GET_TILE_Y(_tiles_around[i] + current->path.node.tile) < TILE_Y_MAX - 1) {
|
||||
// We also directly test if the current tile can connect to this tile..
|
||||
// We do this simply by just building the tile!
|
||||
|
||||
// If the next step is a bridge, we have to enter it the right way
|
||||
if (!PathFinderInfo->rail_or_road && AI_PATHFINDER_IS_ROAD(current->path.node.tile + _tiles_around[i])) {
|
||||
if (IS_TILETYPE(current->path.node.tile + _tiles_around[i], MP_TUNNELBRIDGE)) {
|
||||
// An existing bridge... let's test the direction ;)
|
||||
if ((_map5[current->path.node.tile + _tiles_around[i]] & 1) != (i & 1)) continue;
|
||||
// This problem only is valid for tunnels:
|
||||
// When the last tile was not yet a tunnel, check if we enter from the right side..
|
||||
if (!IS_TILETYPE(current->path.node.tile, MP_TUNNELBRIDGE) && (_map5[current->path.node.tile + _tiles_around[i]] & 0x80) == 0) {
|
||||
if (i != (_map5[current->path.node.tile + _tiles_around[i]] & 3)) continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
// But also if we are on a bridge, we can only move a certain direction
|
||||
if (!PathFinderInfo->rail_or_road && AI_PATHFINDER_IS_ROAD(current->path.node.tile)) {
|
||||
if (IS_TILETYPE(current->path.node.tile, MP_TUNNELBRIDGE)) {
|
||||
// An existing bridge/tunnel... let's test the direction ;)
|
||||
if ((_map5[current->path.node.tile] & 1) != (i & 1)) continue;
|
||||
}
|
||||
}
|
||||
|
||||
if ((AI_PATHFINDER_FLAG_BRIDGE & current->path.node.user_data[0]) != 0 ||
|
||||
(AI_PATHFINDER_FLAG_TUNNEL & current->path.node.user_data[0]) != 0) {
|
||||
// We are a bridge/tunnel, how cool!!
|
||||
// This means we can only point forward.. get the direction from the user_data
|
||||
if (i != (current->path.node.user_data[0] >> 8)) continue;
|
||||
}
|
||||
dir = 0;
|
||||
|
||||
// First, check if we have a parent
|
||||
if (current->path.parent == NULL && current->path.node.user_data[0] == 0) {
|
||||
// If not, this means we are at the starting station
|
||||
if (PathFinderInfo->start_direction != AI_PATHFINDER_NO_DIRECTION) {
|
||||
// We do need a direction?
|
||||
if (AiNew_GetDirection(current->path.node.tile, current->path.node.tile + _tiles_around[i]) != PathFinderInfo->start_direction)
|
||||
// We are not pointing the right way, invalid tile
|
||||
continue;
|
||||
}
|
||||
} else if (current->path.node.user_data[0] == 0) {
|
||||
if (PathFinderInfo->rail_or_road) {
|
||||
// Rail check
|
||||
dir = AiNew_GetRailDirection(current->path.parent->node.tile, current->path.node.tile, current->path.node.tile + _tiles_around[i]);
|
||||
r = DoCommandByTile(current->path.node.tile, 0, dir, DC_AUTO | DC_NO_WATER, CMD_BUILD_SINGLE_RAIL);
|
||||
if (r == CMD_ERROR) continue;
|
||||
#ifdef AI_PATHFINDER_NO_90DEGREES_TURN
|
||||
if (current->path.parent->parent != NULL) {
|
||||
// Check if we don't make a 90degree curve
|
||||
int dir1 = AiNew_GetRailDirection(current->path.parent->parent->node.tile, current->path.parent->node.tile, current->path.node.tile);
|
||||
if (_illegal_curves[dir1] == dir || _illegal_curves[dir] == dir1) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
// Road check
|
||||
dir = AiNew_GetRoadDirection(current->path.parent->node.tile, current->path.node.tile, current->path.node.tile + _tiles_around[i]);
|
||||
if (AI_PATHFINDER_IS_ROAD(current->path.node.tile)) {
|
||||
if (IS_TILETYPE(current->path.node.tile, MP_TUNNELBRIDGE)) {
|
||||
// We have a bridge, how nicely! We should mark it...
|
||||
dir = 0;
|
||||
} else {
|
||||
// It already has road.. check if we miss any bits!
|
||||
if ((_map5[current->path.node.tile] & dir) != dir) {
|
||||
// We do miss some pieces :(
|
||||
dir &= ~_map5[current->path.node.tile];
|
||||
} else {
|
||||
dir = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Only destruct things if it is MP_CLEAR of MP_TREES
|
||||
if (dir != 0) {
|
||||
r = DoCommandByTile(current->path.node.tile, dir, 0, DC_AUTO | DC_NO_WATER, CMD_BUILD_ROAD);
|
||||
if (r == CMD_ERROR) continue;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// The tile can be connected
|
||||
aystar->neighbours[aystar->num_neighbours].tile = _tiles_around[i] + current->path.node.tile;
|
||||
aystar->neighbours[aystar->num_neighbours].user_data[0] = 0;
|
||||
aystar->neighbours[aystar->num_neighbours++].direction = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Next step, check for bridges and tunnels
|
||||
if (current->path.parent != NULL && current->path.node.user_data[0] == 0) {
|
||||
|
||||
TileInfo ti;
|
||||
// First we get the dir from this tile and his parent
|
||||
int dir = AiNew_GetDirection(current->path.parent->node.tile, current->path.node.tile);
|
||||
// It means we can only walk with the track, so the bridge has to be in the same direction
|
||||
TileIndex tile = current->path.node.tile;
|
||||
TileIndex new_tile = tile;
|
||||
|
||||
FindLandscapeHeightByTile(&ti, tile);
|
||||
|
||||
// Bridges can only be build on land that is not flat
|
||||
// And if there is a road or rail blocking
|
||||
if (ti.tileh != 0 ||
|
||||
(PathFinderInfo->rail_or_road && IS_TILETYPE(tile + _tiles_around[dir], MP_STREET)) ||
|
||||
(!PathFinderInfo->rail_or_road && IS_TILETYPE(tile + _tiles_around[dir], MP_RAILWAY))) {
|
||||
|
||||
for (;;) {
|
||||
new_tile += _tiles_around[dir];
|
||||
|
||||
// Precheck, is the length allowed?
|
||||
if (!CheckBridge_Stuff(0,GetBridgeLength(tile, new_tile))) break;
|
||||
|
||||
// Check if we hit the station-tile.. we don't like that!
|
||||
if (TILES_BETWEEN(new_tile,PathFinderInfo->end_tile_tl,PathFinderInfo->end_tile_br)) break;
|
||||
|
||||
// Try building the bridge..
|
||||
r = DoCommandByTile(tile, new_tile, (0<<8) + (MAX_BRIDGES / 2), DC_AUTO, CMD_BUILD_BRIDGE);
|
||||
if (r == CMD_ERROR) continue;
|
||||
// We can build a bridge here.. add him to the neighbours
|
||||
aystar->neighbours[aystar->num_neighbours].tile = new_tile;
|
||||
aystar->neighbours[aystar->num_neighbours].user_data[0] = AI_PATHFINDER_FLAG_BRIDGE + (dir << 8);
|
||||
aystar->neighbours[aystar->num_neighbours++].direction = 0;
|
||||
// We can only have 12 neighbours, and we need 1 left for tunnels
|
||||
if (aystar->num_neighbours == 11) break;
|
||||
}
|
||||
}
|
||||
|
||||
// Next, check for tunnels!
|
||||
// Tunnels can only be build with tileh of 3, 6, 9 or 12, depending on the direction
|
||||
// For now, we check both sides for this tile.. terraforming gives fuzzy result
|
||||
if ((dir == 0 && ti.tileh == 12) ||
|
||||
(dir == 1 && ti.tileh == 6) ||
|
||||
(dir == 2 && ti.tileh == 3) ||
|
||||
(dir == 3 && ti.tileh == 9)) {
|
||||
// Now simply check if a tunnel can be build
|
||||
r = DoCommandByTile(tile, (PathFinderInfo->rail_or_road?0:0x200), 0, DC_AUTO, CMD_BUILD_TUNNEL);
|
||||
FindLandscapeHeightByTile(&ti, _build_tunnel_endtile);
|
||||
if (r != CMD_ERROR && (ti.tileh == 3 || ti.tileh == 6 || ti.tileh == 9 || ti.tileh == 12)) {
|
||||
aystar->neighbours[aystar->num_neighbours].tile = _build_tunnel_endtile;
|
||||
aystar->neighbours[aystar->num_neighbours].user_data[0] = AI_PATHFINDER_FLAG_TUNNEL + (dir << 8);
|
||||
aystar->neighbours[aystar->num_neighbours++].direction = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extern uint GetRailFoundation(uint tileh, uint bits);
|
||||
extern uint GetRoadFoundation(uint tileh, uint bits);
|
||||
extern uint GetBridgeFoundation(uint tileh, byte direction);
|
||||
enum {
|
||||
BRIDGE_NO_FOUNDATION = 1 << 0 | 1 << 3 | 1 << 6 | 1 << 9 | 1 << 12,
|
||||
};
|
||||
|
||||
// The most important function: it calculates the g-value
|
||||
static int32 AyStar_AiPathFinder_CalculateG(AyStar *aystar, AyStarNode *current, OpenListNode *parent) {
|
||||
Ai_PathFinderInfo *PathFinderInfo = (Ai_PathFinderInfo*)aystar->user_target;
|
||||
int r, res = 0;
|
||||
TileInfo ti, parent_ti;
|
||||
|
||||
// Gather some information about the tile..
|
||||
FindLandscapeHeightByTile(&ti, current->tile);
|
||||
FindLandscapeHeightByTile(&parent_ti, parent->path.node.tile);
|
||||
|
||||
// Check if we hit the end-tile
|
||||
if (TILES_BETWEEN(current->tile,PathFinderInfo->end_tile_tl,PathFinderInfo->end_tile_br)) {
|
||||
// We are at the end-tile, check if we had a direction or something...
|
||||
if (PathFinderInfo->end_direction != AI_PATHFINDER_NO_DIRECTION && AiNew_GetDirection(current->tile, parent->path.node.tile) != PathFinderInfo->end_direction)
|
||||
// We are not pointing the right way, invalid tile
|
||||
return AYSTAR_INVALID_NODE;
|
||||
// If it was valid, drop out.. we don't build on the endtile
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Give everything a small penalty
|
||||
res += AI_PATHFINDER_PENALTY;
|
||||
|
||||
if (!PathFinderInfo->rail_or_road) {
|
||||
// Road has the lovely advantage it can use other road... check if
|
||||
// the current tile is road, and if so, give a good bonus
|
||||
if (AI_PATHFINDER_IS_ROAD(current->tile)) {
|
||||
res -= AI_PATHFINDER_ROAD_ALREADY_EXISTS_BONUS;
|
||||
}
|
||||
}
|
||||
|
||||
// We should give a penalty when the tile is going up or down.. this is one way to do so!
|
||||
// Too bad we have to count it from the parent.. but that is not so bad
|
||||
if (parent_ti.tileh != 0 && parent->path.parent != NULL) {
|
||||
// Skip if the tile was from a bridge or tunnel
|
||||
if (parent->path.node.user_data[0] == 0 && current->user_data[0] == 0) {
|
||||
if (PathFinderInfo->rail_or_road) {
|
||||
r = GetRailFoundation(parent_ti.tileh, 1 << AiNew_GetRailDirection(parent->path.parent->node.tile, parent->path.node.tile, current->tile));
|
||||
// Maybe is BRIDGE_NO_FOUNDATION a bit strange here, but it contains just the right information..
|
||||
if (r >= 15 || (r == 0 && (BRIDGE_NO_FOUNDATION & (1 << ti.tileh)))) {
|
||||
res += AI_PATHFINDER_TILE_GOES_UP_PENALTY;
|
||||
}
|
||||
} else {
|
||||
if (!(AI_PATHFINDER_IS_ROAD(parent->path.node.tile) && IS_TILETYPE(parent->path.node.tile, MP_TUNNELBRIDGE))) {
|
||||
r = GetRoadFoundation(parent_ti.tileh, AiNew_GetRoadDirection(parent->path.parent->node.tile, parent->path.node.tile, current->tile));
|
||||
if (r >= 15 || r == 0)
|
||||
res += AI_PATHFINDER_TILE_GOES_UP_PENALTY;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Are we part of a tunnel?
|
||||
if ((AI_PATHFINDER_FLAG_TUNNEL & current->user_data[0]) != 0) {
|
||||
// Tunnels are very expensive when build on long routes..
|
||||
// Ironicly, we are using BridgeCode here ;)
|
||||
r = AI_PATHFINDER_TUNNEL_PENALTY * GetBridgeLength(current->tile, parent->path.node.tile);
|
||||
res += r + (r >> 8);
|
||||
}
|
||||
|
||||
// Are we part of a bridge?
|
||||
if ((AI_PATHFINDER_FLAG_BRIDGE & current->user_data[0]) != 0) {
|
||||
// That means for every length a penalty
|
||||
res += AI_PATHFINDER_BRIDGE_PENALTY * GetBridgeLength(current->tile, parent->path.node.tile);
|
||||
// Check if we are going up or down, first for the starting point
|
||||
// In user_data[0] is at the 8th bit the direction
|
||||
if (!(BRIDGE_NO_FOUNDATION & (1 << parent_ti.tileh))) {
|
||||
if (GetBridgeFoundation(parent_ti.tileh, (current->user_data[0] >> 8) & 1) < 15)
|
||||
res += AI_PATHFINDER_BRIDGE_GOES_UP_PENALTY;
|
||||
}
|
||||
// Second for the end point
|
||||
if (!(BRIDGE_NO_FOUNDATION & (1 << ti.tileh))) {
|
||||
if (GetBridgeFoundation(ti.tileh, (current->user_data[0] >> 8) & 1) < 15)
|
||||
res += AI_PATHFINDER_BRIDGE_GOES_UP_PENALTY;
|
||||
}
|
||||
if (parent_ti.tileh == 0)
|
||||
res += AI_PATHFINDER_BRIDGE_GOES_UP_PENALTY;
|
||||
if (ti.tileh == 0)
|
||||
res += AI_PATHFINDER_BRIDGE_GOES_UP_PENALTY;
|
||||
}
|
||||
|
||||
// To prevent the AI from taking the fastest way in tiles, but not the fastest way
|
||||
// in speed, we have to give a good penalty to direction changing
|
||||
// This way, we get almost the fastest way in tiles, and a very good speed on the track
|
||||
if (!PathFinderInfo->rail_or_road) {
|
||||
if (parent->path.parent != NULL &&
|
||||
AiNew_GetDirection(current->tile, parent->path.node.tile) != AiNew_GetDirection(parent->path.node.tile, parent->path.parent->node.tile)) {
|
||||
// When road exists, we don't like turning, but its free, so don't be to piggy about it
|
||||
if (AI_PATHFINDER_IS_ROAD(parent->path.node.tile))
|
||||
res += AI_PATHFINDER_DIRECTION_CHANGE_ON_EXISTING_ROAD_PENALTY;
|
||||
else
|
||||
res += AI_PATHFINDER_DIRECTION_CHANGE_PENALTY;
|
||||
}
|
||||
} else {
|
||||
// For rail we have 1 exeption: diagonal rail..
|
||||
// So we fetch 2 raildirection. That of the current one, and of the one before that
|
||||
if (parent->path.parent != NULL && parent->path.parent->parent != NULL) {
|
||||
int dir1 = AiNew_GetRailDirection(parent->path.parent->node.tile, parent->path.node.tile, current->tile);
|
||||
int dir2 = AiNew_GetRailDirection(parent->path.parent->parent->node.tile, parent->path.parent->node.tile, parent->path.node.tile);
|
||||
// First, see if we are on diagonal path, that is better then straight path
|
||||
if (dir1 > 1) { res -= AI_PATHFINDER_DIAGONAL_BONUS; }
|
||||
|
||||
// First see if they are different
|
||||
if (dir1 != dir2) {
|
||||
// dir 2 and 3 are 1 diagonal track, and 4 and 5.
|
||||
if (!(((dir1 == 2 || dir1 == 3) && (dir2 == 2 || dir2 == 3)) || ((dir1 == 4 || dir1 == 5) && (dir2 == 4 || dir2 == 5)))) {
|
||||
// It is not, so we changed of direction
|
||||
res += AI_PATHFINDER_DIRECTION_CHANGE_PENALTY;
|
||||
}
|
||||
if (parent->path.parent->parent->parent != NULL) {
|
||||
int dir3 = AiNew_GetRailDirection(parent->path.parent->parent->parent->node.tile, parent->path.parent->parent->node.tile, parent->path.parent->node.tile);
|
||||
// Check if we changed 3 tiles of direction in 3 tiles.. bad!!!
|
||||
if ((dir1 == 0 || dir1 == 1) && dir2 > 1 && (dir3 == 0 || dir3 == 1)) {
|
||||
res += AI_PATHFINDER_CURVE_PENALTY;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Res should never be below zero.. if so, make it zero!
|
||||
if (res < 0) { res = 0; }
|
||||
|
||||
// Return our value
|
||||
return res;
|
||||
}
|
|
@ -1,117 +0,0 @@
|
|||
#include "stdafx.h"
|
||||
#include "ttd.h"
|
||||
#include "ai.h"
|
||||
#include "vehicle.h"
|
||||
|
||||
int AiNew_GetRailDirection(uint tile_a, uint tile_b, uint tile_c) {
|
||||
// 0 = vert
|
||||
// 1 = horz
|
||||
// 2 = dig up-left
|
||||
// 3 = dig down-right
|
||||
// 4 = dig down-left
|
||||
// 5 = dig up-right
|
||||
|
||||
int x1, x2, x3;
|
||||
int y1, y2, y3;
|
||||
|
||||
x1 = GET_TILE_X(tile_a);
|
||||
x2 = GET_TILE_X(tile_b);
|
||||
x3 = GET_TILE_X(tile_c);
|
||||
|
||||
y1 = GET_TILE_Y(tile_a);
|
||||
y2 = GET_TILE_Y(tile_b);
|
||||
y3 = GET_TILE_Y(tile_c);
|
||||
|
||||
if (y1 == y2 && y2 == y3) return 0;
|
||||
if (x1 == x2 && x2 == x3) return 1;
|
||||
if (y2 > y1) {
|
||||
if (x2 > x3) return 2;
|
||||
else return 4;
|
||||
}
|
||||
if (x2 > x1) {
|
||||
if (y2 > y3) return 2;
|
||||
else return 5;
|
||||
}
|
||||
if (y1 > y2) {
|
||||
if (x2 > x3) return 5;
|
||||
else return 3;
|
||||
}
|
||||
if (x1 > x2) {
|
||||
if (y2 > y3) return 4;
|
||||
else return 3;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int AiNew_GetRoadDirection(uint tile_a, uint tile_b, uint tile_c) {
|
||||
int x1, x2, x3;
|
||||
int y1, y2, y3;
|
||||
int r;
|
||||
|
||||
x1 = GET_TILE_X(tile_a);
|
||||
x2 = GET_TILE_X(tile_b);
|
||||
x3 = GET_TILE_X(tile_c);
|
||||
|
||||
y1 = GET_TILE_Y(tile_a);
|
||||
y2 = GET_TILE_Y(tile_b);
|
||||
y3 = GET_TILE_Y(tile_c);
|
||||
|
||||
r = 0;
|
||||
|
||||
if (x1 < x2) r += 8;
|
||||
if (y1 < y2) r += 1;
|
||||
if (x1 > x2) r += 2;
|
||||
if (y1 > y2) r += 4;
|
||||
|
||||
if (x2 < x3) r += 2;
|
||||
if (y2 < y3) r += 4;
|
||||
if (x2 > x3) r += 8;
|
||||
if (y2 > y3) r += 1;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
// Get's the direction between 2 tiles seen from tile_a
|
||||
int AiNew_GetDirection(uint tile_a, uint tile_b) {
|
||||
if (GET_TILE_Y(tile_a) < GET_TILE_Y(tile_b)) return 1;
|
||||
if (GET_TILE_Y(tile_a) > GET_TILE_Y(tile_b)) return 3;
|
||||
if (GET_TILE_X(tile_a) < GET_TILE_X(tile_b)) return 2;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// This functions looks up if this vehicle is special for this AI
|
||||
// and returns his flag
|
||||
uint AiNew_GetSpecialVehicleFlag(Player *p, Vehicle *v) {
|
||||
int i;
|
||||
for (i=0;i<AI_MAX_SPECIAL_VEHICLES;i++) {
|
||||
if (p->ainew.special_vehicles[i].veh_id == v->index) {
|
||||
return p->ainew.special_vehicles[i].flag;
|
||||
}
|
||||
}
|
||||
|
||||
// Not found :(
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool AiNew_SetSpecialVehicleFlag(Player *p, Vehicle *v, uint flag) {
|
||||
int i, new_id = -1;
|
||||
for (i=0;i<AI_MAX_SPECIAL_VEHICLES;i++) {
|
||||
if (p->ainew.special_vehicles[i].veh_id == v->index) {
|
||||
p->ainew.special_vehicles[i].flag |= flag;
|
||||
return true;
|
||||
}
|
||||
if (new_id == -1 && p->ainew.special_vehicles[i].veh_id == 0 &&
|
||||
p->ainew.special_vehicles[i].flag == 0)
|
||||
new_id = i;
|
||||
}
|
||||
|
||||
// Out of special_vehicle spots :s
|
||||
if (new_id == -1) {
|
||||
DEBUG(ai, 1)("special_vehicles list is too small :(");
|
||||
return false;
|
||||
}
|
||||
p->ainew.special_vehicles[new_id].veh_id = v->index;
|
||||
p->ainew.special_vehicles[new_id].flag = flag;
|
||||
return true;
|
||||
}
|
1898
trunk/aircraft_cmd.c
1898
trunk/aircraft_cmd.c
File diff suppressed because it is too large
Load Diff
1145
trunk/aircraft_gui.c
1145
trunk/aircraft_gui.c
File diff suppressed because it is too large
Load Diff
282
trunk/airport.c
282
trunk/airport.c
|
@ -1,282 +0,0 @@
|
|||
#include "stdafx.h"
|
||||
#include "ttd.h"
|
||||
#include "airport.h"
|
||||
|
||||
AirportFTAClass *CountryAirport;
|
||||
AirportFTAClass *CityAirport;
|
||||
AirportFTAClass *Heliport, *Oilrig;
|
||||
AirportFTAClass *MetropolitanAirport;
|
||||
AirportFTAClass *InternationalAirport;
|
||||
|
||||
static void AirportFTAClass_Constructor(AirportFTAClass *Airport,
|
||||
const byte nofterminals, const byte nofterminalgroups,
|
||||
const byte nofhelipads, const byte nofhelipadgroups,
|
||||
const byte entry_point, const byte acc_planes,
|
||||
const AirportFTAbuildup *FA,
|
||||
const TileIndex *depots);
|
||||
static void AirportFTAClass_Destructor(AirportFTAClass *Airport);
|
||||
|
||||
static uint16 AirportGetNofElements(const AirportFTAbuildup *FA);
|
||||
static void AirportBuildAutomata(AirportFTAClass *Airport, const AirportFTAbuildup *FA);
|
||||
static byte AirportTestFTA(const AirportFTAClass *Airport);
|
||||
/*static void AirportPrintOut(const AirportFTAClass *Airport, const bool full_report);
|
||||
static byte AirportBlockToString(uint32 block);*/
|
||||
|
||||
void InitializeAirports()
|
||||
{
|
||||
// country airport
|
||||
CountryAirport = (AirportFTAClass *)malloc(sizeof(AirportFTAClass));
|
||||
AirportFTAClass_Constructor(CountryAirport, 2, 1, 0, 0, 16, ALL, _airport_fta_country, _airport_depots_country);
|
||||
|
||||
// city airport
|
||||
CityAirport = (AirportFTAClass *)malloc(sizeof(AirportFTAClass));
|
||||
AirportFTAClass_Constructor(CityAirport, 3, 1, 0, 0, 19, ALL, _airport_fta_city, _airport_depots_city);
|
||||
|
||||
// metropolitan airport
|
||||
MetropolitanAirport = (AirportFTAClass *)malloc(sizeof(AirportFTAClass));
|
||||
AirportFTAClass_Constructor(MetropolitanAirport, 3, 1, 0, 0, 20, ALL, _airport_fta_metropolitan, _airport_depots_metropolitan);
|
||||
|
||||
// international airport
|
||||
InternationalAirport = (AirportFTAClass *)malloc(sizeof(AirportFTAClass));
|
||||
AirportFTAClass_Constructor(InternationalAirport, 6, 2, 2, 1, 37, ALL, _airport_fta_international, _airport_depots_international);
|
||||
|
||||
// heliport, oilrig
|
||||
Heliport = (AirportFTAClass *)malloc(sizeof(AirportFTAClass));
|
||||
AirportFTAClass_Constructor(Heliport, 0, 0, 1, 1, 7, HELICOPTERS_ONLY, _airport_fta_heliport_oilrig, _airport_depots_heliport_oilrig);
|
||||
Oilrig = Heliport; // exactly the same structure for heliport/oilrig, so share state machine
|
||||
}
|
||||
|
||||
void UnInitializeAirports()
|
||||
{
|
||||
AirportFTAClass_Destructor(CountryAirport);
|
||||
AirportFTAClass_Destructor(CityAirport);
|
||||
AirportFTAClass_Destructor(Heliport);
|
||||
AirportFTAClass_Destructor(MetropolitanAirport);
|
||||
AirportFTAClass_Destructor(InternationalAirport);
|
||||
}
|
||||
|
||||
static void AirportFTAClass_Constructor(AirportFTAClass *Airport,
|
||||
const byte nofterminals, const byte nofterminalgroups,
|
||||
const byte nofhelipads, const byte nofhelipadgroups,
|
||||
const byte entry_point, const byte acc_planes,
|
||||
const AirportFTAbuildup *FA,
|
||||
const TileIndex *depots)
|
||||
{
|
||||
// if there are more terminals than 6, internal variables have to be changed, so don't allow that
|
||||
// same goes for helipads
|
||||
if (nofterminals > MAX_TERMINALS) { printf("Currently only maximum of %2d terminals are supported (you wanted %2d)\n", MAX_TERMINALS, nofterminals);}
|
||||
if (nofhelipads > MAX_HELIPADS) { printf("Currently only maximum of %2d helipads are supported (you wanted %2d)\n", MAX_HELIPADS, nofhelipads);}
|
||||
// terminals/helipads are divided into groups. Groups are computed by dividing the number
|
||||
// of terminals by the number of groups. Half in half. If #terminals is uneven, first group
|
||||
// will get the less # of terminals
|
||||
if (nofterminalgroups > nofterminals) { printf("# of terminalgroups (%2d) must be less or equal to terminals (%2d)", nofterminals, nofterminalgroups);}
|
||||
if (nofhelipadgroups > nofhelipads) { printf("# of helipadgroups (%2d) must be less or equal to helipads (%2d)", nofhelipads, nofhelipadgroups);}
|
||||
|
||||
assert(nofterminals <= MAX_TERMINALS);
|
||||
assert(nofhelipads <= MAX_HELIPADS);
|
||||
assert(nofterminalgroups <= nofterminals);
|
||||
assert(nofhelipadgroups <= nofhelipads);
|
||||
|
||||
Airport->nofelements = AirportGetNofElements(FA);
|
||||
// check
|
||||
if (entry_point >= Airport->nofelements) {printf("Entry point (%2d) must be within the airport positions (which is max %2d)\n", entry_point, Airport->nofelements);}
|
||||
assert(entry_point < Airport->nofelements);
|
||||
|
||||
Airport->nofterminals = nofterminals;
|
||||
Airport->nofterminalgroups = nofterminalgroups;
|
||||
Airport->nofhelipads = nofhelipads;
|
||||
Airport->nofhelipadgroups = nofhelipadgroups;
|
||||
Airport->acc_planes = acc_planes;
|
||||
Airport->entry_point = entry_point;
|
||||
Airport->airport_depots = (const uint16*)depots;
|
||||
|
||||
|
||||
// build the state machine
|
||||
AirportBuildAutomata(Airport, FA);
|
||||
DEBUG(misc, 1) ("#Elements %2d; #Terminals %2d in %d group(s); #Helipads %2d in %d group(s)", Airport->nofelements,
|
||||
Airport->nofterminals, Airport->nofterminalgroups, Airport->nofhelipads, Airport->nofhelipadgroups);
|
||||
|
||||
|
||||
{
|
||||
byte _retval = AirportTestFTA(Airport);
|
||||
if (_retval != MAX_ELEMENTS) {printf("ERROR with element: %d\n", _retval-1);}
|
||||
assert(_retval == MAX_ELEMENTS);
|
||||
}
|
||||
// print out full information
|
||||
// true -- full info including heading, block, etc
|
||||
// false -- short info, only position and next position
|
||||
//AirportPrintOut(Airport, false);
|
||||
}
|
||||
|
||||
static void AirportFTAClass_Destructor(AirportFTAClass *Airport)
|
||||
{
|
||||
int i;
|
||||
AirportFTA *current, *next;
|
||||
|
||||
for (i = 0; i < Airport->nofelements; i++) {
|
||||
current = Airport->layout[i].next_in_chain;
|
||||
while (current != NULL) {
|
||||
next = current->next_in_chain;
|
||||
free(current);
|
||||
current = next;
|
||||
};
|
||||
}
|
||||
free(Airport->layout);
|
||||
free(Airport);
|
||||
}
|
||||
|
||||
static uint16 AirportGetNofElements(const AirportFTAbuildup *FA)
|
||||
{
|
||||
int i;
|
||||
uint16 nofelements = 0;
|
||||
int temp = FA[0].position;
|
||||
for (i = 0; i < MAX_ELEMENTS; i++) {
|
||||
if (temp != FA[i].position) {
|
||||
nofelements++;
|
||||
temp = FA[i].position;
|
||||
}
|
||||
if (FA[i].position == MAX_ELEMENTS) {break;}
|
||||
}
|
||||
return nofelements;
|
||||
}
|
||||
|
||||
static void AirportBuildAutomata(AirportFTAClass *Airport, const AirportFTAbuildup *FA)
|
||||
{
|
||||
AirportFTA *FAutomata;
|
||||
AirportFTA *current;
|
||||
uint16 internalcounter, i;
|
||||
FAutomata = (AirportFTA *)malloc(sizeof(AirportFTA) * Airport->nofelements);
|
||||
Airport->layout = FAutomata;
|
||||
internalcounter = 0;
|
||||
|
||||
for (i = 0; i < Airport->nofelements; i++) {
|
||||
current = &Airport->layout[i];
|
||||
current->position = FA[internalcounter].position;
|
||||
current->heading = FA[internalcounter].heading;
|
||||
current->block = FA[internalcounter].block;
|
||||
current->next_position = FA[internalcounter].next_in_chain;
|
||||
|
||||
// outgoing nodes from the same position, create linked list
|
||||
while (current->position == FA[internalcounter+1].position) {
|
||||
AirportFTA *newNode = (AirportFTA *)malloc(sizeof(AirportFTA));
|
||||
newNode->position = FA[internalcounter+1].position;
|
||||
newNode->heading = FA[internalcounter+1].heading;
|
||||
newNode->block = FA[internalcounter+1].block;
|
||||
newNode->next_position = FA[internalcounter+1].next_in_chain;
|
||||
// create link
|
||||
current->next_in_chain = newNode;
|
||||
current = current->next_in_chain;
|
||||
internalcounter++;
|
||||
} // while
|
||||
current->next_in_chain = NULL;
|
||||
internalcounter++;
|
||||
}
|
||||
}
|
||||
|
||||
static byte AirportTestFTA(const AirportFTAClass *Airport)
|
||||
{
|
||||
byte position, i, next_element;
|
||||
AirportFTA *temp;
|
||||
next_element = 0;
|
||||
|
||||
for (i = 0; i < Airport->nofelements; i++) {
|
||||
position = Airport->layout[i].position;
|
||||
if (position != next_element) {return i;}
|
||||
temp = &Airport->layout[i];
|
||||
|
||||
do {
|
||||
if (temp->heading > MAX_HEADINGS && temp->heading != 255) {return i;}
|
||||
if (temp->heading == 0 && temp->next_in_chain != 0) {return i;}
|
||||
if (position != temp->position) {return i;}
|
||||
if (temp->next_position >= Airport->nofelements) {return i;}
|
||||
temp = temp->next_in_chain;
|
||||
} while (temp != NULL);
|
||||
next_element++;
|
||||
}
|
||||
return MAX_ELEMENTS;
|
||||
}
|
||||
|
||||
static const char* const _airport_heading_strings[MAX_HEADINGS+2] = {
|
||||
"TO_ALL",
|
||||
"HANGAR",
|
||||
"TERM1",
|
||||
"TERM2",
|
||||
"TERM3",
|
||||
"TERM4",
|
||||
"TERM5",
|
||||
"TERM6",
|
||||
"HELIPAD1",
|
||||
"HELIPAD2",
|
||||
"TAKEOFF",
|
||||
"STARTTAKEOFF",
|
||||
"ENDTAKEOFF",
|
||||
"HELITAKEOFF",
|
||||
"FLYING",
|
||||
"LANDING",
|
||||
"ENDLANDING",
|
||||
"HELILANDING",
|
||||
"HELIENDLANDING",
|
||||
"DUMMY" // extra heading for 255
|
||||
};
|
||||
|
||||
/*
|
||||
static void AirportPrintOut(const AirportFTAClass *Airport, const bool full_report)
|
||||
{
|
||||
AirportFTA *temp;
|
||||
uint16 i;
|
||||
byte heading;
|
||||
|
||||
printf("(P = Current Position; NP = Next Position)\n");
|
||||
for (i = 0; i < Airport->nofelements; i++) {
|
||||
temp = &Airport->layout[i];
|
||||
if (full_report) {
|
||||
heading = (temp->heading == 255) ? MAX_HEADINGS+1 : temp->heading;
|
||||
printf("Pos:%2d NPos:%2d Heading:%15s Block:%2d\n", temp->position, temp->next_position,
|
||||
_airport_heading_strings[heading], AirportBlockToString(temp->block));
|
||||
}
|
||||
else { printf("P:%2d NP:%2d", temp->position, temp->next_position);}
|
||||
while (temp->next_in_chain != NULL) {
|
||||
temp = temp->next_in_chain;
|
||||
if (full_report) {
|
||||
heading = (temp->heading == 255) ? MAX_HEADINGS+1 : temp->heading;
|
||||
printf("Pos:%2d NPos:%2d Heading:%15s Block:%2d\n", temp->position, temp->next_position,
|
||||
_airport_heading_strings[heading], AirportBlockToString(temp->block));
|
||||
}
|
||||
else { printf("P:%2d NP:%2d", temp->position, temp->next_position);}
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static byte AirportBlockToString(uint32 block)
|
||||
{
|
||||
byte i = 0;
|
||||
if (block & 0xffff0000) { block >>= 16; i += 16; }
|
||||
if (block & 0x0000ff00) { block >>= 8; i += 8; }
|
||||
if (block & 0x000000f0) { block >>= 4; i += 4; }
|
||||
if (block & 0x0000000c) { block >>= 2; i += 2; }
|
||||
if (block & 0x00000002) { i += 1; }
|
||||
return i;
|
||||
}*/
|
||||
|
||||
const AirportFTAClass* GetAirport(const byte airport_type)
|
||||
{
|
||||
AirportFTAClass *Airport = NULL;
|
||||
//FIXME -- AircraftNextAirportPos_and_Order -> Needs something nicer, don't like this code
|
||||
// needs constant change if more airports are added
|
||||
switch (airport_type) {
|
||||
case AT_SMALL: Airport = CountryAirport; break;
|
||||
case AT_LARGE: Airport = CityAirport; break;
|
||||
case AT_METROPOLITAN: Airport = MetropolitanAirport; break;
|
||||
case AT_HELIPORT: Airport = Heliport; break;
|
||||
case AT_OILRIG: Airport = Oilrig; break;
|
||||
case AT_INTERNATIONAL: Airport = InternationalAirport; break;
|
||||
default:
|
||||
#ifdef DEBUG__
|
||||
printf("Airport AircraftNextAirportPos_and_Order not yet implemented\n");
|
||||
#endif
|
||||
assert(airport_type <= AT_INTERNATIONAL);
|
||||
}
|
||||
return Airport;
|
||||
}
|
|
@ -1,52 +0,0 @@
|
|||
#ifndef AIRPORT_H
|
||||
#define AIRPORT_H
|
||||
|
||||
#include "airport_movement.h"
|
||||
|
||||
enum {MAX_TERMINALS = 6};
|
||||
enum {MAX_HELIPADS = 2};
|
||||
|
||||
// Airport types
|
||||
enum {
|
||||
AT_SMALL = 0,
|
||||
AT_LARGE = 1,
|
||||
AT_HELIPORT = 2,
|
||||
AT_METROPOLITAN = 3,
|
||||
AT_INTERNATIONAL = 4,
|
||||
AT_OILRIG = 5
|
||||
};
|
||||
|
||||
// do not change unless you change v->subtype too. This aligns perfectly with its current setting
|
||||
enum {
|
||||
AIRCRAFT_ONLY = 0,
|
||||
ALL = 1,
|
||||
HELICOPTERS_ONLY = 2
|
||||
};
|
||||
|
||||
// Finite sTate mAchine --> FTA
|
||||
typedef struct AirportFTAClass {
|
||||
byte nofelements; // number of positions the airport consists of
|
||||
byte nofterminals; // number of terminals this airport has
|
||||
byte nofterminalgroups; // terminals belong to so many groups (MAX is the nofterminals)
|
||||
byte nofhelipads; // number of helipads this airport has
|
||||
byte nofhelipadgroups; // helipads belong to so many groups (MAX is the nofhelipads)
|
||||
byte entry_point; // when an airplane arrives at this airport, enter it at position entry_point
|
||||
byte acc_planes; // accept airplanes or helicopters or both
|
||||
const uint16 *airport_depots; // gives the position of the depots on the airports
|
||||
struct AirportFTA *layout; // state machine for airport
|
||||
} AirportFTAClass;
|
||||
|
||||
// internal structure used in openttd - Finite sTate mAchine --> FTA
|
||||
typedef struct AirportFTA {
|
||||
byte position; // the position that an airplane is at
|
||||
byte next_position; // next position from this position
|
||||
uint32 block; // 32 bit blocks (st->airport_flags), should be enough for the most complex airports
|
||||
byte heading; // heading (current orders), guiding an airplane to its target on an airport
|
||||
struct AirportFTA *next_in_chain; // possible extra movement choices from this position
|
||||
} AirportFTA;
|
||||
|
||||
void InitializeAirports();
|
||||
void UnInitializeAirports();
|
||||
const AirportFTAClass* GetAirport(const byte airport_type);
|
||||
|
||||
#endif /* AIRPORT_H */
|
|
@ -1,227 +0,0 @@
|
|||
#include "stdafx.h"
|
||||
#include "ttd.h"
|
||||
|
||||
#include "window.h"
|
||||
#include "gui.h"
|
||||
#include "viewport.h"
|
||||
#include "gfx.h"
|
||||
#include "command.h"
|
||||
#include "vehicle.h"
|
||||
#include "station.h"
|
||||
#include "airport.h"
|
||||
|
||||
static byte _selected_airport_type;
|
||||
|
||||
static void ShowBuildAirportPicker();
|
||||
|
||||
|
||||
static void CcBuildAirport(bool success, uint tile, uint32 p1, uint32 p2)
|
||||
{
|
||||
if (success) {
|
||||
SndPlayTileFx(0x1D, tile);
|
||||
ResetObjectToPlace();
|
||||
}
|
||||
}
|
||||
|
||||
static void PlaceAirport(uint tile)
|
||||
{
|
||||
DoCommandP(tile, _selected_airport_type, 0, CcBuildAirport, CMD_BUILD_AIRPORT | CMD_AUTO | CMD_NO_WATER | CMD_MSG(STR_A001_CAN_T_BUILD_AIRPORT_HERE));
|
||||
}
|
||||
|
||||
static void PlaceAir_DemolishArea(uint tile)
|
||||
{
|
||||
VpStartPlaceSizing(tile, 4);
|
||||
}
|
||||
|
||||
|
||||
static void BuildAirClick_Airport(Window *w)
|
||||
{
|
||||
if (HandlePlacePushButton(w, 2, 0xAA4, 1, PlaceAirport)) ShowBuildAirportPicker();
|
||||
}
|
||||
|
||||
static void BuildAirClick_Demolish(Window *w)
|
||||
{
|
||||
HandlePlacePushButton(w, 3, ANIMCURSOR_DEMOLISH, 1, PlaceAir_DemolishArea);
|
||||
}
|
||||
|
||||
static void BuildAirClick_Lower(Window *w)
|
||||
{
|
||||
HandlePlacePushButton(w, 4, ANIMCURSOR_LOWERLAND, 2, PlaceProc_LowerLand);
|
||||
}
|
||||
|
||||
static void BuildAirClick_Raise(Window *w)
|
||||
{
|
||||
HandlePlacePushButton(w, 5, ANIMCURSOR_RAISELAND, 2, PlaceProc_RaiseLand);
|
||||
}
|
||||
|
||||
static void BuildAirClick_Purchase(Window *w)
|
||||
{
|
||||
HandlePlacePushButton(w, 6, 0x12B8, 1, PlaceProc_BuyLand);
|
||||
}
|
||||
|
||||
typedef void OnButtonClick(Window *w);
|
||||
static OnButtonClick * const _build_air_button_proc[] = {
|
||||
BuildAirClick_Airport,
|
||||
BuildAirClick_Demolish,
|
||||
BuildAirClick_Lower,
|
||||
BuildAirClick_Raise,
|
||||
BuildAirClick_Purchase,
|
||||
};
|
||||
|
||||
static void BuildAirToolbWndProc(Window *w, WindowEvent *e)
|
||||
{
|
||||
switch(e->event) {
|
||||
case WE_PAINT:
|
||||
DrawWindowWidgets(w);
|
||||
break;
|
||||
|
||||
case WE_CLICK:
|
||||
if (e->click.widget-2 >= 0)
|
||||
_build_air_button_proc[e->click.widget - 2](w);
|
||||
break;
|
||||
|
||||
case WE_PLACE_OBJ:
|
||||
_place_proc(e->place.tile);
|
||||
break;
|
||||
|
||||
case WE_PLACE_DRAG: {
|
||||
VpSelectTilesWithMethod(e->place.pt.x, e->place.pt.y, e->place.userdata);
|
||||
return;
|
||||
}
|
||||
|
||||
case WE_PLACE_MOUSEUP:
|
||||
if (e->place.pt.x != -1) {
|
||||
DoCommandP(e->place.tile, e->place.starttile, 0, CcPlaySound10, CMD_CLEAR_AREA | CMD_MSG(STR_00B5_CAN_T_CLEAR_THIS_AREA));
|
||||
}
|
||||
break;
|
||||
|
||||
case WE_ABORT_PLACE_OBJ:
|
||||
w->click_state = 0;
|
||||
SetWindowDirty(w);
|
||||
w = FindWindowById(WC_BUILD_STATION, 0);
|
||||
if (w != 0)
|
||||
WP(w,def_d).close = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static const Widget _air_toolbar_widgets[] = {
|
||||
{ WWT_CLOSEBOX, 7, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
|
||||
{ WWT_CAPTION, 7, 11, 129, 0, 13, STR_A000_AIRPORT_CONSTRUCT, STR_018C_WINDOW_TITLE_DRAG_THIS},
|
||||
{ WWT_PANEL, 7, 0, 41, 14, 35, 0x2E8, STR_A01E_BUILD_AIRPORT},
|
||||
{ WWT_PANEL, 7, 42, 63, 14, 35, 0x2BF, STR_018D_DEMOLISH_BUILDINGS_ETC},
|
||||
{ WWT_PANEL, 7, 64, 85, 14, 35, 0x2B7, STR_018E_LOWER_A_CORNER_OF_LAND},
|
||||
{ WWT_PANEL, 7, 86, 107, 14, 35, 0x2B6, STR_018F_RAISE_A_CORNER_OF_LAND},
|
||||
{ WWT_PANEL, 7, 108, 129, 14, 35, 0x12B7, STR_0329_PURCHASE_LAND_FOR_FUTURE},
|
||||
{ WIDGETS_END},
|
||||
};
|
||||
|
||||
|
||||
static const WindowDesc _air_toolbar_desc = {
|
||||
510, 22, 130, 36,
|
||||
WC_BUILD_TOOLBAR,0,
|
||||
WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET,
|
||||
_air_toolbar_widgets,
|
||||
BuildAirToolbWndProc
|
||||
};
|
||||
|
||||
void ShowBuildAirToolbar()
|
||||
{
|
||||
DeleteWindowById(WC_BUILD_TOOLBAR, 0);
|
||||
AllocateWindowDescFront(&_air_toolbar_desc, 0);
|
||||
}
|
||||
|
||||
static void BuildAirportPickerWndProc(Window *w, WindowEvent *e)
|
||||
{
|
||||
switch(e->event) {
|
||||
case WE_PAINT: {
|
||||
int sel;
|
||||
|
||||
if (WP(w,def_d).close)
|
||||
return;
|
||||
w->disabled_state = 0;
|
||||
|
||||
sel = _selected_airport_type;
|
||||
// FIXME -- BuildAirportPickerWndProc - set availability of airports by year, instead of airplane
|
||||
if (!(_avail_aircraft & 1)) { w->disabled_state |= (1<<3); if (sel == AT_SMALL) sel = AT_LARGE; }
|
||||
if (!(_avail_aircraft & 2)) { w->disabled_state |= (1<<4); if (sel == AT_LARGE) sel = AT_SMALL; }
|
||||
if (!(_avail_aircraft & 4)) { w->disabled_state |= (1<<5); } // heliport
|
||||
// 1980-1-1 is --> 21915
|
||||
// 1990-1-1 is --> 25568
|
||||
if (_date < 21915) {w->disabled_state |= (1<<6);} // metropilitan airport 1980
|
||||
if (_date < 25568) {w->disabled_state |= (1<<7);} // international airport 1990
|
||||
_selected_airport_type = sel;
|
||||
// select default the coverage area to 'Off' (8)
|
||||
w->click_state = ((1<<3) << sel) | ((1<<8) << _station_show_coverage);
|
||||
SetTileSelectSize(_airport_size_x[sel],_airport_size_y[sel]);
|
||||
if (_station_show_coverage) SetTileSelectBigSize(-4, -4, 8, 8);
|
||||
|
||||
DrawWindowWidgets(w);
|
||||
// strings such as 'Size' and 'Coverage Area'
|
||||
DrawStringCentered(74, 16, STR_305B_SIZE, 0);
|
||||
DrawStringCentered(74, 78, STR_3066_COVERAGE_AREA_HIGHLIGHT, 0);
|
||||
DrawStationCoverageAreaText(2, 104, (uint)-1);
|
||||
break;
|
||||
}
|
||||
|
||||
case WE_CLICK: {
|
||||
switch(e->click.widget) {
|
||||
case 0:
|
||||
ResetObjectToPlace();
|
||||
break;
|
||||
case 3: case 4: case 5: case 6: case 7:
|
||||
_selected_airport_type = e->click.widget - 3;
|
||||
SndPlayFx(0x13);
|
||||
SetWindowDirty(w);
|
||||
break;
|
||||
case 8: case 9:
|
||||
_station_show_coverage = e->click.widget - 8;
|
||||
SndPlayFx(0x13);
|
||||
SetWindowDirty(w);
|
||||
break;
|
||||
}
|
||||
} break;
|
||||
|
||||
case WE_MOUSELOOP: {
|
||||
if (WP(w,def_d).close) {
|
||||
DeleteWindow(w);
|
||||
return;
|
||||
}
|
||||
|
||||
CheckRedrawStationCoverage(w);
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
static const Widget _build_airport_picker_widgets[] = {
|
||||
{ WWT_CLOSEBOX, 7, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
|
||||
{ WWT_CAPTION, 7, 11, 147, 0, 13, STR_3001_AIRPORT_SELECTION, STR_018C_WINDOW_TITLE_DRAG_THIS},
|
||||
{ WWT_PANEL, 7, 0, 147, 14, 130, 0x0, STR_NULL},
|
||||
{WWT_NODISTXTBTN, 14, 2, 73, 27, 38, STR_3059_SMALL, STR_3058_SELECT_SIZE_TYPE_OF_AIRPORT},
|
||||
{WWT_NODISTXTBTN, 14, 74, 145, 27, 38, STR_305A_LARGE, STR_3058_SELECT_SIZE_TYPE_OF_AIRPORT},
|
||||
{WWT_NODISTXTBTN, 14, 2, 145, 63, 74, STR_306B_HELIPORT, STR_3058_SELECT_SIZE_TYPE_OF_AIRPORT},
|
||||
{WWT_NODISTXTBTN, 14, 2, 145, 39, 50, STR_305AA_LARGE, STR_3058_SELECT_SIZE_TYPE_OF_AIRPORT},
|
||||
{WWT_NODISTXTBTN, 14, 2, 145, 51, 62, STR_305AB_LARGE, STR_3058_SELECT_SIZE_TYPE_OF_AIRPORT},
|
||||
{ WWT_CLOSEBOX, 14, 14, 73, 88, 98, STR_02DB_OFF, STR_3065_DON_T_HIGHLIGHT_COVERAGE},
|
||||
{ WWT_CLOSEBOX, 14, 74, 133, 88, 98, STR_02DA_ON, STR_3064_HIGHLIGHT_COVERAGE_AREA},
|
||||
{ WIDGETS_END},
|
||||
};
|
||||
|
||||
static const WindowDesc _build_airport_desc = {
|
||||
-1, -1, 148, 131, // height, 130+1
|
||||
WC_BUILD_STATION,WC_BUILD_TOOLBAR,
|
||||
WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET,
|
||||
_build_airport_picker_widgets,
|
||||
BuildAirportPickerWndProc
|
||||
};
|
||||
|
||||
static void ShowBuildAirportPicker()
|
||||
{
|
||||
AllocateWindowDesc(&_build_airport_desc);
|
||||
}
|
||||
|
||||
void InitializeAirportGui()
|
||||
{
|
||||
_selected_airport_type = AT_SMALL;
|
||||
_last_built_aircraft_depot_tile = 0;
|
||||
}
|
|
@ -1,456 +0,0 @@
|
|||
#ifndef AIRPORT_MOVEMENT_H
|
||||
#define AIRPORT_MOVEMENT_H
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "macros.h"
|
||||
|
||||
// don't forget to change the airport_depots too for larger mapsizes. TILE_X_BITS 16
|
||||
// won't fit in uint16 for example and overflow will occur in the checking code!
|
||||
// TrueLight -- So make it a TileIndex..
|
||||
|
||||
typedef struct AirportMovingData {
|
||||
int x,y;
|
||||
byte flag;
|
||||
byte direction;
|
||||
} AirportMovingData;
|
||||
|
||||
// state machine input struct (from external file, etc.)
|
||||
// Finite sTate mAchine --> FTA
|
||||
typedef struct AirportFTAbuildup {
|
||||
byte position; // the position that an airplane is at
|
||||
byte heading; // the current orders (eg. TAKEOFF, HANGAR, ENDLANDING, etc.)
|
||||
uint32 block; // the block this position is on on the airport (st->airport_flags)
|
||||
byte next_in_chain; // next position from this position
|
||||
} AirportFTAbuildup;
|
||||
|
||||
enum {
|
||||
AMED_NOSPDCLAMP = 1<<0,
|
||||
AMED_TAKEOFF = 1<<1,
|
||||
AMED_SLOWTURN = 1<<2,
|
||||
AMED_LAND = 1<<3,
|
||||
AMED_EXACTPOS = 1<<4,
|
||||
AMED_BRAKE = 1<<5,
|
||||
AMED_HELI_RAISE = 1<<6,
|
||||
AMED_HELI_LOWER = 1<<7,
|
||||
};
|
||||
|
||||
enum {MAX_ELEMENTS = 255};
|
||||
enum {MAX_HEADINGS = 18};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
///////***********Movement States on Airports********************//////
|
||||
// headings target
|
||||
enum {
|
||||
TO_ALL = 0,
|
||||
HANGAR = 1,
|
||||
TERM1 = 2,
|
||||
TERM2 = 3,
|
||||
TERM3 = 4,
|
||||
TERM4 = 5,
|
||||
TERM5 = 6,
|
||||
TERM6 = 7,
|
||||
HELIPAD1 = 8,
|
||||
HELIPAD2 = 9,
|
||||
TAKEOFF = 10,
|
||||
STARTTAKEOFF = 11,
|
||||
ENDTAKEOFF = 12,
|
||||
HELITAKEOFF = 13,
|
||||
FLYING = 14,
|
||||
LANDING = 15,
|
||||
ENDLANDING = 16,
|
||||
HELILANDING = 17,
|
||||
HELIENDLANDING = 18
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
///////**********Movement Blocks on Airports*********************//////
|
||||
// blocks (eg_airport_flags)
|
||||
enum {
|
||||
TERM1_block = 1 << 0,
|
||||
TERM2_block = 1 << 1,
|
||||
TERM3_block = 1 << 2,
|
||||
TERM4_block = 1 << 3,
|
||||
TERM5_block = 1 << 4,
|
||||
TERM6_block = 1 << 5,
|
||||
HELIPAD1_block = 1 << 6,
|
||||
HELIPAD2_block = 1 << 7,
|
||||
RUNWAY_IN_OUT_block = 1 << 8,
|
||||
RUNWAY_IN_block = 1 << 8,
|
||||
AIRPORT_BUSY_block = 1 << 8,
|
||||
RUNWAY_OUT_block = 1 << 9,
|
||||
TAXIWAY_BUSY_block = 1 << 10,
|
||||
OUT_WAY_block = 1 << 11,
|
||||
IN_WAY_block = 1 << 12,
|
||||
AIRPORT_ENTRANCE_block = 1 << 13,
|
||||
TERM_GROUP1_block = 1 << 14,
|
||||
TERM_GROUP2_block = 1 << 15,
|
||||
HANGAR2_AREA_block = 1 << 16,
|
||||
TERM_GROUP2_ENTER1_block = 1 << 17,
|
||||
TERM_GROUP2_ENTER2_block = 1 << 18,
|
||||
TERM_GROUP2_EXIT1_block = 1 << 19,
|
||||
TERM_GROUP2_EXIT2_block = 1 << 20,
|
||||
PRE_HELIPAD_block = 1 << 21,
|
||||
NOTHING_block = 1 << 30
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
/////*********Movement Positions on Airports********************///////
|
||||
// Country Airfield (small) 4x3
|
||||
static const AirportMovingData _airport_moving_data_country[22] = {
|
||||
{ 53, 3,AMED_EXACTPOS,3}, // 00 In Hangar
|
||||
{ 53, 27,0,0}, // 01 Taxi to right outside depot
|
||||
{ 32, 23,AMED_EXACTPOS,7}, // 02 Terminal 1
|
||||
{ 10, 23,AMED_EXACTPOS,7}, // 03 Terminal 2
|
||||
{ 43, 37,0,0}, // 04 Going towards terminal 2
|
||||
{ 24, 37,0,0}, // 05 Going towards terminal 2
|
||||
{ 53, 37,0,0}, // 06 Going for takeoff
|
||||
{ 61, 40,AMED_EXACTPOS,1}, // 07 Taxi to start of runway (takeoff)
|
||||
{ 3, 40,AMED_NOSPDCLAMP,0}, // 08 Accelerate to end of runway
|
||||
{-79, 40,AMED_NOSPDCLAMP | AMED_TAKEOFF,0}, // 09 Take off
|
||||
{177, 40,AMED_NOSPDCLAMP | AMED_SLOWTURN,0}, // 10 Fly to landing position in air
|
||||
{ 56, 40,AMED_NOSPDCLAMP | AMED_LAND,0}, // 11 Going down for land
|
||||
{ 3, 40,AMED_NOSPDCLAMP | AMED_BRAKE,0}, // 12 Just landed, brake until end of runway
|
||||
{ 7, 40,0,0}, // 13 Just landed, turn around and taxi 1 square
|
||||
{ 53, 40,0,0}, // 14 Taxi from runway to crossing
|
||||
{-31,193,AMED_NOSPDCLAMP | AMED_SLOWTURN,0}, // 15 Fly around waiting for a landing spot (north-east)
|
||||
{ 1, 1,AMED_NOSPDCLAMP | AMED_SLOWTURN,0}, // 16 Fly around waiting for a landing spot (north-west)
|
||||
{257, 1,AMED_NOSPDCLAMP | AMED_SLOWTURN,0}, // 17 Fly around waiting for a landing spot (south-west)
|
||||
{273, 49,AMED_NOSPDCLAMP | AMED_SLOWTURN,0}, // 18 Fly around waiting for a landing spot (south)
|
||||
{ 44, 37,AMED_HELI_RAISE,0}, // 19 Helicopter takeoff
|
||||
{ 44, 40,AMED_NOSPDCLAMP | AMED_SLOWTURN,0}, // 20 In position above landing spot helicopter
|
||||
{ 44, 40,AMED_HELI_LOWER,0} // 21 Helicopter landing
|
||||
};
|
||||
|
||||
// City Airport (large) 6x6
|
||||
static const AirportMovingData _airport_moving_data_town[25] = {
|
||||
{ 85, 3,AMED_EXACTPOS,3}, // 00 In Hangar
|
||||
{ 85, 27,0,0}, // 01 Taxi to right outside depot
|
||||
{ 26, 41,AMED_EXACTPOS,5}, // 02 Terminal 1
|
||||
{ 56, 20,AMED_EXACTPOS,3}, // 03 Terminal 2
|
||||
{ 38, 8,AMED_EXACTPOS,5}, // 04 Terminal 3
|
||||
{ 65, 6,0,0}, // 05 Taxi to right in infront of terminal 2/3
|
||||
{ 80, 27,0,0}, // 06 Taxiway terminals 2-3
|
||||
{ 44, 63,0,0}, // 07 Taxi to Airport center
|
||||
{ 58, 71,0,0}, // 08 Towards takeoff
|
||||
{ 72, 85,0,0}, // 09 Taxi to runway (takeoff)
|
||||
{ 89, 85,AMED_EXACTPOS,1}, // 10 Taxi to start of runway (takeoff)
|
||||
{ 3, 85,AMED_NOSPDCLAMP,0}, // 11 Accelerate to end of runway
|
||||
{-79, 85,AMED_NOSPDCLAMP | AMED_TAKEOFF,0}, // 12 Take off
|
||||
{177, 85,AMED_NOSPDCLAMP | AMED_SLOWTURN,0}, // 13 Fly to landing position in air
|
||||
{ 89, 85,AMED_NOSPDCLAMP | AMED_LAND,0}, // 14 Going down for land
|
||||
{ 3, 85,AMED_NOSPDCLAMP | AMED_BRAKE,0}, // 15 Just landed, brake until end of runway
|
||||
{ 20, 87,0,0}, // 16 Just landed, turn around and taxi 1 square
|
||||
{ 36, 71,0,0}, // 17 Taxi from runway to crossing
|
||||
{-31,193,AMED_NOSPDCLAMP | AMED_SLOWTURN,0}, // 18 Fly around waiting for a landing spot (north-east)
|
||||
{ 1, 1,AMED_NOSPDCLAMP | AMED_SLOWTURN,0}, // 19 Fly around waiting for a landing spot (north-west)
|
||||
{257, 1,AMED_NOSPDCLAMP | AMED_SLOWTURN,0}, // 20 Fly around waiting for a landing spot (south-west)
|
||||
{273, 49,AMED_NOSPDCLAMP | AMED_SLOWTURN,0}, // 21 Fly around waiting for a landing spot (south)
|
||||
{ 44, 63,AMED_HELI_RAISE,0}, // 22 Helicopter takeoff
|
||||
{ 28, 74,AMED_NOSPDCLAMP | AMED_SLOWTURN,0}, // 23 In position above landing spot helicopter
|
||||
{ 28, 74,AMED_HELI_LOWER,0} // 24 Helicopter landing
|
||||
};
|
||||
|
||||
// Metropolitan Airport (metropolitan) - 2 runways
|
||||
static const AirportMovingData _airport_moving_data_metropolitan[27] = {
|
||||
{ 85, 3,AMED_EXACTPOS,3}, // 00 In Hangar
|
||||
{ 85, 27,0,0}, // 01 Taxi to right outside depot
|
||||
{ 26, 41,AMED_EXACTPOS,5}, // 02 Terminal 1
|
||||
{ 56, 20,AMED_EXACTPOS,3}, // 03 Terminal 2
|
||||
{ 38, 8,AMED_EXACTPOS,5}, // 04 Terminal 3
|
||||
{ 65, 6,0,0}, // 05 Taxi to right in infront of terminal 2/3
|
||||
{ 70, 33,0,0}, // 06 Taxiway terminals 2-3
|
||||
{ 44, 58,0,0}, // 07 Taxi to Airport center
|
||||
{ 72, 58,0,0}, // 08 Towards takeoff
|
||||
{ 72, 69,0,0}, // 09 Taxi to runway (takeoff)
|
||||
{ 89, 69,AMED_EXACTPOS,1}, // 10 Taxi to start of runway (takeoff)
|
||||
{ 3, 69,AMED_NOSPDCLAMP,0}, // 11 Accelerate to end of runway
|
||||
{-79, 69,AMED_NOSPDCLAMP | AMED_TAKEOFF,0}, // 12 Take off
|
||||
{177, 85,AMED_NOSPDCLAMP | AMED_SLOWTURN,0}, // 13 Fly to landing position in air
|
||||
{ 89, 85,AMED_NOSPDCLAMP | AMED_LAND,0}, // 14 Going down for land
|
||||
{ 3, 85,AMED_NOSPDCLAMP | AMED_BRAKE,0}, // 15 Just landed, brake until end of runway
|
||||
{ 21, 85,0,0}, // 16 Just landed, turn around and taxi 1 square
|
||||
{ 21, 69,0,0}, // 17 On Runway-out taxiing to In-Way
|
||||
{ 21, 54,AMED_EXACTPOS,5}, // 18 Taxi from runway to crossing
|
||||
{-31,193,AMED_NOSPDCLAMP | AMED_SLOWTURN,0}, // 19 Fly around waiting for a landing spot (north-east)
|
||||
{ 1, 1,AMED_NOSPDCLAMP | AMED_SLOWTURN,0}, // 20 Fly around waiting for a landing spot (north-west)
|
||||
{257, 1,AMED_NOSPDCLAMP | AMED_SLOWTURN,0}, // 21 Fly around waiting for a landing spot (south-west)
|
||||
{273, 49,AMED_NOSPDCLAMP | AMED_SLOWTURN,0}, // 22 Fly around waiting for a landing spot (south)
|
||||
{ 44, 58,0,0}, // 23 Helicopter takeoff spot on ground (to clear airport sooner)
|
||||
{ 44, 63,AMED_HELI_RAISE,0}, // 24 Helicopter takeoff
|
||||
{ 15, 54,AMED_NOSPDCLAMP | AMED_SLOWTURN,0}, // 25 Get in position above landing spot helicopter
|
||||
{ 15, 54,AMED_HELI_LOWER,0} // 26 Helicopter landing
|
||||
};
|
||||
|
||||
// International Airport (international) - 2 runways, 6 terminals, dedicated helipod
|
||||
static const AirportMovingData _airport_moving_data_international[51] = {
|
||||
{ 7, 55,AMED_EXACTPOS,3}, // 00 In Hangar 1
|
||||
{100, 21,AMED_EXACTPOS,3}, // 01 In Hangar 2
|
||||
{ 7, 70,0,0}, // 02 Taxi to right outside depot
|
||||
{100, 36,0,0}, // 03 Taxi to right outside depot
|
||||
{ 38, 70,AMED_EXACTPOS,5}, // 04 Terminal 1
|
||||
{ 38, 54,AMED_EXACTPOS,5}, // 05 Terminal 2
|
||||
{ 38, 38,AMED_EXACTPOS,5}, // 06 Terminal 3
|
||||
{ 70, 70,AMED_EXACTPOS,1}, // 07 Terminal 4
|
||||
{ 70, 54,AMED_EXACTPOS,1}, // 08 Terminal 5
|
||||
{ 70, 38,AMED_EXACTPOS,1}, // 09 Terminal 6
|
||||
{104, 71,AMED_EXACTPOS,1}, // 10 Helipad 1
|
||||
{104, 55,AMED_EXACTPOS,1}, // 11 Helipad 2
|
||||
{ 22, 87,0,0}, // 12 Towards Terminals 4/5/6, Helipad 1/2
|
||||
{ 60, 87,0,0}, // 13 Towards Terminals 4/5/6, Helipad 1/2
|
||||
{ 66, 87,0,0}, // 14 Towards Terminals 4/5/6, Helipad 1/2
|
||||
{ 86, 87,AMED_EXACTPOS,7}, // 15 Towards Terminals 4/5/6, Helipad 1/2
|
||||
{ 86, 70,0,0}, // 16 In Front of Terminal 4 / Helipad 1
|
||||
{ 86, 54,0,0}, // 17 In Front of Terminal 5 / Helipad 2
|
||||
{ 86, 38,0,0}, // 18 In Front of Terminal 6
|
||||
{ 86, 22,0,0}, // 19 Towards Terminals Takeoff (Taxiway)
|
||||
{ 66, 22,0,0}, // 20 Towards Terminals Takeoff (Taxiway)
|
||||
{ 60, 22,0,0}, // 21 Towards Terminals Takeoff (Taxiway)
|
||||
{ 38, 22,0,0}, // 22 Towards Terminals Takeoff (Taxiway)
|
||||
{ 22, 70,0,0}, // 23 In Front of Terminal 1
|
||||
{ 22, 58,0,0}, // 24 In Front of Terminal 2
|
||||
{ 22, 38,0,0}, // 25 In Front of Terminal 3
|
||||
{ 22, 22,AMED_EXACTPOS,7}, // 26 Going for Takeoff
|
||||
{ 22, 6,0,0}, // 27 On Runway-out, prepare for takeoff
|
||||
{ 3, 6,AMED_EXACTPOS,5}, // 28 Accelerate to end of runway
|
||||
{ 60, 6,AMED_NOSPDCLAMP,0}, // 29 Release control of runway, for smoother movement
|
||||
{105, 6,AMED_NOSPDCLAMP,0}, // 30 End of runway
|
||||
{190, 6,AMED_NOSPDCLAMP | AMED_TAKEOFF,0}, // 31 Take off
|
||||
{193,104,AMED_NOSPDCLAMP | AMED_SLOWTURN,0}, // 32 Fly to landing position in air
|
||||
{105,104,AMED_NOSPDCLAMP | AMED_LAND,0}, // 33 Going down for land
|
||||
{ 3,104,AMED_NOSPDCLAMP | AMED_BRAKE,0}, // 34 Just landed, brake until end of runway
|
||||
{ 12,104,0,0}, // 35 Just landed, turn around and taxi 1 square
|
||||
{ 7, 84,0,0}, // 36 Taxi from runway to crossing
|
||||
{-31,209,AMED_NOSPDCLAMP | AMED_SLOWTURN,0}, // 37 Fly around waiting for a landing spot (north-east)
|
||||
{ 1, 6,AMED_NOSPDCLAMP | AMED_SLOWTURN,0}, // 38 Fly around waiting for a landing spot (north-west)
|
||||
{273, 6,AMED_NOSPDCLAMP | AMED_SLOWTURN,0}, // 39 Fly around waiting for a landing spot (south-west)
|
||||
{305, 81,AMED_NOSPDCLAMP | AMED_SLOWTURN,0}, // 40 Fly around waiting for a landing spot (south)
|
||||
// Helicopter
|
||||
{128, 80,AMED_NOSPDCLAMP | AMED_SLOWTURN,0}, // 41 Bufferspace before helipad
|
||||
{128, 80,AMED_NOSPDCLAMP | AMED_SLOWTURN,0}, // 42 Bufferspace before helipad
|
||||
{ 96, 71,AMED_NOSPDCLAMP | AMED_SLOWTURN,0}, // 43 Get in position for Helipad1
|
||||
{ 96, 55,AMED_NOSPDCLAMP | AMED_SLOWTURN,0}, // 44 Get in position for Helipad2
|
||||
{ 96, 71,AMED_HELI_LOWER,0}, // 45 Land at Helipad1
|
||||
{ 96, 55,AMED_HELI_LOWER,0}, // 46 Land at Helipad2
|
||||
{104, 71,AMED_HELI_RAISE,0}, // 47 Takeoff Helipad1
|
||||
{104, 55,AMED_HELI_RAISE,0}, // 48 Takeoff Helipad2
|
||||
{104, 32,AMED_NOSPDCLAMP | AMED_SLOWTURN,0}, // 49 Go to position for Hangarentrance in air
|
||||
{104, 32,AMED_HELI_LOWER,0} // 50 Land in HANGAR2_AREA to go to hangar
|
||||
};
|
||||
|
||||
// Heliport (heliport)
|
||||
static const AirportMovingData _airport_moving_data_heliport[9] = {
|
||||
{ 5, 9,AMED_EXACTPOS,1}, // 0 - At heliport terminal
|
||||
{ 2, 9,AMED_HELI_RAISE,0}, // 1 - Take off (play sound)
|
||||
{ -3, 9,AMED_NOSPDCLAMP | AMED_SLOWTURN,0}, // 2 - In position above landing spot helicopter
|
||||
{ -3, 9,AMED_HELI_LOWER,0}, // 3 - Land
|
||||
{ 2, 9,0,0}, // 4 - Goto terminal on ground
|
||||
{-31, 59,AMED_NOSPDCLAMP | AMED_SLOWTURN,0}, // 5 - Circle #1 (north-east)
|
||||
{-31,-49,AMED_NOSPDCLAMP | AMED_SLOWTURN,0}, // 6 - Circle #2 (north-west)
|
||||
{ 49,-49,AMED_NOSPDCLAMP | AMED_SLOWTURN,0}, // 7 - Circle #3 (south-west)
|
||||
{ 70, 9,AMED_NOSPDCLAMP | AMED_SLOWTURN,0}, // 8 - Circle #4 (south)
|
||||
};
|
||||
|
||||
// Oilrig
|
||||
static const AirportMovingData _airport_moving_data_oilrig[9] = {
|
||||
{ 31, 9,AMED_EXACTPOS,1}, // 0 - At oilrig terminal
|
||||
{ 28, 9,AMED_HELI_RAISE,0}, // 1 - Take off (play sound)
|
||||
{ 23, 9,AMED_NOSPDCLAMP | AMED_SLOWTURN,0}, // 2 - In position above landing spot helicopter
|
||||
{ 23, 9,AMED_HELI_LOWER,0}, // 3 - Land
|
||||
{ 28, 9,0,0}, // 4 - Goto terminal on ground
|
||||
{-31, 69,AMED_NOSPDCLAMP | AMED_SLOWTURN,0}, // 5 - circle #1 (north-east)
|
||||
{-31,-49,AMED_NOSPDCLAMP | AMED_SLOWTURN,0}, // 6 - circle #2 (north-west)
|
||||
{ 69,-49,AMED_NOSPDCLAMP | AMED_SLOWTURN,0}, // 7 - circle #3 (south-west)
|
||||
{ 70, 9,AMED_NOSPDCLAMP | AMED_SLOWTURN,0}, // 8 - circle #4 (south)
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
/////**********Movement Machine on Airports*********************///////
|
||||
// first element of depots array tells us how many depots there are (to know size of array)
|
||||
// this may be changed later when airports are moved to external file
|
||||
static const TileIndex _airport_depots_country[] = {1, TILE_XY(3,0)};
|
||||
static const AirportFTAbuildup _airport_fta_country[] = {
|
||||
{ 0,HANGAR,NOTHING_block,1},
|
||||
{ 1,255,AIRPORT_BUSY_block,0}, {1,HANGAR,0,0}, {1,TERM1,TERM1_block,2}, {1,TERM2,0,4}, {1,HELITAKEOFF,0,19}, {1,0,0,6},
|
||||
{ 2,TERM1,TERM1_block,1},
|
||||
{ 3,TERM2,TERM2_block,5},
|
||||
{ 4,255,AIRPORT_BUSY_block,0}, {4,TERM2,0,5}, {4,HANGAR,0,1}, {4,TAKEOFF,0,6}, {4,HELITAKEOFF,0,1},
|
||||
{ 5,255,AIRPORT_BUSY_block,0}, {5,TERM2,TERM2_block,3}, {5,0,0,4},
|
||||
{ 6,0,AIRPORT_BUSY_block,7},
|
||||
// takeoff
|
||||
{ 7,TAKEOFF,AIRPORT_BUSY_block,8},
|
||||
{ 8,STARTTAKEOFF,NOTHING_block,9},
|
||||
{ 9,ENDTAKEOFF,NOTHING_block,0},
|
||||
// landing
|
||||
{10,FLYING,NOTHING_block,15}, {10,LANDING,0,11}, {10,HELILANDING,0,20},
|
||||
{11,LANDING,AIRPORT_BUSY_block,12},
|
||||
{12,0,AIRPORT_BUSY_block,13},
|
||||
{13,ENDLANDING,AIRPORT_BUSY_block,14}, {13,TERM2,0,5}, {13,0,0,14},
|
||||
{14,0,AIRPORT_BUSY_block,1},
|
||||
// In air
|
||||
{15,0,NOTHING_block,16},
|
||||
{16,0,NOTHING_block,17},
|
||||
{17,0,NOTHING_block,18},
|
||||
{18,0,NOTHING_block,10},
|
||||
{19,HELITAKEOFF,NOTHING_block,0},
|
||||
{20,HELILANDING,AIRPORT_BUSY_block,21},
|
||||
{21,HELIENDLANDING,AIRPORT_BUSY_block,1},
|
||||
{MAX_ELEMENTS,0,0,0} // end marker. DO NOT REMOVE
|
||||
};
|
||||
|
||||
static const TileIndex _airport_depots_city[] = {1, TILE_XY(5,0)};
|
||||
static const AirportFTAbuildup _airport_fta_city[] = {
|
||||
{ 0,HANGAR,NOTHING_block,1}, {0,TAKEOFF,OUT_WAY_block,1}, {0,0,0,1},
|
||||
{ 1,255,TAXIWAY_BUSY_block,0}, {1,HANGAR,0,0}, {1,TERM2,0,6}, {1,TERM3,0,6}, {1,0,0,7}, // for all else, go to 7
|
||||
{ 2,TERM1,TERM1_block,7}, {2,TAKEOFF,OUT_WAY_block,7}, {2,0,0,7},
|
||||
{ 3,TERM2,TERM2_block,5}, {3,TAKEOFF,OUT_WAY_block,5}, {3,0,0,5},
|
||||
{ 4,TERM3,TERM3_block,5}, {4,TAKEOFF,OUT_WAY_block,5}, {4,0,0,5},
|
||||
{ 5,255,TAXIWAY_BUSY_block,0}, {5,TERM2,TERM2_block,3}, {5,TERM3,TERM3_block,4}, {5,0,0,6},
|
||||
{ 6,255,TAXIWAY_BUSY_block,0}, {6,TERM2,0,5}, {6,TERM3,0,5}, {6,HANGAR,0,1}, {6,0,0,7},
|
||||
{ 7,255,TAXIWAY_BUSY_block,0}, {7,TERM1,TERM1_block,2}, {7,TAKEOFF,OUT_WAY_block,8}, {7,HELITAKEOFF,0,22}, {7,HANGAR,0,1}, {7,0,0,6},
|
||||
{ 8,0,OUT_WAY_block,9},
|
||||
{ 9,0,RUNWAY_IN_OUT_block,10},
|
||||
// takeoff
|
||||
{10,TAKEOFF,RUNWAY_IN_OUT_block,11},
|
||||
{11,STARTTAKEOFF,NOTHING_block,12},
|
||||
{12,ENDTAKEOFF,NOTHING_block,0},
|
||||
// landing
|
||||
{13,FLYING,NOTHING_block,18}, {13,LANDING,0,14}, {13,HELILANDING,0,23},
|
||||
{14,LANDING,RUNWAY_IN_OUT_block,15},
|
||||
{15,0,RUNWAY_IN_OUT_block,16},
|
||||
{16,0,RUNWAY_IN_OUT_block,17},
|
||||
{17,ENDLANDING,IN_WAY_block,7},
|
||||
// In Air
|
||||
{18,0,NOTHING_block,19},
|
||||
{19,0,NOTHING_block,20},
|
||||
{20,0,NOTHING_block,21},
|
||||
{21,0,NOTHING_block,13},
|
||||
// helicopter
|
||||
{22,HELITAKEOFF,NOTHING_block,0},
|
||||
{23,HELILANDING,IN_WAY_block,24},
|
||||
{24,HELIENDLANDING,IN_WAY_block,17},
|
||||
{MAX_ELEMENTS,0,0,0} // end marker. DO NOT REMOVE
|
||||
};
|
||||
|
||||
static const TileIndex _airport_depots_metropolitan[] = {1, TILE_XY(5,0)};
|
||||
static const AirportFTAbuildup _airport_fta_metropolitan[] = {
|
||||
{ 0,HANGAR,NOTHING_block,1},
|
||||
{ 1,255,TAXIWAY_BUSY_block,0}, {1,HANGAR,0,0}, {1,TERM2,0,6}, {1,TERM3,0,6}, {1,0,0,7}, // for all else, go to 7
|
||||
{ 2,TERM1,TERM1_block,7},
|
||||
{ 3,TERM2,TERM2_block,5},
|
||||
{ 4,TERM3,TERM3_block,5},
|
||||
{ 5,255,TAXIWAY_BUSY_block,0}, {5,TERM2,TERM2_block,3}, {5,TERM3,TERM3_block,4}, {5,0,0,6},
|
||||
{ 6,255,TAXIWAY_BUSY_block,0}, {6,TERM2,0,5}, {6,TERM3,0,5}, {6,HANGAR,0,1}, {6,0,0,7},
|
||||
{ 7,255,TAXIWAY_BUSY_block,0}, {7,TERM1,TERM1_block,2}, {7,TAKEOFF,0,8}, {7,HELITAKEOFF,0,23}, {7,HANGAR,0,1}, {7,0,0,6},
|
||||
{ 8,0,OUT_WAY_block,9},
|
||||
{ 9,0,RUNWAY_OUT_block,10},
|
||||
// takeoff
|
||||
{10,TAKEOFF,RUNWAY_OUT_block,11},
|
||||
{11,STARTTAKEOFF,NOTHING_block,12},
|
||||
{12,ENDTAKEOFF,NOTHING_block,0},
|
||||
// landing
|
||||
{13,FLYING,NOTHING_block,19}, {13,LANDING,0,14}, {13,HELILANDING,0,25},
|
||||
{14,LANDING,RUNWAY_IN_block,15},
|
||||
{15,0,RUNWAY_IN_block,16},
|
||||
{16,255,RUNWAY_IN_block,0}, {16,ENDLANDING,IN_WAY_block,17},
|
||||
{17,255,RUNWAY_OUT_block,0}, {17,ENDLANDING,IN_WAY_block,18},
|
||||
{18,ENDLANDING,IN_WAY_block,7},
|
||||
// In Air
|
||||
{19,0,NOTHING_block,20},
|
||||
{20,0,NOTHING_block,21},
|
||||
{21,0,NOTHING_block,22},
|
||||
{22,0,NOTHING_block,13},
|
||||
// helicopter
|
||||
{23,0,NOTHING_block,24},
|
||||
{24,HELITAKEOFF,NOTHING_block,0},
|
||||
{25,HELILANDING,IN_WAY_block,26},
|
||||
{26,HELIENDLANDING,IN_WAY_block,18},
|
||||
{MAX_ELEMENTS,0,0,0} // end marker. DO NOT REMOVE
|
||||
};
|
||||
|
||||
static const TileIndex _airport_depots_international[] = {2, TILE_XY(0,3), TILE_XY(6,1)};
|
||||
static const AirportFTAbuildup _airport_fta_international[] = {
|
||||
{ 0,HANGAR,NOTHING_block,2}, {0,255,TERM_GROUP1_block,0}, {0,255,TERM_GROUP2_ENTER1_block,1}, {0,HELITAKEOFF,HELIPAD1_block,2}, {0,0,0,2},
|
||||
{ 1,HANGAR,NOTHING_block,3}, {1,255,HANGAR2_AREA_block,1}, {1,HELITAKEOFF,HELIPAD2_block,3}, {1,0,0,3},
|
||||
{ 2,255,AIRPORT_ENTRANCE_block,0}, {2,HANGAR,0,0}, {2,TERM4,0,12}, {2,TERM5,0,12}, {2,TERM6,0,12}, {2,HELIPAD1,0,12}, {2,HELIPAD2,0,12}, {2,HELITAKEOFF,0,12}, {2,0,0,23},
|
||||
{ 3,255,HANGAR2_AREA_block,0}, {3,HANGAR,0,1}, {3,0,0,18},
|
||||
{ 4,TERM1,TERM1_block,23}, {4,HANGAR,AIRPORT_ENTRANCE_block,23}, {4,0,0,23},
|
||||
{ 5,TERM2,TERM2_block,24}, {5,HANGAR,AIRPORT_ENTRANCE_block,24}, {5,0,0,24},
|
||||
{ 6,TERM3,TERM3_block,25}, {6,HANGAR,AIRPORT_ENTRANCE_block,25}, {6,0,0,25},
|
||||
{ 7,TERM4,TERM4_block,16}, {7,HANGAR,HANGAR2_AREA_block,16}, {7,0,0,16},
|
||||
{ 8,TERM5,TERM5_block,17}, {8,HANGAR,HANGAR2_AREA_block,17}, {8,0,0,17},
|
||||
{ 9,TERM6,TERM6_block,18}, {9,HANGAR,HANGAR2_AREA_block,18}, {9,0,0,18},
|
||||
{10,HELIPAD1,HELIPAD1_block,10}, {10,HANGAR,HANGAR2_AREA_block,16}, {10,HELITAKEOFF,0,47},
|
||||
{11,HELIPAD2,HELIPAD2_block,11}, {11,HANGAR,HANGAR2_AREA_block,17}, {11,HELITAKEOFF,0,48},
|
||||
{12,0,TERM_GROUP2_ENTER1_block,13},
|
||||
{13,0,TERM_GROUP2_ENTER1_block,14},
|
||||
{14,0,TERM_GROUP2_ENTER2_block,15},
|
||||
{15,0,TERM_GROUP2_ENTER2_block,16},
|
||||
{16,255,TERM_GROUP2_block,0}, {16,TERM4,TERM4_block,7}, {16,HELIPAD1,HELIPAD1_block,10}, {16,HELITAKEOFF,HELIPAD1_block,10}, {16,0,0,17},
|
||||
{17,255,TERM_GROUP2_block,0}, {17,TERM5,TERM5_block,8}, {17,TERM4,0,16}, {17,HELIPAD1,0,16}, {17,HELIPAD2,HELIPAD2_block,11}, {17,HELITAKEOFF,HELIPAD2_block,11}, {17,0,0,18},
|
||||
{18,255,TERM_GROUP2_block,0}, {18,TERM6,TERM6_block,9}, {18,TAKEOFF,0,19}, {18,HANGAR,HANGAR2_AREA_block,3}, {18,0,0,17},
|
||||
{19,0,TERM_GROUP2_EXIT1_block,20},
|
||||
{20,0,TERM_GROUP2_EXIT1_block,21},
|
||||
{21,0,TERM_GROUP2_EXIT2_block,22},
|
||||
{22,0,TERM_GROUP2_EXIT2_block,26},
|
||||
{23,255,TERM_GROUP1_block,0}, {23,TERM1,TERM1_block,4}, {23,HANGAR,AIRPORT_ENTRANCE_block,2}, {23,0,0,24},
|
||||
{24,255,TERM_GROUP1_block,0}, {24,TERM2,TERM2_block,5}, {24,TERM1,0,23}, {24,HANGAR,0,23}, {24,0,0,25},
|
||||
{25,255,TERM_GROUP1_block,0}, {25,TERM3,TERM3_block,6}, {25,TAKEOFF,0,26}, {25,0,0,24},
|
||||
{26,255,TAXIWAY_BUSY_block,0}, {26,TAKEOFF,0,27}, {26,0,0,25},
|
||||
{27,0,OUT_WAY_block,28},
|
||||
// takeoff
|
||||
{28,TAKEOFF,OUT_WAY_block,29},
|
||||
{29,0,RUNWAY_OUT_block,30},
|
||||
{30,STARTTAKEOFF,NOTHING_block,31},
|
||||
{31,ENDTAKEOFF,NOTHING_block,0},
|
||||
// landing
|
||||
{32,FLYING,NOTHING_block,37}, {32,LANDING,0,33}, {32,HELILANDING,0,41},
|
||||
{33,LANDING,RUNWAY_IN_block,34},
|
||||
{34,0,RUNWAY_IN_block,35},
|
||||
{35,0,RUNWAY_IN_block,36},
|
||||
{36,ENDLANDING,IN_WAY_block,36}, {36,255,TERM_GROUP1_block,0}, {36,255,TERM_GROUP2_ENTER1_block,1}, {36,TERM4,0,12}, {36,TERM5,0,12}, {36,TERM6,0,12}, {36,0,0,2},
|
||||
// In Air
|
||||
{37,0,NOTHING_block,38},
|
||||
{38,0,NOTHING_block,39},
|
||||
{39,0,NOTHING_block,40},
|
||||
{40,0,NOTHING_block,32},
|
||||
// Helicopter -- stay in air in special place as a buffer to choose from helipads
|
||||
{41,HELILANDING,PRE_HELIPAD_block,42},
|
||||
{42,HELIENDLANDING,PRE_HELIPAD_block,42}, {42,HELIPAD1,0,43}, {42,HELIPAD2,0,44}, {42,HANGAR,0,49},
|
||||
{43,0,NOTHING_block,45},
|
||||
{44,0,NOTHING_block,46},
|
||||
// landing
|
||||
{45,255,NOTHING_block,0}, {45,HELIPAD1,HELIPAD1_block,10},
|
||||
{46,255,NOTHING_block,0}, {46,HELIPAD2,HELIPAD2_block,11},
|
||||
// Helicopter -- takeoff
|
||||
{47,HELITAKEOFF,NOTHING_block,0},
|
||||
{48,HELITAKEOFF,NOTHING_block,0},
|
||||
{49,0,HANGAR2_AREA_block,50}, // need to go to hangar when waiting in air
|
||||
{50,0,HANGAR2_AREA_block,3},
|
||||
{MAX_ELEMENTS,0,0,0} // end marker. DO NOT REMOVE
|
||||
};
|
||||
|
||||
static const TileIndex _airport_depots_heliport_oilrig[] = {0};
|
||||
static const AirportFTAbuildup _airport_fta_heliport_oilrig[] = {
|
||||
{0,HELIPAD1,HELIPAD1_block,1},
|
||||
{1,HELITAKEOFF,NOTHING_block,0}, // takeoff
|
||||
{2,255,AIRPORT_BUSY_block,0}, {2,HELILANDING,0,3}, {2,HELITAKEOFF,0,1},
|
||||
{3,HELILANDING,AIRPORT_BUSY_block,4},
|
||||
{4,HELIENDLANDING,AIRPORT_BUSY_block,4}, {4,HELIPAD1,HELIPAD1_block,0}, {4,HELITAKEOFF,0,2},
|
||||
// In Air
|
||||
{5,0,NOTHING_block,6},
|
||||
{6,0,NOTHING_block,7},
|
||||
{7,0,NOTHING_block,8},
|
||||
{8,FLYING,NOTHING_block,5}, {8,HELILANDING,HELIPAD1_block,2}, // landing
|
||||
{MAX_ELEMENTS,0,0,0} // end marker. DO NOT REMOVE
|
||||
};
|
||||
|
||||
static const AirportMovingData * const _airport_moving_datas[6] = {
|
||||
_airport_moving_data_country, // Country Airfield (small) 4x3
|
||||
_airport_moving_data_town, // City Airport (large) 6x6
|
||||
_airport_moving_data_heliport, // Heliport
|
||||
_airport_moving_data_metropolitan, // Metropolitain Airport (large) - 2 runways
|
||||
_airport_moving_data_international, // International Airport (xlarge) - 2 runways
|
||||
_airport_moving_data_oilrig // Oilrig
|
||||
};
|
||||
|
||||
#endif /* AIRPORT_MOVEMENT_H */
|
271
trunk/aystar.c
271
trunk/aystar.c
|
@ -1,271 +0,0 @@
|
|||
/*
|
||||
* This file has the core function for AyStar
|
||||
* AyStar is a fast pathfinding routine and is used for things like
|
||||
* AI_pathfinding and Train_pathfinding.
|
||||
* For more information about AyStar (A* Algorithm), you can look at
|
||||
* http://en.wikipedia.org/wiki/A-star_search_algorithm
|
||||
*/
|
||||
|
||||
/*
|
||||
* Friendly reminder:
|
||||
* Call (AyStar).free() when you are done with Aystar. It reserves a lot of memory
|
||||
* And when not free'd, it can cause system-crashes.
|
||||
* Also remember that when you stop an algorithm before it is finished, your
|
||||
* should call clear() yourself!
|
||||
*/
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "ttd.h"
|
||||
#include "aystar.h"
|
||||
// This looks in the Hash if a node exists in ClosedList
|
||||
// If so, it returns the PathNode, else NULL
|
||||
PathNode *AyStarMain_ClosedList_IsInList(AyStar *aystar, AyStarNode *node) {
|
||||
return (PathNode*)Hash_Get(&aystar->ClosedListHash, node->tile, node->direction);
|
||||
}
|
||||
|
||||
// This adds a node to the ClosedList
|
||||
// It makes a copy of the data
|
||||
void AyStarMain_ClosedList_Add(AyStar *aystar, PathNode *node) {
|
||||
// Add a node to the ClosedList
|
||||
PathNode *new_node = malloc(sizeof(PathNode));
|
||||
*new_node = *node;
|
||||
Hash_Set(&aystar->ClosedListHash, node->node.tile, node->node.direction, new_node);
|
||||
}
|
||||
|
||||
// Checks if a node is in the OpenList
|
||||
// If so, it returns the OpenListNode, else NULL
|
||||
OpenListNode *AyStarMain_OpenList_IsInList(AyStar *aystar, AyStarNode *node) {
|
||||
return (OpenListNode*)Hash_Get(&aystar->OpenListHash, node->tile, node->direction);
|
||||
}
|
||||
|
||||
// Gets the best node from OpenList
|
||||
// returns the best node, or NULL of none is found
|
||||
// Also it deletes the node from the OpenList
|
||||
OpenListNode *AyStarMain_OpenList_Pop(AyStar *aystar) {
|
||||
// Return the item the Queue returns.. the best next OpenList item.
|
||||
OpenListNode* res = (OpenListNode*)aystar->OpenListQueue.pop(&aystar->OpenListQueue);
|
||||
if (res != NULL)
|
||||
Hash_Delete(&aystar->OpenListHash, res->path.node.tile, res->path.node.direction);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
// Adds a node to the OpenList
|
||||
// It makes a copy of node, and puts the pointer of parent in the struct
|
||||
void AyStarMain_OpenList_Add(AyStar *aystar, PathNode *parent, AyStarNode *node, int f, int g, int userdata) {
|
||||
// Add a new Node to the OpenList
|
||||
OpenListNode* new_node = malloc(sizeof(OpenListNode));
|
||||
new_node->g = g;
|
||||
new_node->path.parent = parent;
|
||||
new_node->path.node = *node;
|
||||
Hash_Set(&aystar->OpenListHash, node->tile, node->direction, new_node);
|
||||
|
||||
// Add it to the queue
|
||||
aystar->OpenListQueue.push(&aystar->OpenListQueue, new_node, f);
|
||||
}
|
||||
|
||||
/*
|
||||
* Checks one tile and calculate his f-value
|
||||
* return values:
|
||||
* AYSTAR_DONE : indicates we are done
|
||||
*/
|
||||
int AyStarMain_CheckTile(AyStar *aystar, AyStarNode *current, OpenListNode *parent) {
|
||||
int new_f, new_g, new_h;
|
||||
PathNode *closedlist_parent;
|
||||
OpenListNode *check;
|
||||
|
||||
// Check the new node against the ClosedList
|
||||
if (AyStarMain_ClosedList_IsInList(aystar, current) != NULL) return AYSTAR_DONE;
|
||||
|
||||
// Calculate the G-value for this node
|
||||
new_g = aystar->CalculateG(aystar, current, parent);
|
||||
// If the value was INVALID_NODE, we don't do anything with this node
|
||||
if (new_g == AYSTAR_INVALID_NODE) return AYSTAR_DONE;
|
||||
|
||||
// There should not be given any other error-code..
|
||||
assert(new_g >= 0);
|
||||
// Add the parent g-value to the new g-value
|
||||
new_g += parent->g;
|
||||
if (aystar->max_path_cost != 0 && (uint)new_g > aystar->max_path_cost) return AYSTAR_DONE;
|
||||
|
||||
// Calculate the h-value
|
||||
new_h = aystar->CalculateH(aystar, current, parent);
|
||||
// There should not be given any error-code..
|
||||
assert(new_h >= 0);
|
||||
|
||||
// The f-value if g + h
|
||||
new_f = new_g + new_h;
|
||||
|
||||
// Get the pointer to the parent in the ClosedList (the currentone is to a copy of the one in the OpenList)
|
||||
closedlist_parent = AyStarMain_ClosedList_IsInList(aystar, &parent->path.node);
|
||||
|
||||
// Check if this item is already in the OpenList
|
||||
if ((check = AyStarMain_OpenList_IsInList(aystar, current)) != NULL) {
|
||||
int i;
|
||||
// Yes, check if this g value is lower..
|
||||
if (new_g > check->g) return AYSTAR_DONE;
|
||||
aystar->OpenListQueue.del(&aystar->OpenListQueue, check, 0);
|
||||
// It is lower, so change it to this item
|
||||
check->g = new_g;
|
||||
check->path.parent = closedlist_parent;
|
||||
/* Copy user data, will probably have changed */
|
||||
for (i=0;i<lengthof(current->user_data);i++)
|
||||
check->path.node.user_data[i] = current->user_data[i];
|
||||
// Readd him in the OpenListQueue
|
||||
aystar->OpenListQueue.push(&aystar->OpenListQueue, check, new_f);
|
||||
} else {
|
||||
// A new node, add him to the OpenList
|
||||
AyStarMain_OpenList_Add(aystar, closedlist_parent, current, new_f, new_g, 0);
|
||||
}
|
||||
|
||||
return AYSTAR_DONE;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function is the core of AyStar. It handles one item and checks
|
||||
* his neighbour items. If they are valid, they are added to be checked too.
|
||||
* return values:
|
||||
* AYSTAR_EMPTY_OPENLIST : indicates all items are tested, and no path
|
||||
* has been found.
|
||||
* AYSTAR_LIMIT_REACHED : Indicates that the max_nodes limit has been
|
||||
* reached.
|
||||
* AYSTAR_FOUND_END_NODE : indicates we found the end. Path_found now is true, and in path is the path found.
|
||||
* AYSTAR_STILL_BUSY : indicates we have done this tile, did not found the path yet, and have items left to try.
|
||||
*/
|
||||
int AyStarMain_Loop(AyStar *aystar) {
|
||||
int i, r;
|
||||
|
||||
// Get the best node from OpenList
|
||||
OpenListNode *current = AyStarMain_OpenList_Pop(aystar);
|
||||
// If empty, drop an error
|
||||
if (current == NULL) return AYSTAR_EMPTY_OPENLIST;
|
||||
|
||||
// Check for end node and if found, return that code
|
||||
if (aystar->EndNodeCheck(aystar, current) == AYSTAR_FOUND_END_NODE) {
|
||||
if (aystar->FoundEndNode != NULL)
|
||||
aystar->FoundEndNode(aystar, current);
|
||||
free(current);
|
||||
return AYSTAR_FOUND_END_NODE;
|
||||
}
|
||||
|
||||
// Add the node to the ClosedList
|
||||
AyStarMain_ClosedList_Add(aystar, ¤t->path);
|
||||
|
||||
// Load the neighbours
|
||||
aystar->GetNeighbours(aystar, current);
|
||||
|
||||
// Go through all neighbours
|
||||
for (i=0;i<aystar->num_neighbours;i++) {
|
||||
// Check and add them to the OpenList if needed
|
||||
r = aystar->checktile(aystar, &aystar->neighbours[i], current);
|
||||
}
|
||||
|
||||
// Free the node
|
||||
free(current);
|
||||
|
||||
if (aystar->max_search_nodes != 0 && Hash_Size(&aystar->ClosedListHash) >= aystar->max_search_nodes)
|
||||
/* We've expanded enough nodes */
|
||||
return AYSTAR_LIMIT_REACHED;
|
||||
else
|
||||
// Return that we are still busy
|
||||
return AYSTAR_STILL_BUSY;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function frees the memory it allocated
|
||||
*/
|
||||
void AyStarMain_Free(AyStar *aystar) {
|
||||
aystar->OpenListQueue.free(&aystar->OpenListQueue, false);
|
||||
/* 2nd argument above is false, below is true, to free the values only
|
||||
* once */
|
||||
delete_Hash(&aystar->OpenListHash, true);
|
||||
delete_Hash(&aystar->ClosedListHash, true);
|
||||
#ifdef AYSTAR_DEBUG
|
||||
printf("[AyStar] Memory free'd\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* This function make the memory go back to zero
|
||||
* This function should be called when you are using the same instance again.
|
||||
*/
|
||||
void AyStarMain_Clear(AyStar *aystar) {
|
||||
// Clean the Queue, but not the elements within. That will be done by
|
||||
// the hash.
|
||||
aystar->OpenListQueue.clear(&aystar->OpenListQueue, false);
|
||||
// Clean the hashes
|
||||
clear_Hash(&aystar->OpenListHash, true);
|
||||
clear_Hash(&aystar->ClosedListHash, true);
|
||||
|
||||
#ifdef AYSTAR_DEBUG
|
||||
printf("[AyStar] Cleared AyStar\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* This is the function you call to run AyStar.
|
||||
* return values:
|
||||
* AYSTAR_FOUND_END_NODE : indicates we found an end node.
|
||||
* AYSTAR_NO_PATH : indicates that there was no path found.
|
||||
* AYSTAR_STILL_BUSY : indicates we have done some checked, that we did not found the path yet, and that we still have items left to try.
|
||||
* When the algorithm is done (when the return value is not AYSTAR_STILL_BUSY)
|
||||
* aystar->clear() is called. Note that when you stop the algorithm halfway,
|
||||
* you should still call clear() yourself!
|
||||
*/
|
||||
int AyStarMain_Main(AyStar *aystar) {
|
||||
int r, i = 0;
|
||||
// Loop through the OpenList
|
||||
// Quit if result is no AYSTAR_STILL_BUSY or is more then loops_per_tick
|
||||
while ((r = aystar->loop(aystar)) == AYSTAR_STILL_BUSY && (aystar->loops_per_tick == 0 || ++i < aystar->loops_per_tick)) { }
|
||||
#ifdef AYSTAR_DEBUG
|
||||
if (r == AYSTAR_FOUND_END_NODE)
|
||||
printf("[AyStar] Found path!\n");
|
||||
else if (r == AYSTAR_EMPTY_OPENLIST)
|
||||
printf("[AyStar] OpenList run dry, no path found\n");
|
||||
else if (r == AYSTAR_LIMIT_REACHED)
|
||||
printf("[AyStar] Exceeded search_nodes, no path found\n");
|
||||
#endif
|
||||
if (r != AYSTAR_STILL_BUSY)
|
||||
/* We're done, clean up */
|
||||
aystar->clear(aystar);
|
||||
|
||||
// Check result-value
|
||||
if (r == AYSTAR_FOUND_END_NODE) return AYSTAR_FOUND_END_NODE;
|
||||
// Check if we have some left in the OpenList
|
||||
if (r == AYSTAR_EMPTY_OPENLIST || r == AYSTAR_LIMIT_REACHED) return AYSTAR_NO_PATH;
|
||||
|
||||
// Return we are still busy
|
||||
return AYSTAR_STILL_BUSY;
|
||||
}
|
||||
|
||||
/*
|
||||
* Adds a node from where to start an algorithm. Multiple nodes can be added
|
||||
* if wanted. You should make sure that clear() is called before adding nodes
|
||||
* if the AyStar has been used before (though the normal main loop calls
|
||||
* clear() automatically when the algorithm finishes
|
||||
*/
|
||||
void AyStarMain_AddStartNode(AyStar *aystar, AyStarNode *start_node) {
|
||||
#ifdef AYSTAR_DEBUG
|
||||
printf("[AyStar] Starting A* Algorithm from node (%d, %d, %d)\n", GET_TILE_X(start_node->tile), GET_TILE_Y(start_node->tile), start_node->direction);
|
||||
#endif
|
||||
AyStarMain_OpenList_Add(aystar, NULL, start_node, 0, 0, 0);
|
||||
}
|
||||
|
||||
void init_AyStar(AyStar* aystar, Hash_HashProc hash, uint num_buckets) {
|
||||
// Allocated the Hash for the OpenList and ClosedList
|
||||
init_Hash(&aystar->OpenListHash, hash, num_buckets);
|
||||
init_Hash(&aystar->ClosedListHash, hash, num_buckets);
|
||||
|
||||
// Set up our sorting queue
|
||||
// BinaryHeap allocates a block of 1024 nodes
|
||||
// When thatone gets full it reserves an otherone, till this number
|
||||
// That is why it can stay this high
|
||||
init_BinaryHeap(&aystar->OpenListQueue, 102400);
|
||||
|
||||
aystar->addstart = AyStarMain_AddStartNode;
|
||||
aystar->main = AyStarMain_Main;
|
||||
aystar->loop = AyStarMain_Loop;
|
||||
aystar->free = AyStarMain_Free;
|
||||
aystar->clear = AyStarMain_Clear;
|
||||
aystar->checktile = AyStarMain_CheckTile;
|
||||
}
|
169
trunk/aystar.h
169
trunk/aystar.h
|
@ -1,169 +0,0 @@
|
|||
/*
|
||||
* This file has the header for AyStar
|
||||
* AyStar is a fast pathfinding routine and is used for things like
|
||||
* AI_pathfinding and Train_pathfinding.
|
||||
* For more information about AyStar (A* Algorithm), you can look at
|
||||
* http://en.wikipedia.org/wiki/A-star_search_algorithm
|
||||
*/
|
||||
|
||||
#ifndef AYSTAR_H
|
||||
#define AYSTAR_H
|
||||
|
||||
#include "queue.h"
|
||||
|
||||
//#define AYSTAR_DEBUG
|
||||
enum {
|
||||
AYSTAR_FOUND_END_NODE,
|
||||
AYSTAR_EMPTY_OPENLIST,
|
||||
AYSTAR_STILL_BUSY,
|
||||
AYSTAR_NO_PATH,
|
||||
AYSTAR_LIMIT_REACHED,
|
||||
AYSTAR_DONE
|
||||
};
|
||||
|
||||
enum{
|
||||
AYSTAR_INVALID_NODE = -1,
|
||||
};
|
||||
|
||||
typedef struct AyStarNode AyStarNode;
|
||||
struct AyStarNode {
|
||||
uint tile;
|
||||
uint direction;
|
||||
uint user_data[2];
|
||||
};
|
||||
|
||||
// The resulting path has nodes looking like this.
|
||||
typedef struct PathNode PathNode;
|
||||
struct PathNode {
|
||||
AyStarNode node;
|
||||
// The parent of this item
|
||||
PathNode *parent;
|
||||
};
|
||||
|
||||
// For internal use only
|
||||
// We do not save the h-value, because it is only needed to calculate the f-value.
|
||||
// h-value should _always_ be the distance left to the end-tile.
|
||||
typedef struct OpenListNode OpenListNode;
|
||||
struct OpenListNode {
|
||||
int g;
|
||||
PathNode path;
|
||||
};
|
||||
|
||||
typedef struct AyStar AyStar;
|
||||
/*
|
||||
* This function is called to check if the end-tile is found
|
||||
* return values can be:
|
||||
* AYSTAR_FOUND_END_NODE : indicates this is the end tile
|
||||
* AYSTAR_DONE : indicates this is not the end tile (or direction was wrong)
|
||||
*/
|
||||
typedef int32 AyStar_EndNodeCheck(AyStar *aystar, OpenListNode *current);
|
||||
|
||||
/*
|
||||
* This function is called to calculate the G-value for AyStar Algorithm.
|
||||
* return values can be:
|
||||
* AYSTAR_INVALID_NODE : indicates an item is not valid (e.g.: unwalkable)
|
||||
* Any value >= 0 : the g-value for this tile
|
||||
*/
|
||||
typedef int32 AyStar_CalculateG(AyStar *aystar, AyStarNode *current, OpenListNode *parent);
|
||||
|
||||
/*
|
||||
* This function is called to calculate the H-value for AyStar Algorithm.
|
||||
* Mostly, this must result the distance (Manhattan way) between the
|
||||
* current point and the end point
|
||||
* return values can be:
|
||||
* Any value >= 0 : the h-value for this tile
|
||||
*/
|
||||
typedef int32 AyStar_CalculateH(AyStar *aystar, AyStarNode *current, OpenListNode *parent);
|
||||
|
||||
/*
|
||||
* This function request the tiles around the current tile and put them in tiles_around
|
||||
* tiles_around is never resetted, so if you are not using directions, just leave it alone.
|
||||
* Warning: never add more tiles_around than memory allocated for it.
|
||||
*/
|
||||
typedef void AyStar_GetNeighbours(AyStar *aystar, OpenListNode *current);
|
||||
|
||||
/*
|
||||
* If the End Node is found, this function is called.
|
||||
* It can do, for example, calculate the route and put that in an array
|
||||
*/
|
||||
typedef void AyStar_FoundEndNode(AyStar *aystar, OpenListNode *current);
|
||||
|
||||
// For internal use, see aystar.c
|
||||
typedef void AyStar_AddStartNode(AyStar *aystar, AyStarNode* start_node);
|
||||
typedef int AyStar_Main(AyStar *aystar);
|
||||
typedef int AyStar_Loop(AyStar *aystar);
|
||||
typedef int AyStar_CheckTile(AyStar *aystar, AyStarNode *current, OpenListNode *parent);
|
||||
typedef void AyStar_Free(AyStar *aystar);
|
||||
typedef void AyStar_Clear(AyStar *aystar);
|
||||
|
||||
struct AyStar {
|
||||
/* These fields should be filled before initting the AyStar, but not changed
|
||||
* afterwards (except for user_data and user_path)! (free and init again to change them) */
|
||||
|
||||
/* These should point to the application specific routines that do the
|
||||
* actual work */
|
||||
AyStar_CalculateG* CalculateG;
|
||||
AyStar_CalculateH* CalculateH;
|
||||
AyStar_GetNeighbours* GetNeighbours;
|
||||
AyStar_EndNodeCheck* EndNodeCheck;
|
||||
AyStar_FoundEndNode* FoundEndNode;
|
||||
|
||||
/* These are completely untouched by AyStar, they can be accesed by
|
||||
* the application specific routines to input and output data.
|
||||
* user_path should typically contain data about the resulting path
|
||||
* afterwards, user_target should typically contain information about
|
||||
* what where looking for, and user_data can contain just about
|
||||
* everything */
|
||||
void *user_path;
|
||||
void *user_target;
|
||||
uint user_data[10];
|
||||
|
||||
/* How many loops are there called before AyStarMain_Main gives
|
||||
* control back to the caller. 0 = until done */
|
||||
byte loops_per_tick;
|
||||
/* If the g-value goes over this number, it stops searching
|
||||
* 0 = infinite */
|
||||
uint max_path_cost;
|
||||
/* The maximum amount of nodes that will be expanded, 0 = infinite */
|
||||
uint max_search_nodes;
|
||||
|
||||
/* These should be filled with the neighbours of a tile by
|
||||
* GetNeighbours */
|
||||
AyStarNode neighbours[12];
|
||||
byte num_neighbours;
|
||||
|
||||
/* These will contain the methods for manipulating the AyStar. Only
|
||||
* main() should be called externally */
|
||||
AyStar_AddStartNode* addstart;
|
||||
AyStar_Main* main;
|
||||
AyStar_Loop* loop;
|
||||
AyStar_Free* free;
|
||||
AyStar_Clear* clear;
|
||||
AyStar_CheckTile* checktile;
|
||||
|
||||
/* These will contain the open and closed lists */
|
||||
|
||||
/* The actual closed list */
|
||||
Hash ClosedListHash;
|
||||
/* The open queue */
|
||||
Queue OpenListQueue;
|
||||
/* An extra hash to speed up the process of looking up an element in
|
||||
* the open list */
|
||||
Hash OpenListHash;
|
||||
};
|
||||
|
||||
|
||||
void AyStarMain_AddStartNode(AyStar *aystar, AyStarNode *start_node);
|
||||
int AyStarMain_Main(AyStar *aystar);
|
||||
int AyStarMain_Loop(AyStar *aystar);
|
||||
int AyStarMain_CheckTile(AyStar *aystar, AyStarNode *current, OpenListNode *parent);
|
||||
void AyStarMain_Free(AyStar *aystar);
|
||||
void AyStarMain_Clear(AyStar *aystar);
|
||||
|
||||
/* Initialize an AyStar. You should fill all appropriate fields before
|
||||
* callling init_AyStar (see the declaration of AyStar for which fields are
|
||||
* internal */
|
||||
void init_AyStar(AyStar* aystar, Hash_HashProc hash, uint num_buckets);
|
||||
|
||||
|
||||
#endif
|
|
@ -1,55 +0,0 @@
|
|||
#ifdef __BEOS__
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "ttd.h"
|
||||
#include "hal.h"
|
||||
|
||||
// BeOS System Includes
|
||||
#include <MidiSynthFile.h>
|
||||
|
||||
BMidiSynthFile midiSynthFile;
|
||||
|
||||
static char *bemidi_start(char **parm) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void bemidi_stop(void) {
|
||||
midiSynthFile.UnloadFile();
|
||||
}
|
||||
|
||||
static void bemidi_play_song(const char *filename) {
|
||||
bemidi_stop();
|
||||
entry_ref midiRef;
|
||||
get_ref_for_path(filename, &midiRef);
|
||||
midiSynthFile.LoadFile(&midiRef);
|
||||
midiSynthFile.Start();
|
||||
}
|
||||
|
||||
static void bemidi_stop_song(void) {
|
||||
midiSynthFile.UnloadFile();
|
||||
}
|
||||
|
||||
static bool bemidi_is_playing(void) {
|
||||
if(midiSynthFile.IsFinished() == true)
|
||||
{
|
||||
return 0;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void bemidi_set_volume(byte vol) {
|
||||
fprintf(stderr, "BeMidi: Set volume not implemented\n");
|
||||
}
|
||||
|
||||
const HalMusicDriver _bemidi_music_driver = {
|
||||
bemidi_start,
|
||||
bemidi_stop,
|
||||
bemidi_play_song,
|
||||
bemidi_stop_song,
|
||||
bemidi_is_playing,
|
||||
bemidi_set_volume,
|
||||
};
|
||||
|
||||
#endif // __BEOS__
|
|
@ -1,164 +0,0 @@
|
|||
#include "stdafx.h"
|
||||
#include "ttd.h"
|
||||
|
||||
#include "window.h"
|
||||
#include "gui.h"
|
||||
#include "viewport.h"
|
||||
#include "gfx.h"
|
||||
#include "command.h"
|
||||
|
||||
static struct BridgeData {
|
||||
int count;
|
||||
TileIndex start_tile;
|
||||
TileIndex end_tile;
|
||||
byte type;
|
||||
byte indexes[MAX_BRIDGES];
|
||||
int32 costs[MAX_BRIDGES];
|
||||
} _bridge;
|
||||
|
||||
extern const uint16 _bridge_type_price_mod[MAX_BRIDGES];
|
||||
|
||||
extern const PalSpriteID _bridge_sprites[MAX_BRIDGES];
|
||||
extern const uint16 _bridge_speeds[MAX_BRIDGES];
|
||||
extern const StringID _bridge_material[MAX_BRIDGES];
|
||||
|
||||
static void CcBuildBridge(bool success, uint tile, uint32 p1, uint32 p2)
|
||||
{
|
||||
if (success) { SndPlayTileFx(0x25, tile); }
|
||||
}
|
||||
|
||||
static void BuildBridge(Window *w, int i)
|
||||
{
|
||||
DeleteWindow(w);
|
||||
DoCommandP(_bridge.end_tile, _bridge.start_tile, _bridge.indexes[i] | (_bridge.type << 8), CcBuildBridge,
|
||||
CMD_BUILD_BRIDGE | CMD_AUTO | CMD_MSG(STR_5015_CAN_T_BUILD_BRIDGE_HERE));
|
||||
}
|
||||
|
||||
static void BuildBridgeWndProc(Window *w, WindowEvent *e)
|
||||
{
|
||||
switch(e->event) {
|
||||
case WE_PAINT: {
|
||||
int i;
|
||||
|
||||
DrawWindowWidgets(w);
|
||||
|
||||
for(i=0; i < 4 && i + w->vscroll.pos < _bridge.count; i++) {
|
||||
int ind = _bridge.indexes[i + w->vscroll.pos];
|
||||
|
||||
SET_DPARAM32(2, _bridge.costs[i + w->vscroll.pos]);
|
||||
SET_DPARAM16(1, (_bridge_speeds[ind] >> 4) * 10);
|
||||
SET_DPARAM16(0, _bridge_material[ind]);
|
||||
DrawSprite(_bridge_sprites[ind], 3, 15 + i * 22);
|
||||
|
||||
DrawString(44, 15 + i*22 , STR_500D, 0);
|
||||
}
|
||||
} break;
|
||||
|
||||
case WE_KEYPRESS: {
|
||||
uint i = e->keypress.keycode - '1';
|
||||
if (i < 9 && i < (uint)_bridge.count) {
|
||||
e->keypress.cont = false;
|
||||
BuildBridge(w, i);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case WE_CLICK:
|
||||
if (e->click.widget == 2) {
|
||||
uint ind = ((int)e->click.pt.y - 14) / 22;
|
||||
if (ind < 4 && (ind += w->vscroll.pos) < (uint)_bridge.count)
|
||||
BuildBridge(w, ind);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static const Widget _build_bridge_widgets[] = {
|
||||
{ WWT_CLOSEBOX, 7, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
|
||||
{ WWT_CAPTION, 7, 11, 199, 0, 13, STR_100D_SELECT_RAIL_BRIDGE, STR_018C_WINDOW_TITLE_DRAG_THIS},
|
||||
{ WWT_MATRIX, 7, 0, 188, 14, 101, 0x401, STR_101F_BRIDGE_SELECTION_CLICK},
|
||||
{ WWT_SCROLLBAR, 7, 189, 199, 14, 101, 0x0, STR_0190_SCROLL_BAR_SCROLLS_LIST},
|
||||
{ WIDGETS_END},
|
||||
};
|
||||
|
||||
static const WindowDesc _build_bridge_desc = {
|
||||
-1, -1, 200, 102,
|
||||
WC_BUILD_BRIDGE,WC_BUILD_TOOLBAR,
|
||||
WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET,
|
||||
_build_bridge_widgets,
|
||||
BuildBridgeWndProc
|
||||
};
|
||||
|
||||
|
||||
static const Widget _build_road_bridge_widgets[] = {
|
||||
{ WWT_CLOSEBOX, 7, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
|
||||
{ WWT_CAPTION, 7, 11, 199, 0, 13, STR_1803_SELECT_ROAD_BRIDGE, STR_018C_WINDOW_TITLE_DRAG_THIS},
|
||||
{ WWT_MATRIX, 7, 0, 188, 14, 101, 0x401, STR_101F_BRIDGE_SELECTION_CLICK},
|
||||
{ WWT_SCROLLBAR, 7, 189, 199, 14, 101, 0x0, STR_0190_SCROLL_BAR_SCROLLS_LIST},
|
||||
{ WIDGETS_END},
|
||||
};
|
||||
|
||||
static const WindowDesc _build_road_bridge_desc = {
|
||||
-1, -1, 200, 102,
|
||||
WC_BUILD_BRIDGE,WC_BUILD_TOOLBAR,
|
||||
WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET,
|
||||
_build_road_bridge_widgets,
|
||||
BuildBridgeWndProc
|
||||
};
|
||||
|
||||
|
||||
void ShowBuildBridgeWindow(uint start, uint end, byte bridge_type)
|
||||
{
|
||||
int j = 0;
|
||||
int32 ret;
|
||||
uint16 errmsg;
|
||||
|
||||
DeleteWindowById(WC_BUILD_BRIDGE, 0);
|
||||
|
||||
_bridge.type = bridge_type;
|
||||
_bridge.start_tile = start;
|
||||
_bridge.end_tile = end;
|
||||
|
||||
errmsg = 0xFFFF;
|
||||
|
||||
// only query bridge building possibility once, result is the same for all bridges!
|
||||
// returns CMD_ERROR on failure, and priCe on success
|
||||
ret = DoCommandByTile(end, start, (bridge_type << 8), DC_AUTO | DC_QUERY_COST, CMD_BUILD_BRIDGE);
|
||||
|
||||
if (ret == CMD_ERROR) {
|
||||
errmsg = _error_message;
|
||||
}
|
||||
// check which bridges can be built
|
||||
else {
|
||||
int bridge_len; // length of the middle parts of the bridge
|
||||
int tot_bridge_len; // total length of bridge
|
||||
|
||||
// get absolute bridge length
|
||||
bridge_len = GetBridgeLength(start, end);
|
||||
tot_bridge_len = bridge_len + 2;
|
||||
|
||||
tot_bridge_len = CalcBridgeLenCostFactor(tot_bridge_len);
|
||||
|
||||
for (bridge_type = 0; bridge_type != MAX_BRIDGES; bridge_type++) { // loop for all bridgetypes
|
||||
|
||||
if (CheckBridge_Stuff(bridge_type, bridge_len)) {
|
||||
// bridge is accepted, add to list
|
||||
// add to terraforming & bulldozing costs the cost of the bridge itself (not computed with DC_QUERY_COST)
|
||||
_bridge.costs[j] = ret + (((int64)tot_bridge_len * _price.build_bridge * _bridge_type_price_mod[bridge_type]) >> 8);
|
||||
_bridge.indexes[j] = bridge_type;
|
||||
j++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_bridge.count = j;
|
||||
|
||||
if (j != 0) {
|
||||
Window *w = AllocateWindowDesc((_bridge.type & 0x80) ? &_build_road_bridge_desc : &_build_bridge_desc);
|
||||
w->vscroll.cap = 4;
|
||||
w->vscroll.count = (byte)j;
|
||||
} else {
|
||||
ShowErrorMessage(errmsg, STR_5015_CAN_T_BUILD_BRIDGE_HERE, GET_TILE_X(end) * 16, GET_TILE_Y(end) * 16);
|
||||
}
|
||||
}
|
|
@ -1,587 +0,0 @@
|
|||
0.3.4 (2004-09-14)
|
||||
------------------------------------------------------------------------
|
||||
- Add: Dutch translation
|
||||
- Add: Generalised A* Algorithm
|
||||
- Add: Generalised queues (Fifo, Stack, InsSort, BinaryHeap)
|
||||
- Change: Changed 'terraforming' to 'landscaping'
|
||||
- Change: Changed default options (road side, distance units, currency) to most commonly used options
|
||||
- Change: Disable 'Submit Report' and 'Show Details' on OpenTTD error window on Windows. Currently of no use, since no devs have assembly knowledge
|
||||
- Change: Removed patch no_train_service. Instead you can set the default service interval for any vehicle type to 'disabled'.
|
||||
- Codechange: Comments added to the code (blathijs)
|
||||
- Codechange: Made bridge building code more readable [ 996244 ] (follow)
|
||||
- Feature: "None" as option for number of industries in difficulty settings
|
||||
- Feature: Add many random industries and towns in scenario editor
|
||||
- Feature: Added Autosignals, just like Autorail. Can copy signal style, convert signal<->semaphore, etc. Big thanks to betatesters Dribbel and Testman57 (Darkvater)
|
||||
- Feature: Added level land button to scenario editor (chrishuebsch)
|
||||
- Feature: Added never_expire_vehicles to patches GUI (Chris Huebsch)
|
||||
- Feature: Added new icons for landscaping toolbar (drawn by sign_de)
|
||||
- Feature: Added original vehicle names file. Select it from the list. Vehicles will have real name, all other strings are in English (orudge).
|
||||
- Feature: Added/heavily modified patch by truesatan cheat change date
|
||||
- Feature: Align toolbar left/center/right patch (TrueLight)
|
||||
- Feature: All TTDLX kind of savegames are supported (.SS1, .SV1, .SV2, .SV0, .SS0).
|
||||
- Feature: Alpha version of a new AI (TrueLight)
|
||||
- Feature: Autodetect server in LAN via udp (Sign)
|
||||
- Feature: Build_date of station (viewable with Query tool)
|
||||
- Feature: Cheat switch climate
|
||||
- Feature: Company HQ can now be moved somewhere else (cost 1% of company value). Water floods HQ.
|
||||
- Feature: Competitors menu under patches
|
||||
- Feature: Copy/share orders now works from ship depot window for ships and hangar window for aircraft
|
||||
- Feature: Difficulty settings window has been changed (Darkvater)
|
||||
- Feature: Enable/disable all buttons in message settings
|
||||
- Feature: Executeable is now openttd(.exe) always
|
||||
- Feature: General protection around Sprites
|
||||
- Feature: Ingame console (sign_de)
|
||||
- Feature: Invalid (void) orders in schedule are highlighted in red (Celestar)
|
||||
- Feature: Invisible trees when in transparent mode (patch entry)
|
||||
- Feature: Option to sort vehicles in vehicle-list window by different criteria.
|
||||
- Feature: Performance details window in company league menu (TrueLight)
|
||||
- Feature: Proper crediting to graphics artists to about box.
|
||||
- Feature: Removing town roads has been finetuned.
|
||||
- Feature: Safeguard against invalid values in Patches window. Values will stick to their defined min and max values
|
||||
- Feature: Sorting savegames, scenarios by name/date
|
||||
- Feature: Terraforming toolbar (in the plant tree menu)
|
||||
- Feature: The extra dynamite patch has been changed a bit.
|
||||
- Feature: Warning when a vehicle has invalid orders (celestar)
|
||||
- Feature: Water floods everything, including vehicles.
|
||||
- Feature: Working multiplayer gui (sign_de)
|
||||
- Feature: [ 976127 ] No extra frequent jet crash on small airports (truesatan)
|
||||
- Feature: [ 992998 ] Scrollto Station in Orders. CTRL click on orders of a vehicle and main-window scrolls to that station. (chrishuebsch)
|
||||
- Feature: [ 997115 ] Improved industry directory (hampzter)
|
||||
- Feature: [ 1003350 ] Euro introduction news item. (dominik81)
|
||||
- Feature: [ 1009708 ] Percent-based service intervals. Send a vehicle to depot after it has lost X% of its reliability (mivlad)
|
||||
- Feature: [ 1009710 ] Extra Viewport (Dribbel)
|
||||
- Feature: [ 1024044 ] Show max loan in finances window. (ledow)
|
||||
- Fix: (Unix) loading old scenarios (.sv0) works again
|
||||
- Fix: 64bit CPU fixes
|
||||
- Fix: 64x64 stations are now nicely painted
|
||||
- Fix: A lot of network fixing (sign_de)
|
||||
- Fix: A lot of old AI fixed
|
||||
- Fix: All scenarios, savegames show up with their correct name
|
||||
- Fix: Automatic oil refinery generation in editor
|
||||
- Fix: Autosave folder was not created on MorphOS- Fix: Bridge slope fix again, thanks Truelight
|
||||
- Fix: Bulldozing stuff with cheat magic_dynamite turned on doesn't lower city ratings
|
||||
- Fix: Change SDL_HWSURFACE back to SDL_SWSURFACE (Diablo-3D); better performance
|
||||
- Fix: Coast line near edge of map and near oilrigs (Dribbel)
|
||||
- Fix: Company-value was not updated immediatly if legend was changed (vondel)
|
||||
- Fix: Delete canal under bridge wasn't possible
|
||||
- Fix: Disable Fast Forward in network games visually (didn't work anyways, just showed graphical output)
|
||||
- Fix: Error message for 'game load failed' when no town is in a scenario
|
||||
- Fix: Game not pausing when saveload dialog is clicked in main menu
|
||||
- Fix: Load Scenario fix
|
||||
- Fix: Make endianess check 100% accurate
|
||||
- Fix: Memory leak in news system (blathijs)
|
||||
- Fix: Monorail/maglev became available around 1927
|
||||
- Fix: Move around sort-widgets a bit so it looks more natural
|
||||
- Fix: Music now finally works on WinXP. DirectMusic is now default for an OS >= WinNT4 (WinNT4, Win2k, WinXP), and MIDI driver for lower OS's (Win95, Win98, WinME, etc).
|
||||
- Fix: Old scenarios have correct colour
|
||||
- Fix: Placing/editing signs signs is possible in paused mode
|
||||
- Fix: Player window fixes, Getstring id0 fixes, Finances window is now ok
|
||||
- Fix: Playing new game with scenarios in windows works
|
||||
- Fix: Possible to disable some patches (e.g. default service interval) again by setting them to 0
|
||||
- Fix: Problems around exclusive transport rights (Celestar)
|
||||
- Fix: Railroad crossings on slopes are now possible
|
||||
- Fix: Random crash when player-face was displayed in error-dialog
|
||||
- Fix: Rare mousewheel scrolling with scrollbar crash
|
||||
- Fix: Road vehicles don't get stuck any more at stations (Truelight + Celestar)
|
||||
- Fix: Savegames are sorted with newest date first by default
|
||||
- Fix: Scenario editor now asks before it generates a random landscape
|
||||
- Fix: Slopes graphics fix (dominik)
|
||||
- Fix: Small gap between station button and signal button in rail toolbar
|
||||
- Fix: Some minor fixes around GetTileTrackStatus (blathijs)
|
||||
- Fix: Sorter icon pointing down 'v' sorts in every window lowest value first, '^' highest value first
|
||||
- Fix: Starting a new game in DesertLandscape crashed the game
|
||||
- Fix: Stupid bug in company league window if non-player is first
|
||||
- Fix: Two non-AI players when loading a scenario
|
||||
- Fix: Unix uses same sorting of directories, files as windows
|
||||
- Fix: When adding parts to a statin max size is not 15x15 anymore, but _patches.station_spread
|
||||
- Fix: Win98 crashes related to music/sound (orudge)
|
||||
- Fix: Wrong building of road-slopes for a future AI/Town
|
||||
- Fix: Wrong pathfinding when northern station tile is missing (blathijs)
|
||||
- Fix: You cannot take ownership of an oilrig by building right next to it
|
||||
- Fix: [Makefile] Fixed issue where sdl-config was needed even on systems without SDL
|
||||
- Fix: [SDL] Performance fix fo palette animation and mouse jumping (jirif)
|
||||
- Fix: [SDL] Same resolution was displayed more than once in game options
|
||||
- Fix: [SDL] Smoother mouse and performance fix, like in Win32 (jirif)
|
||||
- Fix: [ 963056 ] Wrong trains you can buy with scenarios
|
||||
- Fix: [ 972087 ] Minimap crash
|
||||
- Fix: [ 972247 ] Bug in '[a] weird non-uniform stations handling' (blathijs)
|
||||
- Fix: [ 976583 ] Parent_list was too small
|
||||
- Fix: [ 981934 ] Memoryleak in parent_list
|
||||
- Fix: [ 982666 ] Max_loan in editor bug (TrueLight)
|
||||
- Fix: [ 987888 ] Bridge building over boats
|
||||
- Fix: [ 990770 ] Cargo delivery area patch for bug #989322. (Celstar)
|
||||
- Fix: [ 992726 ] No tunnel crash (Celestar)
|
||||
- Fix: [ 993339 ] Light House Placement Bug
|
||||
- Fix: [ 993374 ] Pressing alt locks the game - sort of a bug.
|
||||
- Fix: [ 993493 ] Buildings on water
|
||||
- Fix: [ 993512 ] No canal building under bridge
|
||||
- Fix: [ 993829 ] UDP Fixes (lucaspiller)
|
||||
- Fix: [ 994067 ] Train drivers dies two times (follow)
|
||||
- Fix: [ 994720 ] Road depot - bus/lorry station (Truelight+Darkvater P )
|
||||
- Fix: [ 996025 ] _local_player fixes. Fixes wrong memory access (TrueLight)
|
||||
- Fix: [ 996065 ] Bridge Bug fixed bug fixed again (Darkvater)
|
||||
- Fix: [ 996065 ] Weird two tile bridges on slopes
|
||||
- Fix: [ 997303 ] Empty strings in signs
|
||||
- Fix: [ 997703 ] Junction after tunnel bug (blathijs)
|
||||
- Fix: [ 999592 ] "autosave" directoy creation (MorphOS/AmigaOS) (Tokai)
|
||||
- Fix: [ 1001540 ] I lost all wagons. Half-assed fix for lost wagons. But now users can at least fix this problem. Consolecommand "resetengines"
|
||||
- Fix: [ 1006530 ] BuildRoadOutsideStation fix.
|
||||
- Fix: [ 1006715 ] Autorenew issues
|
||||
- Fix: [ 1007272 ] Copy orders between bus/truck possible. (Celestar)
|
||||
- Fix: [ 1007630 ] Scenario editor pause bug
|
||||
- Fix: [ 1008605 ] Signals not updated after ClearTunnel Bug [ 985920 ] (TrueLight)
|
||||
- Fix: [ 1009385 ] Too many save games prevented loading
|
||||
- Fix: [ 1009567 ] problem with transferred cargo crashes game.
|
||||
- Fix: [ 1009621 ] build in pause is now a cheat instead of a patch (truesatan)
|
||||
- Fix: [ 1009631 ] Wrong multihead selling (Bodewes)
|
||||
- Fix: [ 1010833 ] Turning on the magic bulldozer removes oil rigs
|
||||
- Fix: [ 1012086 ] Drunk pilot (Celestar)
|
||||
- Fix: [ 1014278 ] TileAddWrap() gave wrong results.
|
||||
- Fix: [ 1016954 ] Cached_sprites does now work again
|
||||
- Fix: [ 1022689 ] Bug when dragging a part of a multiheaded engine to 'sell-whole-train'.
|
||||
- Fix: [ 1023971 ] Fix for MouseWheel assert error in non-zoomable viewports. Zooming now will only occur if mousepointer is either in an extra viewport window, or main game-window (Dribbel)
|
||||
- Fix: [ 1025836 ] Company value problem (again). Now company value rightly shows the value, including ALL your money.
|
||||
- Fix: [ 1025836 ] Company values bigger dan int32 were put to negative
|
||||
- Fix: [ 1025836 ] Long bridges had negative value
|
||||
- Fix: [ 1026271 ] Vehicle depots not transparent with transparent buildings.
|
||||
|
||||
|
||||
0.3.3 (2004-07-13)
|
||||
------------------------------------------------------------------------
|
||||
|
||||
- Feature: (MorphOS/AmigaOS) network support
|
||||
- Feature: improved german town name generator
|
||||
- Change: scenarios now have the file extension .scn
|
||||
- Fix: removing and upgrading tracks under a bridge when a train is on the bridge
|
||||
- Change: default network port from 12345 (known trojan) to 3979
|
||||
- Fix: pause button was not synched in network games
|
||||
- Fix: crash caused by invalid screen resolutions
|
||||
- Fix: AI can not build tubular bridges in 1950, etc. Same restrictions apply to it, as to human players.
|
||||
- Feature: transparent station signs
|
||||
- Feature: show total cargo per wagon type in train details window
|
||||
- Fix: volume, liters, was x100, should be x1000
|
||||
- Feature: bridges on slopes
|
||||
- Fix: bridge building by towns was screwed when executed without testing first
|
||||
- Feature: added Galician translation (by Condex)
|
||||
- Change: crossing tunnels is now considered a cheat
|
||||
- Fix: better AI route finding
|
||||
- Fix: AI builds less inner-city bus stations
|
||||
- Fix: Better industry spreading on random maps
|
||||
- Fix: Two industries that accept the same goods can never be very close to each other
|
||||
- Feature: Extra dynamite, allow the removal of town-owned roads, bridges, tunnels for a popularity rating penalty
|
||||
- Feature: magic bulldozer cheat, that lets you remove industries, unmovables and town-owned buildings, roads and bridges
|
||||
- Fix: destroying bridge (over water or 'higher bridge' with vehicle on it)
|
||||
- Fix Game crashes when you hit the build rail button
|
||||
- Fix: some scenarios had a max_railtype of 0
|
||||
- Fix: Bribe Autorithy. A failed attempt to bribe is now also stored in savegame
|
||||
- Fix: 80% CPU load paused in fast-forward
|
||||
- Feature: Enabled 'remove' button for stations
|
||||
- Feature: Cheat GUI (activate with crtl-alt-c) The game remembers if you have used a cheat
|
||||
- Fix: Some airport runways were treated
|
||||
- Fix: minor minimap glitch
|
||||
- Fix: station sorting scroll fails with not ennough stations
|
||||
- Fix: desert ground for depots in the desert
|
||||
- Feature: station sort implemented using qsort()
|
||||
- Feature: station list shows #of stations owned by player
|
||||
- Fix: trains could run on wrong track type under bridges
|
||||
- Fix: screenshot hangs
|
||||
- Feature: split canal/lock tool in two tools, one for building canals, one for locks.
|
||||
- Fix: wrong sound with ships
|
||||
- Fix: toy shop closes even though it has supply
|
||||
- Fix: nordic characters
|
||||
- Feature: make the HQ generate passengers and mail
|
||||
- Fix: slso restore Service Interval when rebuying vehicle
|
||||
- Fix: crash with map bits > 8
|
||||
- Fix: ufo crash in busstop
|
||||
- Fix: town actions has empty row
|
||||
- Change: made helicopters able to land on small airports again
|
||||
- Feature: display number of houses in town overview window
|
||||
- Fix: train stuck with the head in one depot and tail in another
|
||||
- Fix: Optimized random radio tower spreading
|
||||
- Feature: Land info now shows type of signal
|
||||
- Fix: ground below trees is sometimes not covered by snow
|
||||
- Fix: fast forward button in scenario editor
|
||||
- Change: screenshots are saved to PERSONAL_DIR (unix)
|
||||
- Fix: screenshot hotkey does not function in scenario editor
|
||||
- Fix: allow deleting a bridge if a vehicle is below
|
||||
- Fix: crash loading a scenario
|
||||
- Fix: build tracks on water
|
||||
- Fix: fast forward button pressed with tab
|
||||
- Fix: vehicles don't get old
|
||||
- Feature: realistic train reversing
|
||||
- Feature: added support for 64 bit CPUs
|
||||
- Fix: finance bug with some original scenarios
|
||||
- Feature: added water quantity level "very low", which is the default for easy mode now
|
||||
- Fix: 'Stopped' is shown when train is stopping and 'Reverse' is clicked
|
||||
- Feature: realistic acceleration turned on, train must first slow down and stop before it can reverse
|
||||
- Feature: (MorphOS build) various small improvement to make the the game feel more native
|
||||
- Feature: alt + f now toggles full screen (alt + enter still works)
|
||||
- Feature: (OSX build) command + q shows the quit window and command + f or enter toggles full screen (alt and control still works too)
|
||||
- Feature: pasky's autorenew, autorenews vehicles if enabled.
|
||||
- Feature: (incomplete) news history window
|
||||
- Feature: larger smallmap size
|
||||
- Feature: Austrian Citynames
|
||||
- Feature: repaying most possible debt
|
||||
- Feature: added Polish translation (by tomek)
|
||||
- Feature: added Danish translation (by Gof.dk)
|
||||
- Feature: pasky's grfspecial loader. You have to enable them in openttd.cfg using [newgrf] setting
|
||||
- Feature: smooth economy changes
|
||||
- Fix: 100% CPU bug
|
||||
- Fix: crash when AI builds airport
|
||||
- Fix: plays wrong music on main screen
|
||||
- Fix: inflation was way too high when intrest rate = 0
|
||||
- Fix: can't sell anything if money is TOO negative
|
||||
- Fix: fast forward button resets
|
||||
- Feature: TTDPatch-style gotodepot. Ship depots and aircraft hangars can be inserted in the schedule as well.
|
||||
- Feature: ability to add "service if needed" orders (the "full load" button changes to "service" after selecting a depot order)
|
||||
- Feature: if a vehicle has depot orders in its schedule, automatic servicing is disabled
|
||||
- Change: autosaves are now placed in save/autosave
|
||||
- Feature: patch setting so that helicopters get serviced automatically on helipad
|
||||
- Fix: "refit train" button remains
|
||||
- Change: default savegame directory is /save in Linux
|
||||
- Fix: enable up/down scrolling with the mouse
|
||||
- Feature: center toolbar on screen
|
||||
- Feature: sort savelist by date
|
||||
- Feature: allow scrolling in both directions
|
||||
- Feature: darkvater's two new airports (metropolitan in 1980 and international in 1990)
|
||||
- Feature: Resizing the window in all SDL builds
|
||||
- Fix: 1920 all trains
|
||||
- Fix: wrong heli breakdownspeed
|
||||
- Feature: added MIDI flag to makefile to set custom path to midi player
|
||||
- Fix: station list cargo waiting display bug
|
||||
- Fix: bug that could allow rails on steep slopes
|
||||
- Fix: train depots and checkpoints not flooded by water
|
||||
- Fix: added command line option (-i) to deactivate the grf check
|
||||
- Fix: signal bug [ 949929 ]
|
||||
|
||||
|
||||
0.3.2.1 (2004-05-23)
|
||||
- Fix: use english.lng by default
|
||||
- Fix: No bridges available in 1920
|
||||
- Fix: czech file was missing
|
||||
- Feature: now builds on FreeBSD
|
||||
- Feature: now builds on MorphOS
|
||||
|
||||
|
||||
0.3.2 (2004-05-22)
|
||||
- Feature: HP for trians limited to 16bit int
|
||||
- Feature: added Czech translation
|
||||
- Feature: train refitting
|
||||
- Feature: auto euro
|
||||
- Fix: don't allow building railroad stations on airports or bus stations
|
||||
- Feature: industry directory
|
||||
- Feature: added extend vehicle life/noexpire patch
|
||||
- Feature: show revision number in title bar
|
||||
- Fix: Enable mouse wheel scrolling and zooming in SDL
|
||||
- Fix: Construct industries producing raw materials
|
||||
- Fix: loading TTD saves gave incorrect reliability parameters for wagons
|
||||
- Feature: random network games
|
||||
- Fix: fixed order restore bug in network play
|
||||
- Fix: network sync fix for train goto depot
|
||||
- Feature: smallmap remembers size
|
||||
- Fix: Only one statue per player per town
|
||||
- Fix: enhanced patch configurator
|
||||
- Fix: if realistic acceleration was enabled, train didn't accelerate if they entered a tunnel right after a slope
|
||||
- Fix: remove sdl frameskip message
|
||||
- Fix: road vehicle on hills speedfix
|
||||
- Fix: CompanyValueGraph window too small for currency
|
||||
- Fix: mkdir() problem in unix.c
|
||||
- Fix: client kills server if it leaves a networkgame
|
||||
- Change: autosave go to autosave/
|
||||
- Fix: Canal tool resets after 1 use
|
||||
- Feature: remember value of show town names in smallmap
|
||||
- Feature: norwegian translation
|
||||
- Feature: norwegian currency
|
||||
- Feature: slovak language
|
||||
- Fix: smoother mouse cursor
|
||||
- Fix: fixed a couple of overlapping memcpys
|
||||
- Feature: use SO_REUSEADDR on listen socket
|
||||
- Feature: unix sigabort handling
|
||||
- Feature: hungarian translation
|
||||
- Fix: quit to beos
|
||||
- Fix: dragging to build canals sometimes crashed
|
||||
- Fix: cactus plants died on desert
|
||||
- Feature: added norwegian translation
|
||||
- Feature: added more default resolutions
|
||||
- Feature: return error message if DOS grf files are used
|
||||
- Feature: bemidi support
|
||||
- Fix: invalid letters in spanish town names
|
||||
- Fix: rail upgrade button
|
||||
- Fix: makefile reorganization
|
||||
- Fix: Zoom out button not grayed out
|
||||
- Fix: no space between some values and units
|
||||
- Change: Plant area of trees now allowed for 20x20 area
|
||||
- Change: "kmh^-1" to "km/h"
|
||||
- Fix: Station catchment outline-tiles weren't shown properly on slopes
|
||||
- Fix: oil rig station wasn't properly deleted
|
||||
- Fix: fixed making screenshots in scenario editor
|
||||
- Feature: added icelandic currency
|
||||
- Change: show original savegame names for oldstyle savegames
|
||||
- Fix: mac patches by bjarni
|
||||
- Fix: fixed alignment issue in station drawing
|
||||
|
||||
|
||||
0.3.1 (2004-04-26)
|
||||
- Fix: shift+arrows keys scrolls faster (by pasky)
|
||||
- Feature: bridge pillars for higher bridges
|
||||
- Fix: [ 941880 ] "monorail in 1985" which allowed you to build monorail/maglev at any year
|
||||
- Feature: remember cargo payment rates selection, default to all
|
||||
- Fix: town ratings when companies are deleted/merged
|
||||
- Fix: vehicle reliability calculation in third phase
|
||||
- Change: new directory structure (*.grf+sample.cat in data subdir, *.lng in lang subdir)
|
||||
- Feature: fast forward button
|
||||
- Fix: random world button in scenario editor doesn't build cities, industries, trees
|
||||
- Fix: loading worlds with no towns now fails
|
||||
- Fix: outdated sort order after station renaming
|
||||
- Feature: copy/share orders from trains in depot
|
||||
- Fix: better train detection for copy orders
|
||||
- Fix: [ 938481 ] Euro currency bug
|
||||
- Fix: [ 938170 ] Go to xxx road depot selection bug (2)
|
||||
- Fix: [ 934520 ] scrolling and newspaper in title screen
|
||||
- Feature: swedish translation (by poLiSen)
|
||||
- Fix: incorrect cargo_days for trains
|
||||
- Feature: dragging to construct canals
|
||||
- Fix array bounds error with train breakdown speeds
|
||||
- Fix: towns deleting random tiles around houses
|
||||
- Feature: can now have more than 128 towns
|
||||
- Fix: incorrect road vehicle list caption for competitors
|
||||
- Fix: vehicle menu graying after a bankrupty
|
||||
- Feature: always allow building small airports patch
|
||||
- Feature: colorful newspaper after a certain date
|
||||
- Feature: build while paused patch
|
||||
- Feature: polish town names
|
||||
- Fix: selective road removal
|
||||
- Feature: clear area now works in scenario editor
|
||||
- Feature: drag&drop stations
|
||||
- Fix: make houses available in 1920 to prevent hang
|
||||
- Fix: duration of breakdown smoke
|
||||
- Fix: slope bug under bridges
|
||||
- Feature: more realistic train starting and stopping
|
||||
- Fix: don't play invalid sounds (fixes road reconstruction crash)
|
||||
- Fix: display correct train power with multihead engines
|
||||
- Fix: buffer overflow caused by too long string in english.lng
|
||||
- Fix: destroying things with no money
|
||||
|
||||
0.3.0 (2004-04-14)
|
||||
- Change: don't slow down trains as much on hills
|
||||
- Fix: aircraft terminal wasn't properly freed if aircraft crashed
|
||||
- Fix: fixed station acceptance bug
|
||||
- Change: limit amount of radiotowers.
|
||||
- Feature: cost estimation with Shift
|
||||
- Change: changed speedkey from Shift to Tab.
|
||||
- Feature: added patch for starting_date, takes a value on the form yyyy, yyyymm or yyyymmdd.
|
||||
- Feature: support for multiheaded trains
|
||||
- Feature: sell whole train by dragging loco to special trashcan
|
||||
- Feature: drag the whole train with ctrl in depot
|
||||
- Fix: fixed buy shares in company
|
||||
- Feature: added convert rail tool
|
||||
- Change: enhanced patches window with pages.
|
||||
- Feature: patch to select what vehicle types the ai will build
|
||||
- Feature: better slope graphics
|
||||
- Fix: only deliver goods to stations that have a rating != 0
|
||||
- Feature: new pathfinding algorithm for trains (enable with new_pathfinding)
|
||||
- Change: changed intro graphics
|
||||
- Change: all player stuff is deleted when you load a scenario.
|
||||
- Fix: added F hotkeys in scenario editor
|
||||
- Feature: Added patch to use timidity for BeOS
|
||||
- Feature: mousewheel can now be used to scroll in windows
|
||||
- Feature: added coordinate display to landinfo window
|
||||
- Feature: change default servicing interval for vehicles
|
||||
- Feature: change max # of vehicles per player
|
||||
- Fix: unable to raise land next to signal
|
||||
- Feature: nonuniform stations patch
|
||||
- Feature: moved error message box out of the way
|
||||
- Fix: aircraft was shown instead of ships in player overview window
|
||||
- Feature: canals/shiplifts
|
||||
- Feature: build tree of random type
|
||||
- Feature: build trees on area
|
||||
- Feature: added color coded vehicle profits
|
||||
- Feature: ability to close error messages with space.
|
||||
- Fix: updated installer to take care of savegames more carefully
|
||||
- Fix: don't make a new subsidy if there already exists one that is currently active by a company
|
||||
- Fix: town directory sometimes showed huge numbers
|
||||
- Fix: fixed bugs when changing owners of items (pieces of rail were not always deleted),
|
||||
- Feature: network games (currently unsupported)
|
||||
- Fix: fixed bug with large stations in train pathfinder
|
||||
- Change: use save/ as save folder on win32
|
||||
- Feature: bigger demolish tool
|
||||
- Change: moved date in news window
|
||||
- Feature: two more bridges
|
||||
- Feature: improved depot finding
|
||||
- Feature: bribe the town authority
|
||||
- Feature: allow building many trees on a single tile.
|
||||
- Feature: added snow_line_height setting, only affects new games.
|
||||
- Change: don't check if tiles around the clicked station is a station in order gui
|
||||
- Fix: deleting docks doesn't produce land
|
||||
- Fix: deleting ship depot doesn't produce land
|
||||
- Fix: buoy is now treated as water when flooding
|
||||
- Feature: errmsg_duration controls how long error messages are displayed
|
||||
- Fix: combo presignals bug fix
|
||||
- Fix: prevent going to 0,0 if airport/docks is deleted
|
||||
- Feature: fullscreen_bpp setting in [win32] sets the bpp to use in fullscreen mode
|
||||
- Fix: french town names had bad letters in them
|
||||
- Feature: euro symbol
|
||||
- Feature: high bridges
|
||||
- Fix: order list when replacing train didn't work properly
|
||||
- Change: keep checkpoint button down after placing
|
||||
- Fix: start in the middle of the map
|
||||
- Change: moved disk devices to bottom of list on win32
|
||||
- Fix: more error tolerant saveload code
|
||||
- Feature: ZLIB savegames (smaller than before)
|
||||
- Feature: PNG,PCX screenshot support
|
||||
- Feature: indicate with gray in vehicle popup menus if company has no vehicles of that type
|
||||
- Feature: clicking on the money brings up finances
|
||||
- Fix: (OSX build) now runs even if sdl is not present on the system
|
||||
- Fix: (OSX build) now runs on systems older than 10.3
|
||||
- Fix: (OSX build) altered compiler settings to make a completely stable app
|
||||
- Feature: (OSX build) distribution now uses Apples package system for easier updates
|
||||
- Feature: (OSX build) Application is now a proper bundle application
|
||||
|
||||
0.2.1 (2004-04-04)
|
||||
- Fix: copy orders crashed if you clicked on a wagon
|
||||
- Feature: 'A' hotkey now always opens autorail
|
||||
- Change: Moved autorail button
|
||||
- Feature: X can be used to toggle transparent buildings
|
||||
- Fix: don't show transparent buildings in intro
|
||||
- Fix: installer doesn't delete savegames
|
||||
- Feature: Hotkeys 1-9 can be used to build a bridge in the bridge window
|
||||
- Feature: Added more hotkeys in the road build window
|
||||
|
||||
0.2 (2004-04-03)
|
||||
|
||||
- Feature: autoscroll (only works to left/right)
|
||||
- Feature: train checkpoints, instead of ttdpatch's nonstop handling
|
||||
- Feature: ttdpatch compatible nonstop handling
|
||||
- Fix: news window was moved strangely when resizing
|
||||
- Fix: fixed sign drawing bug in max zoom out mode
|
||||
- Feature: refresh rate configuration setting
|
||||
- Feature: town directory sorting options
|
||||
- Feature: pre-signals (ctrl-click on existing signals to change signal type)
|
||||
- Feature: show semaphores on the right side if right-sided traffic
|
||||
- Improvement: increased number of windows on screen to 20
|
||||
- Feature: patch options configuration window
|
||||
- Fix: road vehicles sometimes getting stuck
|
||||
- Feature: autorail build tool
|
||||
- Feature: "show yearly finances window" option
|
||||
- Feature: "signals on drive side" patch (by Michael Polnick)
|
||||
- Fix: connecting tracks behind depot causing incorrect signal behavior
|
||||
- Fix: save/load diskspace bug
|
||||
- Feature: "show full date in statusbar" option
|
||||
- Feature: italian translation (by duepixel)
|
||||
- Feature: road and rail removal by dragging a selection
|
||||
- Feature: news item for "train is unprofitable"
|
||||
- Feature: news item for "train is lost"
|
||||
- Feature: (win32 build) double size mode (ctrl-d to toggle)
|
||||
- Fix: incorrect bridge cost for long bridges
|
||||
- Feature: "multiple similar industries in close proximity" option
|
||||
- Feature: "multiple industries per down" option
|
||||
- Feature: "crossing tunnels" option
|
||||
- Feature: order sharing and copying ("goto" on other vehicle to copy, ctrl+"goto" to share)
|
||||
- Feature: remember last built rail type
|
||||
- Feature: "debtmax" faster loan management with ctrl key
|
||||
- Fix: disallow buoy in north corner
|
||||
- Feature: "go to depot" orders option
|
||||
- Feature: "long bridges" option
|
||||
- Feature: "select goods" option
|
||||
- Feature: "no train service" option
|
||||
- Feature: "no inflation" option
|
||||
- Improvement: (OSX build) now starts when doubleclicked
|
||||
- Improvement: (OSX build) significant performance increase
|
||||
- Improvement: optimized startup time
|
||||
- Feature: automatically detect available resolutions
|
||||
- Feature: "full load any" option, as in ttdpatch
|
||||
- Feature: automatic detection of available language files
|
||||
- Feature: German translation (by truesatan and wuntvor)
|
||||
- Improvement: sorted savegame list
|
||||
- Feature: finnish town names (by Jpl)
|
||||
- Feature: remember custom difficulty settings
|
||||
- Fix: shift key now increases game speed only when game window is active
|
||||
- Fix: ctrl button now works with SDL driver
|
||||
- Feature: configuration file system
|
||||
- Feature: show vehicle speed in vehicle view windows
|
||||
- Fix: incorrect weight displayed in "new trains" window
|
||||
- Feature: train depot window now has horizontal scrollbar
|
||||
- Feature: mammoth trains
|
||||
- Fix: incorrect train running cost in newspaper
|
||||
- Feature: on-the-fly language selection
|
||||
- Feature: load old premade ttd maps (must be renamed to .sv1 extension)
|
||||
|
||||
0.1.4
|
||||
|
||||
- Feature: crash submit system on win32
|
||||
- Fix: train smoke clouds
|
||||
- Fix: train engine sounds
|
||||
- Fix: play all sounds at 11025 hz (fixes certain sounds)
|
||||
- Feature: autosave
|
||||
- Fix: scenario editor desert button now makes desert instead of lighthouse
|
||||
- Fix: creating random town in scenario editor crash
|
||||
- Fix: candy bubbles sometimes caused crash
|
||||
- Fix: wrong speed was shown in news window for some vehicles
|
||||
- Fix: graph color bleeding
|
||||
- Feature: build on coasts
|
||||
- Feature: Allow building transmitters, lighthouses and company headquarters on slopes
|
||||
- Feature: now builds on MacOSX
|
||||
- Fix: arrow keys with SDL driver
|
||||
- Change: new savegame format
|
||||
- Change: new format for english.lng
|
||||
- Fix: don't allow trains to road depots
|
||||
- Fix: road vehicle was sometimes shown inside depot
|
||||
- Fix: arrow keys in sdl driver were wrong
|
||||
- Fix: endianness bugs in save/load
|
||||
- Fix: now builds on FreeBSD
|
||||
- Fix: screenshot feature now works
|
||||
- Fix: rail foundations sometimes displayed unnecessarily
|
||||
- Fix: minor AI bugs
|
||||
- Fix: fixed industry sounds
|
||||
- Feature: in-game resolution selection via settings window
|
||||
- Feature: Dutch town names
|
||||
- Feature: Added load game menu item
|
||||
- Fix: bug where ship depots were very expensive
|
||||
- Fix: BeOS build (by MYOB)
|
||||
- Fix: yearly expenses data being the same for the past two game years
|
||||
- Fix: adding songs to playlists other than custom1 and custom2
|
||||
- Fix: first and last tracks playing the wrong music
|
||||
- Fix: Palette animation for SDL video (rob)
|
||||
- Fix: Get remaining disk space on most Unix-en (rob)
|
||||
- Fix: screen went black when resizing
|
||||
|
||||
0.1.3
|
||||
|
||||
- Fixed message options window
|
||||
- Fixed company takeover/purchase
|
||||
- Feature: Improved mouse scroll zooming
|
||||
- Fixed station code so it's not possible to steal another player's temporarily deleted station
|
||||
- Fixed subsidy owner bug when deleting station
|
||||
- Fixed crash when deleting a bridge with a train on it
|
||||
- Feature: Larger stations and possibility to join stations
|
||||
- Fixed missing candy initial cargo payment values
|
||||
- Fixed Goods and Food/FizzyDrinks subsidies
|
||||
- Fixed graphical glitch in subsidies window
|
||||
- Take over company dialog was not shown properly
|
||||
- Fixed crash if player windows were open while the company went bankrupt
|
||||
- Fixed train slowness on hills
|
||||
- Feature: swedish town names (patch by glottis)
|
||||
- Feature: more currencies
|
||||
- Better window resizing/zooming
|
||||
- Added goto road vehicle depot for road vehicle orders
|
||||
- Possibility to use either semaphores or signals (Ctrl key)
|
||||
- Limited the scrolling rate for year selector in scenario editor
|
||||
|
||||
0.1.2
|
||||
|
||||
- Mouse wheel can be used to zoom in out on win32 (ludde)
|
||||
- Implemented some support for resizing the window dynamically in win32 (ludde)
|
||||
- Fixed tunnel mouse icon for maglev and monorail
|
||||
|
||||
0.1.1
|
||||
|
||||
- Preliminary presignal support
|
||||
- Added external MIDI driver for unix version (by robertnorris)
|
||||
- Added DirectMusic driver for Win32 version
|
||||
- Fixed problem where directories weren't displayed under Linux (by Markus)
|
||||
- Center windows properly in higher resolutions
|
||||
- Added "build tracks on slopes" feature
|
||||
- Fixed colors in map window for routes
|
||||
- Command line -g flag now optionally takes a game to load
|
||||
- Fixed road drive side
|
||||
- Fixed "Fund road construction" not clickable when unavailable
|
|
@ -1,812 +0,0 @@
|
|||
#include "stdafx.h"
|
||||
#include "ttd.h"
|
||||
#include "viewport.h"
|
||||
#include "command.h"
|
||||
|
||||
typedef struct TerraformerHeightMod {
|
||||
TileIndex tile;
|
||||
byte height;
|
||||
} TerraformerHeightMod;
|
||||
|
||||
typedef struct TerraformerState {
|
||||
int height[4];
|
||||
uint32 flags;
|
||||
|
||||
int direction;
|
||||
int modheight_count;
|
||||
int tile_table_count;
|
||||
|
||||
int32 cost;
|
||||
|
||||
TileIndex *tile_table;
|
||||
TerraformerHeightMod *modheight;
|
||||
|
||||
} TerraformerState;
|
||||
|
||||
static int TerraformAllowTileProcess(TerraformerState *ts, TileIndex tile)
|
||||
{
|
||||
TileIndex *t;
|
||||
int count;
|
||||
|
||||
if ((GET_TILE_X(tile) == TILE_X_MAX) || (GET_TILE_Y(tile) == TILE_Y_MAX))
|
||||
return -1;
|
||||
|
||||
t = ts->tile_table;
|
||||
for(count = ts->tile_table_count; count != 0; count--,t++) {
|
||||
if (*t == tile)
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int TerraformGetHeightOfTile(TerraformerState *ts, TileIndex tile)
|
||||
{
|
||||
TerraformerHeightMod *mod = ts->modheight;
|
||||
int count;
|
||||
|
||||
for(count = ts->modheight_count; count != 0; count--, mod++) {
|
||||
if (mod->tile == tile)
|
||||
return mod->height;
|
||||
}
|
||||
|
||||
return _map_type_and_height[tile] & 0xF;
|
||||
}
|
||||
|
||||
static void TerraformAddDirtyTile(TerraformerState *ts, TileIndex tile)
|
||||
{
|
||||
int count;
|
||||
TileIndex *t;
|
||||
|
||||
count = ts->tile_table_count;
|
||||
|
||||
if (count >= 625)
|
||||
return;
|
||||
|
||||
for(t = ts->tile_table; count != 0; count--,t++) {
|
||||
if (*t == tile)
|
||||
return;
|
||||
}
|
||||
|
||||
ts->tile_table[ts->tile_table_count++] = tile;
|
||||
}
|
||||
|
||||
static void TerraformAddDirtyTileAround(TerraformerState *ts, TileIndex tile)
|
||||
{
|
||||
TerraformAddDirtyTile(ts, tile+TILE_XY(0,-1));
|
||||
TerraformAddDirtyTile(ts, tile+TILE_XY(-1,-1));
|
||||
TerraformAddDirtyTile(ts, tile+TILE_XY(-1,0));
|
||||
TerraformAddDirtyTile(ts, tile);
|
||||
}
|
||||
|
||||
static int TerraformProc(TerraformerState *ts, uint tile, int mode)
|
||||
{
|
||||
int r;
|
||||
int32 ret;
|
||||
|
||||
assert(tile < TILES_X * TILES_Y);
|
||||
|
||||
if ((r=TerraformAllowTileProcess(ts, tile)) <= 0)
|
||||
return r;
|
||||
|
||||
if ((_map_type_and_height[tile] >> 4) == MP_RAILWAY) {
|
||||
static const byte _railway_modes[4] = {8, 0x10, 4, 0x20};
|
||||
static const byte _railway_dangslopes[4] = {0xd, 0xe, 7, 0xb};
|
||||
|
||||
// Nothing could be built at the steep slope - this avoids a bug
|
||||
// when you have a single diagonal track in one corner on a
|
||||
// basement and then you raise the other corner.
|
||||
if ((GetTileSlope(tile, NULL)&0xF) == _railway_dangslopes[mode]) {
|
||||
_error_message = STR_1008_MUST_REMOVE_RAILROAD_TRACK;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// If we have a single diagonal track there, the other side of
|
||||
// tile can be terraformed.
|
||||
if ((_map5[tile]&~0x40) == _railway_modes[mode])
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = DoCommandByTile(tile, 0,0, ts->flags & ~DC_EXEC, CMD_LANDSCAPE_CLEAR);
|
||||
|
||||
if (ret == CMD_ERROR) {
|
||||
_terraform_err_tile = tile;
|
||||
return -1;
|
||||
}
|
||||
|
||||
ts->cost += ret;
|
||||
|
||||
if (ts->tile_table_count >= 625)
|
||||
return -1;
|
||||
ts->tile_table[ts->tile_table_count++] = tile;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool TerraformTileHeight(TerraformerState *ts, uint tile, int height)
|
||||
{
|
||||
int nh;
|
||||
TerraformerHeightMod *mod;
|
||||
int count;
|
||||
|
||||
assert(tile < TILES_X * TILES_Y);
|
||||
|
||||
if (height < 0) {
|
||||
_error_message = STR_1003_ALREADY_AT_SEA_LEVEL;
|
||||
return false;
|
||||
}
|
||||
|
||||
_error_message = STR_1004_TOO_HIGH;
|
||||
|
||||
if (height > 0xF)
|
||||
return false;
|
||||
|
||||
nh = TerraformGetHeightOfTile(ts, tile);
|
||||
if (nh < 0 || height == nh)
|
||||
return false;
|
||||
|
||||
if (TerraformProc(ts, tile, 0)<0)
|
||||
return false;
|
||||
|
||||
if (TerraformProc(ts, tile + TILE_XY(0,-1), 1)<0)
|
||||
return false;
|
||||
|
||||
if (TerraformProc(ts, tile + TILE_XY(-1,-1), 2)<0)
|
||||
return false;
|
||||
|
||||
if (TerraformProc(ts, tile + TILE_XY(-1,0), 3)<0)
|
||||
return false;
|
||||
|
||||
mod = ts->modheight;
|
||||
count = ts->modheight_count;
|
||||
|
||||
for(;;) {
|
||||
if (count == 0) {
|
||||
if (ts->modheight_count >= 576)
|
||||
return false;
|
||||
ts->modheight_count++;
|
||||
break;
|
||||
}
|
||||
if (mod->tile == (TileIndex)tile)
|
||||
break;
|
||||
mod++;
|
||||
count--;
|
||||
}
|
||||
|
||||
mod->tile = (TileIndex)tile;
|
||||
mod->height = (byte)height;
|
||||
|
||||
ts->cost += _price.terraform;
|
||||
|
||||
{
|
||||
int direction = ts->direction, r;
|
||||
const TileIndexDiff *ttm;
|
||||
|
||||
static const TileIndexDiff _terraform_tilepos[5] = {TILE_XY(1,0), TILE_XY(-2,0), TILE_XY(1,1), TILE_XY(0,-2), 0 };
|
||||
|
||||
for(ttm = _terraform_tilepos; *ttm != 0; ttm++) {
|
||||
tile += *ttm;
|
||||
|
||||
r = TerraformGetHeightOfTile(ts, tile);
|
||||
if (r != height && r-direction != height && r+direction != height) {
|
||||
if (!TerraformTileHeight(ts, tile, r+direction))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Terraform land
|
||||
* p1 - corners
|
||||
* p2 - direction
|
||||
*/
|
||||
|
||||
int32 CmdTerraformLand(int x, int y, uint32 flags, uint32 p1, uint32 p2)
|
||||
{
|
||||
TerraformerState ts;
|
||||
uint tile;
|
||||
int direction;
|
||||
|
||||
TerraformerHeightMod modheight_data[576];
|
||||
TileIndex tile_table_data[625];
|
||||
|
||||
SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
|
||||
|
||||
_error_message = INVALID_STRING_ID;
|
||||
_terraform_err_tile = 0;
|
||||
|
||||
ts.direction = direction = p2 ? 1 : -1;
|
||||
ts.flags = flags;
|
||||
ts.modheight_count = ts.tile_table_count = 0;
|
||||
ts.cost = 0;
|
||||
ts.modheight = modheight_data;
|
||||
ts.tile_table = tile_table_data;
|
||||
|
||||
tile = TILE_FROM_XY(x,y);
|
||||
|
||||
if (p1 & 1) {
|
||||
if (!TerraformTileHeight(&ts, tile+TILE_XY(1,0),
|
||||
(_map_type_and_height[tile+TILE_XY(1,0)]&0xF) + direction))
|
||||
return CMD_ERROR;
|
||||
}
|
||||
|
||||
if (p1 & 2) {
|
||||
if (!TerraformTileHeight(&ts, tile+TILE_XY(1,1),
|
||||
(_map_type_and_height[tile+TILE_XY(1,1)]&0xF) + direction))
|
||||
return CMD_ERROR;
|
||||
}
|
||||
|
||||
if (p1 & 4) {
|
||||
if (!TerraformTileHeight(&ts, tile+TILE_XY(0,1),
|
||||
(_map_type_and_height[tile+TILE_XY(0,1)]&0xF) + direction))
|
||||
return CMD_ERROR;
|
||||
}
|
||||
|
||||
if (p1 & 8) {
|
||||
if (!TerraformTileHeight(&ts, tile+TILE_XY(0,0),
|
||||
(_map_type_and_height[tile+TILE_XY(0,0)]&0xF) + direction))
|
||||
return CMD_ERROR;
|
||||
}
|
||||
|
||||
if (direction == -1) {
|
||||
/* Check if tunnel would take damage */
|
||||
int count;
|
||||
TileIndex *ti = ts.tile_table;
|
||||
|
||||
for(count = ts.tile_table_count; count != 0; count--, ti++) {
|
||||
uint z, t;
|
||||
uint tile = *ti;
|
||||
|
||||
z = TerraformGetHeightOfTile(&ts, tile + TILE_XY(0,0));
|
||||
t = TerraformGetHeightOfTile(&ts, tile + TILE_XY(1,0));
|
||||
if (t <= z) z = t;
|
||||
t = TerraformGetHeightOfTile(&ts, tile + TILE_XY(1,1));
|
||||
if (t <= z) z = t;
|
||||
t = TerraformGetHeightOfTile(&ts, tile + TILE_XY(0,1));
|
||||
if (t <= z) z = t;
|
||||
|
||||
if (!CheckTunnelInWay(tile, z*8))
|
||||
return_cmd_error(STR_1002_EXCAVATION_WOULD_DAMAGE);
|
||||
}
|
||||
}
|
||||
|
||||
if (flags & DC_EXEC) {
|
||||
/* Clear the landscape at the tiles */
|
||||
{
|
||||
int count;
|
||||
TileIndex *ti = ts.tile_table;
|
||||
for(count = ts.tile_table_count; count != 0; count--, ti++) {
|
||||
DoCommandByTile(*ti, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
|
||||
}
|
||||
}
|
||||
|
||||
/* change the height */
|
||||
{
|
||||
int count;
|
||||
TerraformerHeightMod *mod;
|
||||
uint til;
|
||||
|
||||
mod = ts.modheight;
|
||||
for(count = ts.modheight_count; count != 0; count--, mod++) {
|
||||
til = mod->tile;
|
||||
|
||||
// Change tile height
|
||||
_map_type_and_height[til] = (_map_type_and_height[til]&~0x0F)|mod->height;
|
||||
|
||||
TerraformAddDirtyTileAround(&ts, til);
|
||||
}
|
||||
}
|
||||
|
||||
/* finally mark the dirty tiles dirty */
|
||||
{
|
||||
int count;
|
||||
TileIndex *ti = ts.tile_table;
|
||||
for(count = ts.tile_table_count; count != 0; count--, ti++) {
|
||||
MarkTileDirtyByTile(*ti);
|
||||
}
|
||||
}
|
||||
}
|
||||
return ts.cost;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* p1 - start
|
||||
*/
|
||||
|
||||
int32 CmdLevelLand(int ex, int ey, uint32 flags, uint32 p1, uint32 p2)
|
||||
{
|
||||
int size_x, size_y;
|
||||
int sx, sy;
|
||||
uint h, curh;
|
||||
uint tile;
|
||||
int32 ret, cost, money;
|
||||
|
||||
// remember level height
|
||||
h = _map_type_and_height[p1]&0xF;
|
||||
|
||||
ex >>= 4; ey >>= 4;
|
||||
|
||||
// make sure sx,sy are smaller than ex,ey
|
||||
sx = GET_TILE_X(p1);
|
||||
sy = GET_TILE_Y(p1);
|
||||
if (ex < sx) intswap(ex, sx);
|
||||
if (ey < sy) intswap(ey, sy);
|
||||
tile = TILE_XY(sx,sy);
|
||||
|
||||
size_x = ex-sx+1;
|
||||
size_y = ey-sy+1;
|
||||
|
||||
money = GetAvailableMoneyForCommand();
|
||||
cost = 0;
|
||||
|
||||
BEGIN_TILE_LOOP(tile2, size_x, size_y, tile)
|
||||
curh = _map_type_and_height[tile2]&0xF;
|
||||
while (curh != h) {
|
||||
ret = DoCommandByTile(tile2, 8, (curh > h)?0:1, flags & ~DC_EXEC, CMD_TERRAFORM_LAND);
|
||||
if (ret == CMD_ERROR) break;
|
||||
cost += ret;
|
||||
|
||||
if (flags & DC_EXEC) {
|
||||
if ((money -= ret) < 0) {
|
||||
_additional_cash_required = ret;
|
||||
return cost - ret;
|
||||
}
|
||||
DoCommandByTile(tile2, 8, (curh > h)?0:1, flags, CMD_TERRAFORM_LAND);
|
||||
}
|
||||
|
||||
curh += (curh > h) ? -1 : 1;
|
||||
}
|
||||
END_TILE_LOOP(tile2, size_x, size_y, tile)
|
||||
|
||||
if (cost == 0) return CMD_ERROR;
|
||||
return cost;
|
||||
}
|
||||
|
||||
/* Purchase a land area
|
||||
* p1 = unused
|
||||
* p2 = unused
|
||||
*/
|
||||
|
||||
int32 CmdPurchaseLandArea(int x, int y, uint32 flags, uint32 p1, uint32 p2)
|
||||
{
|
||||
uint tile;
|
||||
int32 cost;
|
||||
|
||||
SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
|
||||
|
||||
tile = TILE_FROM_XY(x,y);
|
||||
|
||||
if (!EnsureNoVehicle(tile))
|
||||
return CMD_ERROR;
|
||||
|
||||
if (IS_TILETYPE(tile, MP_UNMOVABLE) &&
|
||||
_map5[tile] == 3 &&
|
||||
_map_owner[tile] == _current_player)
|
||||
return_cmd_error(STR_5807_YOU_ALREADY_OWN_IT);
|
||||
|
||||
cost = DoCommandByTile(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
|
||||
if (cost == CMD_ERROR)
|
||||
return CMD_ERROR;
|
||||
|
||||
if (flags & DC_EXEC) {
|
||||
ModifyTile(tile,
|
||||
MP_SETTYPE(MP_UNMOVABLE) | MP_MAPOWNER_CURRENT | MP_MAP5,
|
||||
3 /* map5 */
|
||||
);
|
||||
}
|
||||
|
||||
return cost + _price.purchase_land * 10;
|
||||
}
|
||||
|
||||
|
||||
int32 ClearTile_Clear(uint tile, byte flags) {
|
||||
static const int32 * _clear_price_table[] = {
|
||||
NULL,
|
||||
&_price.clear_1, &_price.clear_1,&_price.clear_1,
|
||||
&_price.purchase_land,&_price.purchase_land,&_price.purchase_land,&_price.purchase_land,
|
||||
&_price.clear_2,&_price.clear_2,&_price.clear_2,&_price.clear_2,
|
||||
&_price.clear_3,&_price.clear_3,&_price.clear_3,&_price.clear_3,
|
||||
&_price.purchase_land,&_price.purchase_land,&_price.purchase_land,&_price.purchase_land,
|
||||
&_price.purchase_land,&_price.purchase_land,&_price.purchase_land,&_price.purchase_land,
|
||||
&_price.clear_2,&_price.clear_2,&_price.clear_2,&_price.clear_2,
|
||||
};
|
||||
const int32 *price = _clear_price_table[_map5[tile] & 0x1F];
|
||||
|
||||
if (flags & DC_EXEC)
|
||||
DoClearSquare(tile);
|
||||
|
||||
if (price == NULL)
|
||||
return 0;
|
||||
return *price;
|
||||
}
|
||||
|
||||
int32 CmdSellLandArea(int x, int y, uint32 flags, uint32 p1, uint32 p2)
|
||||
{
|
||||
uint tile;
|
||||
|
||||
SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
|
||||
|
||||
tile = TILE_FROM_XY(x,y);
|
||||
|
||||
if (!CheckTileOwnership(tile) && _current_player != OWNER_WATER)
|
||||
return CMD_ERROR;
|
||||
|
||||
if (!EnsureNoVehicle(tile))
|
||||
return CMD_ERROR;
|
||||
|
||||
if (flags & DC_EXEC)
|
||||
DoClearSquare(tile);
|
||||
|
||||
return - _price.purchase_land*2;
|
||||
}
|
||||
|
||||
|
||||
#include "table/clear_land.h"
|
||||
|
||||
|
||||
void DrawClearLandTile(TileInfo *ti, byte set)
|
||||
{
|
||||
DrawGroundSprite(0xF54 + _tileh_to_sprite[ti->tileh] + set * 19);
|
||||
}
|
||||
|
||||
void DrawHillyLandTile(TileInfo *ti)
|
||||
{
|
||||
if (ti->tileh != 0) {
|
||||
DrawGroundSprite(0xFA0 + _tileh_to_sprite[ti->tileh]);
|
||||
} else {
|
||||
DrawGroundSprite(_landscape_clear_sprites[((ti->x^ti->y) >> 4) & 0x7]);
|
||||
}
|
||||
}
|
||||
|
||||
void DrawClearLandFence(TileInfo *ti, byte img)
|
||||
{
|
||||
byte z = ti->z;
|
||||
|
||||
if (ti->tileh & 2) {
|
||||
z += 8;
|
||||
if (ti->tileh == 0x17)
|
||||
z += 8;
|
||||
}
|
||||
|
||||
if (img & 0x38) {
|
||||
DrawGroundSpriteAt(_clear_land_fence_sprites_1[((img >> 3) & 7) - 1] + _fence_mod_by_tileh[ti->tileh], ti->x, ti->y, z);
|
||||
}
|
||||
|
||||
if (img & 0x7) {
|
||||
DrawGroundSpriteAt(_clear_land_fence_sprites_1[(img & 7) - 1] + _fence_mod_by_tileh_2[ti->tileh], ti->x, ti->y, z);
|
||||
}
|
||||
}
|
||||
|
||||
static void DrawTile_Clear(TileInfo *ti)
|
||||
{
|
||||
|
||||
switch((ti->map5 & (7<<2)) >> 2) {
|
||||
case 0:
|
||||
DrawClearLandTile(ti, (ti->map5 & 3));
|
||||
break;
|
||||
|
||||
case 1:
|
||||
DrawHillyLandTile(ti);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
DrawGroundSprite(0xFB7 + _tileh_to_sprite[ti->tileh]);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
DrawGroundSprite( _clear_land_sprites_1[_map3_lo[ti->tile]&0xF] + _tileh_to_sprite[ti->tileh]);
|
||||
break;
|
||||
|
||||
case 4:
|
||||
DrawGroundSprite( _clear_land_sprites_2[ti->map5&3] + _tileh_to_sprite[ti->tileh]);
|
||||
break;
|
||||
|
||||
case 5:
|
||||
DrawGroundSprite( _clear_land_sprites_3[ti->map5&3] + _tileh_to_sprite[ti->tileh]);
|
||||
break;
|
||||
}
|
||||
|
||||
DrawClearLandFence(ti, _map3_hi[ti->tile] >> 2);
|
||||
}
|
||||
|
||||
uint GetSlopeZ_Clear(TileInfo *ti) { return GetPartialZ(ti->x&0xF, ti->y&0xF, ti->tileh) + ti->z; }
|
||||
|
||||
uint GetSlopeTileh_Clear(TileInfo *ti)
|
||||
{
|
||||
return ti->tileh;
|
||||
}
|
||||
|
||||
static void GetAcceptedCargo_Clear(uint tile, AcceptedCargo *ac)
|
||||
{
|
||||
/* unused */
|
||||
}
|
||||
|
||||
static void AnimateTile_Clear(uint tile)
|
||||
{
|
||||
/* unused */
|
||||
}
|
||||
|
||||
void TileLoopClearHelper(uint tile)
|
||||
{
|
||||
byte img_1, img_2;
|
||||
static byte img_by_map5[8] = { 0,0,0,2, 1,1,0,0, };
|
||||
uint dirty = -1;
|
||||
|
||||
img_1 = 0;
|
||||
if (IS_TILETYPE(tile, MP_CLEAR)) {
|
||||
img_1 = img_by_map5[(_map5[tile] & 0x1C) >> 2];
|
||||
} else if (IS_TILETYPE(tile, MP_TREES) && (_map2[tile] & 0x30) == 0x20) {
|
||||
img_1 = 1;
|
||||
}
|
||||
|
||||
img_2 = 0;
|
||||
if (IS_TILETYPE(TILE_ADDXY(tile, 1, 0), MP_CLEAR)) {
|
||||
img_2 = img_by_map5[(_map5[TILE_ADDXY(tile, 1, 0)] & 0x1C) >> 2];
|
||||
} else if (IS_TILETYPE(TILE_ADDXY(tile, 1, 0), MP_TREES) && (_map2[TILE_ADDXY(tile, 1, 0)] & 0x30) == 0x20) {
|
||||
img_2 = 1;
|
||||
}
|
||||
|
||||
if (!(_map3_hi[tile] & 0xE0)) {
|
||||
if ( (img_1&2) != (img_2&2) ) {
|
||||
_map3_hi[tile] |= 3 << 5;
|
||||
dirty = tile;
|
||||
}
|
||||
} else {
|
||||
if (img_1 == 1 && img_2 == 1) {
|
||||
_map3_hi[tile] &= ~(3 << 5);
|
||||
dirty = tile;
|
||||
}
|
||||
}
|
||||
|
||||
img_2 = 0;
|
||||
if (IS_TILETYPE(TILE_ADDXY(tile, 0, 1), MP_CLEAR)) {
|
||||
img_2 = img_by_map5[(_map5[TILE_ADDXY(tile, 0, 1)] & 0x1C) >> 2];
|
||||
} else if (IS_TILETYPE(TILE_ADDXY(tile, 0, 1), MP_TREES) && (_map2[TILE_ADDXY(tile, 0, 1)] & 0x30) == 0x20) {
|
||||
img_2 = 1;
|
||||
}
|
||||
|
||||
if (!(_map3_hi[tile] & 0x1C)) {
|
||||
if ( (img_1&2) != (img_2&2) ) {
|
||||
_map3_hi[tile] |= 3 << 2;
|
||||
dirty = tile;
|
||||
}
|
||||
} else {
|
||||
if (img_1 == 1 && img_2 == 1) {
|
||||
_map3_hi[tile] &= ~(3 << 2);
|
||||
dirty = tile;
|
||||
}
|
||||
}
|
||||
|
||||
if (dirty != -1)
|
||||
MarkTileDirtyByTile(dirty);
|
||||
}
|
||||
|
||||
|
||||
/* convert into snowy tiles */
|
||||
static void TileLoopClearAlps(uint tile)
|
||||
{
|
||||
int k;
|
||||
byte m5,tmp;
|
||||
|
||||
/* distance from snow line, in steps of 8 */
|
||||
k = GetTileZ(tile) - _opt.snow_line;
|
||||
|
||||
m5 = _map5[tile] & 0x1C;
|
||||
tmp = _map5[tile] & 3;
|
||||
|
||||
if (k < -8) {
|
||||
/* snow_m2_down */
|
||||
if (m5 != 0x10)
|
||||
return;
|
||||
if (tmp == 0)
|
||||
m5 = 3;
|
||||
} else if (k == -8) {
|
||||
/* snow_m1 */
|
||||
if (m5 != 0x10) {
|
||||
m5 = 0x10;
|
||||
} else if (tmp != 0) {
|
||||
m5 = (tmp - 1) + 0x10;
|
||||
} else
|
||||
return;
|
||||
} else if (k < 8) {
|
||||
/* snow_0 */
|
||||
if (m5 != 0x10) {
|
||||
m5 = 0x10;
|
||||
} else if (tmp != 1) {
|
||||
m5 = 1;
|
||||
if (tmp != 0)
|
||||
m5 = tmp - 1;
|
||||
m5 += 0x10;
|
||||
} else
|
||||
return;
|
||||
} else if (k == 8) {
|
||||
/* snow_p1 */
|
||||
if (m5 != 0x10) {
|
||||
m5 = 0x10;
|
||||
} else if (tmp != 2) {
|
||||
m5 = 2;
|
||||
if (tmp <= 2)
|
||||
m5 = tmp + 1;
|
||||
m5 += 0x10;
|
||||
} else
|
||||
return;
|
||||
} else {
|
||||
/* snow_p2_up */
|
||||
if (m5 != 0x10) {
|
||||
m5 = 0x10;
|
||||
} else if (tmp != 3) {
|
||||
m5 = tmp + 1 + 0x10;
|
||||
} else
|
||||
return;
|
||||
}
|
||||
|
||||
_map5[tile] = m5;
|
||||
MarkTileDirtyByTile(tile);
|
||||
}
|
||||
|
||||
static void TileLoopClearDesert(uint tile)
|
||||
{
|
||||
if ( (_map5[tile] & 0x1C) == 0x14)
|
||||
return;
|
||||
|
||||
if (GetMapExtraBits(tile) == 1) {
|
||||
_map5[tile] = 0x17;
|
||||
} else {
|
||||
if (GetMapExtraBits(tile+TILE_XY(1,0)) != 1 &&
|
||||
GetMapExtraBits(tile+TILE_XY(-1,0)) != 1 &&
|
||||
GetMapExtraBits(tile+TILE_XY(0,1)) != 1 &&
|
||||
GetMapExtraBits(tile+TILE_XY(0,-1)) != 1)
|
||||
return;
|
||||
_map5[tile] = 0x15;
|
||||
}
|
||||
|
||||
MarkTileDirtyByTile(tile);
|
||||
}
|
||||
|
||||
static void TileLoop_Clear(uint tile)
|
||||
{
|
||||
byte m5,m3;
|
||||
|
||||
TileLoopClearHelper(tile);
|
||||
|
||||
if (_opt.landscape == LT_DESERT) {
|
||||
TileLoopClearDesert(tile);
|
||||
} else if (_opt.landscape == LT_HILLY) {
|
||||
TileLoopClearAlps(tile);
|
||||
}
|
||||
|
||||
m5 = _map5[tile];
|
||||
if ( (m5 & 0x1C) == 0x10 || (m5 & 0x1C) == 0x14)
|
||||
return;
|
||||
|
||||
if ( (m5 & 0x1C) != 0xC) {
|
||||
if ( (m5 & 3) == 3)
|
||||
return;
|
||||
|
||||
if (_game_mode != GM_EDITOR) {
|
||||
m5 += 0x20;
|
||||
if (m5 >= 0x20) {
|
||||
// Didn't overflow
|
||||
_map5[tile] = m5;
|
||||
return;
|
||||
}
|
||||
/* did overflow, so continue */
|
||||
} else {
|
||||
m5 = ((byte)Random() > 21) ? (2) : (6);
|
||||
}
|
||||
m5++;
|
||||
} else if (_game_mode != GM_EDITOR) {
|
||||
/* handle farm field */
|
||||
m5 += 0x20;
|
||||
if (m5 >= 0x20) {
|
||||
// Didn't overflow
|
||||
_map5[tile] = m5;
|
||||
return;
|
||||
}
|
||||
/* overflowed */
|
||||
m3 = _map3_lo[tile] + 1;
|
||||
assert( (m3 & 0xF) != 0);
|
||||
if ( (m3 & 0xF) >= 9) /* NOTE: will not work properly if m3&0xF == 0xF */
|
||||
m3 &= ~0xF;
|
||||
_map3_lo[tile] = m3;
|
||||
}
|
||||
|
||||
_map5[tile] = m5;
|
||||
MarkTileDirtyByTile(tile);
|
||||
}
|
||||
|
||||
void GenerateClearTile()
|
||||
{
|
||||
int i,j;
|
||||
uint tile,tile_new;
|
||||
uint32 r;
|
||||
|
||||
/* add hills */
|
||||
i = (Random() & 0x3FF) | 0x400;
|
||||
do {
|
||||
tile = TILE_MASK(Random());
|
||||
if (IS_TILETYPE(tile, MP_CLEAR))
|
||||
_map5[tile] = (byte)((_map5[tile] & ~(3<<2)) | (1<<2));
|
||||
} while (--i);
|
||||
|
||||
/* add grey squares */
|
||||
i = (Random() & 0x7F) | 0x80;
|
||||
do {
|
||||
r = Random();
|
||||
tile = TILE_MASK(r);
|
||||
if (IS_TILETYPE(tile, MP_CLEAR)) {
|
||||
j = ((r >> 16) & 0xF) + 5;
|
||||
for(;;) {
|
||||
_map5[tile] = (byte)((_map5[tile] & ~(3<<2)) | (2<<2));
|
||||
do {
|
||||
if (--j == 0) goto get_out;
|
||||
tile_new = tile + _tileoffs_by_dir[Random() & 3];
|
||||
} while (!IS_TILETYPE(tile_new, MP_CLEAR));
|
||||
tile = tile_new;
|
||||
}
|
||||
get_out:;
|
||||
}
|
||||
} while (--i);
|
||||
}
|
||||
|
||||
static void ClickTile_Clear(uint tile)
|
||||
{
|
||||
/* not used */
|
||||
}
|
||||
|
||||
uint32 GetTileTrackStatus_Clear(uint tile, TransportType mode)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const StringID _clear_land_str[4+8-1] = {
|
||||
STR_080B_ROUGH_LAND,
|
||||
STR_080A_ROCKS,
|
||||
STR_080E_FIELDS,
|
||||
STR_080F_SNOW_COVERED_LAND,
|
||||
STR_0810_DESERT,
|
||||
0,
|
||||
0,
|
||||
STR_080C_BARE_LAND,
|
||||
STR_080D_GRASS,
|
||||
STR_080D_GRASS,
|
||||
STR_080D_GRASS,
|
||||
};
|
||||
|
||||
static void GetTileDesc_Clear(uint tile, TileDesc *td)
|
||||
{
|
||||
int i = (_map5[tile]>>2) & 7;
|
||||
if (i == 0)
|
||||
i = (_map5[tile] & 3) + 8;
|
||||
td->str = _clear_land_str[i - 1];
|
||||
td->owner = _map_owner[tile];
|
||||
}
|
||||
|
||||
static void ChangeTileOwner_Clear(uint tile, byte old_player, byte new_player)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
void InitializeClearLand() {
|
||||
_opt.snow_line = _patches.snow_line_height * 8;
|
||||
}
|
||||
|
||||
const TileTypeProcs _tile_type_clear_procs = {
|
||||
DrawTile_Clear, /* draw_tile_proc */
|
||||
GetSlopeZ_Clear, /* get_slope_z_proc */
|
||||
ClearTile_Clear, /* clear_tile_proc */
|
||||
GetAcceptedCargo_Clear, /* get_accepted_cargo_proc */
|
||||
GetTileDesc_Clear, /* get_tile_desc_proc */
|
||||
GetTileTrackStatus_Clear, /* get_tile_track_status_proc */
|
||||
ClickTile_Clear, /* click_tile_proc */
|
||||
AnimateTile_Clear, /* animate_tile_proc */
|
||||
TileLoop_Clear, /* tile_loop_clear */
|
||||
ChangeTileOwner_Clear, /* change_tile_owner_clear */
|
||||
NULL, /* get_produced_cargo_proc */
|
||||
NULL, /* vehicle_enter_tile_proc */
|
||||
NULL, /* vehicle_leave_tile_proc */
|
||||
GetSlopeTileh_Clear, /* get_slope_tileh_proc */
|
||||
};
|
510
trunk/command.c
510
trunk/command.c
|
@ -1,510 +0,0 @@
|
|||
#include "stdafx.h"
|
||||
#include "ttd.h"
|
||||
#include "gui.h"
|
||||
#include "command.h"
|
||||
#include "player.h"
|
||||
|
||||
#define DEF_COMMAND(yyyy) int32 yyyy(int x, int y, uint32 flags, uint32 p1, uint32 p2)
|
||||
|
||||
DEF_COMMAND(CmdBuildRailroadTrack);
|
||||
DEF_COMMAND(CmdRemoveRailroadTrack);
|
||||
DEF_COMMAND(CmdBuildSingleRail);
|
||||
DEF_COMMAND(CmdRemoveSingleRail);
|
||||
|
||||
DEF_COMMAND(CmdLandscapeClear);
|
||||
|
||||
DEF_COMMAND(CmdBuildBridge);
|
||||
|
||||
DEF_COMMAND(CmdBuildRailroadStation);
|
||||
DEF_COMMAND(CmdRemoveFromRailroadStation);
|
||||
DEF_COMMAND(CmdConvertRail);
|
||||
|
||||
DEF_COMMAND(CmdBuildSignals);
|
||||
DEF_COMMAND(CmdRemoveSignals);
|
||||
|
||||
DEF_COMMAND(CmdTerraformLand);
|
||||
|
||||
DEF_COMMAND(CmdPurchaseLandArea);
|
||||
DEF_COMMAND(CmdSellLandArea);
|
||||
|
||||
DEF_COMMAND(CmdBuildTunnel);
|
||||
|
||||
DEF_COMMAND(CmdBuildTrainDepot);
|
||||
DEF_COMMAND(CmdBuildTrainCheckpoint);
|
||||
DEF_COMMAND(CmdRenameCheckpoint);
|
||||
DEF_COMMAND(CmdRemoveTrainCheckpoint);
|
||||
|
||||
DEF_COMMAND(CmdBuildTruckStation);
|
||||
|
||||
DEF_COMMAND(CmdBuildBusStation);
|
||||
|
||||
DEF_COMMAND(CmdBuildLongRoad);
|
||||
DEF_COMMAND(CmdRemoveLongRoad);
|
||||
DEF_COMMAND(CmdBuildRoad);
|
||||
DEF_COMMAND(CmdRemoveRoad);
|
||||
|
||||
DEF_COMMAND(CmdBuildRoadDepot);
|
||||
|
||||
DEF_COMMAND(CmdBuildAirport);
|
||||
|
||||
DEF_COMMAND(CmdBuildDock);
|
||||
|
||||
DEF_COMMAND(CmdBuildShipDepot);
|
||||
|
||||
DEF_COMMAND(CmdBuildBuoy);
|
||||
|
||||
DEF_COMMAND(CmdPlantTree);
|
||||
|
||||
DEF_COMMAND(CmdBuildRailVehicle);
|
||||
DEF_COMMAND(CmdMoveRailVehicle);
|
||||
|
||||
DEF_COMMAND(CmdStartStopTrain);
|
||||
|
||||
DEF_COMMAND(CmdSellRailWagon);
|
||||
|
||||
DEF_COMMAND(CmdTrainGotoDepot);
|
||||
DEF_COMMAND(CmdForceTrainProceed);
|
||||
DEF_COMMAND(CmdReverseTrainDirection);
|
||||
|
||||
DEF_COMMAND(CmdModifyOrder);
|
||||
DEF_COMMAND(CmdSkipOrder);
|
||||
DEF_COMMAND(CmdDeleteOrder);
|
||||
DEF_COMMAND(CmdInsertOrder);
|
||||
DEF_COMMAND(CmdChangeTrainServiceInt);
|
||||
DEF_COMMAND(CmdRestoreOrderIndex);
|
||||
|
||||
DEF_COMMAND(CmdBuildIndustry);
|
||||
//DEF_COMMAND(CmdDestroyIndustry);
|
||||
|
||||
DEF_COMMAND(CmdBuildCompanyHQ);
|
||||
DEF_COMMAND(CmdDestroyCompanyHQ);
|
||||
DEF_COMMAND(CmdSetPlayerFace);
|
||||
DEF_COMMAND(CmdSetPlayerColor);
|
||||
|
||||
DEF_COMMAND(CmdIncreaseLoan);
|
||||
DEF_COMMAND(CmdDecreaseLoan);
|
||||
|
||||
DEF_COMMAND(CmdWantEnginePreview);
|
||||
|
||||
DEF_COMMAND(CmdNameVehicle);
|
||||
DEF_COMMAND(CmdRenameEngine);
|
||||
|
||||
DEF_COMMAND(CmdChangeCompanyName);
|
||||
DEF_COMMAND(CmdChangePresidentName);
|
||||
|
||||
DEF_COMMAND(CmdRenameStation);
|
||||
|
||||
DEF_COMMAND(CmdSellAircraft);
|
||||
DEF_COMMAND(CmdStartStopAircraft);
|
||||
DEF_COMMAND(CmdBuildAircraft);
|
||||
DEF_COMMAND(CmdSendAircraftToHangar);
|
||||
DEF_COMMAND(CmdChangeAircraftServiceInt);
|
||||
DEF_COMMAND(CmdRefitAircraft);
|
||||
|
||||
DEF_COMMAND(CmdPlaceSign);
|
||||
DEF_COMMAND(CmdRenameSign);
|
||||
|
||||
DEF_COMMAND(CmdBuildRoadVeh);
|
||||
DEF_COMMAND(CmdStartStopRoadVeh);
|
||||
DEF_COMMAND(CmdSellRoadVeh);
|
||||
DEF_COMMAND(CmdSendRoadVehToDepot);
|
||||
DEF_COMMAND(CmdTurnRoadVeh);
|
||||
DEF_COMMAND(CmdChangeRoadVehServiceInt);
|
||||
|
||||
DEF_COMMAND(CmdPause);
|
||||
DEF_COMMAND(CmdResume);
|
||||
|
||||
DEF_COMMAND(CmdBuyShareInCompany);
|
||||
DEF_COMMAND(CmdSellShareInCompany);
|
||||
DEF_COMMAND(CmdBuyCompany);
|
||||
|
||||
DEF_COMMAND(CmdBuildTown);
|
||||
|
||||
DEF_COMMAND(CmdRenameTown);
|
||||
DEF_COMMAND(CmdDoTownAction);
|
||||
|
||||
DEF_COMMAND(CmdSetRoadDriveSide);
|
||||
DEF_COMMAND(CmdSetTownNameType);
|
||||
|
||||
DEF_COMMAND(CmdChangeDifficultyLevel);
|
||||
|
||||
DEF_COMMAND(CmdStartStopShip);
|
||||
DEF_COMMAND(CmdSellShip);
|
||||
DEF_COMMAND(CmdBuildShip);
|
||||
DEF_COMMAND(CmdSendShipToDepot);
|
||||
DEF_COMMAND(CmdChangeShipServiceInt);
|
||||
DEF_COMMAND(CmdRefitShip);
|
||||
|
||||
|
||||
DEF_COMMAND(CmdStartNewGame);
|
||||
DEF_COMMAND(CmdLoadGame);
|
||||
DEF_COMMAND(CmdCreateScenario);
|
||||
DEF_COMMAND(CmdSetSinglePlayer);
|
||||
|
||||
DEF_COMMAND(CmdSetNewLandscapeType);
|
||||
|
||||
DEF_COMMAND(CmdGenRandomNewGame);
|
||||
DEF_COMMAND(CmdCloneOrder);
|
||||
|
||||
DEF_COMMAND(CmdClearArea);
|
||||
|
||||
DEF_COMMAND(CmdMoneyCheat);
|
||||
DEF_COMMAND(CmdBuildCanal);
|
||||
DEF_COMMAND(CmdBuildLock);
|
||||
|
||||
DEF_COMMAND(CmdPlayerCtrl);
|
||||
|
||||
DEF_COMMAND(CmdLevelLand);
|
||||
|
||||
DEF_COMMAND(CmdRefitRailVehicle);
|
||||
|
||||
DEF_COMMAND(CmdStartScenario);
|
||||
|
||||
DEF_COMMAND(CmdBuildManySignals);
|
||||
|
||||
/* The master command table */
|
||||
static CommandProc * const _command_proc_table[] = {
|
||||
CmdBuildRailroadTrack, /* 0 */
|
||||
CmdRemoveRailroadTrack, /* 1 */
|
||||
CmdBuildSingleRail, /* 2 */
|
||||
CmdRemoveSingleRail, /* 3 */
|
||||
CmdLandscapeClear, /* 4 */
|
||||
CmdBuildBridge, /* 5 */
|
||||
CmdBuildRailroadStation, /* 6 */
|
||||
CmdBuildTrainDepot, /* 7 */
|
||||
CmdBuildSignals, /* 8 */
|
||||
CmdRemoveSignals, /* 9 */
|
||||
CmdTerraformLand, /* 10 */
|
||||
CmdPurchaseLandArea, /* 11 */
|
||||
CmdSellLandArea, /* 12 */
|
||||
CmdBuildTunnel, /* 13 */
|
||||
CmdRemoveFromRailroadStation, /* 14 */
|
||||
CmdConvertRail, /* 15 */
|
||||
CmdBuildTrainCheckpoint, /* 16 */
|
||||
CmdRenameCheckpoint, /* 17 */
|
||||
CmdRemoveTrainCheckpoint, /* 18 */
|
||||
CmdBuildTruckStation, /* 19 */
|
||||
NULL, /* 20 */
|
||||
CmdBuildBusStation, /* 21 */
|
||||
NULL, /* 22 */
|
||||
CmdBuildLongRoad, /* 23 */
|
||||
CmdRemoveLongRoad, /* 24 */
|
||||
CmdBuildRoad, /* 25 */
|
||||
CmdRemoveRoad, /* 26 */
|
||||
CmdBuildRoadDepot, /* 27 */
|
||||
NULL, /* 28 */
|
||||
CmdBuildAirport, /* 29 */
|
||||
CmdBuildDock, /* 30 */
|
||||
CmdBuildShipDepot, /* 31 */
|
||||
CmdBuildBuoy, /* 32 */
|
||||
CmdPlantTree, /* 33 */
|
||||
CmdBuildRailVehicle, /* 34 */
|
||||
CmdMoveRailVehicle, /* 35 */
|
||||
CmdStartStopTrain, /* 36 */
|
||||
NULL, /* 37 */
|
||||
CmdSellRailWagon, /* 38 */
|
||||
CmdTrainGotoDepot, /* 39 */
|
||||
CmdForceTrainProceed, /* 40 */
|
||||
CmdReverseTrainDirection, /* 41 */
|
||||
|
||||
CmdModifyOrder, /* 42 */
|
||||
CmdSkipOrder, /* 43 */
|
||||
CmdDeleteOrder, /* 44 */
|
||||
CmdInsertOrder, /* 45 */
|
||||
|
||||
CmdChangeTrainServiceInt, /* 46 */
|
||||
|
||||
CmdBuildIndustry, /* 47 */
|
||||
CmdBuildCompanyHQ, /* 48 */
|
||||
CmdSetPlayerFace, /* 49 */
|
||||
CmdSetPlayerColor, /* 50 */
|
||||
|
||||
CmdIncreaseLoan, /* 51 */
|
||||
CmdDecreaseLoan, /* 52 */
|
||||
|
||||
CmdWantEnginePreview, /* 53 */
|
||||
|
||||
CmdNameVehicle, /* 54 */
|
||||
CmdRenameEngine, /* 55 */
|
||||
|
||||
CmdChangeCompanyName, /* 56 */
|
||||
CmdChangePresidentName, /* 57 */
|
||||
|
||||
CmdRenameStation, /* 58 */
|
||||
|
||||
CmdSellAircraft, /* 59 */
|
||||
CmdStartStopAircraft, /* 60 */
|
||||
CmdBuildAircraft, /* 61 */
|
||||
CmdSendAircraftToHangar, /* 62 */
|
||||
CmdChangeAircraftServiceInt, /* 63 */
|
||||
CmdRefitAircraft, /* 64 */
|
||||
|
||||
CmdPlaceSign, /* 65 */
|
||||
CmdRenameSign, /* 66 */
|
||||
|
||||
CmdBuildRoadVeh, /* 67 */
|
||||
CmdStartStopRoadVeh, /* 68 */
|
||||
CmdSellRoadVeh, /* 69 */
|
||||
CmdSendRoadVehToDepot, /* 70 */
|
||||
CmdTurnRoadVeh, /* 71 */
|
||||
CmdChangeRoadVehServiceInt, /* 72 */
|
||||
|
||||
CmdPause, /* 73 */
|
||||
|
||||
CmdBuyShareInCompany, /* 74 */
|
||||
CmdSellShareInCompany, /* 75 */
|
||||
CmdBuyCompany, /* 76 */
|
||||
|
||||
CmdBuildTown, /* 77 */
|
||||
NULL, /* 78 */
|
||||
NULL, /* 79 */
|
||||
CmdRenameTown, /* 80 */
|
||||
CmdDoTownAction, /* 81 */
|
||||
|
||||
CmdSetRoadDriveSide, /* 82 */
|
||||
CmdSetTownNameType, /* 83 */
|
||||
NULL, /* 84 */
|
||||
CmdChangeDifficultyLevel, /* 85 */
|
||||
|
||||
CmdStartStopShip, /* 86 */
|
||||
CmdSellShip, /* 87 */
|
||||
CmdBuildShip, /* 88 */
|
||||
CmdSendShipToDepot, /* 89 */
|
||||
CmdChangeShipServiceInt, /* 90 */
|
||||
CmdRefitShip, /* 91 */
|
||||
|
||||
CmdStartNewGame, /* 92 */
|
||||
CmdLoadGame, /* 93 */
|
||||
CmdCreateScenario, /* 94 */
|
||||
CmdSetSinglePlayer, /* 95 */
|
||||
NULL, /* 96 */
|
||||
CmdSetNewLandscapeType, /* 97 */
|
||||
|
||||
CmdGenRandomNewGame, /* 98 */
|
||||
|
||||
CmdCloneOrder, /* 99 */
|
||||
|
||||
CmdClearArea, /* 100 */
|
||||
CmdResume, /* 101 */
|
||||
|
||||
CmdMoneyCheat, /* 102 */
|
||||
CmdBuildCanal, /* 103 */
|
||||
CmdPlayerCtrl, /* 104 */
|
||||
|
||||
CmdLevelLand, /* 105 */
|
||||
|
||||
CmdRefitRailVehicle, /* 106 */
|
||||
CmdRestoreOrderIndex, /* 107 */
|
||||
CmdBuildLock, /* 108 */
|
||||
CmdStartScenario, /* 109 */
|
||||
CmdBuildManySignals, /* 110 */
|
||||
//CmdDestroyIndustry, /* 109 */
|
||||
CmdDestroyCompanyHQ, /* 111 */
|
||||
};
|
||||
|
||||
int32 DoCommandByTile(TileIndex tile, uint32 p1, uint32 p2, uint32 flags, uint procc)
|
||||
{
|
||||
return DoCommand(GET_TILE_X(tile)*16, GET_TILE_Y(tile)*16, p1, p2, flags, procc);
|
||||
}
|
||||
|
||||
|
||||
//extern void _stdcall Sleep(int s);
|
||||
|
||||
int32 DoCommand(int x, int y, uint32 p1, uint32 p2, uint32 flags, uint procc)
|
||||
{
|
||||
int32 res;
|
||||
CommandProc *proc;
|
||||
|
||||
proc = _command_proc_table[procc];
|
||||
|
||||
if (_docommand_recursive == 0) {
|
||||
_error_message = INVALID_STRING_ID;
|
||||
// update last build coord of player
|
||||
if ( (x|y) != 0 && _current_player < MAX_PLAYERS) {
|
||||
DEREF_PLAYER(_current_player)->last_build_coordinate = TILE_FROM_XY(x,y);
|
||||
}
|
||||
}
|
||||
|
||||
_docommand_recursive++;
|
||||
|
||||
// only execute the test call if it's toplevel, or we're not execing.
|
||||
if (_docommand_recursive == 1 || !(flags & DC_EXEC) || (flags & DC_FORCETEST) ) {
|
||||
res = proc(x, y, flags&~DC_EXEC, p1, p2);
|
||||
if ((uint32)res >> 16 == 0x8000) {
|
||||
if (res & 0xFFFF) _error_message = res & 0xFFFF;
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (_docommand_recursive == 1) {
|
||||
if (!(flags&DC_QUERY_COST) && res != 0 && !CheckPlayerHasMoney(res))
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (!(flags & DC_EXEC)) {
|
||||
_docommand_recursive--;
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
// execute the command here.
|
||||
_yearly_expenses_type = 0;
|
||||
res = proc(x, y, flags, p1, p2);
|
||||
if ((uint32)res >> 16 == 0x8000) {
|
||||
if (res & 0xFFFF) _error_message = res & 0xFFFF;
|
||||
error:
|
||||
_docommand_recursive--;
|
||||
return CMD_ERROR;
|
||||
}
|
||||
|
||||
// if toplevel, subtract the money.
|
||||
if (--_docommand_recursive == 0) {
|
||||
SubtractMoneyFromPlayer(res);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
int32 GetAvailableMoneyForCommand()
|
||||
{
|
||||
uint pid = _current_player;
|
||||
if (pid >= MAX_PLAYERS) return 0x7FFFFFFF; // max int
|
||||
return DEREF_PLAYER(pid)->player_money;
|
||||
}
|
||||
|
||||
// toplevel network safe docommand function for the current player. must not be called recursively.
|
||||
// the callback is called when the command succeeded or failed.
|
||||
bool DoCommandP(TileIndex tile, uint32 p1, uint32 p2, CommandCallback *callback, uint32 cmd)
|
||||
{
|
||||
int32 res = 0,res2;
|
||||
CommandProc *proc;
|
||||
uint32 flags;
|
||||
bool notest;
|
||||
|
||||
int x = GET_TILE_X(tile)*16;
|
||||
int y = GET_TILE_Y(tile)*16;
|
||||
|
||||
assert(_docommand_recursive == 0);
|
||||
|
||||
if (_networking && !(cmd & CMD_NET_INSTANT) && _pause) {
|
||||
// When the game is paused, and we are in a network game
|
||||
// we do not allow any commands. This is because
|
||||
// of some technical reasons
|
||||
ShowErrorMessage(-1, STR_MULTIPLAYER_PAUSED, x, y);
|
||||
_docommand_recursive = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
_error_message = INVALID_STRING_ID;
|
||||
_error_message_2 = cmd >> 16;
|
||||
_additional_cash_required = 0;
|
||||
|
||||
// spectator has no rights.
|
||||
if (_current_player == OWNER_SPECTATOR) {
|
||||
ShowErrorMessage(_error_message, _error_message_2, x, y);
|
||||
return false;
|
||||
}
|
||||
|
||||
flags = 0;
|
||||
if (cmd & CMD_AUTO) flags |= DC_AUTO;
|
||||
if (cmd & CMD_NO_WATER) flags |= DC_NO_WATER;
|
||||
|
||||
// get pointer to command handler
|
||||
assert((cmd & 0xFF) < lengthof(_command_proc_table));
|
||||
proc = _command_proc_table[cmd & 0xFF];
|
||||
|
||||
// this command is a notest command?
|
||||
notest =
|
||||
(cmd & 0xFF) == CMD_CLEAR_AREA ||
|
||||
(cmd & 0xFF) == CMD_CONVERT_RAIL ||
|
||||
(cmd & 0xFF) == CMD_LEVEL_LAND ||
|
||||
(cmd & 0xFF) == CMD_TRAIN_GOTO_DEPOT;
|
||||
|
||||
if (_networking && (cmd & CMD_ASYNC)) notest = true;
|
||||
|
||||
_docommand_recursive = 1;
|
||||
|
||||
// cost estimation only?
|
||||
if (_shift_pressed && _current_player == _local_player && !(cmd & CMD_DONT_NETWORK)) {
|
||||
// estimate the cost.
|
||||
res = proc(x, y, flags, p1, p2);
|
||||
if ((uint32)res >> 16 == 0x8000) {
|
||||
if (res & 0xFFFF) _error_message = res & 0xFFFF;
|
||||
ShowErrorMessage(_error_message, _error_message_2, x, y);
|
||||
} else {
|
||||
ShowEstimatedCostOrIncome(res, x, y);
|
||||
}
|
||||
|
||||
_docommand_recursive = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// unless the command is a notest command, check if it can be executed.
|
||||
if (!notest) {
|
||||
// first test if the command can be executed.
|
||||
res = proc(x,y, flags, p1, p2);
|
||||
if ((uint32)res >> 16 == 0x8000) {
|
||||
if (res & 0xFFFF) _error_message = res & 0xFFFF;
|
||||
goto show_error;
|
||||
}
|
||||
// no money?
|
||||
if (res != 0 && !CheckPlayerHasMoney(res)) goto show_error;
|
||||
}
|
||||
|
||||
// put the command in a network queue and execute it later?
|
||||
if (_networking && !(cmd & CMD_DONT_NETWORK)) {
|
||||
if (!(cmd & CMD_NET_INSTANT)) {
|
||||
NetworkSendCommand(tile, p1, p2, cmd, callback);
|
||||
_docommand_recursive = 0;
|
||||
return true;
|
||||
} else {
|
||||
// Instant Command ... Relay and Process then
|
||||
NetworkSendCommand(tile, p1, p2, cmd, callback);
|
||||
}
|
||||
}
|
||||
|
||||
// update last build coordinate of player.
|
||||
if ( tile != 0 && _current_player < MAX_PLAYERS) DEREF_PLAYER(_current_player)->last_build_coordinate = tile;
|
||||
|
||||
// actually try and execute the command.
|
||||
_yearly_expenses_type = 0;
|
||||
res2 = proc(x,y, flags|DC_EXEC, p1, p2);
|
||||
|
||||
if (!notest) {
|
||||
assert(res == res2); // sanity check
|
||||
} else {
|
||||
if ((uint32)res2 >> 16 == 0x8000) {
|
||||
if (res2 & 0xFFFF) _error_message = res2 & 0xFFFF;
|
||||
goto show_error;
|
||||
}
|
||||
}
|
||||
|
||||
SubtractMoneyFromPlayer(res2);
|
||||
|
||||
if (_current_player == _local_player && _game_mode != GM_EDITOR) {
|
||||
if (res2 != 0)
|
||||
ShowCostOrIncomeAnimation(x, y, GetSlopeZ(x, y), res2);
|
||||
if (_additional_cash_required) {
|
||||
SET_DPARAM32(0, _additional_cash_required);
|
||||
ShowErrorMessage(STR_0003_NOT_ENOUGH_CASH_REQUIRES, _error_message_2, x,y);
|
||||
if (res2 == 0) goto callb_err;
|
||||
}
|
||||
}
|
||||
|
||||
_docommand_recursive = 0;
|
||||
|
||||
if (callback) callback(true, tile, p1, p2);
|
||||
return true;
|
||||
|
||||
show_error:
|
||||
// show error message if the command fails?
|
||||
if (_current_player == _local_player && _error_message_2 != 0)
|
||||
ShowErrorMessage(_error_message, _error_message_2, x,y);
|
||||
|
||||
callb_err:
|
||||
_docommand_recursive = 0;
|
||||
|
||||
if (callback) callback(false, tile, p1, p2);
|
||||
return false;
|
||||
}
|
183
trunk/command.h
183
trunk/command.h
|
@ -1,183 +0,0 @@
|
|||
#ifndef COMMAND_H
|
||||
#define COMMAND_H
|
||||
|
||||
enum {
|
||||
CMD_BUILD_RAILROAD_TRACK = 0,
|
||||
CMD_REMOVE_RAILROAD_TRACK = 1,
|
||||
CMD_BUILD_SINGLE_RAIL = 2,
|
||||
CMD_REMOVE_SINGLE_RAIL = 3,
|
||||
CMD_LANDSCAPE_CLEAR = 4,
|
||||
CMD_BUILD_BRIDGE = 5,
|
||||
CMD_BUILD_RAILROAD_STATION = 6,
|
||||
CMD_BUILD_TRAIN_DEPOT = 7,
|
||||
CMD_BUILD_SIGNALS = 8,
|
||||
CMD_REMOVE_SIGNALS = 9,
|
||||
CMD_TERRAFORM_LAND = 10,
|
||||
CMD_PURCHASE_LAND_AREA = 11,
|
||||
CMD_SELL_LAND_AREA = 12,
|
||||
CMD_BUILD_TUNNEL = 13,
|
||||
|
||||
CMD_REMOVE_FROM_RAILROAD_STATION = 14,
|
||||
CMD_CONVERT_RAIL = 15,
|
||||
|
||||
CMD_BUILD_TRAIN_CHECKPOINT = 16,
|
||||
CMD_RENAME_CHECKPOINT = 17,
|
||||
CMD_REMOVE_TRAIN_CHECKPOINT = 18,
|
||||
|
||||
CMD_BUILD_TRUCK_STATION = 19,
|
||||
CMD_BUILD_BUS_STATION = 21,
|
||||
CMD_BUILD_LONG_ROAD = 23,
|
||||
CMD_REMOVE_LONG_ROAD = 24,
|
||||
CMD_BUILD_ROAD = 25,
|
||||
CMD_REMOVE_ROAD = 26,
|
||||
CMD_BUILD_ROAD_DEPOT = 27,
|
||||
|
||||
CMD_BUILD_AIRPORT = 29,
|
||||
|
||||
CMD_BUILD_DOCK = 30,
|
||||
|
||||
CMD_BUILD_SHIP_DEPOT = 31,
|
||||
CMD_BUILD_BUOY = 32,
|
||||
|
||||
CMD_PLANT_TREE = 33,
|
||||
|
||||
CMD_BUILD_RAIL_VEHICLE = 34,
|
||||
CMD_MOVE_RAIL_VEHICLE = 35,
|
||||
|
||||
CMD_START_STOP_TRAIN = 36,
|
||||
|
||||
CMD_SELL_RAIL_WAGON = 38,
|
||||
|
||||
CMD_TRAIN_GOTO_DEPOT = 39,
|
||||
CMD_FORCE_TRAIN_PROCEED = 40,
|
||||
CMD_REVERSE_TRAIN_DIRECTION = 41,
|
||||
|
||||
CMD_MODIFY_ORDER = 42,
|
||||
CMD_SKIP_ORDER = 43,
|
||||
CMD_DELETE_ORDER = 44,
|
||||
CMD_INSERT_ORDER = 45,
|
||||
|
||||
CMD_CHANGE_TRAIN_SERVICE_INT = 46,
|
||||
|
||||
CMD_BUILD_INDUSTRY = 47,
|
||||
|
||||
CMD_BUILD_COMPANY_HQ = 48,
|
||||
CMD_SET_PLAYER_FACE = 49,
|
||||
CMD_SET_PLAYER_COLOR = 50,
|
||||
|
||||
CMD_INCREASE_LOAN = 51,
|
||||
CMD_DECREASE_LOAN = 52,
|
||||
|
||||
CMD_WANT_ENGINE_PREVIEW = 53,
|
||||
|
||||
CMD_NAME_VEHICLE = 54,
|
||||
CMD_RENAME_ENGINE = 55,
|
||||
CMD_CHANGE_COMPANY_NAME = 56,
|
||||
CMD_CHANGE_PRESIDENT_NAME = 57,
|
||||
CMD_RENAME_STATION = 58,
|
||||
|
||||
CMD_SELL_AIRCRAFT = 59,
|
||||
CMD_START_STOP_AIRCRAFT = 60,
|
||||
CMD_BUILD_AIRCRAFT = 61,
|
||||
CMD_SEND_AIRCRAFT_TO_HANGAR = 62,
|
||||
CMD_CHANGE_AIRCRAFT_SERVICE_INT = 63,
|
||||
CMD_REFIT_AIRCRAFT = 64,
|
||||
|
||||
CMD_PLACE_SIGN = 65,
|
||||
CMD_RENAME_SIGN = 66,
|
||||
|
||||
CMD_BUILD_ROAD_VEH = 67,
|
||||
CMD_START_STOP_ROADVEH = 68,
|
||||
CMD_SELL_ROAD_VEH = 69,
|
||||
CMD_SEND_ROADVEH_TO_DEPOT = 70,
|
||||
CMD_TURN_ROADVEH = 71,
|
||||
CMD_CHANGE_ROADVEH_SERVICE_INT = 72,
|
||||
|
||||
CMD_PAUSE = 73,
|
||||
|
||||
CMD_BUY_SHARE_IN_COMPANY = 74,
|
||||
CMD_SELL_SHARE_IN_COMPANY = 75,
|
||||
CMD_BUY_COMPANY = 76,
|
||||
|
||||
CMD_BUILD_TOWN = 77,
|
||||
|
||||
CMD_RENAME_TOWN = 80,
|
||||
CMD_DO_TOWN_ACTION = 81,
|
||||
|
||||
CMD_SET_ROAD_DRIVE_SIDE = 82,
|
||||
CMD_SET_TOWN_NAME_TYPE = 83,
|
||||
|
||||
|
||||
CMD_CHANGE_DIFFICULTY_LEVEL = 85,
|
||||
|
||||
CMD_START_STOP_SHIP = 86,
|
||||
CMD_SELL_SHIP = 87,
|
||||
CMD_BUILD_SHIP = 88,
|
||||
CMD_SEND_SHIP_TO_DEPOT = 89,
|
||||
CMD_CHANGE_SHIP_SERVICE_INT = 90,
|
||||
CMD_REFIT_SHIP = 91,
|
||||
|
||||
CMD_START_NEW_GAME = 92,
|
||||
CMD_LOAD_GAME = 93,
|
||||
CMD_CREATE_SCENARIO = 94,
|
||||
CMD_SET_SINGLE_PLAYER = 95,
|
||||
|
||||
CMD_SET_NEW_LANDSCAPE_TYPE = 97,
|
||||
|
||||
CMD_GEN_RANDOM_NEW_GAME = 98,
|
||||
|
||||
CMD_CLONE_ORDER = 99,
|
||||
CMD_CLEAR_AREA = 100,
|
||||
|
||||
CMD_RESUME = 101,
|
||||
|
||||
CMD_MONEY_CHEAT = 102,
|
||||
CMD_BUILD_CANAL = 103,
|
||||
|
||||
CMD_PLAYER_CTRL = 104, // used in multiplayer to create a new player etc.
|
||||
CMD_LEVEL_LAND = 105, // level land
|
||||
|
||||
CMD_REFIT_RAIL_VEHICLE = 106,
|
||||
CMD_RESTORE_ORDER_INDEX = 107,
|
||||
CMD_BUILD_LOCK = 108,
|
||||
|
||||
CMD_START_SCENARIO = 109,
|
||||
CMD_BUILD_MANY_SIGNALS = 110,
|
||||
|
||||
//CMD_DESTROY_INDUSTRY = 109,
|
||||
CMD_DESTROY_COMPANY_HQ = 111,
|
||||
};
|
||||
|
||||
enum {
|
||||
DC_EXEC = 1,
|
||||
DC_AUTO = 2, // don't allow building on structures
|
||||
DC_QUERY_COST = 4, // query cost only, don't build.
|
||||
DC_NO_WATER = 8, // don't allow building on water
|
||||
DC_NO_RAIL_OVERLAP = 0x10, // don't allow overlap of rails (used in buildrail)
|
||||
DC_AI_BUILDING = 0x20, // special building rules for AI
|
||||
DC_NO_TOWN_RATING = 0x40, // town rating does not disallow you from building
|
||||
DC_FORCETEST = 0x80, // force test too.
|
||||
|
||||
CMD_ERROR = ((int32)0x80000000),
|
||||
};
|
||||
|
||||
#define CMD_MSG(x) ((x)<<16)
|
||||
|
||||
enum {
|
||||
CMD_AUTO = 0x200,
|
||||
CMD_NO_WATER = 0x400,
|
||||
CMD_DONT_NETWORK = 0x800, // execute the command without sending it on the network
|
||||
CMD_ASYNC = 0x1000, // execute the command asynchronously without testing first in networking
|
||||
CMD_NET_INSTANT = 0x2000,
|
||||
};
|
||||
|
||||
//#define return_cmd_error(errcode) do { _error_message=(errcode); return CMD_ERROR; } while(0)
|
||||
#define return_cmd_error(errcode) do { return CMD_ERROR | (errcode); } while (0)
|
||||
|
||||
/* command.c */
|
||||
int32 DoCommand(int x, int y, uint32 p1, uint32 p2, uint32 flags, uint procc);
|
||||
int32 DoCommandByTile(TileIndex tile, uint32 p1, uint32 p2, uint32 flags, uint procc);
|
||||
|
||||
int32 GetAvailableMoneyForCommand();
|
||||
|
||||
#endif /* COMMAND_H */
|
|
@ -1,24 +0,0 @@
|
|||
#!/bin/sh -
|
||||
|
||||
SDLCONFIG=`which sdl-config || which sdl11-config || which sdl12-config || echo `
|
||||
if [ -n "$SDLCONFIG" ] ; then
|
||||
echo "SDL config is located at: $SDLCONFIG"
|
||||
sed -e"s@XX_SDL_CONFIG_PLACEHOLDER_XX@$SDLCONFIG@g" < Jamfile.next > tmp && mv tmp Jamfile
|
||||
else
|
||||
echo "********************************"
|
||||
echo "ERROR! SDL CONFIG WAS NOT FOUND!"
|
||||
echo "********************************"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Configure complete. Now use 'jam' to build"
|
||||
echo "Add -sWITH_PNG=<dir to png.h> to build with PNG support"
|
||||
echo "Add -sWITH_ZLIB=1 to enable zlib savegame support"
|
||||
echo "Add -sRELEASE=1 to build an optimized executable"
|
||||
echo "Add -sWITH_BONE_NETWORKING=1 to build with BeOS BONE networking support"
|
||||
echo "Add -sBEOS_MIDI=1 to enable BeOS native MIDI (libmidi.so) music output"
|
||||
echo ""
|
||||
echo "For people using make:"
|
||||
echo "write make (or gmake)"
|
||||
echo "configure have nothing to do with the makefile"
|
||||
|
1235
trunk/console.c
1235
trunk/console.c
File diff suppressed because it is too large
Load Diff
129
trunk/console.h
129
trunk/console.h
|
@ -1,129 +0,0 @@
|
|||
#ifndef CONSOLE_H
|
||||
#define CONSOLE_H
|
||||
|
||||
// ** console ** //
|
||||
|
||||
enum {
|
||||
ICONSOLE_OPENED=0,
|
||||
ICONSOLE_CLOSED,
|
||||
} _iconsole_modes;
|
||||
|
||||
// ** console parser ** //
|
||||
|
||||
enum {
|
||||
ICONSOLE_VAR_NONE=0,
|
||||
ICONSOLE_VAR_BOOLEAN,
|
||||
ICONSOLE_VAR_BYTE,
|
||||
ICONSOLE_VAR_UINT16,
|
||||
ICONSOLE_VAR_UINT32,
|
||||
ICONSOLE_VAR_INT16,
|
||||
ICONSOLE_VAR_INT32,
|
||||
ICONSOLE_VAR_STRING,
|
||||
ICONSOLE_VAR_POINTER,
|
||||
ICONSOLE_VAR_REFERENCE,
|
||||
ICONSOLE_VAR_UNKNOWN,
|
||||
} _iconsole_var_types;
|
||||
|
||||
enum {
|
||||
ICONSOLE_HOOK_ACCESS,
|
||||
ICONSOLE_HOOK_BEFORE_CHANGE,
|
||||
ICONSOLE_HOOK_BEFORE_EXEC,
|
||||
ICONSOLE_HOOK_AFTER_CHANGE,
|
||||
ICONSOLE_HOOK_AFTER_EXEC,
|
||||
} _iconsole_hook_types;
|
||||
|
||||
typedef struct {
|
||||
// -------------- //
|
||||
void * addr;
|
||||
byte * name;
|
||||
// -------------- //
|
||||
void * hook_access;
|
||||
void * hook_before_exec;
|
||||
void * hook_after_exec;
|
||||
// -------------- //
|
||||
void * _next;
|
||||
} _iconsole_cmd;
|
||||
|
||||
typedef struct {
|
||||
// --------------- //
|
||||
void * addr;
|
||||
const byte * name;
|
||||
byte type;
|
||||
// -------------- //
|
||||
void * hook_access;
|
||||
void * hook_before_change;
|
||||
void * hook_after_change;
|
||||
// -------------- //
|
||||
void * _next;
|
||||
bool _malloc;
|
||||
} _iconsole_var;
|
||||
|
||||
// ** console parser ** //
|
||||
|
||||
_iconsole_cmd * _iconsole_cmds; // list of registred commands
|
||||
_iconsole_var * _iconsole_vars; // list of registred vars
|
||||
|
||||
// ** console colors ** //
|
||||
VARDEF byte _iconsole_color_default;
|
||||
VARDEF byte _iconsole_color_error;
|
||||
VARDEF byte _iconsole_color_warning;
|
||||
VARDEF byte _iconsole_color_debug;
|
||||
VARDEF byte _iconsole_color_commands;
|
||||
|
||||
// ** ttd.c functions ** //
|
||||
|
||||
void SetDebugString(const char *s);
|
||||
|
||||
// ** console functions ** //
|
||||
|
||||
void IConsoleClearCommand();
|
||||
void IConsoleInit();
|
||||
void IConsoleClear();
|
||||
void IConsoleFree();
|
||||
void IConsoleResize();
|
||||
void IConsoleSwitch();
|
||||
void IConsoleClose();
|
||||
void IConsoleOpen();
|
||||
|
||||
// ** console cmd buffer ** //
|
||||
void IConsoleCmdBufferAdd(const byte *cmd);
|
||||
void IConsoleCmdBufferNavigate(signed char direction);
|
||||
|
||||
// ** console output ** //
|
||||
void IConsolePrint(byte color_code, const byte* string);
|
||||
void CDECL IConsolePrintF(byte color_code, const char *s, ...);
|
||||
void IConsoleDebug(byte* string);
|
||||
void IConsoleError(const byte* string);
|
||||
void IConsoleWarning(const byte* string);
|
||||
|
||||
// *** Commands *** //
|
||||
|
||||
void IConsoleCmdRegister(const byte * name, void * addr);
|
||||
_iconsole_cmd * IConsoleCmdGet(const byte * name);
|
||||
|
||||
// *** Variables *** //
|
||||
|
||||
void IConsoleVarRegister(const byte * name, void * addr, byte type);
|
||||
void IConsoleVarMemRegister(const byte * name, byte type);
|
||||
void IConsoleVarInsert(_iconsole_var * var, const byte * name);
|
||||
_iconsole_var * IConsoleVarGet(const byte * name);
|
||||
_iconsole_var * IConsoleVarAlloc(byte type);
|
||||
void IConsoleVarFree(_iconsole_var * var);
|
||||
void IConsoleVarSetString(_iconsole_var * var, const byte * string);
|
||||
void IConsoleVarSetValue(_iconsole_var * var, int value);
|
||||
void IConsoleVarDump(_iconsole_var * var, const byte * dump_desc);
|
||||
|
||||
// *** Parser *** //
|
||||
|
||||
void IConsoleCmdExec(const byte* cmdstr);
|
||||
|
||||
// ** console std lib ** //
|
||||
void IConsoleStdLibRegister();
|
||||
|
||||
// ** hook code ** //
|
||||
void IConsoleVarHook(const byte * name, byte type, void * proc);
|
||||
void IConsoleCmdHook(const byte * name, byte type, void * proc);
|
||||
bool IConsoleVarHookHandle(_iconsole_var * hook_var, byte type);
|
||||
bool IConsoleCmdHookHandle(_iconsole_cmd * hook_cmd, byte type);
|
||||
|
||||
#endif /* CONSOLE_H */
|
|
@ -1,476 +0,0 @@
|
|||
/* -------------------- dont cross this line --------------------- */
|
||||
#include "stdafx.h"
|
||||
#include "ttd.h"
|
||||
#include "console.h"
|
||||
#include "engine.h"
|
||||
#include "functions.h"
|
||||
#include "variables.h"
|
||||
|
||||
#if defined(WIN32)
|
||||
# define ENABLE_NETWORK
|
||||
#endif
|
||||
|
||||
|
||||
// ** scriptfile handling ** //
|
||||
static FILE * _script_file;
|
||||
static bool _script_running;
|
||||
|
||||
// ** console command / variable defines ** //
|
||||
|
||||
#define DEF_CONSOLE_CMD(yyyy) static _iconsole_var * yyyy(byte argc, byte* argv[], byte argt[])
|
||||
#define DEF_CONSOLE_CMD_HOOK(yyyy) static bool yyyy(_iconsole_cmd * hookcmd)
|
||||
#define DEF_CONSOLE_VAR_HOOK(yyyy) static bool yyyy(_iconsole_var * hookvar)
|
||||
|
||||
|
||||
// ** supporting functions ** //
|
||||
|
||||
static int32 GetArgumentInteger(byte *arg)
|
||||
{
|
||||
int32 result;
|
||||
sscanf((char *)arg, "%u", &result);
|
||||
|
||||
if (result == 0 && arg[0] == '0' && arg[1] == 'x')
|
||||
sscanf((char *)arg, "%x", &result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* **************************** */
|
||||
/* variable and command hooks */
|
||||
/* **************************** */
|
||||
|
||||
DEF_CONSOLE_CMD_HOOK(ConCmdHookNoNetwork)
|
||||
{
|
||||
if (_networking) {
|
||||
IConsoleError("this command is forbidden in multiplayer");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
#if 0 /* Not used atm */
|
||||
DEF_CONSOLE_VAR_HOOK(ConVarHookNoNetwork)
|
||||
{
|
||||
if (_networking) {
|
||||
IConsoleError("this variable is forbidden in multiplayer");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
DEF_CONSOLE_VAR_HOOK(ConVarHookNoNetClient)
|
||||
{
|
||||
if (!_networking_server) {
|
||||
IConsoleError("this variable only makes sense for a network server");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/* **************************** */
|
||||
/* reset commands */
|
||||
/* **************************** */
|
||||
|
||||
DEF_CONSOLE_CMD(ConResetEngines)
|
||||
{
|
||||
StartupEngines();
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEF_CONSOLE_CMD(ConResetTile)
|
||||
{
|
||||
if (argc == 2) {
|
||||
TileIndex tile = (TileIndex)GetArgumentInteger(argv[1]);
|
||||
DoClearSquare(tile);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEF_CONSOLE_CMD(ConScrollToTile)
|
||||
{
|
||||
if (argc == 2) {
|
||||
TileIndex tile = (TileIndex)GetArgumentInteger(argv[1]);
|
||||
ScrollMainWindowToTile(tile);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// ********************************* //
|
||||
// * Network Core Console Commands * //
|
||||
// ********************************* //
|
||||
#ifdef ENABLE_NETWORK
|
||||
|
||||
DEF_CONSOLE_CMD(ConNetworkConnect)
|
||||
{
|
||||
byte * ip;
|
||||
const byte *port = NULL;
|
||||
const byte *player = NULL;
|
||||
uint16 rport;
|
||||
|
||||
if (argc<2) return NULL;
|
||||
|
||||
ip = argv[1];
|
||||
rport = _network_server_port;
|
||||
|
||||
ParseConnectionString(&player, &port, ip);
|
||||
|
||||
IConsolePrintF(_iconsole_color_default,"Connecting to %s...", ip);
|
||||
if (player!=NULL) {
|
||||
_network_playas = atoi(player);
|
||||
IConsolePrintF(_iconsole_color_default," player-no: %s", player);
|
||||
}
|
||||
if (port!=NULL) {
|
||||
rport = atoi(port);
|
||||
IConsolePrintF(_iconsole_color_default," port: %s", port);
|
||||
}
|
||||
|
||||
NetworkCoreConnectGame(ip, rport);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* ******************************** */
|
||||
/* script file console commands */
|
||||
/* ******************************** */
|
||||
|
||||
DEF_CONSOLE_CMD(ConExec)
|
||||
{
|
||||
char cmd[1024];
|
||||
bool doerror;
|
||||
|
||||
if (argc<2) return NULL;
|
||||
|
||||
doerror = true;
|
||||
_script_file = fopen(argv[1],"rb");
|
||||
|
||||
if (_script_file == NULL) {
|
||||
if (argc>2) if (atoi(argv[2])==0) doerror=false;
|
||||
if (doerror) IConsoleError("script file not found");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
_script_running = true;
|
||||
|
||||
while (!feof(_script_file) && _script_running) {
|
||||
|
||||
fgets((char *)&cmd, 1024, _script_file);
|
||||
|
||||
IConsoleCmdExec((byte *) &cmd);
|
||||
|
||||
}
|
||||
|
||||
_script_running = false;
|
||||
fclose(_script_file);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
DEF_CONSOLE_CMD(ConReturn)
|
||||
{
|
||||
_script_running = false;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* **************************** */
|
||||
/* default console commands */
|
||||
/* **************************** */
|
||||
|
||||
DEF_CONSOLE_CMD(ConScript)
|
||||
{
|
||||
extern FILE* _iconsole_output_file;
|
||||
|
||||
if (_iconsole_output_file!=NULL) {
|
||||
if (argc<2) return NULL;
|
||||
IConsolePrintF(_iconsole_color_default,"file output complete");
|
||||
fclose(_iconsole_output_file);
|
||||
} else {
|
||||
IConsolePrintF(_iconsole_color_default,"file output started to: %s",argv[1]);
|
||||
_iconsole_output_file = fopen(argv[1],"ab");
|
||||
if (_iconsole_output_file == NULL) IConsoleError("could not open file");
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
DEF_CONSOLE_CMD(ConEcho)
|
||||
{
|
||||
if (argc<2) return NULL;
|
||||
IConsolePrint(_iconsole_color_default, argv[1]);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
DEF_CONSOLE_CMD(ConEchoC)
|
||||
{
|
||||
if (argc<3) return NULL;
|
||||
IConsolePrint(atoi(argv[1]), argv[2]);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
DEF_CONSOLE_CMD(ConPrintF)
|
||||
{
|
||||
if (argc<3) return NULL;
|
||||
IConsolePrintF(_iconsole_color_default, argv[1] ,argv[2],argv[3],argv[4],argv[5],argv[6],argv[7],argv[8],argv[9],argv[10],argv[11],argv[12],argv[13],argv[14],argv[15],argv[16],argv[17],argv[18],argv[19]);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
DEF_CONSOLE_CMD(ConPrintFC)
|
||||
{
|
||||
if (argc<3) return NULL;
|
||||
IConsolePrintF(atoi(argv[1]), argv[2] ,argv[3],argv[4],argv[5],argv[6],argv[7],argv[8],argv[9],argv[10],argv[11],argv[12],argv[13],argv[14],argv[15],argv[16],argv[17],argv[18],argv[19]);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
DEF_CONSOLE_CMD(ConScreenShot)
|
||||
{
|
||||
if (argc<2) {
|
||||
_make_screenshot=1;
|
||||
} else {
|
||||
if (strcmp(argv[1],"big")==0) {
|
||||
_make_screenshot=2;
|
||||
}
|
||||
if (strcmp(argv[1],"no_con")==0) {
|
||||
IConsoleClose();
|
||||
_make_screenshot=1;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
DEF_CONSOLE_CMD(ConInfoVar)
|
||||
{
|
||||
if (argc<2) return NULL;
|
||||
if (argt[1]!=ICONSOLE_VAR_REFERENCE) {
|
||||
IConsoleError("first argument has to be a variable reference");
|
||||
} else {
|
||||
_iconsole_var * item;
|
||||
item = (_iconsole_var *) argv[1];
|
||||
IConsolePrintF(_iconsole_color_default,"var_name: %s",item->name);
|
||||
IConsolePrintF(_iconsole_color_default,"var_type: %i",item->type);
|
||||
IConsolePrintF(_iconsole_color_default,"var_addr: %i",item->addr);
|
||||
if (item->_malloc) IConsolePrintF(_iconsole_color_default,"var_malloc: internal");
|
||||
else IConsolePrintF(_iconsole_color_default, "var_malloc: external");
|
||||
if (item->hook_access) IConsoleWarning("var_access hooked");
|
||||
if (item->hook_before_change) IConsoleWarning("var_before_change hooked");
|
||||
if (item->hook_after_change) IConsoleWarning("var_after_change hooked");
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
DEF_CONSOLE_CMD(ConInfoCmd)
|
||||
{
|
||||
if (argc<2) return NULL;
|
||||
if (argt[1]!=ICONSOLE_VAR_UNKNOWN) {
|
||||
IConsoleError("first argument has to be a command name");
|
||||
} else {
|
||||
_iconsole_cmd * item;
|
||||
item = IConsoleCmdGet(argv[1]);
|
||||
if (item==NULL) {
|
||||
IConsoleError("the given command was not found");
|
||||
return NULL;
|
||||
}
|
||||
IConsolePrintF(_iconsole_color_default,"cmd_name: %s",item->name);
|
||||
IConsolePrintF(_iconsole_color_default,"cmd_addr: %i",item->addr);
|
||||
if (item->hook_access) IConsoleWarning("cmd_access hooked");
|
||||
if (item->hook_before_exec) IConsoleWarning("cmd_before_exec hooked");
|
||||
if (item->hook_after_exec) IConsoleWarning("cmd_after_exec hooked");
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
DEF_CONSOLE_CMD(ConDebugLevel)
|
||||
{
|
||||
if (argc<2) return NULL;
|
||||
SetDebugString(argv[1]);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
DEF_CONSOLE_CMD(ConExit)
|
||||
{
|
||||
_exit_game = true;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
DEF_CONSOLE_CMD(ConHelp)
|
||||
{
|
||||
IConsolePrint(13 ," -- console help -- ");
|
||||
IConsolePrint(1 ," variables: [command to list them: list_vars]");
|
||||
IConsolePrint(1 ," *temp_string = \"my little \"");
|
||||
IConsolePrint(1 ,"");
|
||||
IConsolePrint(1 ," commands: [command to list them: list_cmds]");
|
||||
IConsolePrint(1 ," [command] [\"string argument with spaces\"] [argument 2] ...");
|
||||
IConsolePrint(1 ," printf \"%s world\" *temp_string");
|
||||
IConsolePrint(1 ,"");
|
||||
IConsolePrint(1 ," command/variable returning a value into an variable:");
|
||||
IConsolePrint(1 ," *temp_uint16 << random");
|
||||
IConsolePrint(1 ," *temp_uint16 << *temp_uint16_2");
|
||||
IConsolePrint(1 ,"");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
DEF_CONSOLE_CMD(ConRandom)
|
||||
{
|
||||
_iconsole_var * result;
|
||||
result = IConsoleVarAlloc(ICONSOLE_VAR_UINT16);
|
||||
IConsoleVarSetValue(result,rand());
|
||||
return result;
|
||||
}
|
||||
|
||||
DEF_CONSOLE_CMD(ConListCommands)
|
||||
{
|
||||
_iconsole_cmd * item;
|
||||
int l = 0;
|
||||
|
||||
if (argv[1]!=NULL) l = strlen((char *) argv[1]);
|
||||
|
||||
item = _iconsole_cmds;
|
||||
while (item != NULL) {
|
||||
if (argv[1]!=NULL) {
|
||||
|
||||
if (memcmp((void *) item->name, (void *) argv[1],l)==0)
|
||||
IConsolePrintF(_iconsole_color_default,"%s",item->name);
|
||||
|
||||
} else {
|
||||
|
||||
IConsolePrintF(_iconsole_color_default,"%s",item->name);
|
||||
|
||||
}
|
||||
item = item->_next;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
DEF_CONSOLE_CMD(ConListVariables)
|
||||
{
|
||||
_iconsole_var * item;
|
||||
int l = 0;
|
||||
|
||||
if (argv[1]!=NULL) l = strlen((char *) argv[1]);
|
||||
|
||||
item = _iconsole_vars;
|
||||
while (item != NULL) {
|
||||
if (argv[1]!=NULL) {
|
||||
|
||||
if (memcmp(item->name, argv[1],l)==0)
|
||||
IConsolePrintF(_iconsole_color_default,"%s",item->name);
|
||||
|
||||
} else {
|
||||
|
||||
IConsolePrintF(_iconsole_color_default,"%s",item->name);
|
||||
|
||||
}
|
||||
item = item->_next;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
DEF_CONSOLE_CMD(ConListDumpVariables)
|
||||
{
|
||||
_iconsole_var * item;
|
||||
int l = 0;
|
||||
|
||||
if (argv[1]!=NULL) l = strlen((char *) argv[1]);
|
||||
|
||||
item = _iconsole_vars;
|
||||
while (item != NULL) {
|
||||
if (argv[1]!=NULL) {
|
||||
|
||||
if (memcmp(item->name, argv[1],l)==0)
|
||||
IConsoleVarDump(item,NULL);
|
||||
|
||||
} else {
|
||||
|
||||
IConsoleVarDump(item,NULL);
|
||||
|
||||
}
|
||||
item = item->_next;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifdef _DEBUG
|
||||
/* ****************************************** */
|
||||
/* debug commands and variables */
|
||||
/* ****************************************** */
|
||||
|
||||
void IConsoleDebugLibRegister()
|
||||
{
|
||||
// stdlib
|
||||
extern bool _stdlib_con_developer;
|
||||
|
||||
IConsoleVarRegister("con_developer",(void *) &_stdlib_con_developer,ICONSOLE_VAR_BOOLEAN);
|
||||
IConsoleVarMemRegister("temp_bool",ICONSOLE_VAR_BOOLEAN);
|
||||
IConsoleVarMemRegister("temp_int16",ICONSOLE_VAR_INT16);
|
||||
IConsoleVarMemRegister("temp_int32",ICONSOLE_VAR_INT32);
|
||||
IConsoleVarMemRegister("temp_pointer",ICONSOLE_VAR_POINTER);
|
||||
IConsoleVarMemRegister("temp_uint16",ICONSOLE_VAR_UINT16);
|
||||
IConsoleVarMemRegister("temp_uint16_2",ICONSOLE_VAR_UINT16);
|
||||
IConsoleVarMemRegister("temp_uint32",ICONSOLE_VAR_UINT32);
|
||||
IConsoleVarMemRegister("temp_string",ICONSOLE_VAR_STRING);
|
||||
IConsoleVarMemRegister("temp_string2",ICONSOLE_VAR_STRING);
|
||||
IConsoleCmdRegister("resettile",ConResetTile);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* ****************************************** */
|
||||
/* console command and variable registration */
|
||||
/* ****************************************** */
|
||||
|
||||
void IConsoleStdLibRegister()
|
||||
{
|
||||
// stdlib
|
||||
extern byte _stdlib_developer;
|
||||
|
||||
#ifdef _DEBUG
|
||||
IConsoleDebugLibRegister();
|
||||
#else
|
||||
(void)ConResetTile; // Silence warning, this is only used in _DEBUG
|
||||
#endif
|
||||
|
||||
// functions [please add them alphabeticaly]
|
||||
#ifdef ENABLE_NETWORK
|
||||
IConsoleCmdRegister("connect",ConNetworkConnect);
|
||||
IConsoleCmdHook("connect",ICONSOLE_HOOK_ACCESS,ConCmdHookNoNetwork);
|
||||
#endif
|
||||
IConsoleCmdRegister("debug_level",ConDebugLevel);
|
||||
IConsoleCmdRegister("dump_vars",ConListDumpVariables);
|
||||
IConsoleCmdRegister("echo",ConEcho);
|
||||
IConsoleCmdRegister("echoc",ConEchoC);
|
||||
IConsoleCmdRegister("exec",ConExec);
|
||||
IConsoleCmdRegister("exit",ConExit);
|
||||
IConsoleCmdRegister("help",ConHelp);
|
||||
IConsoleCmdRegister("info_cmd",ConInfoCmd);
|
||||
IConsoleCmdRegister("info_var",ConInfoVar);
|
||||
IConsoleCmdRegister("list_cmds",ConListCommands);
|
||||
IConsoleCmdRegister("list_vars",ConListVariables);
|
||||
IConsoleCmdRegister("printf",ConPrintF);
|
||||
IConsoleCmdRegister("printfc",ConPrintFC);
|
||||
IConsoleCmdRegister("quit",ConExit);
|
||||
IConsoleCmdRegister("random",ConRandom);
|
||||
IConsoleCmdRegister("resetengines",ConResetEngines);
|
||||
IConsoleCmdHook("resetengines",ICONSOLE_HOOK_ACCESS,ConCmdHookNoNetwork);
|
||||
IConsoleCmdRegister("return",ConReturn);
|
||||
IConsoleCmdRegister("screenshot",ConScreenShot);
|
||||
IConsoleCmdRegister("script",ConScript);
|
||||
IConsoleCmdRegister("scrollto",ConScrollToTile);
|
||||
|
||||
// variables [please add them alphabeticaly]
|
||||
IConsoleVarRegister("developer",(void *) &_stdlib_developer,ICONSOLE_VAR_BYTE);
|
||||
#ifdef ENABLE_NETWORK
|
||||
IConsoleVarRegister("net_client_timeout",&_network_client_timeout,ICONSOLE_VAR_UINT16);
|
||||
IConsoleVarHook("*net_client_timeout",ICONSOLE_HOOK_ACCESS,ConVarHookNoNetClient);
|
||||
IConsoleVarRegister("net_ready_ahead",&_network_ready_ahead,ICONSOLE_VAR_UINT16);
|
||||
IConsoleVarRegister("net_sync_freq",&_network_sync_freq,ICONSOLE_VAR_UINT16);
|
||||
IConsoleVarHook("*net_sync_freq",ICONSOLE_HOOK_ACCESS,ConVarHookNoNetClient);
|
||||
#endif
|
||||
|
||||
|
||||
}
|
||||
/* -------------------- dont cross this line --------------------- */
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -1,980 +0,0 @@
|
|||
#include "stdafx.h"
|
||||
#include "ttd.h"
|
||||
#include "vehicle.h"
|
||||
#include "command.h"
|
||||
#include "news.h"
|
||||
#include "gfx.h"
|
||||
#include "station.h"
|
||||
#include "town.h"
|
||||
#include "industry.h"
|
||||
#include "player.h"
|
||||
#include "airport_movement.h"
|
||||
|
||||
static void DisasterClearSquare(uint tile)
|
||||
{
|
||||
int type;
|
||||
|
||||
if (!EnsureNoVehicle(tile))
|
||||
return;
|
||||
|
||||
type = _map_type_and_height[tile] >> 4;
|
||||
|
||||
if (type == MP_RAILWAY) {
|
||||
if (IS_HUMAN_PLAYER(_map_owner[tile]))
|
||||
DoClearSquare(tile);
|
||||
} else if (type == MP_HOUSE) {
|
||||
byte p = _current_player;
|
||||
_current_player = OWNER_NONE;
|
||||
DoCommandByTile(tile, 0, 0, DC_EXEC, CMD_LANDSCAPE_CLEAR);
|
||||
_current_player = p;
|
||||
} else if (type == MP_TREES || type == MP_CLEAR) {
|
||||
DoClearSquare(tile);
|
||||
}
|
||||
}
|
||||
|
||||
static const SpriteID _disaster_images_1[] = {0xF41,0xF41,0xF41,0xF41,0xF41,0xF41,0xF41,0xF41};
|
||||
static const SpriteID _disaster_images_2[] = {0xF44,0xF44,0xF44,0xF44,0xF44,0xF44,0xF44,0xF44};
|
||||
static const SpriteID _disaster_images_3[] = {0xF4E,0xF4E,0xF4E,0xF4E,0xF4E,0xF4E,0xF4E,0xF4E};
|
||||
static const SpriteID _disaster_images_4[] = {0xF46,0xF46,0xF47,0xF47,0xF48,0xF48,0xF49,0xF49};
|
||||
static const SpriteID _disaster_images_5[] = {0xF4A,0xF4A,0xF4B,0xF4B,0xF4C,0xF4C,0xF4D,0xF4D};
|
||||
static const SpriteID _disaster_images_6[] = {0xF50,0xF50,0xF50,0xF50,0xF50,0xF50,0xF50,0xF50};
|
||||
static const SpriteID _disaster_images_7[] = {0xF51,0xF51,0xF51,0xF51,0xF51,0xF51,0xF51,0xF51};
|
||||
static const SpriteID _disaster_images_8[] = {0xF52,0xF52,0xF52,0xF52,0xF52,0xF52,0xF52,0xF52};
|
||||
static const SpriteID _disaster_images_9[] = {0xF3E,0xF3E,0xF3E,0xF3E,0xF3E,0xF3E,0xF3E,0xF3E};
|
||||
|
||||
static const SpriteID * const _disaster_images[] = {
|
||||
_disaster_images_1,_disaster_images_1,
|
||||
_disaster_images_2,_disaster_images_2,
|
||||
_disaster_images_3,_disaster_images_3,
|
||||
_disaster_images_8,_disaster_images_8,_disaster_images_9,
|
||||
_disaster_images_6,_disaster_images_6,
|
||||
_disaster_images_7,_disaster_images_7,
|
||||
_disaster_images_4,_disaster_images_5,
|
||||
};
|
||||
|
||||
static void DisasterVehicleUpdateImage(Vehicle *v)
|
||||
{
|
||||
int img = v->u.disaster.image_override;
|
||||
if (img == 0)
|
||||
img = _disaster_images[v->subtype][v->direction];
|
||||
v->cur_image = img;
|
||||
}
|
||||
|
||||
static void InitializeDisasterVehicle(Vehicle *v, int x, int y, byte z, byte direction, byte subtype)
|
||||
{
|
||||
v->type = VEH_Disaster;
|
||||
v->x_pos = x;
|
||||
v->y_pos = y;
|
||||
v->z_pos = z;
|
||||
v->tile = TILE_FROM_XY(x,y);
|
||||
v->direction = direction;
|
||||
v->subtype = subtype;
|
||||
v->x_offs = -1;
|
||||
v->y_offs = -1;
|
||||
v->sprite_width = 2;
|
||||
v->sprite_height = 2;
|
||||
v->z_height = 5;
|
||||
v->owner = OWNER_NONE;
|
||||
v->vehstatus = VS_UNCLICKABLE;
|
||||
v->u.disaster.image_override = 0;
|
||||
v->next_order = 0;
|
||||
|
||||
DisasterVehicleUpdateImage(v);
|
||||
VehiclePositionChanged(v);
|
||||
BeginVehicleMove(v);
|
||||
EndVehicleMove(v);
|
||||
}
|
||||
|
||||
static void DeleteDisasterVeh(Vehicle *v)
|
||||
{
|
||||
DeleteVehicleChain(v);
|
||||
}
|
||||
|
||||
static void SetDisasterVehiclePos(Vehicle *v, int x, int y, byte z)
|
||||
{
|
||||
Vehicle *u;
|
||||
int yt;
|
||||
|
||||
BeginVehicleMove(v);
|
||||
v->x_pos = x;
|
||||
v->y_pos = y;
|
||||
v->z_pos = z;
|
||||
v->tile = TILE_FROM_XY(x,y);
|
||||
|
||||
DisasterVehicleUpdateImage(v);
|
||||
VehiclePositionChanged(v);
|
||||
EndVehicleMove(v);
|
||||
|
||||
if ( (u=v->next) != NULL) {
|
||||
BeginVehicleMove(u);
|
||||
|
||||
u->x_pos = x;
|
||||
u->y_pos = yt = y - 1 - (max(z - GetSlopeZ(x, y-1), 0) >> 3);
|
||||
u->z_pos = GetSlopeZ(x,yt);
|
||||
u->direction = v->direction;
|
||||
|
||||
DisasterVehicleUpdateImage(u);
|
||||
VehiclePositionChanged(u);
|
||||
EndVehicleMove(u);
|
||||
|
||||
if ( (u=u->next) != NULL) {
|
||||
BeginVehicleMove(u);
|
||||
u->x_pos = x;
|
||||
u->y_pos = y;
|
||||
u->z_pos = z + 5;
|
||||
VehiclePositionChanged(u);
|
||||
EndVehicleMove(u);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void DisasterTick_Zeppeliner(Vehicle *v)
|
||||
{
|
||||
GetNewVehiclePosResult gp;
|
||||
Station *st;
|
||||
int x,y;
|
||||
byte z;
|
||||
uint tile;
|
||||
|
||||
++v->tick_counter;
|
||||
|
||||
if (v->next_order < 2) {
|
||||
if (v->tick_counter&1)
|
||||
return;
|
||||
|
||||
GetNewVehiclePos(v, &gp);
|
||||
|
||||
SetDisasterVehiclePos(v, gp.x, gp.y, v->z_pos);
|
||||
|
||||
if (v->next_order == 1) {
|
||||
if (++v->age == 38) {
|
||||
v->next_order = 2;
|
||||
v->age = 0;
|
||||
}
|
||||
|
||||
if ((v->tick_counter&7)==0) {
|
||||
CreateEffectVehicleRel(v, 0, -17, 2, EV_SMOKE_3);
|
||||
}
|
||||
} else if (v->next_order == 0) {
|
||||
tile = v->tile; /**/
|
||||
|
||||
if (IS_TILETYPE(tile, MP_STATION) &&
|
||||
IS_BYTE_INSIDE(_map5[tile], 8, 0x43) &&
|
||||
IS_HUMAN_PLAYER(_map_owner[tile])) {
|
||||
|
||||
v->next_order = 1;
|
||||
v->age = 0;
|
||||
|
||||
SET_DPARAM16(0, _map2[tile]);
|
||||
AddNewsItem(STR_B000_ZEPPELIN_DISASTER_AT,
|
||||
NEWS_FLAGS(NM_THIN, NF_VIEWPORT|NF_VEHICLE, NT_ACCIDENT, 0),
|
||||
v->index,
|
||||
0);
|
||||
}
|
||||
}
|
||||
if (v->y_pos >= (TILES_Y+9) * 16 - 1)
|
||||
DeleteDisasterVeh(v);
|
||||
return;
|
||||
}
|
||||
|
||||
if (v->next_order > 2) {
|
||||
if (++v->age <= 13320)
|
||||
return;
|
||||
|
||||
tile = v->tile; /**/
|
||||
|
||||
if (IS_TILETYPE(tile, MP_STATION) &&
|
||||
IS_BYTE_INSIDE(_map5[tile], 8, 0x43) &&
|
||||
IS_HUMAN_PLAYER(_map_owner[tile])) {
|
||||
|
||||
st = DEREF_STATION(_map2[tile]);
|
||||
CLRBITS(st->airport_flags, RUNWAY_IN_block);
|
||||
}
|
||||
|
||||
SetDisasterVehiclePos(v, v->x_pos, v->y_pos, v->z_pos);
|
||||
DeleteDisasterVeh(v);
|
||||
return;
|
||||
}
|
||||
|
||||
x = v->x_pos;
|
||||
y = v->y_pos;
|
||||
z = GetSlopeZ(x,y);
|
||||
if (z < v->z_pos)
|
||||
z = v->z_pos - 1;
|
||||
SetDisasterVehiclePos(v, x, y, z);
|
||||
|
||||
if (++v->age == 1) {
|
||||
CreateEffectVehicleRel(v, 0, 7, 8, EV_CRASHED_SMOKE);
|
||||
SndPlayVehicleFx(0x10, v);
|
||||
v->u.disaster.image_override = 0xF42;
|
||||
} else if (v->age == 70) {
|
||||
v->u.disaster.image_override = 0xF43;
|
||||
} else if (v->age <= 300) {
|
||||
if (!(v->tick_counter&7)) {
|
||||
uint32 r = Random();
|
||||
|
||||
CreateEffectVehicleRel(v,
|
||||
-7 + (r&0xF),
|
||||
-7 + (r>>4&0xF),
|
||||
5 + (r>>8&0x7),
|
||||
EV_DEMOLISH);
|
||||
}
|
||||
} else if (v->age == 350) {
|
||||
v->next_order = 3;
|
||||
v->age = 0;
|
||||
}
|
||||
|
||||
tile = v->tile;/**/
|
||||
if (IS_TILETYPE(tile, MP_STATION) &&
|
||||
IS_BYTE_INSIDE(_map5[tile], 8, 0x43) &&
|
||||
IS_HUMAN_PLAYER(_map_owner[tile])) {
|
||||
|
||||
st = DEREF_STATION(_map2[tile]);
|
||||
SETBITS(st->airport_flags, RUNWAY_IN_block);
|
||||
}
|
||||
}
|
||||
|
||||
// UFO starts in the middle, and flies around a bit until it locates
|
||||
// a road vehicle which it targets.
|
||||
static void DisasterTick_UFO(Vehicle *v)
|
||||
{
|
||||
GetNewVehiclePosResult gp;
|
||||
Vehicle *u;
|
||||
uint dist;
|
||||
byte z;
|
||||
|
||||
v->u.disaster.image_override = (++v->tick_counter & 8) ? 0xF45 : 0xF44;
|
||||
|
||||
if (v->next_order == 0) {
|
||||
// fly around randomly
|
||||
int x = GET_TILE_X(v->dest_tile)*16;
|
||||
int y = GET_TILE_Y(v->dest_tile)*16;
|
||||
if (abs(x - v->x_pos) + abs(y - v->y_pos) >= 16) {
|
||||
v->direction = GetDirectionTowards(v, x, y);
|
||||
GetNewVehiclePos(v, &gp);
|
||||
SetDisasterVehiclePos(v, gp.x, gp.y, v->z_pos);
|
||||
return;
|
||||
}
|
||||
if (++v->age < 6) {
|
||||
v->dest_tile = TILE_MASK(Random());
|
||||
return;
|
||||
}
|
||||
v->next_order = 1;
|
||||
|
||||
FOR_ALL_VEHICLES(u) {
|
||||
if (u->type == VEH_Road && IS_HUMAN_PLAYER(u->owner)) {
|
||||
v->dest_tile = u->index;
|
||||
v->age = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
DeleteDisasterVeh(v);
|
||||
} else {
|
||||
// target a vehicle
|
||||
u = &_vehicles[v->dest_tile];
|
||||
if (u->type != VEH_Road) {
|
||||
DeleteDisasterVeh(v);
|
||||
return;
|
||||
}
|
||||
|
||||
dist = abs(v->x_pos - u->x_pos) + abs(v->y_pos - u->y_pos);
|
||||
|
||||
if (dist < 16 && !(u->vehstatus&VS_HIDDEN) && u->breakdown_ctr==0) {
|
||||
u->breakdown_ctr = 3;
|
||||
u->breakdown_delay = 140;
|
||||
}
|
||||
|
||||
v->direction = GetDirectionTowards(v, u->x_pos, u->y_pos);
|
||||
GetNewVehiclePos(v, &gp);
|
||||
|
||||
z = v->z_pos;
|
||||
if (dist <= 16 && z > u->z_pos) z--;
|
||||
SetDisasterVehiclePos(v, gp.x, gp.y, z);
|
||||
|
||||
if (z <= u->z_pos && (u->vehstatus&VS_HIDDEN)==0) {
|
||||
v->age++;
|
||||
if (u->u.road.crashed_ctr == 0) {
|
||||
u->u.road.crashed_ctr++;
|
||||
u->vehstatus |= VS_CRASHED;
|
||||
|
||||
AddNewsItem(STR_B001_ROAD_VEHICLE_DESTROYED,
|
||||
NEWS_FLAGS(NM_THIN, NF_VIEWPORT|NF_VEHICLE, NT_ACCIDENT, 0),
|
||||
u->index,
|
||||
0);
|
||||
}
|
||||
}
|
||||
|
||||
// destroy?
|
||||
if (v->age > 50) {
|
||||
CreateEffectVehicleRel(v, 0, 7, 8, EV_CRASHED_SMOKE);
|
||||
SndPlayVehicleFx(0x10, v);
|
||||
DeleteDisasterVeh(v);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void DestructIndustry(Industry *i)
|
||||
{
|
||||
uint tile;
|
||||
byte index = i - _industries;
|
||||
|
||||
for(tile=0; tile != TILES_X*TILES_Y; tile++) {
|
||||
if (IS_TILETYPE(tile, MP_INDUSTRY) && _map2[tile] == index) {
|
||||
_map_owner[tile] = 0;
|
||||
MarkTileDirtyByTile(tile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Airplane which destroys an oil refinery
|
||||
static void DisasterTick_2(Vehicle *v)
|
||||
{
|
||||
GetNewVehiclePosResult gp;
|
||||
|
||||
v->tick_counter++;
|
||||
v->u.disaster.image_override = (v->next_order == 1 && v->tick_counter&4) ? 0xF4F : 0;
|
||||
|
||||
GetNewVehiclePos(v, &gp);
|
||||
SetDisasterVehiclePos(v, gp.x, gp.y, v->z_pos);
|
||||
|
||||
if (gp.x < -160) {
|
||||
DeleteDisasterVeh(v);
|
||||
return;
|
||||
}
|
||||
|
||||
if (v->next_order == 2) {
|
||||
if (!(v->tick_counter&3)) {
|
||||
Industry *i = DEREF_INDUSTRY(v->dest_tile);
|
||||
int x = GET_TILE_X(i->xy)*16;
|
||||
int y = GET_TILE_Y(i->xy)*16;
|
||||
uint32 r = Random();
|
||||
|
||||
CreateEffectVehicleAbove(
|
||||
x + (r & 0x3F),
|
||||
y + (r >> 6 & 0x3F),
|
||||
(r >> 12 & 0xF),
|
||||
EV_DEMOLISH);
|
||||
|
||||
if (++v->age >= 55)
|
||||
v->next_order = 3;
|
||||
}
|
||||
} else if (v->next_order == 1) {
|
||||
if (++v->age == 112) {
|
||||
Industry *i;
|
||||
|
||||
v->next_order = 2;
|
||||
v->age = 0;
|
||||
|
||||
i = DEREF_INDUSTRY(v->dest_tile);
|
||||
DestructIndustry(i);
|
||||
|
||||
SET_DPARAM16(0, i->town->index);
|
||||
AddNewsItem(STR_B002_OIL_REFINERY_EXPLOSION, NEWS_FLAGS(NM_THIN,NF_VIEWPORT|NF_TILE,NT_ACCIDENT,0), i->xy, 0);
|
||||
SndPlayTileFx(0x10, i->xy);
|
||||
}
|
||||
} else if (v->next_order == 0) {
|
||||
int x,y;
|
||||
uint tile;
|
||||
int ind;
|
||||
|
||||
x = v->x_pos - 15*16;
|
||||
y = v->y_pos;
|
||||
|
||||
if ( (uint)x > (TILES_X-1) * 16-1)
|
||||
return;
|
||||
|
||||
tile = TILE_FROM_XY(x,y);
|
||||
if (!IS_TILETYPE(tile, MP_INDUSTRY))
|
||||
return;
|
||||
|
||||
v->dest_tile = ind = _map2[tile];
|
||||
|
||||
if (DEREF_INDUSTRY(ind)->type == IT_OIL_REFINERY) {
|
||||
v->next_order = 1;
|
||||
v->age = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Helicopter which destroys a factory
|
||||
static void DisasterTick_3(Vehicle *v)
|
||||
{
|
||||
GetNewVehiclePosResult gp;
|
||||
|
||||
v->tick_counter++;
|
||||
v->u.disaster.image_override = (v->next_order == 1 && v->tick_counter&4) ? 0xF53 : 0;
|
||||
|
||||
GetNewVehiclePos(v, &gp);
|
||||
SetDisasterVehiclePos(v, gp.x, gp.y, v->z_pos);
|
||||
|
||||
if (gp.x > TILES_X * 16 + 9*16 - 1) {
|
||||
DeleteDisasterVeh(v);
|
||||
return;
|
||||
}
|
||||
|
||||
if (v->next_order == 2) {
|
||||
if (!(v->tick_counter&3)) {
|
||||
Industry *i = DEREF_INDUSTRY(v->dest_tile);
|
||||
int x = GET_TILE_X(i->xy)*16;
|
||||
int y = GET_TILE_Y(i->xy)*16;
|
||||
uint32 r = Random();
|
||||
|
||||
CreateEffectVehicleAbove(
|
||||
x + (r & 0x3F),
|
||||
y + (r >> 6 & 0x3F),
|
||||
(r >> 12 & 0xF),
|
||||
EV_DEMOLISH);
|
||||
|
||||
if (++v->age >= 55)
|
||||
v->next_order = 3;
|
||||
}
|
||||
} else if (v->next_order == 1) {
|
||||
if (++v->age == 112) {
|
||||
Industry *i;
|
||||
|
||||
v->next_order = 2;
|
||||
v->age = 0;
|
||||
|
||||
i = DEREF_INDUSTRY(v->dest_tile);
|
||||
DestructIndustry(i);
|
||||
|
||||
SET_DPARAM16(0, i->town->index);
|
||||
AddNewsItem(STR_B003_FACTORY_DESTROYED_IN_SUSPICIOUS, NEWS_FLAGS(NM_THIN,NF_VIEWPORT|NF_TILE,NT_ACCIDENT,0), i->xy, 0);
|
||||
SndPlayTileFx(0x10, i->xy);
|
||||
}
|
||||
} else if (v->next_order == 0) {
|
||||
int x,y;
|
||||
uint tile;
|
||||
int ind;
|
||||
|
||||
x = v->x_pos - 15*16;
|
||||
y = v->y_pos;
|
||||
|
||||
if ( (uint)x > (TILES_X-1) * 16-1)
|
||||
return;
|
||||
|
||||
tile = TILE_FROM_XY(x,y);
|
||||
if (!IS_TILETYPE(tile, MP_INDUSTRY))
|
||||
return;
|
||||
|
||||
v->dest_tile = ind = _map2[tile];
|
||||
|
||||
if (DEREF_INDUSTRY(ind)->type == IT_FACTORY) {
|
||||
v->next_order = 1;
|
||||
v->age = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Helicopter rotor blades
|
||||
static void DisasterTick_3b(Vehicle *v)
|
||||
{
|
||||
if (++v->tick_counter & 1)
|
||||
return;
|
||||
|
||||
if (++v->cur_image == 0xF40 + 1)
|
||||
v->cur_image = 0xF3E;
|
||||
|
||||
VehiclePositionChanged(v);
|
||||
BeginVehicleMove(v);
|
||||
EndVehicleMove(v);
|
||||
}
|
||||
|
||||
// Big UFO which lands on a piece of rail.
|
||||
// Will be shot down by a plane
|
||||
static void DisasterTick_4(Vehicle *v)
|
||||
{
|
||||
GetNewVehiclePosResult gp;
|
||||
byte z;
|
||||
Vehicle *u,*w;
|
||||
Town *t;
|
||||
uint tile,tile_org;
|
||||
|
||||
v->tick_counter++;
|
||||
|
||||
if (v->next_order == 1) {
|
||||
int x = GET_TILE_X(v->dest_tile)*16 + 8;
|
||||
int y = GET_TILE_Y(v->dest_tile)*16 + 8;
|
||||
if (abs(v->x_pos - x) + abs(v->y_pos - y) >= 8) {
|
||||
v->direction = GetDirectionTowards(v, x, y);
|
||||
|
||||
GetNewVehiclePos(v, &gp);
|
||||
SetDisasterVehiclePos(v, gp.x, gp.y, v->z_pos);
|
||||
return;
|
||||
}
|
||||
|
||||
z = GetSlopeZ(v->x_pos, v->y_pos);
|
||||
if (z < v->z_pos) {
|
||||
SetDisasterVehiclePos(v, v->x_pos, v->y_pos, v->z_pos - 1);
|
||||
return;
|
||||
}
|
||||
|
||||
v->next_order = 2;
|
||||
|
||||
FOR_ALL_VEHICLES(u) {
|
||||
if (u->type == VEH_Train || u->type == VEH_Road) {
|
||||
if (abs(u->x_pos - v->x_pos) + abs(u->y_pos - v->y_pos) <= 12*16) {
|
||||
u->breakdown_ctr = 5;
|
||||
u->breakdown_delay = 0xF0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
t = ClosestTownFromTile(v->dest_tile, (uint)-1);
|
||||
SET_DPARAM16(0, t->index);
|
||||
AddNewsItem(STR_B004_UFO_LANDS_NEAR,
|
||||
NEWS_FLAGS(NM_THIN, NF_VIEWPORT|NF_TILE, NT_ACCIDENT, 0),
|
||||
v->tile,
|
||||
0);
|
||||
|
||||
u = ForceAllocateSpecialVehicle();
|
||||
if (u == NULL) {
|
||||
DeleteDisasterVeh(v);
|
||||
return;
|
||||
}
|
||||
|
||||
InitializeDisasterVehicle(u, -6*16, v->y_pos, 135, 5, 11);
|
||||
u->u.disaster.unk2 = v->index;
|
||||
|
||||
w = ForceAllocateSpecialVehicle();
|
||||
if (w == NULL)
|
||||
return;
|
||||
|
||||
u->next = w;
|
||||
InitializeDisasterVehicle(w, -6*16, v->y_pos, 0, 5, 12);
|
||||
w->vehstatus |= VS_DISASTER;
|
||||
} else if (v->next_order < 1) {
|
||||
|
||||
int x = GET_TILE_X(v->dest_tile)*16;
|
||||
int y = GET_TILE_Y(v->dest_tile)*16;
|
||||
if (abs(x - v->x_pos) + abs(y - v->y_pos) >= 16) {
|
||||
v->direction = GetDirectionTowards(v, x, y);
|
||||
GetNewVehiclePos(v, &gp);
|
||||
SetDisasterVehiclePos(v, gp.x, gp.y, v->z_pos);
|
||||
return;
|
||||
}
|
||||
|
||||
if (++v->age < 6) {
|
||||
v->dest_tile = TILE_MASK(Random());
|
||||
return;
|
||||
}
|
||||
v->next_order = 1;
|
||||
|
||||
tile_org = tile = TILE_MASK(Random());
|
||||
do {
|
||||
if (IS_TILETYPE(tile, MP_RAILWAY) &&
|
||||
(_map5[tile]&~3)!=0xC0 && IS_HUMAN_PLAYER(_map_owner[tile]))
|
||||
break;
|
||||
tile = TILE_MASK(tile+1);
|
||||
} while (tile != tile_org);
|
||||
v->dest_tile = tile;
|
||||
v->age = 0;
|
||||
} else
|
||||
return;
|
||||
}
|
||||
|
||||
// The plane which will shoot down the UFO
|
||||
static void DisasterTick_4b(Vehicle *v)
|
||||
{
|
||||
GetNewVehiclePosResult gp;
|
||||
Vehicle *u;
|
||||
int i;
|
||||
|
||||
v->tick_counter++;
|
||||
|
||||
GetNewVehiclePos(v, &gp);
|
||||
SetDisasterVehiclePos(v, gp.x, gp.y, v->z_pos);
|
||||
|
||||
if (gp.x > TILES_X * 16 + 9*16 - 1) {
|
||||
DeleteDisasterVeh(v);
|
||||
return;
|
||||
}
|
||||
|
||||
if (v->next_order == 0) {
|
||||
u = &_vehicles[v->u.disaster.unk2];
|
||||
if (abs(v->x_pos - u->x_pos) > 16)
|
||||
return;
|
||||
v->next_order = 1;
|
||||
|
||||
CreateEffectVehicleRel(u, 0, 7, 8, EV_CRASHED_SMOKE);
|
||||
SndPlayVehicleFx(0x10, u);
|
||||
|
||||
DeleteDisasterVeh(u);
|
||||
|
||||
for(i=0; i!=80; i++) {
|
||||
uint32 r = Random();
|
||||
CreateEffectVehicleAbove(
|
||||
v->x_pos-32+(r&0x3F),
|
||||
v->y_pos-32+(r>>5&0x3F),
|
||||
0,
|
||||
EV_DEMOLISH);
|
||||
}
|
||||
|
||||
BEGIN_TILE_LOOP(tile,6,6,v->tile - TILE_XY(3,3))
|
||||
tile = TILE_MASK(tile);
|
||||
DisasterClearSquare(tile);
|
||||
END_TILE_LOOP(tile,6,6,v->tile - TILE_XY(3,3))
|
||||
}
|
||||
}
|
||||
|
||||
// Submarine handler
|
||||
static void DisasterTick_5_and_6(Vehicle *v)
|
||||
{
|
||||
uint32 r;
|
||||
GetNewVehiclePosResult gp;
|
||||
uint tile;
|
||||
|
||||
v->tick_counter++;
|
||||
|
||||
if (++v->age > 8880) {
|
||||
VehiclePositionChanged(v);
|
||||
BeginVehicleMove(v);
|
||||
EndVehicleMove(v);
|
||||
DeleteVehicle(v);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(v->tick_counter&1))
|
||||
return;
|
||||
|
||||
tile = v->tile + _tileoffs_by_dir[v->direction >> 1];
|
||||
if (IsValidTile(tile) &&
|
||||
(r=GetTileTrackStatus(tile,TRANSPORT_WATER),(byte)(r+(r >> 8)) == 0x3F) &&
|
||||
!CHANCE16(1,90)) {
|
||||
GetNewVehiclePos(v, &gp);
|
||||
SetDisasterVehiclePos(v, gp.x, gp.y, v->z_pos);
|
||||
return;
|
||||
}
|
||||
|
||||
v->direction = (v->direction + ((Random()&1)?2:-2))&7;
|
||||
}
|
||||
|
||||
|
||||
static void DisasterTick_NULL(Vehicle *v) {}
|
||||
typedef void DisasterVehicleTickProc(Vehicle *v);
|
||||
|
||||
static DisasterVehicleTickProc * const _disastervehicle_tick_procs[] = {
|
||||
DisasterTick_Zeppeliner,DisasterTick_NULL,
|
||||
DisasterTick_UFO,DisasterTick_NULL,
|
||||
DisasterTick_2,DisasterTick_NULL,
|
||||
DisasterTick_3,DisasterTick_NULL,DisasterTick_3b,
|
||||
DisasterTick_4,DisasterTick_NULL,
|
||||
DisasterTick_4b,DisasterTick_NULL,
|
||||
DisasterTick_5_and_6,
|
||||
DisasterTick_5_and_6,
|
||||
};
|
||||
|
||||
|
||||
void DisasterVehicle_Tick(Vehicle *v)
|
||||
{
|
||||
_disastervehicle_tick_procs[v->subtype](v);
|
||||
}
|
||||
|
||||
void HandleClickOnDisasterVeh(Vehicle *v)
|
||||
{
|
||||
// not used
|
||||
}
|
||||
|
||||
void OnNewDay_DisasterVehicle(Vehicle *v)
|
||||
{
|
||||
// not used
|
||||
}
|
||||
|
||||
typedef void DisasterInitProc();
|
||||
|
||||
// Zeppeliner which crashes on a small airport
|
||||
static void Disaster0_Init()
|
||||
{
|
||||
Vehicle *v = ForceAllocateSpecialVehicle(), *u;
|
||||
Station *st;
|
||||
int x;
|
||||
|
||||
if (v == NULL)
|
||||
return;
|
||||
|
||||
for(st=_stations;;) {
|
||||
if (st->xy && st->airport_tile != 0 &&
|
||||
st->airport_type <= 1 &&
|
||||
IS_HUMAN_PLAYER(st->owner)) {
|
||||
x = (GET_TILE_X(st->xy) + 2) * 16;
|
||||
break;
|
||||
}
|
||||
|
||||
if (++st == endof(_stations)) {
|
||||
x = (GET_TILE_X(Random())) * 16 + 8;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
InitializeDisasterVehicle(v, x, 0, 135, 3, 0);
|
||||
|
||||
// Allocate shadow too?
|
||||
u = ForceAllocateSpecialVehicle();
|
||||
if (u != NULL) {
|
||||
v->next = u;
|
||||
InitializeDisasterVehicle(u,x,0,0,3,1);
|
||||
u->vehstatus |= VS_DISASTER;
|
||||
}
|
||||
}
|
||||
|
||||
static void Disaster1_Init()
|
||||
{
|
||||
Vehicle *v = ForceAllocateSpecialVehicle(), *u;
|
||||
int x;
|
||||
|
||||
if (v == NULL)
|
||||
return;
|
||||
|
||||
x = (GET_TILE_X(Random())) * 16 + 8;
|
||||
|
||||
InitializeDisasterVehicle(v, x, 0, 135, 3, 2);
|
||||
v->dest_tile = TILE_XY(TILES_X/2,TILES_Y/2);
|
||||
v->age = 0;
|
||||
|
||||
// Allocate shadow too?
|
||||
u = ForceAllocateSpecialVehicle();
|
||||
if (u != NULL) {
|
||||
v->next = u;
|
||||
InitializeDisasterVehicle(u,x,0,0,3,3);
|
||||
u->vehstatus |= VS_DISASTER;
|
||||
}
|
||||
}
|
||||
|
||||
static void Disaster2_Init()
|
||||
{
|
||||
Industry *i, *found;
|
||||
Vehicle *v,*u;
|
||||
int x,y;
|
||||
|
||||
for(found=NULL,i=_industries; i != endof(_industries); i++) {
|
||||
if (i->xy != 0 &&
|
||||
i->type == IT_OIL_REFINERY &&
|
||||
(found==NULL || CHANCE16(1,2))) {
|
||||
found = i;
|
||||
}
|
||||
}
|
||||
|
||||
if (found == NULL)
|
||||
return;
|
||||
|
||||
v = ForceAllocateSpecialVehicle();
|
||||
if (v == NULL)
|
||||
return;
|
||||
|
||||
x = (TILES_X+9) * 16 - 1;
|
||||
y = GET_TILE_Y(found->xy)*16 + 37;
|
||||
|
||||
InitializeDisasterVehicle(v,x,y, 135,1,4);
|
||||
|
||||
u = ForceAllocateSpecialVehicle();
|
||||
if (u != NULL) {
|
||||
v->next = u;
|
||||
InitializeDisasterVehicle(u,x,y,0,3,5);
|
||||
u->vehstatus |= VS_DISASTER;
|
||||
}
|
||||
}
|
||||
|
||||
static void Disaster3_Init()
|
||||
{
|
||||
Industry *i, *found;
|
||||
Vehicle *v,*u,*w;
|
||||
int x,y;
|
||||
|
||||
for(found=NULL,i=_industries; i != endof(_industries); i++) {
|
||||
if (i->xy != 0 &&
|
||||
i->type == IT_FACTORY &&
|
||||
(found==NULL || CHANCE16(1,2))) {
|
||||
found = i;
|
||||
}
|
||||
}
|
||||
|
||||
if (found == NULL)
|
||||
return;
|
||||
|
||||
v = ForceAllocateSpecialVehicle();
|
||||
if (v == NULL)
|
||||
return;
|
||||
|
||||
x = -16 * 16;
|
||||
y = GET_TILE_Y(found->xy)*16 + 37;
|
||||
|
||||
InitializeDisasterVehicle(v,x,y, 135,5,6);
|
||||
|
||||
u = ForceAllocateSpecialVehicle();
|
||||
if (u != NULL) {
|
||||
v->next = u;
|
||||
InitializeDisasterVehicle(u,x,y,0,5,7);
|
||||
u->vehstatus |= VS_DISASTER;
|
||||
|
||||
w = ForceAllocateSpecialVehicle();
|
||||
if (w != NULL) {
|
||||
u->next = w;
|
||||
InitializeDisasterVehicle(w,x,y,140,5,8);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void Disaster4_Init()
|
||||
{
|
||||
Vehicle *v = ForceAllocateSpecialVehicle(), *u;
|
||||
int x,y;
|
||||
|
||||
if (v == NULL)
|
||||
return;
|
||||
|
||||
x = (GET_TILE_X(Random())) * 16 + 8;
|
||||
|
||||
y = (TILES_X-1)*16-1;
|
||||
InitializeDisasterVehicle(v, x, y, 135, 7, 9);
|
||||
v->dest_tile = TILE_XY(TILES_X/2,TILES_Y/2);
|
||||
v->age = 0;
|
||||
|
||||
// Allocate shadow too?
|
||||
u = ForceAllocateSpecialVehicle();
|
||||
if (u != NULL) {
|
||||
v->next = u;
|
||||
InitializeDisasterVehicle(u,x,y,0,7,10);
|
||||
u->vehstatus |= VS_DISASTER;
|
||||
}
|
||||
}
|
||||
|
||||
// Submarine type 1
|
||||
static void Disaster5_Init()
|
||||
{
|
||||
Vehicle *v = ForceAllocateSpecialVehicle();
|
||||
int x,y;
|
||||
byte dir;
|
||||
uint32 r;
|
||||
|
||||
if (v == NULL)
|
||||
return;
|
||||
|
||||
r = Random();
|
||||
x = (GET_TILE_X(r)) * 16 + 8;
|
||||
|
||||
y = 8;
|
||||
dir = 3;
|
||||
if (r & 0x80000000) { y = (TILES_X-1) * 16 - 8 - 1; dir = 7; }
|
||||
InitializeDisasterVehicle(v, x, y, 0, dir,13);
|
||||
v->age = 0;
|
||||
}
|
||||
|
||||
// Submarine type 2
|
||||
static void Disaster6_Init()
|
||||
{
|
||||
Vehicle *v = ForceAllocateSpecialVehicle();
|
||||
int x,y;
|
||||
byte dir;
|
||||
uint32 r;
|
||||
|
||||
if (v == NULL)
|
||||
return;
|
||||
|
||||
r = Random();
|
||||
x = (GET_TILE_X(r)) * 16 + 8;
|
||||
|
||||
y = 8;
|
||||
dir = 3;
|
||||
if (r & 0x80000000) { y = (TILES_X-1) * 16 - 8 - 1; dir = 7; }
|
||||
InitializeDisasterVehicle(v, x, y, 0, dir,14);
|
||||
v->age = 0;
|
||||
}
|
||||
|
||||
static void Disaster7_Init()
|
||||
{
|
||||
Industry *i;
|
||||
int maxloop = 15;
|
||||
int index = Random() & 0xF;
|
||||
|
||||
do {
|
||||
for(i=_industries; i != endof(_industries); i++) {
|
||||
if (i->xy != 0 && i->type == IT_COAL_MINE && --index < 0) {
|
||||
|
||||
SET_DPARAM16(0, i->town->index);
|
||||
AddNewsItem(STR_B005_COAL_MINE_SUBSIDENCE_LEAVES,
|
||||
NEWS_FLAGS(NM_THIN,NF_VIEWPORT|NF_TILE,NT_ACCIDENT,0), i->xy + TILE_XY(1,1), 0);
|
||||
|
||||
{
|
||||
uint tile = i->xy;
|
||||
int step = _tileoffs_by_dir[Random() & 3];
|
||||
int count = 30;
|
||||
do {
|
||||
DisasterClearSquare(tile);
|
||||
tile = TILE_MASK(tile + step);
|
||||
} while (--count);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
} while (--maxloop != 0);
|
||||
}
|
||||
|
||||
static DisasterInitProc * const _disaster_initprocs[] = {
|
||||
Disaster0_Init,
|
||||
Disaster1_Init,
|
||||
Disaster2_Init,
|
||||
Disaster3_Init,
|
||||
Disaster4_Init,
|
||||
Disaster5_Init,
|
||||
Disaster6_Init,
|
||||
Disaster7_Init,
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
byte min,max;
|
||||
} DisasterYears;
|
||||
|
||||
#define MK(a,b) {a-20,b-20}
|
||||
static const DisasterYears _dis_years[8] = {
|
||||
MK(30,55),
|
||||
MK(40,70),
|
||||
MK(60,90),
|
||||
MK(70,100),
|
||||
MK(100,200),
|
||||
MK(40,65),
|
||||
MK(75,110),
|
||||
MK(50,85),
|
||||
};
|
||||
|
||||
|
||||
void DoDisaster()
|
||||
{
|
||||
byte buf[8];
|
||||
byte year = _cur_year;
|
||||
int i,j;
|
||||
|
||||
for(i=j=0; i!=lengthof(_dis_years); i++) {
|
||||
if (year >= _dis_years[i].min &&
|
||||
year < _dis_years[i].max)
|
||||
buf[j++] = i;
|
||||
}
|
||||
|
||||
if (j == 0)
|
||||
return;
|
||||
|
||||
_disaster_initprocs[buf[(uint16)Random() * j >> 16]]();
|
||||
}
|
||||
|
||||
|
||||
static void ResetDisasterDelay()
|
||||
{
|
||||
_disaster_delay = (int)(Random() & 0x1FF) + 730;
|
||||
}
|
||||
|
||||
void DisasterDailyLoop()
|
||||
{
|
||||
if (--_disaster_delay != 0)
|
||||
return;
|
||||
|
||||
ResetDisasterDelay();
|
||||
|
||||
if (_opt.diff.disasters != 0)
|
||||
DoDisaster();
|
||||
}
|
||||
|
||||
void StartupDisasters() {
|
||||
ResetDisasterDelay();
|
||||
}
|
||||
|
323
trunk/dock_gui.c
323
trunk/dock_gui.c
|
@ -1,323 +0,0 @@
|
|||
#include "stdafx.h"
|
||||
#include "ttd.h"
|
||||
|
||||
#include "window.h"
|
||||
#include "gui.h"
|
||||
#include "viewport.h"
|
||||
#include "gfx.h"
|
||||
#include "command.h"
|
||||
|
||||
static void ShowBuildDockStationPicker();
|
||||
static void ShowBuildDocksDepotPicker();
|
||||
|
||||
static byte _ship_depot_direction;
|
||||
|
||||
static void CcBuildDocks(bool success, uint tile, uint32 p1, uint32 p2)
|
||||
{
|
||||
if (success) {
|
||||
SndPlayTileFx(0, tile);
|
||||
ResetObjectToPlace();
|
||||
}
|
||||
}
|
||||
|
||||
static void CcBuildCanal(bool success, uint tile, uint32 p1, uint32 p2)
|
||||
{
|
||||
if (success) { SndPlayTileFx(0, tile); }
|
||||
}
|
||||
|
||||
|
||||
static void PlaceDocks_Dock(uint tile)
|
||||
{
|
||||
DoCommandP(tile, 0, 0, CcBuildDocks, CMD_BUILD_DOCK | CMD_AUTO | CMD_MSG(STR_9802_CAN_T_BUILD_DOCK_HERE));
|
||||
}
|
||||
|
||||
static void PlaceDocks_Depot(uint tile)
|
||||
{
|
||||
DoCommandP(tile, _ship_depot_direction, 0, CcBuildDocks, CMD_BUILD_SHIP_DEPOT | CMD_AUTO | CMD_MSG(STR_3802_CAN_T_BUILD_SHIP_DEPOT));
|
||||
}
|
||||
|
||||
static void PlaceDocks_Buoy(uint tile)
|
||||
{
|
||||
DoCommandP(tile, 0, 0, CcBuildDocks, CMD_BUILD_BUOY | CMD_AUTO | CMD_MSG(STR_9835_CAN_T_POSITION_BUOY_HERE));
|
||||
}
|
||||
|
||||
static void PlaceDocks_DemolishArea(uint tile)
|
||||
{
|
||||
VpStartPlaceSizing(tile, VPM_X_AND_Y);
|
||||
}
|
||||
|
||||
static void PlaceDocks_BuildCanal(uint tile)
|
||||
{
|
||||
VpStartPlaceSizing(tile, VPM_X_OR_Y);
|
||||
}
|
||||
|
||||
static void PlaceDocks_BuildLock(uint tile)
|
||||
{
|
||||
DoCommandP(tile, 0, 0, CcBuildDocks, CMD_BUILD_LOCK | CMD_AUTO | CMD_MSG(STR_CANT_BUILD_LOCKS));
|
||||
}
|
||||
|
||||
|
||||
static void BuildDocksClick_Dock(Window *w)
|
||||
{
|
||||
|
||||
if (HandlePlacePushButton(w, 2, 0xE54, 3, PlaceDocks_Dock)) ShowBuildDockStationPicker();
|
||||
}
|
||||
|
||||
static void BuildDocksClick_Depot(Window *w)
|
||||
{
|
||||
if (HandlePlacePushButton(w, 3, 0x2D1, 1, PlaceDocks_Depot)) ShowBuildDocksDepotPicker();
|
||||
}
|
||||
|
||||
static void BuildDocksClick_Buoy(Window *w)
|
||||
{
|
||||
HandlePlacePushButton(w, 4, 0x2BE, 1, PlaceDocks_Buoy);
|
||||
}
|
||||
|
||||
static void BuildDocksClick_Demolish(Window *w)
|
||||
{
|
||||
HandlePlacePushButton(w, 5, ANIMCURSOR_DEMOLISH, 1, PlaceDocks_DemolishArea);
|
||||
}
|
||||
|
||||
static void BuildDocksClick_Lower(Window *w)
|
||||
{
|
||||
HandlePlacePushButton(w, 6, ANIMCURSOR_LOWERLAND, 2, PlaceProc_LowerLand);
|
||||
}
|
||||
|
||||
static void BuildDocksClick_Raise(Window *w)
|
||||
{
|
||||
HandlePlacePushButton(w, 7, ANIMCURSOR_RAISELAND, 2, PlaceProc_RaiseLand);
|
||||
}
|
||||
|
||||
static void BuildDocksClick_Purchase(Window *w)
|
||||
{
|
||||
HandlePlacePushButton(w, 8, 0x12B8, 1, PlaceProc_BuyLand);
|
||||
}
|
||||
|
||||
static void BuildDocksClick_Canal(Window *w)
|
||||
{
|
||||
HandlePlacePushButton(w, 9, SPR_OPENTTD_BASE + 11, 1, PlaceDocks_BuildCanal);
|
||||
}
|
||||
|
||||
static void BuildDocksClick_Lock(Window *w)
|
||||
{
|
||||
HandlePlacePushButton(w, 10, SPR_OPENTTD_BASE + 64, 1, PlaceDocks_BuildLock);
|
||||
}
|
||||
|
||||
typedef void OnButtonClick(Window *w);
|
||||
static OnButtonClick * const _build_docks_button_proc[] = {
|
||||
BuildDocksClick_Dock,
|
||||
BuildDocksClick_Depot,
|
||||
BuildDocksClick_Buoy,
|
||||
BuildDocksClick_Demolish,
|
||||
BuildDocksClick_Lower,
|
||||
BuildDocksClick_Raise,
|
||||
BuildDocksClick_Purchase,
|
||||
BuildDocksClick_Canal,
|
||||
BuildDocksClick_Lock,
|
||||
};
|
||||
|
||||
static void BuildDocksToolbWndProc(Window *w, WindowEvent *e)
|
||||
{
|
||||
switch(e->event) {
|
||||
case WE_PAINT:
|
||||
DrawWindowWidgets(w);
|
||||
break;
|
||||
|
||||
case WE_CLICK: {
|
||||
if (e->click.widget - 2 >= 0) _build_docks_button_proc[e->click.widget - 2](w);
|
||||
} break;
|
||||
|
||||
case WE_PLACE_OBJ:
|
||||
_place_proc(e->place.tile);
|
||||
break;
|
||||
|
||||
case WE_PLACE_DRAG: {
|
||||
VpSelectTilesWithMethod(e->place.pt.x, e->place.pt.y, e->place.userdata);
|
||||
return;
|
||||
}
|
||||
|
||||
case WE_PLACE_MOUSEUP:
|
||||
if (e->click.pt.x != -1) {
|
||||
if (e->place.userdata == VPM_X_AND_Y)
|
||||
DoCommandP(e->place.tile, e->place.starttile, 0, CcPlaySound10, CMD_CLEAR_AREA | CMD_MSG(STR_00B5_CAN_T_CLEAR_THIS_AREA));
|
||||
else if(e->place.userdata == VPM_X_OR_Y)
|
||||
DoCommandP(e->place.tile, e->place.starttile, 0, CcBuildCanal, CMD_BUILD_CANAL | CMD_AUTO | CMD_MSG(STR_CANT_BUILD_CANALS));
|
||||
}
|
||||
break;
|
||||
|
||||
case WE_ABORT_PLACE_OBJ:
|
||||
w->click_state = 0;
|
||||
SetWindowDirty(w);
|
||||
|
||||
w = FindWindowById(WC_BUILD_STATION, 0);
|
||||
if (w != NULL) WP(w,def_d).close=true;
|
||||
|
||||
w = FindWindowById(WC_BUILD_DEPOT, 0);
|
||||
if (w != NULL) WP(w,def_d).close=true;
|
||||
break;
|
||||
|
||||
case WE_PLACE_PRESIZE: {
|
||||
uint tile_from, tile_to;
|
||||
|
||||
tile_from = tile_to = e->place.tile;
|
||||
switch(GetTileSlope(tile_from, NULL)) {
|
||||
case 3: tile_to += TILE_XY(-1,0); break;
|
||||
case 6: tile_to += TILE_XY(0,-1); break;
|
||||
case 9: tile_to += TILE_XY(0,1); break;
|
||||
case 12:tile_to += TILE_XY(1,0); break;
|
||||
}
|
||||
VpSetPresizeRange(tile_from, tile_to);
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
static const Widget _build_docks_toolb_widgets[] = {
|
||||
{ WWT_CLOSEBOX, 7, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
|
||||
{ WWT_CAPTION, 7, 11, 197, 0, 13, STR_9801_DOCK_CONSTRUCTION, STR_018C_WINDOW_TITLE_DRAG_THIS},
|
||||
{ WWT_PANEL, 7, 0, 21, 14, 35, 746, STR_981D_BUILD_SHIP_DOCK},
|
||||
{ WWT_PANEL, 7, 22, 43, 14, 35, 748, STR_981E_BUILD_SHIP_DEPOT_FOR_BUILDING},
|
||||
{ WWT_PANEL, 7, 44, 65, 14, 35, 693, STR_9834_POSITION_BUOY_WHICH_CAN},
|
||||
{ WWT_PANEL, 7, 66, 87, 14, 35, 703, STR_018D_DEMOLISH_BUILDINGS_ETC},
|
||||
{ WWT_PANEL, 7, 88, 109, 14, 35, 695, STR_018E_LOWER_A_CORNER_OF_LAND},
|
||||
{ WWT_PANEL, 7, 110, 131, 14, 35, 694, STR_018F_RAISE_A_CORNER_OF_LAND},
|
||||
{ WWT_PANEL, 7, 132, 153, 14, 35, 4791, STR_0329_PURCHASE_LAND_FOR_FUTURE},
|
||||
{ WWT_PANEL, 7, 154, 175, 14, 35, SPR_OPENTTD_BASE+65, STR_BUILD_CANALS_TIP},
|
||||
{ WWT_PANEL, 7, 176, 197, 14, 35, SPR_CANALS_BASE+69, STR_BUILD_LOCKS_TIP},
|
||||
{ WIDGETS_END},
|
||||
};
|
||||
|
||||
static const WindowDesc _build_docks_toolbar_desc = {
|
||||
640-197, 22, 198, 36,
|
||||
WC_BUILD_TOOLBAR,0,
|
||||
WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET,
|
||||
_build_docks_toolb_widgets,
|
||||
BuildDocksToolbWndProc
|
||||
};
|
||||
|
||||
void ShowBuildDocksToolbar()
|
||||
{
|
||||
DeleteWindowById(WC_BUILD_TOOLBAR, 0);
|
||||
AllocateWindowDesc(&_build_docks_toolbar_desc);
|
||||
}
|
||||
|
||||
static void BuildDockStationWndProc(Window *w, WindowEvent *e)
|
||||
{
|
||||
switch(e->event) {
|
||||
case WE_PAINT: {
|
||||
if (WP(w,def_d).close)
|
||||
return;
|
||||
DrawWindowWidgets(w);
|
||||
DrawStationCoverageAreaText(2, 15, (uint)-1);
|
||||
} break;
|
||||
|
||||
case WE_CLICK: {
|
||||
if (e->click.widget == 0) {
|
||||
ResetObjectToPlace();
|
||||
}
|
||||
} break;
|
||||
|
||||
case WE_MOUSELOOP: {
|
||||
if (WP(w,def_d).close) {
|
||||
DeleteWindow(w);
|
||||
return;
|
||||
}
|
||||
|
||||
CheckRedrawStationCoverage(w);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static const Widget _build_dock_station_widgets[] = {
|
||||
{ WWT_CLOSEBOX, 7, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
|
||||
{ WWT_CAPTION, 7, 11, 147, 0, 13, STR_3068_DOCK, STR_018C_WINDOW_TITLE_DRAG_THIS},
|
||||
{ WWT_PANEL, 7, 0, 147, 14, 45, 0x0, STR_NULL},
|
||||
{ WIDGETS_END},
|
||||
};
|
||||
|
||||
static const WindowDesc _build_dock_station_desc = {
|
||||
-1, -1, 148, 46,
|
||||
WC_BUILD_STATION,WC_BUILD_TOOLBAR,
|
||||
WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET,
|
||||
_build_dock_station_widgets,
|
||||
BuildDockStationWndProc
|
||||
};
|
||||
|
||||
static void ShowBuildDockStationPicker()
|
||||
{
|
||||
AllocateWindowDesc(&_build_dock_station_desc);
|
||||
}
|
||||
|
||||
static void UpdateDocksDirection()
|
||||
{
|
||||
if (_ship_depot_direction != 0) {
|
||||
SetTileSelectSize(1, 2);
|
||||
} else {
|
||||
SetTileSelectSize(2, 1);
|
||||
}
|
||||
}
|
||||
|
||||
static void BuildDocksDepotWndProc(Window *w, WindowEvent *e)
|
||||
{
|
||||
switch(e->event) {
|
||||
case WE_PAINT:
|
||||
w->click_state = (1<<3) << _ship_depot_direction;
|
||||
DrawWindowWidgets(w);
|
||||
|
||||
DrawShipDepotSprite(67, 35, 0);
|
||||
DrawShipDepotSprite(35, 51, 1);
|
||||
DrawShipDepotSprite(135, 35, 2);
|
||||
DrawShipDepotSprite(167, 51, 3);
|
||||
return;
|
||||
|
||||
case WE_CLICK: {
|
||||
switch(e->click.widget) {
|
||||
case 0:
|
||||
ResetObjectToPlace();
|
||||
break;
|
||||
case 3:
|
||||
case 4:
|
||||
_ship_depot_direction = e->click.widget - 3;
|
||||
SndPlayFx(0x13);
|
||||
UpdateDocksDirection();
|
||||
SetWindowDirty(w);
|
||||
break;
|
||||
}
|
||||
} break;
|
||||
|
||||
case WE_MOUSELOOP:
|
||||
if (WP(w,def_d).close)
|
||||
DeleteWindow(w);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static const Widget _build_docks_depot_widgets[] = {
|
||||
{ WWT_CLOSEBOX, 7, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
|
||||
{ WWT_CAPTION, 7, 11, 203, 0, 13, STR_3800_SHIP_DEPOT_ORIENTATION, STR_018C_WINDOW_TITLE_DRAG_THIS},
|
||||
{ WWT_PANEL, 7, 0, 203, 14, 85, 0x0, STR_NULL},
|
||||
{ WWT_PANEL, 14, 3, 100, 17, 82, 0x0, STR_3803_SELECT_SHIP_DEPOT_ORIENTATION},
|
||||
{ WWT_PANEL, 14, 103, 200, 17, 82, 0x0, STR_3803_SELECT_SHIP_DEPOT_ORIENTATION},
|
||||
{ WIDGETS_END},
|
||||
};
|
||||
|
||||
static const WindowDesc _build_docks_depot_desc = {
|
||||
-1, -1, 204, 86,
|
||||
WC_BUILD_DEPOT,WC_BUILD_TOOLBAR,
|
||||
WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET,
|
||||
_build_docks_depot_widgets,
|
||||
BuildDocksDepotWndProc
|
||||
};
|
||||
|
||||
|
||||
static void ShowBuildDocksDepotPicker()
|
||||
{
|
||||
AllocateWindowDesc(&_build_docks_depot_desc);
|
||||
UpdateDocksDirection();
|
||||
}
|
||||
|
||||
|
||||
void InitializeDockGui()
|
||||
{
|
||||
_ship_depot_direction = 0;
|
||||
}
|
|
@ -1,49 +0,0 @@
|
|||
This is a guide to compile strgen on gcc
|
||||
|
||||
All this is done in the makefile, so it's only interesting for people, who wants to alter something themselves (translators)
|
||||
|
||||
HOWTO compile lng files:
|
||||
|
||||
First you get strgen compiled (look below/download nightly build/run makefile)
|
||||
|
||||
strgen takes the argument of a txt file and translates it to a lng file and places that lng file in the same dir as the txt file.
|
||||
|
||||
Example 1:
|
||||
if you are in the root of your working copy (svn code), you should type
|
||||
strgen/strgen lang/english.txt
|
||||
to compile englist.lng. It will be placed in the lang dir
|
||||
|
||||
Example 2:
|
||||
you have strgen but not the source and you want to compile a txt file in the same dir. YOu should type
|
||||
./strgen english.txt
|
||||
and you will get english.lng in the same dir
|
||||
|
||||
You can change english to whatever language you want
|
||||
|
||||
Commands used by strgen
|
||||
|
||||
-v --version
|
||||
strgen will tell what svn revision it is based on
|
||||
|
||||
-t
|
||||
strgen will add <TODO> to the missing strings and use the english strings while compiling
|
||||
this will need english.txt to be present
|
||||
|
||||
-w
|
||||
strgen will print any missing strings to standard error output(stderr)
|
||||
this will need english.txt to be present
|
||||
|
||||
here are a very useful tool for translators:
|
||||
http://openttd.rulez.org/
|
||||
|
||||
|
||||
HOWTO compile strgen:
|
||||
(this should be useless as you can just type make)
|
||||
Goto the main dir
|
||||
Compile by typing
|
||||
gcc strgen/strgen.c -o strgen/strgen -DUNIX
|
||||
or if you want it to tell the revision too
|
||||
gcc strgen/strgen.c rev.o -o strgen/strgen -DUNIX -DWITH_REV (this is the one the makefile uses)
|
||||
|
||||
you now have a program called strgen in the strgen directory
|
||||
|
|
@ -1,101 +0,0 @@
|
|||
Welcome to the manual for OpenTTD. The latest release version at the time of writing is 0.3.2.
|
||||
|
||||
1 Obtaining OpenTTD.
|
||||
|
||||
You can obtain built binaries of OpenTTD for the 4 supported platforms - Win32, Linux,-x86, BeOS 5 and MacOS-X from the projects Sourceforge page, at http://sourceforge.net/projects/openttd . For the non-Win32 builds you will need libSDL.so, libpng.so and zlib.so compiled for your platform. Some builds will include these.
|
||||
|
||||
If you use another platform, such as FreeBSD, which has POSIX file i/o and an SDL port, you should be able to build OpenTTD from its source. This is available in the proejcts Subversion repository at svn://svn.openttd.com . The module name is "trunk".
|
||||
|
||||
1.1 Building OpenTTD.
|
||||
|
||||
Once you have obtained a recent copy of the source, you must build it. Windows build instructions will be provided later.
|
||||
|
||||
On UNIX platforms (including OS-X and BeOS), ensure you have a recent GCC (2.9 or above, or 3 and above).You will also need SDL development headers and libraries (libSDL 1.2 or higher). For PNG screenshot support and zlib compressed games, you will need libpng 1.0.12 or higher and zlib 1.2 or higher.
|
||||
|
||||
Most UNIX platforms:
|
||||
Use make or gmake to compile OpenTTD. You can adjust Makefile.config to compile with other options.
|
||||
|
||||
BeOS:
|
||||
On BeOS, run ./configure and then use jam. There are a variaty of options you can pass to your build tool, these are reported by ./configure.
|
||||
|
||||
|
||||
1.2 Installing OpenTTD.
|
||||
|
||||
On Windows, insert your "Transport Tycoon Deluxe for Windows 95" disk. You can use a DOS version, but your graphics will be purple. NB: Even if your version of Transport Tycoon Deluxe ran on Windows 95, it may still be the DOS version. Then run the OpenTTD installer.
|
||||
|
||||
On UNIX platforms; decompress your OpenTTD archive, or otherwise run the installer. You should be left with an OpenTTD directory on your system. In this directory, make a subdirectory called 'data', and into this place the sample.cat file and all the .grf files from the install CD of 'Transport Tycoon Deluxe for Windows 95".
|
||||
|
||||
If you want MIDI music, copy the 'gm' folder from the original game directory/CD to the OpenTTD folder.
|
||||
|
||||
1.3 Running OpenTTD.
|
||||
|
||||
On Windows, you can use a third-party launcher such as OTTD-Launcher to run OpenTTD directly from Explorer. Otherwise, navigate via the command prompt to the correct location and launch ttd.exe.
|
||||
|
||||
On Linux, navigate at the shell to the correct location and run ttd.
|
||||
|
||||
On BeOS and Mac OS-X, just double click the ttd binary in the Tracker/Finder. You can also start from the shell.
|
||||
|
||||
1.4 Configuring OpenTTD
|
||||
|
||||
OpenTTD's launch menu contains three configuration menus - Difficulty Settings, Configure Patches and Game Settings. Most of these menus can be configured from within a running game as well.
|
||||
|
||||
Difficulty Settings lets you configure settings that affect the difficulty of playing the game. These include when your (computer-controlled) competitors can start building, how many of them there are, and how intelligent they are. You can also control how much the subsidy mutliplier is for subsidised routes, and how stable/volitile the in-game economy is. You can also set how you want the terrain to be configured in a random game.
|
||||
|
||||
Game Settings lets you set regional settings - currency, language, town names, etc. It also lets you select the resolution to run the game at, as well as the screenshot format to use.
|
||||
|
||||
Configure Patches lets you select which patches to use in the game. This allows you to set the game play to either original Transport Tycoon Deluxe compatible mode or a mode more like playing under TTD-Patch. Patches include building on slopes, longer bridges, longer trains, pre-signals, and TTD-Patch compatible handling of non-stop orders.
|
||||
|
||||
2.1 Gameplay
|
||||
|
||||
This section of the manual is written with the assumption that you already know the gameplay basics of Transport Tycoon Deluxe, on either DOS or Windows. As you must have the Windows Transport Tycoon Deluxe CD to play OpenTTD, you should either have a paper manual or the complete manual in PDF format on the disk. This section will only cover the gameplay differences from Transport Tycoon Deluxe.
|
||||
|
||||
2.2 Station Construction
|
||||
|
||||
In OpenTTD, you can build rail stations up to seven squares long and with up to seven platforms. You can also have stations spreading across far larger distances, allowing a large rail station to be connected to a large airport, for instance.
|
||||
|
||||
However, there is an even more noticable difference in rail station construction. You may now add platforms and lenght to a station after it has been built, and you may also add platforms of a different type. Users of TTDPatch will be used to this behaviour. But beyond what TTDPatch has, you can make stations of uneven lenght/width, and even ones with perpendicular tracks. You can also delete single tiles or tracks from a station, by holding down Shift before pressing the station construction button.
|
||||
|
||||
2.3 Checkpoint Stations
|
||||
|
||||
|
||||
Checkpoint stations (the small blue item in the rail construction window) are small 1x1 stations. They must be built on top of pre-existing track. They do not accept or produce carge of any kind. They exist solely for use as route points. They become useful when dealing with large networks where trains may attempt to route themselves along undesirable or impossible routes. As an alternative to checkpoint stations, you can also direct trains to visit depots along the way. This has the advantage of also servicing the train and hence the train will rarely to never need to depart from its route to be serviced.
|
||||
|
||||
2.4 Freeform Rail Laying.
|
||||
|
||||
Along side the other rail laying buttons, you will see a button that looks somewhat like a crossing. This is the freeform rail laying tool., and it allows you to drag rail in any direction to lay it. This has a number of advantages, one of the main ones being that it can seriously speed up the laying of diagonal tracks.
|
||||
|
||||
2.5 Vehicle Queuing (with Quantum Effects)
|
||||
|
||||
This useful addition to OpenTTD means that road vehicles will queue outside a road station to wait for a space rather than attempt to enter it immediately. As anyone who has operated a large road network with busy stations will know, road vehicles quickly pile up inside stations. This will prevent that. The Quantum Effects are down to a bug in the game that means that mutliple vehicles will often only take up one space in the queue. However, this is almost too useful to fix, and should still be there in later versions. This can be enabled/disabled.
|
||||
|
||||
2.6 Building On Slopes
|
||||
|
||||
This allows you to build roads, rails, stations and depots on slopes. It also allows the construction of trasmitters and lighthouses on slopes in the scenario editor. There are some minor differences between OpenTTD's and TTD-Patch's handling of building on slopes, the main one being that bridges must still have solid land at their endings.
|
||||
|
||||
2.7 Long Bridges
|
||||
|
||||
OpenTTD allows you to constuct bridges up to 127 squares - half the size of the current map. This means that the crossing of large estuaries, such at the Bristol Channel in the original "West Country 90210" scenario can be acheived with one bridge instead of many bridges with staging points.
|
||||
|
||||
2.8 Long trains
|
||||
|
||||
OpenTTD allows trains of around 60 cars length, hence allowing you to use 7 square stations to their capacity and beyond.
|
||||
|
||||
2.9 Speed Display
|
||||
|
||||
This addition to OpenTTD allows you to see the current speed of any vehicle in their status window. Just open the status window of a vehicle and you can see the speed at that given moment. This allows you to see wheter better bridges, flatter/straighter track or more powerful engines could be used to increase the speed of a vehicle
|
||||
|
||||
2.10 More Trains, More Ships, More Everything!
|
||||
|
||||
Virtually any settings - train numbers, start date, what vehicles your competitors can use, etc - can be set in OpenTTD. Just use the Configure Patches menu on the main screen.
|
||||
|
||||
2.11 Network Play
|
||||
|
||||
OpenTTD now supports rudimentary TCP/IP based network play. This is not supported on all platforms. To start a server, use the '-n' CLI switch, and start a client with '-n' and the servers IP adress. The OpenTTD network play runs over port 12345, so you may need to open this on your firewall.
|
||||
|
||||
2.12 Rail Recycling.
|
||||
|
||||
This button, at the end of the train construction window, lets you 'recycle' track to a new type. It also works on bridges, tunnels, stations and depots.
|
||||
|
||||
2.13 Canal Building
|
||||
|
||||
This button, at the end of the water construction window, lets you build canals and shiplifts across the landscape. These act just like normal water.
|
|
@ -1,38 +0,0 @@
|
|||
Since you are reading this, OpenTTD have crashed. This file tells you how
|
||||
to fix the most common problems or make to make a bug report, that the
|
||||
developers can use to track down the problem
|
||||
|
||||
The first thing you need to do is to get the error message. You can access OSX's build-in log by double-clicking Crash_Log_Opener. OTTD will do that if that file is present in the same folder as OTTD and is not renamed. However, major crashes can prevent the autoopen feature and you have to do it manually then
|
||||
If Crash_Log_Opener doesn't work you can view the log by opening Console inside Applications/utilities.
|
||||
|
||||
If you use the Console app, you should look at the buttom of the console.log window
|
||||
|
||||
The problems are as follows:
|
||||
NOTE: build from source means to download the source and compile
|
||||
yourself. If you get one of the build from source error with the version
|
||||
that is downloaded on a dmg file, you should make a bug report
|
||||
|
||||
--Didn't find a needed file:
|
||||
you just give it the file it asks for. It even tells you what
|
||||
folder it wants it in
|
||||
most common version of this problem is "Error: Cannot open file
|
||||
'data/sample.cat'"
|
||||
if you get that one, that means that you haven't got all the
|
||||
needed files from the WINDOWS version of TTD
|
||||
or if you build from source,
|
||||
|
||||
--Error: No available language packs
|
||||
you need at least one .lng file in your lang folder. This applies
|
||||
only to people who build from source
|
||||
|
||||
--spritecache.c:237: failed assertion `b'
|
||||
you got an outdated grf file. Update from the data folder in the
|
||||
source. This applies only to people, who build from source
|
||||
|
||||
--assertion error that are not triggered by one of the errors listed in
|
||||
this file:
|
||||
you most likely found a bug. Write down the assertion and try to
|
||||
see if you can reproduce it. If you can, make a
|
||||
savegame from just before it happens (autosaves are useful here)
|
||||
and post a bugreport with it on sourceforge
|
||||
Write what you did to trigger the bug and what assertion it made
|
|
@ -1,60 +0,0 @@
|
|||
Compiling and developing OpenTTD on MandrakeLinux 10.0 Official
|
||||
|
||||
A quick guide to get started with OpenTTD development on Linux.
|
||||
---------------------------------------------------------------
|
||||
|
||||
1.) RPMs:
|
||||
|
||||
Most packages that are required for development (like gcc) should already be installed on your box. You will require those RPMs additionally:
|
||||
- libsdl1.2-devel-1.2.7-2mdk
|
||||
- subversion-1.0.1-1mdk (+ dependencies)
|
||||
- libsvn_ra_svn1_0-1.0.1-1mdk
|
||||
|
||||
|
||||
2.) Subversion:
|
||||
|
||||
To obtain the source code from the subversion server type
|
||||
$ svn co svn://svn.openttd.com/openttd/trunk openttd
|
||||
from command line to dump the code into the directory 'openttd'.
|
||||
|
||||
To update your working copy to the latest revision use
|
||||
$ svn update
|
||||
Don't worry, your version will be merged with the latest version.
|
||||
|
||||
The command
|
||||
$ svn diff > mypatch.diff
|
||||
creates a patch file (aka diff file) which you can submit to the developers to share your improvements.
|
||||
|
||||
You can undo changes to a file with
|
||||
$svn revert filename
|
||||
|
||||
|
||||
3.) Required data files:
|
||||
|
||||
Copy the following files from the WINDOWS version of Transport Tycoon Deluxe to openttd/data/
|
||||
sample.cat
|
||||
trg1r.grf
|
||||
trgcr.grf
|
||||
trghr.grf
|
||||
trgir.grf
|
||||
trgtr.grf
|
||||
|
||||
|
||||
4.) Compiling and running:
|
||||
|
||||
Compile OpenTTD with
|
||||
$ make
|
||||
and run it with
|
||||
$ ./ttd
|
||||
|
||||
|
||||
5.) Playing the soundtrack:
|
||||
|
||||
If you want the original TTD music you need to copy the whole /gm/ directory from Windows. Additionally the TiMidity driver is required:
|
||||
TiMidity++-2.12.0-0.pre1.4mdk (+ dependencies)
|
||||
To run OpenTTD with music support type
|
||||
$ ./ttd -m extmidi
|
||||
|
||||
|
||||
X.) Last Update: $Date: 2004-06-01 19:08:09 +0200 (Tue, 01 Jun 2004) $
|
||||
Written for revision $Rev: 710 $
|
|
@ -1,89 +0,0 @@
|
|||
Compilung OpenTTD using MS VC6.0
|
||||
|
||||
|
||||
Step 1
|
||||
------------------
|
||||
Downloaded:
|
||||
Useful.zip http://sourceforge.net/project/showfiles.php?group_id=103924&package_id=114307&release_id=228633
|
||||
SDL.zip http://www.libsdl.org/release/SDL-1.2.7-win32.zip
|
||||
DirectX7.0 SDK http://www.tt-forums.net/download.php?id=15989
|
||||
(or alternatively the latest DirectX SDK from Microsoft)
|
||||
afxres.h http://www-d0.fnal.gov/d0dist/dist/packages/d0ve/devel/windows/AFXRES.H
|
||||
|
||||
|
||||
Step 2
|
||||
------------------
|
||||
Put the newly downloaded files in the VC lib and include directories
|
||||
(Where D:\program files\ is your local location of VC)
|
||||
|
||||
|
||||
* zconf.h [useful.zip]
|
||||
* zlib.h [useful.zip]
|
||||
* afxres.h
|
||||
in
|
||||
D:\Program Files\Microsoft Visual Studio\VC98\Include
|
||||
|
||||
* zlibstat.lib [usefull.zip]
|
||||
* SDL.lib [SDL.zip
|
||||
* libpng.lib [usefull.zip]
|
||||
in
|
||||
D:\Program Files\Microsoft Visual Studio\VC98\Lib
|
||||
|
||||
You can also make custum directories, for libraries (.lib) and includes/header files (.h) and
|
||||
add it to the VC paths via:
|
||||
Tools -> Options -> Directories -> show directories for:
|
||||
a) include files (the include dir: D:\Program Files\Microsoft Visual Studio\VC98\DirectX 7 SDK\include )
|
||||
b) library files (the lib dir, D:\Program Files\Microsoft Visual Studio\VC98\DirectX 7 SDK\lib )
|
||||
|
||||
|
||||
Step 3: DirextX SDK
|
||||
------------------
|
||||
(This should work with the latest DirectX SDK as well.)
|
||||
The installation with DirectX 7 was odd, so you'd better use the version available via the forum, see also
|
||||
the download link on top.
|
||||
|
||||
Copy the DirectX 7 SDK files, leaving the directory stucture intact, to the directory:
|
||||
D:\Program Files\Microsoft Visual Studio\VC98\
|
||||
thus resulting in
|
||||
D:\Program Files\Microsoft Visual Studio\VC98\DirectX 7 SDK\include and
|
||||
D:\Program Files\Microsoft Visual Studio\VC98\DirectX 7 SDK\lib
|
||||
|
||||
Step 3.1
|
||||
|
||||
Add these two folders to the search path of VC.
|
||||
In VC6.0: Tools -> Options -> Directories -> show directories for:
|
||||
a) include files (the include dir: D:\Program Files\Microsoft Visual Studio\VC98\DirectX 7 SDK\include )
|
||||
b) libraru files (the lib dir, D:\Program Files\Microsoft Visual Studio\VC98\DirectX 7 SDK\lib )
|
||||
|
||||
|
||||
Step 4
|
||||
-----------------
|
||||
Copy the following files from the WINDOWS version of Transport Tycoon Deluxe to the data folder
|
||||
sample.cat
|
||||
trg1r.grf
|
||||
trgcr.grf
|
||||
trghr.grf
|
||||
trgir.grf
|
||||
trgtr.grf
|
||||
|
||||
|
||||
|
||||
Step 5
|
||||
-----------------
|
||||
Compile ...
|
||||
|
||||
|
||||
Step 6
|
||||
-----------------
|
||||
|
||||
Now it should work, it worked for me :)
|
||||
|
||||
Go ahead and make that patch!
|
||||
|
||||
Happy Hacking!
|
||||
|
||||
|
||||
|
||||
------------------
|
||||
written by Dribbel
|
||||
|
|
@ -1,54 +0,0 @@
|
|||
OPENTTD INGAME CONSOLE DOCUMENTATION
|
||||
====================================
|
||||
http://openttd.rulez.org/wiki2/index.php/OpenTTDDevBlackBook
|
||||
for detailed information
|
||||
|
||||
HOTKEY: BACKQUOTE (aka tilde, the key left to "1")
|
||||
|
||||
COMMANDS:
|
||||
---------
|
||||
|
||||
echo [string]
|
||||
echoc [color-code] [string]
|
||||
exit
|
||||
debug_level [0-9]
|
||||
dump_vars [filter]
|
||||
help
|
||||
list_cmds [filter]
|
||||
list_vars [filter]
|
||||
printf [formatstring] [var] [var] [var]....
|
||||
printfc [color-code] [formatstring] [var] [var] [var]....
|
||||
quit
|
||||
random
|
||||
screenshot ["big"/"no_con"]
|
||||
|
||||
VARIABLES:
|
||||
----------
|
||||
*con_developer
|
||||
-> true = console debugging info
|
||||
-> false = no output
|
||||
|
||||
*developer
|
||||
-> 0 = no output
|
||||
-> 1 = console error output [like command not found]
|
||||
-> 2 = console error and debug output
|
||||
|
||||
*cursor_rate
|
||||
-> 1-12 = defines the cursor blink interval
|
||||
|
||||
|
||||
VARIABLE HANDLING:
|
||||
------------------
|
||||
|
||||
*developer = 0
|
||||
*developer ++
|
||||
|
||||
*temp_string = test
|
||||
*temp_string = "my little"
|
||||
|
||||
printf "%s world" *temp_string
|
||||
|
||||
|
||||
---------------------------------------------------
|
||||
feel free to add more commands and use this in-game
|
||||
console for your debugging / enhancements
|
|
@ -1,20 +0,0 @@
|
|||
Notes about DirectMusic driver for Win32
|
||||
----------------------------------------
|
||||
|
||||
If compiling under MinGW32, you require the DirectX 7.0 files for MinGW32, available from
|
||||
http://alleg.sourceforge.net/files/dx70_mgw.zip.
|
||||
|
||||
If compiling under MSVC 6.0, you require the equivalent for MSVC, available from
|
||||
http://alleg.sourceforge.net/files/dx70_min.zip. MSVC 7.0/7.1 include header files that
|
||||
are recent enough.
|
||||
|
||||
If you do not want to compile the DirectMusic driver, undefine WIN32_ENABLE_DIRECTMUSIC_SUPPORT
|
||||
in stdafx.h.
|
||||
|
||||
Bugs, etc
|
||||
---------
|
||||
|
||||
- The volume control doesn't work properly. I'll fix this soon.
|
||||
|
||||
Owen Rudge
|
||||
14th March 2004
|
|
@ -1,611 +0,0 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
|
||||
<html>
|
||||
<head>
|
||||
<meta name="Author" content="Marcin Grzegorczyk">
|
||||
<meta name="Description" content="Structure of Transport Tycoon Deluxe (TTD) savegame files">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<title>Transport Tycoon Deluxe savegame internals</title>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<h3><a name="Landscape">Landscape</a></h3>
|
||||
<p>
|
||||
Five arrays are used to encode the information of the contents of each tile. These arrays are referred to as <a href="#_landscape1">map_owner</a>, <a href="#_landscape2">map2</a>, <a href="#_landscape3">map3_lo</a>, <a href="#_landscape4">type_and_height</a> and <a href="#_landscape5">map5</a>. The known encodings are listed in the table below. The most important value is the class of a tile, stored in the upper 4 bits of the type_and_height array.
|
||||
</p>
|
||||
<p>
|
||||
<a name="OwnershipInfo">Owner values</a> <tt>00</tt> through <tt>07</tt> are companies (they're indices into the <a href="#_CompanyArray">array of companies</a>), <tt>10</tt> is no owner, <tt>11</tt> appears to be reserved for water, <tt>80</tt> and above are towns (in this case the low 7 bits contain an index into the <a href="#_TownArray">town array</a>).
|
||||
</p>
|
||||
<p>
|
||||
TTD's class-specific periodic tile processing routine is called once every +256 ticks for each tile.
|
||||
</p>
|
||||
|
||||
<table border=1 cellpadding=3>
|
||||
<tr><th align=left>Class</th><th align=left>Meaning & details of encoding</th></tr>
|
||||
|
||||
<tr><td valign=top nowrap><a name="Class0"><tt> 0 </tt></a></td><td>
|
||||
<ul>
|
||||
<li>map5 bits 4..0: tile type:
|
||||
<table>
|
||||
<tr><td nowrap valign=top><tt>00</tt> </td><td align=left>bare land</td></tr>
|
||||
<tr><td nowrap valign=top><tt>01</tt> </td><td align=left>1/3 grass</td></tr>
|
||||
<tr><td nowrap valign=top><tt>02</tt> </td><td align=left>2/3 grass</td></tr>
|
||||
<tr><td nowrap valign=top><tt>03</tt> </td><td align=left>full grass</td></tr>
|
||||
<tr><td nowrap valign=top><tt>07</tt> </td><td align=left>rough land</td></tr>
|
||||
<tr><td nowrap valign=top><tt>0B</tt> </td><td align=left>rocks</td></tr>
|
||||
<tr><td nowrap valign=top><tt>0F</tt> </td><td align=left>fields; type of fields in map3_lo bits 3..0 (legal values: 0 through 9)</td></tr>
|
||||
<tr><td nowrap valign=top><tt>10</tt> </td><td align=left>1/4 snow</td></tr>
|
||||
<tr><td nowrap valign=top><tt>11</tt> </td><td align=left>2/4 snow</td></tr>
|
||||
<tr><td nowrap valign=top><tt>12</tt> </td><td align=left>3/4 snow</td></tr>
|
||||
<tr><td nowrap valign=top><tt>13</tt> </td><td align=left>full snow</td></tr>
|
||||
<tr><td nowrap valign=top><tt>15</tt> </td><td align=left>partial desert</td></tr>
|
||||
<tr><td nowrap valign=top><tt>17</tt> </td><td align=left>full desert</td></tr>
|
||||
</table>
|
||||
</li>
|
||||
<li>map5 bits 7..6: update counter, incremented on every periodic processing for tile types other than <tt>03</tt>, <tt>07</tt>, <tt>0B</tt> and <tt>10</tt> and above, on wraparound the tile is updated (for fields, the type of fields in map3_lo is increased, for other types the tile type in map5 is increased)
|
||||
<br>(for snow and desert, these bits are not used, tile is updated on every periodic processing)
|
||||
</li>
|
||||
<li>map_owner: <a href="#OwnershipInfo">owner</a> of the tile (normally <tt>10</tt>)
|
||||
</li>
|
||||
<li>map3_hi bits 7..5: type of hedge on the SW border of the tile (1 through 6, or 0=none); bits 4..2: same for the SE border
|
||||
</li>
|
||||
</ul>
|
||||
</td></tr>
|
||||
|
||||
<tr><td valign=top nowrap><a name="Class1"><tt> 1 </tt></a></td><td>
|
||||
map5 bit 7 clear: railway track
|
||||
<ul>
|
||||
<li>map5 bits 0..5: track layout: bit set = track present:
|
||||
<table>
|
||||
<tr><td nowrap valign=top>bit 0: </td><td align=left>in the X direction</td></tr>
|
||||
<tr><td nowrap valign=top>bit 1: </td><td align=left>in the Y direction</td></tr>
|
||||
<tr><td nowrap valign=top>bit 2: </td><td align=left>in the north corner (direction W-E)</td></tr>
|
||||
<tr><td nowrap valign=top>bit 3: </td><td align=left>in the south corner (direction W-E)</td></tr>
|
||||
<tr><td nowrap valign=top>bit 4: </td><td align=left>in the west corner (direction N-S)</td></tr>
|
||||
<tr><td nowrap valign=top>bit 5: </td><td align=left>in the east corner (direction N-S)</td></tr>
|
||||
</table></li>
|
||||
<li>map5 bit 6 set = with signals:
|
||||
<ul>
|
||||
<li>map3_lo bits 7..4: bit set = signal present:
|
||||
<ul>
|
||||
<li>For track in the X direction:
|
||||
<table>
|
||||
<tr><td nowrap valign=top>bit 6: </td><td align=left>signal in the SW direction</td></tr>
|
||||
<tr><td nowrap valign=top>bit 7: </td><td align=left>signal in the NE direction</td></tr>
|
||||
</table></li>
|
||||
<li>For track in the Y direction:
|
||||
<table>
|
||||
<tr><td nowrap valign=top>bit 6: </td><td align=left>signal in the NW direction</td></tr>
|
||||
<tr><td nowrap valign=top>bit 7: </td><td align=left>signal in the SE direction</td></tr>
|
||||
</table></li>
|
||||
<li>For tracks in the W-E direction:
|
||||
<table>
|
||||
<tr><td nowrap valign=top>bit 4: </td><td align=left>signal in the W direction on the track in the S corner</td></tr>
|
||||
<tr><td nowrap valign=top>bit 5: </td><td align=left>signal in the E direction on the track in the S corner</td></tr>
|
||||
<tr><td nowrap valign=top>bit 6: </td><td align=left>signal in the W direction on the track in the N corner</td></tr>
|
||||
<tr><td nowrap valign=top>bit 7: </td><td align=left>signal in the E direction on the track in the N corner</td></tr>
|
||||
</table></li>
|
||||
<li>For tracks in the N-S direction:
|
||||
<table>
|
||||
<tr><td nowrap valign=top>bit 4: </td><td align=left>signal in the S direction on the track in the E corner</td></tr>
|
||||
<tr><td nowrap valign=top>bit 5: </td><td align=left>signal in the N direction on the track in the E corner</td></tr>
|
||||
<tr><td nowrap valign=top>bit 6: </td><td align=left>signal in the S direction on the track in the W corner</td></tr>
|
||||
<tr><td nowrap valign=top>bit 7: </td><td align=left>signal in the N direction on the track in the W corner</td></tr>
|
||||
</table></li>
|
||||
</ul></li>
|
||||
<li>map2 bits 7..4: bit clear = signal shows red; same bits as in map3_lo</li>
|
||||
<li>OpenTTD bits in map3_hi:
|
||||
<table>
|
||||
<tr><td nowrap valign=top>bits 1..0: </td><td align=left>type of signal:</td></tr>
|
||||
<tr><td nowrap valign=top><tt>00</tt>: </td><td align=left>normal signals</td></tr>
|
||||
<tr><td nowrap valign=top><tt>01</tt>: </td><td align=left>pre-signals</td></tr>
|
||||
<tr><td nowrap valign=top><tt>10</tt>: </td><td align=left>exit-signals</td></tr>
|
||||
<tr><td nowrap valign=top><tt>11</tt>: </td><td align=left>combo-signals</td></tr>
|
||||
<tr><td nowrap valign=top>bit 2: </td><td align=left>set = semaphore signals, clear = light signals</td></tr>
|
||||
</table></li>
|
||||
</ul></li>
|
||||
<li>map_owner: <a href="#OwnershipInfo">owner</a> of the track
|
||||
</li>
|
||||
<li>map2 bits 0..3:
|
||||
<table>
|
||||
<tr><td nowrap valign=top><tt>0</tt> </td><td align=left>on bare land</td></tr>
|
||||
<tr><td nowrap valign=top><tt>1</tt> </td><td align=left>on grass, no fences</td></tr>
|
||||
<tr><td nowrap valign=top><tt>2</tt> </td><td align=left>fence on the NW side</td></tr>
|
||||
<tr><td nowrap valign=top><tt>3</tt> </td><td align=left>fence on the SE side</td></tr>
|
||||
<tr><td nowrap valign=top><tt>4</tt> </td><td align=left>fences on the NW and SE sides</td></tr>
|
||||
<tr><td nowrap valign=top><tt>5</tt> </td><td align=left>fence on the NE side</td></tr>
|
||||
<tr><td nowrap valign=top><tt>6</tt> </td><td align=left>fence on the SW side</td></tr>
|
||||
<tr><td nowrap valign=top><tt>7</tt> </td><td align=left>fences on the NE and SW sides</td></tr>
|
||||
<tr><td nowrap valign=top><tt>8</tt> </td><td align=left>fence on the E side (track in the W corner)</td></tr>
|
||||
<tr><td nowrap valign=top><tt>9</tt> </td><td align=left>fence on the W side (track in the E corner)</td></tr>
|
||||
<tr><td nowrap valign=top><tt>A</tt> </td><td align=left>fence on the S side (track in the N corner)</td></tr>
|
||||
<tr><td nowrap valign=top><tt>B</tt> </td><td align=left>fence on the N side (track in the S corner)</td></tr>
|
||||
<tr><td nowrap valign=top><tt>C</tt> </td><td align=left>on snow or desert</td></tr>
|
||||
</table></li>
|
||||
<li>map3_lo bits 0..3 = <a name="TrackType">track type</a>: <tt>0</tt> - conventional railway, <tt>1</tt> - monorail, <tt>2</tt> - maglev
|
||||
</li>
|
||||
</ul>
|
||||
map5 bits 7 and 6 set: railway depot / checkpoints
|
||||
<ul>
|
||||
<li>map5 value C0..C3: railway depot
|
||||
<br>map5 bits 1..0 - direction: exit towards: <tt>00</tt> = NE, <tt>01</tt> = SE, <tt>02</tt> = SW, <tt>03</tt> = NW</li>
|
||||
<li>map5 value C4..C5: checkpoint
|
||||
<br>bit 0: clear = in X direction, set = in Y direction
|
||||
<br>
|
||||
<br>
|
||||
<li>map_owner: <a href="#OwnershipInfo">owner</a> of the depot / checkpoint</li>
|
||||
<li>map3_lo bits 0..3 = <a href="#TrackType">track type</a></li>
|
||||
</ul>
|
||||
</td></tr>
|
||||
|
||||
<tr><td valign=top nowrap><a name="Class2"><tt> 2 </tt></a></td><td>
|
||||
map5 bits 7..4 clear: road
|
||||
<ul>
|
||||
<li>map5 bits 3..0: road layout: bit set = road piece present:
|
||||
<table>
|
||||
<tr><td nowrap valign=top>bit 0: </td><td align=left>NW piece</td></tr>
|
||||
<tr><td nowrap valign=top>bit 1: </td><td align=left>SW piece</td></tr>
|
||||
<tr><td nowrap valign=top>bit 2: </td><td align=left>SE piece</td></tr>
|
||||
<tr><td nowrap valign=top>bit 3: </td><td align=left>NE piece</td></tr>
|
||||
</table></li>
|
||||
<li>map_owner: <a href="#OwnershipInfo">owner</a> of the road</li>
|
||||
<li>map2 bits 0..2: <tt>0</tt> - on bare land, <tt>1</tt> - on grass, <tt>2</tt> - paved, <tt>3</tt> - with streetlights, <tt>5</tt> - tree-lined, <tt>6</tt> - on grass with road works, <tt>7</tt> - paved with road works</li>
|
||||
<li>map3_hi bit 7 set = on snow or desert</li>
|
||||
</ul>
|
||||
map5 bit 4 set, bits 7..5 clear: level crossing
|
||||
<ul>
|
||||
<li>map5 bit 3: clear - road in the X direction, set - road in the Y direction (railway track always perpendicular)</li>
|
||||
<li>map5 bit 2: set if crossing lights are on</li>
|
||||
<li>map_owner: <a href="#OwnershipInfo">owner</a> of the railway track</li>
|
||||
<li>map2 bits 0..2: <tt>0</tt> - on bare land, <tt>1</tt> - on grass, <tt>2</tt> or higher - paved</li>
|
||||
<li>map3_lo bits 0..7: <a href="#OwnershipInfo">owner</a> of the road</li>
|
||||
<li>map3_hi bits 3..0: <a href="#TrackType">track type</a></li>
|
||||
<li>map3_hi bit 7 set = on snow or desert</li>
|
||||
</ul>
|
||||
map5 bit 5 set: road depot
|
||||
<ul>
|
||||
<li>map5 bits 3..0 - direction: exit towards: <tt>0</tt> = NE, <tt>1</tt> = SE, <tt>2</tt> = SW, <tt>3</tt> = NW</li>
|
||||
<li>map_owner: <a href="#OwnershipInfo">owner</a> of the depot</li>
|
||||
<li>map3_hi bit 7 set = on snow or desert (not displayed, but set internally)</li>
|
||||
</ul>
|
||||
</td></tr>
|
||||
|
||||
<tr><td valign=top nowrap><a name="Class3"><tt> 3 </tt></a></td><td>
|
||||
Town building
|
||||
<ul>
|
||||
<li>map2: <a name="HouseTypes">town building type</a>:
|
||||
<p><small>Note: In the climate list, 'sub-arctic' means below the <a href="#_snowline">snow line</a>, and 'snow' means above the snow line in the sub-arctic climate.</small></p>
|
||||
<table>
|
||||
<tr><th align=left>Type </th><th align=left>Size </th><th align=left>Climates </th><th align=left>Description</th></tr>
|
||||
<tr><td nowrap valign=top><tt>00</tt> </td><td>1×1</td><td>temperate</td><td align=left>tall office block</td></tr>
|
||||
<tr><td nowrap valign=top><tt>01</tt> </td><td>1×1</td><td>temperate</td><td align=left>office block</td></tr>
|
||||
<tr><td nowrap valign=top><tt>02</tt> </td><td>1×1</td><td>temperate</td><td align=left>small block of flats</td></tr>
|
||||
<tr><td nowrap valign=top><tt>03</tt> </td><td>1×1</td><td>temperate</td><td align=left>church</td></tr>
|
||||
<tr><td nowrap valign=top><tt>04</tt> </td><td>1×1</td><td>temperate, sub-arctic, sub-tropical</td><td align=left>large office block</td></tr>
|
||||
<tr><td nowrap valign=top><tt>05</tt> </td><td>1×1</td><td>snow</td><td align=left>large office block</td></tr>
|
||||
<tr><td nowrap valign=top><tt>06</tt> </td><td>1×1</td><td>temperate</td><td align=left>town houses</td></tr>
|
||||
<tr><td nowrap valign=top><tt>07</tt>..<tt>08</tt> </td><td>1×2</td><td>temperate</td><td align=left>hotel</td></tr>
|
||||
<tr><td nowrap valign=top><tt>09</tt> </td><td>1×1</td><td>temperate, sub-arctic, sub-tropical </td><td align=left>statue</td></tr>
|
||||
<tr><td nowrap valign=top><tt>0A</tt> </td><td>1×1</td><td>temperate, sub-arctic, sub-tropical</td><td align=left>fountain</td></tr>
|
||||
<tr><td nowrap valign=top><tt>0B</tt> </td><td>1×1</td><td>temperate</td><td align=left>park (with a pond)</td></tr>
|
||||
<tr><td nowrap valign=top><tt>0C</tt> </td><td>1×1</td><td>temperate</td><td align=left>park (with an alley)</td></tr>
|
||||
<tr><td nowrap valign=top><tt>0D</tt> </td><td>1×1</td><td>temperate</td><td align=left>office block</td></tr>
|
||||
<tr><td nowrap valign=top><tt>0E</tt>..<tt>10</tt> </td><td>1×1</td><td>temperate</td><td align=left>various types of shops and offices</td></tr>
|
||||
<tr><td nowrap valign=top><tt>11</tt> </td><td>1×1</td><td>temperate, sub-arctic, sub-tropical</td><td align=left>modern office building</td></tr>
|
||||
<tr><td nowrap valign=top><tt>12</tt> </td><td>1×1</td><td>temperate</td><td align=left>warehouse</td></tr>
|
||||
<tr><td nowrap valign=top><tt>13</tt> </td><td>1×1</td><td>temperate</td><td align=left>office block (with spiral stairway on the side)</td></tr>
|
||||
<tr><td nowrap valign=top><tt>14</tt>..<tt>17</tt> </td><td>2×2</td><td>temperate</td><td align=left>stadium</td></tr>
|
||||
<tr><td nowrap valign=top><tt>18</tt> </td><td>1×1</td><td>temperate</td><td align=left>old houses</td></tr>
|
||||
<tr><td nowrap valign=top><tt>19</tt> </td><td>1×1</td><td>temperate</td><td align=left>cottages</td></tr>
|
||||
<tr><td nowrap valign=top><tt>1A</tt> </td><td>1×1</td><td>temperate</td><td align=left>houses</td></tr>
|
||||
<tr><td nowrap valign=top><tt>1B</tt> </td><td>1×1</td><td>temperate</td><td align=left>flats</td></tr>
|
||||
<tr><td nowrap valign=top><tt>1C</tt> </td><td>1×1</td><td>temperate</td><td align=left>tall office block</td></tr>
|
||||
<tr><td nowrap valign=top><tt>1D</tt> </td><td>1×1</td><td>temperate</td><td align=left>shops and offices</td></tr>
|
||||
<tr><td nowrap valign=top><tt>1E</tt> </td><td>1×1</td><td>temperate, sub-tropical</td><td align=left>shops and offices</td></tr>
|
||||
<tr><td nowrap valign=top><tt>1F</tt> </td><td>1×1</td><td>temperate</td><td align=left>theatre</td></tr>
|
||||
<tr><td nowrap valign=top><tt>20</tt>..<tt>23</tt> </td><td>2×2</td><td>temperate, sub-arctic, sub-tropical</td><td align=left>stadium (modern style)</td></tr>
|
||||
<tr><td nowrap valign=top><tt>24</tt> </td><td>1×1</td><td>temperate, sub-arctic, sub-tropical</td><td align=left>offices (the modern 'vertical tube' style)</td></tr>
|
||||
<tr><td nowrap valign=top><tt>25</tt> </td><td>1×1</td><td>sub-arctic</td><td align=left>houses</td></tr>
|
||||
<tr><td nowrap valign=top><tt>26</tt> </td><td>1×1</td><td>snow</td><td align=left>houses</td></tr>
|
||||
<tr><td nowrap valign=top><tt>27</tt> </td><td>1×1</td><td>temperate</td><td align=left>cinema</td></tr>
|
||||
<tr><td nowrap valign=top><tt>28</tt>..<tt>2B</tt> </td><td>2×2</td><td>temperate</td><td align=left>shopping mall</td></tr>
|
||||
<tr><td nowrap valign=top><tt>2C</tt> </td><td>1×1</td><td>sub-arctic</td><td align=left>flats</td></tr>
|
||||
<tr><td nowrap valign=top><tt>2D</tt> </td><td>1×1</td><td>snow</td><td align=left>flats</td></tr>
|
||||
<tr><td nowrap valign=top><tt>2E</tt> </td><td>1×1</td><td>sub-arctic</td><td align=left>houses</td></tr>
|
||||
<tr><td nowrap valign=top><tt>2F</tt> </td><td>1×1</td><td>snow</td><td align=left>houses</td></tr>
|
||||
<tr><td nowrap valign=top><tt>30</tt> </td><td>1×1</td><td>sub-arctic</td><td align=left>houses</td></tr>
|
||||
<tr><td nowrap valign=top><tt>31</tt> </td><td>1×1</td><td>snow</td><td align=left>houses</td></tr>
|
||||
<tr><td nowrap valign=top><tt>32</tt> </td><td>1×1</td><td>sub-arctic, sub-tropical</td><td align=left>tall office block</td></tr>
|
||||
<tr><td nowrap valign=top><tt>33</tt> </td><td>1×1</td><td>snow</td><td align=left>tall office block</td></tr>
|
||||
<tr><td nowrap valign=top><tt>34</tt> </td><td>1×1</td><td>sub-arctic</td><td align=left>tall office block</td></tr>
|
||||
<tr><td nowrap valign=top><tt>35</tt> </td><td>1×1</td><td>snow</td><td align=left>tall office block</td></tr>
|
||||
<tr><td nowrap valign=top><tt>36</tt> </td><td>1×1</td><td>sub-arctic, sub-tropical</td><td align=left>tall office block</td></tr>
|
||||
<tr><td nowrap valign=top><tt>37</tt> </td><td>1×1</td><td>snow</td><td align=left>tall office block</td></tr>
|
||||
<tr><td nowrap valign=top><tt>38</tt> </td><td>1×1</td><td>sub-arctic</td><td align=left>houses</td></tr>
|
||||
<tr><td nowrap valign=top><tt>39</tt> </td><td>1×1</td><td>snow</td><td align=left>houses</td></tr>
|
||||
<tr><td nowrap valign=top><tt>3A</tt> </td><td>1×1</td><td>sub-arctic</td><td align=left>shops and offices</td></tr>
|
||||
<tr><td nowrap valign=top><tt>3B</tt> </td><td>1×1</td><td>snow</td><td align=left>shops and offices</td></tr>
|
||||
<tr><td nowrap valign=top><tt>3C</tt> </td><td>1×1</td><td>sub-arctic</td><td align=left>church</td></tr>
|
||||
<tr><td nowrap valign=top><tt>3D</tt> </td><td>1×1</td><td>snow</td><td align=left>church</td></tr>
|
||||
<tr><td nowrap valign=top><tt>3E</tt> </td><td>1×1</td><td>sub-arctic</td><td align=left>houses</td></tr>
|
||||
<tr><td nowrap valign=top><tt>3F</tt> </td><td>1×1</td><td>snow</td><td align=left>houses</td></tr>
|
||||
<tr><td nowrap valign=top><tt>40</tt> </td><td>1×1</td><td>sub-arctic</td><td align=left>shops and offices</td></tr>
|
||||
<tr><td nowrap valign=top><tt>41</tt> </td><td>1×1</td><td>snow</td><td align=left>shops and offices</td></tr>
|
||||
<tr><td nowrap valign=top><tt>42</tt>..<tt>43</tt> </td><td>1×2</td><td>sub-arctic</td><td align=left>hotel</td></tr>
|
||||
<tr><td nowrap valign=top><tt>44</tt>..<tt>45</tt> </td><td>1×2</td><td>snow</td><td align=left>hotel</td></tr>
|
||||
<tr><td nowrap valign=top><tt>46</tt> </td><td>1×1</td><td>sub-arctic, sub-tropical</td><td align=left>shops and offices</td></tr>
|
||||
<tr><td nowrap valign=top><tt>47</tt> </td><td>1×1</td><td>snow</td><td align=left>shops and offices</td></tr>
|
||||
<tr><td nowrap valign=top><tt>48</tt> </td><td>1×1</td><td>sub-arctic</td><td align=left>tall office block</td></tr>
|
||||
<tr><td nowrap valign=top><tt>49</tt> </td><td>1×1</td><td>snow</td><td align=left>tall office block</td></tr>
|
||||
<tr><td nowrap valign=top><tt>4A</tt>..<tt>4B</tt> </td><td>2×1</td><td>sub-arctic</td><td align=left>tall office block</td></tr>
|
||||
<tr><td nowrap valign=top><tt>4C</tt>..<tt>4D</tt> </td><td>2×1</td><td>snow</td><td align=left>tall office block</td></tr>
|
||||
<tr><td nowrap valign=top><tt>4E</tt> </td><td>1×1</td><td>sub-tropical</td><td align=left>houses (with a tree in a corner)</td></tr>
|
||||
<tr><td nowrap valign=top><tt>4F</tt>, <tt>50</tt> </td><td>1×1</td><td>sub-tropical</td><td align=left>houses</td></tr>
|
||||
<tr><td nowrap valign=top><tt>51</tt> </td><td>1×1</td><td>sub-tropical</td><td align=left>houses (suburb-type)</td></tr>
|
||||
<tr><td nowrap valign=top><tt>52</tt> </td><td>1×1</td><td>sub-tropical</td><td align=left>flats</td></tr>
|
||||
<tr><td nowrap valign=top><tt>53</tt> </td><td>1×1</td><td>sub-tropical</td><td align=left>church</td></tr>
|
||||
<tr><td nowrap valign=top><tt>54</tt> </td><td>1×1</td><td>sub-tropical</td><td align=left>houses (with two trees in front)</td></tr>
|
||||
<tr><td nowrap valign=top><tt>55</tt>, <tt>56</tt> </td><td>1×1</td><td>sub-tropical</td><td align=left>flats</td></tr>
|
||||
<tr><td nowrap valign=top><tt>57</tt>..<tt>58</tt> </td><td>2×1</td><td>sub-tropical</td><td align=left>tall office block</td></tr>
|
||||
<tr><td nowrap valign=top><tt>59</tt> </td><td>1×1</td><td>sub-tropical</td><td align=left>flats</td></tr>
|
||||
<tr><td nowrap valign=top><tt>5A</tt> </td><td>1×1</td><td>sub-tropical</td><td align=left>tall office block</td></tr>
|
||||
<tr><td nowrap valign=top><tt>5B</tt> </td><td>1×1</td><td>toyland</td><td align=left>church</td></tr>
|
||||
<tr><td nowrap valign=top><tt>5C</tt>..<tt>61</tt> </td><td>1×1</td><td>toyland</td><td align=left>various types of toyland houses</td></tr>
|
||||
<tr><td nowrap valign=top><tt>62</tt> </td><td>1×1</td><td>toyland</td><td align=left>tall office block</td></tr>
|
||||
<tr><td nowrap valign=top><tt>63</tt>..<tt>64</tt> </td><td>1×2</td><td>toyland</td><td align=left>houses ('shoe' style)</td></tr>
|
||||
<tr><td nowrap valign=top><tt>65</tt> </td><td>1×1</td><td>toyland</td><td align=left>tall office block</td></tr>
|
||||
<tr><td nowrap valign=top><tt>66</tt> </td><td>1×1</td><td>toyland</td><td align=left>igloo</td></tr>
|
||||
<tr><td nowrap valign=top><tt>67</tt> </td><td>1×1</td><td>toyland</td><td align=left>tepees</td></tr>
|
||||
<tr><td nowrap valign=top><tt>68</tt>, <tt>69</tt> </td><td>1×1</td><td>toyland</td><td align=left>shops and offices</td></tr>
|
||||
<tr><td nowrap valign=top><tt>6A</tt> </td><td>1×1</td><td>toyland</td><td align=left>tall office block</td></tr>
|
||||
<tr><td nowrap valign=top><tt>6B</tt> </td><td>1×1</td><td>toyland</td><td align=left>statue</td></tr>
|
||||
<tr><td nowrap valign=top><tt>6C</tt> </td><td>1×1</td><td>toyland</td><td align=left>teapot-house</td></tr>
|
||||
<tr><td nowrap valign=top><tt>6D</tt> </td><td>1×1</td><td>toyland</td><td align=left>piggy-bank</td></tr>
|
||||
<tr><td colspan=2></td></tr> <!-- spacer -- -- (and I don't mean a walk) -->
|
||||
</table></li>
|
||||
<li>map3_lo bits 7..6: stage of construction (<tt>3</tt> = completed)</li>
|
||||
<li>map5 bits 2..0: construction counter, for buildings under construction incremented on every periodic tile processing, on wraparound the stage of construction in map3_lo is increased</li>
|
||||
<li>for large office blocks (types <tt>04</tt> and <tt>05</tt>):
|
||||
<ul>
|
||||
<li>map_owner bits 6..0: position of the lift</li>
|
||||
<li>map_owner bit 7: if set the lift is moving</li>
|
||||
<li>map5 bit 7: if set then map5 bits 5..0 hold the final position of the lift divided by 6 (valid values 0..6 except 1)</li>
|
||||
</ul></li>
|
||||
</ul>
|
||||
</td></tr>
|
||||
|
||||
<tr><td valign=top nowrap><a name="Class4"><tt> 4 </tt></a></td><td>
|
||||
Trees
|
||||
<ul>
|
||||
<li>map5 bits 7..6: number of trees minus one</li>
|
||||
<li>map5 bits 2..0: growth status: <tt>0</tt>..<tt>2</tt> - one of trees is growing, <tt>3</tt> - all trees are fully grown, <tt>4</tt>..<tt>6</tt> - one of trees is withering</li>
|
||||
<li>map3_lo bits 7..0: type of trees:
|
||||
<table>
|
||||
<tr><td nowrap valign=top><tt>00</tt>..<tt>0B</tt> </td><td align=left>temperate climate trees</td></tr>
|
||||
<tr><td nowrap valign=top><tt>0C</tt>..<tt>13</tt> </td><td align=left>sub-arctic climate trees</td></tr>
|
||||
<tr><td nowrap valign=top><tt>14</tt>..<tt>1A</tt> </td><td align=left>rainforest trees</td></tr>
|
||||
<tr><td nowrap valign=top><tt>1B</tt> </td><td align=left>cactus plants</td></tr>
|
||||
<tr><td nowrap valign=top><tt>1C</tt>..<tt>1F</tt> </td><td align=left>sub-tropical climate, non-rainforest, non-desert trees</td></tr>
|
||||
<tr><td nowrap valign=top><tt>20</tt>..<tt>28</tt> </td><td align=left>toyland trees</td></tr>
|
||||
</table>
|
||||
(note: the actually displayed set of trees depends on both type and number of trees)
|
||||
</li>
|
||||
<li>map3_hi bits 7..5: type of hedge on the SW border of the tile (1 through 6, or 0=none)</li>
|
||||
<li>map3_hi bits 4..2: type of hedge on the SE border of the tile (1 through 6, or 0=none)</li>
|
||||
<li>map2 bits 5..4:
|
||||
<table>
|
||||
<tr><td nowrap valign=top><tt>0</tt> </td><td align=left>on grass</td></tr>
|
||||
<tr><td nowrap valign=top><tt>1</tt> </td><td align=left>on rough land</td></tr>
|
||||
<tr><td nowrap valign=top><tt>2</tt> </td><td align=left>on snow or desert; map2 bits 7..6 - amount of snow or desert (for desert always set to 3 in TTD)
|
||||
</td></tr>
|
||||
</table></li>
|
||||
<li>map2 bits 3..0: update counter, incremented on every periodic processing, on wraparound the growth status is updated (or, if it's <tt>3</tt>, a random action is taken)</li>
|
||||
<li>map_owner: <a href="#OwnershipInfo">owner</a> (normally <tt>10</tt>)</li>
|
||||
</ul>
|
||||
</td></tr>
|
||||
|
||||
<tr><td valign=top nowrap><a name="Class5"><tt> 5 </tt></a></td><td>
|
||||
Station tile
|
||||
<ul>
|
||||
<li>map5: tile type:
|
||||
<table>
|
||||
<tr><td nowrap valign=top><tt>00</tt>..<tt>07</tt> </td><td align=left>railway station
|
||||
<br><tt>00</tt>..<tt>01</tt> - open platform, <tt>02</tt>..<tt>03</tt> - open platform with station building, <tt>04</tt>....<tt>07</tt> - roofed platform
|
||||
<br>bit 0: clear = in X direction, set = in Y direction
|
||||
</td></tr>
|
||||
<tr><td nowrap valign=top><tt>08</tt>..<tt>33</tt> </td><td align=left>large airport
|
||||
<table>
|
||||
<tr><td nowrap valign=top><tt>0B</tt> </td><td align=left>pad 1</td></tr>
|
||||
<tr><td nowrap valign=top><tt>16</tt>..<tt>19</tt> </td><td align=left>runway middle</td></tr>
|
||||
<tr><td nowrap valign=top><tt>1A</tt> </td><td align=left>runway ending</td></tr>
|
||||
<tr><td nowrap valign=top><tt>1C</tt> </td><td align=left>control tower</td></tr>
|
||||
<tr><td nowrap valign=top><tt>20</tt> </td><td align=left>hangar</td></tr>
|
||||
<tr><td nowrap valign=top><tt>21</tt> </td><td align=left>pad 3</td></tr>
|
||||
<tr><td nowrap valign=top><tt>22</tt> </td><td align=left>pad 2</td></tr>
|
||||
<tr><td nowrap valign=top><tt>27</tt>..<tt>32</tt> </td><td align=left>radar (animated)</td></tr>
|
||||
<tr><td nowrap valign=top><tt>33</tt> </td><td align=left>transmitter</td></tr>
|
||||
</table>
|
||||
The initial layout of a large airport is (rows in Y direction, columns in X direction):
|
||||
<pre>
|
||||
1F 1B 1E 33 26 1A
|
||||
09 24 0B 0C 0D 16
|
||||
21 1D 23 0E 0F 17
|
||||
09 22 0D 11 10 18
|
||||
09 08 14 13 12 19
|
||||
20 0A 15 1C 27 1A
|
||||
</pre>
|
||||
</td></tr>
|
||||
<tr><td nowrap valign=top><tt>34</tt>..<tt>41</tt> </td><td align=left>small airport
|
||||
<table>
|
||||
<tr><td nowrap valign=top><tt>3A</tt>..<tt>3D</tt> </td><td align=left>field with the wind meter (animated)</td></tr>
|
||||
<tr><td nowrap valign=top><tt>3E</tt> </td><td align=left>runway south ending</td></tr>
|
||||
<tr><td nowrap valign=top><tt>3F</tt> </td><td align=left>runway middle</td></tr>
|
||||
<tr><td nowrap valign=top><tt>40</tt> </td><td align=left>runway north ending</td></tr>
|
||||
<tr><td nowrap valign=top><tt>41</tt> </td><td align=left>hangar</td></tr>
|
||||
</table>
|
||||
The initial layout of a small airport is (rows in Y direction, columns in X direction):
|
||||
<pre>
|
||||
36 3A 40
|
||||
35 39 3F
|
||||
34 38 3F
|
||||
41 37 3E
|
||||
</pre>
|
||||
</td></tr>
|
||||
<tr><td nowrap valign=top><tt>42</tt> </td><td align=left>heliport</td></tr>
|
||||
<tr><td nowrap valign=top><tt>43</tt>..<tt>46</tt> </td><td align=left>lorry loading area;
|
||||
exit towards: <tt>43</tt> - NE, <tt>44</tt> - SE, <tt>45</tt> - SW, <tt>46</tt> - NW
|
||||
</td></tr>
|
||||
<tr><td nowrap valign=top><tt>47</tt>..<tt>4A</tt> </td><td align=left>bus station;
|
||||
exit towards: <tt>47</tt> - NE, <tt>48</tt> - SE, <tt>49</tt> - SW, <tt>4A</tt> - NW
|
||||
<tr><td nowrap valign=top><tt>4B</tt> </td><td align=left>oilfield</td></tr>
|
||||
<tr><td nowrap valign=top><tt>4C</tt>..<tt>51</tt> </td><td align=left>ship dock;
|
||||
<tt>4C</tt> - SW coast part, <tt>4D</tt> - NW coast part, <tt>4E</tt> - NE coast part, <tt>4F</tt> - SE coast part, <tt>50</tt> - X direction water part, <tt>51</tt> - Y direction water part
|
||||
<tr><td nowrap valign=top><tt>52</tt> </td><td align=left>buoy</td></tr>
|
||||
</td></tr>
|
||||
<tr><td colspan=2></td></tr> <!-- spacer -->
|
||||
</table>
|
||||
</li>
|
||||
<li>map_owner: <a href="#OwnershipInfo">owner</a> of the station</li>
|
||||
<li>map2: index into the <a href="#_StationArray">array of stations</a></li>
|
||||
<li>map3_lo bits 0..3: <a href="#TrackType">track type</a> for railway stations, must be 0 for all the other stations</li>
|
||||
</ul>
|
||||
</td></tr>
|
||||
|
||||
<tr><td valign=top nowrap><a name="Class6"><tt> 6 </tt></a></td><td>
|
||||
<ul>
|
||||
<li>map5: tile type:
|
||||
<table>
|
||||
<tr><td nowrap valign=top><tt>00</tt> </td><td align=left>water</td></tr>
|
||||
<tr><td nowrap valign=top><tt>01</tt> </td><td align=left>coast or riverbank</td></tr>
|
||||
<tr><td nowrap valign=top><tt>10</tt>..<tt>1B</tt> </td><td align=left>canal locks
|
||||
<table>
|
||||
<tr><td nowrap valign=top><tt>10</tt> </td><td align=left>middle part, (SW-NE direction)
|
||||
<tr><td nowrap valign=top><tt>11</tt> </td><td align=left>middle part, (NW-SE direction)
|
||||
<tr><td nowrap valign=top><tt>12</tt> </td><td align=left>middle part, (NE-SW direction)
|
||||
<tr><td nowrap valign=top><tt>13</tt> </td><td align=left>middle part, (SE-NW direction)
|
||||
<tr><td nowrap valign=top><tt>14</tt> </td><td align=left>lower part, (SW-NE direction)
|
||||
<tr><td nowrap valign=top><tt>15</tt> </td><td align=left>lower part, (NW-SE direction)
|
||||
<tr><td nowrap valign=top><tt>16</tt> </td><td align=left>lower part, (NE-SW direction)
|
||||
<tr><td nowrap valign=top><tt>17</tt> </td><td align=left>lower part, (SE-NW direction)
|
||||
<tr><td nowrap valign=top><tt>18</tt> </td><td align=left>upper part, (SW-NE direction)
|
||||
<tr><td nowrap valign=top><tt>19</tt> </td><td align=left>upper part, (NW-SE direction)
|
||||
<tr><td nowrap valign=top><tt>1A</tt> </td><td align=left>upper part, (NE-SW direction)
|
||||
<tr><td nowrap valign=top><tt>1B</tt> </td><td align=left>upper part, (SE-NW direction)
|
||||
</table>
|
||||
<tr><td nowrap valign=top><tt>80</tt>..<tt>83</tt> </td><td align=left>ship depots
|
||||
<table>
|
||||
<tr><td nowrap valign=top><tt>80</tt> </td><td align=left>ship depot, NE part (X direction)
|
||||
<tr><td nowrap valign=top><tt>81</tt> </td><td align=left>ship depot, SW part (X direction)
|
||||
<tr><td nowrap valign=top><tt>82</tt> </td><td align=left>ship depot, NW part (Y direction)
|
||||
<tr><td nowrap valign=top><tt>83</tt> </td><td align=left>ship depot, SE part (Y direction)
|
||||
|
||||
</td></tr>
|
||||
|
||||
</table>
|
||||
</td></tr>
|
||||
</table></li>
|
||||
<li>map_owner: <a href="#OwnershipInfo">owner</a> (for water and coasts normally <tt>11</tt>)</li>
|
||||
</ul>
|
||||
</td></tr>
|
||||
|
||||
<tr><td valign=top nowrap><a name="Class7"><tt> 7 </tt></a></td><td>
|
||||
Void
|
||||
<p>
|
||||
Tiles of this class form an invisible, one tile wide border at the south (bottom) edges of the map, so as to protect several algorithms from the consequences of a wraparound at the edges.
|
||||
</p>
|
||||
</td></tr>
|
||||
|
||||
<tr><td valign=top nowrap><a name="Class8"><tt> 8 </tt></a></td><td>
|
||||
Industry tile
|
||||
<ul>
|
||||
<li>map5: type:
|
||||
<br><small>(note: this is not the same as the <a href="#industry.type">industry type</a> stored in the <a href="#_IndustryArray">array of industries</a>)</small>
|
||||
<table>
|
||||
<tr><td nowrap valign=top><tt>00</tt>..<tt>06</tt> </td><td align=left>coal mine
|
||||
<table>
|
||||
<tr><td nowrap valign=top><tt>00</tt> </td><td align=left>wheel tower when not animated</td></tr>
|
||||
<tr><td nowrap valign=top><tt>01</tt> </td><td align=left>wheel tower when animated; animation state in map_owner bits 5..0; map_owner bit 6 set = sound already generated</td></tr>
|
||||
</table>
|
||||
</td></tr>
|
||||
<tr><td nowrap valign=top><tt>07</tt>..<tt>0A</tt> </td><td align=left>power station
|
||||
<table>
|
||||
<tr><td nowrap valign=top><tt>08</tt> </td><td align=left>chimney</td></tr>
|
||||
<tr><td nowrap valign=top><tt>0A</tt> </td><td align=left>transformer; animation progress in map_owner bits 5..2 (valid range <tt>0</tt>..<tt>7</tt>)</td></tr>
|
||||
</table>
|
||||
</td></tr>
|
||||
<tr><td nowrap valign=top><tt>0B</tt>..<tt>0F</tt> </td><td align=left>sawmill</td></tr>
|
||||
<tr><td nowrap valign=top><tt>10</tt>..<tt>11</tt> </td><td align=left>forest
|
||||
<table>
|
||||
<tr><td nowrap valign=top><tt>11</tt> </td><td align=left>trees cut down</td></tr>
|
||||
</table>
|
||||
</td></tr>
|
||||
<tr><td nowrap valign=top><tt>12</tt>..<tt>17</tt> </td><td align=left>oil refinery</td></tr>
|
||||
<tr><td nowrap valign=top><tt>18</tt>..<tt>1C</tt> </td><td align=left>oil rig</td></tr>
|
||||
<tr><td nowrap valign=top><tt>1D</tt>..<tt>20</tt> </td><td align=left>oil wells
|
||||
<table>
|
||||
<tr><td nowrap valign=top><tt>1D</tt> </td><td align=left>not animated</td></tr>
|
||||
<tr><td nowrap valign=top><tt>1E</tt>..<tt>20</tt> </td><td align=left>various stages of animation; progress of animation in map_owner bits 1..0</td></tr>
|
||||
</table>
|
||||
</td></tr>
|
||||
<tr><td nowrap valign=top><tt>21</tt>..<tt>26</tt> </td><td align=left>farm</td></tr>
|
||||
<tr><td nowrap valign=top><tt>27</tt>..<tt>2A</tt> </td><td align=left>factory (temperate climate)</td></tr>
|
||||
<tr><td nowrap valign=top><tt>2B</tt>..<tt>2E</tt> </td><td align=left>printing works</td></tr>
|
||||
<tr><td nowrap valign=top><tt>2F</tt>..<tt>33</tt> </td><td align=left>copper ore mine
|
||||
<table>
|
||||
<tr><td nowrap valign=top><tt>2F</tt> </td><td align=left>wheel tower when not animated</td></tr>
|
||||
<tr><td nowrap valign=top><tt>30</tt> </td><td align=left>wheel tower when animated; animation state in map_owner bits 5..0; map_owner bit 6 set = sound already generated</td></tr>
|
||||
<tr><td nowrap valign=top><tt>31</tt> </td><td align=left>chimney</td></tr>
|
||||
</table>
|
||||
</td></tr>
|
||||
<tr><td nowrap valign=top><tt>34</tt>..<tt>39</tt> </td><td align=left>steel mill</td></tr>
|
||||
<tr><td nowrap valign=top><tt>3A</tt>..<tt>3B</tt> </td><td align=left>bank (temperate climate)</td></tr>
|
||||
<tr><td nowrap valign=top><tt>3C</tt>..<tt>3F</tt> </td><td align=left>food processing plant</td></tr>
|
||||
<tr><td nowrap valign=top><tt>40</tt>..<tt>47</tt> </td><td align=left>paper mill</td></tr>
|
||||
<tr><td nowrap valign=top><tt>48</tt>..<tt>58</tt> </td><td align=left>gold mine
|
||||
<table>
|
||||
<tr><td nowrap valign=top><tt>4F</tt> </td><td align=left>wheel tower when not animated</td></tr>
|
||||
<tr><td nowrap valign=top><tt>58</tt> </td><td align=left>wheel tower when animated; animation state in map_owner bits 5..0; map_owner bit 6 set = sound already generated</td></tr>
|
||||
</table>
|
||||
</td></tr>
|
||||
<tr><td nowrap valign=top><tt>59</tt>..<tt>5A</tt> </td><td align=left>bank (sub-arctic or sub-tropical climate)</td></tr>
|
||||
<tr><td nowrap valign=top><tt>5B</tt>..<tt>63</tt> </td><td align=left>diamond mine</td></tr>
|
||||
<tr><td nowrap valign=top><tt>64</tt>..<tt>73</tt> </td><td align=left>iron ore mine</td></tr>
|
||||
<tr><td nowrap valign=top><tt>74</tt></td><td align=left>fruit plantation</td></tr>
|
||||
<tr><td nowrap valign=top><tt>75</tt></td><td align=left>rubber plantation</td></tr>
|
||||
<tr><td nowrap valign=top><tt>76</tt>..<tt>77</tt> </td><td align=left>water supply</td></tr>
|
||||
<tr><td nowrap valign=top><tt>78</tt></td><td align=left>water tower</td></tr>
|
||||
<tr><td nowrap valign=top><tt>79</tt>..<tt>7C</tt> </td><td align=left>factory (sub-tropical climate)</td></tr>
|
||||
<tr><td nowrap valign=top><tt>7D</tt>..<tt>80</tt> </td><td align=left>lumber mill</td></tr>
|
||||
<tr><td nowrap valign=top><tt>81</tt>..<tt>82</tt> </td><td align=left>candyfloss forest
|
||||
<table>
|
||||
<tr><td nowrap valign=top><tt>82</tt> </td><td align=left>candyfloss 'trees' cut down</td></tr>
|
||||
</table>
|
||||
</td></tr>
|
||||
<tr><td nowrap valign=top><tt>83</tt>..<tt>86</tt> </td><td align=left>sweet factory</td></tr>
|
||||
<tr><td nowrap valign=top><tt>87</tt>..<tt>88</tt> </td><td align=left>battery farm
|
||||
<table>
|
||||
<tr><td nowrap valign=top><tt>88</tt> </td><td align=left>batteries 'reaped'</td></tr>
|
||||
</table>
|
||||
</td></tr>
|
||||
<tr><td nowrap valign=top><tt>89</tt></td><td align=left>cola wells</td></tr>
|
||||
<tr><td nowrap valign=top><tt>8A</tt>..<tt>8D</tt> </td><td align=left>toy shop</td></tr>
|
||||
<tr><td nowrap valign=top><tt>8E</tt>..<tt>93</tt> </td><td align=left>toy factory
|
||||
<table>
|
||||
<tr><td nowrap valign=top><tt>8F</tt> </td><td align=left>animated part; animation state in map3_lo (valid range <tt>00</tt>..<tt>31</tt>)<br>
|
||||
tile animation is started (map3_hi zeroed) on the periodic processing if <a href="#industry.didtransform">field <tt>2C</tt></a> in the corresponding industry array entry is nonzero<br>
|
||||
while the animation is in progress (see the <a href="#_AnimatedTilesList">array at <tt>04328</tt></a>) map3_hi holds the number of animation cycles that have already taken place; when this number reaches 8 the animation is stopped</td></tr>
|
||||
</table>
|
||||
</td></tr>
|
||||
<tr><td nowrap valign=top><tt>94</tt>..<tt>9B</tt> </td><td align=left>plastic fountains (various stages of cyclic animation)</td></tr>
|
||||
<tr><td nowrap valign=top><tt>9C</tt>..<tt>9F</tt> </td><td align=left>fizzy drink factory</td></tr>
|
||||
<tr><td nowrap valign=top><tt>A0</tt>..<tt>A3</tt> </td><td align=left>bubble generator
|
||||
<table>
|
||||
<tr><td nowrap valign=top><tt>A1</tt> </td><td align=left>generators</td></tr>
|
||||
<tr><td nowrap valign=top><tt>A2</tt> </td><td align=left>bubble capture facility; animation state in map3_lo (valid range <tt>00</tt>..<tt>27</tt>)</td></tr>
|
||||
</table>
|
||||
</td></tr>
|
||||
<tr><td nowrap valign=top><tt>A4</tt>..<tt>A6</tt> </td><td align=left>toffee quarry
|
||||
<table>
|
||||
<tr><td nowrap valign=top><tt>A5</tt> </td><td align=left>animated part; animation state in map3_lo (valid range <tt>00</tt>..<tt>45</tt>)</td></tr>
|
||||
</table>
|
||||
</td></tr>
|
||||
<tr><td nowrap valign=top><tt>A7</tt>..<tt>AE</tt> </td><td align=left>sugar mine
|
||||
<table>
|
||||
<tr><td nowrap valign=top><tt>AE</tt> </td><td align=left>animated part; animation state in map3_lo (valid range <tt>00</tt>..<tt>5F</tt>)</td></tr>
|
||||
</table>
|
||||
</td></tr>
|
||||
<tr><td colspan=2></td></tr> <!-- spacer -->
|
||||
</table></li>
|
||||
<li>map2: index into the <a href="#_IndustryArray">array of industries</a>
|
||||
</li>
|
||||
<li>map_owner bit 7: clear = under construction
|
||||
<ul>
|
||||
<li>map_owner bits 4..2: construction counter, for buildings under construction incremented on every periodic tile processing
|
||||
</li>
|
||||
</ul></li>
|
||||
<li>map_owner bits 1..0: stage of construction (<tt>3</tt> = completed), incremented when the construction counter wraps around
|
||||
<br>the meaning is different for some animated tiles which are never under construction (types <tt>01</tt>, <tt>1E</tt>..<tt>20</tt>, <tt>30</tt>, <tt>58</tt>; see above)
|
||||
</li>
|
||||
</ul>
|
||||
</td></tr>
|
||||
|
||||
<tr><td valign=top nowrap><a name="Class9"><tt> 9 </tt></a></td><td>
|
||||
map5 bits 7..4 clear: tunnel entrance/exit
|
||||
<ul>
|
||||
<li>map5 bits 3..2: <tt>0</tt> - railway tunnel, <tt>1</tt> - road tunnel</li>
|
||||
<li>map5 bits 1..0 - direction: entrance towards: <tt>0</tt> = NE, <tt>1</tt> = SE, <tt>2</tt> = SW, <tt>3</tt> = NW</li>
|
||||
<li>map_owner: <a href="#OwnershipInfo">owner</a> of the tunnel</li>
|
||||
<li>map3_lo bits 3..0 = <a href="#TrackType">track type</a> for railway tunnel, must be 0 for road tunnel</li>
|
||||
<li>map3_hi bit 7 set = on snow or desert</li>
|
||||
</ul>
|
||||
map5 bit 7 set: bridge
|
||||
<ul><li>
|
||||
map5 bit 6 clear: bridge ending
|
||||
<ul>
|
||||
<li>map5 bit 5: clear - northern, set - southern ending</li>
|
||||
<li>map3_lo bits 3..0 = <a href="#TrackType">type of track</a> on the bridge, must be 0 for road bridge</li>
|
||||
<li>map_owner: <a href="#OwnershipInfo">owner</a> of the bridge</li>
|
||||
</ul>
|
||||
map5 bit 6 set: bridge middle part
|
||||
<ul>
|
||||
<li>map5 bit 5 clear:
|
||||
<ul>
|
||||
<li>map5 bits 4..3: land under bridge: <tt>0</tt> - grass, snow or desert, <tt>1</tt> - water</li>
|
||||
</ul>
|
||||
map5 bit 5 set:
|
||||
<ul>
|
||||
<li>map5 bits 4..3: transport route under bridge: <tt>0</tt> - railway, <tt>1</tt> - road</li>
|
||||
</ul>
|
||||
<li>map3_lo bits 7..4 = <a href="#TrackType">type of track</a> on the bridge, must be 0 for road bridge</li>
|
||||
<li>map3_lo bits 3..0 = <a href="#TrackType">type of track</a> under the bridge, if any</li>
|
||||
<li>map2 bits 3..0: bridge piece (<tt>0</tt>..<tt>5</tt>)
|
||||
<li>map_owner: <a href="#OwnershipInfo">owner</a> of the land under bridge</li>
|
||||
</ul></li>
|
||||
<li>map5 bits 2..1: <tt>0</tt> - railway bridge, <tt>1</tt> - road bridge</li>
|
||||
<li>map5 bit 0: clear - bridge in the X direction, set - bridge in the Y direction</li>
|
||||
<li>map2 bits 7..4: <a name="BridgeType">bridge type</a>:
|
||||
<table>
|
||||
<tr><th align=left>Type </th><th align=left>Max. speed (mph) </th><th align=left>Description</th></tr>
|
||||
<tr><td nowrap valign=top><tt>0</tt> </td><td align=center>20</td><td align=left>wooden</td></tr>
|
||||
<tr><td nowrap valign=top><tt>1</tt> </td><td align=center>30</td><td align=left>concrete</td></tr>
|
||||
<tr><td nowrap valign=top><tt>2</tt> </td><td align=center>40</td><td align=left>girder, steel</td></tr>
|
||||
<tr><td nowrap valign=top><tt>3</tt> </td><td align=center>50</td><td align=left>suspension, concrete</td></tr>
|
||||
<tr><td nowrap valign=top><tt>4</tt> </td><td align=center>60</td><td align=left>suspension, steel</td></tr>
|
||||
<tr><td nowrap valign=top><tt>5</tt> </td><td align=center>70</td><td align=left>suspension, steel</td></tr>
|
||||
<tr><td nowrap valign=top><tt>6</tt> </td><td align=center>100</td><td align=left>cantilever, steel</td></tr>
|
||||
<tr><td nowrap valign=top><tt>7</tt> </td><td align=center>130</td><td align=left>cantilever, steel</td></tr>
|
||||
<tr><td nowrap valign=top><tt>8</tt> </td><td align=center>150</td><td align=left>cantilever, steel</td></tr>
|
||||
<tr><td nowrap valign=top><tt>9</tt> </td><td align=center>160</td><td align=left>girder, steel</td></tr>
|
||||
<tr><td nowrap valign=top><tt>A</tt> </td><td align=center>200</td><td align=left>tubular, steel</td></tr>
|
||||
</table></li>
|
||||
<li>map3_hi bit 7 set = on snow or desert</li>
|
||||
</ul>
|
||||
</td></tr>
|
||||
|
||||
<tr><td valign=top nowrap><a name="ClassA"><tt> A </tt></a></td><td>
|
||||
<ul>
|
||||
<li>map5: tile type:
|
||||
<table>
|
||||
<tr><td nowrap valign=top><tt>00</tt> </td><td align=left>transmitter</td></tr>
|
||||
<tr><td nowrap valign=top><tt>01</tt> </td><td align=left>lighthouse</td></tr>
|
||||
<tr><td nowrap valign=top><tt>02</tt> </td><td align=left>company statue</td></tr>
|
||||
<tr><td nowrap valign=top><tt>03</tt> </td><td align=left>company-owned land</td></tr>
|
||||
<tr><td nowrap valign=top><tt>80</tt>..<tt>93</tt> </td><td align=left>company headquarters (5 sets of 4 tiles each, updated quarterly depending on the company performance)</td></tr>
|
||||
</table>
|
||||
</li>
|
||||
<li>map_owner: <a href="#OwnershipInfo">owner</a> of the object (for lighthouses and transmitters normally <tt>10</tt>)</li>
|
||||
</ul>
|
||||
</td></tr>
|
||||
|
||||
<tr><td colspan=2>
|
||||
Classes <tt>B</tt> through <tt>F</tt> are reserved. The presence of a tile in one of the reserved classes will crash TTD.
|
||||
</td></tr>
|
||||
</table>
|
||||
|
||||
|
||||
<hr>
|
||||
Copyright © 2003 by Marcin Grzegorczyk.<br>
|
||||
Transport Tycoon and Transport Tycoon Deluxe are Copyright © by Chris Sawyer. All the other trademarks are the property of their respective owners.<br>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -1,70 +0,0 @@
|
|||
Multiplayer Manual for OpenTTD
|
||||
----------------------------------------
|
||||
|
||||
1. Starting a Server
|
||||
|
||||
- click "multiplayer" on the startup screen
|
||||
- click "start server"
|
||||
- type in a game name
|
||||
- click "start game" ,"load game" or "load scenario"
|
||||
|
||||
2. Connecting to a Server
|
||||
|
||||
- click "multiplayer" on the startup screen
|
||||
|
||||
- if you want to connect to any network game in your LAN click "find server"
|
||||
|
||||
- if there were more then one server
|
||||
- select one in the list below the buttons
|
||||
- click on "join game".
|
||||
|
||||
- if you want to play over the internet you should have the ip of the game server you want connect to.
|
||||
- click direct connect
|
||||
- type in the ip address or hostname
|
||||
- if you want to add a port use :<port>
|
||||
- if you want to connect as an special player use #<player-no>
|
||||
|
||||
3. Connecting to a Server over the Console
|
||||
|
||||
- open the console and type in the following command:
|
||||
|
||||
]connect <ip/host>:<port>#<player-no>
|
||||
|
||||
|
||||
4. Playing Internet-Games
|
||||
|
||||
- since OpenTTD 0.3.4 you can also play internet games over higher latency connections.
|
||||
- to do this the gameservers sync frequency should be highered to a decent value.
|
||||
- open the console [on the server]
|
||||
- type in the following command:
|
||||
|
||||
] *net_sync_freq = <4-80>
|
||||
|
||||
default value: 4
|
||||
|
||||
- this is lowering the sync frequency of the server and your game should be less laggy.
|
||||
- this is a server variable: it has nothing to do with the clients
|
||||
|
||||
- you can also change when the clients ready packet is sent if you still have lags.
|
||||
- open the console
|
||||
- type in the following command:
|
||||
|
||||
] *net_ready_ahead = <1-8>
|
||||
|
||||
default value: 1
|
||||
|
||||
- in that way your client is sending its "i am ready for next sync" a bit earlier
|
||||
thats quite good for games where some players have higher latencies than the others.
|
||||
- this is a client variable: it has nothing to do with the server
|
||||
|
||||
- to change the client timeout time
|
||||
- open the console [on the server]
|
||||
- type in the following command:
|
||||
|
||||
] *net_client_timeout = <30-x>
|
||||
|
||||
default value: 300
|
||||
|
||||
- warning: a too low value will disconnect your clients if they have a short lag
|
||||
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 51 KiB |
|
@ -1,38 +0,0 @@
|
|||
0,9,10,2,3,13,9,9,0,10,4,15,6,11,14,1
|
||||
dark blue=0 =0
|
||||
pale_green=1 =9
|
||||
pink=2 =10
|
||||
yellow=3 =2
|
||||
red=4 =3
|
||||
light blue=5 =13
|
||||
green=6 =9
|
||||
dark green=7 =9
|
||||
blue=8 =0
|
||||
cream=9 =10
|
||||
mauve=10 =4
|
||||
purple=11 =15
|
||||
orange=12 =6
|
||||
brown=13 =11
|
||||
grey=14 =14
|
||||
white=15 =1
|
||||
|
||||
|
||||
=blue=0
|
||||
=white=1
|
||||
=yellow=2
|
||||
=red=3
|
||||
=blue=4
|
||||
=grey=5
|
||||
=orange=6
|
||||
=green=7
|
||||
=light yellow=8
|
||||
=light green=9
|
||||
=cream=10
|
||||
=brown=11
|
||||
=white=12
|
||||
=light blue=13
|
||||
=dark grey=14
|
||||
=purple=15
|
||||
=black=16
|
||||
=dark green=17=not good
|
||||
=dark grey=21
|
Binary file not shown.
Before Width: | Height: | Size: 37 KiB |
|
@ -1,77 +0,0 @@
|
|||
#include "stdafx.h"
|
||||
#include "ttd.h"
|
||||
#include "viewport.h"
|
||||
#include "command.h"
|
||||
|
||||
static void DrawTile_Dummy(TileInfo *ti)
|
||||
{
|
||||
DrawGroundSpriteAt(0x3EC, ti->x, ti->y, ti->z);
|
||||
}
|
||||
|
||||
|
||||
static uint GetSlopeZ_Dummy(TileInfo *ti) {
|
||||
return GetPartialZ(ti->x&0xF, ti->y&0xF, ti->tileh) + ti->z;
|
||||
}
|
||||
|
||||
static uint GetSlopeTileh_Dummy(TileInfo *ti) {
|
||||
return ti->tileh;
|
||||
}
|
||||
|
||||
static int32 ClearTile_Dummy(uint tile, byte flags) {
|
||||
return_cmd_error(STR_0001_OFF_EDGE_OF_MAP);
|
||||
}
|
||||
|
||||
|
||||
static void GetAcceptedCargo_Dummy(uint tile, AcceptedCargo *ac)
|
||||
{
|
||||
/* not used */
|
||||
}
|
||||
|
||||
static void GetTileDesc_Dummy(uint tile, TileDesc *td)
|
||||
{
|
||||
td->str = STR_EMPTY;
|
||||
td->owner = OWNER_NONE;
|
||||
}
|
||||
|
||||
static void AnimateTile_Dummy(uint tile)
|
||||
{
|
||||
/* not used */
|
||||
}
|
||||
|
||||
static void TileLoop_Dummy(uint tile)
|
||||
{
|
||||
/* not used */
|
||||
}
|
||||
|
||||
static void ClickTile_Dummy(uint tile)
|
||||
{
|
||||
/* not used */
|
||||
}
|
||||
|
||||
static void ChangeTileOwner_Dummy(uint tile, byte old_player, byte new_player)
|
||||
{
|
||||
/* not used */
|
||||
}
|
||||
|
||||
static uint32 GetTileTrackStatus_Dummy(uint tile, TransportType mode)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
const TileTypeProcs _tile_type_dummy_procs = {
|
||||
DrawTile_Dummy, /* draw_tile_proc */
|
||||
GetSlopeZ_Dummy, /* get_slope_z_proc */
|
||||
ClearTile_Dummy, /* clear_tile_proc */
|
||||
GetAcceptedCargo_Dummy, /* get_accepted_cargo_proc */
|
||||
GetTileDesc_Dummy, /* get_tile_desc_proc */
|
||||
GetTileTrackStatus_Dummy, /* get_tile_track_status_proc */
|
||||
ClickTile_Dummy, /* click_tile_proc */
|
||||
AnimateTile_Dummy, /* animate_tile_proc */
|
||||
TileLoop_Dummy, /* tile_loop_clear */
|
||||
ChangeTileOwner_Dummy, /* change_tile_owner_clear */
|
||||
NULL, /* get_produced_cargo_proc */
|
||||
NULL, /* vehicle_enter_tile_proc */
|
||||
NULL, /* vehicle_leave_tile_proc */
|
||||
GetSlopeTileh_Dummy, /* get_slope_tileh_proc */
|
||||
};
|
||||
|
1471
trunk/economy.c
1471
trunk/economy.c
File diff suppressed because it is too large
Load Diff
|
@ -1,78 +0,0 @@
|
|||
#ifndef ECONOMY_H
|
||||
#define ECONOMY_H
|
||||
|
||||
typedef struct {
|
||||
// Maximum possible loan
|
||||
int32 max_loan;
|
||||
int32 max_loan_unround;
|
||||
// Economy fluctuation status
|
||||
int fluct;
|
||||
// Interest
|
||||
byte interest_rate;
|
||||
byte infl_amount;
|
||||
byte infl_amount_pr;
|
||||
} Economy;
|
||||
|
||||
VARDEF Economy _economy;
|
||||
|
||||
typedef struct Subsidy {
|
||||
byte cargo_type;
|
||||
byte age;
|
||||
byte from;
|
||||
byte to;
|
||||
} Subsidy;
|
||||
|
||||
|
||||
enum {
|
||||
SCORE_VEHICLES = 0,
|
||||
SCORE_STATIONS = 1,
|
||||
SCORE_MIN_PROFIT = 2,
|
||||
SCORE_MIN_INCOME = 3,
|
||||
SCORE_MAX_INCOME = 4,
|
||||
SCORE_DELIVERED = 5,
|
||||
SCORE_CARGO = 6,
|
||||
SCORE_MONEY = 7,
|
||||
SCORE_LOAN = 8,
|
||||
SCORE_TOTAL = 9, // This must always be the last entry
|
||||
|
||||
NUM_SCORE = 10, // How many scores are there..
|
||||
|
||||
SCORE_MAX = 1000, // The max score that can be in the performance history
|
||||
// the scores together of score_info is allowed to be more!
|
||||
};
|
||||
|
||||
typedef struct ScoreInfo {
|
||||
byte id; // Unique ID of the score
|
||||
int needed; // How much you need to get the perfect score
|
||||
int score; // How much score it will give
|
||||
} ScoreInfo;
|
||||
|
||||
static const ScoreInfo score_info[] = {
|
||||
{SCORE_VEHICLES, 120, 100},
|
||||
{SCORE_STATIONS, 80, 100},
|
||||
{SCORE_MIN_PROFIT, 10000, 100},
|
||||
{SCORE_MIN_INCOME, 50000, 50},
|
||||
{SCORE_MAX_INCOME, 100000, 100},
|
||||
{SCORE_DELIVERED, 40000, 400},
|
||||
{SCORE_CARGO, 8, 50},
|
||||
{SCORE_MONEY, 10000000, 50},
|
||||
{SCORE_LOAN, 250000, 50},
|
||||
{SCORE_TOTAL, 0, 0}
|
||||
};
|
||||
|
||||
int _score_part[MAX_PLAYERS][NUM_SCORE];
|
||||
|
||||
int UpdateCompanyRatingAndValue(Player *p, bool update);
|
||||
void UpdatePlayerHouse(Player *p, uint score);
|
||||
|
||||
|
||||
VARDEF Subsidy _subsidies[MAX_PLAYERS];
|
||||
Pair SetupSubsidyDecodeParam(Subsidy *s, bool mode);
|
||||
void DeleteSubsidyWithIndustry(byte index);
|
||||
void DeleteSubsidyWithStation(byte index);
|
||||
void RemoteSubsidyAdd(Subsidy *s_new);
|
||||
|
||||
int32 GetTransportedGoodsIncome(uint num_pieces, uint dist, byte transit_days, byte cargo_type);
|
||||
uint MoveGoodsToStation(uint tile, int w, int h, int type, uint amount);
|
||||
|
||||
#endif /* ECONOMY_H */
|
|
@ -1,22 +0,0 @@
|
|||
#include <stdio.h>
|
||||
|
||||
// This pretty simple file checks if the system is LITTLE_ENDIAN or BIG_ENDIAN
|
||||
// it does that by putting a 1 and a 0 in an array, and read it out as one
|
||||
// number. If it is 1, it is LITTLE_ENDIAN, if it is 256, it is BIG_ENDIAN
|
||||
//
|
||||
// After that it outputs the contents of an include files (endian.h)
|
||||
// that says or TTD_LITTLE_ENDIAN, or TTD_BIG_ENDIAN. Makefile takes
|
||||
// care of the real writing to the file.
|
||||
|
||||
int main () {
|
||||
unsigned char EndianTest[2] = { 1, 0 };
|
||||
printf("#ifndef ENDIAN_H\n#define ENDIAN_H\n");
|
||||
if( *(short *) EndianTest == 1 )
|
||||
printf("#define TTD_LITTLE_ENDIAN\n");
|
||||
else
|
||||
printf("#define TTD_BIG_ENDIAN\n");
|
||||
|
||||
printf("#endif\n");
|
||||
|
||||
return 0;
|
||||
}
|
557
trunk/engine.c
557
trunk/engine.c
|
@ -1,557 +0,0 @@
|
|||
#include "stdafx.h"
|
||||
#include "ttd.h"
|
||||
#include "engine.h"
|
||||
#include "table/engines.h"
|
||||
#include "player.h"
|
||||
#include "command.h"
|
||||
#include "vehicle.h"
|
||||
#include "news.h"
|
||||
#include "saveload.h"
|
||||
|
||||
#define UPDATE_PLAYER_RAILTYPE(e,p) if ((byte)(e->railtype + 1) > p->max_railtype) p->max_railtype = e->railtype + 1;
|
||||
|
||||
enum {
|
||||
ENGINE_AVAILABLE = 1,
|
||||
ENGINE_INTRODUCING = 2,
|
||||
ENGINE_PREVIEWING = 4,
|
||||
};
|
||||
|
||||
/* This maps per-landscape cargo ids to globally unique cargo ids usable ie. in
|
||||
* the custom GRF files. It is basically just a transcribed table from
|
||||
* TTDPatch's newgrf.txt. */
|
||||
byte _global_cargo_id[NUM_LANDSCAPE][NUM_CARGO] = {
|
||||
/* LT_NORMAL */ { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12 },
|
||||
/* LT_HILLY */ { 0, 1, 2, 3, 4, 5, 6, 7, 28, 11, 10, 12 },
|
||||
/* LT_DESERT */ { 0, 16, 2, 3, 13, 5, 6, 7, 14, 15, 10, 12 },
|
||||
/* LT_CANDY */ { 0, 17, 2, 18, 19, 20, 21, 22, 23, 24, 25, 26 },
|
||||
// 27 is paper in temperate climate in TTDPatch
|
||||
// Following can be renumbered:
|
||||
// 29 is the default cargo for the purpose of spritesets
|
||||
// 30 is the purchase list image (the equivalent of 0xff) for the purpose of spritesets
|
||||
};
|
||||
|
||||
/* These two arrays provide a reverse mapping. */
|
||||
byte _local_cargo_id_ctype[NUM_CID] = {
|
||||
CT_PASSENGERS, CT_COAL, CT_MAIL, CT_OIL, CT_LIVESTOCK, CT_GOODS, CT_GRAIN, CT_WOOD, // 0-7
|
||||
CT_IRON_ORE, CT_STEEL, CT_VALUABLES, CT_PAPER, CT_FOOD, CT_FRUIT, CT_COPPER_ORE, CT_WATER, // 8-15
|
||||
CT_RUBBER, CT_SUGAR, CT_TOYS, CT_BATTERIES, CT_CANDY, CT_TOFFEE, CT_COLA, CT_COTTON_CANDY, // 16-23
|
||||
CT_BUBBLES, CT_PLASTIC, CT_FIZZY_DRINKS, CT_PAPER /* unsup. */, CT_HILLY_UNUSED // 24-28
|
||||
};
|
||||
|
||||
/* LT'th bit is set of the particular landscape if cargo available there.
|
||||
* 1: LT_NORMAL, 2: LT_HILLY, 4: LT_DESERT, 8: LT_CANDY */
|
||||
byte _local_cargo_id_landscape[NUM_CID] = {
|
||||
15, 3, 15, 7, 3, 7, 7, 7, 1, 1, 7, 2, 7, // 0-12
|
||||
4, 4, 4, 4, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 1, 2, // 13-28
|
||||
};
|
||||
|
||||
void ShowEnginePreviewWindow(int engine);
|
||||
|
||||
void DeleteCustomEngineNames()
|
||||
{
|
||||
uint i;
|
||||
StringID old;
|
||||
|
||||
for(i=0; i!=TOTAL_NUM_ENGINES; i++) {
|
||||
old = _engine_name_strings[i];
|
||||
_engine_name_strings[i] = i + STR_8000_KIRBY_PAUL_TANK_STEAM;
|
||||
DeleteName(old);
|
||||
}
|
||||
|
||||
_vehicle_design_names &= ~1;
|
||||
}
|
||||
|
||||
void LoadCustomEngineNames()
|
||||
{
|
||||
// XXX: not done */
|
||||
DEBUG(misc, 1) ("LoadCustomEngineNames: not done");
|
||||
}
|
||||
|
||||
static void SetupEngineNames()
|
||||
{
|
||||
uint i;
|
||||
|
||||
for(i=0; i!=TOTAL_NUM_ENGINES; i++)
|
||||
_engine_name_strings[i] = STR_SV_EMPTY;
|
||||
|
||||
DeleteCustomEngineNames();
|
||||
LoadCustomEngineNames();
|
||||
}
|
||||
|
||||
static void AdjustAvailAircraft()
|
||||
{
|
||||
uint16 date = _date;
|
||||
byte avail = 0;
|
||||
if (date >= 12784) avail |= 2; // big airport
|
||||
if (date < 14610 || _patches.always_small_airport) avail |= 1; // small airport
|
||||
if (date >= 15706) avail |= 4; // enable heliport
|
||||
|
||||
if (avail != _avail_aircraft) {
|
||||
_avail_aircraft = avail;
|
||||
InvalidateWindow(WC_BUILD_STATION, 0);
|
||||
}
|
||||
}
|
||||
|
||||
static void CalcEngineReliability(Engine *e)
|
||||
{
|
||||
uint age = e->age;
|
||||
|
||||
if (age < e->duration_phase_1) {
|
||||
uint start = e->reliability_start;
|
||||
e->reliability = age * (e->reliability_max - start) / e->duration_phase_1 + start;
|
||||
} else if ((age -= e->duration_phase_1) < e->duration_phase_2) {
|
||||
e->reliability = e->reliability_max;
|
||||
} else if ((age -= e->duration_phase_2) < e->duration_phase_3) {
|
||||
uint max = e->reliability_max;
|
||||
e->reliability = (int)age * (int)(e->reliability_final - max) / e->duration_phase_3 + max;
|
||||
} else {
|
||||
e->player_avail = _patches.never_expire_vehicles ? -1 : 0;
|
||||
e->reliability = e->reliability_final;
|
||||
}
|
||||
}
|
||||
|
||||
void StartupEngines()
|
||||
{
|
||||
Engine *e;
|
||||
const EngineInfo *ei;
|
||||
uint32 r;
|
||||
|
||||
SetupEngineNames();
|
||||
|
||||
|
||||
for(e=_engines, ei=_engine_info; e != endof(_engines); e++,ei++) {
|
||||
e->age = 0;
|
||||
e->railtype = ei->railtype_climates >> 4;
|
||||
e->flags = 0;
|
||||
e->player_avail = 0;
|
||||
|
||||
r = Random();
|
||||
e->intro_date = (uint16)((r & 0x1FF) + ei->base_intro);
|
||||
if (e->intro_date <= _date) {
|
||||
e->age = (_date - e->intro_date) >> 5;
|
||||
e->player_avail = (byte)-1;
|
||||
e->flags |= ENGINE_AVAILABLE;
|
||||
}
|
||||
|
||||
e->reliability_start = (uint16)(((r >> 16) & 0x3fff) + 0x7AE0);
|
||||
r = Random();
|
||||
e->reliability_max = (uint16)((r & 0x3fff) + 0xbfff);
|
||||
e->reliability_final = (uint16)(((r>>16) & 0x3fff) + 0x3fff);
|
||||
|
||||
r = Random();
|
||||
e->duration_phase_1 = (uint16)((r & 0x1F) + 7);
|
||||
e->duration_phase_2 = (uint16)(((r >> 5) & 0xF) + ei->base_life * 12 - 96);
|
||||
e->duration_phase_3 = (uint16)(((r >> 9) & 0x7F) + 120);
|
||||
|
||||
e->reliability_spd_dec = (ei->unk2&0x7F) << 2;
|
||||
|
||||
/* my invented flag for something that is a wagon */
|
||||
if (ei->unk2 & 0x80) {
|
||||
e->age = 0xFFFF;
|
||||
} else {
|
||||
CalcEngineReliability(e);
|
||||
}
|
||||
|
||||
e->lifelength = ei->lifelength + _patches.extend_vehicle_life;
|
||||
|
||||
// prevent certain engines from ever appearing.
|
||||
if (!HASBIT(ei->railtype_climates, _opt.landscape)) {
|
||||
e->flags |= ENGINE_AVAILABLE;
|
||||
e->player_avail = 0;
|
||||
}
|
||||
}
|
||||
|
||||
AdjustAvailAircraft();
|
||||
}
|
||||
|
||||
uint32 _engine_refit_masks[256];
|
||||
|
||||
|
||||
// TODO: We don't support cargo-specific wagon overrides. Pretty exotic... ;-) --pasky
|
||||
|
||||
struct WagonOverride {
|
||||
byte *train_id;
|
||||
int trains;
|
||||
struct SpriteSuperSet superset;
|
||||
};
|
||||
|
||||
static struct WagonOverrides {
|
||||
int overrides_count;
|
||||
struct WagonOverride *overrides;
|
||||
} _engine_wagon_overrides[256];
|
||||
|
||||
void SetWagonOverrideSprites(byte engine, struct SpriteSuperSet *superset,
|
||||
byte *train_id, int trains)
|
||||
{
|
||||
struct WagonOverrides *wos;
|
||||
struct WagonOverride *wo;
|
||||
|
||||
wos = &_engine_wagon_overrides[engine];
|
||||
wos->overrides_count++;
|
||||
wos->overrides = realloc(wos->overrides,
|
||||
wos->overrides_count * sizeof(struct WagonOverride));
|
||||
|
||||
wo = &wos->overrides[wos->overrides_count - 1];
|
||||
wo->superset = *superset;
|
||||
wo->trains = trains;
|
||||
wo->train_id = malloc(trains);
|
||||
memcpy(wo->train_id, train_id, trains);
|
||||
}
|
||||
|
||||
static struct SpriteSuperSet *GetWagonOverrideSpriteSet(byte engine, byte overriding_engine)
|
||||
{
|
||||
struct WagonOverrides *wos = &_engine_wagon_overrides[engine];
|
||||
int i;
|
||||
|
||||
// XXX: This could turn out to be a timesink on profiles. We could always just
|
||||
// dedicate 65535 bytes for an [engine][train] trampoline.
|
||||
|
||||
for (i = 0; i < wos->overrides_count; i++) {
|
||||
struct WagonOverride *wo = &wos->overrides[i];
|
||||
int j;
|
||||
|
||||
for (j = 0; j < wo->trains; j++) {
|
||||
if (wo->train_id[j] == overriding_engine)
|
||||
return &wo->superset;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
byte _engine_original_sprites[256];
|
||||
// 0 - 28 are cargos, 29 is default, 30 is the advert (purchase list)
|
||||
// (It isn't and shouldn't be like this in the GRF files since new cargo types
|
||||
// may appear in future - however it's more convenient to store it like this in
|
||||
// memory. --pasky)
|
||||
static struct SpriteSuperSet _engine_custom_sprites[256][NUM_CID];
|
||||
|
||||
void SetCustomEngineSprites(byte engine, byte cargo, struct SpriteSuperSet *superset)
|
||||
{
|
||||
assert(superset->sprites_per_set == 4 || superset->sprites_per_set == 8);
|
||||
_engine_custom_sprites[engine][cargo] = *superset;
|
||||
}
|
||||
|
||||
int GetCustomEngineSprite(byte engine, uint16 overriding_engine, byte cargo,
|
||||
byte loaded, byte in_motion, byte direction)
|
||||
{
|
||||
struct SpriteSuperSet *superset = &_engine_custom_sprites[engine][cargo];
|
||||
int totalsets, spriteset;
|
||||
int r;
|
||||
|
||||
if (overriding_engine != 0xffff) {
|
||||
struct SpriteSuperSet *overset;
|
||||
|
||||
overset = GetWagonOverrideSpriteSet(engine, overriding_engine);
|
||||
if (overset) superset = overset;
|
||||
}
|
||||
|
||||
if (!superset->sprites_per_set && cargo != 29) {
|
||||
// This superset is empty but perhaps there'll be a default one.
|
||||
superset = &_engine_custom_sprites[engine][29];
|
||||
}
|
||||
|
||||
if (!superset->sprites_per_set) {
|
||||
// This superset is empty. This function users should therefore
|
||||
// look up the sprite number in _engine_original_sprites.
|
||||
return 0;
|
||||
}
|
||||
|
||||
direction %= 8;
|
||||
if (superset->sprites_per_set == 4)
|
||||
direction %= 4;
|
||||
|
||||
totalsets = in_motion ? superset->loaded_count : superset->loading_count;
|
||||
|
||||
// My aim here is to make it possible to visually determine absolutely
|
||||
// empty and totally full vehicles. --pasky
|
||||
if (loaded == 100 || totalsets == 1) { // full
|
||||
spriteset = totalsets - 1;
|
||||
} else if (loaded == 0 || totalsets == 2) { // empty
|
||||
spriteset = 0;
|
||||
} else { // something inbetween
|
||||
spriteset = loaded * (totalsets - 2) / 100 + 1;
|
||||
// correct possible rounding errors
|
||||
if (!spriteset)
|
||||
spriteset = 1;
|
||||
else if (spriteset == totalsets - 1)
|
||||
spriteset--;
|
||||
}
|
||||
|
||||
r = (in_motion ? superset->loaded[spriteset] : superset->loading[spriteset]) + direction;
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
static char *_engine_custom_names[256];
|
||||
|
||||
void SetCustomEngineName(int engine, char *name)
|
||||
{
|
||||
_engine_custom_names[engine] = strdup(name);
|
||||
}
|
||||
|
||||
StringID GetCustomEngineName(int engine)
|
||||
{
|
||||
if (!_engine_custom_names[engine])
|
||||
return _engine_name_strings[engine];
|
||||
strcpy(_userstring, _engine_custom_names[engine]);
|
||||
return STR_SPEC_USERSTRING;
|
||||
}
|
||||
|
||||
|
||||
void AcceptEnginePreview(Engine *e, int player)
|
||||
{
|
||||
Player *p;
|
||||
|
||||
SETBIT(e->player_avail, player);
|
||||
|
||||
p = DEREF_PLAYER(player);
|
||||
|
||||
UPDATE_PLAYER_RAILTYPE(e,p);
|
||||
|
||||
e->preview_player = 0xFF;
|
||||
InvalidateWindowClasses(WC_BUILD_VEHICLE);
|
||||
}
|
||||
|
||||
void EnginesDailyLoop()
|
||||
{
|
||||
Engine *e;
|
||||
int i,num;
|
||||
Player *p;
|
||||
uint mask;
|
||||
int32 best_hist;
|
||||
int best_player;
|
||||
|
||||
if (_cur_year >= 130)
|
||||
return;
|
||||
|
||||
for(e=_engines,i=0; i!=TOTAL_NUM_ENGINES; e++,i++) {
|
||||
if (e->flags & ENGINE_INTRODUCING) {
|
||||
if (e->flags & ENGINE_PREVIEWING) {
|
||||
if (!--e->preview_wait) {
|
||||
e->flags &= ~ENGINE_PREVIEWING;
|
||||
DeleteWindowById(WC_ENGINE_PREVIEW, i);
|
||||
e->preview_player++;
|
||||
}
|
||||
} else if (e->preview_player != 0xFF) {
|
||||
num = e->preview_player;
|
||||
mask = 0;
|
||||
do {
|
||||
best_hist = -1;
|
||||
best_player = -1;
|
||||
FOR_ALL_PLAYERS(p) {
|
||||
if (p->is_active && p->block_preview == 0 && !HASBIT(mask,p->index) &&
|
||||
p->old_economy[0].performance_history > best_hist) {
|
||||
best_hist = p->old_economy[0].performance_history;
|
||||
best_player = p->index;
|
||||
}
|
||||
}
|
||||
if (best_player == -1) {
|
||||
e->preview_player = 0xFF;
|
||||
goto next_engine;
|
||||
}
|
||||
mask |= (1 << best_player);
|
||||
} while (--num != 0);
|
||||
|
||||
if (!IS_HUMAN_PLAYER(best_player)) {
|
||||
/* TTDBUG: TTD has a bug here */
|
||||
AcceptEnginePreview(e, best_player);
|
||||
} else {
|
||||
e->flags |= ENGINE_PREVIEWING;
|
||||
e->preview_wait = 20;
|
||||
if (IS_INTERACTIVE_PLAYER(best_player)) {
|
||||
ShowEnginePreviewWindow(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
next_engine:;
|
||||
}
|
||||
}
|
||||
|
||||
int32 CmdWantEnginePreview(int x, int y, uint32 flags, uint32 p1, uint32 p2)
|
||||
{
|
||||
if (flags & DC_EXEC) {
|
||||
AcceptEnginePreview(&_engines[p1], _current_player);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void NewVehicleAvailable(Engine *e)
|
||||
{
|
||||
Vehicle *v;
|
||||
Player *p;
|
||||
int index = e - _engines;
|
||||
|
||||
// In case the player didn't build the vehicle during the intro period,
|
||||
// prevent that player from getting future intro periods for a while.
|
||||
if (e->flags&ENGINE_INTRODUCING) {
|
||||
FOR_ALL_PLAYERS(p) {
|
||||
if (!HASBIT(e->player_avail,p->index))
|
||||
continue;
|
||||
|
||||
for(v=_vehicles;;) {
|
||||
if (v->type == VEH_Train || v->type == VEH_Road || v->type == VEH_Ship ||
|
||||
(v->type == VEH_Aircraft && v->subtype <= 2)) {
|
||||
if (v->owner == p->index && v->engine_type == index) break;
|
||||
}
|
||||
if (++v == endof(_vehicles)) {
|
||||
p->block_preview = 20;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
e->flags = (e->flags & ~ENGINE_INTRODUCING) | ENGINE_AVAILABLE;
|
||||
InvalidateWindowClasses(WC_BUILD_VEHICLE);
|
||||
|
||||
// Now available for all players
|
||||
e->player_avail = (byte)-1;
|
||||
|
||||
// Do not introduce new rail wagons
|
||||
if ((byte)index < NUM_TRAIN_ENGINES) {
|
||||
const RailVehicleInfo *rvi = &_rail_vehicle_info[index];
|
||||
if(rvi->flags & RVI_WAGON)
|
||||
return;
|
||||
}
|
||||
|
||||
// make maglev / monorail available
|
||||
FOR_ALL_PLAYERS(p) {
|
||||
if (p->is_active)
|
||||
UPDATE_PLAYER_RAILTYPE(e,p);
|
||||
}
|
||||
|
||||
if ((byte)index < NUM_TRAIN_ENGINES) {
|
||||
AddNewsItem(index, NEWS_FLAGS(NM_CALLBACK, 0, NT_NEW_VEHICLES, DNC_TRAINAVAIL), 0, 0);
|
||||
} else if ((byte)index < NUM_TRAIN_ENGINES + NUM_ROAD_ENGINES) {
|
||||
AddNewsItem(index, NEWS_FLAGS(NM_CALLBACK, 0, NT_NEW_VEHICLES, DNC_ROADAVAIL), 0, 0);
|
||||
} else if ((byte)index < NUM_TRAIN_ENGINES + NUM_ROAD_ENGINES + NUM_SHIP_ENGINES) {
|
||||
AddNewsItem(index, NEWS_FLAGS(NM_CALLBACK, 0, NT_NEW_VEHICLES, DNC_SHIPAVAIL), 0, 0);
|
||||
} else {
|
||||
AddNewsItem(index, NEWS_FLAGS(NM_CALLBACK, 0, NT_NEW_VEHICLES, DNC_AIRCRAFTAVAIL), 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void EnginesMonthlyLoop()
|
||||
{
|
||||
Engine *e;
|
||||
|
||||
if (_cur_year < 130) {
|
||||
for(e=_engines; e != endof(_engines); e++) {
|
||||
// Age the vehicle
|
||||
if (e->flags&ENGINE_AVAILABLE && e->age != 0xFFFF) {
|
||||
e->age++;
|
||||
CalcEngineReliability(e);
|
||||
}
|
||||
|
||||
if (!(e->flags & ENGINE_AVAILABLE) && (uint16)(_date - min(_date, 365)) >= e->intro_date) {
|
||||
// Introduce it to all players
|
||||
NewVehicleAvailable(e);
|
||||
} else if (!(e->flags & (ENGINE_AVAILABLE|ENGINE_INTRODUCING)) && _date >= e->intro_date) {
|
||||
// Introduction date has passed.. show introducing dialog to one player.
|
||||
e->flags |= ENGINE_INTRODUCING;
|
||||
e->preview_player = 1; // Give to the player with the highest rating.
|
||||
}
|
||||
}
|
||||
}
|
||||
AdjustAvailAircraft();
|
||||
}
|
||||
|
||||
int32 CmdRenameEngine(int x, int y, uint32 flags, uint32 p1, uint32 p2)
|
||||
{
|
||||
StringID str;
|
||||
|
||||
str = AllocateName((byte*)_decode_parameters, 0);
|
||||
if (str == 0)
|
||||
return CMD_ERROR;
|
||||
|
||||
if (flags & DC_EXEC) {
|
||||
StringID old_str = _engine_name_strings[p1];
|
||||
_engine_name_strings[p1] = str;
|
||||
DeleteName(old_str);
|
||||
_vehicle_design_names |= 3;
|
||||
MarkWholeScreenDirty();
|
||||
} else {
|
||||
DeleteName(str);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int GetPlayerMaxRailtype(int p)
|
||||
{
|
||||
Engine *e;
|
||||
int rt = 0;
|
||||
int i;
|
||||
|
||||
for(e=_engines,i=0; i!=lengthof(_engines); e++,i++) {
|
||||
if (!HASBIT(e->player_avail, p))
|
||||
continue;
|
||||
|
||||
if ((i >= 27 && i < 54) || (i >= 57 && i < 84) || (i >= 89 && i < 116))
|
||||
continue;
|
||||
|
||||
if (rt < e->railtype)
|
||||
rt = e->railtype;
|
||||
}
|
||||
|
||||
return rt + 1;
|
||||
}
|
||||
|
||||
|
||||
static const byte _engine_desc[] = {
|
||||
SLE_VAR(Engine,intro_date, SLE_UINT16),
|
||||
SLE_VAR(Engine,age, SLE_UINT16),
|
||||
SLE_VAR(Engine,reliability, SLE_UINT16),
|
||||
SLE_VAR(Engine,reliability_spd_dec, SLE_UINT16),
|
||||
SLE_VAR(Engine,reliability_start, SLE_UINT16),
|
||||
SLE_VAR(Engine,reliability_max, SLE_UINT16),
|
||||
SLE_VAR(Engine,reliability_final, SLE_UINT16),
|
||||
SLE_VAR(Engine,duration_phase_1, SLE_UINT16),
|
||||
SLE_VAR(Engine,duration_phase_2, SLE_UINT16),
|
||||
SLE_VAR(Engine,duration_phase_3, SLE_UINT16),
|
||||
|
||||
SLE_VAR(Engine,lifelength, SLE_UINT8),
|
||||
SLE_VAR(Engine,flags, SLE_UINT8),
|
||||
SLE_VAR(Engine,preview_player, SLE_UINT8),
|
||||
SLE_VAR(Engine,preview_wait, SLE_UINT8),
|
||||
SLE_VAR(Engine,railtype, SLE_UINT8),
|
||||
SLE_VAR(Engine,player_avail, SLE_UINT8),
|
||||
|
||||
// reserve extra space in savegame here. (currently 16 bytes)
|
||||
SLE_CONDARR(NullStruct,null,SLE_FILE_U64 | SLE_VAR_NULL, 2, 2, 255),
|
||||
|
||||
SLE_END()
|
||||
};
|
||||
|
||||
static void Save_ENGN()
|
||||
{
|
||||
Engine *e;
|
||||
int i;
|
||||
for(i=0,e=_engines; i != lengthof(_engines); i++,e++) {
|
||||
SlSetArrayIndex(i);
|
||||
SlObject(e, _engine_desc);
|
||||
}
|
||||
}
|
||||
|
||||
static void Load_ENGN()
|
||||
{
|
||||
int index;
|
||||
while ((index = SlIterateArray()) != -1) {
|
||||
SlObject(&_engines[index], _engine_desc);
|
||||
}
|
||||
}
|
||||
|
||||
static void LoadSave_ENGS()
|
||||
{
|
||||
SlArray(_engine_name_strings, lengthof(_engine_name_strings), SLE_STRINGID);
|
||||
}
|
||||
|
||||
const ChunkHandler _engine_chunk_handlers[] = {
|
||||
{ 'ENGN', Save_ENGN, Load_ENGN, CH_ARRAY},
|
||||
{ 'ENGS', LoadSave_ENGS, LoadSave_ENGS, CH_RIFF | CH_LAST},
|
||||
};
|
||||
|
||||
|
||||
|
137
trunk/engine.h
137
trunk/engine.h
|
@ -1,137 +0,0 @@
|
|||
#ifndef ENGINE_H
|
||||
#define ENGINE_H
|
||||
|
||||
typedef struct RailVehicleInfo {
|
||||
byte image_index;
|
||||
byte flags; /* 1=multihead engine, 2=wagon */
|
||||
byte base_cost;
|
||||
uint16 max_speed;
|
||||
uint16 power;
|
||||
byte weight;
|
||||
byte running_cost_base;
|
||||
byte engclass; // 0: steam, 1: diesel, 2: electric
|
||||
byte capacity;
|
||||
byte cargo_type;
|
||||
} RailVehicleInfo;
|
||||
|
||||
typedef struct ShipVehicleInfo {
|
||||
byte image_index;
|
||||
byte base_cost;
|
||||
uint16 max_speed;
|
||||
byte cargo_type;
|
||||
uint16 capacity;
|
||||
byte running_cost;
|
||||
byte sfx;
|
||||
byte refittable;
|
||||
} ShipVehicleInfo;
|
||||
|
||||
|
||||
typedef struct EngineInfo {
|
||||
uint16 base_intro;
|
||||
byte unk2;
|
||||
byte lifelength;
|
||||
byte base_life;
|
||||
byte railtype_climates;
|
||||
} EngineInfo;
|
||||
|
||||
typedef struct Engine {
|
||||
uint16 intro_date;
|
||||
uint16 age;
|
||||
uint16 reliability;
|
||||
uint16 reliability_spd_dec;
|
||||
uint16 reliability_start, reliability_max, reliability_final;
|
||||
uint16 duration_phase_1, duration_phase_2, duration_phase_3;
|
||||
byte lifelength;
|
||||
byte flags;
|
||||
byte preview_player;
|
||||
byte preview_wait;
|
||||
byte railtype;
|
||||
byte player_avail;
|
||||
} Engine;
|
||||
|
||||
|
||||
enum {
|
||||
RVI_MULTIHEAD = 1,
|
||||
RVI_WAGON = 2,
|
||||
};
|
||||
|
||||
|
||||
void StartupEngines();
|
||||
|
||||
|
||||
struct SpriteSuperSet {
|
||||
// XXX: Would anyone ever need more than 16 spritesets? Maybe we should
|
||||
// use even less, now we take whole 8kb for custom sprites table, oh my!
|
||||
byte sprites_per_set; // means number of directions - 4 or 8
|
||||
// Loaded = in motion, loading = not moving
|
||||
// Each superset contains several spritesets, for various loading stages
|
||||
byte loaded_count;
|
||||
uint16 loaded[16]; // sprite ids
|
||||
byte loading_count;
|
||||
uint16 loading[16]; // sprite ids
|
||||
};
|
||||
|
||||
extern byte _global_cargo_id[NUM_LANDSCAPE][NUM_CARGO];
|
||||
enum {
|
||||
CID_DEFAULT = 29,
|
||||
CID_PURCHASE = 30,
|
||||
NUM_CID = 31,
|
||||
};
|
||||
extern byte _local_cargo_id_ctype[NUM_CID];
|
||||
extern byte _local_cargo_id_landscape[NUM_CID];
|
||||
|
||||
extern uint32 _engine_refit_masks[256];
|
||||
|
||||
extern byte _engine_original_sprites[256];
|
||||
void SetWagonOverrideSprites(byte engine, struct SpriteSuperSet *superset, byte *train_id, int trains);
|
||||
void SetCustomEngineSprites(byte engine, byte cargo, struct SpriteSuperSet *superset);
|
||||
// loaded is in percents, overriding_engine 0xffff is none
|
||||
int GetCustomEngineSprite(byte engine, uint16 overriding_engine, byte cargo, byte loaded, byte in_motion, byte direction);
|
||||
#define GetCustomVehicleSprite(v, direction) \
|
||||
GetCustomEngineSprite(v->engine_type, v->type == VEH_Train ? v->u.rail.first_engine : -1, \
|
||||
_global_cargo_id[_opt.landscape][v->cargo_type], \
|
||||
((v->cargo_count + 1) * 100) / (v->cargo_cap + 1), \
|
||||
!!v->cur_speed, direction);
|
||||
|
||||
void SetCustomEngineName(int engine, char *name);
|
||||
StringID GetCustomEngineName(int engine);
|
||||
|
||||
|
||||
void DrawTrainEngine(int x, int y, int engine, uint32 image_ormod);
|
||||
void DrawRoadVehEngine(int x, int y, int engine, uint32 image_ormod);
|
||||
void DrawShipEngine(int x, int y, int engine, uint32 image_ormod);
|
||||
void DrawAircraftEngine(int x, int y, int engine, uint32 image_ormod);
|
||||
|
||||
void DrawTrainEngineInfo(int engine, int x, int y, int maxw);
|
||||
void DrawRoadVehEngineInfo(int engine, int x, int y, int maxw);
|
||||
void DrawShipEngineInfo(int engine, int x, int y, int maxw);
|
||||
void DrawAircraftEngineInfo(int engine, int x, int y, int maxw);
|
||||
|
||||
void AcceptEnginePreview(Engine *e, int player);
|
||||
|
||||
void LoadCustomEngineNames();
|
||||
void DeleteCustomEngineNames();
|
||||
|
||||
|
||||
enum {
|
||||
NUM_NORMAL_RAIL_ENGINES = 54,
|
||||
NUM_MONORAIL_ENGINES = 30,
|
||||
NUM_MAGLEV_ENGINES = 32,
|
||||
NUM_TRAIN_ENGINES = NUM_NORMAL_RAIL_ENGINES + NUM_MONORAIL_ENGINES + NUM_MAGLEV_ENGINES,
|
||||
NUM_ROAD_ENGINES = 88,
|
||||
NUM_SHIP_ENGINES = 11,
|
||||
NUM_AIRCRAFT_ENGINES = 41,
|
||||
TOTAL_NUM_ENGINES = NUM_NORMAL_RAIL_ENGINES+NUM_MONORAIL_ENGINES+NUM_MAGLEV_ENGINES+NUM_ROAD_ENGINES+NUM_SHIP_ENGINES+NUM_AIRCRAFT_ENGINES,
|
||||
AIRCRAFT_ENGINES_INDEX = NUM_TRAIN_ENGINES + NUM_ROAD_ENGINES + NUM_SHIP_ENGINES,
|
||||
SHIP_ENGINES_INDEX = NUM_TRAIN_ENGINES + NUM_ROAD_ENGINES,
|
||||
ROAD_ENGINES_INDEX = NUM_TRAIN_ENGINES,
|
||||
};
|
||||
VARDEF Engine _engines[TOTAL_NUM_ENGINES];
|
||||
VARDEF StringID _engine_name_strings[TOTAL_NUM_ENGINES];
|
||||
|
||||
extern EngineInfo _engine_info[TOTAL_NUM_ENGINES];
|
||||
extern RailVehicleInfo _rail_vehicle_info[];
|
||||
#define ship_vehicle_info(e) _ship_vehicle_info[e - SHIP_ENGINES_INDEX]
|
||||
extern ShipVehicleInfo _ship_vehicle_info[];
|
||||
|
||||
#endif
|
|
@ -1,224 +0,0 @@
|
|||
#include "stdafx.h"
|
||||
#include "ttd.h"
|
||||
|
||||
#include "window.h"
|
||||
#include "gui.h"
|
||||
#include "viewport.h"
|
||||
#include "gfx.h"
|
||||
#include "engine.h"
|
||||
#include "command.h"
|
||||
#include "news.h"
|
||||
|
||||
void DrawShipEngine(int x, int y, int engine, uint32 image_ormod);
|
||||
void DrawShipEngineInfo(int engine, int x, int y, int maxw);
|
||||
|
||||
|
||||
StringID GetEngineCategoryName(byte engine)
|
||||
{
|
||||
if (engine < NUM_NORMAL_RAIL_ENGINES)
|
||||
return STR_8102_RAILROAD_LOCOMOTIVE;
|
||||
|
||||
if (engine < NUM_NORMAL_RAIL_ENGINES + NUM_MONORAIL_ENGINES)
|
||||
return STR_8106_MONORAIL_LOCOMOTIVE;
|
||||
|
||||
if (engine < NUM_TRAIN_ENGINES)
|
||||
return STR_8107_MAGLEV_LOCOMOTIVE;
|
||||
|
||||
if (engine < NUM_TRAIN_ENGINES + NUM_ROAD_ENGINES)
|
||||
return STR_8103_ROAD_VEHICLE;
|
||||
|
||||
if (engine < NUM_TRAIN_ENGINES + NUM_ROAD_ENGINES + NUM_SHIP_ENGINES)
|
||||
return STR_8105_SHIP;
|
||||
|
||||
return STR_8104_AIRCRAFT;
|
||||
}
|
||||
|
||||
static const Widget _engine_preview_widgets[] = {
|
||||
{ WWT_TEXTBTN, 5, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
|
||||
{ WWT_CAPTION, 5, 11, 299, 0, 13, STR_8100_MESSAGE_FROM_VEHICLE_MANUFACTURE, STR_018C_WINDOW_TITLE_DRAG_THIS},
|
||||
{ WWT_IMGBTN, 5, 0, 299, 14, 191, 0x0, STR_NULL},
|
||||
{ WWT_PUSHTXTBTN, 5, 85, 144, 172, 183, STR_00C9_NO, STR_NULL},
|
||||
{ WWT_PUSHTXTBTN, 5, 155, 214, 172, 183, STR_00C8_YES, STR_NULL},
|
||||
{ WIDGETS_END},
|
||||
};
|
||||
|
||||
typedef void DrawEngineProc(int x, int y, int engine, uint32 image_ormod);
|
||||
typedef void DrawEngineInfoProc(int x, int y, int engine, int maxw);
|
||||
|
||||
typedef struct DrawEngineInfo {
|
||||
DrawEngineProc *engine_proc;
|
||||
DrawEngineInfoProc *info_proc;
|
||||
} DrawEngineInfo;
|
||||
|
||||
static const DrawEngineInfo _draw_engine_list[4] = {
|
||||
{DrawTrainEngine,DrawTrainEngineInfo},
|
||||
{DrawRoadVehEngine,DrawRoadVehEngineInfo},
|
||||
{DrawShipEngine,DrawShipEngineInfo},
|
||||
{DrawAircraftEngine,DrawAircraftEngineInfo},
|
||||
};
|
||||
|
||||
static void EnginePreviewWndProc(Window *w, WindowEvent *e)
|
||||
{
|
||||
byte eng;
|
||||
int engine;
|
||||
const DrawEngineInfo *dei;
|
||||
int width;
|
||||
|
||||
switch(e->event) {
|
||||
case WE_PAINT:
|
||||
DrawWindowWidgets(w);
|
||||
engine = w->window_number;
|
||||
|
||||
SET_DPARAM16(0, GetEngineCategoryName(engine));
|
||||
DrawStringMultiCenter(150, 44, STR_8101_WE_HAVE_JUST_DESIGNED_A, 296);
|
||||
|
||||
DrawStringCentered(w->width >> 1, 80, GetCustomEngineName(engine), 0x10);
|
||||
|
||||
eng = (byte)engine;
|
||||
(dei = _draw_engine_list,eng < NUM_TRAIN_ENGINES) ||
|
||||
(dei++,eng < NUM_TRAIN_ENGINES + NUM_ROAD_ENGINES) ||
|
||||
(dei++,eng < NUM_TRAIN_ENGINES + NUM_ROAD_ENGINES + NUM_SHIP_ENGINES) ||
|
||||
(dei++, true);
|
||||
|
||||
width = w->width;
|
||||
dei->engine_proc(width >> 1, 100, engine, 0);
|
||||
dei->info_proc(engine, width >> 1, 130, width - 52);
|
||||
break;
|
||||
|
||||
case WE_CLICK:
|
||||
switch(e->click.widget) {
|
||||
case 3: DeleteWindow(w); break;
|
||||
case 4:
|
||||
DoCommandP(0, w->window_number, 0, NULL, CMD_WANT_ENGINE_PREVIEW);
|
||||
DeleteWindow(w);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static const WindowDesc _engine_preview_desc = {
|
||||
WDP_CENTER, WDP_CENTER, 300, 192,
|
||||
WC_ENGINE_PREVIEW,0,
|
||||
WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET,
|
||||
_engine_preview_widgets,
|
||||
EnginePreviewWndProc
|
||||
};
|
||||
|
||||
|
||||
void ShowEnginePreviewWindow(int engine)
|
||||
{
|
||||
Window *w;
|
||||
|
||||
w = AllocateWindowDesc(&_engine_preview_desc);
|
||||
w->window_number = engine;
|
||||
}
|
||||
|
||||
void DrawNewsNewTrainAvail(Window *w)
|
||||
{
|
||||
int engine;
|
||||
|
||||
DrawNewsBorder(w);
|
||||
|
||||
engine = WP(w,news_d).ni->string_id;
|
||||
SET_DPARAM16(0, GetEngineCategoryName(engine));
|
||||
DrawStringMultiCenter(w->width >> 1, 20, STR_8859_NEW_NOW_AVAILABLE, w->width - 2);
|
||||
|
||||
GfxFillRect(25, 56, w->width - 25, w->height - 2, 10);
|
||||
|
||||
SET_DPARAM16(0, GetCustomEngineName(engine));
|
||||
DrawStringMultiCenter(w->width >> 1, 57, STR_885A, w->width - 2);
|
||||
|
||||
DrawTrainEngine(w->width >> 1, 88, engine, 0);
|
||||
GfxFillRect(25, 56, w->width - 56, 112, 0x4323);
|
||||
DrawTrainEngineInfo(engine, w->width >> 1, 129, w->width - 52);
|
||||
}
|
||||
|
||||
StringID GetNewsStringNewTrainAvail(NewsItem *ni)
|
||||
{
|
||||
int engine = ni->string_id;
|
||||
SET_DPARAM16(0, STR_8859_NEW_NOW_AVAILABLE);
|
||||
SET_DPARAM16(1, GetEngineCategoryName(engine));
|
||||
SET_DPARAM16(2, GetCustomEngineName(engine));
|
||||
return STR_02B6;
|
||||
}
|
||||
|
||||
void DrawNewsNewAircraftAvail(Window *w)
|
||||
{
|
||||
int engine;
|
||||
|
||||
DrawNewsBorder(w);
|
||||
|
||||
engine = WP(w,news_d).ni->string_id;
|
||||
|
||||
DrawStringMultiCenter(w->width >> 1, 20, STR_A02C_NEW_AIRCRAFT_NOW_AVAILABLE, w->width - 2);
|
||||
GfxFillRect(25, 56, w->width - 25, w->height - 2, 10);
|
||||
|
||||
SET_DPARAM16(0, GetCustomEngineName(engine));
|
||||
DrawStringMultiCenter(w->width >> 1, 57, STR_A02D, w->width - 2);
|
||||
|
||||
DrawAircraftEngine(w->width >> 1, 93, engine, 0);
|
||||
GfxFillRect(25, 56, w->width - 56, 110, 0x4323);
|
||||
DrawAircraftEngineInfo(engine, w->width >> 1, 131, w->width - 52);
|
||||
}
|
||||
|
||||
StringID GetNewsStringNewAircraftAvail(NewsItem *ni)
|
||||
{
|
||||
int engine = ni->string_id;
|
||||
SET_DPARAM16(0, STR_A02C_NEW_AIRCRAFT_NOW_AVAILABLE);
|
||||
SET_DPARAM16(1, GetCustomEngineName(engine));
|
||||
return STR_02B6;
|
||||
}
|
||||
|
||||
void DrawNewsNewRoadVehAvail(Window *w)
|
||||
{
|
||||
int engine;
|
||||
|
||||
DrawNewsBorder(w);
|
||||
|
||||
engine = WP(w,news_d).ni->string_id;
|
||||
DrawStringMultiCenter(w->width >> 1, 20, STR_9028_NEW_ROAD_VEHICLE_NOW_AVAILABLE, w->width - 2);
|
||||
GfxFillRect(25, 56, w->width - 25, w->height - 2, 10);
|
||||
|
||||
SET_DPARAM16(0, GetCustomEngineName(engine));
|
||||
DrawStringMultiCenter(w->width >> 1, 57, STR_9029, w->width - 2);
|
||||
|
||||
DrawRoadVehEngine(w->width >> 1, 88, engine, 0);
|
||||
GfxFillRect(25, 56, w->width - 56, 112, 0x4323);
|
||||
DrawRoadVehEngineInfo(engine, w->width >> 1, 129, w->width - 52);
|
||||
}
|
||||
|
||||
StringID GetNewsStringNewRoadVehAvail(NewsItem *ni)
|
||||
{
|
||||
int engine = ni->string_id;
|
||||
SET_DPARAM16(0, STR_9028_NEW_ROAD_VEHICLE_NOW_AVAILABLE);
|
||||
SET_DPARAM16(1, GetCustomEngineName(engine));
|
||||
return STR_02B6;
|
||||
}
|
||||
|
||||
void DrawNewsNewShipAvail(Window *w)
|
||||
{
|
||||
int engine;
|
||||
|
||||
DrawNewsBorder(w);
|
||||
|
||||
engine = WP(w,news_d).ni->string_id;
|
||||
|
||||
DrawStringMultiCenter(w->width >> 1, 20, STR_982C_NEW_SHIP_NOW_AVAILABLE, w->width - 2);
|
||||
GfxFillRect(25, 56, w->width - 25, w->height - 2, 10);
|
||||
|
||||
SET_DPARAM16(0, GetCustomEngineName(engine));
|
||||
DrawStringMultiCenter(w->width >> 1, 57, STR_982D, w->width - 2);
|
||||
|
||||
DrawShipEngine(w->width >> 1, 93, engine, 0);
|
||||
GfxFillRect(25, 56, w->width - 56, 110, 0x4323);
|
||||
DrawShipEngineInfo(engine, w->width >> 1, 131, w->width - 52);
|
||||
}
|
||||
|
||||
StringID GetNewsStringNewShipAvail(NewsItem *ni)
|
||||
{
|
||||
int engine = ni->string_id;
|
||||
SET_DPARAM16(0, STR_982C_NEW_SHIP_NOW_AVAILABLE);
|
||||
SET_DPARAM16(1, GetCustomEngineName(engine));
|
||||
return STR_02B6;
|
||||
}
|
103
trunk/extmidi.c
103
trunk/extmidi.c
|
@ -1,103 +0,0 @@
|
|||
#ifndef __BEOS__
|
||||
#ifndef __MORPHOS__
|
||||
#include "stdafx.h"
|
||||
|
||||
#include "ttd.h"
|
||||
#include "hal.h"
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
#include <sys/stat.h>
|
||||
#include <errno.h>
|
||||
|
||||
#ifndef EXTERNAL_PLAYER
|
||||
#define EXTERNAL_PLAYER "/usr/bin/timidity"
|
||||
#endif
|
||||
|
||||
static pid_t _pid;
|
||||
|
||||
static void extmidi_kill(void) {
|
||||
if(_pid > 0) {
|
||||
kill(_pid, SIGKILL);
|
||||
while(waitpid(_pid, NULL, WNOHANG) != _pid);
|
||||
}
|
||||
_pid = 0;
|
||||
}
|
||||
|
||||
static char *extmidi_start(char **parm) {
|
||||
_pid = 0;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void extmidi_stop(void) {
|
||||
extmidi_kill();
|
||||
}
|
||||
|
||||
static void extmidi_play_song(const char *filename) {
|
||||
extmidi_kill();
|
||||
|
||||
_pid = fork();
|
||||
if(_pid < 0) {
|
||||
fprintf(stderr, "extmidi: couldn't fork: %s\n", strerror(errno));
|
||||
_pid = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if(_pid == 0) {
|
||||
#if defined(MIDI_ARG)
|
||||
execl(EXTERNAL_PLAYER, "extmidi", MIDI_ARG, filename, NULL);
|
||||
#else
|
||||
execl(EXTERNAL_PLAYER, "extmidi", filename, NULL);
|
||||
#endif
|
||||
|
||||
fprintf(stderr, "extmidi: couldn't execl: %s\n", strerror(errno));
|
||||
|
||||
exit(0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
usleep(500);
|
||||
|
||||
|
||||
if(_pid == waitpid(_pid, NULL, WNOHANG)) {
|
||||
fprintf(stderr, "extmidi: play song failed\n");
|
||||
_pid = 0;
|
||||
|
||||
usleep(5000);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
static void extmidi_stop_song(void) {
|
||||
extmidi_kill();
|
||||
}
|
||||
|
||||
static bool extmidi_is_playing(void) {
|
||||
if(_pid == 0)
|
||||
return 0;
|
||||
|
||||
if(waitpid(_pid, NULL, WNOHANG) == _pid) {
|
||||
_pid = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void extmidi_set_volume(byte vol) {
|
||||
fprintf(stderr, "extmidi: set volume not implemented\n");
|
||||
}
|
||||
|
||||
const HalMusicDriver _extmidi_music_driver = {
|
||||
extmidi_start,
|
||||
extmidi_stop,
|
||||
extmidi_play_song,
|
||||
extmidi_stop_song,
|
||||
extmidi_is_playing,
|
||||
extmidi_set_volume,
|
||||
};
|
||||
#endif /* __MORPHOS__ */
|
||||
#endif /* __BEOS__ */
|
123
trunk/fileio.c
123
trunk/fileio.c
|
@ -1,123 +0,0 @@
|
|||
#include "stdafx.h"
|
||||
#include "ttd.h"
|
||||
#if defined(UNIX)
|
||||
#include <ctype.h> // required for tolower()
|
||||
#endif
|
||||
|
||||
/*************************************************/
|
||||
/* FILE IO ROUTINES ******************************/
|
||||
/*************************************************/
|
||||
|
||||
#define FIO_BUFFER_SIZE 512
|
||||
|
||||
typedef struct {
|
||||
byte *buffer, *buffer_end;
|
||||
uint32 pos;
|
||||
FILE *cur_fh;
|
||||
FILE *handles[32];
|
||||
byte buffer_start[512];
|
||||
} Fio;
|
||||
|
||||
static Fio _fio;
|
||||
|
||||
// Get current position in file
|
||||
uint32 FioGetPos()
|
||||
{
|
||||
return _fio.pos + (_fio.buffer - _fio.buffer_start) - FIO_BUFFER_SIZE;
|
||||
}
|
||||
|
||||
void FioSeekTo(uint32 pos, int mode)
|
||||
{
|
||||
if (mode == SEEK_CUR) pos += FioGetPos();
|
||||
_fio.buffer = _fio.buffer_end = _fio.buffer_start + FIO_BUFFER_SIZE;
|
||||
fseek(_fio.cur_fh, (_fio.pos=pos), SEEK_SET);
|
||||
}
|
||||
|
||||
// Seek to a file and a position
|
||||
void FioSeekToFile(uint32 pos)
|
||||
{
|
||||
FILE *f = _fio.handles[pos >> 24];
|
||||
assert(f != NULL);
|
||||
_fio.cur_fh = f;
|
||||
FioSeekTo(pos & 0xFFFFFF, SEEK_SET);
|
||||
}
|
||||
|
||||
byte FioReadByte()
|
||||
{
|
||||
if (_fio.buffer == _fio.buffer_end) {
|
||||
_fio.pos += FIO_BUFFER_SIZE;
|
||||
fread(_fio.buffer = _fio.buffer_start, 1, FIO_BUFFER_SIZE, _fio.cur_fh);
|
||||
}
|
||||
return *_fio.buffer++;
|
||||
}
|
||||
|
||||
void FioSkipBytes(int n)
|
||||
{
|
||||
for(;;) {
|
||||
int m = min(_fio.buffer_end - _fio.buffer, n);
|
||||
_fio.buffer += m;
|
||||
n -= m;
|
||||
if (n == 0) break;
|
||||
FioReadByte();
|
||||
n--;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
uint16 FioReadWord()
|
||||
{
|
||||
byte b = FioReadByte();
|
||||
return (FioReadByte() << 8) | b;
|
||||
}
|
||||
|
||||
uint32 FioReadDword()
|
||||
{
|
||||
uint b = FioReadWord();
|
||||
return (FioReadWord() << 16) | b;
|
||||
}
|
||||
|
||||
void FioReadBlock(void *ptr, uint size)
|
||||
{
|
||||
FioSeekTo(FioGetPos(), SEEK_SET);
|
||||
_fio.pos += size;
|
||||
fread(ptr, 1, size, _fio.cur_fh);
|
||||
}
|
||||
|
||||
void FioCloseAll()
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i=0; i!=lengthof(_fio.handles); i++) {
|
||||
if (_fio.handles[i] != NULL) {
|
||||
fclose(_fio.handles[i]);
|
||||
_fio.handles[i] = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FioOpenFile(int slot, const char *filename)
|
||||
{
|
||||
FILE *f;
|
||||
char buf[MAX_PATH];
|
||||
|
||||
sprintf(buf, "%s%s", _path.data_dir, filename);
|
||||
|
||||
f = fopen(buf, "rb");
|
||||
#if !defined(WIN32)
|
||||
if (f == NULL) {
|
||||
char *s;
|
||||
// Make lower case and try again
|
||||
for(s=buf + strlen(_path.data_dir) - 1; *s != 0; s++)
|
||||
*s = tolower(*s);
|
||||
f = fopen(buf, "rb");
|
||||
}
|
||||
#endif
|
||||
|
||||
if (f == NULL)
|
||||
error("Cannot open file '%s'", buf);
|
||||
|
||||
_fio.handles[slot] = f;
|
||||
FioSeekToFile(slot << 24);
|
||||
}
|
||||
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
#ifndef FILEIO_H
|
||||
#define FILEIO_H
|
||||
|
||||
void FioSeekTo(uint32 pos, int mode);
|
||||
void FioSeekToFile(uint32 pos);
|
||||
uint32 FioGetPos();
|
||||
byte FioReadByte();
|
||||
uint16 FioReadWord();
|
||||
uint32 FioReadDword();
|
||||
void FioCloseAll();
|
||||
void FioOpenFile(int slot, const char *filename);
|
||||
void FioReadBlock(void *ptr, uint size);
|
||||
void FioSkipBytes(int n);
|
||||
|
||||
#endif /* FILEIO_H */
|
|
@ -1,286 +0,0 @@
|
|||
#ifndef FUNCTIONS_H
|
||||
#define FUNCTIONS_H
|
||||
|
||||
#include "network.h"
|
||||
|
||||
/* vehicle.c */
|
||||
|
||||
/* window.c */
|
||||
|
||||
|
||||
/* landscape.c */
|
||||
void FindLandscapeHeight(TileInfo *ti, uint x, uint y);
|
||||
void FindLandscapeHeightByTile(TileInfo *ti, uint tile);
|
||||
uint GetTileSlope(uint tile, int *h);
|
||||
int GetTileZ(uint tile);
|
||||
|
||||
void DoClearSquare(uint tile);
|
||||
void CDECL ModifyTile(uint tile, uint flags, ...);
|
||||
void SetMapExtraBits(uint tile, byte flags);
|
||||
uint GetMapExtraBits(uint tile);
|
||||
void RunTileLoop();
|
||||
|
||||
uint GetPartialZ(int x, int y, int corners);
|
||||
uint GetSlopeZ(int x, int y);
|
||||
uint32 GetTileTrackStatus(uint tile, TransportType mode);
|
||||
void GetAcceptedCargo(uint tile, AcceptedCargo *ac);
|
||||
void ChangeTileOwner(uint tile, byte old_player, byte new_player);
|
||||
void AnimateTile(uint tile);
|
||||
void ClickTile(uint tile);
|
||||
void GetTileDesc(uint tile, TileDesc *td);
|
||||
void DrawTile(TileInfo *ti);
|
||||
|
||||
uint TileAddWrap(TileIndex tile, int addx, int addy);
|
||||
enum {
|
||||
TILE_WRAPPED = (uint)-1
|
||||
};
|
||||
|
||||
bool IsValidTile(uint tile);
|
||||
|
||||
#if !defined(NEW_ROTATION)
|
||||
static Point FORCEINLINE RemapCoords(int x, int y, int z) { Point pt = { (y-x)*2, y + x -z }; return pt; }
|
||||
#else
|
||||
static Point FORCEINLINE RemapCoords(int x, int y, int z) { Point pt = { (x + y)*2, x - y -z }; return pt; }
|
||||
#endif
|
||||
|
||||
static Point FORCEINLINE RemapCoords2(int x, int y) { return RemapCoords(x, y, GetSlopeZ(x, y)); }
|
||||
|
||||
/* game.c */
|
||||
byte *GetString(byte *buffr, uint16 string);
|
||||
void InjectDparam(int amount);
|
||||
|
||||
int32 GetParamInt32();
|
||||
int GetParamInt16();
|
||||
int GetParamInt8();
|
||||
int GetParamUint16();
|
||||
|
||||
|
||||
/* sound.c */
|
||||
void SndPlayTileFx(int sound, TileIndex tile);
|
||||
void SndPlayVehicleFx(int sound, Vehicle *v);
|
||||
void SndPlayFx(int sound);
|
||||
|
||||
/* clear_land.c */
|
||||
void DrawHillyLandTile(TileInfo *ti);
|
||||
void DrawClearLandTile(TileInfo *ti, byte set);
|
||||
void DrawClearLandFence(TileInfo *ti, byte img);
|
||||
void TileLoopClearHelper(uint tile);
|
||||
|
||||
/* station_land.c */
|
||||
void StationPickerDrawSprite(int x, int y, int railtype, int image);
|
||||
|
||||
/* track_land.c */
|
||||
void DrawTrainDepotSprite(int x, int y, int image, int railtype);
|
||||
|
||||
/* road_land.c */
|
||||
void DrawRoadDepotSprite(int x, int y, int image);
|
||||
|
||||
/* water_land.c */
|
||||
void DrawShipDepotSprite(int x, int y, int image);
|
||||
void TileLoop_Water(uint tile);
|
||||
|
||||
/* players.c */
|
||||
bool CheckPlayerHasMoney(int32 cost);
|
||||
void SubtractMoneyFromPlayer(int32 cost);
|
||||
void SubtractMoneyFromPlayerFract(byte player, int32 cost);
|
||||
bool CheckOwnership(byte owner);
|
||||
bool CheckTileOwnership(uint tile);
|
||||
StringID GetPlayerNameString(byte player, byte index);
|
||||
|
||||
/* standard */
|
||||
void ShowInfo(const char *str);
|
||||
void CDECL ShowInfoF(const char *str, ...);
|
||||
void NORETURN CDECL error(const char *str, ...);
|
||||
void memswap(void *a, void *b, size_t size);
|
||||
|
||||
/* ttd.c */
|
||||
uint32 Random();
|
||||
uint RandomRange(uint max);
|
||||
|
||||
void InitPlayerRandoms();
|
||||
|
||||
uint32 InteractiveRandom(); /* Used for random sequences that are not the same on the other end of the multiplayer link */
|
||||
uint InteractiveRandomRange(uint max);
|
||||
|
||||
void SetDate(uint date);
|
||||
/* facedraw.c */
|
||||
void DrawPlayerFace(uint32 face, int color, int x, int y);
|
||||
|
||||
/* texteff.c */
|
||||
void MoveAllTextEffects();
|
||||
void AddTextEffect(StringID msg, int x, int y, uint16 duration);
|
||||
void InitTextEffects();
|
||||
void DrawTextEffects(DrawPixelInfo *dpi);
|
||||
|
||||
bool AddAnimatedTile(uint tile);
|
||||
void DeleteAnimatedTile(uint tile);
|
||||
void AnimateAnimatedTiles();
|
||||
void InitializeAnimatedTiles();
|
||||
|
||||
/* tunnelbridge_cmd.c */
|
||||
bool CheckTunnelInWay(uint tile, int z);
|
||||
bool CheckBridge_Stuff(byte bridge_type, int bridge_len);
|
||||
uint32 GetBridgeLength(TileIndex begin, TileIndex end);
|
||||
int CalcBridgeLenCostFactor(int x);
|
||||
|
||||
/* network.c */
|
||||
typedef void CommandCallback(bool success, uint tile, uint32 p1, uint32 p2);
|
||||
bool DoCommandP(TileIndex tile, uint32 p1, uint32 p2, CommandCallback *callback, uint32 cmd);
|
||||
|
||||
void NetworkReceive();
|
||||
void NetworkSend();
|
||||
void NetworkProcessCommands();
|
||||
void NetworkListen();
|
||||
void NetworkInitialize();
|
||||
void NetworkShutdown();
|
||||
void NetworkSendCommand(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd, CommandCallback *callback);
|
||||
void NetworkSendEvent(uint16 type, uint16 data_len, void * data);
|
||||
void NetworkStartSync(bool fcreset);
|
||||
void NetworkClose(bool client);
|
||||
void NetworkSendReadyPacket();
|
||||
void NetworkSendSyncPackets();
|
||||
void NetworkSendFrameSyncPackets();
|
||||
bool NetworkCheckClientReady();
|
||||
|
||||
void NetworkIPListInit();
|
||||
|
||||
void NetworkCoreInit();
|
||||
void NetworkCoreShutdown();
|
||||
void NetworkCoreDisconnect();
|
||||
void NetworkCoreLoop(bool incomming);
|
||||
bool NetworkCoreConnectGame(const byte* b, unsigned short port);
|
||||
bool NetworkCoreConnectGameStruct(NetworkGameList * item);
|
||||
bool NetworkCoreStartGame();
|
||||
|
||||
void NetworkLobbyShutdown();
|
||||
void NetworkLobbyInit();
|
||||
|
||||
void NetworkGameListClear();
|
||||
NetworkGameList * NetworkGameListAdd();
|
||||
void NetworkGameListFromLAN();
|
||||
void NetworkGameListFromInternet();
|
||||
NetworkGameList * NetworkGameListItem(uint16 index);
|
||||
|
||||
void NetworkGameFillDefaults();
|
||||
void NetworkGameChangeDate(uint16 newdate);
|
||||
|
||||
/* misc_cmd.c */
|
||||
void PlaceTreesRandomly();
|
||||
|
||||
uint GetTileDist(TileIndex xy1, TileIndex xy2);
|
||||
uint GetTileDist1D(TileIndex xy1, TileIndex xy2);
|
||||
uint GetTileDist1Db(TileIndex xy1, TileIndex xy2);
|
||||
uint GetTileDistAdv(TileIndex xy1, TileIndex xy2);
|
||||
bool CheckDistanceFromEdge(TileIndex tile, uint distance);
|
||||
|
||||
void InitializeLandscapeVariables(bool only_constants);
|
||||
|
||||
/* misc.c */
|
||||
void DeleteName(StringID id);
|
||||
byte *GetName(int id, byte *buff);
|
||||
StringID AllocateName(const byte *name, byte skip);
|
||||
void ConvertDayToYMD(YearMonthDay *ymd, uint16 date);
|
||||
uint ConvertYMDToDay(uint year, uint month, uint day);
|
||||
uint ConvertIntDate(uint date);
|
||||
|
||||
|
||||
|
||||
/* misc functions */
|
||||
void MarkTileDirty(int x, int y);
|
||||
void MarkTileDirtyByTile(TileIndex tile);
|
||||
void InvalidateWindow(byte cls, WindowNumber number);
|
||||
void InvalidateWindowWidget(byte cls, WindowNumber number, byte widget_index);
|
||||
void InvalidateWindowClasses(byte cls);
|
||||
void DeleteWindowById(WindowClass cls, WindowNumber number);
|
||||
|
||||
void SetObjectToPlaceWnd(int icon, byte mode, Window *w);
|
||||
void SetObjectToPlace(int icon, byte mode, byte window_class, uint16 window_num);
|
||||
|
||||
void ResetObjectToPlace();
|
||||
|
||||
bool ScrollWindowToTile(TileIndex tile, Window * w);
|
||||
bool ScrollWindowTo(int x, int y, Window * w);
|
||||
|
||||
bool ScrollMainWindowToTile(TileIndex tile);
|
||||
bool ScrollMainWindowTo(int x, int y);
|
||||
void DrawSprite(uint32 img, int x, int y);
|
||||
bool EnsureNoVehicle(TileIndex tile);
|
||||
bool EnsureNoVehicleZ(TileIndex tile, byte z);
|
||||
void MarkAllViewportsDirty(int left, int top, int right, int bottom);
|
||||
void ShowCostOrIncomeAnimation(int x, int y, int z, int32 cost);
|
||||
void MarkWholeScreenDirty();
|
||||
|
||||
void DrawFoundation(TileInfo *ti, uint f);
|
||||
|
||||
bool CheckIfAuthorityAllows(uint tile);
|
||||
Town *ClosestTownFromTile(uint tile, uint threshold);
|
||||
void ChangeTownRating(Town *t, int add, int max);
|
||||
|
||||
uint GetRoadBitsByTile(TileIndex tile);
|
||||
int GetTownRadiusGroup(Town *t, uint tile);
|
||||
int32 GetTransportedGoodsIncome(uint num_pieces, uint dist, byte transit_days, byte cargo_type);
|
||||
void ShowRenameSignWindow(SignStruct *ss);
|
||||
void ShowRenameCheckpointWindow(Checkpoint *cp);
|
||||
int FindFirstBit(uint32 x);
|
||||
void ShowHighscoreTable(int tbl);
|
||||
TileIndex AdjustTileCoordRandomly(TileIndex a, byte rng);
|
||||
|
||||
enum SaveOrLoadResult {
|
||||
SL_OK = 0, // completed successfully
|
||||
SL_ERROR = 1, // error that was caught before internal structures were modified
|
||||
SL_REINIT = 2, // error that was caught in the middle of updating game state, need to clear it. (can only happen during load)
|
||||
};
|
||||
enum SaveOrLoadMode {
|
||||
SL_INVALID = -1,
|
||||
SL_LOAD = 0,
|
||||
SL_SAVE = 1,
|
||||
SL_OLD_LOAD = 2,
|
||||
};
|
||||
|
||||
int SaveOrLoad(const char *filename, int mode);
|
||||
|
||||
void AfterLoadTown();
|
||||
void AskExitGame();
|
||||
void AskExitToGameMenu();
|
||||
|
||||
void RedrawAutosave();
|
||||
|
||||
StringID RemapOldStringID(StringID s);
|
||||
|
||||
void UpdateViewportSignPos(ViewportSign *sign, int left, int top, StringID str);
|
||||
|
||||
enum {
|
||||
SLD_LOAD_GAME = 0,
|
||||
SLD_LOAD_SCENARIO = 1,
|
||||
SLD_SAVE_GAME = 2,
|
||||
SLD_SAVE_SCENARIO = 3,
|
||||
SLD_NEW_GAME = 4,
|
||||
};
|
||||
void ShowSaveLoadDialog(int mode);
|
||||
|
||||
void ttd_strlcpy(char *dst, const char *src, size_t len);
|
||||
|
||||
// callback from drivers that is called if the game size changes dynamically
|
||||
void GameSizeChanged();
|
||||
bool MakeScreenshot();
|
||||
bool MakeWorldScreenshot(int left, int top, int width, int height, int zoom);
|
||||
bool FileExists(const char *filename);
|
||||
bool ReadLanguagePack(int index);
|
||||
void InitializeLanguagePacks();
|
||||
byte *ReadFileToMem(const char *filename, size_t *lenp, size_t maxsize);
|
||||
int GetLanguageList(char **languages, int max);
|
||||
|
||||
const char *GetScreenshotFormatDesc(int i);
|
||||
void InitializeScreenshotFormats();
|
||||
void SetScreenshotFormat(int i);
|
||||
void CheckSwitchToEuro();
|
||||
|
||||
void LoadFromConfig();
|
||||
void SaveToConfig();
|
||||
int ttd_main(int argc, char* argv[]);
|
||||
byte GetOSVersion();
|
||||
|
||||
void DeterminePaths();
|
||||
char * CDECL str_fmt(const char *str, ...);
|
||||
|
||||
#endif /* FUNCTIONS_H */
|
1930
trunk/gfx.c
1930
trunk/gfx.c
File diff suppressed because it is too large
Load Diff
110
trunk/gfx.h
110
trunk/gfx.h
|
@ -1,110 +0,0 @@
|
|||
#ifndef GFX_H
|
||||
#define GFX_H
|
||||
|
||||
|
||||
typedef struct ColorList {
|
||||
byte unk0, unk1, unk2;
|
||||
byte window_color_1a, window_color_1b;
|
||||
byte window_color_bga, window_color_bgb;
|
||||
byte window_color_2;
|
||||
} ColorList;
|
||||
|
||||
struct DrawPixelInfo {
|
||||
byte *dst_ptr;
|
||||
int left, top, width, height;
|
||||
int pitch;
|
||||
uint16 zoom;
|
||||
};
|
||||
|
||||
|
||||
typedef struct SpriteHdr {
|
||||
byte info;
|
||||
byte height;
|
||||
uint16 width;
|
||||
int16 x_offs, y_offs;
|
||||
} SpriteHdr;
|
||||
assert_compile(sizeof(SpriteHdr) == 8);
|
||||
|
||||
typedef struct CursorVars {
|
||||
Point pos, size, offs, delta;
|
||||
Point draw_pos, draw_size;
|
||||
uint32 sprite;
|
||||
|
||||
int wheel; // mouse wheel movement
|
||||
const uint16 *animate_list, *animate_cur;
|
||||
uint animate_timeout;
|
||||
|
||||
bool visible;
|
||||
bool dirty;
|
||||
bool fix_at;
|
||||
} CursorVars;
|
||||
|
||||
|
||||
void RedrawScreenRect(int left, int top, int right, int bottom);
|
||||
void GfxScroll(int left, int top, int width, int height, int xo, int yo);
|
||||
int DrawStringCentered(int x, int y, uint16 str, byte color);
|
||||
int DrawString(int x, int y, uint16 str, byte color);
|
||||
void DrawStringCenterUnderline(int x, int y, uint16 str, byte color);
|
||||
int DoDrawString(const byte *string, int x, int y, byte color);
|
||||
void DrawStringRightAligned(int x, int y, uint16 str, byte color);
|
||||
void GfxFillRect(int left, int top, int right, int bottom, int color);
|
||||
void GfxDrawLine(int left, int top, int right, int bottom, int color);
|
||||
void DrawFrameRect(int left, int top, int right, int bottom, int color, int flags);
|
||||
|
||||
int GetStringWidth(const byte *str);
|
||||
void LoadStringWidthTable();
|
||||
void DrawStringMultiCenter(int x, int y, uint16 str, int maxw);
|
||||
void DrawStringMultiLine(int x, int y, uint16 str, int maxw);
|
||||
void DrawDirtyBlocks();
|
||||
void SetDirtyBlocks(int left, int top, int right, int bottom);
|
||||
void MarkWholeScreenDirty();
|
||||
|
||||
void GfxInitPalettes();
|
||||
|
||||
bool FillDrawPixelInfo(DrawPixelInfo *n, DrawPixelInfo *o, int left, int top, int width, int height);
|
||||
|
||||
/* window.c */
|
||||
void DrawOverlappedWindowForAll(int left, int top, int right, int bottom);
|
||||
|
||||
/* spritecache.c */
|
||||
byte *GetSpritePtr(uint sprite);
|
||||
void GfxInitSpriteMem(byte *ptr, uint32 size);
|
||||
void GfxLoadSprites();
|
||||
|
||||
void SetMouseCursor(uint cursor);
|
||||
void SetAnimatedMouseCursor(const uint16 *table);
|
||||
void CursorTick();
|
||||
void DrawMouseCursor();
|
||||
void ScreenSizeChanged();
|
||||
void UndrawMouseCursor();
|
||||
bool ChangeResInGame(int w, int h);
|
||||
|
||||
typedef struct {
|
||||
int xoffs, yoffs;
|
||||
int xsize, ysize;
|
||||
} SpriteDimension;
|
||||
|
||||
const SpriteDimension *GetSpriteDimension(uint sprite);
|
||||
|
||||
/* gfx.c */
|
||||
VARDEF int _stringwidth_base;
|
||||
VARDEF byte _stringwidth_table[0x2A0];
|
||||
|
||||
VARDEF DrawPixelInfo _screen;
|
||||
VARDEF DrawPixelInfo *_cur_dpi;
|
||||
VARDEF ColorList _color_list[16];
|
||||
VARDEF CursorVars _cursor;
|
||||
|
||||
VARDEF int _pal_first_dirty;
|
||||
VARDEF int _pal_last_dirty;
|
||||
|
||||
/* spritecache.c */
|
||||
//enum { NUM_SPRITES = 0x1320 };
|
||||
//enum { NUM_SPRITES = 0x1500 };
|
||||
enum { NUM_SPRITES = 0x3500 }; // 1500 + space for custom GRF sets
|
||||
|
||||
/* tables.h */
|
||||
extern byte _palettes[4][256 * 3];
|
||||
VARDEF byte _cur_palette[768];
|
||||
|
||||
#endif
|
1103
trunk/graph_gui.c
1103
trunk/graph_gui.c
File diff suppressed because it is too large
Load Diff
1072
trunk/grfspecial.c
1072
trunk/grfspecial.c
File diff suppressed because it is too large
Load Diff
121
trunk/gui.h
121
trunk/gui.h
|
@ -1,121 +0,0 @@
|
|||
#ifndef GUI_H
|
||||
#define GUI_H
|
||||
|
||||
#include "window.h"
|
||||
|
||||
/* main_gui.c */
|
||||
void SetupColorsAndInitialWindow();
|
||||
void CcPlaySound10(bool success, uint tile, uint32 p1, uint32 p2);
|
||||
void PlaceProc_Sign(uint tile);
|
||||
|
||||
/* settings_gui.c */
|
||||
void ShowGameOptions();
|
||||
void ShowGameDifficulty();
|
||||
void ShowPatchesSelection();
|
||||
|
||||
/* graph_gui.c */
|
||||
void ShowOperatingProfitGraph();
|
||||
void ShowIncomeGraph();
|
||||
void ShowDeliveredCargoGraph();
|
||||
void ShowPerformanceHistoryGraph();
|
||||
void ShowCompanyValueGraph();
|
||||
void ShowCargoPaymentRates();
|
||||
void ShowCompanyLeagueTable();
|
||||
void ShowPerformanceRatingDetail();
|
||||
|
||||
/* news_gui.c */
|
||||
void ShowLastNewsMessage();
|
||||
void ShowMessageOptions();
|
||||
void ShowMessageHistory();
|
||||
|
||||
/* traintoolb_gui.c */
|
||||
void ShowBuildRailToolbar(int index, int button);
|
||||
void PlaceProc_BuyLand(uint tile);
|
||||
|
||||
/* train_gui.c */
|
||||
void ShowPlayerTrains(int player);
|
||||
void ShowTrainViewWindow(Vehicle *v);
|
||||
void ShowTrainDetailsWindow(Vehicle *v);
|
||||
void ShowOrdersWindow(Vehicle *v);
|
||||
|
||||
void ShowRoadVehViewWindow(Vehicle *v);
|
||||
|
||||
/* road_gui.c */
|
||||
void ShowBuildRoadToolbar();
|
||||
void ShowBuildRoadScenToolbar();
|
||||
void ShowPlayerRoadVehicles(int player);
|
||||
|
||||
/* dock_gui.c */
|
||||
void ShowBuildDocksToolbar();
|
||||
void ShowPlayerShips(int player);
|
||||
|
||||
void ShowShipViewWindow(Vehicle *v);
|
||||
|
||||
/* aircraft_gui.c */
|
||||
void ShowBuildAirToolbar();
|
||||
void ShowPlayerAircraft(int player);
|
||||
|
||||
/* terraform_gui.c */
|
||||
void PlaceProc_DemolishArea(uint tile);
|
||||
void PlaceProc_LowerLand(uint tile);
|
||||
void PlaceProc_RaiseLand(uint tile);
|
||||
void PlaceProc_LevelLand(uint tile);
|
||||
void ShowTerraformToolbar();
|
||||
|
||||
/* misc_gui.c */
|
||||
void PlaceLandBlockInfo();
|
||||
void ShowAboutWindow();
|
||||
void ShowBuildTreesToolbar();
|
||||
void ShowBuildTreesScenToolbar();
|
||||
void ShowTownDirectory();
|
||||
void ShowIndustryDirectory();
|
||||
void ShowSubsidiesList();
|
||||
void ShowPlayerStations(int player);
|
||||
void ShowPlayerFinances(int player);
|
||||
void ShowPlayerCompany(int player);
|
||||
|
||||
void ShowEstimatedCostOrIncome(int32 cost, int x, int y);
|
||||
void ShowErrorMessage(StringID msg_1, StringID msg_2, int x, int y);
|
||||
|
||||
void DrawStationCoverageAreaText(int sx, int sy, uint mask);
|
||||
void CheckRedrawStationCoverage(Window *w);
|
||||
|
||||
void ShowSmallMap();
|
||||
void ShowExtraViewPortWindow();
|
||||
void SetVScrollCount(Window *w, int num);
|
||||
void SetHScrollCount(Window *w, int num);
|
||||
int HandleEditBoxKey(Window *w, int wid, WindowEvent *we);
|
||||
|
||||
void ShowCheatWindow();
|
||||
void AskForNewGameToStart();
|
||||
|
||||
void DrawEditBox(Window *w, int wid);
|
||||
void HandleEditBox(Window *w, int wid);
|
||||
|
||||
|
||||
/* network gui */
|
||||
void ShowNetworkGameWindow();
|
||||
|
||||
|
||||
/* bridge_gui.c */
|
||||
void ShowBuildBridgeWindow(uint start, uint end, byte type);
|
||||
|
||||
enum {
|
||||
ZOOM_IN = 0,
|
||||
ZOOM_OUT = 1,
|
||||
ZOOM_NONE = 2, // hack, used to update the button status
|
||||
};
|
||||
|
||||
bool DoZoomInOutWindow(int how, Window * w);
|
||||
void ShowBuildIndustryWindow();
|
||||
void ShowQueryString(StringID str, StringID caption, int maxlen, int maxwidth, byte window_class, uint16 window_number);
|
||||
void ShowMusicWindow();
|
||||
|
||||
/* main_gui.c */
|
||||
VARDEF byte _newspaper_flag;
|
||||
VARDEF byte _construct_mode;
|
||||
VARDEF byte _station_show_coverage;
|
||||
VARDEF PlaceProc *_place_proc;
|
||||
VARDEF bool _no_button_sound;
|
||||
|
||||
#endif /* GUI_H */
|
146
trunk/hal.h
146
trunk/hal.h
|
@ -1,146 +0,0 @@
|
|||
#ifndef HAL_H
|
||||
#define HAL_H
|
||||
|
||||
typedef struct {
|
||||
char *(*start)(char **parm);
|
||||
void (*stop)();
|
||||
} HalCommonDriver;
|
||||
|
||||
typedef struct {
|
||||
const char *(*start)(char **parm);
|
||||
void (*stop)();
|
||||
void (*make_dirty)(int left, int top, int width, int height);
|
||||
int (*main_loop)();
|
||||
bool (*change_resolution)(int w, int h);
|
||||
} HalVideoDriver;
|
||||
|
||||
enum {
|
||||
ML_QUIT = 0,
|
||||
ML_SWITCHDRIVER = 1,
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
char *(*start)(char **parm);
|
||||
void (*stop)();
|
||||
} HalSoundDriver;
|
||||
|
||||
typedef struct {
|
||||
char *(*start)(char **parm);
|
||||
void (*stop)();
|
||||
|
||||
void (*play_song)(const char *filename);
|
||||
void (*stop_song)();
|
||||
bool (*is_song_playing)();
|
||||
void (*set_volume)(byte vol);
|
||||
} HalMusicDriver;
|
||||
|
||||
typedef struct {
|
||||
const char *name;
|
||||
const char *longname;
|
||||
const void *drv;
|
||||
uint32 flags;
|
||||
} DriverDesc;
|
||||
|
||||
enum {
|
||||
HALERR_OK = 0,
|
||||
HALERR_ERROR = 1,
|
||||
};
|
||||
|
||||
extern const HalMusicDriver _null_music_driver;
|
||||
extern const HalVideoDriver _null_video_driver;
|
||||
extern const HalSoundDriver _null_sound_driver;
|
||||
|
||||
VARDEF HalMusicDriver *_music_driver;
|
||||
VARDEF HalSoundDriver *_sound_driver;
|
||||
VARDEF HalVideoDriver *_video_driver;
|
||||
|
||||
extern const DriverDesc _video_driver_descs[];
|
||||
extern const DriverDesc _sound_driver_descs[];
|
||||
extern const DriverDesc _music_driver_descs[];
|
||||
|
||||
#if defined(WITH_SDL)
|
||||
extern const HalSoundDriver _sdl_sound_driver;
|
||||
extern const HalVideoDriver _sdl_video_driver;
|
||||
#endif
|
||||
|
||||
#if defined(UNIX)
|
||||
extern const HalMusicDriver _extmidi_music_driver;
|
||||
#endif
|
||||
|
||||
#if defined(__BEOS__)
|
||||
extern const HalMusicDriver _bemidi_music_driver;
|
||||
#endif
|
||||
|
||||
enum DriverType {
|
||||
VIDEO_DRIVER = 0,
|
||||
SOUND_DRIVER = 1,
|
||||
MUSIC_DRIVER = 2,
|
||||
};
|
||||
|
||||
extern void GameLoop();
|
||||
extern bool _dbg_screen_rect;
|
||||
|
||||
void LoadDriver(int driver, const char *name);
|
||||
|
||||
char *GetDriverParam(char **parm, const char *name);
|
||||
bool GetDriverParamBool(char **parm, const char *name);
|
||||
int GetDriverParamInt(char **parm, const char *name, int def);
|
||||
|
||||
|
||||
|
||||
// Deals with finding savegames
|
||||
typedef struct {
|
||||
uint16 id;
|
||||
byte type;
|
||||
uint64 mtime;
|
||||
char title[64];
|
||||
char name[256-12-64];
|
||||
int old_extension;
|
||||
} FiosItem;
|
||||
|
||||
// extensions of old savegames, scenarios
|
||||
static const char* const _old_extensions[] = {
|
||||
// old savegame types
|
||||
"ss1", // Transport Tycoon Deluxe preset game
|
||||
"sv1", // Transport Tycoon Deluxe (Patch) saved game
|
||||
"sv2", // Transport Tycoon Deluxe (Patch) saved 2-player game
|
||||
// old scenario game type
|
||||
"sv0", // Transport Tycoon Deluxe (Patch) scenario
|
||||
"ss0", // Transport Tycoon Deluxe preset scenario
|
||||
};
|
||||
|
||||
enum {
|
||||
FIOS_TYPE_DRIVE = 0,
|
||||
FIOS_TYPE_PARENT = 1,
|
||||
FIOS_TYPE_DIR = 2,
|
||||
FIOS_TYPE_FILE = 3,
|
||||
FIOS_TYPE_OLDFILE = 4,
|
||||
FIOS_TYPE_SCENARIO = 5,
|
||||
FIOS_TYPE_OLD_SCENARIO = 6,
|
||||
};
|
||||
|
||||
// get the name of an oldstyle savegame
|
||||
void GetOldSaveGameName(char *title, const char *file);
|
||||
// get the name of an oldstyle scenario
|
||||
void GetOldScenarioGameName(char *title, const char *file);
|
||||
|
||||
// Get a list of savegames
|
||||
FiosItem *FiosGetSavegameList(int *num, int mode);
|
||||
// Get a list of scenarios
|
||||
FiosItem *FiosGetScenarioList(int *num, int mode);
|
||||
// Free the list of savegames
|
||||
void FiosFreeSavegameList();
|
||||
// Browse to. Returns a filename w/path if we reached a file.
|
||||
char *FiosBrowseTo(const FiosItem *item);
|
||||
// Get descriptive texts.
|
||||
// Returns a path as well as a
|
||||
// string describing the path.
|
||||
StringID FiosGetDescText(const char **path);
|
||||
// Delete a name
|
||||
void FiosDelete(const char *name);
|
||||
// Make a filename from a name
|
||||
void FiosMakeSavegameName(char *buf, const char *name);
|
||||
|
||||
void CreateConsole();
|
||||
|
||||
#endif /* HAL_H */
|
|
@ -1,74 +0,0 @@
|
|||
#ifndef INDUSTRY_H
|
||||
#define INDUSTRY_H
|
||||
|
||||
struct Industry {
|
||||
TileIndex xy;
|
||||
byte width; /* swapped order of w/h with town */
|
||||
byte height;
|
||||
Town *town;
|
||||
byte produced_cargo[2];
|
||||
uint16 cargo_waiting[2];
|
||||
byte production_rate[2];
|
||||
byte accepts_cargo[3];
|
||||
byte prod_level;
|
||||
uint16 last_mo_production[2];
|
||||
uint16 last_mo_transported[2];
|
||||
byte pct_transported[2];
|
||||
uint16 total_production[2];
|
||||
uint16 total_transported[2];
|
||||
uint16 counter;
|
||||
|
||||
byte type;
|
||||
byte owner;
|
||||
byte color_map;
|
||||
byte last_prod_year;
|
||||
byte was_cargo_delivered;
|
||||
};
|
||||
|
||||
VARDEF int _total_industries; // For the AI: the amount of industries active
|
||||
VARDEF Industry _industries[90];
|
||||
#define DEREF_INDUSTRY(i) (&_industries[i])
|
||||
VARDEF bool _industry_sort_dirty;
|
||||
void DeleteIndustry(Industry *is);
|
||||
|
||||
enum {
|
||||
IT_COAL_MINE = 0,
|
||||
IT_POWER_STATION = 1,
|
||||
IT_SAWMILL = 2,
|
||||
IT_FOREST = 3,
|
||||
IT_OIL_REFINERY = 4,
|
||||
IT_OIL_RIG = 5,
|
||||
IT_FACTORY = 6,
|
||||
IT_PRINTING_WORKS = 7,
|
||||
IT_STEEL_MILL = 8,
|
||||
IT_FARM = 9,
|
||||
IT_COPPER_MINE = 10,
|
||||
IT_OIL_WELL = 11,
|
||||
IT_BANK = 12,
|
||||
IT_FOOD_PROCESS = 13,
|
||||
IT_PAPER_MILL = 14,
|
||||
IT_GOLD_MINE = 15,
|
||||
IT_BANK_2 = 16,
|
||||
IT_DIAMOND_MINE = 17,
|
||||
IT_IRON_MINE = 18,
|
||||
IT_FRUIT_PLANTATION = 19,
|
||||
IT_RUBBER_PLANTATION = 20,
|
||||
IT_WATER_SUPPLY = 21,
|
||||
IT_WATER_TOWER = 22,
|
||||
IT_FACTORY_2 = 23,
|
||||
IT_FARM_2 = 24,
|
||||
IT_LUMBER_MILL = 25,
|
||||
IT_COTTON_CANDY = 26,
|
||||
IT_CANDY_FACTORY = 27,
|
||||
IT_BATTERY_FARM = 28,
|
||||
IT_COLA_WELLS = 29,
|
||||
IT_TOY_SHOP = 30,
|
||||
IT_TOY_FACTORY = 31,
|
||||
IT_PLASTIC_FOUNTAINS = 32,
|
||||
IT_FIZZY_DRINK_FACTORY = 33,
|
||||
IT_BUBBLE_GENERATOR = 34,
|
||||
IT_TOFFEE_QUARRY = 35,
|
||||
IT_SUGAR_MINE = 36,
|
||||
};
|
||||
|
||||
#endif
|
1905
trunk/industry_cmd.c
1905
trunk/industry_cmd.c
File diff suppressed because it is too large
Load Diff
|
@ -1,589 +0,0 @@
|
|||
#include "stdafx.h"
|
||||
#include "ttd.h"
|
||||
//#include "gui.h"
|
||||
#include "window.h"
|
||||
#include "gfx.h"
|
||||
#include "command.h"
|
||||
#include "viewport.h"
|
||||
#include "industry.h"
|
||||
#include "town.h"
|
||||
|
||||
static const byte _build_industry_types[4][12] = {
|
||||
{ 1, 2, 4, 6, 8, 0, 3, 5, 9, 11, 18 },
|
||||
{ 1, 14, 4, 13, 7, 0, 3, 9, 11, 15 },
|
||||
{ 25, 13, 4, 23, 22, 11, 17, 10, 24, 19, 20, 21 },
|
||||
{ 27, 30, 31, 33, 26, 28, 29, 32, 34, 35, 36 },
|
||||
};
|
||||
|
||||
extern const byte _industry_type_costs[37];
|
||||
|
||||
static void BuildIndustryWndProc(Window *w, WindowEvent *e)
|
||||
{
|
||||
switch(e->event) {
|
||||
case WE_PAINT:
|
||||
DrawWindowWidgets(w);
|
||||
if (_thd.place_mode == 1 && _thd.window_class == WC_BUILD_INDUSTRY) {
|
||||
int ind_type = _build_industry_types[_opt.landscape][WP(w,def_d).data_1];
|
||||
|
||||
SET_DPARAM32(0, (_price.build_industry >> 5) * _industry_type_costs[ind_type]);
|
||||
DrawStringCentered(85, w->height - 21, STR_482F_COST, 0);
|
||||
}
|
||||
break;
|
||||
|
||||
case WE_CLICK: {
|
||||
int wid = e->click.widget;
|
||||
if (wid >= 3) {
|
||||
if (HandlePlacePushButton(w, wid, 0xFF1, 1, NULL))
|
||||
WP(w,def_d).data_1 = wid - 3;
|
||||
}
|
||||
} break;
|
||||
|
||||
case WE_PLACE_OBJ:
|
||||
if (DoCommandP(e->place.tile, _build_industry_types[_opt.landscape][WP(w,def_d).data_1], 0, NULL, CMD_BUILD_INDUSTRY | CMD_MSG(STR_4830_CAN_T_CONSTRUCT_THIS_INDUSTRY)))
|
||||
ResetObjectToPlace();
|
||||
break;
|
||||
|
||||
case WE_ABORT_PLACE_OBJ:
|
||||
w->click_state = 0;
|
||||
SetWindowDirty(w);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static const Widget _build_industry_land0_widgets[] = {
|
||||
{ WWT_CLOSEBOX, 7, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
|
||||
{ WWT_CAPTION, 7, 11, 169, 0, 13, STR_0314_FUND_NEW_INDUSTRY, STR_018C_WINDOW_TITLE_DRAG_THIS},
|
||||
{ WWT_PANEL, 7, 0, 169, 14, 115, 0x0, STR_NULL},
|
||||
{ WWT_CLOSEBOX, 14, 2, 167, 16, 27, STR_0241_POWER_STATION, STR_0263_CONSTRUCT_POWER_STATION},
|
||||
{ WWT_CLOSEBOX, 14, 2, 167, 29, 40, STR_0242_SAWMILL, STR_0264_CONSTRUCT_SAWMILL},
|
||||
{ WWT_CLOSEBOX, 14, 2, 167, 42, 53, STR_0244_OIL_REFINERY, STR_0266_CONSTRUCT_OIL_REFINERY},
|
||||
{ WWT_CLOSEBOX, 14, 2, 167, 55, 66, STR_0246_FACTORY, STR_0268_CONSTRUCT_FACTORY},
|
||||
{ WWT_CLOSEBOX, 14, 2, 167, 68, 79, STR_0247_STEEL_MILL, STR_0269_CONSTRUCT_STEEL_MILL},
|
||||
{ WIDGETS_END},
|
||||
};
|
||||
|
||||
static const Widget _build_industry_land1_widgets[] = {
|
||||
{ WWT_CLOSEBOX, 7, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
|
||||
{ WWT_CAPTION, 7, 11, 169, 0, 13, STR_0314_FUND_NEW_INDUSTRY, STR_018C_WINDOW_TITLE_DRAG_THIS},
|
||||
{ WWT_PANEL, 7, 0, 169, 14, 115, 0x0, STR_NULL},
|
||||
{ WWT_CLOSEBOX, 14, 2, 167, 16, 27, STR_0241_POWER_STATION, STR_0263_CONSTRUCT_POWER_STATION},
|
||||
{ WWT_CLOSEBOX, 14, 2, 167, 29, 40, STR_024C_PAPER_MILL, STR_026E_CONSTRUCT_PAPER_MILL},
|
||||
{ WWT_CLOSEBOX, 14, 2, 167, 42, 53, STR_0244_OIL_REFINERY, STR_0266_CONSTRUCT_OIL_REFINERY},
|
||||
{ WWT_CLOSEBOX, 14, 2, 167, 55, 66, STR_024D_FOOD_PROCESSING_PLANT,STR_026F_CONSTRUCT_FOOD_PROCESSING},
|
||||
{ WWT_CLOSEBOX, 14, 2, 167, 68, 79, STR_024E_PRINTING_WORKS, STR_0270_CONSTRUCT_PRINTING_WORKS},
|
||||
{ WIDGETS_END},
|
||||
};
|
||||
|
||||
static const Widget _build_industry_land2_widgets[] = {
|
||||
{ WWT_CLOSEBOX, 7, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
|
||||
{ WWT_CAPTION, 7, 11, 169, 0, 13, STR_0314_FUND_NEW_INDUSTRY, STR_018C_WINDOW_TITLE_DRAG_THIS},
|
||||
{ WWT_PANEL, 7, 0, 169, 14, 115, 0x0, STR_NULL},
|
||||
{ WWT_CLOSEBOX, 14, 2, 167, 16, 27, STR_0250_LUMBER_MILL, STR_0273_CONSTRUCT_LUMBER_MILL_TO},
|
||||
{ WWT_CLOSEBOX, 14, 2, 167, 29, 40, STR_024D_FOOD_PROCESSING_PLANT,STR_026F_CONSTRUCT_FOOD_PROCESSING},
|
||||
{ WWT_CLOSEBOX, 14, 2, 167, 42, 53, STR_0244_OIL_REFINERY, STR_0266_CONSTRUCT_OIL_REFINERY},
|
||||
{ WWT_CLOSEBOX, 14, 2, 167, 55, 66, STR_0246_FACTORY, STR_0268_CONSTRUCT_FACTORY},
|
||||
{ WWT_CLOSEBOX, 14, 2, 167, 68, 79, STR_0254_WATER_TOWER, STR_0277_CONSTRUCT_WATER_TOWER_CAN},
|
||||
{ WIDGETS_END},
|
||||
};
|
||||
|
||||
static const Widget _build_industry_land3_widgets[] = {
|
||||
{ WWT_CLOSEBOX, 7, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
|
||||
{ WWT_CAPTION, 7, 11, 169, 0, 13, STR_0314_FUND_NEW_INDUSTRY, STR_018C_WINDOW_TITLE_DRAG_THIS},
|
||||
{ WWT_PANEL, 7, 0, 169, 14, 115, 0x0, STR_NULL},
|
||||
{ WWT_CLOSEBOX, 14, 2, 167, 16, 27, STR_0258_CANDY_FACTORY, STR_027B_CONSTRUCT_CANDY_FACTORY},
|
||||
{ WWT_CLOSEBOX, 14, 2, 167, 29, 40, STR_025B_TOY_SHOP, STR_027E_CONSTRUCT_TOY_SHOP},
|
||||
{ WWT_CLOSEBOX, 14, 2, 167, 42, 53, STR_025C_TOY_FACTORY, STR_027F_CONSTRUCT_TOY_FACTORY},
|
||||
{ WWT_CLOSEBOX, 14, 2, 167, 55, 66, STR_025E_FIZZY_DRINK_FACTORY, STR_0281_CONSTRUCT_FIZZY_DRINK_FACTORY},
|
||||
{ WIDGETS_END},
|
||||
};
|
||||
|
||||
static const Widget _build_industry_land0_widgets_extra[] = {
|
||||
{ WWT_CLOSEBOX, 7, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
|
||||
{ WWT_CAPTION, 7, 11, 169, 0, 13, STR_0314_FUND_NEW_INDUSTRY,STR_018C_WINDOW_TITLE_DRAG_THIS},
|
||||
{ WWT_PANEL, 7, 0, 169, 14, 187, 0x0, STR_NULL},
|
||||
|
||||
{ WWT_CLOSEBOX, 14, 2, 167, 16, 27, STR_0241_POWER_STATION,STR_0263_CONSTRUCT_POWER_STATION},
|
||||
{ WWT_CLOSEBOX, 14, 2, 167, 29, 40, STR_0242_SAWMILL, STR_0264_CONSTRUCT_SAWMILL},
|
||||
{ WWT_CLOSEBOX, 14, 2, 167, 42, 53, STR_0244_OIL_REFINERY, STR_0266_CONSTRUCT_OIL_REFINERY},
|
||||
{ WWT_CLOSEBOX, 14, 2, 167, 55, 66, STR_0246_FACTORY, STR_0268_CONSTRUCT_FACTORY},
|
||||
{ WWT_CLOSEBOX, 14, 2, 167, 68, 79, STR_0247_STEEL_MILL, STR_0269_CONSTRUCT_STEEL_MILL},
|
||||
|
||||
{ WWT_CLOSEBOX, 14, 2, 167, 84, 95, STR_0240_COAL_MINE, STR_CONSTRUCT_COAL_MINE_TIP},
|
||||
{ WWT_CLOSEBOX, 14, 2, 167, 97, 108, STR_0243_FOREST, STR_CONSTRUCT_FOREST_TIP},
|
||||
{ WWT_CLOSEBOX, 14, 2, 167, 110, 121, STR_0245_OIL_RIG, STR_CONSTRUCT_OIL_RIG_TIP},
|
||||
{ WWT_CLOSEBOX, 14, 2, 167, 123, 134, STR_0248_FARM, STR_CONSTRUCT_FARM_TIP},
|
||||
{ WWT_CLOSEBOX, 14, 2, 167, 136, 147, STR_024A_OIL_WELLS, STR_CONSTRUCT_OIL_WELLS_TIP},
|
||||
{ WWT_CLOSEBOX, 14, 2, 167, 149, 160, STR_0249_IRON_ORE_MINE, STR_CONSTRUCT_IRON_ORE_MINE_TIP},
|
||||
|
||||
{ WIDGETS_END},
|
||||
};
|
||||
|
||||
static const Widget _build_industry_land1_widgets_extra[] = {
|
||||
{ WWT_CLOSEBOX, 7, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
|
||||
{ WWT_CAPTION, 7, 11, 169, 0, 13, STR_0314_FUND_NEW_INDUSTRY, STR_018C_WINDOW_TITLE_DRAG_THIS},
|
||||
{ WWT_PANEL, 7, 0, 169, 14, 174, 0x0, STR_NULL},
|
||||
|
||||
{ WWT_CLOSEBOX, 14, 2, 167, 16, 27, STR_0241_POWER_STATION, STR_0263_CONSTRUCT_POWER_STATION},
|
||||
{ WWT_CLOSEBOX, 14, 2, 167, 29, 40, STR_024C_PAPER_MILL, STR_026E_CONSTRUCT_PAPER_MILL},
|
||||
{ WWT_CLOSEBOX, 14, 2, 167, 42, 53, STR_0244_OIL_REFINERY, STR_0266_CONSTRUCT_OIL_REFINERY},
|
||||
{ WWT_CLOSEBOX, 14, 2, 167, 55, 66, STR_024D_FOOD_PROCESSING_PLANT,STR_026F_CONSTRUCT_FOOD_PROCESSING},
|
||||
{ WWT_CLOSEBOX, 14, 2, 167, 68, 79, STR_024E_PRINTING_WORKS, STR_0270_CONSTRUCT_PRINTING_WORKS},
|
||||
|
||||
{ WWT_CLOSEBOX, 14, 2, 167, 81+3, 92+3, STR_0240_COAL_MINE, STR_CONSTRUCT_COAL_MINE_TIP},
|
||||
{ WWT_CLOSEBOX, 14, 2, 167, 94+3, 105+3, STR_0243_FOREST, STR_CONSTRUCT_FOREST_TIP},
|
||||
{ WWT_CLOSEBOX, 14, 2, 167, 107+3, 118+3, STR_0248_FARM, STR_CONSTRUCT_FARM_TIP},
|
||||
{ WWT_CLOSEBOX, 14, 2, 167, 120+3, 131+3, STR_024A_OIL_WELLS, STR_CONSTRUCT_OIL_WELLS_TIP},
|
||||
{ WWT_CLOSEBOX, 14, 2, 167, 133+3, 144+3, STR_024F_GOLD_MINE, STR_CONSTRUCT_GOLD_MINE_TIP},
|
||||
{ WIDGETS_END},
|
||||
};
|
||||
|
||||
static const Widget _build_industry_land2_widgets_extra[] = {
|
||||
{ WWT_CLOSEBOX, 7, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
|
||||
{ WWT_CAPTION, 7, 11, 169, 0, 13, STR_0314_FUND_NEW_INDUSTRY, STR_018C_WINDOW_TITLE_DRAG_THIS},
|
||||
{ WWT_PANEL, 7, 0, 169, 14, 200, 0x0, STR_NULL},
|
||||
|
||||
{ WWT_CLOSEBOX, 14, 2, 167, 16, 27, STR_0250_LUMBER_MILL, STR_0273_CONSTRUCT_LUMBER_MILL_TO},
|
||||
{ WWT_CLOSEBOX, 14, 2, 167, 29, 40, STR_024D_FOOD_PROCESSING_PLANT,STR_026F_CONSTRUCT_FOOD_PROCESSING},
|
||||
{ WWT_CLOSEBOX, 14, 2, 167, 42, 53, STR_0244_OIL_REFINERY, STR_0266_CONSTRUCT_OIL_REFINERY},
|
||||
{ WWT_CLOSEBOX, 14, 2, 167, 55, 66, STR_0246_FACTORY, STR_0268_CONSTRUCT_FACTORY},
|
||||
{ WWT_CLOSEBOX, 14, 2, 167, 68, 79, STR_0254_WATER_TOWER, STR_0277_CONSTRUCT_WATER_TOWER_CAN},
|
||||
|
||||
{ WWT_CLOSEBOX, 14, 2, 167, 81+3, 92+3, STR_024A_OIL_WELLS,STR_CONSTRUCT_OIL_WELLS_TIP},
|
||||
{ WWT_CLOSEBOX, 14, 2, 167, 94+3, 105+3, STR_0255_DIAMOND_MINE, STR_CONSTRUCT_DIAMOND_MINE_TIP},
|
||||
{ WWT_CLOSEBOX, 14, 2, 167, 107+3, 118+3, STR_0256_COPPER_ORE_MINE, STR_CONSTRUCT_COPPER_ORE_MINE_TIP},
|
||||
{ WWT_CLOSEBOX, 14, 2, 167, 120+3, 131+3, STR_0248_FARM, STR_CONSTRUCT_FARM_TIP},
|
||||
{ WWT_CLOSEBOX, 14, 2, 167, 133+3, 144+3, STR_0251_FRUIT_PLANTATION, STR_CONSTRUCT_FRUIT_PLANTATION_TIP},
|
||||
{ WWT_CLOSEBOX, 14, 2, 167, 146+3, 157+3, STR_0252_RUBBER_PLANTATION,STR_CONSTRUCT_RUBBER_PLANTATION_TIP},
|
||||
{ WWT_CLOSEBOX, 14, 2, 167, 159+3, 170+3, STR_0253_WATER_SUPPLY, STR_CONSTRUCT_WATER_SUPPLY_TIP},
|
||||
{ WIDGETS_END},
|
||||
};
|
||||
|
||||
static const Widget _build_industry_land3_widgets_extra[] = {
|
||||
{ WWT_CLOSEBOX, 7, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
|
||||
{ WWT_CAPTION, 7, 11, 169, 0, 13, STR_0314_FUND_NEW_INDUSTRY, STR_018C_WINDOW_TITLE_DRAG_THIS},
|
||||
{ WWT_PANEL, 7, 0, 169, 14, 187, 0x0, STR_NULL},
|
||||
|
||||
{ WWT_CLOSEBOX, 14, 2, 167, 16, 27, STR_0258_CANDY_FACTORY, STR_027B_CONSTRUCT_CANDY_FACTORY},
|
||||
{ WWT_CLOSEBOX, 14, 2, 167, 29, 40, STR_025B_TOY_SHOP, STR_027E_CONSTRUCT_TOY_SHOP},
|
||||
{ WWT_CLOSEBOX, 14, 2, 167, 42, 53, STR_025C_TOY_FACTORY, STR_027F_CONSTRUCT_TOY_FACTORY},
|
||||
{ WWT_CLOSEBOX, 14, 2, 167, 55, 66, STR_025E_FIZZY_DRINK_FACTORY, STR_0281_CONSTRUCT_FIZZY_DRINK_FACTORY},
|
||||
|
||||
{ WWT_CLOSEBOX, 14, 2, 167, 68+3, 79+3, STR_0257_COTTON_CANDY_FOREST,STR_CONSTRUCT_COTTON_CANDY_TIP},
|
||||
{ WWT_CLOSEBOX, 14, 2, 167, 81+3, 92+3, STR_0259_BATTERY_FARM, STR_CONSTRUCT_BATTERY_FARM_TIP},
|
||||
{ WWT_CLOSEBOX, 14, 2, 167, 94+3, 105+3, STR_025A_COLA_WELLS, STR_CONSTRUCT_COLA_WELLS_TIP},
|
||||
{ WWT_CLOSEBOX, 14, 2, 167, 107+3, 118+3, STR_025D_PLASTIC_FOUNTAINS,STR_CONSTRUCT_PLASTIC_FOUNTAINS_TIP},
|
||||
{ WWT_CLOSEBOX, 14, 2, 167, 120+3, 131+3, STR_025F_BUBBLE_GENERATOR, STR_CONSTRUCT_BUBBLE_GENERATOR_TIP},
|
||||
{ WWT_CLOSEBOX, 14, 2, 167, 133+3, 144+3, STR_0260_TOFFEE_QUARRY, STR_CONSTRUCT_TOFFEE_QUARRY_TIP},
|
||||
{ WWT_CLOSEBOX, 14, 2, 167, 146+3, 157+3, STR_0261_SUGAR_MINE, STR_CONSTRUCT_SUGAR_MINE_TIP},
|
||||
{ WIDGETS_END},
|
||||
};
|
||||
|
||||
|
||||
static const WindowDesc _build_industry_land0_desc = {
|
||||
-1, -1, 170, 116,
|
||||
WC_BUILD_INDUSTRY,0,
|
||||
WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET,
|
||||
_build_industry_land0_widgets,
|
||||
BuildIndustryWndProc
|
||||
};
|
||||
|
||||
static const WindowDesc _build_industry_land1_desc = {
|
||||
-1, -1, 170, 116,
|
||||
WC_BUILD_INDUSTRY,0,
|
||||
WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET,
|
||||
_build_industry_land1_widgets,
|
||||
BuildIndustryWndProc
|
||||
};
|
||||
|
||||
static const WindowDesc _build_industry_land2_desc = {
|
||||
-1, -1, 170, 116,
|
||||
WC_BUILD_INDUSTRY,0,
|
||||
WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET,
|
||||
_build_industry_land2_widgets,
|
||||
BuildIndustryWndProc
|
||||
};
|
||||
|
||||
static const WindowDesc _build_industry_land3_desc = {
|
||||
-1, -1, 170, 116,
|
||||
WC_BUILD_INDUSTRY,0,
|
||||
WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET,
|
||||
_build_industry_land3_widgets,
|
||||
BuildIndustryWndProc
|
||||
};
|
||||
|
||||
static const WindowDesc _build_industry_land0_desc_extra = {
|
||||
-1, -1, 170, 188,
|
||||
WC_BUILD_INDUSTRY,0,
|
||||
WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET,
|
||||
_build_industry_land0_widgets_extra,
|
||||
BuildIndustryWndProc
|
||||
};
|
||||
|
||||
static const WindowDesc _build_industry_land1_desc_extra = {
|
||||
-1, -1, 170, 175,
|
||||
WC_BUILD_INDUSTRY,0,
|
||||
WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET,
|
||||
_build_industry_land1_widgets_extra,
|
||||
BuildIndustryWndProc
|
||||
};
|
||||
|
||||
static const WindowDesc _build_industry_land2_desc_extra = {
|
||||
-1, -1, 170, 201,
|
||||
WC_BUILD_INDUSTRY,0,
|
||||
WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET,
|
||||
_build_industry_land2_widgets_extra,
|
||||
BuildIndustryWndProc
|
||||
};
|
||||
|
||||
static const WindowDesc _build_industry_land3_desc_extra = {
|
||||
-1, -1, 170, 188,
|
||||
WC_BUILD_INDUSTRY,0,
|
||||
WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET,
|
||||
_build_industry_land3_widgets_extra,
|
||||
BuildIndustryWndProc
|
||||
};
|
||||
|
||||
static const WindowDesc * const _industry_window_desc[2][4] = {
|
||||
{
|
||||
&_build_industry_land0_desc,
|
||||
&_build_industry_land1_desc,
|
||||
&_build_industry_land2_desc,
|
||||
&_build_industry_land3_desc,
|
||||
},
|
||||
{
|
||||
&_build_industry_land0_desc_extra,
|
||||
&_build_industry_land1_desc_extra,
|
||||
&_build_industry_land2_desc_extra,
|
||||
&_build_industry_land3_desc_extra,
|
||||
},
|
||||
};
|
||||
|
||||
void ShowBuildIndustryWindow()
|
||||
{
|
||||
AllocateWindowDescFront(_industry_window_desc[_patches.build_rawmaterial_ind][_opt.landscape],0);
|
||||
}
|
||||
|
||||
static void IndustryViewWndProc(Window *w, WindowEvent *e)
|
||||
{
|
||||
Industry *i;
|
||||
StringID str;
|
||||
|
||||
switch(e->event) {
|
||||
case WE_PAINT:
|
||||
// in editor, use bulldoze to destroy industry
|
||||
// Destroy Industry button costing money removed per request of dominik
|
||||
//w->disabled_state = (_patches.extra_dynamite && !_networking && _game_mode != GM_EDITOR) ? 0 : (1 << 6);
|
||||
i = DEREF_INDUSTRY(w->window_number);
|
||||
SET_DPARAM16(0, i->town->index);
|
||||
SET_DPARAM16(1, i->type + STR_4802_COAL_MINE);
|
||||
DrawWindowWidgets(w);
|
||||
|
||||
if (i->accepts_cargo[0] != 0xFF) {
|
||||
SET_DPARAM16(0, _cargoc.names_s[i->accepts_cargo[0]]);
|
||||
str = STR_4827_REQUIRES;
|
||||
if (i->accepts_cargo[1] != 0xFF) {
|
||||
SET_DPARAM16(1, _cargoc.names_s[i->accepts_cargo[1]]);
|
||||
str++;
|
||||
if (i->accepts_cargo[2] != 0xFF) {
|
||||
SET_DPARAM16(2, _cargoc.names_s[i->accepts_cargo[2]]);
|
||||
str++;
|
||||
}
|
||||
}
|
||||
DrawString(2, 107, str, 0);
|
||||
}
|
||||
|
||||
if (i->produced_cargo[0] != 0xFF) {
|
||||
DrawString(2, 117, STR_482A_PRODUCTION_LAST_MONTH, 0);
|
||||
|
||||
SET_DPARAM16(1, i->total_production[0]);
|
||||
SET_DPARAM16(0, _cargoc.names_long_s[i->produced_cargo[0]] + ((i->total_production[0]!=1)<<5));
|
||||
SET_DPARAM16(2, i->pct_transported[0] * 100 >> 8);
|
||||
DrawString(4, 127, STR_482B_TRANSPORTED, 0);
|
||||
|
||||
if (i->produced_cargo[1] != 0xFF) {
|
||||
SET_DPARAM16(1, i->total_production[1]);
|
||||
SET_DPARAM16(0, _cargoc.names_long_s[i->produced_cargo[1]] + ((i->total_production[1]!=1)<<5));
|
||||
SET_DPARAM16(2, i->pct_transported[1] * 100 >> 8);
|
||||
DrawString(4, 137, STR_482B_TRANSPORTED, 0);
|
||||
}
|
||||
}
|
||||
|
||||
DrawWindowViewport(w);
|
||||
break;
|
||||
|
||||
case WE_CLICK:
|
||||
switch(e->click.widget) {
|
||||
case 5:
|
||||
i = DEREF_INDUSTRY(w->window_number);
|
||||
ScrollMainWindowToTile(i->xy + TILE_XY(1,1));
|
||||
break;
|
||||
case 6:
|
||||
// Destroy Industry button costing money removed per request of dominik
|
||||
//i = DEREF_INDUSTRY(w->window_number);
|
||||
/* passing only i->xy is not safe if industry has a weird shape like:
|
||||
_ X X
|
||||
X X X
|
||||
_ <--- grass, no industry, but i->xy points there (first top-left tile)!,
|
||||
so passing i->xy to destroy industry will fail in called procedure
|
||||
*/
|
||||
//DoCommandP(i->xy, w->window_number, 0, CcPlaySound10, CMD_DESTROY_INDUSTRY | CMD_MSG(STR_00B5_CAN_T_CLEAR_THIS_AREA));
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static const Widget _industry_view_widgets[] = {
|
||||
{ WWT_TEXTBTN, 9, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
|
||||
{ WWT_CAPTION, 9, 11, 259, 0, 13, STR_4801, STR_018C_WINDOW_TITLE_DRAG_THIS},
|
||||
{ WWT_IMGBTN, 9, 0, 259, 14, 105, 0x0, STR_NULL},
|
||||
{ WWT_6, 9, 2, 257, 16, 103, 0x0, STR_NULL},
|
||||
{ WWT_IMGBTN, 9, 0, 259, 106, 147, 0x0, STR_NULL},
|
||||
{ WWT_PUSHTXTBTN, 9, 0, 129, 148, 159, STR_00E4_LOCATION, STR_482C_CENTER_THE_MAIN_VIEW_ON},
|
||||
{ WWT_IMGBTN, 9, 130, 259, 148, 159, 0x0, STR_NULL},
|
||||
// Destroy Industry button costing money removed per request of dominik
|
||||
//{ WWT_PUSHTXTBTN, 9, 130, 259, 148, 159, STR_INDUSTRYDIR_DESTROY, STR_482C_DESTROY_INDUSTRY},
|
||||
{ WIDGETS_END},
|
||||
};
|
||||
|
||||
static const WindowDesc _industry_view_desc = {
|
||||
-1, -1, 260, 160,
|
||||
WC_INDUSTRY_VIEW,0,
|
||||
WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS,
|
||||
_industry_view_widgets,
|
||||
IndustryViewWndProc
|
||||
};
|
||||
|
||||
void ShowIndustryViewWindow(int industry)
|
||||
{
|
||||
Window *w;
|
||||
Industry *i;
|
||||
|
||||
w = AllocateWindowDescFront(&_industry_view_desc, industry);
|
||||
if (w) {
|
||||
w->flags4 |= WF_DISABLE_VP_SCROLL;
|
||||
i = DEREF_INDUSTRY(w->window_number);
|
||||
AssignWindowViewport(w, 3, 17, 0xFE, 0x56, i->xy + TILE_XY(1,1), 1);
|
||||
}
|
||||
}
|
||||
|
||||
static const Widget _industry_directory_widgets[] = {
|
||||
{ WWT_TEXTBTN, 13, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
|
||||
{ WWT_CAPTION, 13, 11, 507, 0, 13, STR_INDUSTRYDIR_CAPTION, STR_018C_WINDOW_TITLE_DRAG_THIS},
|
||||
{ WWT_PUSHTXTBTN, 13, 0, 100, 14, 25, STR_SORT_BY_NAME, STR_SORT_TIP},
|
||||
{ WWT_PUSHTXTBTN, 13, 101, 200, 14, 25, STR_SORT_BY_TYPE, STR_SORT_TIP},
|
||||
{ WWT_PUSHTXTBTN, 13, 201, 300, 14, 25, STR_SORT_BY_PRODUCTION, STR_SORT_TIP},
|
||||
{ WWT_PUSHTXTBTN, 13, 301, 400, 14, 25, STR_SORT_BY_TRANSPORTED, STR_SORT_TIP},
|
||||
{ WWT_PANEL, 13, 401, 496, 14, 25, 0x0, STR_NULL},
|
||||
{ WWT_IMGBTN, 13, 0, 496, 26, 189, 0x0, STR_200A_TOWN_NAMES_CLICK_ON_NAME},
|
||||
{ WWT_SCROLLBAR, 13, 497, 507, 14, 189, 0x0, STR_0190_SCROLL_BAR_SCROLLS_LIST},
|
||||
{ WIDGETS_END},
|
||||
};
|
||||
|
||||
static byte _industry_sort[lengthof(_industries)];
|
||||
static uint _num_industry_sort;
|
||||
|
||||
static char _bufcache[96];
|
||||
static byte _last_industry_idx;
|
||||
|
||||
static byte _industry_sort_order;
|
||||
|
||||
static int CDECL GeneralIndustrySorter(const void *a, const void *b)
|
||||
{
|
||||
char buf1[96];
|
||||
byte val;
|
||||
Industry *i = DEREF_INDUSTRY(*(const byte*)a);
|
||||
Industry *j = DEREF_INDUSTRY(*(const byte*)b);
|
||||
int r = 0;
|
||||
|
||||
switch (_industry_sort_order >> 1) {
|
||||
/* case 0: Sort by Name (handled later) */
|
||||
case 1: /* Sort by Type */
|
||||
r = i->type - j->type;
|
||||
break;
|
||||
// FIXME - Production & Transported sort need to be inversed...but, WTF it does not wanna!
|
||||
// FIXME - And no simple --> "if (!(_industry_sort_order & 1)) r = -r;" hack at the bottom!!
|
||||
case 2: { /* Sort by Production */
|
||||
if (i->produced_cargo[0] != 0xFF && j->produced_cargo[0] != 0xFF) { // both industries produce cargo?
|
||||
if (i->produced_cargo[1] == 0xFF) // producing one or two things?
|
||||
r = j->total_production[0] - i->total_production[0];
|
||||
else
|
||||
r = (j->total_production[0] + j->total_production[1]) / 2 - (i->total_production[0] + i->total_production[1]) / 2;
|
||||
} else if (i->produced_cargo[0] == 0xFF && j->produced_cargo[0] == 0xFF) // none of them producing anything, let them go to the name-sorting
|
||||
r = 0;
|
||||
else if (i->produced_cargo[0] == 0xFF) // end up the non-producer industry first/last in list
|
||||
r = 1;
|
||||
else
|
||||
r = -1;
|
||||
break;
|
||||
}
|
||||
case 3: /* Sort by Transported amount */
|
||||
if (i->produced_cargo[0] != 0xFF && j->produced_cargo[0] != 0xFF) { // both industries produce cargo?
|
||||
if (i->produced_cargo[1] == 0xFF) // producing one or two things?
|
||||
r = (j->pct_transported[0] * 100 >> 8) - (i->pct_transported[0] * 100 >> 8);
|
||||
else
|
||||
r = ((j->pct_transported[0] * 100 >> 8) + (j->pct_transported[1] * 100 >> 8)) / 2 - ((i->pct_transported[0] * 100 >> 8) + (i->pct_transported[1] * 100 >> 8)) / 2;
|
||||
} else if (i->produced_cargo[0] == 0xFF && j->produced_cargo[0] == 0xFF) // none of them producing anything, let them go to the name-sorting
|
||||
r = 0;
|
||||
else if (i->produced_cargo[0] == 0xFF) // end up the non-producer industry first/last in list
|
||||
r = 1;
|
||||
else
|
||||
r = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
// default to string sorting if they are otherwise equal
|
||||
if (r == 0) {
|
||||
SET_DPARAM32(0, i->town->townnameparts);
|
||||
GetString(buf1, i->town->townnametype);
|
||||
|
||||
if ( (val=*(const byte*)b) != _last_industry_idx) {
|
||||
_last_industry_idx = val;
|
||||
SET_DPARAM32(0, j->town->townnameparts);
|
||||
GetString(_bufcache, j->town->townnametype);
|
||||
}
|
||||
r = strcmp(buf1, _bufcache);
|
||||
}
|
||||
|
||||
if (_industry_sort_order & 1) r = -r;
|
||||
return r;
|
||||
}
|
||||
|
||||
static void MakeSortedIndustryList()
|
||||
{
|
||||
Industry *i;
|
||||
int n = 0, index = 0;
|
||||
|
||||
for(i=_industries; i != endof(_industries); i++) {
|
||||
if(i->xy) _industry_sort[n++] = index;
|
||||
index++;
|
||||
}
|
||||
_num_industry_sort = n;
|
||||
_last_industry_idx = 255; // used for "cache"
|
||||
|
||||
qsort(_industry_sort, n, 1, GeneralIndustrySorter);
|
||||
|
||||
DEBUG(misc, 1) ("Resorting Industries list...");
|
||||
}
|
||||
|
||||
|
||||
static void IndustryDirectoryWndProc(Window *w, WindowEvent *e)
|
||||
{
|
||||
switch(e->event) {
|
||||
case WE_PAINT: {
|
||||
int n;
|
||||
uint p;
|
||||
Industry *i;
|
||||
static const uint16 _indicator_positions[4] = {88, 187, 284, 387};
|
||||
|
||||
if (_industry_sort_dirty) {
|
||||
_industry_sort_dirty = false;
|
||||
MakeSortedIndustryList();
|
||||
}
|
||||
|
||||
w->vscroll.count = _num_industry_sort;
|
||||
|
||||
DrawWindowWidgets(w);
|
||||
DoDrawString(_industry_sort_order & 1 ? "\xAA" : "\xA0", _indicator_positions[_industry_sort_order>>1], 15, 0x10);
|
||||
|
||||
p = w->vscroll.pos;
|
||||
n = 0;
|
||||
|
||||
while (p < _num_industry_sort) {
|
||||
i = DEREF_INDUSTRY(_industry_sort[p]);
|
||||
SET_DPARAM16(0, i->town->index);
|
||||
SET_DPARAM16(1, i->type + STR_4802_COAL_MINE);
|
||||
if (i->produced_cargo[0] != 0xFF) {
|
||||
SET_DPARAM16(3, i->total_production[0]);
|
||||
SET_DPARAM16(2, _cargoc.names_long_s[i->produced_cargo[0]] + ((i->total_production[0]!=1)<<5));
|
||||
|
||||
if (i->produced_cargo[1] != 0xFF) {
|
||||
SET_DPARAM16(5, i->total_production[1]);
|
||||
SET_DPARAM16(4, _cargoc.names_long_s[i->produced_cargo[1]] + ((i->total_production[1]!=1)<<5));
|
||||
SET_DPARAM16(6, i->pct_transported[0] * 100 >> 8);
|
||||
SET_DPARAM16(7, i->pct_transported[1] * 100 >> 8);
|
||||
DrawString(4, 28+n*10, STR_INDUSTRYDIR_ITEM_TWO, 0);
|
||||
} else {
|
||||
SET_DPARAM16(4, i->pct_transported[0] * 100 >> 8);
|
||||
DrawString(4, 28+n*10, STR_INDUSTRYDIR_ITEM, 0);
|
||||
}
|
||||
} else {
|
||||
DrawString(4, 28+n*10, STR_INDUSTRYDIR_ITEM_NOPROD, 0);
|
||||
}
|
||||
p++;
|
||||
if (++n == 16)
|
||||
break;
|
||||
}
|
||||
} break;
|
||||
|
||||
case WE_CLICK:
|
||||
switch(e->click.widget) {
|
||||
case 2: {
|
||||
_industry_sort_order = _industry_sort_order==0 ? 1 : 0;
|
||||
_industry_sort_dirty = true;
|
||||
SetWindowDirty(w);
|
||||
} break;
|
||||
|
||||
case 3: {
|
||||
_industry_sort_order = _industry_sort_order==2 ? 3 : 2;
|
||||
_industry_sort_dirty = true;
|
||||
SetWindowDirty(w);
|
||||
} break;
|
||||
|
||||
case 4: {
|
||||
_industry_sort_order = _industry_sort_order==4 ? 5 : 4;
|
||||
_industry_sort_dirty = true;
|
||||
SetWindowDirty(w);
|
||||
} break;
|
||||
|
||||
case 5: {
|
||||
_industry_sort_order = _industry_sort_order==6 ? 7 : 6;
|
||||
_industry_sort_dirty = true;
|
||||
SetWindowDirty(w);
|
||||
} break;
|
||||
|
||||
case 7: {
|
||||
int y = (e->click.pt.y - 28) / 10;
|
||||
byte p;
|
||||
Industry *c;
|
||||
|
||||
if (!IS_INT_INSIDE(y, 0, 16))
|
||||
return;
|
||||
p = y + w->vscroll.pos;
|
||||
if (p < _num_industry_sort) {
|
||||
c = DEREF_INDUSTRY(_industry_sort[p]);
|
||||
ScrollMainWindowToTile(c->xy);
|
||||
}
|
||||
} break;
|
||||
}
|
||||
break;
|
||||
|
||||
case WE_4:
|
||||
SetWindowDirty(w);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Industry List */
|
||||
static const WindowDesc _industry_directory_desc = {
|
||||
-1, -1, 508, 190,
|
||||
WC_INDUSTRY_DIRECTORY,0,
|
||||
WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS,
|
||||
_industry_directory_widgets,
|
||||
IndustryDirectoryWndProc
|
||||
};
|
||||
|
||||
|
||||
|
||||
void ShowIndustryDirectory()
|
||||
{
|
||||
/* Industry List */
|
||||
Window *w;
|
||||
|
||||
w = AllocateWindowDescFront(&_industry_directory_desc, 0);
|
||||
if (w) {
|
||||
w->vscroll.cap = 16;
|
||||
SetWindowDirty(w);
|
||||
}
|
||||
}
|
|
@ -1,291 +0,0 @@
|
|||
#include "stdafx.h"
|
||||
#include "ttd.h"
|
||||
|
||||
#include "window.h"
|
||||
#include "gui.h"
|
||||
#include "viewport.h"
|
||||
#include "gfx.h"
|
||||
#include "player.h"
|
||||
#include "command.h"
|
||||
#include "console.h"
|
||||
|
||||
extern void MakeNewGame();
|
||||
extern void StartScenario();
|
||||
|
||||
/*
|
||||
static void ShowSelectTutorialWindow()
|
||||
{
|
||||
}
|
||||
*/
|
||||
|
||||
static const Widget _select_game_widgets[] = {
|
||||
{ WWT_CAPTION, 13, 0, 335, 0, 13, STR_0307_OPENTTD, STR_NULL},
|
||||
{ WWT_IMGBTN, 13, 0, 335, 14, 196, 0x0, STR_NULL},
|
||||
{ WWT_PUSHTXTBTN, 12, 10, 167, 22, 33, STR_0140_NEW_GAME, STR_02FB_START_A_NEW_GAME},
|
||||
{ WWT_PUSHTXTBTN, 12, 168, 325, 22, 33, STR_0141_LOAD_GAME, STR_02FC_LOAD_A_SAVED_GAME_FROM},
|
||||
//{ WWT_PUSHTXTBTN, 12, 10, 167, 177, 188, STR_0142_TUTORIAL_DEMONSTRATION, STR_02FD_VIEW_DEMONSTRATIONS_TUTORIALS},
|
||||
{ WWT_PUSHTXTBTN, 12, 10, 167, 177, 188, STR_CONFIG_PATCHES, STR_CONFIG_PATCHES_TIP},
|
||||
{ WWT_PUSHTXTBTN, 12, 10, 167, 40, 51, STR_0220_CREATE_SCENARIO,STR_02FE_CREATE_A_CUSTOMIZED_GAME},
|
||||
{ WWT_PUSHTXTBTN, 12, 10, 167, 136, 147, STR_SINGLE_PLAYER, STR_02FF_SELECT_SINGLE_PLAYER_GAME},
|
||||
{ WWT_PUSHTXTBTN, 12, 168, 325, 136, 147, STR_MULTIPLAYER, STR_0300_SELECT_TWO_PLAYER_GAME},
|
||||
{ WWT_PUSHTXTBTN, 12, 10, 167, 159, 170, STR_0148_GAME_OPTIONS, STR_0301_DISPLAY_GAME_OPTIONS},
|
||||
{ WWT_PUSHTXTBTN, 12, 168, 325, 159, 170, STR_01FE_DIFFICULTY, STR_0302_DISPLAY_DIFFICULTY_OPTIONS},
|
||||
{ WWT_PUSHTXTBTN, 12, 168, 325, 40, 51, STR_029A_PLAY_SCENARIO, STR_0303_START_A_NEW_GAME_USING},
|
||||
{ WWT_PUSHTXTBTN, 12, 168, 325, 177, 188, STR_0304_QUIT, STR_0305_LEAVE_OPENTTD},
|
||||
{ WWT_PANEL_2, 12, 10, 85, 69, 122, 0x1312, STR_030E_SELECT_TEMPERATE_LANDSCAPE},
|
||||
{ WWT_PANEL_2, 12, 90, 165, 69, 122, 0x1314, STR_030F_SELECT_SUB_ARCTIC_LANDSCAPE},
|
||||
{ WWT_PANEL_2, 12, 170, 245, 69, 122, 0x1316, STR_0310_SELECT_SUB_TROPICAL_LANDSCAPE},
|
||||
{ WWT_PANEL_2, 12, 250, 325, 69, 122, 0x1318, STR_0311_SELECT_TOYLAND_LANDSCAPE},
|
||||
{ WIDGETS_END},
|
||||
};
|
||||
|
||||
static void SelectGameWndProc(Window *w, WindowEvent *e) {
|
||||
switch(e->event) {
|
||||
case WE_PAINT:
|
||||
w->click_state = (w->click_state & ~(0xC0) & ~(0xF << 12)) | (1 << (_new_opt.landscape+12)) | (!_networking?(1<<6):(1<<7));
|
||||
w->disabled_state = _networking ? 0x30 : 0;
|
||||
SET_DPARAM16(0, STR_6801_EASY + _new_opt.diff_level);
|
||||
DrawWindowWidgets(w);
|
||||
break;
|
||||
|
||||
case WE_CLICK:
|
||||
switch(e->click.widget) {
|
||||
case 2: DoCommandP(0, 0, 0, NULL, CMD_START_NEW_GAME); break;
|
||||
case 3: ShowSaveLoadDialog(SLD_LOAD_GAME); break;
|
||||
case 4: ShowPatchesSelection(); break;
|
||||
case 5: DoCommandP(0, InteractiveRandom(), 0, NULL, CMD_CREATE_SCENARIO); break;
|
||||
case 6:
|
||||
if (_networking)
|
||||
DoCommandP(0, 0, 0, NULL, CMD_SET_SINGLE_PLAYER);
|
||||
break;
|
||||
case 7:
|
||||
if (!_network_available) {
|
||||
ShowErrorMessage(-1,STR_NETWORK_ERR_NOTAVAILABLE, 0, 0);
|
||||
} else {
|
||||
ShowNetworkGameWindow();
|
||||
ShowErrorMessage(-1, TEMP_STRING_NO_NETWORK, 0, 0);
|
||||
}
|
||||
break;
|
||||
case 8: ShowGameOptions(); break;
|
||||
case 9: ShowGameDifficulty(); break;
|
||||
case 10:ShowSaveLoadDialog(SLD_LOAD_SCENARIO); break;
|
||||
case 11:AskExitGame(); break;
|
||||
case 12: case 13: case 14: case 15:
|
||||
DoCommandP(0, e->click.widget - 12, 0, NULL, CMD_SET_NEW_LANDSCAPE_TYPE);
|
||||
break;
|
||||
}
|
||||
case WE_KEYPRESS:
|
||||
switch(e->keypress.keycode) {
|
||||
case WKC_BACKQUOTE: IConsoleSwitch(); break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static const WindowDesc _select_game_desc = {
|
||||
WDP_CENTER, WDP_CENTER, 336, 197,
|
||||
WC_SELECT_GAME,0,
|
||||
WDF_STD_TOOLTIPS | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS,
|
||||
_select_game_widgets,
|
||||
SelectGameWndProc
|
||||
};
|
||||
|
||||
void ShowSelectGameWindow()
|
||||
{
|
||||
AllocateWindowDesc(&_select_game_desc);
|
||||
}
|
||||
|
||||
|
||||
// p1 = mode
|
||||
// 0 - start new game
|
||||
// 1 - close new game dialog
|
||||
|
||||
int32 CmdStartNewGame(int x, int y, uint32 flags, uint32 p1, uint32 p2)
|
||||
{
|
||||
if (!(flags & DC_EXEC))
|
||||
return 0;
|
||||
|
||||
switch(p1) {
|
||||
case 0: // show select game window
|
||||
AskForNewGameToStart();
|
||||
break;
|
||||
case 1: // close select game window
|
||||
DeleteWindowById(WC_SAVELOAD, 0);
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32 CmdGenRandomNewGame(int x, int y, uint32 flags, uint32 p1, uint32 p2)
|
||||
{
|
||||
if (!(flags & DC_EXEC))
|
||||
return 0;
|
||||
|
||||
// this forces stuff into test mode.
|
||||
_docommand_recursive = 0;
|
||||
|
||||
_random_seeds[0][0] = p1;
|
||||
_random_seeds[0][1] = p2;
|
||||
|
||||
if (_networking) { NetworkStartSync(true); }
|
||||
|
||||
MakeNewGame();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32 CmdLoadGame(int x, int y, uint32 flags, uint32 p1, uint32 p2)
|
||||
{
|
||||
if (!(flags & DC_EXEC))
|
||||
return 0;
|
||||
|
||||
// ShowSaveLoadDialog(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32 CmdCreateScenario(int x, int y, uint32 flags, uint32 p1, uint32 p2)
|
||||
{
|
||||
if (!(flags & DC_EXEC))
|
||||
return 0;
|
||||
|
||||
_switch_mode = SM_EDITOR;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32 CmdSetSinglePlayer(int x, int y, uint32 flags, uint32 p1, uint32 p2)
|
||||
{
|
||||
printf("CmdSetSinglePlayer\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32 CmdStartScenario(int x, int y, uint32 flags, uint32 p1, uint32 p2)
|
||||
{
|
||||
if (!(flags & DC_EXEC))
|
||||
return 0;
|
||||
|
||||
// this forces stuff into test mode.
|
||||
_docommand_recursive = 0;
|
||||
|
||||
_random_seeds[0][0] = p1;
|
||||
_random_seeds[0][1] = p2;
|
||||
|
||||
if (_networking) { NetworkStartSync(true); }
|
||||
|
||||
StartScenario();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static const Widget _ask_abandon_game_widgets[] = {
|
||||
{ WWT_TEXTBTN, 4, 0, 10, 0, 13, STR_00C5, STR_NULL},
|
||||
{ WWT_CAPTION, 4, 11, 179, 0, 13, STR_00C7_QUIT, STR_NULL},
|
||||
{ WWT_IMGBTN, 4, 0, 179, 14, 91, 0x0, STR_NULL},
|
||||
{ WWT_TEXTBTN, 12, 25, 84, 72, 83, STR_00C9_NO, STR_NULL},
|
||||
{ WWT_TEXTBTN, 12, 95, 154, 72, 83, STR_00C8_YES, STR_NULL},
|
||||
{ WIDGETS_END},
|
||||
};
|
||||
|
||||
static void AskAbandonGameWndProc(Window *w, WindowEvent *e) {
|
||||
switch(e->event) {
|
||||
case WE_PAINT:
|
||||
DrawWindowWidgets(w);
|
||||
#if defined(_WIN32)
|
||||
SET_DPARAM16(0, STR_0133_WINDOWS);
|
||||
#elif defined(__APPLE__)
|
||||
SET_DPARAM16(0, STR_0135_OSX);
|
||||
#elif defined(__BEOS__)
|
||||
SET_DPARAM16(0, STR_OSNAME_BEOS);
|
||||
#elif defined(__MORPHOS__)
|
||||
SET_DPARAM16(0, STR_OSNAME_MORPHOS);
|
||||
#else
|
||||
SET_DPARAM16(0, STR_0134_UNIX);
|
||||
#endif
|
||||
DrawStringMultiCenter(0x5A, 0x26, STR_00CA_ARE_YOU_SURE_YOU_WANT_TO, 178);
|
||||
return;
|
||||
|
||||
case WE_CLICK:
|
||||
switch(e->click.widget) {
|
||||
case 3:
|
||||
DeleteWindow(w);
|
||||
break;
|
||||
case 4:
|
||||
_exit_game = true;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case WE_KEYPRESS: /* Exit game on pressing 'Enter' */
|
||||
if (e->keypress.keycode == WKC_RETURN)
|
||||
_exit_game = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static const WindowDesc _ask_abandon_game_desc = {
|
||||
WDP_CENTER, WDP_CENTER, 180, 92,
|
||||
WC_ASK_ABANDON_GAME,0,
|
||||
WDF_STD_TOOLTIPS | WDF_DEF_WIDGET | WDF_STD_BTN | WDF_UNCLICK_BUTTONS,
|
||||
_ask_abandon_game_widgets,
|
||||
AskAbandonGameWndProc
|
||||
};
|
||||
|
||||
void AskExitGame()
|
||||
{
|
||||
AllocateWindowDescFront(&_ask_abandon_game_desc, 0);
|
||||
}
|
||||
|
||||
|
||||
static const Widget _ask_quit_game_widgets[] = {
|
||||
{ WWT_TEXTBTN, 4, 0, 10, 0, 13, STR_00C5, STR_NULL},
|
||||
{ WWT_CAPTION, 4, 11, 179, 0, 13, STR_0161_QUIT_GAME, STR_NULL},
|
||||
{ WWT_IMGBTN, 4, 0, 179, 14, 91, 0x0, STR_NULL},
|
||||
{ WWT_TEXTBTN, 12, 25, 84, 72, 83, STR_00C9_NO, STR_NULL},
|
||||
{ WWT_TEXTBTN, 12, 95, 154, 72, 83, STR_00C8_YES, STR_NULL},
|
||||
{ WIDGETS_END},
|
||||
};
|
||||
|
||||
static void AskQuitGameWndProc(Window *w, WindowEvent *e) {
|
||||
switch(e->event) {
|
||||
case WE_PAINT:
|
||||
DrawWindowWidgets(w);
|
||||
DrawStringMultiCenter(0x5A, 0x26,
|
||||
_game_mode != GM_EDITOR ? STR_0160_ARE_YOU_SURE_YOU_WANT_TO :
|
||||
STR_029B_ARE_YOU_SURE_YOU_WANT_TO,
|
||||
178);
|
||||
return;
|
||||
|
||||
case WE_CLICK:
|
||||
switch(e->click.widget) {
|
||||
case 3:
|
||||
DeleteWindow(w);
|
||||
break;
|
||||
case 4:
|
||||
_switch_mode = SM_MENU;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static const WindowDesc _ask_quit_game_desc = {
|
||||
WDP_CENTER, WDP_CENTER, 180, 92,
|
||||
WC_QUIT_GAME,0,
|
||||
WDF_STD_TOOLTIPS | WDF_DEF_WIDGET | WDF_STD_BTN | WDF_UNCLICK_BUTTONS,
|
||||
_ask_quit_game_widgets,
|
||||
AskQuitGameWndProc
|
||||
};
|
||||
|
||||
|
||||
void AskExitToGameMenu()
|
||||
{
|
||||
AllocateWindowDescFront(&_ask_quit_game_desc, 0);
|
||||
}
|
||||
|
||||
int32 CmdSetNewLandscapeType(int x, int y, uint32 flags, uint32 p1, uint32 p2)
|
||||
{
|
||||
if (flags & DC_EXEC) {
|
||||
// XXX: some stuff
|
||||
_new_opt.landscape = p1;
|
||||
InvalidateWindowClasses(WC_SELECT_GAME);
|
||||
}
|
||||
return 0;
|
||||
}
|
|
@ -1,767 +0,0 @@
|
|||
#include "stdafx.h"
|
||||
#include "ttd.h"
|
||||
#include <stdarg.h>
|
||||
#include "gfx.h"
|
||||
#include "viewport.h"
|
||||
#include "command.h"
|
||||
#include "vehicle.h"
|
||||
|
||||
byte _map_type_and_height[TILES_X * TILES_Y];
|
||||
byte _map5[TILES_X * TILES_Y];
|
||||
byte _map3_lo[TILES_X * TILES_Y];
|
||||
byte _map3_hi[TILES_X * TILES_Y];
|
||||
byte _map_owner[TILES_X * TILES_Y];
|
||||
byte _map2[TILES_X * TILES_Y];
|
||||
byte _map_extra_bits[TILES_X * TILES_Y/4];
|
||||
|
||||
extern const TileTypeProcs
|
||||
_tile_type_clear_procs,
|
||||
_tile_type_rail_procs,
|
||||
_tile_type_road_procs,
|
||||
_tile_type_town_procs,
|
||||
_tile_type_trees_procs,
|
||||
_tile_type_station_procs,
|
||||
_tile_type_water_procs,
|
||||
_tile_type_dummy_procs,
|
||||
_tile_type_industry_procs,
|
||||
_tile_type_tunnelbridge_procs,
|
||||
_tile_type_unmovable_procs;
|
||||
|
||||
const TileTypeProcs * const _tile_type_procs[16] = {
|
||||
&_tile_type_clear_procs,
|
||||
&_tile_type_rail_procs,
|
||||
&_tile_type_road_procs,
|
||||
&_tile_type_town_procs,
|
||||
&_tile_type_trees_procs,
|
||||
&_tile_type_station_procs,
|
||||
&_tile_type_water_procs,
|
||||
&_tile_type_dummy_procs,
|
||||
&_tile_type_industry_procs,
|
||||
&_tile_type_tunnelbridge_procs,
|
||||
&_tile_type_unmovable_procs,
|
||||
};
|
||||
|
||||
/* landscape slope => sprite */
|
||||
const byte _tileh_to_sprite[32] = {
|
||||
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,0,
|
||||
0,0,0,0,0,0,0,16,0,0,0,17,0,15,18,0,
|
||||
};
|
||||
|
||||
uint GetTileSlope(uint tile, int *h)
|
||||
{
|
||||
uint a,b,c,d,min;
|
||||
int r;
|
||||
|
||||
if (GET_TILE_X(tile) == TILE_X_MAX || GET_TILE_Y(tile) == TILE_Y_MAX) {
|
||||
if (h)
|
||||
*h = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
assert(tile < TILES_X * TILES_Y && GET_TILE_X(tile) != TILE_X_MAX && GET_TILE_Y(tile) != TILE_Y_MAX);
|
||||
|
||||
min = a = _map_type_and_height[tile] & 0xF;
|
||||
b = _map_type_and_height[tile+TILE_XY(1,0)] & 0xF;
|
||||
if (min >= b) min = b;
|
||||
c = _map_type_and_height[tile+TILE_XY(0,1)] & 0xF;
|
||||
if (min >= c) min = c;
|
||||
d = _map_type_and_height[tile+TILE_XY(1,1)] & 0xF;
|
||||
if (min >= d) min = d;
|
||||
|
||||
r = 0;
|
||||
if ((a-=min)!=0) { r += (--a << 4) + 8; }
|
||||
if ((c-=min)!=0) { r += (--c << 4) + 4; }
|
||||
if ((d-=min)!=0) { r += (--d << 4) + 2; }
|
||||
if ((b-=min)!=0) { r += (--b << 4) + 1; }
|
||||
|
||||
if (h != 0)
|
||||
*h = min * 8;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
int GetTileZ(uint tile)
|
||||
{
|
||||
int h;
|
||||
GetTileSlope(tile, &h);
|
||||
return h;
|
||||
}
|
||||
|
||||
void FindLandscapeHeightByTile(TileInfo *ti, uint tile)
|
||||
{
|
||||
if (GET_TILE_X(tile) == TILE_X_MAX ||
|
||||
GET_TILE_Y(tile) == TILE_Y_MAX) {
|
||||
ti->tileh = 0;
|
||||
ti->type = MP_STRANGE;
|
||||
ti->tile = 0;
|
||||
ti->map5 = 0;
|
||||
ti->z = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
ti->tile = tile;
|
||||
ti->map5 = _map5[tile];
|
||||
ti->type = GET_TILETYPE(tile);
|
||||
ti->tileh = GetTileSlope(tile, &ti->z);
|
||||
// ti->z = min * 8;
|
||||
}
|
||||
|
||||
/* find the landscape height for the coordinates x y */
|
||||
void FindLandscapeHeight(TileInfo *ti, uint x, uint y)
|
||||
{
|
||||
int tile;
|
||||
|
||||
ti->x = x;
|
||||
ti->y = y;
|
||||
|
||||
if (x >= TILE_X_MAX*16-1 || y >= TILE_Y_MAX*16-1) {
|
||||
ti->tileh = 0;
|
||||
ti->type = MP_STRANGE;
|
||||
ti->tile = 0;
|
||||
ti->map5 = 0;
|
||||
ti->z = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
tile = TILE_FROM_XY(x,y);
|
||||
FindLandscapeHeightByTile(ti, tile);
|
||||
}
|
||||
|
||||
uint GetPartialZ(int x, int y, int corners)
|
||||
{
|
||||
int z = 0;
|
||||
|
||||
switch(corners) {
|
||||
case 1:
|
||||
if (x - y >= 0)
|
||||
z = (x - y) >> 1;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
y^=0xF;
|
||||
if ( (x - y) >= 0)
|
||||
z = (x - y) >> 1;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
z = (x>>1) + 1;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
if (y - x >= 0)
|
||||
z = (y - x) >> 1;
|
||||
break;
|
||||
|
||||
case 5:
|
||||
case 10:
|
||||
case 15:
|
||||
z = 4;
|
||||
break;
|
||||
|
||||
case 6:
|
||||
z = (y>>1) + 1;
|
||||
break;
|
||||
|
||||
case 7:
|
||||
z = 8;
|
||||
y^=0xF;
|
||||
if (x - y < 0)
|
||||
z += (x - y) >> 1;
|
||||
break;
|
||||
|
||||
case 8:
|
||||
y ^= 0xF;
|
||||
if (y - x >= 0)
|
||||
z = (y - x) >> 1;
|
||||
break;
|
||||
|
||||
case 9:
|
||||
z = (y^0xF)>>1;
|
||||
break;
|
||||
|
||||
case 11:
|
||||
z = 8;
|
||||
if (x - y < 0)
|
||||
z += (x - y) >> 1;
|
||||
break;
|
||||
|
||||
case 12:
|
||||
z = (x^0xF)>>1;
|
||||
break;
|
||||
|
||||
case 13:
|
||||
z = 8;
|
||||
y ^= 0xF;
|
||||
if (y - x < 0)
|
||||
z += (y - x) >> 1;
|
||||
break;
|
||||
|
||||
case 14:
|
||||
z = 8;
|
||||
if (y - x < 0)
|
||||
z += (y - x) >> 1;
|
||||
break;
|
||||
|
||||
case 23:
|
||||
z = 1 + ((x+y)>>1);
|
||||
break;
|
||||
|
||||
case 27:
|
||||
z = 1 + ((x+(y^0xF))>>1);
|
||||
break;
|
||||
|
||||
case 29:
|
||||
z = 1 + (((x^0xF)+(y^0xF))>>1);
|
||||
break;
|
||||
|
||||
case 30:
|
||||
z = 1 + (((x^0xF)+(y^0xF))>>1);
|
||||
break;
|
||||
}
|
||||
|
||||
return z;
|
||||
}
|
||||
|
||||
uint GetSlopeZ(int x, int y)
|
||||
{
|
||||
TileInfo ti;
|
||||
// int z;
|
||||
|
||||
FindLandscapeHeight(&ti, x, y);
|
||||
|
||||
/*
|
||||
z = ti.z;
|
||||
x &= 0xF;
|
||||
y &= 0xF;
|
||||
|
||||
|
||||
assert(z < 256);
|
||||
*/
|
||||
return _tile_type_procs[ti.type]->get_slope_z_proc(&ti);
|
||||
}
|
||||
|
||||
// direction=true: check for foundation in east and south corner
|
||||
// direction=false: check for foundation in west and south corner
|
||||
bool hasFoundation(TileInfo *ti, bool direction)
|
||||
{
|
||||
bool south, other; // southern corner and east/west corner
|
||||
uint slope = _tile_type_procs[ti->type]->get_slope_tileh_proc(ti);
|
||||
uint tileh = ti->tileh;
|
||||
|
||||
if(slope==0 && slope!=tileh) tileh=15;
|
||||
south = (tileh & 2) != (slope & 2);
|
||||
|
||||
if(direction)
|
||||
other = (tileh & 4) != (slope & 4);
|
||||
else
|
||||
other = (tileh & 1) != (slope & 1);
|
||||
return south || other;
|
||||
|
||||
}
|
||||
|
||||
void DrawFoundation(TileInfo *ti, uint f)
|
||||
{
|
||||
uint32 sprite_base = SPR_SLOPES_BASE-14;
|
||||
|
||||
TileInfo ti2;
|
||||
FindLandscapeHeight(&ti2, ti->x, ti->y-1);
|
||||
if(hasFoundation( &ti2, true )) sprite_base += 22; // foundation in NW direction
|
||||
FindLandscapeHeight(&ti2, ti->x-1, ti->y);
|
||||
if(hasFoundation( &ti2, false )) sprite_base += 22*2; // foundation in NE direction
|
||||
|
||||
if (f < 15) {
|
||||
// leveled foundation
|
||||
if( sprite_base < SPR_SLOPES_BASE ) sprite_base = 990; // use original slope sprites
|
||||
|
||||
AddSortableSpriteToDraw(f-1 + sprite_base, ti->x, ti->y, 16, 16, 7, ti->z);
|
||||
ti->z += 8;
|
||||
ti->tileh = 0;
|
||||
OffsetGroundSprite(31, 1);
|
||||
} else {
|
||||
// inclined foundation
|
||||
sprite_base += 14;
|
||||
|
||||
AddSortableSpriteToDraw(
|
||||
HASBIT( (1<<1) | (1<<2) | (1<<4) | (1<<8), ti->tileh) ? sprite_base + (f - 15) : ti->tileh + 0x3DE - 1,
|
||||
ti->x, ti->y, 1, 1, 1, ti->z
|
||||
);
|
||||
|
||||
ti->tileh = _inclined_tileh[f - 15];
|
||||
OffsetGroundSprite(31, 9);
|
||||
}
|
||||
}
|
||||
|
||||
void DoClearSquare(uint tile)
|
||||
{
|
||||
ModifyTile(tile,
|
||||
MP_SETTYPE(MP_CLEAR) |
|
||||
MP_MAP2_CLEAR | MP_MAP3LO_CLEAR | MP_MAP3HI_CLEAR | MP_MAPOWNER | MP_MAP5,
|
||||
OWNER_NONE, /* map_owner */
|
||||
_generating_world ? 3 : 0 /* map5 */
|
||||
);
|
||||
}
|
||||
|
||||
uint32 GetTileTrackStatus(uint tile, TransportType mode)
|
||||
{
|
||||
return _tile_type_procs[GET_TILETYPE(tile)]->get_tile_track_status_proc(tile, mode);
|
||||
}
|
||||
|
||||
void ChangeTileOwner(uint tile, byte old_player, byte new_player)
|
||||
{
|
||||
_tile_type_procs[GET_TILETYPE(tile)]->change_tile_owner_proc(tile, old_player, new_player);
|
||||
}
|
||||
|
||||
void GetAcceptedCargo(uint tile, AcceptedCargo *ac)
|
||||
{
|
||||
memset(ac, 0, sizeof(AcceptedCargo));
|
||||
_tile_type_procs[GET_TILETYPE(tile)]->get_accepted_cargo_proc(tile, ac);
|
||||
}
|
||||
|
||||
void AnimateTile(uint tile)
|
||||
{
|
||||
_tile_type_procs[GET_TILETYPE(tile)]->animate_tile_proc(tile);
|
||||
}
|
||||
|
||||
void ClickTile(uint tile)
|
||||
{
|
||||
_tile_type_procs[GET_TILETYPE(tile)]->click_tile_proc(tile);
|
||||
}
|
||||
|
||||
void DrawTile(TileInfo *ti)
|
||||
{
|
||||
_tile_type_procs[ti->type]->draw_tile_proc(ti);
|
||||
}
|
||||
|
||||
void GetTileDesc(uint tile, TileDesc *td)
|
||||
{
|
||||
_tile_type_procs[GET_TILETYPE(tile)]->get_tile_desc_proc(tile, td);
|
||||
}
|
||||
|
||||
/* Clear a piece of landscape
|
||||
* p1 = 0,
|
||||
* p2 = 0
|
||||
*/
|
||||
|
||||
int32 CmdLandscapeClear(int x, int y, uint32 flags, uint32 p1, uint32 p2)
|
||||
{
|
||||
uint tile;
|
||||
SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
|
||||
|
||||
tile = TILE_FROM_XY(x,y);
|
||||
return _tile_type_procs[GET_TILETYPE(tile)]->clear_tile_proc(tile, flags);
|
||||
}
|
||||
|
||||
// p1 = end tile
|
||||
int32 CmdClearArea(int ex, int ey, uint32 flags, uint32 p1, uint32 p2)
|
||||
{
|
||||
int32 cost,ret, money;
|
||||
int sx,sy;
|
||||
int x,y;
|
||||
bool success = false;
|
||||
|
||||
// make sure sx,sy are smaller than ex,ey
|
||||
sx = GET_TILE_X(p1)*16;
|
||||
sy = GET_TILE_Y(p1)*16;
|
||||
if (ex < sx) intswap(ex, sx);
|
||||
if (ey < sy) intswap(ey, sy);
|
||||
|
||||
money = GetAvailableMoneyForCommand();
|
||||
cost = 0;
|
||||
|
||||
for(x=sx; x<=ex; x+=16) {
|
||||
for(y=sy; y<=ey; y+=16) {
|
||||
ret = DoCommandByTile(TILE_FROM_XY(x,y), 0, 0, flags &~DC_EXEC, CMD_LANDSCAPE_CLEAR);
|
||||
if (ret == CMD_ERROR) continue;
|
||||
cost += ret;
|
||||
success = true;
|
||||
|
||||
if (flags & DC_EXEC) {
|
||||
if ( ret>0 && (money -= ret) < 0) {
|
||||
_additional_cash_required = ret;
|
||||
return cost - ret;
|
||||
}
|
||||
DoCommandByTile(TILE_FROM_XY(x,y), 0, 0, flags, CMD_LANDSCAPE_CLEAR);
|
||||
|
||||
// draw explosion animation...
|
||||
if ((x==sx || x==ex) && (y==sy || y==ey)) {
|
||||
// big explosion in each corner, or small explosion for single tiles
|
||||
CreateEffectVehicleAbove(x + 8,y + 8, 2, sy==ey && sx==ex ? EV_DEMOLISH : EV_CRASHED_SMOKE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!success)
|
||||
cost = CMD_ERROR;
|
||||
return cost;
|
||||
}
|
||||
|
||||
|
||||
/* utility function used to modify a tile */
|
||||
void CDECL ModifyTile(uint tile, uint flags, ...)
|
||||
{
|
||||
va_list va;
|
||||
int i;
|
||||
|
||||
va_start(va, flags);
|
||||
|
||||
if ((i = (flags >> 8) & 0xF) != 0) {
|
||||
_map_type_and_height[tile] = (_map_type_and_height[tile]&~0xF0)|((i-1) << 4);
|
||||
}
|
||||
|
||||
if (flags & (MP_MAP2_CLEAR | MP_MAP2)) {
|
||||
int x = 0;
|
||||
if (flags & MP_MAP2) x = va_arg(va, int);
|
||||
_map2[tile] = x;
|
||||
}
|
||||
|
||||
if (flags & (MP_MAP3LO_CLEAR | MP_MAP3LO)) {
|
||||
int x = 0;
|
||||
if (flags & MP_MAP3LO) x = va_arg(va, int);
|
||||
_map3_lo[tile] = x;
|
||||
}
|
||||
|
||||
if (flags & (MP_MAP3HI_CLEAR | MP_MAP3HI)) {
|
||||
int x = 0;
|
||||
if (flags & MP_MAP3HI) x = va_arg(va, int);
|
||||
_map3_hi[tile] = x;
|
||||
}
|
||||
|
||||
if (flags & (MP_MAPOWNER|MP_MAPOWNER_CURRENT)) {
|
||||
byte x = _current_player;
|
||||
if (flags & MP_MAPOWNER) x = va_arg(va, int);
|
||||
_map_owner[tile] = x;
|
||||
}
|
||||
|
||||
if (flags & MP_MAP5) {
|
||||
_map5[tile] = va_arg(va, int);
|
||||
}
|
||||
|
||||
va_end(va);
|
||||
|
||||
if (!(flags & MP_NODIRTY))
|
||||
MarkTileDirtyByTile(tile);
|
||||
}
|
||||
|
||||
void SetMapExtraBits(uint tile, byte bits)
|
||||
{
|
||||
_map_extra_bits[tile >> 2] &= ~(3 << ((tile&3)*2));
|
||||
_map_extra_bits[tile >> 2] |= (bits&3) << ((tile&3)*2);
|
||||
}
|
||||
|
||||
uint GetMapExtraBits(uint tile)
|
||||
{
|
||||
return (_map_extra_bits[tile >> 2] >> (tile&3)*2)&3;
|
||||
}
|
||||
|
||||
#define TILELOOP_BITS 4
|
||||
#define TILELOOP_SIZE (1 << TILELOOP_BITS)
|
||||
#define TILELOOP_ASSERTMASK ((TILELOOP_SIZE-1) + ((TILELOOP_SIZE-1) << TILE_X_BITS))
|
||||
#define TILELOOP_CHKMASK (((1 << (TILE_X_BITS - TILELOOP_BITS))-1) << TILELOOP_BITS)
|
||||
|
||||
void RunTileLoop()
|
||||
{
|
||||
uint tile;
|
||||
uint count;
|
||||
|
||||
tile = _cur_tileloop_tile;
|
||||
|
||||
assert( (tile & ~TILELOOP_ASSERTMASK) == 0);
|
||||
count = (TILES_X/TILELOOP_SIZE) * (TILES_Y/TILELOOP_SIZE);
|
||||
do {
|
||||
_tile_type_procs[GET_TILETYPE(tile)]->tile_loop_proc(tile);
|
||||
|
||||
if ( GET_TILE_X(tile) < TILES_X - TILELOOP_SIZE) {
|
||||
tile += TILELOOP_SIZE; /* no overflow */
|
||||
} else {
|
||||
tile = TILE_MASK(tile - TILELOOP_SIZE * (TILES_X/TILELOOP_SIZE-1) + TILE_XY(0, TILELOOP_SIZE)); /* x would overflow, also increase y */
|
||||
}
|
||||
} while (--count);
|
||||
assert( (tile & ~TILELOOP_ASSERTMASK) == 0);
|
||||
|
||||
tile += 9;
|
||||
if (tile & TILELOOP_CHKMASK)
|
||||
tile = (tile + TILES_X) & TILELOOP_ASSERTMASK;
|
||||
_cur_tileloop_tile = tile;
|
||||
}
|
||||
|
||||
void InitializeLandscape()
|
||||
{
|
||||
int i;
|
||||
|
||||
memset(_map_owner, OWNER_NONE, sizeof(_map_owner));
|
||||
memset(_map2, 0, sizeof(_map2));
|
||||
memset(_map3_lo, 0, sizeof(_map3_lo));
|
||||
memset(_map3_hi, 0, sizeof(_map3_hi));
|
||||
memset(_map_extra_bits, 0, sizeof(_map_extra_bits));
|
||||
memset(_map_type_and_height, MP_WATER << 4, sizeof(_map_type_and_height));
|
||||
|
||||
for(i=0; i!=TILES_Y-1; i++)
|
||||
memset(_map_type_and_height + i*TILES_X, 0, TILES_X-1);
|
||||
|
||||
memset(_map5, 3, sizeof(_map5));
|
||||
}
|
||||
|
||||
void ConvertGroundTilesIntoWaterTiles()
|
||||
{
|
||||
uint tile = 0;
|
||||
int h;
|
||||
|
||||
while(true) {
|
||||
if (IS_TILETYPE(tile, MP_CLEAR) && GetTileSlope(tile, &h) == 0 && h == 0) {
|
||||
_map_type_and_height[tile] = MP_WATER << 4;
|
||||
_map5[tile] = 0;
|
||||
_map_owner[tile] = OWNER_WATER;
|
||||
}
|
||||
tile++;
|
||||
if (GET_TILE_X(tile) == TILE_X_MAX) {
|
||||
tile += TILE_XY(-TILE_X_MAX, 1);
|
||||
if (GET_TILE_Y(tile) == TILE_Y_MAX)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static const byte _genterrain_tbl_1[5] = { 10, 22, 33, 37, 4 };
|
||||
static const byte _genterrain_tbl_2[5] = { 0, 0, 0, 0, 33 };
|
||||
|
||||
static void GenerateTerrain(int type, int flag)
|
||||
{
|
||||
uint32 r;
|
||||
int x,y;
|
||||
int w,h;
|
||||
byte *p,*tile;
|
||||
byte direction;
|
||||
|
||||
r = Random();
|
||||
p = GetSpritePtr((((r >> 24) * _genterrain_tbl_1[type]) >> 8) + _genterrain_tbl_2[type] + 4845);
|
||||
|
||||
x = r & TILE_X_MAX;
|
||||
y = (r >> TILE_X_BITS) & TILE_Y_MAX;
|
||||
|
||||
|
||||
if (x < 2 || y < 2)
|
||||
return;
|
||||
|
||||
direction = (byte)(r >> 22) & 3;
|
||||
w = p[2];
|
||||
h = p[1];
|
||||
if (direction & 1) { w = p[1]; h = p[2]; }
|
||||
p += 8;
|
||||
|
||||
if (flag & 4) {
|
||||
if (!(flag & 2)) {
|
||||
if (!(flag & 1)) {
|
||||
if (x + y > 190)
|
||||
return;
|
||||
} else {
|
||||
if (y < 30 + x)
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if (!(flag & 1)) {
|
||||
if (x + y < 256)
|
||||
return;
|
||||
} else {
|
||||
if (x < 30 + y)
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (x + w >= TILE_X_MAX-1)
|
||||
return;
|
||||
|
||||
if (y + h >= TILE_Y_MAX-1)
|
||||
return;
|
||||
|
||||
tile = &_map_type_and_height[TILE_XY(x,y)];
|
||||
|
||||
if (direction == 0) {
|
||||
do {
|
||||
int w_cur = w;
|
||||
byte *tile_cur = tile;
|
||||
do {
|
||||
if (*p >= *tile_cur) *tile_cur = *p;
|
||||
p++;
|
||||
tile_cur++;
|
||||
} while (--w_cur != 0);
|
||||
tile += TILE_XY(0,1);
|
||||
} while (--h != 0);
|
||||
} else if (direction == 1) {
|
||||
do {
|
||||
int h_cur = h;
|
||||
byte *tile_cur = tile;
|
||||
do {
|
||||
if (*p >= *tile_cur) *tile_cur = *p;
|
||||
p++;
|
||||
tile_cur+=TILE_XY(0,1);
|
||||
} while (--h_cur != 0);
|
||||
tile++;
|
||||
} while (--w != 0);
|
||||
} else if (direction == 2) {
|
||||
tile += w - 1;
|
||||
do {
|
||||
int w_cur = w;
|
||||
byte *tile_cur = tile;
|
||||
do {
|
||||
if (*p >= *tile_cur) *tile_cur = *p;
|
||||
p++;
|
||||
tile_cur--;
|
||||
} while (--w_cur != 0);
|
||||
tile += TILE_XY(0,1);
|
||||
} while (--h != 0);
|
||||
} else {
|
||||
tile += (h - 1) * TILE_XY(0,1);
|
||||
do {
|
||||
int h_cur = h;
|
||||
byte *tile_cur = tile;
|
||||
do {
|
||||
if (*p >= *tile_cur) *tile_cur = *p;
|
||||
p++;
|
||||
tile_cur-=TILE_XY(0,1);
|
||||
} while (--h_cur != 0);
|
||||
tile++;
|
||||
} while (--w != 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#include "table/genland.h"
|
||||
|
||||
static void CreateDesertOrRainForest()
|
||||
{
|
||||
uint tile;
|
||||
const TileIndexDiff *data;
|
||||
byte mt;
|
||||
int i;
|
||||
|
||||
tile = 0;
|
||||
do {
|
||||
data = _make_desert_or_rainforest_data;
|
||||
do {
|
||||
if ((i = *data++) == MDORD_LAST) {
|
||||
SetMapExtraBits(tile, 1);
|
||||
break;
|
||||
}
|
||||
mt = _map_type_and_height[TILE_MASK(tile + i)];
|
||||
} while ((mt & 0xC) == 0 && (mt >> 4) != MP_WATER);
|
||||
} while (++tile != TILES_X*TILES_Y);
|
||||
|
||||
for(i=0; i!=256; i++)
|
||||
RunTileLoop();
|
||||
|
||||
tile = 0;
|
||||
do {
|
||||
data = _make_desert_or_rainforest_data;
|
||||
do {
|
||||
if ((i = *data++) == MDORD_LAST) {
|
||||
SetMapExtraBits(tile, 2);
|
||||
break;
|
||||
}
|
||||
} while ( !IS_TILETYPE(TILE_MASK(tile+i), MP_CLEAR) || (_map5[TILE_MASK(tile + i)]&0x1C) != 0x14);
|
||||
} while (++tile != TILES_X*TILES_Y);
|
||||
}
|
||||
|
||||
void GenerateLandscape()
|
||||
{
|
||||
int i,flag;
|
||||
uint32 r;
|
||||
|
||||
if (_opt.landscape == LT_HILLY) {
|
||||
i = ((Random() & 0x7F) + 950) * LANDSCAPE_SIZE_FACTOR;
|
||||
do {
|
||||
GenerateTerrain(2, 0);
|
||||
} while (--i);
|
||||
|
||||
r = Random();
|
||||
flag = (r & 3) | 4;
|
||||
i = (((r >> 16) & 0x7F) + 450) * LANDSCAPE_SIZE_FACTOR;
|
||||
do {
|
||||
GenerateTerrain(4, flag);
|
||||
} while (--i);
|
||||
} else if (_opt.landscape == LT_DESERT) {
|
||||
i = ((Random()&0x7F) + 170) * LANDSCAPE_SIZE_FACTOR;
|
||||
do {
|
||||
GenerateTerrain(0, 0);
|
||||
} while (--i);
|
||||
|
||||
r = Random();
|
||||
flag = (r & 3) | 4;
|
||||
i = (((r >> 16) & 0xFF) + 1700) * LANDSCAPE_SIZE_FACTOR;
|
||||
do {
|
||||
GenerateTerrain(0, flag);
|
||||
} while (--i);
|
||||
|
||||
flag ^= 2;
|
||||
|
||||
i = ((Random() & 0x7F) + 410) * LANDSCAPE_SIZE_FACTOR;
|
||||
do {
|
||||
GenerateTerrain(3, flag);
|
||||
} while (--i);
|
||||
} else {
|
||||
i = ((Random() & 0x7F) + (3 - _opt.diff.quantity_sea_lakes)*256 + 100) * LANDSCAPE_SIZE_FACTOR;
|
||||
do {
|
||||
GenerateTerrain(_opt.diff.terrain_type, 0);
|
||||
} while (--i);
|
||||
}
|
||||
|
||||
ConvertGroundTilesIntoWaterTiles();
|
||||
|
||||
if (_opt.landscape == LT_DESERT)
|
||||
CreateDesertOrRainForest();
|
||||
}
|
||||
|
||||
void OnTick_Town();
|
||||
void OnTick_Trees();
|
||||
void OnTick_Station();
|
||||
void OnTick_Industry();
|
||||
|
||||
void OnTick_Players();
|
||||
void OnTick_Train();
|
||||
|
||||
void CallLandscapeTick()
|
||||
{
|
||||
OnTick_Town();
|
||||
OnTick_Trees();
|
||||
OnTick_Station();
|
||||
OnTick_Industry();
|
||||
|
||||
OnTick_Players();
|
||||
OnTick_Train();
|
||||
}
|
||||
|
||||
TileIndex AdjustTileCoordRandomly(TileIndex a, byte rng)
|
||||
{
|
||||
int rn = rng;
|
||||
uint32 r = Random();
|
||||
|
||||
return TILE_XY(
|
||||
GET_TILE_X(a) + ((byte)r * rn * 2 >> 8) - rn,
|
||||
GET_TILE_Y(a) + ((byte)(r>>8) * rn * 2 >> 8) - rn
|
||||
);
|
||||
}
|
||||
|
||||
// This function checks if we add addx/addy to tile, if we
|
||||
// do wrap around the edges. For example, tile = (10,2) and
|
||||
// addx = +3 and addy = -4. This function will now return
|
||||
// TILE_WRAPPED, because the y is wrapped. This is needed in
|
||||
// for example, farmland. When the tile is not wrapped,
|
||||
// the result will be tile + TILE_XY(addx, addy)
|
||||
uint TileAddWrap(TileIndex tile, int addx, int addy)
|
||||
{
|
||||
int x, y;
|
||||
x = GET_TILE_X(tile) + addx;
|
||||
y = GET_TILE_Y(tile) + addy;
|
||||
|
||||
// Are we about to wrap?
|
||||
if (x > 0 && x < TILE_X_MAX && y > 0 && y < TILE_Y_MAX)
|
||||
return tile + TILE_XY(addx, addy);
|
||||
|
||||
return TILE_WRAPPED;
|
||||
}
|
||||
|
||||
bool IsValidTile(uint tile)
|
||||
{
|
||||
return (tile < TILES_X * TILE_Y_MAX && GET_TILE_X(tile) != TILE_X_MAX);
|
||||
}
|
File diff suppressed because it is too large
Load Diff
2592
trunk/lang/czech.txt
2592
trunk/lang/czech.txt
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
2110
trunk/lang/dutch.txt
2110
trunk/lang/dutch.txt
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -1,260 +0,0 @@
|
|||
##name Original vehicle names (ENG)
|
||||
##ownname Original vehicle names (ENG)
|
||||
|
||||
##id 0x8000
|
||||
STR_8000_KIRBY_PAUL_TANK_STEAM :Collett Pannier Tank (Steam)
|
||||
STR_8001_MJS_250_DIESEL :MJS 250 (Diesel)
|
||||
STR_8002_PLODDYPHUT_CHOO_CHOO :Ploddyphut Choo-Choo
|
||||
STR_8003_POWERNAUT_CHOO_CHOO :Powernaut Choo-Choo
|
||||
STR_8004_MIGHTYMOVER_CHOO_CHOO :Mightymover Choo-Choo
|
||||
STR_8005_PLODDYPHUT_DIESEL :Ploddyphut Diesel
|
||||
STR_8006_POWERNAUT_DIESEL :Powernaut Diesel
|
||||
STR_8007_WILLS_2_8_0_STEAM :Wills 2-8-0 (Steam)
|
||||
STR_8008_CHANEY_JUBILEE_STEAM :Stanier 'Jubilee' (Steam)
|
||||
STR_8009_GINZU_A4_STEAM :Gresley 'A4' (Steam)
|
||||
STR_800A_SH_8P_STEAM :BR '8P' (Steam)
|
||||
STR_800B_MANLEY_MOREL_DMU_DIESEL :Metro Cammell DMU (Diesel)
|
||||
STR_800C_DASH_DIESEL :'Sprinter' (Diesel)
|
||||
STR_800D_SH_HENDRY_25_DIESEL :BR/Sulzer '25' (Diesel)
|
||||
STR_800E_UU_37_DIESEL :EE '37'
|
||||
STR_800F_FLOSS_47_DIESEL :Brush '47' (Diesel)
|
||||
STR_8010_CS_4000_DIESEL :CS 4000 (Diesel)
|
||||
STR_8011_CS_2400_DIESEL :CS 2400 (Diesel)
|
||||
STR_8012_CENTENNIAL_DIESEL :Centennial (Diesel)
|
||||
STR_8013_KELLING_3100_DIESEL :Kelling 3100 (Diesel)
|
||||
STR_8014_TURNER_TURBO_DIESEL :Turner Turbo (Diesel)
|
||||
STR_8015_MJS_1000_DIESEL :MJS 1000 (Diesel)
|
||||
STR_8016_SH_125_DIESEL :BR 'IC125' (Diesel)
|
||||
STR_8017_SH_30_ELECTRIC :BR '86' (Electric)
|
||||
STR_8018_SH_40_ELECTRIC :BR '87' (Electric)
|
||||
STR_8019_T_I_M_ELECTRIC :'T.G.V.' (Electric)
|
||||
STR_801A_ASIASTAR_ELECTRIC :'Eurostar' (Electric)
|
||||
STR_801B_PASSENGER_CAR :Passenger Carriage
|
||||
STR_801C_MAIL_VAN :Mail Van
|
||||
STR_801D_COAL_CAR :Coal Truck
|
||||
STR_801E_OIL_TANKER :Oil Tanker
|
||||
STR_801F_LIVESTOCK_VAN :Livestock Van
|
||||
STR_8020_GOODS_VAN :Goods Van
|
||||
STR_8021_GRAIN_HOPPER :Grain Hopper
|
||||
STR_8022_WOOD_TRUCK :Wood Truck
|
||||
STR_8023_IRON_ORE_HOPPER :Iron Ore Hopper
|
||||
STR_8024_STEEL_TRUCK :Steel Truck
|
||||
STR_8025_ARMORED_VAN :Armoured Van
|
||||
STR_8026_FOOD_VAN :Food Van
|
||||
STR_8027_PAPER_TRUCK :Paper Truck
|
||||
STR_8028_COPPER_ORE_HOPPER :Copper Ore Hopper
|
||||
STR_8029_WATER_TANKER :Water Tanker
|
||||
STR_802A_FRUIT_TRUCK :Fruit Truck
|
||||
STR_802B_RUBBER_TRUCK :Rubber Truck
|
||||
STR_802C_SUGAR_TRUCK :Sugar Truck
|
||||
STR_802D_COTTON_CANDY_HOPPER :Candyfloss Hopper
|
||||
STR_802E_TOFFEE_HOPPER :Toffee Hopper
|
||||
STR_802F_BUBBLE_VAN :Bubble Van
|
||||
STR_8030_COLA_TANKER :Cola Tanker
|
||||
STR_8031_CANDY_VAN :Sweets Van
|
||||
STR_8032_TOY_VAN :Toy Van
|
||||
STR_8033_BATTERY_TRUCK :Battery Truck
|
||||
STR_8034_FIZZY_DRINK_TRUCK :Fizzy Drink Truck
|
||||
STR_8035_PLASTIC_TRUCK :Plastic Truck
|
||||
STR_8036_X2001_ELECTRIC :'X2001' (Electric)
|
||||
STR_8037_MILLENNIUM_Z1_ELECTRIC :'Millennium Z1' (Electric)
|
||||
STR_8038_WIZZOWOW_Z99 :Wizzowow Z99
|
||||
STR_8039_PASSENGER_CAR :Passenger Carriage
|
||||
STR_803A_MAIL_VAN :Mail Van
|
||||
STR_803B_COAL_CAR :Coal Truck
|
||||
STR_803C_OIL_TANKER :Oil Tanker
|
||||
STR_803D_LIVESTOCK_VAN :Livestock Van
|
||||
STR_803E_GOODS_VAN :Goods Van
|
||||
STR_803F_GRAIN_HOPPER :Grain Hopper
|
||||
STR_8040_WOOD_TRUCK :Wood Truck
|
||||
STR_8041_IRON_ORE_HOPPER :Iron Ore Hopper
|
||||
STR_8042_STEEL_TRUCK :Steel Truck
|
||||
STR_8043_ARMORED_VAN :Armoured Van
|
||||
STR_8044_FOOD_VAN :Food Van
|
||||
STR_8045_PAPER_TRUCK :Paper Truck
|
||||
STR_8046_COPPER_ORE_HOPPER :Copper Ore Hopper
|
||||
STR_8047_WATER_TANKER :Water Tanker
|
||||
STR_8048_FRUIT_TRUCK :Fruit Truck
|
||||
STR_8049_RUBBER_TRUCK :Rubber Truck
|
||||
STR_804A_SUGAR_TRUCK :Sugar Truck
|
||||
STR_804B_COTTON_CANDY_HOPPER :Candyfloss Hopper
|
||||
STR_804C_TOFFEE_HOPPER :Toffee Hopper
|
||||
STR_804D_BUBBLE_VAN :Bubble Van
|
||||
STR_804E_COLA_TANKER :Cola Tanker
|
||||
STR_804F_CANDY_VAN :Sweets Van
|
||||
STR_8050_TOY_VAN :Toy Van
|
||||
STR_8051_BATTERY_TRUCK :Battery Truck
|
||||
STR_8052_FIZZY_DRINK_TRUCK :Fizzy Drink Truck
|
||||
STR_8053_PLASTIC_TRUCK :Plastic Truck
|
||||
STR_8054_LEV1_LEVIATHAN_ELECTRIC :Lev1 'Leviathan' (Electric)
|
||||
STR_8055_LEV2_CYCLOPS_ELECTRIC :Lev2 'Cyclops' (Electric)
|
||||
STR_8056_LEV3_PEGASUS_ELECTRIC :Lev3 'Pegasus' (Electric)
|
||||
STR_8057_LEV4_CHIMAERA_ELECTRIC :Lev4 'Chimaera' (Electric)
|
||||
STR_8058_WIZZOWOW_ROCKETEER :Wizzowow Rocketeer
|
||||
STR_8059_PASSENGER_CAR :Passenger Car
|
||||
STR_805A_MAIL_VAN :Mail Van
|
||||
STR_805B_COAL_CAR :Coal Car
|
||||
STR_805C_OIL_TANKER :Oil Tanker
|
||||
STR_805D_LIVESTOCK_VAN :Livestock Van
|
||||
STR_805E_GOODS_VAN :Goods Van
|
||||
STR_805F_GRAIN_HOPPER :Grain Hopper
|
||||
STR_8060_WOOD_TRUCK :Wood Truck
|
||||
STR_8061_IRON_ORE_HOPPER :Iron Ore Hopper
|
||||
STR_8062_STEEL_TRUCK :Steel Truck
|
||||
STR_8063_ARMORED_VAN :Armored Van
|
||||
STR_8064_FOOD_VAN :Food Van
|
||||
STR_8065_PAPER_TRUCK :Paper Truck
|
||||
STR_8066_COPPER_ORE_HOPPER :Copper Ore Hopper
|
||||
STR_8067_WATER_TANKER :Water Tanker
|
||||
STR_8068_FRUIT_TRUCK :Fruit Truck
|
||||
STR_8069_RUBBER_TRUCK :Rubber Truck
|
||||
STR_806A_SUGAR_TRUCK :Sugar Truck
|
||||
STR_806B_COTTON_CANDY_HOPPER :Candyfloss Hopper
|
||||
STR_806C_TOFFEE_HOPPER :Toffee Hopper
|
||||
STR_806D_BUBBLE_VAN :Bubble Van
|
||||
STR_806E_COLA_TANKER :Cola Tanker
|
||||
STR_806F_CANDY_VAN :Sweets Van
|
||||
STR_8070_TOY_VAN :Toy Van
|
||||
STR_8071_BATTERY_TRUCK :Battery Truck
|
||||
STR_8072_FIZZY_DRINK_TRUCK :Fizzy Drink Truck
|
||||
STR_8073_PLASTIC_TRUCK :Plastic Truck
|
||||
STR_8074_MPS_REGAL_BUS :AEC Regal Bus
|
||||
STR_8075_HEREFORD_LEOPARD_BUS :Leyland Leopard Bus
|
||||
STR_8076_FOSTER_BUS :Volvo Bus
|
||||
STR_8077_FOSTER_MKII_SUPERBUS :Volvo MkII Superbus
|
||||
STR_8078_PLODDYPHUT_MKI_BUS :Ploddyphut MkI Bus
|
||||
STR_8079_PLODDYPHUT_MKII_BUS :Ploddyphut MkII Bus
|
||||
STR_807A_PLODDYPHUT_MKIII_BUS :Ploddyphut MkIII Bus
|
||||
STR_807B_BALOGH_COAL_TRUCK :Bedford Coal Lorry
|
||||
STR_807C_UHL_COAL_TRUCK :Ford Coal Lorry
|
||||
STR_807D_DW_COAL_TRUCK :DW Coal Lorry
|
||||
STR_807E_MPS_MAIL_TRUCK :AEC Mail Truck
|
||||
STR_807F_REYNARD_MAIL_TRUCK :Renault Mail Truck
|
||||
STR_8080_PERRY_MAIL_TRUCK :Perry Mail Truck
|
||||
STR_8081_MIGHTYMOVER_MAIL_TRUCK :MightyMover Mail Truck
|
||||
STR_8082_POWERNAUGHT_MAIL_TRUCK :Powernaught Mail Truck
|
||||
STR_8083_WIZZOWOW_MAIL_TRUCK :Wizzowow Mail Truck
|
||||
STR_8084_WITCOMBE_OIL_TANKER :Scammell Oil Tanker
|
||||
STR_8085_FOSTER_OIL_TANKER :Volvo Oil Tanker
|
||||
STR_8086_PERRY_OIL_TANKER :Perry Oil Tanker
|
||||
STR_8087_TALBOTT_LIVESTOCK_VAN :Dennis Livestock Van
|
||||
STR_8088_UHL_LIVESTOCK_VAN :Ford Livestock Van
|
||||
STR_8089_FOSTER_LIVESTOCK_VAN :Foster Livestock Van
|
||||
STR_808A_BALOGH_GOODS_TRUCK :Bedford Goods Lorry
|
||||
STR_808B_CRAIGHEAD_GOODS_TRUCK :Fiat Goods Lorry
|
||||
STR_808C_GOSS_GOODS_TRUCK :Goss Goods Lorry
|
||||
STR_808D_HEREFORD_GRAIN_TRUCK :Leyland Grain Truck
|
||||
STR_808E_THOMAS_GRAIN_TRUCK :Peugeot Grain Truck
|
||||
STR_808F_GOSS_GRAIN_TRUCK :Goss Grain Truck
|
||||
STR_8090_WITCOMBE_WOOD_TRUCK :Scammell Wood Truck
|
||||
STR_8091_FOSTER_WOOD_TRUCK :Volvo Wood Truck
|
||||
STR_8092_MORELAND_WOOD_TRUCK :Moreland Wood Truck
|
||||
STR_8093_MPS_IRON_ORE_TRUCK :AEC Iron Ore Truck
|
||||
STR_8094_UHL_IRON_ORE_TRUCK :Ford Iron Ore Truck
|
||||
STR_8095_CHIPPY_IRON_ORE_TRUCK :Chippy Iron Ore Truck
|
||||
STR_8096_BALOGH_STEEL_TRUCK :Bedford Steel Truck
|
||||
STR_8097_UHL_STEEL_TRUCK :Ford Steel Truck
|
||||
STR_8098_KELLING_STEEL_TRUCK :Kelling Steel Truck
|
||||
STR_8099_BALOGH_ARMORED_TRUCK :Bedford Armoured Truck
|
||||
STR_809A_UHL_ARMORED_TRUCK :Ford Armoured Truck
|
||||
STR_809B_FOSTER_ARMORED_TRUCK :Foster Armored Truck
|
||||
STR_809C_FOSTER_FOOD_VAN :Foster Food Van
|
||||
STR_809D_PERRY_FOOD_VAN :Perry Food Van
|
||||
STR_809E_CHIPPY_FOOD_VAN :Chippy Food Van
|
||||
STR_809F_UHL_PAPER_TRUCK :Uhl Paper Truck
|
||||
STR_80A0_BALOGH_PAPER_TRUCK :Balogh Paper Truck
|
||||
STR_80A1_MPS_PAPER_TRUCK :MPS Paper Truck
|
||||
STR_80A2_MPS_COPPER_ORE_TRUCK :MPS Copper Ore Truck
|
||||
STR_80A3_UHL_COPPER_ORE_TRUCK :Uhl Copper Ore Truck
|
||||
STR_80A4_GOSS_COPPER_ORE_TRUCK :Goss Copper Ore Truck
|
||||
STR_80A5_UHL_WATER_TANKER :Uhl Water Tanker
|
||||
STR_80A6_BALOGH_WATER_TANKER :Balogh Water Tanker
|
||||
STR_80A7_MPS_WATER_TANKER :MPS Water Tanker
|
||||
STR_80A8_BALOGH_FRUIT_TRUCK :Balogh Fruit Truck
|
||||
STR_80A9_UHL_FRUIT_TRUCK :Uhl Fruit Truck
|
||||
STR_80AA_KELLING_FRUIT_TRUCK :Kelling Fruit Truck
|
||||
STR_80AB_BALOGH_RUBBER_TRUCK :Balogh Rubber Truck
|
||||
STR_80AC_UHL_RUBBER_TRUCK :Uhl Rubber Truck
|
||||
STR_80AD_RMT_RUBBER_TRUCK :RMT Rubber Truck
|
||||
STR_80AE_MIGHTYMOVER_SUGAR_TRUCK :MightyMover Sugar Truck
|
||||
STR_80AF_POWERNAUGHT_SUGAR_TRUCK :Powernaught Sugar Truck
|
||||
STR_80B0_WIZZOWOW_SUGAR_TRUCK :Wizzowow Sugar Truck
|
||||
STR_80B1_MIGHTYMOVER_COLA_TRUCK :MightyMover Cola Truck
|
||||
STR_80B2_POWERNAUGHT_COLA_TRUCK :Powernaught Cola Truck
|
||||
STR_80B3_WIZZOWOW_COLA_TRUCK :Wizzowow Cola Truck
|
||||
STR_80B4_MIGHTYMOVER_COTTON_CANDY :MightyMover Candyfloss Truck
|
||||
STR_80B5_POWERNAUGHT_COTTON_CANDY :Powernaught Candyfloss Truck
|
||||
STR_80B6_WIZZOWOW_COTTON_CANDY_TRUCK :Wizzowow Candyfloss Truck
|
||||
STR_80B7_MIGHTYMOVER_TOFFEE_TRUCK :MightyMover Toffee Truck
|
||||
STR_80B8_POWERNAUGHT_TOFFEE_TRUCK :Powernaught Toffee Truck
|
||||
STR_80B9_WIZZOWOW_TOFFEE_TRUCK :Wizzowow Toffee Truck
|
||||
STR_80BA_MIGHTYMOVER_TOY_VAN :MightyMover Toy Van
|
||||
STR_80BB_POWERNAUGHT_TOY_VAN :Powernaught Toy Van
|
||||
STR_80BC_WIZZOWOW_TOY_VAN :Wizzowow Toy Van
|
||||
STR_80BD_MIGHTYMOVER_CANDY_TRUCK :MightyMover Sweet Lorry
|
||||
STR_80BE_POWERNAUGHT_CANDY_TRUCK :Powernaught Sweet Lorry
|
||||
STR_80BF_WIZZOWOW_CANDY_TRUCK :Wizzowow Sweet Lorry
|
||||
STR_80C0_MIGHTYMOVER_BATTERY_TRUCK :MightyMover Battery Truck
|
||||
STR_80C1_POWERNAUGHT_BATTERY_TRUCK :Powernaught Battery Truck
|
||||
STR_80C2_WIZZOWOW_BATTERY_TRUCK :Wizzowow Battery Truck
|
||||
STR_80C3_MIGHTYMOVER_FIZZY_DRINK :MightyMover Fizzy Drink Truck
|
||||
STR_80C4_POWERNAUGHT_FIZZY_DRINK :Powernaught Fizzy Drink Truck
|
||||
STR_80C5_WIZZOWOW_FIZZY_DRINK_TRUCK :Wizzowow Fizzy Drink Truck
|
||||
STR_80C6_MIGHTYMOVER_PLASTIC_TRUCK :MightyMover Plastic Truck
|
||||
STR_80C7_POWERNAUGHT_PLASTIC_TRUCK :Powernaught Plastic Truck
|
||||
STR_80C8_WIZZOWOW_PLASTIC_TRUCK :Wizzowow Plastic Truck
|
||||
STR_80C9_MIGHTYMOVER_BUBBLE_TRUCK :MightyMover Bubble Truck
|
||||
STR_80CA_POWERNAUGHT_BUBBLE_TRUCK :Powernaught Bubble Truck
|
||||
STR_80CB_WIZZOWOW_BUBBLE_TRUCK :Wizzowow Bubble Truck
|
||||
STR_80CC_MPS_OIL_TANKER :MPS Oil Tanker
|
||||
STR_80CD_CS_INC_OIL_TANKER :CS-Inc. Oil Tanker
|
||||
STR_80CE_MPS_PASSENGER_FERRY :MPS Passenger Ferry
|
||||
STR_80CF_FFP_PASSENGER_FERRY :FFP Passenger Ferry
|
||||
STR_80D0_BAKEWELL_300_HOVERCRAFT :Bakewell 300 Hovercraft
|
||||
STR_80D1_CHUGGER_CHUG_PASSENGER :Chugger-Chug Passenger Ferry
|
||||
STR_80D2_SHIVERSHAKE_PASSENGER_FERRY :Shivershake Passenger Ferry
|
||||
STR_80D3_YATE_CARGO_SHIP :Yate Cargo ship
|
||||
STR_80D4_BAKEWELL_CARGO_SHIP :Bakewell Cargo ship
|
||||
STR_80D5_MIGHTYMOVER_CARGO_SHIP :Mightymover Cargo ship
|
||||
STR_80D6_POWERNAUT_CARGO_SHIP :Powernaut Cargo ship
|
||||
STR_80D7_SAMPSON_U52 :Junkers JU52
|
||||
STR_80D8_COLEMAN_COUNT :Vickers Viscount
|
||||
STR_80D9_FFP_DART :Aërospatiale SE-310 Caravelle
|
||||
STR_80DA_YATE_HAUGAN :BAC-Aërospatiale Concorde
|
||||
STR_80DB_BAKEWELL_COTSWALD_LB_3 :Douglas DC-3 Dakota
|
||||
STR_80DC_BAKEWELL_LUCKETT_LB_8 :McDonnell Douglas DC-8
|
||||
STR_80DD_BAKEWELL_LUCKETT_LB_9 :McDonnell Douglas DC-9
|
||||
STR_80DE_BAKEWELL_LUCKETT_LB80 :McDonnell Douglas MD80
|
||||
STR_80DF_BAKEWELL_LUCKETT_LB_10 :McDonnell Douglas DC-10
|
||||
STR_80E0_BAKEWELL_LUCKETT_LB_11 :McDonnell Douglas MD-11
|
||||
STR_80E1_YATE_AEROSPACE_YAC_1_11 :British Aerospace BAC 1-11
|
||||
STR_80E2_DARWIN_100 :Boeing 727
|
||||
STR_80E3_DARWIN_200 :Boeing 737
|
||||
STR_80E4_DARWIN_300 :Boeing 747
|
||||
STR_80E5_DARWIN_400 :Boeing 757
|
||||
STR_80E6_DARWIN_500 :Boeing 767
|
||||
STR_80E7_DARWIN_600 :Boeing 777
|
||||
STR_80E8_GURU_GALAXY :Lockheed Tristar
|
||||
STR_80E9_AIRTAXI_A21 :Airbus A300
|
||||
STR_80EA_AIRTAXI_A31 :Airbus A310
|
||||
STR_80EB_AIRTAXI_A32 :Airbus A320
|
||||
STR_80EC_AIRTAXI_A33 :Airbus A330
|
||||
STR_80ED_YATE_AEROSPACE_YAE46 :British Aerospace BAe46
|
||||
STR_80EE_DINGER_100 :Fokker 100
|
||||
STR_80EF_AIRTAXI_A34_1000 :AirTaxi A34-1000
|
||||
STR_80F0_YATE_Z_SHUTTLE :Yate Z-Shuttle
|
||||
STR_80F1_KELLING_K1 :Kelling K1
|
||||
STR_80F2_KELLING_K6 :Kelling K6
|
||||
STR_80F3_KELLING_K7 :Kelling K7
|
||||
STR_80F4_DARWIN_700 :Darwin 700
|
||||
STR_80F5_FFP_HYPERDART_2 :FFP Hyperdart 2
|
||||
STR_80F6_DINGER_200 :Dinger 200
|
||||
STR_80F7_DINGER_1000 :Dinger 1000
|
||||
STR_80F8_PLODDYPHUT_100 :Ploddyphut 100
|
||||
STR_80F9_PLODDYPHUT_500 :Ploddyphut 500
|
||||
STR_80FA_FLASHBANG_X1 :Flashbang X1
|
||||
STR_80FB_JUGGERPLANE_M1 :Juggerplane M1
|
||||
STR_80FC_FLASHBANG_WIZZER :Flashbang Wizzer
|
||||
STR_80FD_TRICARIO_HELICOPTER :Sikorsky Helicopter
|
||||
STR_80FE_GURU_X2_HELICOPTER :Guru X2 Helicopter
|
||||
STR_80FF_POWERNAUT_HELICOPTER :Powernaut Helicopter
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
218
trunk/langs.dsp
218
trunk/langs.dsp
|
@ -1,218 +0,0 @@
|
|||
# Microsoft Developer Studio Project File - Name="langs" - Package Owner=<4>
|
||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||
# ** DO NOT EDIT **
|
||||
|
||||
# TARGTYPE "Win32 (x86) Generic Project" 0x010a
|
||||
|
||||
CFG=langs - Win32 Debug
|
||||
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
|
||||
!MESSAGE use the Export Makefile command and run
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "langs.mak".
|
||||
!MESSAGE
|
||||
!MESSAGE You can specify a configuration when running NMAKE
|
||||
!MESSAGE by defining the macro CFG on the command line. For example:
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "langs.mak" CFG="langs - Win32 Debug"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "langs - Win32 Debug" (based on "Win32 (x86) Generic Project")
|
||||
!MESSAGE
|
||||
|
||||
# Begin Project
|
||||
# PROP AllowPerConfigDependencies 0
|
||||
# PROP Scc_ProjName ""
|
||||
# PROP Scc_LocalPath ""
|
||||
MTL=midl.exe
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 1
|
||||
# PROP BASE Output_Dir "langs___Win32_Debug"
|
||||
# PROP BASE Intermediate_Dir "langs___Win32_Debug"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 1
|
||||
# PROP Output_Dir ""
|
||||
# PROP Intermediate_Dir ""
|
||||
# PROP Target_Dir ""
|
||||
# Begin Target
|
||||
|
||||
# Name "langs - Win32 Debug"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\lang\american.txt
|
||||
# Begin Custom Build
|
||||
InputPath=.\lang\american.txt
|
||||
|
||||
"lang\american.lng" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
strgen\debug\strgen.exe lang\american.txt
|
||||
|
||||
# End Custom Build
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\lang\czech.txt
|
||||
# Begin Custom Build
|
||||
InputPath=.\lang\czech.txt
|
||||
|
||||
"lang\czech.lng" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
strgen\debug\strgen.exe lang\czech.txt
|
||||
|
||||
# End Custom Build
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\lang\danish.txt
|
||||
# Begin Custom Build
|
||||
InputPath=.\lang\danish.txt
|
||||
|
||||
"lang\danish.lng" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
strgen\debug\strgen.exe lang\danish.txt
|
||||
|
||||
# End Custom Build
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\lang\dutch.txt
|
||||
# Begin Custom Build
|
||||
InputPath=.\lang\dutch.txt
|
||||
|
||||
"lang\dutch.lng" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
strgen\debug\strgen.exe lang\dutch.txt
|
||||
|
||||
# End Custom Build
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\lang\english.txt
|
||||
# Begin Custom Build
|
||||
InputPath=.\lang\english.txt
|
||||
|
||||
"lang\english.lng" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
strgen\debug\strgen.exe
|
||||
|
||||
# End Custom Build
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\lang\french.txt
|
||||
# Begin Custom Build
|
||||
InputPath=.\lang\french.txt
|
||||
|
||||
"lang\french.lng" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
strgen\debug\strgen.exe lang\french.txt
|
||||
|
||||
# End Custom Build
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\lang\galician.txt
|
||||
# Begin Custom Build
|
||||
InputPath=.\lang\galician.txt
|
||||
|
||||
"lang\galician.lng" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
strgen\debug\strgen.exe lang\galician.txt
|
||||
|
||||
# End Custom Build
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\lang\german.txt
|
||||
# Begin Custom Build
|
||||
InputPath=.\lang\german.txt
|
||||
|
||||
"lang\german.lng" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
strgen\debug\strgen.exe lang\german.txt
|
||||
|
||||
# End Custom Build
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\lang\hungarian.txt
|
||||
# Begin Custom Build
|
||||
InputPath=.\lang\hungarian.txt
|
||||
|
||||
"lang\hungarian.lng" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
strgen\debug\strgen.exe lang\hungarian.txt
|
||||
|
||||
# End Custom Build
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\lang\italian.txt
|
||||
# Begin Custom Build
|
||||
InputPath=.\lang\italian.txt
|
||||
|
||||
"lang\italian.lng" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
strgen\debug\strgen.exe lang\italian.txt
|
||||
|
||||
# End Custom Build
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\lang\norwegian.txt
|
||||
# Begin Custom Build
|
||||
InputPath=.\lang\norwegian.txt
|
||||
|
||||
"lang\norwegian.lng" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
strgen\debug\strgen.exe lang\norwegian.txt
|
||||
|
||||
# End Custom Build
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\lang\origveh.txt
|
||||
# Begin Custom Build
|
||||
InputPath=.\lang\origveh.txt
|
||||
|
||||
"lang\origveh.lng" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
strgen\debug\strgen.exe lang\origveh.txt
|
||||
|
||||
# End Custom Build
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\lang\polish.txt
|
||||
# Begin Custom Build
|
||||
InputPath=.\lang\polish.txt
|
||||
|
||||
"lang\polish.lng" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
strgen\debug\strgen.exe lang\polish.txt
|
||||
|
||||
# End Custom Build
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\lang\romanian.txt
|
||||
# Begin Custom Build
|
||||
InputPath=.\lang\romanian.txt
|
||||
|
||||
"lang\romanian.lng" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
strgen\debug\strgen.exe lang\romanian.txt
|
||||
|
||||
# End Custom Build
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\lang\slovak.txt
|
||||
# Begin Custom Build
|
||||
InputPath=.\lang\slovak.txt
|
||||
|
||||
"lang\slovak.lng" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
strgen\debug\strgen.exe lang\slovak.txt
|
||||
|
||||
# End Custom Build
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\lang\swedish.txt
|
||||
# Begin Custom Build
|
||||
InputPath=.\lang\swedish.txt
|
||||
|
||||
"lang\swedish.lng" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
strgen\debug\strgen.exe lang\swedish.txt
|
||||
|
||||
# End Custom Build
|
||||
# End Source File
|
||||
# End Target
|
||||
# End Project
|
|
@ -1,233 +0,0 @@
|
|||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="7.10"
|
||||
Name="langs"
|
||||
ProjectGUID="{0F066B23-18DF-4284-8265-F4A5E7E3B966}"
|
||||
RootNamespace="langs"
|
||||
SccProjectName=""
|
||||
SccLocalPath=""
|
||||
Keyword="MakeFileProj">
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"/>
|
||||
</Platforms>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="."
|
||||
IntermediateDirectory="."
|
||||
ConfigurationType="10"
|
||||
UseOfMFC="0"
|
||||
ATLMinimizesCRunTimeLibraryUsage="FALSE">
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
TypeLibraryName="./langs.tlb"
|
||||
HeaderFileName=""/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
Description="Generating strings.h"
|
||||
CommandLine="strgen\debug\strgen.exe"/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<File
|
||||
RelativePath=".\lang\american.txt">
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32">
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
Description="Generating american language file"
|
||||
CommandLine="strgen\debug\strgen.exe "$(InputPath)""
|
||||
Outputs="lang\american.lng"/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\lang\czech.txt">
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32">
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
Description="Generating czech language file"
|
||||
CommandLine="strgen\debug\strgen.exe "$(InputPath)"
|
||||
"
|
||||
Outputs="lang\czech.lng"/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\lang\danish.txt">
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32">
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
Description="Generating danish language file"
|
||||
CommandLine="strgen\debug\strgen.exe "$(InputPath)"
|
||||
"
|
||||
Outputs="lang\danish.lng"/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\lang\dutch.txt">
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32">
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
Description="Generating dutch language file"
|
||||
CommandLine="strgen\debug\strgen.exe "$(InputPath)"
|
||||
"
|
||||
Outputs="lang\dutch.lng"/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="lang\english.txt">
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32">
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
Description="Generating english language file"
|
||||
CommandLine="strgen\debug\strgen.exe "$(InputPath)"
|
||||
"
|
||||
Outputs="lang\english.lng"/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\lang\french.txt">
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32">
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
Description="Generating french language file"
|
||||
CommandLine="strgen\debug\strgen.exe "$(InputPath)"
|
||||
"
|
||||
Outputs="lang\french.lng"/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\lang\galician.txt">
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32">
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
Description="Generating galician language file"
|
||||
CommandLine="strgen\debug\strgen.exe "$(InputPath)"
|
||||
"
|
||||
Outputs="lang\galician.lng"/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\lang\german.txt">
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32">
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
Description="Generating german language file"
|
||||
CommandLine="strgen\debug\strgen.exe "$(InputPath)"
|
||||
"
|
||||
Outputs="lang\german.lng"/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\lang\hungarian.txt">
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32">
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
Description="Generating hungarian language file"
|
||||
CommandLine="strgen\debug\strgen.exe "$(InputPath)"
|
||||
"
|
||||
Outputs="lang\hungarian.lng"/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\lang\italian.txt">
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32">
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
Description="Generating italian language file"
|
||||
CommandLine="strgen\debug\strgen.exe "$(InputPath)"
|
||||
"
|
||||
Outputs="lang\italian.lng"/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\lang\norwegian.txt">
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32">
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
Description="Generating norwegian language file"
|
||||
CommandLine="strgen\debug\strgen.exe "$(InputPath)"
|
||||
"
|
||||
Outputs="lang\norwegian.lng"/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\lang\origveh.txt">
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32">
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
Description="Generating Original Vehicle names file"
|
||||
CommandLine="strgen\debug\strgen.exe "$(InputPath)""
|
||||
Outputs="lang\origveh.lng"/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\lang\polish.txt">
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32">
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
Description="Generating polish language file"
|
||||
CommandLine="strgen\debug\strgen.exe "$(InputPath)"
|
||||
"
|
||||
Outputs="lang\polish.lng"/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\lang\romanian.txt">
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32">
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
Description="Generating romanian language file"
|
||||
CommandLine="strgen\debug\strgen.exe "$(InputPath)"
|
||||
"
|
||||
Outputs="lang\romanian.lng"/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\lang\slovak.txt">
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32">
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
Description="Generating slovak language file"
|
||||
CommandLine="strgen\debug\strgen.exe "$(InputPath)"
|
||||
"
|
||||
Outputs="lang\slovak.lng"/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="lang\swedish.txt">
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32">
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
Description="Generating swedish language file"
|
||||
CommandLine="strgen\debug\strgen.exe "$(InputPath)"
|
||||
"
|
||||
Outputs="lang\swedish.lng"/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
451
trunk/lzoconf.h
451
trunk/lzoconf.h
|
@ -1,451 +0,0 @@
|
|||
/* lzoconf.h -- configuration for the LZO real-time data compression library
|
||||
|
||||
This file is part of the LZO real-time data compression library.
|
||||
|
||||
Copyright (C) 2002 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 2001 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 2000 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1999 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1998 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1997 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996 Markus Franz Xaver Johannes Oberhumer
|
||||
All Rights Reserved.
|
||||
|
||||
The LZO library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
The LZO library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with the LZO library; see the file COPYING.
|
||||
If not, write to the Free Software Foundation, Inc.,
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
Markus F.X.J. Oberhumer
|
||||
<markus@oberhumer.com>
|
||||
http://www.oberhumer.com/opensource/lzo/
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __LZOCONF_H
|
||||
#define __LZOCONF_H
|
||||
|
||||
#define LZO_VERSION 0x1080
|
||||
#define LZO_VERSION_STRING "1.08"
|
||||
#define LZO_VERSION_DATE "Jul 12 2002"
|
||||
|
||||
/* internal Autoconf configuration file - only used when building LZO */
|
||||
#if defined(LZO_HAVE_CONFIG_H)
|
||||
# include <config.h>
|
||||
#endif
|
||||
#include <limits.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
// LZO requires a conforming <limits.h>
|
||||
************************************************************************/
|
||||
|
||||
#if !defined(CHAR_BIT) || (CHAR_BIT != 8)
|
||||
# error "invalid CHAR_BIT"
|
||||
#endif
|
||||
#if !defined(UCHAR_MAX) || !defined(UINT_MAX) || !defined(ULONG_MAX)
|
||||
# error "check your compiler installation"
|
||||
#endif
|
||||
#if (USHRT_MAX < 1) || (UINT_MAX < 1) || (ULONG_MAX < 1)
|
||||
# error "your limits.h macros are broken"
|
||||
#endif
|
||||
|
||||
/* workaround a cpp bug under hpux 10.20 */
|
||||
#define LZO_0xffffffffL 4294967295ul
|
||||
|
||||
#if !defined(LZO_UINT32_C)
|
||||
# if (UINT_MAX < LZO_0xffffffffL)
|
||||
# define LZO_UINT32_C(c) c ## UL
|
||||
# else
|
||||
# define LZO_UINT32_C(c) c ## U
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
// architecture defines
|
||||
************************************************************************/
|
||||
|
||||
#if !defined(__LZO_WIN) && !defined(__LZO_DOS) && !defined(__LZO_OS2)
|
||||
# if defined(__WINDOWS__) || defined(_WINDOWS) || defined(_Windows)
|
||||
# define __LZO_WIN
|
||||
# elif defined(__WIN32__) || defined(_WIN32) || defined(WIN32)
|
||||
# define __LZO_WIN
|
||||
# elif defined(__NT__) || defined(__NT_DLL__) || defined(__WINDOWS_386__)
|
||||
# define __LZO_WIN
|
||||
# elif defined(__DOS__) || defined(__MSDOS__) || defined(MSDOS)
|
||||
# define __LZO_DOS
|
||||
# elif defined(__OS2__) || defined(__OS2V2__) || defined(OS2)
|
||||
# define __LZO_OS2
|
||||
# elif defined(__palmos__)
|
||||
# define __LZO_PALMOS
|
||||
# elif defined(__TOS__) || defined(__atarist__)
|
||||
# define __LZO_TOS
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if (UINT_MAX < LZO_0xffffffffL)
|
||||
# if defined(__LZO_WIN)
|
||||
# define __LZO_WIN16
|
||||
# elif defined(__LZO_DOS)
|
||||
# define __LZO_DOS16
|
||||
# elif defined(__LZO_PALMOS)
|
||||
# define __LZO_PALMOS16
|
||||
# elif defined(__LZO_TOS)
|
||||
# define __LZO_TOS16
|
||||
# elif defined(__C166__)
|
||||
# else
|
||||
/* porting hint: for pure 16-bit architectures try compiling
|
||||
* everything with -D__LZO_STRICT_16BIT */
|
||||
# error "16-bit target not supported - contact me for porting hints"
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if !defined(__LZO_i386)
|
||||
# if defined(__LZO_DOS) || defined(__LZO_WIN16)
|
||||
# define __LZO_i386
|
||||
# elif defined(__i386__) || defined(__386__) || defined(_M_IX86)
|
||||
# define __LZO_i386
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined(__LZO_STRICT_16BIT)
|
||||
# if (UINT_MAX < LZO_0xffffffffL)
|
||||
# include <lzo16bit.h>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* memory checkers */
|
||||
#if !defined(__LZO_CHECKER)
|
||||
# if defined(__BOUNDS_CHECKING_ON)
|
||||
# define __LZO_CHECKER
|
||||
# elif defined(__CHECKER__)
|
||||
# define __LZO_CHECKER
|
||||
# elif defined(__INSURE__)
|
||||
# define __LZO_CHECKER
|
||||
# elif defined(__PURIFY__)
|
||||
# define __LZO_CHECKER
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
// integral and pointer types
|
||||
************************************************************************/
|
||||
|
||||
/* Integral types with 32 bits or more */
|
||||
#if !defined(LZO_UINT32_MAX)
|
||||
# if (UINT_MAX >= LZO_0xffffffffL)
|
||||
typedef unsigned int lzo_uint32;
|
||||
typedef int lzo_int32;
|
||||
# define LZO_UINT32_MAX UINT_MAX
|
||||
# define LZO_INT32_MAX INT_MAX
|
||||
# define LZO_INT32_MIN INT_MIN
|
||||
# elif (ULONG_MAX >= LZO_0xffffffffL)
|
||||
typedef unsigned long lzo_uint32;
|
||||
typedef long lzo_int32;
|
||||
# define LZO_UINT32_MAX ULONG_MAX
|
||||
# define LZO_INT32_MAX LONG_MAX
|
||||
# define LZO_INT32_MIN LONG_MIN
|
||||
# else
|
||||
# error "lzo_uint32"
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* lzo_uint is used like size_t */
|
||||
#if !defined(LZO_UINT_MAX)
|
||||
# if (UINT_MAX >= LZO_0xffffffffL)
|
||||
typedef unsigned int lzo_uint;
|
||||
typedef int lzo_int;
|
||||
# define LZO_UINT_MAX UINT_MAX
|
||||
# define LZO_INT_MAX INT_MAX
|
||||
# define LZO_INT_MIN INT_MIN
|
||||
# elif (ULONG_MAX >= LZO_0xffffffffL)
|
||||
typedef unsigned long lzo_uint;
|
||||
typedef long lzo_int;
|
||||
# define LZO_UINT_MAX ULONG_MAX
|
||||
# define LZO_INT_MAX LONG_MAX
|
||||
# define LZO_INT_MIN LONG_MIN
|
||||
# else
|
||||
# error "lzo_uint"
|
||||
# endif
|
||||
#endif
|
||||
|
||||
typedef int lzo_bool;
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
// memory models
|
||||
************************************************************************/
|
||||
|
||||
/* Memory model for the public code segment. */
|
||||
#if !defined(__LZO_CMODEL)
|
||||
# if defined(__LZO_DOS16) || defined(__LZO_WIN16)
|
||||
# define __LZO_CMODEL __far
|
||||
# elif defined(__LZO_i386) && defined(__WATCOMC__)
|
||||
# define __LZO_CMODEL __near
|
||||
# else
|
||||
# define __LZO_CMODEL
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Memory model for the public data segment. */
|
||||
#if !defined(__LZO_DMODEL)
|
||||
# if defined(__LZO_DOS16) || defined(__LZO_WIN16)
|
||||
# define __LZO_DMODEL __far
|
||||
# elif defined(__LZO_i386) && defined(__WATCOMC__)
|
||||
# define __LZO_DMODEL __near
|
||||
# else
|
||||
# define __LZO_DMODEL
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Memory model that allows to access memory at offsets of lzo_uint. */
|
||||
#if !defined(__LZO_MMODEL)
|
||||
# if (LZO_UINT_MAX <= UINT_MAX)
|
||||
# define __LZO_MMODEL
|
||||
# elif defined(__LZO_DOS16) || defined(__LZO_WIN16)
|
||||
# define __LZO_MMODEL __huge
|
||||
# define LZO_999_UNSUPPORTED
|
||||
# elif defined(__LZO_PALMOS16) || defined(__LZO_TOS16)
|
||||
# define __LZO_MMODEL
|
||||
# else
|
||||
# error "__LZO_MMODEL"
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* no typedef here because of const-pointer issues */
|
||||
#define lzo_byte unsigned char __LZO_MMODEL
|
||||
#define lzo_bytep unsigned char __LZO_MMODEL *
|
||||
#define lzo_charp char __LZO_MMODEL *
|
||||
#define lzo_voidp void __LZO_MMODEL *
|
||||
#define lzo_shortp short __LZO_MMODEL *
|
||||
#define lzo_ushortp unsigned short __LZO_MMODEL *
|
||||
#define lzo_uint32p lzo_uint32 __LZO_MMODEL *
|
||||
#define lzo_int32p lzo_int32 __LZO_MMODEL *
|
||||
#define lzo_uintp lzo_uint __LZO_MMODEL *
|
||||
#define lzo_intp lzo_int __LZO_MMODEL *
|
||||
#define lzo_voidpp lzo_voidp __LZO_MMODEL *
|
||||
#define lzo_bytepp lzo_bytep __LZO_MMODEL *
|
||||
|
||||
#ifndef lzo_sizeof_dict_t
|
||||
# define lzo_sizeof_dict_t sizeof(lzo_bytep)
|
||||
#endif
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
// calling conventions and function types
|
||||
************************************************************************/
|
||||
|
||||
/* linkage */
|
||||
#if !defined(__LZO_EXTERN_C)
|
||||
# ifdef __cplusplus
|
||||
# define __LZO_EXTERN_C extern "C"
|
||||
# else
|
||||
# define __LZO_EXTERN_C extern
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* calling convention */
|
||||
#if !defined(__LZO_CDECL)
|
||||
# if defined(__LZO_DOS16) || defined(__LZO_WIN16)
|
||||
# define __LZO_CDECL __LZO_CMODEL __cdecl
|
||||
# elif defined(__LZO_i386) && defined(_MSC_VER)
|
||||
# define __LZO_CDECL __LZO_CMODEL __cdecl
|
||||
# elif defined(__LZO_i386) && defined(__WATCOMC__)
|
||||
# define __LZO_CDECL __LZO_CMODEL __cdecl
|
||||
# else
|
||||
# define __LZO_CDECL __LZO_CMODEL
|
||||
# endif
|
||||
#endif
|
||||
#if !defined(__LZO_ENTRY)
|
||||
# define __LZO_ENTRY __LZO_CDECL
|
||||
#endif
|
||||
|
||||
/* C++ exception specification for extern "C" function types */
|
||||
#if !defined(__cplusplus)
|
||||
# undef LZO_NOTHROW
|
||||
# define LZO_NOTHROW
|
||||
#elif !defined(LZO_NOTHROW)
|
||||
# define LZO_NOTHROW
|
||||
#endif
|
||||
|
||||
|
||||
typedef int
|
||||
(__LZO_ENTRY *lzo_compress_t) ( const lzo_byte *src, lzo_uint src_len,
|
||||
lzo_byte *dst, lzo_uintp dst_len,
|
||||
lzo_voidp wrkmem );
|
||||
|
||||
typedef int
|
||||
(__LZO_ENTRY *lzo_decompress_t) ( const lzo_byte *src, lzo_uint src_len,
|
||||
lzo_byte *dst, lzo_uintp dst_len,
|
||||
lzo_voidp wrkmem );
|
||||
|
||||
typedef int
|
||||
(__LZO_ENTRY *lzo_optimize_t) ( lzo_byte *src, lzo_uint src_len,
|
||||
lzo_byte *dst, lzo_uintp dst_len,
|
||||
lzo_voidp wrkmem );
|
||||
|
||||
typedef int
|
||||
(__LZO_ENTRY *lzo_compress_dict_t)(const lzo_byte *src, lzo_uint src_len,
|
||||
lzo_byte *dst, lzo_uintp dst_len,
|
||||
lzo_voidp wrkmem,
|
||||
const lzo_byte *dict, lzo_uint dict_len );
|
||||
|
||||
typedef int
|
||||
(__LZO_ENTRY *lzo_decompress_dict_t)(const lzo_byte *src, lzo_uint src_len,
|
||||
lzo_byte *dst, lzo_uintp dst_len,
|
||||
lzo_voidp wrkmem,
|
||||
const lzo_byte *dict, lzo_uint dict_len );
|
||||
|
||||
|
||||
/* assembler versions always use __cdecl */
|
||||
typedef int
|
||||
(__LZO_CDECL *lzo_compress_asm_t)( const lzo_byte *src, lzo_uint src_len,
|
||||
lzo_byte *dst, lzo_uintp dst_len,
|
||||
lzo_voidp wrkmem );
|
||||
|
||||
typedef int
|
||||
(__LZO_CDECL *lzo_decompress_asm_t)( const lzo_byte *src, lzo_uint src_len,
|
||||
lzo_byte *dst, lzo_uintp dst_len,
|
||||
lzo_voidp wrkmem );
|
||||
|
||||
|
||||
/* a progress indicator callback function */
|
||||
typedef void (__LZO_ENTRY *lzo_progress_callback_t) (lzo_uint, lzo_uint);
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
// export information
|
||||
************************************************************************/
|
||||
|
||||
/* DLL export information */
|
||||
#if !defined(__LZO_EXPORT1)
|
||||
# define __LZO_EXPORT1
|
||||
#endif
|
||||
#if !defined(__LZO_EXPORT2)
|
||||
# define __LZO_EXPORT2
|
||||
#endif
|
||||
|
||||
/* exported calling convention for C functions */
|
||||
#if !defined(LZO_PUBLIC)
|
||||
# define LZO_PUBLIC(_rettype) \
|
||||
__LZO_EXPORT1 _rettype __LZO_EXPORT2 __LZO_ENTRY
|
||||
#endif
|
||||
#if !defined(LZO_EXTERN)
|
||||
# define LZO_EXTERN(_rettype) __LZO_EXTERN_C LZO_PUBLIC(_rettype)
|
||||
#endif
|
||||
#if !defined(LZO_PRIVATE)
|
||||
# define LZO_PRIVATE(_rettype) static _rettype __LZO_ENTRY
|
||||
#endif
|
||||
|
||||
/* exported __cdecl calling convention for assembler functions */
|
||||
#if !defined(LZO_PUBLIC_CDECL)
|
||||
# define LZO_PUBLIC_CDECL(_rettype) \
|
||||
__LZO_EXPORT1 _rettype __LZO_EXPORT2 __LZO_CDECL
|
||||
#endif
|
||||
#if !defined(LZO_EXTERN_CDECL)
|
||||
# define LZO_EXTERN_CDECL(_rettype) __LZO_EXTERN_C LZO_PUBLIC_CDECL(_rettype)
|
||||
#endif
|
||||
|
||||
/* exported global variables (LZO currently uses no static variables and
|
||||
* is fully thread safe) */
|
||||
#if !defined(LZO_PUBLIC_VAR)
|
||||
# define LZO_PUBLIC_VAR(_type) \
|
||||
__LZO_EXPORT1 _type __LZO_EXPORT2 __LZO_DMODEL
|
||||
#endif
|
||||
#if !defined(LZO_EXTERN_VAR)
|
||||
# define LZO_EXTERN_VAR(_type) extern LZO_PUBLIC_VAR(_type)
|
||||
#endif
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
// error codes and prototypes
|
||||
************************************************************************/
|
||||
|
||||
/* Error codes for the compression/decompression functions. Negative
|
||||
* values are errors, positive values will be used for special but
|
||||
* normal events.
|
||||
*/
|
||||
#define LZO_E_OK 0
|
||||
#define LZO_E_ERROR (-1)
|
||||
#define LZO_E_OUT_OF_MEMORY (-2) /* not used right now */
|
||||
#define LZO_E_NOT_COMPRESSIBLE (-3) /* not used right now */
|
||||
#define LZO_E_INPUT_OVERRUN (-4)
|
||||
#define LZO_E_OUTPUT_OVERRUN (-5)
|
||||
#define LZO_E_LOOKBEHIND_OVERRUN (-6)
|
||||
#define LZO_E_EOF_NOT_FOUND (-7)
|
||||
#define LZO_E_INPUT_NOT_CONSUMED (-8)
|
||||
|
||||
|
||||
/* lzo_init() should be the first function you call.
|
||||
* Check the return code !
|
||||
*
|
||||
* lzo_init() is a macro to allow checking that the library and the
|
||||
* compiler's view of various types are consistent.
|
||||
*/
|
||||
#define lzo_init() __lzo_init2(LZO_VERSION,(int)sizeof(short),(int)sizeof(int),\
|
||||
(int)sizeof(long),(int)sizeof(lzo_uint32),(int)sizeof(lzo_uint),\
|
||||
(int)lzo_sizeof_dict_t,(int)sizeof(char *),(int)sizeof(lzo_voidp),\
|
||||
(int)sizeof(lzo_compress_t))
|
||||
LZO_EXTERN(int) __lzo_init2(unsigned,int,int,int,int,int,int,int,int,int);
|
||||
|
||||
/* version functions (useful for shared libraries) */
|
||||
LZO_EXTERN(unsigned) lzo_version(void);
|
||||
LZO_EXTERN(const char *) lzo_version_string(void);
|
||||
LZO_EXTERN(const char *) lzo_version_date(void);
|
||||
LZO_EXTERN(const lzo_charp) _lzo_version_string(void);
|
||||
LZO_EXTERN(const lzo_charp) _lzo_version_date(void);
|
||||
|
||||
/* string functions */
|
||||
LZO_EXTERN(int)
|
||||
lzo_memcmp(const lzo_voidp _s1, const lzo_voidp _s2, lzo_uint _len);
|
||||
LZO_EXTERN(lzo_voidp)
|
||||
lzo_memcpy(lzo_voidp _dest, const lzo_voidp _src, lzo_uint _len);
|
||||
LZO_EXTERN(lzo_voidp)
|
||||
lzo_memmove(lzo_voidp _dest, const lzo_voidp _src, lzo_uint _len);
|
||||
LZO_EXTERN(lzo_voidp)
|
||||
lzo_memset(lzo_voidp _s, int _c, lzo_uint _len);
|
||||
|
||||
/* checksum functions */
|
||||
LZO_EXTERN(lzo_uint32)
|
||||
lzo_adler32(lzo_uint32 _adler, const lzo_byte *_buf, lzo_uint _len);
|
||||
LZO_EXTERN(lzo_uint32)
|
||||
lzo_crc32(lzo_uint32 _c, const lzo_byte *_buf, lzo_uint _len);
|
||||
|
||||
/* misc. */
|
||||
LZO_EXTERN(lzo_bool) lzo_assert(int _expr);
|
||||
LZO_EXTERN(int) _lzo_config_check(void);
|
||||
typedef union { lzo_bytep p; lzo_uint u; } __lzo_pu_u;
|
||||
typedef union { lzo_bytep p; lzo_uint32 u32; } __lzo_pu32_u;
|
||||
typedef union { void *vp; lzo_bytep bp; lzo_uint32 u32; long l; } lzo_align_t;
|
||||
|
||||
/* align a char pointer on a boundary that is a multiple of `size' */
|
||||
LZO_EXTERN(unsigned) __lzo_align_gap(const lzo_voidp _ptr, lzo_uint _size);
|
||||
#define LZO_PTR_ALIGN_UP(_ptr,_size) \
|
||||
((_ptr) + (lzo_uint) __lzo_align_gap((const lzo_voidp)(_ptr),(lzo_uint)(_size)))
|
||||
|
||||
/* deprecated - only for backward compatibility */
|
||||
#define LZO_ALIGN(_ptr,_size) LZO_PTR_ALIGN_UP(_ptr,_size)
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* already included */
|
||||
|
231
trunk/macros.h
231
trunk/macros.h
|
@ -1,231 +0,0 @@
|
|||
#ifndef MACROS_H
|
||||
#define MACROS_H
|
||||
|
||||
#define MAX_INT 0x7FFFFFFF
|
||||
|
||||
#ifdef min
|
||||
#undef min
|
||||
#endif
|
||||
|
||||
#ifdef max
|
||||
#undef max
|
||||
#endif
|
||||
|
||||
static INLINE int min(int a, int b) { if (a <= b) return a; return b; }
|
||||
static INLINE int max(int a, int b) { if (a >= b) return a; return b; }
|
||||
static INLINE int64 max64(int64 a, int64 b) { if (a >= b) return a; return b; }
|
||||
|
||||
static INLINE uint minu(uint a, uint b) { if (a <= b) return a; return b; }
|
||||
static INLINE uint maxu(uint a, uint b) { if (a >= b) return a; return b; }
|
||||
|
||||
|
||||
static INLINE int clamp(int a, int min, int max) { if (a <= min) return min; if (a >= max) return max; return a; }
|
||||
static INLINE int clamp2(int a, int min, int max) { if (a <= min) a=min; if (a >= max) a=max; return a; }
|
||||
static INLINE bool int32_add_overflow(int32 a, int32 b) { return (int32)(a^b)>=0 && (int32)(a^(a+b))<0; }
|
||||
static INLINE bool int32_sub_overflow(int32 a, int32 b) { return (int32)(a^b)<0 && (int32)(a^(a-b))<0; }
|
||||
|
||||
static INLINE bool str_eq(const byte *a, const byte *b)
|
||||
{
|
||||
int i=0;
|
||||
while (a[i] == b[i]) {
|
||||
if (a[i] == 0)
|
||||
return true;
|
||||
i++;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Will crash if strings are equal
|
||||
static INLINE bool str_is_below(byte *a, byte *b) {
|
||||
while (*a <= *b) {
|
||||
if (*a < *b) return true;
|
||||
a++;
|
||||
b++;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
static INLINE int32 BIGMULSS(int32 a, int32 b, int shift) {
|
||||
return (int32)(((int64)(a) * (int64)(b)) >> (shift));
|
||||
}
|
||||
|
||||
static INLINE int64 BIGMULSS64(int64 a, int64 b, int shift) {
|
||||
return ((a) * (b)) >> (shift);
|
||||
}
|
||||
|
||||
static INLINE uint32 BIGMULUS(uint32 a, uint32 b, int shift) {
|
||||
return (uint32)(((uint64)(a) * (uint64)(b)) >> (shift));
|
||||
}
|
||||
|
||||
static INLINE int64 BIGMULS(int32 a, int32 b) {
|
||||
return (int32)(((int64)(a) * (int64)(b)));
|
||||
}
|
||||
|
||||
/* OPT: optimized into an unsigned comparison */
|
||||
//#define IS_INSIDE_1D(x, base, size) ((x) >= (base) && (x) < (base) + (size))
|
||||
#define IS_INSIDE_1D(x, base, size) ( (uint)((x) - (base)) < ((uint)(size)) )
|
||||
|
||||
#define TILE_X_BITS 8
|
||||
#define TILE_Y_BITS 8
|
||||
#define LANDSCAPE_SIZE_FACTOR 1
|
||||
|
||||
#define TILE_FROM_XY(x,y) (int)((((y) >> 4) << TILE_X_BITS) + ((x) >> 4))
|
||||
#define TILE_XY(x,y) (int)(((y) << TILE_X_BITS) + (x))
|
||||
|
||||
#define IS_TILETYPE(_t_, _s_) (_map_type_and_height[(_t_)] >> 4 == (_s_))
|
||||
#define GET_TILETYPE(_t_) (_map_type_and_height[(_t_)] >> 4)
|
||||
#define GET_TILEHEIGHT(_t_) ((_map_type_and_height[_t_] & 0xF) * 8)
|
||||
|
||||
enum {
|
||||
CORRECT_Z_BITS = 1 << 1 | 1 << 2 | 1 << 3 | 1 << 4 | 1 << 5 | 1 << 6 | 1 << 7
|
||||
};
|
||||
#define CORRECT_Z(tileh) (CORRECT_Z_BITS & (1 << tileh))
|
||||
|
||||
#define TILES_X (1 << TILE_X_BITS)
|
||||
#define TILES_Y (1 << TILE_Y_BITS)
|
||||
|
||||
#define TILE_X_MAX (TILES_X-1)
|
||||
#define TILE_Y_MAX (TILES_Y-1)
|
||||
|
||||
#define TILE_ASSERT(x) assert( TILE_MASK(x) == (x) );
|
||||
|
||||
extern uint SafeTileAdd(uint x, int add, const char *exp, const char *file, int line);
|
||||
|
||||
#if !defined(_DEBUG) || TILE_X_BITS != 8
|
||||
# define TILE_ADD(x,y) ((x)+(y))
|
||||
#else
|
||||
# if defined(__GNUC__)
|
||||
# define TILE_ADD(x,y) (SafeTileAdd((x),(y), "??", __FILE__, __LINE__))
|
||||
# else
|
||||
# define TILE_ADD(x,y) (SafeTileAdd((x),(y), #x ## ", " ## #y, __FILE__, __LINE__))
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#define TILE_ADDXY(tile, x, y) TILE_ADD(tile, TILE_XY(x,y))
|
||||
|
||||
#if TILE_X_BITS == 8
|
||||
#define GET_TILE_X(t) (uint)((byte)(t))
|
||||
#define GET_TILE_Y(t) (uint)((t) >> 8)
|
||||
#define TILE_MASK(x) ((uint16)(x))
|
||||
#else
|
||||
#define GET_TILE_X(t) (uint)((t) & ((1 << TILE_X_BITS)-1))
|
||||
#define GET_TILE_Y(t) (uint)((t) >> TILE_X_BITS)
|
||||
#define TILE_MASK(x) (int)((x) & ((1 << (TILE_X_BITS + TILE_Y_BITS))-1))
|
||||
#endif
|
||||
|
||||
//#define REMADP_COORDS(x,y,z) { int t = x; x = (y-t)*2; y+=t-z; }
|
||||
|
||||
#define PACK_POINT(x,y) ((x) | ((y) << 16))
|
||||
#define UNPACK_POINT_X(p) ((uint16)(p))
|
||||
#define UNPACK_POINT_Y(p) ((uint16)(p>>16))
|
||||
|
||||
#define PACK_PPOINT(p) PACK_POINT((p).x, (p).y)
|
||||
|
||||
#define HASBIT(x,y) ((x) & (1 << (y)))
|
||||
#define SETBIT(x,y) ((x) |= (1 << (y)))
|
||||
#define CLRBIT(x,y) ((x) &= ~(1 << (y)))
|
||||
|
||||
// checking more bits. Maybe unneccessary, but easy to use
|
||||
#define HASBITS(x,y) ((x) & (y))
|
||||
#define SETBITS(x,y) ((x) |= (y))
|
||||
#define CLRBITS(x,y) ((x) &= ~(y))
|
||||
|
||||
#define PLAYER_SPRITE_COLOR(owner) ((_player_colors[owner] << 16) + 0x3070000)
|
||||
#define SPRITE_PALETTE(x) ((x) + 0x8000)
|
||||
|
||||
extern const byte _ffb_64[128];
|
||||
/* Returns the position of the first bit that is not zero, counted from the
|
||||
* left. Ie, 10110100 returns 2, 00000001 returns 0, etc. When x == 0 returns
|
||||
* 0.
|
||||
*/
|
||||
#define FIND_FIRST_BIT(x) _ffb_64[(x)]
|
||||
/* Returns x with the first bit that is not zero, counted from the left, set
|
||||
* to zero. So, 10110100 returns 10110000, 00000001 returns 00000000, etc.
|
||||
*/
|
||||
#define KILL_FIRST_BIT(x) _ffb_64[(x)+64]
|
||||
|
||||
static INLINE int FindFirstBit2x64(int value)
|
||||
{
|
||||
int i = 0;
|
||||
if ( (byte) value == 0) {
|
||||
i += 8;
|
||||
value >>= 8;
|
||||
}
|
||||
return i + FIND_FIRST_BIT(value & 0x3F);
|
||||
}
|
||||
|
||||
|
||||
#if TILE_X_BITS + TILE_Y_BITS <= 16
|
||||
typedef uint16 TileIndex;
|
||||
typedef int16 TileIndexDiff;
|
||||
#else
|
||||
typedef uint32 TileIndex;
|
||||
typedef int32 TileIndexDiff;
|
||||
#endif
|
||||
|
||||
/* [min,max), strictly less than */
|
||||
#define IS_BYTE_INSIDE(a,min,max) ((byte)((a)-(min)) < (byte)((max)-(min)))
|
||||
#define IS_INT_INSIDE(a,min,max) ((uint)((a)-(min)) < (uint)((max)-(min)))
|
||||
|
||||
|
||||
#define CHANCE16(a,b) ((uint16)Random() <= (uint16)((65536 * a) / b))
|
||||
#define ICHANCE16(a,b) ((uint16)InteractiveRandom() <= (uint16)((65536 * a) / b))
|
||||
#define CHANCE16R(a,b,r) ((uint16)(r=Random()) <= (uint16)((65536 * a) / b))
|
||||
#define CHANCE16I(a,b,v) ((uint16)(v) <= (uint16)((65536 * a) / b))
|
||||
|
||||
#define BEGIN_TILE_LOOP(var,w,h,tile) \
|
||||
{int h_cur = h; \
|
||||
uint var = tile; \
|
||||
do { \
|
||||
int w_cur = w; \
|
||||
do {
|
||||
|
||||
#define END_TILE_LOOP(var,w,h,tile) \
|
||||
} while (++var, --w_cur != 0); \
|
||||
} while (var += TILE_XY(0,1) - (w), --h_cur != 0);}
|
||||
|
||||
|
||||
#define for_each_bit(_i,_b) \
|
||||
for(_i=0; _b!=0; _i++,_b>>=1) \
|
||||
if (_b&1)
|
||||
|
||||
#define assert_array(i,j) assert(i < lengthof(j))
|
||||
|
||||
#define abs myabs
|
||||
|
||||
|
||||
static INLINE int intxchg_(int *a, int b) { int t = *a; *a = b; return t; }
|
||||
#define intxchg(a,b) intxchg_(&(a), (b))
|
||||
#define intswap(a,b) ((b) = intxchg_(&(a), (b)))
|
||||
|
||||
static INLINE int myabs(int a) { if (a<0) a = -a; return a; }
|
||||
static INLINE int64 myabs64(int64 a) { if (a<0) a = -a; return a; }
|
||||
|
||||
static INLINE void swap_byte(byte *a, byte *b) { byte t = *a; *a = *b; *b = t; }
|
||||
static INLINE void swap_uint16(uint16 *a, uint16 *b) { uint16 t = *a; *a = *b; *b = t; }
|
||||
static INLINE void swap_int16(int16 *a, int16 *b) { int16 t = *a; *a = *b; *b = t; }
|
||||
static INLINE void swap_tile(TileIndex *a, TileIndex *b) { TileIndex t = *a; *a = *b; *b = t; }
|
||||
|
||||
|
||||
|
||||
#if defined(TTD_LITTLE_ENDIAN)
|
||||
# define READ_LE_UINT16(b) (*(const uint16*)(b))
|
||||
# define ADD_WORD(x) (x)&0xFF, ((x) >> 8)&0xFF
|
||||
# define ADD_DWORD(x) (x)&0xFF, ((x) >> 8)&0xFF, ((x) >> 16)&0xFF, ((x) >> 24)&0xFF
|
||||
#elif defined(TTD_BIG_ENDIAN)
|
||||
static INLINE uint16 READ_LE_UINT16(const void *b) {
|
||||
return ((const byte*)b)[0] + (((const byte*)b)[1] << 8);
|
||||
}
|
||||
# define ADD_WORD(x) ((x) >> 8)&0xFF, (x)&0xFF
|
||||
# define ADD_DWORD(x) ((x) >> 24)&0xFF, ((x) >> 16)&0xFF, ((x) >> 8)&0xFF, (x)&0xFF
|
||||
#endif
|
||||
|
||||
static INLINE void WRITE_LE_UINT16(void *b, uint16 x) {
|
||||
((byte*)b)[0] = (byte)x;
|
||||
((byte*)b)[1] = (byte)(x >> 8);
|
||||
}
|
||||
|
||||
#define MAX_DETOUR 6
|
||||
|
||||
#endif /* MACROS_H */
|
2266
trunk/main_gui.c
2266
trunk/main_gui.c
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Before Width: | Height: | Size: 766 B |
|
@ -1,84 +0,0 @@
|
|||
# This file generates Makefile.config
|
||||
# Create default config from autodetected values
|
||||
# Magic at work, note that you can't use commas in arguments for this
|
||||
CONFIG_LINE=@$(SHELL) -c 'echo $(1)' >> $(MAKE_CONFIG) 2> /dev/null
|
||||
|
||||
$(MAKE_CONFIG):
|
||||
|
||||
touch $(MAKE_CONFIG)
|
||||
|
||||
$(call CONFIG_LINE,\# OpenTTD config file for makefile)
|
||||
$(call CONFIG_LINE,\# Set your options here - 1 for use and empty for disable)
|
||||
$(call CONFIG_LINE,)
|
||||
|
||||
$(call CONFIG_LINE,\# User setup flags)
|
||||
$(call CONFIG_LINE,\# Translator: adds TODO to any untranslated strings)
|
||||
$(call CONFIG_LINE,\# Display_Warnings: when off it hides some warnings while compiling)
|
||||
$(call CONFIG_LINE,\# MIDI: sets path to midi player)
|
||||
$(call CONFIG_LINE,\# MIDI_ARG: sets an argument which is used when calling the midi player. Default off)
|
||||
$(call CONFIG_LINE,\# SUPRESS_LANG_ERRORS: supresses output about missing and mismatched strings)
|
||||
$(call CONFIG_LINE,STATIC:=$(STATIC))
|
||||
$(call CONFIG_LINE,TRANSLATOR:=$(TRANSLATOR))
|
||||
$(call CONFIG_LINE,DISPLAY_WARNINGS:=$(DISPLAY_WARNINGS))
|
||||
$(call CONFIG_LINE,DEBUG:=$(DEBUG))
|
||||
$(call CONFIG_LINE,PROFILE:=$(PROFILE))
|
||||
$(call CONFIG_LINE,MIDI:=$(MIDI))
|
||||
$(call CONFIG_LINE,MIDI_ARG:=$(MIDI_ARG))
|
||||
$(call CONFIG_LINE,SUPRESS_LANG_ERRORS:=$(SUPRESS_LANG_ERRORS))
|
||||
$(call CONFIG_LINE,)
|
||||
|
||||
$(call CONFIG_LINE,\# DATA_DIR_PREFIX is the path to OpenTTD. It can be absolute or relative)
|
||||
$(call CONFIG_LINE,\# USE_HOMEDIR sets \~/ in front of DATA_DIR_PREFIX so it uses the homedir)
|
||||
$(call CONFIG_LINE,\# do not type \~/ yourself because that will not work)
|
||||
$(call CONFIG_LINE,\# Folders should end with /)
|
||||
$(call CONFIG_LINE,BINARY_DIR:=$(BINARY_DIR))
|
||||
$(call CONFIG_LINE,INSTALL_DIR:=$(INSTALL_DIR))
|
||||
$(call CONFIG_LINE,USE_HOMEDIR:=$(USE_HOMEDIR))
|
||||
$(call CONFIG_LINE,GAME_DATA_DIR:=$(GAME_DATA_DIR))
|
||||
$(call CONFIG_LINE,PERSONAL_DIR:=$(PERSONAL_DIR))
|
||||
$(call CONFIG_LINE,)
|
||||
|
||||
$(call CONFIG_LINE,\# Experimental)
|
||||
$(call CONFIG_LINE,WITH_NETWORK:=$(WITH_NETWORK))
|
||||
$(call CONFIG_LINE,WITH_DIRECTMUSIC:=$(WITH_DIRECTMUSIC))
|
||||
$(call CONFIG_LINE,)
|
||||
$(call CONFIG_LINE,)
|
||||
|
||||
$(call CONFIG_LINE,\# Flag to skip test for OS when building static)
|
||||
$(call CONFIG_LINE,\# OpenTTD have only been succesfully tested with static builds on MorphOS and MacOSX)
|
||||
$(call CONFIG_LINE,\# If you want to try anyway on other OSes, set this flag)
|
||||
$(call CONFIG_LINE,\# Inform us if you have success)
|
||||
$(call CONFIG_LINE,SKIP_STATIC_CHECK:=$(SKIP_STATIC_CHECK))
|
||||
$(call CONFIG_LINE,)
|
||||
$(call CONFIG_LINE,)
|
||||
|
||||
$(call CONFIG_LINE,\# Everything below this line is autogenerated)
|
||||
$(call CONFIG_LINE,\#)
|
||||
$(call CONFIG_LINE,\# If you need to change anything below, you should run "make upgradeconf")
|
||||
$(call CONFIG_LINE,\# If that does not fix the problem, you should make a bug report.)
|
||||
$(call CONFIG_LINE,\# It would really help if you could tell how to autodetect the missing setting)
|
||||
$(call CONFIG_LINE,\# That info could be where the missing lib is placed)
|
||||
$(call CONFIG_LINE,)
|
||||
|
||||
$(call CONFIG_LINE,\# Libs)
|
||||
$(call CONFIG_LINE,WITH_ZLIB:=$(WITH_ZLIB))
|
||||
$(call CONFIG_LINE,WITH_SDL:=$(WITH_SDL))
|
||||
$(call CONFIG_LINE,WITH_PNG:=$(WITH_PNG))
|
||||
$(call CONFIG_LINE,STATIC_ZLIB_PATH:=$(STATIC_ZLIB_PATH))
|
||||
$(call CONFIG_LINE,)
|
||||
|
||||
$(call CONFIG_LINE,\# OS flags)
|
||||
$(call CONFIG_LINE,WIN32:=$(WIN32))
|
||||
$(call CONFIG_LINE,UNIX:=$(UNIX))
|
||||
$(call CONFIG_LINE,OSX:=$(OSX))
|
||||
$(call CONFIG_LINE,FREEBSD:=$(FREEBSD))
|
||||
$(call CONFIG_LINE,MORPHOS:=$(MORPHOS))
|
||||
$(call CONFIG_LINE,CYGWIN:=$(CYGWIN))
|
||||
$(call CONFIG_LINE,MINGW:=$(MINGW))
|
||||
$(call CONFIG_LINE,)
|
||||
|
||||
$(call CONFIG_LINE,\# misc)
|
||||
$(call CONFIG_LINE,SDL-CONFIG:=$(SDL-CONFIG))
|
||||
$(call CONFIG_LINE,CONFIG_INCLUDED:=yes)
|
||||
$(call CONFIG_LINE,PATH_SET:=$(PATH_SET))
|
||||
$(call CONFIG_LINE,CONFIG_VERSION:=$(MAKEFILE_VERSION))
|
|
@ -1,80 +0,0 @@
|
|||
# this file detects what OS and libs the computer have/are running
|
||||
|
||||
# Automatically recognize if building on Win32
|
||||
ifdef WINDIR
|
||||
ifndef UNIX
|
||||
WIN32:=1
|
||||
endif
|
||||
else
|
||||
UNIX:=1
|
||||
endif
|
||||
|
||||
# Automatically recognize if building on FreeBSD
|
||||
ifeq ($(shell uname),FreeBSD)
|
||||
FREEBSD:=1
|
||||
endif
|
||||
|
||||
# Automatically recognize if building on MacOSX
|
||||
ifeq ($(VENDOR), apple)
|
||||
OSX:=1
|
||||
# OSX uses the unix setup too
|
||||
UNIX:=1
|
||||
endif
|
||||
|
||||
# Automatically recognize if building on MorphOS
|
||||
ifeq ($(shell uname), MorphOS)
|
||||
MORPHOS:=1
|
||||
# MorphOS uses UNIX setup too
|
||||
UNIX:=1
|
||||
endif
|
||||
|
||||
# FreeBSD uses sdl11 instead of sdl
|
||||
ifdef FREEBSD
|
||||
SDL-CONFIG:=sdl11-config
|
||||
else
|
||||
SDL-CONFIG:=sdl-config
|
||||
endif
|
||||
|
||||
|
||||
# Library detections
|
||||
WITH_SDL:=$(shell $(SDL-CONFIG) --version 2>/dev/null)
|
||||
|
||||
# libpng detection
|
||||
ifdef FREEBSD
|
||||
# a little hack was needed for FreeBSD because it misses libpng-config
|
||||
WITH_PNG:=$(shell ls /usr/lib | grep "libpng" 2>/dev/null) $(shell \
|
||||
ls /usr/local/lib | grep "libpng" 2>/dev/null)
|
||||
ifdef WITH_PNG
|
||||
# makes the flag look nicer in makefile.config
|
||||
WITH_PNG:=1
|
||||
endif
|
||||
else
|
||||
WITH_PNG:=$(shell libpng-config --version 2>/dev/null)
|
||||
endif
|
||||
|
||||
ifdef WITH_PNG
|
||||
# LibPNG depends on Zlib
|
||||
WITH_ZLIB:=1
|
||||
else
|
||||
# We go looking for zlib with a little hack
|
||||
WITH_ZLIB:=$(shell ls /usr/include | grep "zlib.h" 2>/dev/null) \
|
||||
$(shell ls /usr/local/include | grep "zlib.h" 2>/dev/null)
|
||||
ifdef WITH_ZLIB
|
||||
WITH_ZLIB:=1
|
||||
endif
|
||||
endif
|
||||
|
||||
|
||||
# sets the default paths
|
||||
ifdef UNIX
|
||||
ifndef OSX
|
||||
ifndef MORPHOS
|
||||
ifndef BIN_DIR
|
||||
#BINARY_DIR:=
|
||||
#DATA_DIR_PREFIX:=
|
||||
#INSTALL_DIR:=/usr/local/
|
||||
#USE_HOMEDIR:=
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endif
|
Binary file not shown.
Binary file not shown.
Before Width: | Height: | Size: 14 KiB |
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue