Initial import

This commit is contained in:
Simon Morgan 2017-08-05 16:30:32 +01:00
commit 64aec5d376
47 changed files with 19141 additions and 0 deletions

340
License.txt Normal file
View File

@ -0,0 +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.

42
ReadMe.txt Normal file
View File

@ -0,0 +1,42 @@
SPACE TRADER 1.2.2 SOURCE CODE
******************************
This package contains the source code of Space Trader 1.2.2. The author and copyright holder of Space Trader is Pieter Spronck. The homepage for the game is http://www.spronck.net/picoverse/spacetrader.
You should unzip the package with the option to create subdirectories on.
License
*******
This code is distributed under the GNU General Public License. The GPL license is found in the file License.txt, included in the package, and can also be found on the Web at http://www.opensource.org/licenses/gpl-license.html or http://www.gnu.org/copyleft/gpl.html.
In general, this license protects the author's copyright to his own code, but allows others to create their own programs based on this code, provided they distribute these programs under the same conditions as the original program, that is, also under the GPL license (which means, among other things, that you should release the program with source code). There are, of course, more details to the license, which you can look up in the complete license text.
Please do not release a new version of Space Trader without consulting me. For the time being, I would prefer to remain the only person who releases Space Trader versions. You can, however, create new programs based on the Space Trader code, port Space Trader to another platform or translate it into another language (please, consult me before you do that, and be warned that I still intend to enhance the program), use parts of the code in your own programs, and experiment with changes which you can then email to me so I can incorporate them in a new release.
In addition, if you do wish to make use of this code for another program, I'd like you to mention this somewhere in your program, and to inform me of your efforts, especially if you intend to distribute it. If nothing else, I might give you some advice on how to best use the code. Or, in case you intend to port it to another platform, I can inform you whether or not someone else is already creating such a port.
Note that the in-game pictures, except for the program's icon, are copyrighted by Alexander Lawrence. You can contact him at al_virtual@yahoo.com.
Coding environment
******************
Space Trader is developed in C with CodeWarrior for the Palm, version 8.3. I used the 4.0 SDKs with the latest patches which include many warnings about OS 5.0 idiosyncracies. Any issues previous versions of the code had with OS 5.0 have been resolved for this release. For version 1.2.2 of Space Trader I found the Constructor had problems, so I used the Constructor version 1.9, which comes with CodeWarrior 9. I could not transfer all source codes to CodeWarrior 9, because they started to generate errors there.
I use a tab setting of 4.
In the Space Trader project file, three targets are defined: a color version, a grayscale version and a black & white version. Each of these targets creates a PRC file with the name SpaceTrader.prc. You should make each target separately and rename it to the appropriate name. I could have specified a different output name for each target, but then you would not be able to replace one with another on your Palm. If you want to add a new picture to the game, you must add the black & white version to the MerchantBW resource file, the grayscale version to the MerchantGray resource file, and the color version to the MerchantColor resource file. You must also add a BitmapFamily for the new picture to each of these resource files, and this BitmapFamily MUST have the same name and number in each of the files. Check the other BitmapFamilies for examples.
The current code supports Palm OS 2.0 and higher. I have not used any functions that didn't exist in OS version 2.0. Of course, the color and grayscale versions need at least OS 3.5 to run. If you update the code, be very careful using functions not defined in the OS 2.0 feature set. As soon as you use such a function, you restrict the user base considerably. Also note that several control types (like graphic buttons) and fonts (like LargeBold) didn't exist in OS 2.0.
If you create your own version of this program, you should definitely change the Creator ID, otherwise you will get into problems when Space Trader is installed on the same Palm where you install your own version. The Creator ID of Space Trader is "STra", and you need to change it inside the CodeWarrior Constructor (the ID exists in several places in the resource file and in the program code, and it must be changed in all those places).
Remarks
*******
Space Trader is my first Palm program. I am not a Palm programming wizard and haven't studied this environment very deeply. It may be that I haven't used the best way to code certain things.
Copyright (C) 2000, 2001, 2002, 2005 by Pieter Spronck.

0
Rsc/Merchant.rsrc Normal file
View File

0
Rsc/MerchantBW.rsrc Normal file
View File

0
Rsc/MerchantColor.rsrc Normal file
View File

432
Rsc/MerchantGraphics.h Normal file
View File

@ -0,0 +1,432 @@
// Header generated by Constructor for Palm OS (R) 1.6.2
//
// Generated at 17:10:41 on maandag 27 januari 2003
//
// Generated for file: C:\CW8\SourceCode\Space Trader\Rsc\Merchant16bits.rsrc
//
// THIS IS AN AUTOMATICALLY GENERATED HEADER FILE
// DO NOT EDIT - CHANGES MADE TO THIS FILE WILL BE LOST
//
// Palm App Name: "Untitled"
//
// Palm App Version: "1.0"
// Resource: PICT 3900
#define VisitedSystemBitmap 3900
// Resource: PICT 4500
#define WormholeBitmap 4500
// Resource: PICT 3500
#define CurrentSystemBitmap 3500
// Resource: PICT 3300
#define SystemBitmap 3300
// Resource: PICT 3700
#define ShortRangeSystemBitmap 3700
// Resource: PICT 4100
#define CurrentVisitedSystemBitmap 4100
// Resource: PICT 4300
#define VisitedShortRangeSystemBitmap 4300
// Resource: PICT 4700
#define SmallWormholeBitmap 4700
// Resource: PICT 5300
#define FleaBitmap 5300
// Resource: PICT 5500
#define FleaDamagedBitmap 5500
// Resource: PICT 6100
#define GnatBitmap 6100
// Resource: PICT 6300
#define GnatDamagedBitmap 6300
// Resource: PICT 6900
#define FireflyBitmap 6900
// Resource: PICT 7100
#define FireflyDamagedBitmap 7100
// Resource: PICT 7300
#define FireflyShieldedBitmap 7300
// Resource: PICT 7500
#define FireflyShDamBitmap 7500
// Resource: PICT 7700
#define MosquitoBitmap 7700
// Resource: PICT 7900
#define MosquitoDamagedBitmap 7900
// Resource: PICT 8100
#define MosquitoShieldedBitmap 8100
// Resource: PICT 8300
#define MosquitoShDamBitmap 8300
// Resource: PICT 8500
#define BumblebeeBitmap 8500
// Resource: PICT 8700
#define BumblebeeDamagedBitmap 8700
// Resource: PICT 8900
#define BumblebeeShieldedBitmap 8900
// Resource: PICT 9100
#define BumblebeeShDamBitmap 9100
// Resource: PICT 9300
#define BeetleBitmap 9300
// Resource: PICT 9500
#define BeetleDamagedBitmap 9500
// Resource: PICT 9700
#define BeetleShieldedBitmap 9700
// Resource: PICT 9900
#define BeetleShDamBitmap 9900
// Resource: PICT 10100
#define HornetBitmap 10100
// Resource: PICT 10300
#define HornetDamagedBitmap 10300
// Resource: PICT 10500
#define HornetShieldedBitmap 10500
// Resource: PICT 10700
#define HornetShDamBitmap 10700
// Resource: PICT 10900
#define GrasshopperBitmap 10900
// Resource: PICT 11100
#define GrasshopperDamagedBitmap 11100
// Resource: PICT 11300
#define GrasshopperShieldedBitmap 11300
// Resource: PICT 11500
#define GrasshopperShDamBitmap 11500
// Resource: PICT 11700
#define TermiteBitmap 11700
// Resource: PICT 11900
#define TermiteDamagedBitmap 11900
// Resource: PICT 12100
#define TermiteShieldedBitmap 12100
// Resource: PICT 12300
#define TermiteShDamBitmap 12300
// Resource: PICT 12500
#define WaspBitmap 12500
// Resource: PICT 12700
#define WaspDamagedBitmap 12700
// Resource: PICT 12900
#define WaspShieldedBitmap 12900
// Resource: PICT 13100
#define WaspShDamBitmap 13100
// Resource: PICT 13300
#define MonsterBitmap 13300
// Resource: PICT 13500
#define MonsterDamagedBitmap 13500
// Resource: PICT 14100
#define DragonflyBitmap 14100
// Resource: PICT 14300
#define DragonflyDamagedBitmap 14300
// Resource: PICT 14500
#define DragonflyShieldedBitmap 14500
// Resource: PICT 14700
#define DragonflyShDamBitmap 14700
// Resource: PICT 14900
#define MantisBitmap 14900
// Resource: PICT 15100
#define MantisDamagedBitmap 15100
// Resource: PICT 15300
#define MantisShieldedBitmap 15300
// Resource: PICT 15500
#define MantisShDamBitmap 15500
// Resource: PICT 16500
#define RetireBitmap 16500
// Resource: PICT 16700
#define DestroyedBitmap 16700
// Resource: PICT 5100
#define UtopiaBitmap 5100
// Resource: PICT 4900
#define SpaceTraderBitmap 4900
// Resource: PICT 16900
#define PirateBitmap 16900
// Resource: PICT 17100
#define PoliceBitmap 17100
// Resource: PICT 17300
#define TraderBitmap 17300
// Resource: PICT 17500
#define AlienBitmap 17500
// Resource: PICT 17700
#define AttackBitmap 17700
// Resource: PICT 17900
#define Attack2Bitmap 17900
// Resource: PICT 15700
#define ScarabBitmap 15700
// Resource: PICT 18100
#define SpecialBitmap 18100
// Resource: PICT 15900
#define BottleBitmap 15900
// Resource: PICT 16100
#define ScarabDamagedBitmap 16100
// Resource: PICT 18200
#define AboutBitmap 18200
// Resource: tbmf 7900
#define BottleDamagedBitmapFamily 7900
// Resource: tbmf 7800
#define BottleBitmapFamily 7800
// Resource: tbmf 11100
#define Attack2BitmapFamily 11100
// Resource: tbmf 9500
#define PirateBitmapFamily 9500
// Resource: tbmf 9600
#define PoliceBitmapFamily 9600
// Resource: tbmf 9800
#define AlienBitmapFamily 9800
// Resource: tbmf 9700
#define TraderBitmapFamily 9700
// Resource: tbmf 11000
#define AttackBitmapFamily 11000
// Resource: tbmf 9900
#define SpecialBitmapFamily 9900
// Resource: tbmf 7400
#define ScarabBitmapFamily 7400
// Resource: tbmf 7500
#define ScarabDamagedBitmapFamily 7500
// Resource: tbmf 12000
#define DestroyedBitmapFamily 12000
// Resource: tbmf 7300
#define MantisShDamBitmapFamily 7300
// Resource: tbmf 7200
#define MantisShieldedBitmapFamily 7200
// Resource: tbmf 7100
#define MantisDamagedBitmapFamily 7100
// Resource: tbmf 7000
#define MantisBitmapFamily 7000
// Resource: tbmf 6900
#define DragonflyShDamBitmapFamily 6900
// Resource: tbmf 6800
#define DragonflyShieldedBitmapFamily 6800
// Resource: tbmf 6700
#define DragonflyDamagedBitmapFamily 6700
// Resource: tbmf 6600
#define DragonflyBitmapFamily 6600
// Resource: tbmf 6300
#define MonsterDamagedBitmapFamily 6300
// Resource: tbmf 6200
#define MonsterBitmapFamily 6200
// Resource: tbmf 6100
#define WaspShDamBitmapFamily 6100
// Resource: tbmf 6000
#define WaspShieldedBitmapFamily 6000
// Resource: tbmf 5900
#define WaspDamagedBitmapFamily 5900
// Resource: tbmf 5800
#define WaspBitmapFamily 5800
// Resource: tbmf 5700
#define TermiteShDamBitmapFamily 5700
// Resource: tbmf 5600
#define TermiteShieldedBitmapFamily 5600
// Resource: tbmf 5500
#define TermiteDamagedBitmapFamily 5500
// Resource: tbmf 5400
#define TermiteBitmapFamily 5400
// Resource: tbmf 5300
#define GrasshopperShDamBitmapFamily 5300
// Resource: tbmf 5200
#define GrasshopperShieldedBitmapFamily 5200
// Resource: tbmf 5100
#define GrasshopperDamagedBitmapFamily 5100
// Resource: tbmf 5000
#define GrasshopperBitmapFamily 5000
// Resource: tbmf 4900
#define HornetShDamBitmapFamily 4900
// Resource: tbmf 4800
#define HornetShieldedBitmapFamily 4800
// Resource: tbmf 4700
#define HornetDamagedBitmapFamily 4700
// Resource: tbmf 4600
#define HornetBitmapFamily 4600
// Resource: tbmf 4500
#define BeetleShDamBitmapFamily 4500
// Resource: tbmf 4400
#define BeetleShieldedBitmapFamily 4400
// Resource: tbmf 4300
#define BeetleDamagedBitmapFamily 4300
// Resource: tbmf 4200
#define BeetleBitmapFamily 4200
// Resource: tbmf 4100
#define BumblebeeShDamBitmapFamily 4100
// Resource: tbmf 4000
#define BumblebeeShieldedBitmapFamily 4000
// Resource: tbmf 3900
#define BumblebeeDamagedBitmapFamily 3900
// Resource: tbmf 3800
#define BumblebeeBitmapFamily 3800
// Resource: tbmf 3700
#define MosquitoShDamBitmapFamily 3700
// Resource: tbmf 3600
#define MosquitoShieldedBitmapFamily 3600
// Resource: tbmf 3500
#define MosquitoDamagedBitmapFamily 3500
// Resource: tbmf 3400
#define MosquitoBitmapFamily 3400
// Resource: tbmf 3300
#define FireflyShDamBitmapFamily 3300
// Resource: tbmf 3200
#define FireflyShieldedBitmapFamily 3200
// Resource: tbmf 3100
#define FireflyDamagedBitmapFamily 3100
// Resource: tbmf 3000
#define FireflyBitmapFamily 3000
// Resource: tbmf 2700
#define GnatDamagedBitmapFamily 2700
// Resource: tbmf 2600
#define GnatBitmapFamily 2600
// Resource: tbmf 1100
#define RetireBitmapFamily 1100
// Resource: tbmf 2300
#define FleaDamagedBitmapFamily 2300
// Resource: tbmf 2200
#define FleaBitmapFamily 2200
// Resource: tbmf 1800
#define UtopiaBitmapFamily 1800
// Resource: tbmf 1500
#define SpaceTraderBitmapFamily 1500
// Resource: tbmf 1700
#define SmallWormholeBitmapFamily 1700
// Resource: tbmf 1600
#define WormholeBitmapFamily 1600
// Resource: tbmf 2100
#define VisitedShortRangeSystemBitmapFamily 2100
// Resource: tbmf 2000
#define CurrentVisitedSystemBitmapFamily 2000
// Resource: tbmf 1900
#define VisitedSystemBitmapFamily 1900
// Resource: tbmf 1400
#define ShortRangeSystemBitmapFamily 1400
// Resource: tbmf 1300
#define CurrentSystemBitmapFamily 1300
// Resource: tbmf 1200
#define SystemBitmapFamily 1200
// Resource: tbmf 1000
#define AboutBitmapFamily 1000

0
Rsc/MerchantGray.rsrc Normal file
View File

2423
Rsc/MerchantRsc.h Normal file

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 202 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 282 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 297 KiB

BIN
Space Trader.mcp Normal file

Binary file not shown.

763
Src/AppHandleEvent.c Normal file
View File

@ -0,0 +1,763 @@
/***********************************************************************
*
* SPACE TRADER 1.2.0
*
* AppHandleEvent.c
*
* Copyright (C) 2000-2002 Pieter Spronck, All Rights Reserved
*
* Additional coding by Sam Anderson (rulez2@home.com)
* Additional coding by Samuel Goldstein (palm@fogbound.net)
*
* Some code of Matt Lee's Dope Wars program has been used.
*
* 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.
*
* You can contact the author at space_trader@hotmail.com
*
* For those who are familiar with the classic game Elite: many of the
* ideas in Space Trader are heavily inspired by Elite.
*
**********************************************************************/
#include "external.h"
// *************************************************************************
// The standard menu handling of all "Docked" forms.
// *************************************************************************
static Boolean DockedFormDoCommand(Word command)
{
Boolean handled = true;
FormPtr frm;
Handle AmountH;
int NewForm = -1;
UInt16 buttonPressed = 0;
Boolean inOpts;
Boolean SkipOptions1;
char label1[21], label2[21], label3[21], label4[21];
switch (command)
{
case MenuGameNewGame:
if (FrmAlert( NewGameAlert) == NewGameYes)
StartNewGame();
break;
case MenuGameSnapshot:
if (SaveGame( 1 ))
FrmAlert( GameSavedAlert );
break;
case MenuGameSwitchGame:
if (FrmAlert( SwitchGameAlert ) != SwitchGameYes)
break;
if (SaveGame( 2 ))
{
if (NameCommander[0] == '\0')
{
FrmAlert( SwitchToNewAlert );
IdentifyStartup = true;
StartNewGame();
}
else
{
FrmCustomAlert( SwitchedAlert, NameCommander, "", "" );
FrmGotoForm( CurForm );
}
}
break;
case MenuGameHighScores:
ViewHighScores();
break;
case MenuGameClearHighScores:
ClearHighScores();
break;
case MenuHelpAbout:
AutoAttack = false;
AutoFlee = false;
MenuEraseStatus( 0 );
frm = FrmInitForm( AboutForm );
FrmDoDialog( frm );
FrmDeleteForm( frm );
break;
case MenuCommandGalacticChart:
NewForm = GalacticChartForm;
break;
case MenuCommandSystemInformation:
NewForm = SystemInformationForm;
break;
case MenuCommandShortRangeChart:
NewForm = WarpForm;
break;
case MenuCommandBuyCargo:
NewForm = BuyCargoForm;
break;
case MenuCommandSellCargo:
NewForm = SellCargoForm;
break;
case MenuCommandShipYard:
NewForm = ShipYardForm;
break;
case MenuCommandBuyEquipment:
NewForm = BuyEquipmentForm;
break;
case MenuCommandSellEquipment:
NewForm = SellEquipmentForm;
break;
case MenuCommandPersonnelRoster:
NewForm = PersonnelRosterForm;
break;
case MenuCommandCommanderStatus:
NewForm = CommanderStatusForm;
break;
case MenuCommandBank:
NewForm = BankForm;
break;
case MenuGameRetire:
if (FrmAlert( RetireAlert) == RetireYes)
NewForm = RetireForm;
break;
case MenuGameShortcuts:
AutoAttack = false;
AutoFlee = false;
MenuEraseStatus( 0 );
frm = FrmInitForm( ShortcutsForm );
SetTriggerList(frm, ShortcutsShortcuts1List, Shortcut1);
SetTriggerList(frm, ShortcutsShortcuts2List, Shortcut2);
SetTriggerList(frm, ShortcutsShortcuts3List, Shortcut3);
SetTriggerList(frm, ShortcutsShortcuts4List, Shortcut4);
SysStringByIndex(ShortcutTextStringList,Shortcut1, label1, 21);
SetControlLabel(frm, ShortcutsShortcut1PopTrigger, label1);
SysStringByIndex(ShortcutTextStringList,Shortcut2, label2, 21);
SetControlLabel(frm, ShortcutsShortcut2PopTrigger, label2);
SysStringByIndex(ShortcutTextStringList,Shortcut3, label3, 21);
SetControlLabel(frm, ShortcutsShortcut3PopTrigger, label3);
SysStringByIndex(ShortcutTextStringList,Shortcut4, label4, 21);
SetControlLabel(frm, ShortcutsShortcut4PopTrigger, label4);
buttonPressed = FrmDoDialog( frm );
Shortcut1 = GetTriggerList(frm, ShortcutsShortcuts1List);
Shortcut2 = GetTriggerList(frm, ShortcutsShortcuts2List);
Shortcut3 = GetTriggerList(frm, ShortcutsShortcuts3List);
Shortcut4 = GetTriggerList(frm, ShortcutsShortcuts4List);
FrmDeleteForm( frm );
if (CurForm == SystemInformationForm || CurForm == WarpForm || CurForm == GalacticChartForm ||
CurForm == ExecuteWarpForm || CurForm == BuyCargoForm || CurForm == SellCargoForm ||
CurForm == ShipYardForm || CurForm == BuyShipForm || CurForm == BuyEquipmentForm ||
CurForm == SellEquipmentForm | CurForm == PersonnelRosterForm ||
CurForm == CommanderStatusForm || CurForm == BankForm || CurForm == CurrentShipForm ||
CurForm == QuestsForm || CurForm == SpecialCargoForm)
{
FrmGotoForm(CurForm);
}
break;
case MenuGameOptions:
AutoAttack = false;
AutoFlee = false;
SkipOptions1 = false;
MenuEraseStatus( 0 );
inOpts = true;
while (inOpts)
{
if (!SkipOptions1)
{
frm = FrmInitForm( OptionsForm );
SetCheckBox( frm, OptionsAutoFuelCheckbox, AutoFuel );
SetCheckBox( frm, OptionsAutoRepairCheckbox, AutoRepair );
SetCheckBox( frm, OptionsAlwaysIgnoreTradersCheckbox, AlwaysIgnoreTraders );
SetCheckBox( frm, OptionsAlwaysIgnorePoliceCheckbox, AlwaysIgnorePolice );
SetCheckBox( frm, OptionsAlwaysIgnorePiratesCheckbox, AlwaysIgnorePirates );
SetCheckBox( frm, OptionsTradeInOrbitCheckbox, AlwaysIgnoreTradeInOrbit );
SetCheckBox( frm, OptionsReserveMoneyCheckbox, ReserveMoney );
SetCheckBox( frm, OptionsAlwaysInfoCheckbox, AlwaysInfo );
SetCheckBox( frm, OptionsContinuousCheckbox, Continuous );
SetCheckBox( frm, OptionsAttackFleeingCheckbox, AttackFleeing );
StrIToA( SBuf, min( 99, LeaveEmpty ) );
AmountH = (Handle) SetField( frm, OptionsLeaveEmptyField, SBuf, 4, true );
buttonPressed = FrmDoDialog( frm );
GetField( frm, OptionsLeaveEmptyField, SBuf, AmountH );
if (SBuf[0] == '\0')
LeaveEmpty = 0;
else
LeaveEmpty = StrAToI( SBuf );
AutoFuel = GetCheckBox( frm, OptionsAutoFuelCheckbox );
AutoRepair = GetCheckBox( frm, OptionsAutoRepairCheckbox );
AlwaysIgnoreTraders = GetCheckBox( frm, OptionsAlwaysIgnoreTradersCheckbox );
AlwaysIgnorePolice = GetCheckBox( frm, OptionsAlwaysIgnorePoliceCheckbox );
AlwaysIgnorePirates = GetCheckBox( frm, OptionsAlwaysIgnorePiratesCheckbox );
AlwaysIgnoreTradeInOrbit = GetCheckBox( frm, OptionsTradeInOrbitCheckbox );
ReserveMoney = GetCheckBox( frm, OptionsReserveMoneyCheckbox );
AlwaysInfo = GetCheckBox( frm, OptionsAlwaysInfoCheckbox );
Continuous = GetCheckBox( frm, OptionsContinuousCheckbox );
AttackFleeing = GetCheckBox( frm, OptionsAttackFleeingCheckbox );
FrmDeleteForm( frm );
if (buttonPressed != OptionsOptions2Button)
{
inOpts = false;
}
SkipOptions1 = true;
}
else
{
SkipOptions1 = false;
frm = FrmInitForm( Options2Form );
#ifdef SELECTRECT
if (BELOW50)
{
FrmHideObject( frm, FrmGetObjectIndex( frm, Options2RectOnButton ) );
FrmHideObject( frm, FrmGetObjectIndex( frm, Options2RectOffButton ) );
}
else if (RectangularButtonsOn)
{
FrmHideObject( frm, FrmGetObjectIndex( frm, Options2RectOnButton ) );
FrmShowObject( frm, FrmGetObjectIndex( frm, Options2RectOffButton ) );
}
else
{
FrmHideObject( frm, FrmGetObjectIndex( frm, Options2RectOffButton ) );
FrmShowObject( frm, FrmGetObjectIndex( frm, Options2RectOnButton ) );
}
#endif
SetCheckBox( frm, Options2AutoNewsPayCheckbox, NewsAutoPay );
SetCheckBox( frm, Options2UseHWButtonsCheckbox, UseHWButtons );
SetCheckBox( frm, Options2ShowRangeCheckbox, ShowTrackedRange );
SetCheckBox( frm, Options2TrackAutoOffCheckbox, TrackAutoOff );
SetCheckBox( frm, Options2TextualEncountersCheckbox, TextualEncounters );
SetCheckBox( frm, Options2RemindLoansCheckbox, RemindLoans );
SetCheckBox( frm, Options2SharePreferencesCheckbox, SharePreferences );
SetCheckBox( frm, Options2IdentifyStartupCheckbox, IdentifyStartup );
buttonPressed = FrmDoDialog( frm );
NewsAutoPay = GetCheckBox( frm, Options2AutoNewsPayCheckbox );
UseHWButtons = GetCheckBox( frm, Options2UseHWButtonsCheckbox );
ShowTrackedRange = GetCheckBox( frm, Options2ShowRangeCheckbox );
TrackAutoOff = GetCheckBox( frm, Options2TrackAutoOffCheckbox );
TextualEncounters = GetCheckBox( frm, Options2TextualEncountersCheckbox );
RemindLoans = GetCheckBox( frm, Options2RemindLoansCheckbox );
SharePreferences = GetCheckBox( frm, Options2SharePreferencesCheckbox );
IdentifyStartup = GetCheckBox( frm, Options2IdentifyStartupCheckbox );
FrmDeleteForm( frm );
#ifdef SELECTRECT
if (buttonPressed == Options2RectOnButton || buttonPressed == Options2RectOffButton)
{
if (buttonPressed == Options2RectOnButton)
{
if (FrmAlert( RectangularButtonsOnAlert ) == RectangularButtonsOnYes)
{
RectangularButtonsOn = true;
FrmAlert( AttemptRectangularAlert );
}
}
else
RectangularButtonsOn = false;
SkipOptions1 = true;
}
else
#endif
if (buttonPressed != Options2Options1Button)
{
inOpts = false;
}
}
}
break;
case MenuHelpHowToPlay:
FrmHelp( HowToPlayString );
break;
case MenuHelpTrading:
FrmHelp( TradingString );
break;
case MenuHelpTraveling:
FrmHelp( TravellingString );
break;
case MenuHelpShipEquipment:
FrmHelp( ShipEquipmentString );
break;
case MenuHelpSkills:
FrmHelp( SkillsString );
break;
case MenuHelpAcknowledgements:
FrmHelp( AcknowledgementsString );
break;
case MenuHelpFirstSteps:
FrmHelp( FirstStepsString );
break;
case MenuHelpHelpOnMenu:
FrmHelp( HelpOnMenuString );
break;
case MenuHelpHelpCurrentScreen:
AutoAttack = false;
AutoFlee = false;
switch (FrmGetActiveFormID())
{
case BuyCargoForm:
FrmHelp( BuyCargoString );
break;
case SellCargoForm:
FrmHelp( SellCargoString );
break;
case ShipYardForm:
FrmHelp( ShipYardString );
break;
case BuyShipForm:
FrmHelp( BuyShipString );
break;
case ShiptypeInfoForm:
FrmHelp( ShiptypeInfoString );
break;
case BuyEquipmentForm:
FrmHelp( BuyEquipmentString );
break;
case SellEquipmentForm:
FrmHelp( SellEquipmentString );
break;
case PersonnelRosterForm:
FrmHelp( PersonnelRosterString );
break;
case SystemInformationForm:
FrmHelp( SystemInformationString );
break;
case GalacticChartForm:
FrmHelp( GalacticChartString );
break;
case WarpForm:
FrmHelp( WarpString );
break;
case ExecuteWarpForm:
FrmHelp( ExecuteWarpString );
break;
case CommanderStatusForm:
FrmHelp( CommanderStatusString );
break;
case AveragePricesForm:
FrmHelp( AveragePricesString );
break;
case BankForm:
FrmHelp( BankString );
break;
case CurrentShipForm:
FrmHelp( CurrentShipString );
break;
case QuestsForm:
FrmHelp( QuestsString );
break;
case PlunderForm:
FrmHelp( PlunderString );
break;
case EncounterForm:
FrmHelp( EncounterString );
break;
case MainForm:
FrmHelp( HowToPlayString );
break;
case NewCommanderForm:
FrmHelp( NewCommanderString );
break;
case RetireForm:
case UtopiaForm:
case DestroyedForm:
FrmHelp( RetireDestroyedUtopiaString );
break;
default:
FrmHelp( MainString );
break;
}
break;
default:
handled = false;
break;
}
if (NewForm >= 0)
{
CurForm = NewForm;
FrmGotoForm( CurForm );
}
return handled;
}
// *************************************************************************
// This routine loads form resources and set the event handler for the form loaded.
// *************************************************************************
Boolean AppHandleEvent( EventPtr eventP)
{
Word formId;
FormPtr frmP;
int i, Dock;
FormEventHandlerType* Set;
Set = 0L;
Dock = -1;
if (eventP->eType == frmLoadEvent)
{
// Load the form resource.
formId = eventP->data.frmLoad.formID;
frmP = FrmInitForm(formId);
FrmSetActiveForm(frmP);
// Set the event handler for the form. The handler of the currently
// active form is called by FrmHandleEvent each time is receives an
// event.
switch (formId)
{
case MainForm:
Set = MainFormHandleEvent;
break;
case NewCommanderForm:
Set = NewCommanderFormHandleEvent;
break;
case SpecialCargoForm:
Set = SpecialCargoFormHandleEvent;
break;
case SystemInformationForm:
Set = SystemInformationFormHandleEvent;
break;
case GalacticChartForm:
Set = GalacticChartFormHandleEvent;
break;
case WarpForm:
Set = WarpFormHandleEvent;
break;
case ExecuteWarpForm:
Set = ExecuteWarpFormHandleEvent;
break;
case AveragePricesForm:
Set = AveragePricesFormHandleEvent;
break;
case BuyCargoForm:
Set = BuyCargoFormHandleEvent;
break;
case SellCargoForm:
Set = SellCargoFormHandleEvent;
break;
case DumpCargoForm:
Set = DiscardCargoFormHandleEvent;
break;
case ShipYardForm:
Set = ShipYardFormHandleEvent;
break;
case BuyShipForm:
Set = BuyShipFormHandleEvent;
break;
case ShiptypeInfoForm:
Set = ShiptypeInfoFormHandleEvent;
break;
case BuyEquipmentForm:
Set = BuyEquipmentFormHandleEvent;
break;
case SellEquipmentForm:
Set = SellEquipmentFormHandleEvent;
break;
case PersonnelRosterForm:
Set = PersonnelRosterFormHandleEvent;
break;
case SpecialEventForm:
Set = SpecialEventFormHandleEvent;
break;
case CommanderStatusForm:
Set = CommanderStatusFormHandleEvent;
break;
case BankForm:
Set = BankFormHandleEvent;
break;
case EncounterForm:
Set = EncounterFormHandleEvent;
break;
case PlunderForm:
Set = PlunderFormHandleEvent;
break;
case CurrentShipForm:
Set = CurrentShipFormHandleEvent;
break;
case QuestsForm:
Set = QuestsFormHandleEvent;
break;
case RetireForm:
Set = RetireFormHandleEvent;
break;
case UtopiaForm:
Set = UtopiaFormHandleEvent;
break;
case DestroyedForm:
Set = DestroyedFormHandleEvent;
break;
case NewspaperForm:
Set = NewspaperFormHandleEvent;
break;
default:
break;
}
if (Set != 0L)
FrmSetEventHandler( frmP, Set );
return true;
}
else if (eventP->eType == menuEvent)
{
return DockedFormDoCommand( eventP->data.menu.itemID );
}
else if (eventP->eType == ctlSelectEvent)
{
if (eventP->data.ctlSelect.controlID >= CurForm+49 &&
eventP->data.ctlSelect.controlID <= CurForm+53)
{
i = eventP->data.ctlSelect.controlID - CurForm - 49;
switch (i)
{
case 0:
return true;
case 1:
Dock = ShortcutTarget[Shortcut1];
break;
case 2:
Dock = ShortcutTarget[Shortcut2];
break;
case 3:
Dock = ShortcutTarget[Shortcut3];
break;
case 4:
Dock = ShortcutTarget[Shortcut4];
break;
}
if (Dock >= 0)
return DockedFormDoCommand( Dock );
return false;
}
}
else if (eventP->eType == keyDownEvent &&
!((eventP->data.keyDown.chr == chrPageUp) ||
(eventP->data.keyDown.chr == chrPageDown)))
{
// trap accidental hw button presses
if ( (eventP->data.keyDown.chr == hard1Chr ||
eventP->data.keyDown.chr == hard2Chr ||
eventP->data.keyDown.chr == hard3Chr ||
eventP->data.keyDown.chr == hard4Chr) &&
CurForm != EncounterForm && CurForm != SystemInformationForm &&
CurForm != WarpForm && CurForm != GalacticChartForm && CurForm != ExecuteWarpForm &&
CurForm != BuyCargoForm && CurForm != SellCargoForm && CurForm != ShipYardForm &&
CurForm != BuyShipForm && CurForm != BuyEquipmentForm && CurForm != SellEquipmentForm &&
CurForm != PersonnelRosterForm && CurForm != CommanderStatusForm &&
CurForm != BankForm && CurForm != CurrentShipForm && CurForm != QuestsForm &&
CurForm != SpecialCargoForm)
return true;
if (CurForm != EncounterForm && CurForm != MainForm && CurForm != NewCommanderForm &&
CurForm != PlunderForm && CurForm != DestroyedForm && CurForm != RetireForm &&
CurForm != UtopiaForm && CurForm != SpecialEventForm)
{
switch (TOLOWER( eventP->data.keyDown.chr ))
{
// Address HW Button maps to Buy Cargo
case hard1Chr:
Dock = ShortcutTarget[Shortcut1];
break;
// Phone HW Button maps to Sell Cargo
case hard2Chr:
Dock = ShortcutTarget[Shortcut2];
break;
// To-do HW Button maps to Ship Yard
case hard3Chr:
Dock = ShortcutTarget[Shortcut3];
break;
// Memo HW Button maps to Short Range Chart
case hard4Chr:
Dock = ShortcutTarget[Shortcut4];
break;
case 'b':
Dock = MenuCommandBuyCargo;
break;
case 's':
Dock = MenuCommandSellCargo;
break;
case 'y':
Dock = MenuCommandShipYard;
break;
case 'e':
Dock = MenuCommandBuyEquipment;
break;
case 'q':
Dock = MenuCommandSellEquipment;
break;
case 'p':
Dock = MenuCommandPersonnelRoster;
break;
case 'k':
Dock = MenuCommandBank;
break;
case 'i':
Dock = MenuCommandSystemInformation;
break;
case 'c':
Dock = MenuCommandCommanderStatus;
break;
case 'g':
Dock = MenuCommandGalacticChart;
break;
case 'w':
Dock = MenuCommandShortRangeChart;
break;
}
}
if (CurForm != NewCommanderForm)
{
switch (TOLOWER( eventP->data.keyDown.chr ))
{
case 'h':
Dock = MenuHelpHelpCurrentScreen;
break;
case 'o':
Dock = MenuGameOptions;
break;
}
}
if (Dock >= 0)
return DockedFormDoCommand( Dock );
}
return false;
}

1
Src/BW.h Normal file
View File

@ -0,0 +1 @@
#define BPP1 1

251
Src/Bank.c Normal file
View File

@ -0,0 +1,251 @@
/***********************************************************************
*
* SPACE TRADER 1.2.0
*
* Bank.c
*
* Copyright (C) 2000-2002 Pieter Spronck, All Rights Reserved
*
* Additional coding by Sam Anderson (rulez2@home.com)
* Additional coding by Samuel Goldstein (palm@fogbound.net)
*
* Some code of Matt Lee's Dope Wars program has been used.
*
* 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.
*
* You can contact the author at space_trader@hotmail.com
*
* For those who are familiar with the classic game Elite: many of the
* ideas in Space Trader are heavily inspired by Elite.
*
**********************************************************************/
#include "external.h"
// *************************************************************************
// Maximum loan
// *************************************************************************
static long MaxLoan( void )
{
return (PoliceRecordScore >= CLEANSCORE ?
min( 25000L, max( 1000L, ((CurrentWorth() / 10L) / 500L) * 500L ) ) : 500L);
}
// *************************************************************************
// Lending money
// *************************************************************************
static void GetLoan( long Loan )
{
long Amount;
Amount = min( MaxLoan() - Debt, Loan );
Credits += Amount;
Debt += Amount;
}
// *************************************************************************
// Paying back
// *************************************************************************
static void PayBack( long Cash )
{
long Amount;
Amount = min( Debt, Cash );
Amount = min( Amount, Credits );
Credits -= Amount;
Debt -= Amount;
}
// *************************************************************************
// Show the Bank screen
// *************************************************************************
static void ShowBank( void )
{
FormPtr frmP;
frmP = FrmGetActiveForm();
RectangularShortcuts( frmP, BankBButton );
if (Debt <= 0)
FrmHideObject( frmP, FrmGetObjectIndex( frmP, BankPayBackButton ) );
else
FrmShowObject( frmP, FrmGetObjectIndex( frmP, BankPayBackButton ) );
if (Insurance)
{
FrmHideObject( frmP, FrmGetObjectIndex( frmP, BankBuyInsuranceButton ) );
FrmShowObject( frmP, FrmGetObjectIndex( frmP, BankStopInsuranceButton ) );
}
else
{
FrmShowObject( frmP, FrmGetObjectIndex( frmP, BankBuyInsuranceButton ) );
FrmHideObject( frmP, FrmGetObjectIndex( frmP, BankStopInsuranceButton ) );
}
FrmDrawForm( frmP );
EraseRectangle( 80, 32, 80, 26 );
StrIToA( SBuf, Debt );
StrCat( SBuf, " cr." );
DrawChars( SBuf, 80, 32 );
StrIToA( SBuf, MaxLoan() );
StrCat( SBuf, " cr." );
DrawChars( SBuf, 80, 46 );
EraseRectangle( 80, 100, 80, 40 );
StrIToA( SBuf, CurrentShipPriceWithoutCargo( true ) );
StrCat( SBuf, " cr. " );
DrawChars( SBuf, 80, 100 );
StrIToA( SBuf, min( NoClaim, 90 ) );
StrCat( SBuf, "%" );
if (NoClaim == 90)
StrCat( SBuf, " (maximum)" );
DrawChars( SBuf, 80, 114 );
StrIToA( SBuf, InsuranceMoney() );
StrCat( SBuf, " cr. daily" );
DrawChars( SBuf, 80, 128 );
DisplayTradeCredits();
}
// *************************************************************************
// Handling of events on the Bank screen
// *************************************************************************
Boolean BankFormHandleEvent(EventPtr eventP)
{
Boolean handled = false;
FormPtr frmP;
int d;
long Amount;
Handle AmountH;
switch (eventP->eType)
{
case frmOpenEvent:
case frmUpdateEvent:
ShowBank();
handled = true;
break;
case ctlSelectEvent:
if (eventP->data.ctlSelect.controlID == BankGetLoanButton)
{
if (Debt >= MaxLoan())
{
FrmAlert( DebtTooHighAlert );
handled = true;
break;
}
frmP = FrmInitForm( GetLoanForm );
AmountH = (Handle) SetField( frmP, GetLoanGetLoanField, "", 6, true );
StrCopy( SBuf, "You can borrow up to " );
StrIToA( SBuf2, (MaxLoan() - Debt) );
StrCat( SBuf, SBuf2 );
StrCat( SBuf, " credits." );
setLabelText( frmP, GetLoanMaxLoanLabel, SBuf );
d = FrmDoDialog( frmP );
GetField( frmP, GetLoanGetLoanField, SBuf, AmountH );
if (SBuf[0] == '\0')
Amount = 0;
else
Amount = StrAToI( SBuf );
FrmDeleteForm( frmP );
if (d == GetLoanEverythingButton)
GetLoan( MaxLoan() );
else if (d != GetLoanNothingButton)
GetLoan( Amount );
}
else if (eventP->data.ctlSelect.controlID == BankPayBackButton)
{
if (Debt <= 0)
{
FrmAlert( NoDebtAlert );
handled = true;
break;
}
frmP = FrmInitForm( PayBackForm );
AmountH = (Handle) SetField( frmP, PayBackPayBackField, "", 6, true );
StrCopy( SBuf, "You have a debt of " );
StrIToA( SBuf2, Debt );
StrCat( SBuf, SBuf2 );
StrCat( SBuf, " credits." );
setLabelText( frmP, PayBackMaxDebtLabel, SBuf );
d = FrmDoDialog( frmP );
GetField( frmP, PayBackPayBackField, SBuf, AmountH );
if (SBuf[0] == '\0')
Amount = 0;
else
Amount = StrAToI( SBuf );
FrmDeleteForm( frmP );
if (d == PayBackEverythingButton)
PayBack( 99999 );
else if (d != PayBackNothingButton)
PayBack( Amount );
}
else if (eventP->data.ctlSelect.controlID == BankBuyInsuranceButton)
{
if (!EscapePod)
{
FrmAlert( NoEscapePodAlert );
handled = true;
break;
}
Insurance = true;
}
else if (eventP->data.ctlSelect.controlID == BankStopInsuranceButton)
{
if (FrmAlert( StopInsuranceAlert ) == StopInsuranceNo)
{
handled = true;
break;
}
Insurance = false;
NoClaim = 0;
}
ShowBank();
handled = true;
break;
default:
break;
}
return handled;
}

165
Src/BuyEquipEvent.c Normal file
View File

@ -0,0 +1,165 @@
/***********************************************************************
*
* SPACE TRADER 1.2.0
*
* BuyEquipEvent.c
*
* Copyright (C) 2000-2002 Pieter Spronck, All Rights Reserved
*
* Additional coding by Sam Anderson (rulez2@home.com)
* Additional coding by Samuel Goldstein (palm@fogbound.net)
*
* Some code of Matt Lee's Dope Wars program has been used.
*
* 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.
*
* You can contact the author at space_trader@hotmail.com
*
* For those who are familiar with the classic game Elite: many of the
* ideas in Space Trader are heavily inspired by Elite.
*
**********************************************************************/
#include "external.h"
// *************************************************************************
// Draw an item on the screen
// *************************************************************************
static void DrawItem( char* Name, int y, long Price )
{
int j;
FntSetFont( stdFont );
DrawChars( Name, 30, y );
EraseRectangle( 110, y, 56, 9 );
StrIToA( SBuf, Price );
StrCat( SBuf, " cr." );
j = MAXDIGITS - StrLen( SBuf );
if (Price > 0)
DrawChars( SBuf, 124+j*5, y );
else
DrawChars( "not sold", 122, y );
}
static void DrawBuyEquipmentForm()
{
FormPtr frmP = FrmGetActiveForm();
int i;
RectangularShortcuts( frmP, BuyEquipmentBButton );
for (i=0; i<MAXWEAPONTYPE+MAXSHIELDTYPE+MAXGADGETTYPE; ++i)
{
RectangularButton( frmP, BuyEquipmentBuy0Button + i );
if (i < MAXWEAPONTYPE)
{
if (BASEWEAPONPRICE( i ) <= 0)
FrmHideObject( frmP, FrmGetObjectIndex( frmP, BuyEquipmentBuy0Button + i ) );
else
FrmShowObject( frmP, FrmGetObjectIndex( frmP, BuyEquipmentBuy0Button + i ) );
}
else if (i < MAXWEAPONTYPE + MAXSHIELDTYPE)
{
if (BASESHIELDPRICE( i-MAXWEAPONTYPE ) <= 0)
FrmHideObject( frmP, FrmGetObjectIndex( frmP, BuyEquipmentBuy0Button + i ) );
else
FrmShowObject( frmP, FrmGetObjectIndex( frmP, BuyEquipmentBuy0Button + i ) );
}
else
{
if (BASEGADGETPRICE( i-MAXWEAPONTYPE-MAXSHIELDTYPE ) <= 0)
FrmHideObject( frmP, FrmGetObjectIndex( frmP, BuyEquipmentBuy0Button + i ) );
else
FrmShowObject( frmP, FrmGetObjectIndex( frmP, BuyEquipmentBuy0Button + i ) );
}
}
FrmDrawForm( frmP );
for (i=0; i<MAXWEAPONTYPE; ++i)
DrawItem( Weapontype[i].Name, 17+i*13, BASEWEAPONPRICE( i ) );
for (i=0; i<MAXSHIELDTYPE; ++i)
DrawItem( Shieldtype[i].Name, 17+(i+MAXWEAPONTYPE)*13, BASESHIELDPRICE( i ) );
for (i=0; i<MAXGADGETTYPE; ++i)
DrawItem( Gadgettype[i].Name, 17+(i+MAXWEAPONTYPE+MAXSHIELDTYPE)*13, BASEGADGETPRICE( i ) );
DisplayTradeCredits();
}
// *************************************************************************
// Handling of the events of the Buy Equipment form.
// *************************************************************************
Boolean BuyEquipmentFormHandleEvent( EventPtr eventP )
{
Boolean handled = false;
switch (eventP->eType)
{
case frmOpenEvent:
case frmUpdateEvent:
DrawBuyEquipmentForm();
handled = true;
break;
case ctlSelectEvent:
if (eventP->data.ctlSelect.controlID >= BuyEquipmentBuy0Button &&
eventP->data.ctlSelect.controlID < BuyEquipmentBuy0Button+MAXWEAPONTYPE)
{
BuyItem( Shiptype[Ship.Type].WeaponSlots,
Ship.Weapon,
BASEWEAPONPRICE( eventP->data.ctlSelect.controlID - BuyEquipmentBuy0Button ),
Weapontype[eventP->data.ctlSelect.controlID - BuyEquipmentBuy0Button].Name,
eventP->data.ctlSelect.controlID - BuyEquipmentBuy0Button );
}
if (eventP->data.ctlSelect.controlID >= BuyEquipmentBuy0Button+MAXWEAPONTYPE &&
eventP->data.ctlSelect.controlID < BuyEquipmentBuy0Button+MAXWEAPONTYPE+MAXSHIELDTYPE)
{
BuyItem( Shiptype[Ship.Type].ShieldSlots,
Ship.Shield,
BASESHIELDPRICE( eventP->data.ctlSelect.controlID - BuyEquipmentBuy0Button - MAXWEAPONTYPE ),
Shieldtype[eventP->data.ctlSelect.controlID - BuyEquipmentBuy0Button - MAXWEAPONTYPE].Name,
eventP->data.ctlSelect.controlID - BuyEquipmentBuy0Button - MAXWEAPONTYPE );
}
if (eventP->data.ctlSelect.controlID >= BuyEquipmentBuy0Button+MAXWEAPONTYPE+MAXSHIELDTYPE &&
eventP->data.ctlSelect.controlID < BuyEquipmentBuy0Button+MAXWEAPONTYPE+MAXSHIELDTYPE+MAXGADGETTYPE )
{
if (HasGadget( &Ship, eventP->data.ctlSelect.controlID - BuyEquipmentBuy0Button - MAXWEAPONTYPE - MAXSHIELDTYPE ) &&
EXTRABAYS != eventP->data.ctlSelect.controlID - BuyEquipmentBuy0Button - MAXWEAPONTYPE - MAXSHIELDTYPE)
FrmAlert( NoMoreOfItemAlert );
else
{
BuyItem( Shiptype[Ship.Type].GadgetSlots,
Ship.Gadget,
BASEGADGETPRICE( eventP->data.ctlSelect.controlID - BuyEquipmentBuy0Button - MAXWEAPONTYPE - MAXSHIELDTYPE ),
Gadgettype[eventP->data.ctlSelect.controlID - BuyEquipmentBuy0Button - MAXWEAPONTYPE - MAXSHIELDTYPE].Name,
eventP->data.ctlSelect.controlID - BuyEquipmentBuy0Button - MAXWEAPONTYPE - MAXSHIELDTYPE );
}
}
handled = true;
break;
default:
break;
}
return handled;
}

384
Src/BuyShipEvent.c Normal file
View File

@ -0,0 +1,384 @@
/***********************************************************************
*
* SPACE TRADER 1.2.0
*
* BuyShipEvent.c
*
* Copyright (C) 2000-2002 Pieter Spronck, All Rights Reserved
*
* Additional coding by Sam Anderson (rulez2@home.com)
* Additional coding by Samuel Goldstein (palm@fogbound.net)
*
* Some code of Matt Lee's Dope Wars program has been used.
*
* 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.
*
* You can contact the author at space_trader@hotmail.com
*
* For those who are familiar with the classic game Elite: many of the
* ideas in Space Trader are heavily inspired by Elite.
*
**********************************************************************/
#include "external.h"
// *************************************************************************
// Create a new ship.
// *************************************************************************
static void CreateShip( int Index )
{
int i;
Ship.Type = Index;
for (i=0; i<MAXWEAPON; ++i)
{
Ship.Weapon[i] = -1;
}
for (i=0; i<MAXSHIELD; ++i)
{
Ship.Shield[i] = -1;
Ship.ShieldStrength[i] = 0;
}
for (i=0; i<MAXGADGET; ++i)
{
Ship.Gadget[i] = -1;
}
for (i=0; i<MAXTRADEITEM; ++i)
{
Ship.Cargo[i] = 0;
BuyingPrice[i] = 0;
}
Ship.Fuel = GetFuelTanks();
Ship.Hull = Shiptype[Ship.Type].HullStrength;
}
// *************************************************************************
// Buy a new ship.
// *************************************************************************
static void BuyShip( int Index )
{
CreateShip( Index );
Credits -= ShipPrice[Index];
if (ScarabStatus == 3)
ScarabStatus = 0;
}
// *************************************************************************
// Determine Ship Prices depending on tech level of current system.
// *************************************************************************
static void DetermineShipPrices( void )
{
int i;
for (i=0; i<MAXSHIPTYPE; ++i)
{
if (Shiptype[i].MinTechLevel <= CURSYSTEM.TechLevel)
{
ShipPrice[i] = BASESHIPPRICE( i ) - CurrentShipPrice( false );
if (ShipPrice[i] == 0)
ShipPrice[i] = 1;
}
else
ShipPrice[i] = 0;
}
}
// *************************************************************************
// You get a Flea
// *************************************************************************
void CreateFlea( void )
{
int i;
CreateShip( 0 );
for (i=1; i<MAXCREW; ++i)
Ship.Crew[i] = -1;
EscapePod = false;
Insurance = false;
NoClaim = 0;
}
static void DrawBuyShipForm()
{
FormPtr frmP = FrmGetActiveForm();
int i, j;
RectangularShortcuts( frmP, BuyShipBButton );
DetermineShipPrices();
for (i=0; i<MAXSHIPTYPE; ++i)
{
RectangularButton( frmP, BuyShipInfo0Button + i );
RectangularButton( frmP, BuyShipBuy0Button + i );
if (ShipPrice[i] == 0 || Ship.Type == i)
FrmHideObject( frmP, FrmGetObjectIndex( frmP, BuyShipBuy0Button + i ) );
else
FrmShowObject( frmP, FrmGetObjectIndex( frmP, BuyShipBuy0Button + i ) );
FrmShowObject( frmP, FrmGetObjectIndex( frmP, BuyShipInfo0Button + i ) );
}
FrmDrawForm( frmP );
for (i=0; i<MAXSHIPTYPE; ++i)
{
FntSetFont( stdFont );
DrawChars( Shiptype[i].Name, 30, 17+i*13 );
EraseRectangle( 110, 17+i*13, 56, 9 );
StrIToA( SBuf, ShipPrice[i] );
StrCat( SBuf, " cr." );
j = MAXDIGITS - StrLen( SBuf );
if (ShipPrice[i] == 0)
DrawChars( "not sold", 122, 17+i*13 );
else if (Ship.Type == i)
DrawChars( "got one", 123, 17+i*13 );
else
DrawChars( SBuf, 124+j*5+(ShipPrice[i] < 0 ? 1 : 0), 17+i*13 );
}
DisplayTradeCredits();
if (Ship.Tribbles > 0 && !TribbleMessage)
{
FrmAlert( ShipNotWorthMuchAlert );
TribbleMessage = true;
}
}
// *************************************************************************
// Handling of the events of the Buy Ship form.
// *************************************************************************
Boolean BuyShipFormHandleEvent( EventPtr eventP )
{
Boolean handled = false;
Boolean addLightning, addCompactor, addMorganLaser;
Boolean hasLightning, hasCompactor, hasMorganLaser;
long extra;
int d, i, j;
switch (eventP->eType)
{
case frmOpenEvent:
case frmUpdateEvent:
DrawBuyShipForm();
handled = true;
break;
case ctlSelectEvent:
if (eventP->data.ctlSelect.controlID >= BuyShipInfo0Button &&
eventP->data.ctlSelect.controlID <= BuyShipInfo9Button)
{
SelectedShipType = eventP->data.ctlSelect.controlID - BuyShipInfo0Button;
CurForm = ShiptypeInfoForm;
FrmGotoForm( CurForm );
}
else if (eventP->data.ctlSelect.controlID >= BuyShipBuy0Button &&
eventP->data.ctlSelect.controlID <= BuyShipBuy9Button)
{
j = 0;
for (i=0; i<MAXCREW; ++i)
if (Ship.Crew[i] >= 0)
++j;
if (ShipPrice[eventP->data.ctlSelect.controlID - BuyShipBuy0Button] == 0)
FrmAlert( ShipNotAvailableAlert );
else if ((ShipPrice[eventP->data.ctlSelect.controlID - BuyShipBuy0Button] > 0) &&
(Debt > 0))
FrmAlert( YoureInDebtAlert );
else if (ShipPrice[eventP->data.ctlSelect.controlID - BuyShipBuy0Button] > ToSpend())
FrmAlert( CantBuyShipAlert );
else if ((JarekStatus == 1) && (Shiptype[eventP->data.ctlSelect.controlID -
BuyShipBuy0Button].CrewQuarters < 2))
FrmCustomAlert( PassengerNeedsQuartersAlert, "Ambassador Jarek", NULL, NULL );
else if ((WildStatus == 1) && (Shiptype[eventP->data.ctlSelect.controlID -
BuyShipBuy0Button].CrewQuarters < 2))
FrmCustomAlert( PassengerNeedsQuartersAlert, "Jonathan Wild", NULL, NULL );
else if (ReactorStatus > 0 && ReactorStatus < 21)
FrmAlert ( CantSellShipWithReactorAlert );
else
{
extra = 0;
hasLightning = false;
hasCompactor = false;
hasMorganLaser = false;
addLightning = false;
addCompactor = false;
addMorganLaser = false;
if (HasShield( &Ship, LIGHTNINGSHIELD ))
{
if (Shiptype[eventP->data.ctlSelect.controlID - BuyShipBuy0Button].ShieldSlots == 0)
{
// can't transfer the Lightning Shields. How often would this happen?
FrmCustomAlert(CantTransferSlotAlert, Shiptype[eventP->data.ctlSelect.controlID -
BuyShipBuy0Button].Name, "Lightning Shield", "Shield");
}
hasLightning = true;
extra += 30000;
}
if (HasGadget( &Ship, FUELCOMPACTOR ))
{
if (Shiptype[eventP->data.ctlSelect.controlID - BuyShipBuy0Button].GadgetSlots == 0)
{
// can't transfer the Fuel Compactor
FrmCustomAlert(CantTransferSlotAlert, Shiptype[eventP->data.ctlSelect.controlID -
BuyShipBuy0Button].Name, "Fuel Compactor", "Gadget");
}
hasCompactor = true;
extra += 20000;
}
if (HasWeapon( &Ship, MORGANLASERWEAPON, true ))
{
if (Shiptype[eventP->data.ctlSelect.controlID - BuyShipBuy0Button].WeaponSlots == 0)
{
// can't transfer the Laser
FrmCustomAlert(CantTransferSlotAlert, Shiptype[eventP->data.ctlSelect.controlID -
BuyShipBuy0Button].Name, "Morgan's Laser", "Weapon");
}
extra += 33333;
hasMorganLaser = true;
}
if (ShipPrice[eventP->data.ctlSelect.controlID - BuyShipBuy0Button] + extra > ToSpend())
FrmCustomAlert( CantBuyShipWithEquipmentAlert, SBuf, NULL, NULL );
extra = 0;
if (hasLightning && Shiptype[eventP->data.ctlSelect.controlID - BuyShipBuy0Button].ShieldSlots > 0)
{
if (ShipPrice[eventP->data.ctlSelect.controlID - BuyShipBuy0Button] + extra <= ToSpend())
{
d = FrmAlert( TransferLightningShieldAlert );
if (d == 0)
{
addLightning = true;
extra += 30000;
}
}
else
{
FrmCustomAlert ( CantTransferAlert, "Lightning Shield", NULL, NULL );
}
}
if (hasCompactor && Shiptype[eventP->data.ctlSelect.controlID - BuyShipBuy0Button].GadgetSlots > 0)
{
if (ShipPrice[eventP->data.ctlSelect.controlID - BuyShipBuy0Button] + extra <= ToSpend())
{
d = FrmAlert( TransferFuelCompactorAlert );
if (d == 0)
{
addCompactor = true;
extra += 20000;
}
}
else
{
FrmCustomAlert( CantTransferAlert, "Fuel Compactor", NULL, NULL);
}
}
if (hasMorganLaser && Shiptype[eventP->data.ctlSelect.controlID - BuyShipBuy0Button].WeaponSlots > 0)
{
if (ShipPrice[eventP->data.ctlSelect.controlID - BuyShipBuy0Button] + extra <= ToSpend())
{
d = FrmAlert( TransferMorganLaserAlert );
if (d == 0)
{
addMorganLaser = true;
extra += 33333;
}
}
else
{
FrmCustomAlert( CantTransferAlert, "Morgan's Laser", NULL, NULL);
}
}
/*
if (ShipPrice[eventP->data.ctlSelect.controlID - BuyShipBuy0Button] + extra > ToSpend())
FrmCustomAlert( CantBuyShipWithEquipmentAlert, SBuf, NULL, NULL );
*/
if (j > Shiptype[eventP->data.ctlSelect.controlID -
BuyShipBuy0Button].CrewQuarters)
FrmAlert( TooManyCrewmembersAlert );
else
{
/*
frmP = FrmInitForm( TradeInShipForm );
StrCopy( SBuf, Shiptype[Ship.Type].Name );
StrCat( SBuf, " for a new " );
StrCat( SBuf, Shiptype[eventP->data.ctlSelect.controlID -
BuyShipBuy0Button].Name );
StrCat( SBuf, "?" );
setLabelText( frmP, TradeInShipTradeInShipLabel, SBuf );
d = FrmDoDialog( frmP );
FrmDeleteForm( frmP );
*/
if (addCompactor || addLightning || addMorganLaser)
{
StrCopy(SBuf, ", and transfer your unique equipment to the new ship?");
}
else
{
StrCopy(SBuf, "?");
}
d = FrmCustomAlert( TradeShipAlert, Shiptype[Ship.Type].Name,
Shiptype[eventP->data.ctlSelect.controlID - BuyShipBuy0Button].Name,
SBuf);
if (d == TradeShipYes)
{
BuyShip( eventP->data.ctlSelect.controlID - BuyShipBuy0Button );
Credits -= extra;
if (addCompactor)
Ship.Gadget[0] = FUELCOMPACTOR;
if (addLightning)
Ship.Shield[0] = LIGHTNINGSHIELD;
if (addMorganLaser)
Ship.Weapon[0] = MORGANLASERWEAPON;
Ship.Tribbles = 0;
CurForm = BuyShipForm;
FrmGotoForm( CurForm );
}
}
}
}
handled = true;
break;
default:
break;
}
return handled;
}

1286
Src/Cargo.c Normal file

File diff suppressed because it is too large Load Diff

255
Src/CmdrStatusEvent.c Normal file
View File

@ -0,0 +1,255 @@
/***********************************************************************
*
* SPACE TRADER 1.2.0
*
* CmdrStatusEvent.c
*
* Copyright (C) 2000-2002 Pieter Spronck, All Rights Reserved
*
* Additional coding by Sam Anderson (rulez2@home.com)
* Additional coding by Samuel Goldstein (palm@fogbound.net)
*
* Some code of Matt Lee's Dope Wars program has been used.
*
* 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.
*
* You can contact the author at space_trader@hotmail.com
*
* For those who are familiar with the classic game Elite: many of the
* ideas in Space Trader are heavily inspired by Elite.
*
**********************************************************************/
// *************************************************************************
// Commander Status Event Module
// *************************************************************************
#include "external.h"
// *************************************************************************
// Show skill on the Commander Status screen
// *************************************************************************
static void DisplaySkill( int Skill, int AdaptedSkill, FormPtr frmP, long Label )
{
StrIToA( SBuf, Skill );
StrCat( SBuf, " [" );
StrIToA( SBuf2, AdaptedSkill );
StrCat( SBuf, SBuf2 );
StrCat( SBuf, "]" );
setLabelText( frmP, Label, SBuf );
}
// *************************************************************************
// Show the Commander Status screen
// *************************************************************************
static void ShowCommanderStatus( void )
{
FormPtr frmP;
int i;
frmP = FrmGetActiveForm();
RectangularShortcuts( frmP, CommanderStatusBButton );
setLabelText( frmP, CommanderStatusNameLabel, NameCommander );
DisplaySkill( COMMANDER.Pilot, PilotSkill( &Ship ), frmP, CommanderStatusPilotLabel );
DisplaySkill( COMMANDER.Fighter, FighterSkill( &Ship ), frmP, CommanderStatusFighterLabel );
DisplaySkill( COMMANDER.Trader, TraderSkill( &Ship ), frmP, CommanderStatusTraderLabel );
DisplaySkill( COMMANDER.Engineer, EngineerSkill( &Ship ), frmP, CommanderStatusEngineerLabel );
StrIToA( SBuf, PoliceKills + TraderKills + PirateKills );
setLabelText( frmP, CommanderStatusKillsLabel, SBuf );
i = 0;
while (i < MAXPOLICERECORD && PoliceRecordScore >= PoliceRecord[i].MinScore)
++i;
--i;
if (i < 0)
++i;
setLabelText( frmP, CommanderStatusPoliceRecordLabel, PoliceRecord[i].Name );
i = 0;
while (i < MAXREPUTATION && ReputationScore >= Reputation[i].MinScore)
++i;
--i;
if (i < 0)
i = 0;
setLabelText( frmP, CommanderStatusReputationLabel, Reputation[i].Name );
setLabelText( frmP, CommanderStatusLevelLabel, DifficultyLevel[Difficulty] );
StrIToA( SBuf, Days );
StrCat( SBuf, " days" );
setLabelText( frmP, CommanderStatusDaysLabel, SBuf );
StrIToA( SBuf, Credits );
StrCat( SBuf, " cr." );
setLabelText( frmP, CommanderStatusCreditsLabel, SBuf );
StrIToA( SBuf, Debt );
StrCat( SBuf, " cr." );
setLabelText( frmP, CommanderStatusDebtLabel, SBuf );
StrIToA (SBuf, CurrentWorth());
StrCat (SBuf, " cr." );
setLabelText(frmP, CommanderStatusNetWorthLabel, SBuf);
#ifdef _STRA_CHEAT_
if (CheatCounter == 3)
FrmShowObject( frmP, FrmGetObjectIndex( frmP, CommanderStatusCheatButton ));
else
FrmHideObject( frmP, FrmGetObjectIndex( frmP, CommanderStatusCheatButton ));
#endif
FrmDrawForm( frmP );
}
// *************************************************************************
// Handling of events on the Commander Status screen
// *************************************************************************
Boolean CommanderStatusFormHandleEvent(EventPtr eventP)
{
Boolean handled = false;
static FormPtr frm;
static int i;
static Handle AmountH[4];
switch (eventP->eType)
{
// Show information on current system
case frmOpenEvent:
ShowCommanderStatus();
CheatCounter = 0;
handled = true;
break;
case frmUpdateEvent:
ShowCommanderStatus();
handled = true;
break;
case ctlSelectEvent:
#ifdef _STRA_CHEAT_ // cheat enable defined ?
if (eventP->data.ctlSelect.controlID == CommanderStatusCheatButton)
{
frm = FrmInitForm( CheatForm );
StrIToA( SBuf, Credits );
AmountH[0] = SetField( frm, CheatCreditsField, SBuf, 9, true );
StrIToA( SBuf, Debt );
AmountH[1] = SetField( frm, CheatDebtField, SBuf, 9, true );
StrIToA( SBuf, ReputationScore );
AmountH[2] = SetField( frm, CheatReputationField, SBuf, 5, false );
StrIToA( SBuf, ABS( PoliceRecordScore ) );
AmountH[3] = SetField( frm, CheatPoliceRecordField, SBuf, 5, false );
SetCheckBox( frm, CheatNegativeCheckbox, (PoliceRecordScore < 0) );
SetCheckBox( frm, CheatMoonCheckbox, MoonBought );
SetCheckBox( frm, CheatLightningShieldCheckbox, HasShield( &Ship, LIGHTNINGSHIELD ) );
SetCheckBox( frm, CheatFuelCompactorCheckbox, HasGadget( &Ship, FUELCOMPACTOR ) );
SetCheckBox( frm, CheatMorganLaserCheckbox, HasWeapon( &Ship, MORGANLASERWEAPON, true ) );
SetCheckBox( frm, CheatSingularityCheckbox, CanSuperWarp );
FrmDoDialog( frm );
GetField( frm, CheatCreditsField, SBuf, AmountH[0] );
if (SBuf[0] != '\0')
Credits = StrAToI( SBuf );
GetField(frm, CheatDebtField, SBuf, AmountH[1]);
if (SBuf[0] != '\0')
Debt = StrAToI(SBuf);
GetField( frm, CheatReputationField, SBuf, AmountH[2] );
if (SBuf[0] != '\0')
ReputationScore = StrAToI( SBuf );
GetField( frm, CheatPoliceRecordField, SBuf, AmountH[3] );
if (SBuf[0] != '\0')
PoliceRecordScore = StrAToI( SBuf );
if (GetCheckBox( frm, CheatNegativeCheckbox ))
PoliceRecordScore = -PoliceRecordScore;
MoonBought = GetCheckBox( frm, CheatMoonCheckbox );
if (GetCheckBox( frm, CheatLightningShieldCheckbox ) && !HasShield( &Ship, LIGHTNINGSHIELD ) &&
Shiptype[Ship.Type].ShieldSlots > 0)
Ship.Shield[0] = LIGHTNINGSHIELD;
else if (!GetCheckBox( frm, CheatLightningShieldCheckbox ) && HasShield( &Ship, LIGHTNINGSHIELD ))
{
for (i=0; i<MAXSHIELD; ++i)
if (Ship.Shield[i] == LIGHTNINGSHIELD)
Ship.Shield[i] = 1;
}
if (GetCheckBox( frm, CheatFuelCompactorCheckbox ) && !HasGadget( &Ship, FUELCOMPACTOR ) &&
Shiptype[Ship.Type].GadgetSlots > 0)
Ship.Gadget[0] = FUELCOMPACTOR;
else if (!GetCheckBox( frm, CheatFuelCompactorCheckbox ) && HasGadget( &Ship, FUELCOMPACTOR ))
{
for (i=0; i<MAXGADGET; ++i)
if (Ship.Gadget[i] == FUELCOMPACTOR)
Ship.Gadget[i] = 1;
}
if (GetCheckBox( frm, CheatMorganLaserCheckbox ) && !HasWeapon( &Ship, MORGANLASERWEAPON, true) &&
Shiptype[Ship.Type].WeaponSlots > 0)
Ship.Weapon[0] = MORGANLASERWEAPON;
else if (!GetCheckBox( frm, CheatMorganLaserCheckbox ) && HasWeapon( &Ship, MORGANLASERWEAPON, true ))
{
for (i=0; i<MAXWEAPON; ++i)
if (Ship.Weapon[i] == MORGANLASERWEAPON)
Ship.Weapon[i] = 1;
}
CanSuperWarp = GetCheckBox( frm, CheatSingularityCheckbox );
FrmDeleteForm( frm );
ShowCommanderStatus();
}
else
#endif // Cheat Enabled End
if (eventP->data.ctlSelect.controlID == CommanderStatusQuestsButton)
{
CurForm = QuestsForm;
}
else if (eventP->data.ctlSelect.controlID == CommanderStatusSpecialButton)
{
CurForm = SpecialCargoForm;
}
else
{
CurForm = CurrentShipForm;
}
FrmGotoForm( CurForm );
handled = true;
break;
default:
break;
}
return handled;
}

1
Src/Color.h Normal file
View File

@ -0,0 +1 @@
#define BPP8 1

267
Src/DataTypes.h Normal file
View File

@ -0,0 +1,267 @@
/***********************************************************************
*
* SPACE TRADER 1.2.0
*
* Datatypes.h
*
* Copyright (C) 2000-2002 Pieter Spronck, All Rights Reserved
*
* Additional coding by Sam Anderson (rulez2@home.com)
* Additional coding by Samuel Goldstein (palm@fogbound.net)
*
* Some code of Matt Lee's Dope Wars program has been used.
*
* 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.
*
* You can contact the author at space_trader@hotmail.com
*
* For those who are familiar with the classic game Elite: many of the
* ideas in Space Trader are heavily inspired by Elite.
*
**********************************************************************/
// Data Types Defined for Space Trader
#ifndef __SPACETRADER_INC__
#include "spacetrader.h" // we need our maximums defined before here
#endif
typedef struct {
Byte Type;
int Cargo[MAXTRADEITEM];
int Weapon[MAXWEAPON];
int Shield[MAXSHIELD];
long ShieldStrength[MAXSHIELD];
int Gadget[MAXGADGET];
int Crew[MAXCREW];
Byte Fuel;
long Hull;
long Tribbles;
long ForFutureUse[4];
} SHIP;
typedef struct {
char* Name;
long Price;
Byte TechLevel;
Byte Chance; // Chance that this is fitted in a slot
} GADGET;
typedef struct {
char* Name;
long Power;
long Price;
Byte TechLevel;
Byte Chance; // Chance that this is fitted in a slot
} WEAPON;
typedef struct {
char* Name;
long Power;
long Price;
Byte TechLevel;
Byte Chance; // Chance that this is fitted in a slot
} SHIELD;
typedef struct {
Byte NameIndex;
Byte Pilot;
Byte Fighter;
Byte Trader;
Byte Engineer;
Byte CurSystem;
} CREWMEMBER;
typedef struct {
char* Name;
Byte CargoBays; // Number of cargo bays
Byte WeaponSlots; // Number of lasers possible
Byte ShieldSlots; // Number of shields possible
Byte GadgetSlots; // Number of gadgets possible (e.g. docking computers)
Byte CrewQuarters; // Number of crewmembers possible
Byte FuelTanks; // Each tank contains enough fuel to travel 10 parsecs
Byte MinTechLevel; // Minimum tech level needed to build ship
Byte CostOfFuel; // Cost to fill one tank with fuel
long Price; // Base ship cost
int Bounty; // Base bounty
int Occurrence; // Percentage of the ships you meet
long HullStrength; // Hull strength
int Police; // Encountered as police with at least this strength
int Pirates; // idem Pirates
int Traders; // idem Traders
Byte RepairCosts; // Repair costs for 1 point of hull strength.
Byte Size; // Determines how easy it is to hit this ship
} SHIPTYPE;
typedef struct {
Byte NameIndex;
Byte TechLevel; // Tech level
Byte Politics; // Political system
Byte Status; // Status
Byte X; // X-coordinate (galaxy width = 150)
Byte Y; // Y-coordinate (galaxy height = 100)
Byte SpecialResources; // Special resources
Byte Size; // System size
int Qty[MAXTRADEITEM]; // Quantities of tradeitems. These change very slowly over time.
Byte CountDown; // Countdown for reset of tradeitems.
Boolean Visited; // Visited Yes or No
int Special; // Special event
} SOLARSYSTEM;
typedef struct {
char* Name;
Byte TechProduction; // Tech level needed for production
Byte TechUsage; // Tech level needed to use
Byte TechTopProduction; // Tech level which produces this item the most
int PriceLowTech; // Medium price at lowest tech level
int PriceInc; // Price increase per tech level
int Variance; // Max percentage above or below calculated price
int DoublePriceStatus; // Price increases considerably when this event occurs
int CheapResource; // When this resource is available, this trade item is cheap
int ExpensiveResource; // When this resource is available, this trade item is expensive
int MinTradePrice; // Minimum price to buy/sell in orbit
int MaxTradePrice; // Minimum price to buy/sell in orbit
int RoundOff; // Roundoff price for trade in orbit
} TRADEITEM;
typedef struct {
char* Name;
Byte ReactionIllegal; // Reaction level of illegal goods 0 = total acceptance (determines how police reacts if they find you carry them)
Byte StrengthPolice; // Strength level of police force 0 = no police (determines occurrence rate)
Byte StrengthPirates; // Strength level of pirates 0 = no pirates
Byte StrengthTraders; // Strength levcel of traders 0 = no traders
Byte MinTechLevel; // Mininum tech level needed
Byte MaxTechLevel; // Maximum tech level where this is found
Byte BribeLevel; // Indicates how easily someone can be bribed 0 = unbribeable/high bribe costs
Boolean DrugsOK; // Drugs can be traded (if not, people aren't interested or the governemnt is too strict)
Boolean FirearmsOK; // Firearms can be traded (if not, people aren't interested or the governemnt is too strict)
int Wanted; // Tradeitem requested in particular in this type of government
} POLITICS;
typedef struct {
char* Title;
int QuestStringID;
long Price;
Byte Occurrence;
Boolean JustAMessage;
} SPECIALEVENT;
typedef struct {
char* Name;
int MinScore;
} POLICERECORD;
typedef struct {
char* Name;
int MinScore;
} REPUTATION;
typedef struct
{
long Credits;
long Debt;
int Days;
int WarpSystem;
int SelectedShipType;
long BuyPrice[MAXTRADEITEM];
long SellPrice[MAXTRADEITEM];
long ShipPrice[MAXSHIPTYPE];
int GalacticChartSystem;
long PoliceKills;
long TraderKills;
long PirateKills;
long PoliceRecordScore;
long ReputationScore;
Boolean AutoFuel;
Boolean AutoRepair;
Boolean Clicks;
int EncounterType;
Boolean Raided;
Byte MonsterStatus;
Byte DragonflyStatus;
Byte JaporiDiseaseStatus;
Boolean MoonBought;
long MonsterHull;
char NameCommander[NAMELEN+1];
int CurForm;
SHIP Ship;
SHIP Opponent;
CREWMEMBER Mercenary[MAXCREWMEMBER+1];
SOLARSYSTEM SolarSystem[MAXSOLARSYSTEM];
Boolean EscapePod;
Boolean Insurance;
int NoClaim;
Boolean Inspected;
Boolean AlwaysIgnoreTraders;
Byte Wormhole[MAXWORMHOLE];
Byte Difficulty;
Byte VersionMajor;
Byte VersionMinor;
long BuyingPrice[MAXTRADEITEM];
Boolean ArtifactOnBoard;
Boolean ReserveMoney;
Boolean PriceDifferences;
Boolean APLscreen;
int LeaveEmpty;
Boolean TribbleMessage;
Boolean AlwaysInfo;
Boolean AlwaysIgnorePolice;
Boolean AlwaysIgnorePirates;
Boolean TextualEncounters;
Byte JarekStatus;
Byte InvasionStatus;
Boolean Continuous;
Boolean AttackFleeing;
Byte ExperimentAndWildStatus;
Byte FabricRipProbability;
Byte VeryRareEncounter;
Byte BooleanCollection;
Byte ReactorStatus;
int TrackedSystem;
Byte ScarabStatus;
Boolean AlwaysIgnoreTradeInOrbit;
Boolean AlreadyPaidForNewspaper;
Boolean GameLoaded;
int Shortcut1;
int Shortcut2;
int Shortcut3;
int Shortcut4;
Boolean LitterWarning;
Boolean SharePreferences;
Boolean IdentifyStartup;
Boolean RectangularButtonsOn;
Byte ForFutureUse[MAXFORFUTUREUSE]; // Make sure this is properly adapted or savegames won't work after an upgrade!
} SAVEGAMETYPE;
typedef struct HighScoreType {
char Name[NAMELEN+1];
Byte Status; // 0 = killed, 1 = Retired, 2 = Bought moon
int Days;
long Worth;
Byte Difficulty;
Byte ForFutureUse;
} HIGHSCORE;
#define __DATATYPES_INC__

378
Src/Draw.c Normal file
View File

@ -0,0 +1,378 @@
/***********************************************************************
*
* SPACE TRADER 1.2.0
*
* Draw.c
*
* Copyright (C) 2000-2002 Pieter Spronck, All Rights Reserved
*
* Additional coding by Sam Anderson (rulez2@home.com)
* Additional coding by Samuel Goldstein (palm@fogbound.net)
*
* Some code of Matt Lee's Dope Wars program has been used.
*
* 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.
*
* You can contact the author at space_trader@hotmail.com
*
* For those who are familiar with the classic game Elite: many of the
* ideas in Space Trader are heavily inspired by Elite.
*
**********************************************************************/
// *************************************************************************
// ControlPtr RectangularButton( FormPtr frmP, int Nr )
// void SBufMultiples( long Count, char* Txt )
// void setFormTitle( int formID, CharPtr s )
// void setCurrentWinTitle( CharPtr s )
// void setLabelText( FormPtr frm, int labelid, CharPtr s )
// void RectangularShortcuts( FormPtr frm, int First )
// void EraseRectangle( int x, int y, int ex, int ey )
// void DrawChars( char* Text, int x, int y )
// int ScrollButton( EventPtr eventP )
//
// Modifications:
// mm/dd/yy - description - author
// *************************************************************************
// Needed to change the frames of buttons to rectangles. There is currently no function
// that allows to do it. When an OS is published that fails on this access (probably OS 5.0),
// the RectangularButton function must be adapted.
#ifndef ALLOW_ACCESS_TO_INTERNALS_OF_CONTROLS
#define ALLOW_ACCESS_TO_INTERNALS_OF_CONTROLS 1
#endif
#include "external.h"
// *************************************************************************
// Make button rectangular
// *************************************************************************
ControlPtr RectangularButton( FormPtr frmP, int Nr )
{
int objindex;
ControlPtr cp;
objindex = FrmGetObjectIndex( frmP, Nr );
cp = (ControlPtr)FrmGetObjectPtr( frmP, objindex );
if (BELOW50 || RectangularButtonsOn)
cp->attr.frame = rectangleButtonFrame;
return cp;
}
// *************************************************************************
// String number and qualifier together
// *************************************************************************
void SBufMultiples( long Count, char* Txt )
{
StrIToA( SBuf2, Count );
StrCat( SBuf, SBuf2 );
StrCat( SBuf, " " );
StrCat( SBuf, Txt );
if (Count != 1)
StrCat( SBuf, "s" );
}
// *************************************************************************
// String number and qualifier together, but no digit for singulars
// *************************************************************************
void SBufShortMultiples( long Count, char* Txt )
{
if (Count != 1)
{
StrIToA( SBuf2, Count );
StrCat( SBuf, SBuf2 );
StrCat( SBuf, " " );
StrCat( SBuf, Txt );
if (Count != 1)
StrCat( SBuf, "s" );
}
else
{
StrCat( SBuf, Txt );
}
}
// *************************************************************************
// Setting the title of a form.
// CW 8 required a rewrite, as FrmGetTitle now returns a const Char *
// *************************************************************************
void setFormTitle( int formID, CharPtr s )
{
FormPtr frm;
// CharPtr wintitle;
frm = FrmGetFormPtr( formID );
// wintitle = FrmGetTitle( frm );
// StrCopy( wintitle, s );
// FrmSetTitle( frm, wintitle );
FrmCopyTitle( frm, s );
}
// *************************************************************************
// Setting the title of the current form.
// *************************************************************************
void setCurrentWinTitle( CharPtr s )
{
FormPtr frm = FrmGetActiveForm();
FrmSetTitle( frm, s );
}
// *************************************************************************
// Setting the text of a label.
// CW 8 required a rewrite, as CtlGetLabel now returns a const Char *
// *************************************************************************
void setLabelText( FormPtr frm, int labelid, CharPtr s )
{
int objindex;
// ControlPtr cp;
// CharPtr c;
objindex = FrmGetObjectIndex( frm, labelid );
// cp = (ControlPtr)FrmGetObjectPtr( frm, objindex );
// c = CtlGetLabel( cp );
// StrCopy( c, s );
FrmHideObject(frm, objindex);
FrmCopyLabel(frm, labelid, s);
FrmShowObject(frm, objindex);
}
// *************************************************************************
// Make shortcut buttons rectangular
// *************************************************************************
void RectangularShortcuts( FormPtr frm, int First )
{
SetControlLabel(frm, First+0, Shortcuts[Shortcut1]);
RectangularButton( frm, First+0 );
SetControlLabel(frm, First+1, Shortcuts[Shortcut2]);
RectangularButton( frm, First+1 );
SetControlLabel(frm, First+2, Shortcuts[Shortcut3]);
RectangularButton( frm, First+2 );
SetControlLabel(frm, First+3, Shortcuts[Shortcut4]);
RectangularButton( frm, First+3 );
}
// *************************************************************************
// Erases a rectangle
// *************************************************************************
void EraseRectangle( int x, int y, int ex, int ey )
{
RectangleType a;
a.topLeft.x = x;
a.topLeft.y = y;
a.extent.x = ex;
a.extent.y = ey;
WinEraseRectangle( &a, 0 );
}
// *************************************************************************
// Draws a text on the screen
// *************************************************************************
void DrawChars( char* Text, int x, int y )
{
WinDrawChars( Text, StrLen( Text ), x, y );
}
// ******
// Debug Alerts
// ******
// only compile this in if desired. The resource does get included regardless,
// but that's only at a cost of a handful of bytes.
#ifdef _INCLUDE_DEBUG_DIALOGS_
void DebugIntAlert(int a, int b, int c)
{
char as[51],bs[51],cs[51];
StrIToA(as, a);
StrIToA(bs, b);
StrIToA(cs, c);
FrmCustomAlert(DebugAlert, as, bs, cs);
}
void DebugLongAlert(long a, long b, long c)
{
char as[51],bs[51],cs[51];
StrPrintF(as, "%ld", a);
StrPrintF(bs, "%ld", b);
StrPrintF(cs, "%ld", c);
FrmCustomAlert(DebugAlert, as, bs, cs);
}
void DebugCharAlert(char *a, char *b, char *c)
{
FrmCustomAlert(DebugAlert, a,b,c);
}
#endif // end of debug code
// *************************************************************************
// Draws a text centered on the screen
// *************************************************************************
void DrawCharsCentered( char* Text, int y, Boolean useBold )
{
FontID originalFont;
Int16 width=160, length=StrLen(Text);
Boolean fits;
if (useBold)
{
originalFont = FntSetFont(boldFont);
}
else
{
originalFont = FntSetFont(stdFont);
}
FntCharsInWidth(Text, &width, &length, &fits);
// should probably find the width of the screen for the hi-rez crowd.
WinDrawChars( Text, StrLen( Text ), (int)(80 - width/2), y );
FntSetFont(originalFont);
}
// *****************************************************************
// Utility function for displaying headlines and incrementing the
// line counter. If we're too far down the page, we simply don't
// display the headline (we'll return a false if that's the case)
// *****************************************************************
Boolean DisplayHeadline(char *text, int *y_coord)
{
int offset=0;
Int16 width=158 - (NEWSINDENT1 * 2), length=StrLen(text);
Boolean fits;
char theText[72];
FntCharsInWidth(text, &width, &length, &fits);
// check to see if we've got room to put it on one line
if (fits)
{
// do we have room on the page?
if (*y_coord > 128)
return false;
DrawChars(text, NEWSINDENT1, *y_coord);
}
else
{
// do we have room for two lines on the page?
if (*y_coord > 107)
return false;
// is our text too long?
if (StrLen(text) > 71)
{
return false;
}
StrCopy(theText, text);
offset = length;
while (offset > 0 && theText[offset] != ' ')
offset--;
theText[offset]='\0';
DrawChars(theText, NEWSINDENT1, *y_coord);
*y_coord += 11;
DrawChars(theText + offset + 1, NEWSINDENT2, *y_coord);
}
*y_coord += 15;
return true;
}
// *****************************************************************
// Utility function for displaying a page of text.
// *****************************************************************
void DisplayPage(char *text, int start_y)
{
int offset=0;
int internalOffset = 0;
int vert = start_y;
Int16 width=148, length, origLength=StrLen(text);
Boolean fits, looping;
char theText[46];
looping = true;
while (looping)
{
StrNCopy(theText, text + offset, min(45, origLength-offset));
theText[min (45, origLength - offset) ] = '\0';
length=StrLen(theText);
FntCharsInWidth(theText, &width, &length, &fits);
if (fits)
{
offset += 45;
}
else
{
internalOffset = length;
while (internalOffset > 0 &&
theText[internalOffset] != ' ' && theText[internalOffset] != '-')
internalOffset--;
if (theText[internalOffset] == '-' && internalOffset < length)
{
theText[internalOffset+1]='\0';
}
else
{
theText[internalOffset]='\0';
}
offset += internalOffset + 1;
}
DrawChars(theText, 8, vert);
vert += 12;
if (offset >= origLength)
{
looping = false;
theText[45]='\0';
}
}
}
// *************************************************************************
// Return scrollbutton that is pushed
// *************************************************************************
int ScrollButton( EventPtr eventP )
{
ULong Ticks;
if ((eventP->data.keyDown.chr == chrPageUp) ||
(eventP->data.keyDown.chr == chrPageDown))
{
Ticks = TimGetTicks();
if (Ticks < GalacticChartUpdateTicks + (SysTicksPerSecond() >> 1))
return 0;
GalacticChartUpdateTicks = Ticks;
return eventP->data.keyDown.chr;
}
return 0;
}

2320
Src/Encounter.c Normal file

File diff suppressed because it is too large Load Diff

154
Src/Field.c Normal file
View File

@ -0,0 +1,154 @@
/***********************************************************************
*
* SPACE TRADER 1.2.0
*
* Field.c
*
* Copyright (C) 2000-2002 Pieter Spronck, All Rights Reserved
*
* Additional coding by Sam Anderson (rulez2@home.com)
* Additional coding by Samuel Goldstein (palm@fogbound.net)
*
* Some code of Matt Lee's Dope Wars program has been used.
*
* 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.
*
* You can contact the author at space_trader@hotmail.com
*
* For those who are familiar with the classic game Elite: many of the
* ideas in Space Trader are heavily inspired by Elite.
*
**********************************************************************/
// *************************************************************************
// Field.c - Functions Include:
// Handle SetField( FormPtr frm, int Nr, char* Value, int Size, Boolean Focus )
// void GetField( FormPtr frm, int Nr, char* Value, Handle AmountH )
// void SetCheckBox( FormPtr frm, int Nr, Boolean Value )
// Boolean GetCheckBox( FormPtr frm, int Nr )
//
// Modifications:
// mm/dd/yy - description - author
// *************************************************************************
#include "external.h"
// *************************************************************************
// Set Field
// *************************************************************************
Handle SetField( FormPtr frm, int Nr, char* Value, int Size, Boolean Focus )
{
Word objIndex;
CharPtr AmountP;
Handle AmountH;
objIndex = FrmGetObjectIndex( frm, Nr );
AmountH = MemHandleNew( Size );
AmountP = MemHandleLock( AmountH );
StrCopy( AmountP, Value );
MemPtrUnlock( AmountP );
FldSetTextHandle( FrmGetObjectPtr( frm, objIndex ), AmountH );
if (Focus)
FrmSetFocus( frm, objIndex );
return AmountH;
}
// *************************************************************************
// Get Field
// *************************************************************************
void GetField( FormPtr frm, int Nr, char* Value, Handle AmountH )
{
Word objIndex;
CharPtr AmountP;
objIndex = FrmGetObjectIndex( frm, Nr );
FldSetTextHandle( FrmGetObjectPtr( frm, objIndex ), 0 );
AmountP = MemHandleLock( AmountH );
StrCopy( Value, AmountP );
MemPtrUnlock( AmountP );
MemHandleFree( AmountH );
}
// *************************************************************************
// Set Trigger List value
// *************************************************************************
void SetTriggerList( FormPtr frm, int Nr, int Index )
{
Word objIndex;
ControlPtr cp;
objIndex = FrmGetObjectIndex( frm, Nr );
cp = (ControlPtr)FrmGetObjectPtr( frm, objIndex );
LstSetSelection( cp, Index );
}
// *************************************************************************
// Set Control Label
// *************************************************************************
void SetControlLabel( FormPtr frm, int Nr, Char * Label )
{
Word objIndex;
ControlPtr cp;
objIndex = FrmGetObjectIndex( frm, Nr );
cp = (ControlPtr)FrmGetObjectPtr( frm, objIndex );
CtlSetLabel( cp, Label );
}
// *************************************************************************
// Get Trigger List value
// *************************************************************************
int GetTriggerList( FormPtr frm, int Nr)
{
Word objIndex;
ControlPtr cp;
objIndex = FrmGetObjectIndex( frm, Nr );
cp = (ControlPtr)FrmGetObjectPtr( frm, objIndex );
return LstGetSelection( cp );
}
// *************************************************************************
// Set Checkbox value
// *************************************************************************
void SetCheckBox( FormPtr frm, int Nr, Boolean Value )
{
Word objIndex;
ControlPtr cp;
objIndex = FrmGetObjectIndex( frm, Nr );
cp = (ControlPtr)FrmGetObjectPtr( frm, objIndex );
CtlSetValue( cp, (Value ? 1 : 0) );
}
// *************************************************************************
// Get Checkbox value
// *************************************************************************
Boolean GetCheckBox( FormPtr frm, int Nr )
{
Word objIndex;
ControlPtr cp;
objIndex = FrmGetObjectIndex( frm, Nr );
cp = (ControlPtr)FrmGetObjectPtr( frm, objIndex );
if (CtlGetValue( cp ) == 0)
return false;
else
return true;
}

83
Src/Fuel.c Normal file
View File

@ -0,0 +1,83 @@
/***********************************************************************
*
* SPACE TRADER 1.2.0
*
* Fuel.c
*
* Copyright (C) 2000-2002 Pieter Spronck, All Rights Reserved
*
* Additional coding by Sam Anderson (rulez2@home.com)
* Additional coding by Samuel Goldstein (palm@fogbound.net)
*
* Some code of Matt Lee's Dope Wars program has been used.
*
* 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.
*
* You can contact the author at space_trader@hotmail.com
*
* For those who are familiar with the classic game Elite: many of the
* ideas in Space Trader are heavily inspired by Elite.
*
**********************************************************************/
// *************************************************************************
// Fuel.c - Functions include:
// char GetFuelTanks( void )
// char GetFuel( void )
// void BuyFuel( int Amount )
//
// Modifications:
// mm/dd/yy - description - author
// *************************************************************************
#include "external.h"
// *************************************************************************
// Determine size of fueltanks
// *************************************************************************
char GetFuelTanks( void )
{
return (HasGadget( &Ship, FUELCOMPACTOR ) ? 18 : Shiptype[Ship.Type].FuelTanks);
}
// *************************************************************************
// Determine fuel in tank
// *************************************************************************
char GetFuel( void )
{
return min( Ship.Fuel, GetFuelTanks() );
}
// *************************************************************************
// Buy Fuel for Amount credits
// *************************************************************************
void BuyFuel( int Amount )
{
int MaxFuel;
int Parsecs;
MaxFuel = (GetFuelTanks() - GetFuel()) * Shiptype[Ship.Type].CostOfFuel;
if (Amount > MaxFuel)
Amount = MaxFuel;
if (Amount > Credits)
Amount = Credits;
Parsecs = Amount / Shiptype[Ship.Type].CostOfFuel;
Ship.Fuel += Parsecs;
Credits -= Parsecs * Shiptype[Ship.Type].CostOfFuel;
}

683
Src/Global.c Normal file
View File

@ -0,0 +1,683 @@
/***********************************************************************
*
* SPACE TRADER 1.2.0
*
* Global.c
*
* Copyright (C) 2000-2002 Pieter Spronck, All Rights Reserved
*
* Additional coding by Sam Anderson (rulez2@home.com)
* Additional coding by Samuel Goldstein (palm@fogbound.net)
*
* Some code of Matt Lee's Dope Wars program has been used.
*
* 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.
*
* You can contact the author at space_trader@hotmail.com
*
* For those who are familiar with the classic game Elite: many of the
* ideas in Space Trader are heavily inspired by Elite.
*
**********************************************************************/
// Global Variable Storage
// Define any Global Variable Here and Reference it in external.h
// Include the external.h file in any new source file to have
// access to the global variable
//
#define PILOT_PRECOMPILED_HEADERS_OFF 1
#include <PalmCompatibility.h>
#include <PalmOS.h>
#include "spacetrader.h"
#include "MerchantRsc.h"
const POLICERECORD PoliceRecord[MAXPOLICERECORD] =
{
{ "Psycho", -100 },
{ "Villain", PSYCHOPATHSCORE },
{ "Criminal", VILLAINSCORE },
{ "Crook", CRIMINALSCORE },
{ "Dubious", DUBIOUSSCORE },
{ "Clean", CLEANSCORE },
{ "Lawful", LAWFULSCORE },
{ "Trusted", TRUSTEDSCORE },
{ "Liked", HELPERSCORE },
{ "Hero", HEROSCORE }
};
const REPUTATION Reputation[MAXREPUTATION] =
{
{ "Harmless", HARMLESSREP },
{ "Mostly harmless", MOSTLYHARMLESSREP },
{ "Poor", POORREP },
{ "Average", AVERAGESCORE },
{ "Above average", ABOVEAVERAGESCORE },
{ "Competent", COMPETENTREP },
{ "Dangerous", DANGEROUSREP },
{ "Deadly", DEADLYREP },
{ "Elite", ELITESCORE }
};
const char* DifficultyLevel[MAXDIFFICULTY] =
{
"Beginner",
"Easy",
"Normal",
"Hard",
"Impossible"
};
const char* SpecialResources[MAXRESOURCES] =
{
"Nothing special",
"Mineral rich",
"Mineral poor",
"Desert",
"Sweetwater oceans",
"Rich soil",
"Poor soil",
"Rich fauna",
"Lifeless",
"Weird mushrooms",
"Special herbs",
"Artistic populace",
"Warlike populace"
};
const char* Status[MAXSTATUS] =
{
"under no particular pressure", // Uneventful
"at war", // Ore and Weapons in demand
"ravaged by a plague", // Medicine in demand
"suffering from a drought", // Water in demand
"suffering from extreme boredom", // Games and Narcotics in demand
"suffering from a cold spell", // Furs in demand
"suffering from a crop failure", // Food in demand
"lacking enough workers" // Machinery and Robots in demand
};
const char* Activity[MAXACTIVITY] =
{
"Absent",
"Minimal",
"Few",
"Some",
"Moderate",
"Many",
"Abundant",
"Swarms"
};
const TRADEITEM Tradeitem[MAXTRADEITEM] =
{
{ "Water", 0, 0, 2, 30, +3, 4, DROUGHT, LOTSOFWATER, DESERT, 30, 50, 1 },
{ "Furs", 0, 0, 0, 250, +10, 10, COLD, RICHFAUNA, LIFELESS, 230, 280, 5 },
{ "Food", 1, 0, 1, 100, +5, 5, CROPFAILURE, RICHSOIL, POORSOIL, 90, 160, 5 },
{ "Ore", 2, 2, 3, 350, +20, 10, WAR, MINERALRICH, MINERALPOOR, 350, 420, 10 },
{ "Games", 3, 1, 6, 250, -10, 5, BOREDOM, ARTISTIC, -1, 160, 270, 5 },
{ "Firearms", 3, 1, 5, 1250, -75, 100, WAR, WARLIKE, -1, 600, 1100, 25 },
{ "Medicine", 4, 1, 6, 650, -20, 10, PLAGUE, LOTSOFHERBS, -1, 400, 700, 25 },
{ "Machines", 4, 3, 5, 900, -30, 5, LACKOFWORKERS, -1, -1, 600, 800, 25 },
{ "Narcotics", 5, 0, 5, 3500, -125, 150, BOREDOM, WEIRDMUSHROOMS, -1, 2000, 3000, 50 },
{ "Robots", 6, 4, 7, 5000, -150, 100, LACKOFWORKERS, -1, -1, 3500, 5000, 100 }
};
char NameCommander[NAMELEN+1] = "Jameson";
char* MercenaryName[MAXCREWMEMBER] =
{
NameCommander,
"Alyssa",
"Armatur",
"Bentos",
"C2U2",
"Chi'Ti",
"Crystal",
"Dane",
"Deirdre",
"Doc",
"Draco",
"Iranda",
"Jeremiah",
"Jujubal",
"Krydon",
"Luis",
"Mercedez",
"Milete",
"Muri-L",
"Mystyc",
"Nandi",
"Orestes",
"Pancho",
"PS37",
"Quarck",
"Sosumi",
"Uma",
"Wesley",
"Wonton",
"Yorvick",
"Zeethibal" // anagram for Elizabeth
};
CREWMEMBER Mercenary[MAXCREWMEMBER + 1];
const SHIPTYPE Shiptype[MAXSHIPTYPE+EXTRASHIPS] =
{
{ "Flea", 10, 0, 0, 0, 1, MAXRANGE, 4, 1, 2000, 5, 2, 25, -1, -1, 0, 1, 0 },
{ "Gnat", 15, 1, 0, 1, 1, 14, 5, 2, 10000, 50, 28, 100, 0, 0, 0, 1, 1 },
{ "Firefly", 20, 1, 1, 1, 1, 17, 5, 3, 25000, 75, 20, 100, 0, 0, 0, 1, 1 },
{ "Mosquito", 15, 2, 1, 1, 1, 13, 5, 5, 30000, 100, 20, 100, 0, 1, 0, 1, 1 },
{ "Bumblebee", 25, 1, 2, 2, 2, 15, 5, 7, 60000, 125, 15, 100, 1, 1, 0, 1, 2 },
{ "Beetle", 50, 0, 1, 1, 3, 14, 5, 10, 80000, 50, 3, 50, -1, -1, 0, 1, 2 },
{ "Hornet", 20, 3, 2, 1, 2, 16, 6, 15, 100000, 200, 6, 150, 2, 3, 1, 2, 3 },
{ "Grasshopper", 30, 2, 2, 3, 3, 15, 6, 15, 150000, 300, 2, 150, 3, 4, 2, 3, 3 },
{ "Termite", 60, 1, 3, 2, 3, 13, 7, 20, 225000, 300, 2, 200, 4, 5, 3, 4, 4 },
{ "Wasp", 35, 3, 2, 2, 3, 14, 7, 20, 300000, 500, 2, 200, 5, 6, 4, 5, 4 },
// The ships below can't be bought
{ "Space monster", 0, 3, 0, 0, 1, 1, 8, 1, 500000, 0, 0, 500, 8, 8, 8, 1, 4 },
{ "Dragonfly", 0, 2, 3, 2, 1, 1, 8, 1, 500000, 0, 0, 10, 8, 8, 8, 1, 1 },
{ "Mantis", 0, 3, 1, 3, 3, 1, 8, 1, 500000, 0, 0, 300, 8, 8, 8, 1, 2 },
{ "Scarab", 20, 2, 0, 0, 2, 1, 8, 1, 500000, 0, 0, 400, 8, 8, 8, 1, 3 },
{ "Bottle", 0, 0, 0, 0, 0, 1, 8, 1, 100, 0, 0, 10, 8, 8, 8, 1, 1 }
};
const WEAPON Weapontype[MAXWEAPONTYPE+EXTRAWEAPONS] =
{
{ "Pulse laser", PULSELASERPOWER, 2000, 5, 50 },
{ "Beam laser", BEAMLASERPOWER, 12500, 6, 35 },
{ "Military laser", MILITARYLASERPOWER, 35000, 7, 15 },
// The weapons below cannot be bought
{ "Morgan's laser", MORGANLASERPOWER, 50000, 8, 0 }
};
const SHIELD Shieldtype[MAXSHIELDTYPE+EXTRASHIELDS] =
{
{ "Energy shield", ESHIELDPOWER, 5000, 5, 70 },
{ "Reflective shield", RSHIELDPOWER, 20000, 6, 30 },
// The shields below can't be bought
{ "Lightning shield", LSHIELDPOWER, 45000, 8, 0 }
};
const GADGET Gadgettype[MAXGADGETTYPE+EXTRAGADGETS] =
{
{ "5 extra cargo bays", 2500, 4, 35 }, // 5 extra holds
{ "Auto-repair system", 7500, 5, 20 }, // Increases engineer's effectivity
{ "Navigating system", 15000, 6, 20 }, // Increases pilot's effectivity
{ "Targeting system", 25000, 6, 20 }, // Increases fighter's effectivity
{ "Cloaking device", 100000, 7, 5 }, // If you have a good engineer, nor pirates nor police will notice you
// The gadgets below can't be bought
{ "Fuel compactor", 30000, 8, 0 }
};
// Note that these initializations are overruled by the StartNewGame function
SHIP Ship =
{
1, // Gnat
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // No cargo
{ 0, -1, -1 }, // One pulse laser
{ -1, -1, -1 },{ 0,0,0 }, // No shields
{ -1, -1, -1 }, // No gadgets
{ 0, -1, -1 }, // Commander on board
14, // Full tank
100, // Full hull strength
0, // No tribbles on board
{ 0, 0, 0, 0 } // For future use
};
SHIP Opponent =
{
1, // Gnat
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // No cargo
{ 0, -1, -1 }, // One pulse laser
{ -1, -1, -1 }, { 0, 0, 0 }, // No shields
{ -1, -1, -1 }, // No gadgets
{ 1, -1, -1 }, // Alyssa on board
14, // Full tank
100, // Full hull strength
0, // No tribbles on board
{ 0, 0, 0, 0 } // For future use
};
SHIP SpaceMonster =
{
MAXSHIPTYPE, // Space monster
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // No cargo
{ 2, 2, 2 }, // Three military lasers
{ -1, -1, -1 }, { 0, 0, 0 }, // No shields
{ -1, -1, -1 }, // No gadgets
{ MAXCREWMEMBER, -1, -1 }, // super stats
1, // Full tank
500, // Full hull strength
0, // No tribbles on board
{ 0, 0, 0, 0 } // For future use
};
SHIP Scarab =
{
MAXSHIPTYPE+3, // Scarab
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // No cargo
{ 2, 2, -1 }, // Two military lasers
{ -1, -1, -1 }, { 0, 0, 0 }, // No shields
{ -1, -1, -1 }, // No gadgets
{ MAXCREWMEMBER, -1, -1 }, // super stats
1, // Full tank
400, // Full hull strength
0, // No tribbles on board
{ 0, 0, 0, 0 } // For future use
};
SHIP Dragonfly =
{
MAXSHIPTYPE+1, // Dragonfly
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // No cargo
{ 2, 0, -1 }, // One military laser and one pulse laser
{ LIGHTNINGSHIELD, LIGHTNINGSHIELD, LIGHTNINGSHIELD }, // Three lightning shields
{ LSHIELDPOWER, LSHIELDPOWER, LSHIELDPOWER },
{ AUTOREPAIRSYSTEM, TARGETINGSYSTEM, -1 }, // Gadgets
{ MAXCREWMEMBER, -1, -1 }, // super stats
1, // Full tank
10, // Full hull strength (though this isn't much)
0, // No tribbles on board
{ 0, 0, 0, 0 } // For future use
};
const char* SystemSize[MAXSIZE] =
{
"Tiny",
"Small",
"Medium",
"Large",
"Huge"
};
const char* TechLevel[MAXTECHLEVEL] =
{
"Pre-agricultural",
"Agricultural",
"Medieval",
"Renaissance",
"Early Industrial",
"Industrial",
"Post-industrial",
"Hi-tech"
};
const POLITICS Politics[MAXPOLITICS] =
{
{ "Anarchy", 0, 0, 7, 1, 0, 5, 7, true, true, FOOD },
{ "Capitalist State", 2, 3, 2, 7, 4, 7, 1, true, true, ORE },
{ "Communist State", 6, 6, 4, 4, 1, 5, 5, true, true, -1 },
{ "Confederacy", 5, 4, 3, 5, 1, 6, 3, true, true, GAMES },
{ "Corporate State", 2, 6, 2, 7, 4, 7, 2, true, true, ROBOTS },
{ "Cybernetic State", 0, 7, 7, 5, 6, 7, 0, false, false, ORE },
{ "Democracy", 4, 3, 2, 5, 3, 7, 2, true, true, GAMES },
{ "Dictatorship", 3, 4, 5, 3, 0, 7, 2, true, true, -1 },
{ "Fascist State", 7, 7, 7, 1, 4, 7, 0, false, true, MACHINERY },
{ "Feudal State", 1, 1, 6, 2, 0, 3, 6, true, true, FIREARMS },
{ "Military State", 7, 7, 0, 6, 2, 7, 0, false, true, ROBOTS },
{ "Monarchy", 3, 4, 3, 4, 0, 5, 4, true, true, MEDICINE },
{ "Pacifist State", 7, 2, 1, 5, 0, 3, 1, true, false, -1 },
{ "Socialist State", 4, 2, 5, 3, 0, 5, 6, true, true, -1 },
{ "State of Satori", 0, 1, 1, 1, 0, 1, 0, false, false, -1 },
{ "Technocracy", 1, 6, 3, 6, 4, 7, 2, true, true, WATER },
{ "Theocracy", 5, 6, 1, 4, 0, 4, 0, true, true, NARCOTICS }
};
// Many of these names are from Star Trek: The Next Generation, or are small changes
// to names of this series. A few have different origins.
const char* SolarSystemName[MAXSOLARSYSTEM] =
{
"Acamar",
"Adahn", // The alternate personality for The Nameless One in "Planescape: Torment"
"Aldea",
"Andevian",
"Antedi",
"Balosnee",
"Baratas",
"Brax", // One of the heroes in Master of Magic
"Bretel", // This is a Dutch device for keeping your pants up.
"Calondia",
"Campor",
"Capelle", // The city I lived in while programming this game
"Carzon",
"Castor", // A Greek demi-god
"Cestus",
"Cheron",
"Courteney", // After Courteney Cox...
"Daled",
"Damast",
"Davlos",
"Deneb",
"Deneva",
"Devidia",
"Draylon",
"Drema",
"Endor",
"Esmee", // One of the witches in Pratchett's Discworld
"Exo",
"Ferris", // Iron
"Festen", // A great Scandinavian movie
"Fourmi", // An ant, in French
"Frolix", // A solar system in one of Philip K. Dick's novels
"Gemulon",
"Guinifer", // One way of writing the name of king Arthur's wife
"Hades", // The underworld
"Hamlet", // From Shakespeare
"Helena", // Of Troy
"Hulst", // A Dutch plant
"Iodine", // An element
"Iralius",
"Janus", // A seldom encountered Dutch boy's name
"Japori",
"Jarada",
"Jason", // A Greek hero
"Kaylon",
"Khefka",
"Kira", // My dog's name
"Klaatu", // From a classic SF movie
"Klaestron",
"Korma", // An Indian sauce
"Kravat", // Interesting spelling of the French word for "tie"
"Krios",
"Laertes", // A king in a Greek tragedy
"Largo",
"Lave", // The starting system in Elite
"Ligon",
"Lowry", // The name of the "hero" in Terry Gilliam's "Brazil"
"Magrat", // The second of the witches in Pratchett's Discworld
"Malcoria",
"Melina",
"Mentar", // The Psilon home system in Master of Orion
"Merik",
"Mintaka",
"Montor", // A city in Ultima III and Ultima VII part 2
"Mordan",
"Myrthe", // The name of my daughter
"Nelvana",
"Nix", // An interesting spelling of a word meaning "nothing" in Dutch
"Nyle", // An interesting spelling of the great river
"Odet",
"Og", // The last of the witches in Pratchett's Discworld
"Omega", // The end of it all
"Omphalos", // Greek for navel
"Orias",
"Othello", // From Shakespeare
"Parade", // This word means the same in Dutch and in English
"Penthara",
"Picard", // The enigmatic captain from ST:TNG
"Pollux", // Brother of Castor
"Quator",
"Rakhar",
"Ran", // A film by Akira Kurosawa
"Regulas",
"Relva",
"Rhymus",
"Rochani",
"Rubicum", // The river Ceasar crossed to get into Rome
"Rutia",
"Sarpeidon",
"Sefalla",
"Seltrice",
"Sigma",
"Sol", // That's our own solar system
"Somari",
"Stakoron",
"Styris",
"Talani",
"Tamus",
"Tantalos", // A king from a Greek tragedy
"Tanuga",
"Tarchannen",
"Terosa",
"Thera", // A seldom encountered Dutch girl's name
"Titan", // The largest moon of Jupiter
"Torin", // A hero from Master of Magic
"Triacus",
"Turkana",
"Tyrus",
"Umberlee", // A god from AD&D, which has a prominent role in Baldur's Gate
"Utopia", // The ultimate goal
"Vadera",
"Vagra",
"Vandor",
"Ventax",
"Xenon",
"Xerxes", // A Greek hero
"Yew", // A city which is in almost all of the Ultima games
"Yojimbo", // A film by Akira Kurosawa
"Zalkon",
"Zuul" // From the first Ghostbusters movie
};
SOLARSYSTEM SolarSystem[MAXSOLARSYSTEM];
Byte Wormhole[MAXWORMHOLE]; // Systems which have a wormhole
// Quest descriptions have been moved into the Resources.
// This makes them marginally easier to edit, as well as moves them out
// of the heap during runtime. SjG
const SPECIALEVENT SpecialEvent[MAXSPECIALEVENT] =
{
{ "Dragonfly Destroyed", QuestDragonflyDestroyedString, 0, 0, true },
{ "Weird Ship", QuestWeirdShipString, 0, 0, true },
{ "Lightning Ship", QuestLightningShipString, 0, 0, true },
{ "Strange Ship", QuestStrangeShipString, 0, 0, true },
{ "Monster Killed", QuestMonsterKilledString, -15000, 0, true },
{ "Medicine Delivery", QuestMedicineDeliveredString, 0, 0, true },
{ "Retirement", QuestRetirementString, 0, 0, false },
{ "Moon For Sale", QuestMoonForSaleString, COSTMOON, 4, false },
{ "Skill Increase", QuestSkillIncreaseString, 3000, 3, false },
{ "Merchant Prince", QuestMerchantPrinceString, 1000, 1, false },
{ "Erase Record", QuestEraseRecordString, 5000, 3, false },
{ "Tribble Buyer", QuestTribbleBuyerString, 0, 3, false },
{ "Space Monster", QuestSpaceMonsterString, 0, 1, true },
{ "Dragonfly", QuestDragonflyString, 0, 1, true },
{ "Cargo For Sale", QuestCargoForSaleString, 1000, 3, false },
{ "Lightning Shield", QuestLightningShieldString, 0, 0, false },
{ "Japori Disease", QuestJaporiDiseaseString, 0, 1, false },
{ "Lottery Winner", QuestLotteryWinnerString, -1000, 0, true },
{ "Artifact Delivery", QuestArtifactDeliveryString, -20000, 0, true },
{ "Alien Artifact", QuestAlienArtifactString, 0, 1, false },
{ "Ambassador Jarek", QuestAmbassadorJarekString, 0, 1, false },
{ "Alien Invasion", QuestAlienInvasionString, 0, 0, true },
{ "Gemulon Invaded", QuestGemulonInvadedString, 0, 0, true },
{ "Fuel Compactor", QuestFuelCompactorString, 0, 0, false },
{ "Dangerous Experiment", QuestDangerousExperimentString, 0, 0, true },
{ "Jonathan Wild", QuestJonathanWildString, 0, 1, false },
{ "Morgan's Reactor", QuestMorgansReactorString, 0, 0, false },
{ "Install Morgan's Laser", QuestInstallMorgansLaserString, 0, 0, false },
{ "Scarab Stolen", QuestScarabStolenString, 0, 1, true},
{ "Upgrade Hull", QuestUpgradeHullString, 0, 0, false},
{ "Scarab Destroyed", QuestScarabDestroyedString, 0, 0, true},
{ "Reactor Delivered", QuestReactorDeliveredString, 0, 0, true },
{ "Jarek Gets Out", QuestJarekGetsOutString, 0, 0, true },
{ "Gemulon Rescued", QuestGemulonRescuedString, 0, 0, true },
{ "Disaster Averted", QuestDisasterAvertedString, 0, 0, true },
{ "Experiment Failed", QuestExperimentFailedString, 0, 0, true },
{ "Wild Gets Out", QuestWildGetsOutString, 0, 0, true }
};
const char *Shortcuts[11] = {
"B","S","Y","E","Q","P","K","I","C","G","W"
};
int ShortcutTarget[11] = {
MenuCommandBuyCargo,
MenuCommandSellCargo,
MenuCommandShipYard,
MenuCommandBuyEquipment,
MenuCommandSellEquipment,
MenuCommandPersonnelRoster,
MenuCommandBank,
MenuCommandSystemInformation,
MenuCommandCommanderStatus,
MenuCommandGalacticChart,
MenuCommandShortRangeChart
};
// increased from 51 to 128 to handle the needs of the Newspaper, and various
// quest messages stored in String Resources
char SBuf[128];
char SBuf2[51];
//int NewsEvents[MAXSPECIALNEWSEVENTS];
Handle SystemBmp;
Handle CurrentSystemBmp;
Handle ShortRangeSystemBmp;
Handle WormholeBmp;
Handle SmallWormholeBmp;
Handle VisitedSystemBmp;
Handle CurrentVisitedSystemBmp;
Handle VisitedShortRangeSystemBmp;
Handle ShipBmp[MAXSHIPTYPE+EXTRASHIPS];
Handle DamagedShipBmp[MAXSHIPTYPE+EXTRASHIPS];
Handle ShieldedShipBmp[MAXSHIPTYPE+EXTRASHIPS];
Handle DamagedShieldedShipBmp[MAXSHIPTYPE+EXTRASHIPS];
Handle IconBmp[5];
BitmapPtr SystemBmpPtr;
BitmapPtr CurrentSystemBmpPtr;
BitmapPtr ShortRangeSystemBmpPtr;
BitmapPtr WormholeBmpPtr;
BitmapPtr SmallWormholeBmpPtr;
BitmapPtr VisitedSystemBmpPtr;
BitmapPtr CurrentVisitedSystemBmpPtr;
BitmapPtr VisitedShortRangeSystemBmpPtr;
BitmapPtr ShipBmpPtr[MAXSHIPTYPE+EXTRASHIPS];
BitmapPtr DamagedShipBmpPtr[MAXSHIPTYPE+EXTRASHIPS];
BitmapPtr ShieldedShipBmpPtr[MAXSHIPTYPE+EXTRASHIPS];
BitmapPtr DamagedShieldedShipBmpPtr[MAXSHIPTYPE+EXTRASHIPS];
BitmapPtr IconBmpPtr[5];
unsigned long GalacticChartUpdateTicks = 0;
Handle NameH;
//DmOpenRef pmDB;
// The following globals are saved between sessions
// Note that these initializations are overruled by the StartNewGame function
long Credits = 1000; // Current credits owned
long Debt = 0; // Current Debt
long BuyPrice[MAXTRADEITEM]; // Price list current system
long BuyingPrice[MAXTRADEITEM]; // Total price paid for trade goods
long SellPrice[MAXTRADEITEM]; // Price list current system
long ShipPrice[MAXSHIPTYPE]; // Price list current system (recalculate when buy ship screen is entered)
long PoliceKills = 0; // Number of police ships killed
long TraderKills = 0; // Number of trader ships killed
long PirateKills = 0; // Number of pirate ships killed
long PoliceRecordScore = 0; // 0 = Clean record
long ReputationScore = 0; // 0 = Harmless
long MonsterHull = 500; // Hull strength of monster
int Days = 0; // Number of days playing
int WarpSystem = 0; // Target system for warp
int SelectedShipType = 0; // Selected Ship type for Shiptype Info screen
int CheatCounter = 0;
int GalacticChartSystem = 0; // Current system on Galactic chart
int EncounterType = 0; // Type of current encounter
int CurForm = 0; // Form to return to
int NoClaim = 0; // Days of No-Claim
int LeaveEmpty = 0; // Number of cargo bays to leave empty when buying goods
int NewsSpecialEventCount = 0; // Simplifies tracking what Quests have just been initiated or completed for the News System. This is not important enough to get saved.
int TrackedSystem = -1; // The short-range chart will display an arrow towards this system if the value is not -1
int Shortcut1 = 0; // default shortcut 1 = Buy Cargo
int Shortcut2 = 1; // default shortcut 2 = Sell Cargo
int Shortcut3 = 2; // default shortcut 3 = Shipyard
int Shortcut4 = 10; // default shortcut 4 = Short Range Warp
// the next two values are NOT saved between sessions -- they can only be changed via cheats.
int ChanceOfVeryRareEncounter = CHANCEOFVERYRAREENCOUNTER;
int ChanceOfTradeInOrbit = CHANCEOFTRADEINORBIT;
Byte MonsterStatus = 0; // 0 = Space monster isn't available, 1 = Space monster is in Acamar system, 2 = Space monster is destroyed
Byte DragonflyStatus = 0; // 0 = Dragonfly not available, 1 = Go to Baratas, 2 = Go to Melina, 3 = Go to Regulas, 4 = Go to Zalkon, 5 = Dragonfly destroyed
Byte JaporiDiseaseStatus = 0; // 0 = No disease, 1 = Go to Japori (always at least 10 medicine cannisters), 2 = Assignment finished or canceled
Byte Difficulty = NORMAL; // Difficulty level
Byte JarekStatus = 0; // Ambassador Jarek 0=not delivered; 1=on board; 2=delivered
Byte InvasionStatus = 0; // Status Alien invasion of Gemulon; 0=not given yet; 1-7=days from start; 8=too late
Byte ExperimentStatus = 0; // Experiment; 0=not given yet,1-11 days from start; 12=performed, 13=cancelled
Byte FabricRipProbability = 0; // if Experiment = 8, this is the probability of being warped to a random planet.
Byte VeryRareEncounter = 0; // bit map for which Very Rare Encounter(s) have taken place (see traveler.c, around line 1850)
Byte WildStatus = 0; // Jonathan Wild: 0=not delivered; 1=on board; 2=delivered
Byte ReactorStatus = 0; // Unstable Reactor Status: 0=not encountered; 1-20=days of mission (bays of fuel left = 10 - (ReactorStatus/2); 21=delivered
Byte ScarabStatus = 0; // Scarab: 0=not given yet, 1=not destroyed, 2=destroyed, upgrade not performed, 3=destroyed, hull upgrade performed
Boolean AutoFuel = false; // Automatically get a full tank when arriving in a new system
Boolean AutoRepair = false; // Automatically get a full hull repair when arriving in a new system
Boolean Clicks = 0; // Distance from target system, 0 = arrived
Boolean Raided = false; // True when the commander has been raided during the trip
Boolean Inspected = false; // True when the commander has been inspected during the trip
Boolean MoonBought = false; // Indicates whether a moon is available at Utopia
Boolean EscapePod = false; // Escape Pod in ship
Boolean Insurance = false; // Insurance bought
Boolean AlwaysIgnoreTraders = false; // Automatically ignores traders when it is safe to do so
Boolean AlwaysIgnorePolice = true; // Automatically ignores police when it is safe to do so
Boolean AlwaysIgnorePirates = false; // Automatically ignores pirates when it is safe to do so
Boolean AlwaysIgnoreTradeInOrbit = false; // Automatically ignores Trade in Orbit when it is safe to do so
Boolean ArtifactOnBoard = false; // Alien artifact on board
Boolean ReserveMoney = false; // Keep enough money for insurance and mercenaries
Boolean PriceDifferences = false; // Show price differences instead of absolute prices
Boolean APLscreen = false; // Is true is the APL screen was last shown after the SRC
Boolean TribbleMessage = false; // Is true if the Ship Yard on the current system informed you about the tribbles
Boolean AlwaysInfo = false; // Will always go from SRC to Info
Boolean TextualEncounters = false; // Show encounters as text.
Boolean AutoAttack = false; // Auto-attack mode
Boolean AutoFlee = false; // Auto-flee mode
Boolean Continuous = false; // Continuous attack/flee mode
Boolean AttackIconStatus = false; // Show Attack Star or not
Boolean AttackFleeing = false; // Continue attack on fleeing ship
Boolean PossibleToGoThroughRip = false; // if Dr Fehler's experiment happened, we can only go through one space-time rip per warp.
Boolean UseHWButtons = false; // by default, don't use Hardware W buttons
Boolean NewsAutoPay = false; // by default, ask each time someone buys a newspaper
Boolean ShowTrackedRange = true; // display range when tracking a system on Short Range Chart
Boolean JustLootedMarie = 0; // flag to indicate whether player looted Marie Celeste
Boolean ArrivedViaWormhole = false; // flag to indicate whether player arrived on current planet via wormhole
Boolean AlreadyPaidForNewspaper = false; // once you buy a paper on a system, you don't have to pay again.
Boolean TrackAutoOff = true; // Automatically stop tracking a system when you get to it?
Boolean RemindLoans = true; // remind you every five days about outstanding loan balances
Boolean CanSuperWarp = false; // Do you have the Portable Singularity on board?
Boolean GameLoaded = false; // Indicates whether a game is loaded
Boolean LitterWarning = false; // Warning against littering has been issued.
Boolean SharePreferences = true; // Share preferences between switched games.
Boolean IdentifyStartup = false; // Identify commander at game start
Boolean RectangularButtonsOn = false; // Indicates on OS 5.0 and higher whether rectangular buttons should be used.
HIGHSCORE Hscores[MAXHIGHSCORE];
DWord romVersion;

1
Src/Gray.h Normal file
View File

@ -0,0 +1 @@
#define BPP4 1

112
Src/Math.c Normal file
View File

@ -0,0 +1,112 @@
/***********************************************************************
*
* SPACE TRADER 1.2.0
*
* Math.c
*
* Copyright (C) 2000-2002 Pieter Spronck, All Rights Reserved
*
* Additional coding by Sam Anderson (rulez2@home.com)
* Additional coding by Samuel Goldstein (palm@fogbound.net)
*
* Some code of Matt Lee's Dope Wars program has been used.
*
* 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.
*
* You can contact the author at space_trader@hotmail.com
*
* For those who are familiar with the classic game Elite: many of the
* ideas in Space Trader are heavily inspired by Elite.
*
**********************************************************************/
// *************************************************************************
// Math.c
// *************************************************************************
#include "external.h"
// *************************************************************************
// Temporary implementation of square root
// *************************************************************************
int sqrt( int a )
{
int i;
i = 0;
while (SQR( i ) < a)
++i;
if (i > 0)
if ((SQR( i ) - a) > (a - SQR( i-1 )))
--i;
return( i );
}
// *************************************************************************
// Square of the distance between two solar systems
// *************************************************************************
long SqrDistance( SOLARSYSTEM a, SOLARSYSTEM b )
{
return (SQR( a.X - b.X ) + SQR( a.Y - b.Y ));
}
// *************************************************************************
// Distance between two solar systems
// *************************************************************************
long RealDistance( SOLARSYSTEM a, SOLARSYSTEM b )
{
return (sqrt( SqrDistance( a, b ) ));
}
// *************************************************************************
// Pieter's new random functions, tweaked a bit by SjG
// *************************************************************************
#define DEFSEEDX 521288629
#define DEFSEEDY 362436069
static UInt16 SeedX = DEFSEEDX;
static UInt16 SeedY = DEFSEEDY;
int GetRandom2(int maxVal)
{
return (int)(Rand() % maxVal);
}
UInt16 Rand()
{
static UInt16 a = 18000;
static UInt16 b = 30903;
SeedX = a*(SeedX&MAX_WORD) + (SeedX>>16);
SeedY = b*(SeedY&MAX_WORD) + (SeedY>>16);
return ((SeedX<<16) + (SeedY&MAX_WORD));
}
void RandSeed( UInt16 seed1, UInt16 seed2 )
{
if (seed1)
SeedX = seed1; /* use default seeds if parameter is 0 */
else
SeedX = DEFSEEDX;
if (seed2)
SeedY = seed2;
else
SeedY = DEFSEEDY;
}

989
Src/Merchant.c Normal file
View File

@ -0,0 +1,989 @@
/***********************************************************************
*
* SPACE TRADER 1.2.0
*
* Merchant.c
*
* Copyright (C) 2000-2002 Pieter Spronck, All Rights Reserved
*
* Additional coding by Sam Anderson (rulez2@home.com)
* Additional coding by Samuel Goldstein (palm@fogbound.net)
*
* Some code of Matt Lee's Dope Wars program has been used.
*
* 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.
*
* You can contact the author at space_trader@hotmail.com
*
* For those who are familiar with the classic game Elite: many of the
* ideas in Space Trader are heavily inspired by Elite.
*
**********************************************************************/
// Needed to determine the height and width of a bitmap below OS version 4.0.
// The direct access is only used below 4.0, otherwise the BmpGetDimensions function is used.
#ifndef ALLOW_ACCESS_TO_INTERNALS_OF_BITMAPS
#define ALLOW_ACCESS_TO_INTERNALS_OF_BITMAPS 1
#endif
#include "external.h"
//#include <scrDriver.h>
#define ourMinVersion sysMakeROMVersion(2,0,0,sysROMStageRelease,0)
void UnpackBooleans(Byte _val, Boolean *_a, Boolean *_b, Boolean *_c, Boolean *_d,
Boolean *_e, Boolean *_f, Boolean *_g, Boolean *_h);
Byte PackBooleans(Boolean _a, Boolean _b, Boolean _c, Boolean _d,
Boolean _e, Boolean _f, Boolean _g, Boolean _h);
Byte PackBytes(Byte _a, Byte _b);
void UnpackBytes(Byte _val, Byte *_a, Byte *_b);
#define BELOW35 (romVersion < sysMakeROMVersion( 3, 5, 0, sysROMStageRelease, 0 ))
#define BELOW40 (romVersion < sysMakeROMVersion( 4, 0, 0, sysROMStageRelease, 0 ))
static char* SAVEGAMENAME = "SpaceTraderSave";
static char* SWITCHGAMENAME = "SpaceTraderSwitch";
// *************************************************************************
// Get width of bitmap
// *************************************************************************
int GetBitmapWidth( BitmapPtr BmpPtr )
{
Coord W;
if (BELOW40)
return BmpPtr->width;
else
{
BmpGetDimensions( BmpPtr, &W, 0, 0 );
return W;
}
}
// *************************************************************************
// Get heigth of bitmap
// *************************************************************************
int GetBitmapHeight( BitmapPtr BmpPtr )
{
Coord H;
if (BELOW40)
return BmpPtr->height;
else
{
BmpGetDimensions( BmpPtr, 0, &H, 0 );
return H;
}
}
// *************************************************************************
// Determines if the OS supports this resolution
// *************************************************************************
static Err GraphicsSupport( void )
{
#ifdef BPP1
return 0;
#else
UInt32 depth, reqmode, reqmodedec;
#ifdef BPP8
Boolean color;
#endif
#ifdef BPP16
Boolean color;
#endif
DWord romVersion;
// See if we're on in minimum required version of the ROM or later.
FtrGet( sysFtrCreator, sysFtrNumROMVersion, &romVersion );
if (BELOW35)
{
FrmAlert( ErrGraphicsSupportAlert );
return 1;
}
#ifdef BPP16
if (BELOW40)
{
FrmAlert( ErrGraphicsSupport40Alert );
return 1;
}
#endif
#ifdef BPP16
reqmode = 0x8000;
reqmodedec = 16;
#else
#ifdef BPP8
reqmode = 0x0080;
reqmodedec = 8;
#else // BPP4
reqmode = 0x0008;
reqmodedec = 4;
#endif
#endif
#ifndef BPP4
WinScreenMode( winScreenModeGetSupportsColor, NULL, NULL, NULL, &color );
if (!color)
{
FrmAlert( ErrGraphicsSupportAlert );
return 1;
}
#endif
WinScreenMode( winScreenModeGetSupportedDepths, NULL, NULL, &depth, NULL );
if (((reqmode & depth) == 0) || (WinScreenMode( winScreenModeSet, NULL, NULL, &reqmodedec, NULL )))
{
FrmAlert( ErrGraphicsSupportAlert );
return 1;
}
return( 0 );
#endif
}
/***********************************************************************
* Resets the screen depth to default values.
***********************************************************************/
static void EndGraphicsSupport( void )
{
#ifndef BPP1
WinScreenMode( winScreenModeSetToDefaults, NULL, NULL, NULL, NULL );
#endif
return;
}
// *************************************************************************
// Determines if the ROM version is compatible
// *************************************************************************
Err RomVersionCompatible(DWord requiredVersion, Word launchFlags)
{
DWord romVersion;
// See if we're on in minimum required version of the ROM or later.
FtrGet( sysFtrCreator, sysFtrNumROMVersion, &romVersion );
if (romVersion < requiredVersion)
{
if ((launchFlags & (sysAppLaunchFlagNewGlobals | sysAppLaunchFlagUIApp)) ==
(sysAppLaunchFlagNewGlobals | sysAppLaunchFlagUIApp))
{
FrmAlert (RomIncompatibleAlert);
// Pilot 1.0 will continuously relaunch this app unless we switch to
// another safe one.
if (romVersion < sysMakeROMVersion( 2,0,0,sysROMStageRelease,0 ))
AppLaunchWithCommand(sysFileCDefaultApp, sysAppLaunchCmdNormalLaunch, NULL);
}
return (sysErrRomIncompatible);
}
return (0);
}
// *************************************************************************
// Determines if the software is outdated
// *************************************************************************
Err OutdatedSoftware( void )
{
#ifdef BETATEST
ULong Secs;
DateTimeType Dt;
DateTimePtr DtP;
Dt.year = 2002;
Dt.month = 12;
Dt.day = 31;
Dt.hour = 0;
Dt.minute = 0;
Dt.second = 0;
DtP = &Dt;
Secs = TimDateTimeToSeconds( DtP );
if (Secs < TimGetSeconds())
{
FrmAlert( OutdatedSoftwareAlert );
return( 1 );
}
#endif
return( 0 );
}
// Fills global variables
static void FillGlobals( SAVEGAMETYPE* sg, int State )
{
int i;
Boolean OldVersion = false;
Boolean Trash;
if (sg->VersionMinor < 4)
OldVersion = true;
Credits = sg->Credits;
Debt = sg->Debt;
Days = sg->Days;
WarpSystem = sg->WarpSystem;
SelectedShipType = sg->SelectedShipType;
for (i=0; i<MAXTRADEITEM; ++i)
{
BuyPrice[i] = sg->BuyPrice[i];
SellPrice[i] = sg->SellPrice[i];
}
for (i=0; i<MAXSHIPTYPE; ++i)
ShipPrice[i] = sg->ShipPrice[i];
GalacticChartSystem = sg->GalacticChartSystem;
PoliceKills = sg->PoliceKills;
TraderKills = sg->TraderKills;
PirateKills = sg->PirateKills;
PoliceRecordScore = sg->PoliceRecordScore;
ReputationScore = sg->ReputationScore;
Clicks = sg->Clicks;
EncounterType = sg->EncounterType;
Raided = sg->Raided;
MonsterStatus = sg->MonsterStatus;
DragonflyStatus = sg->DragonflyStatus;
JaporiDiseaseStatus = sg->JaporiDiseaseStatus;
MoonBought = sg->MoonBought;
MonsterHull = sg->MonsterHull;
StrCopy( NameCommander, sg->NameCommander );
CurForm = sg->CurForm;
MemMove( &Ship, &(sg->Ship), sizeof( Ship ) );
MemMove( &Opponent, &(sg->Opponent), sizeof( Opponent) );
for (i=0; i<MAXCREWMEMBER+1; ++i)
MemMove( &Mercenary[i], &(sg->Mercenary[i]), sizeof( Mercenary[i] ) );
for (i=0; i<MAXSOLARSYSTEM; ++i)
MemMove( &SolarSystem[i], &(sg->SolarSystem[i]), sizeof( SolarSystem[i] ) );
EscapePod = sg->EscapePod;
Insurance = sg->Insurance;
NoClaim = sg->NoClaim;
Inspected = sg->Inspected;
LitterWarning = sg->LitterWarning;
Difficulty = sg->Difficulty;
for (i=0; i<MAXWORMHOLE; ++i)
Wormhole[i] = sg->Wormhole[i];
for (i=0; i<MAXTRADEITEM; ++i)
if (Ship.Cargo[i] <= 0)
BuyingPrice[i] = 0;
else
BuyingPrice[i] = sg->BuyingPrice[i];
ArtifactOnBoard = sg->ArtifactOnBoard;
JarekStatus = sg->JarekStatus;
InvasionStatus = sg->InvasionStatus;
if (OldVersion)
{
ExperimentStatus = 0;
FabricRipProbability = 0;
VeryRareEncounter = 0;
WildStatus = 0;
ReactorStatus = 0;
TrackedSystem = -1;
JustLootedMarie = false;
AlreadyPaidForNewspaper = false;
GameLoaded = false;
// if Nix already has a special, we have to get rid of the
// spurious GETREACTOR quest.
if (SolarSystem[NIXSYSTEM].Special == -1)
SolarSystem[NIXSYSTEM].Special = REACTORDELIVERED;
else
{
for (i=0;i<MAXSOLARSYSTEM;i++)
if (SolarSystem[i].Special == GETREACTOR)
SolarSystem[i].Special = -1;
}
// To make sure 1.1.2 is upgradeable to 1.2.0
if (SolarSystem[GEMULONSYSTEM].Special == 27)
SolarSystem[GEMULONSYSTEM].Special = GEMULONRESCUED;
if (SolarSystem[DEVIDIASYSTEM].Special == 26)
SolarSystem[DEVIDIASYSTEM].Special = JAREKGETSOUT;
ScarabStatus = 0;
ArrivedViaWormhole = false;
CanSuperWarp = false;
SharePreferences = true;
if (State != 2 || !SharePreferences)
{
Shortcut1 = 0;
Shortcut2 = 1;
Shortcut3 = 2;
Shortcut4 = 10;
UseHWButtons = false;
NewsAutoPay = false;
AlwaysIgnoreTradeInOrbit = false;
ShowTrackedRange = true;
TrackAutoOff = true;
RemindLoans = true;
IdentifyStartup = false;
}
}
else
{
UnpackBytes(sg->ExperimentAndWildStatus, &ExperimentStatus,&WildStatus);
FabricRipProbability = sg->FabricRipProbability;
VeryRareEncounter = sg->VeryRareEncounter;
SharePreferences = sg->SharePreferences;
if (State != 2 || !SharePreferences)
UnpackBooleans(sg->BooleanCollection, &UseHWButtons, &NewsAutoPay,
&ShowTrackedRange, &JustLootedMarie, &ArrivedViaWormhole, &TrackAutoOff,
&RemindLoans, &CanSuperWarp);
else
UnpackBooleans(sg->BooleanCollection, &Trash, &Trash,
&Trash, &JustLootedMarie, &ArrivedViaWormhole, &Trash,
&Trash, &CanSuperWarp);
ReactorStatus = sg-> ReactorStatus;
TrackedSystem = sg->TrackedSystem;
ScarabStatus = sg->ScarabStatus;
AlreadyPaidForNewspaper = sg->AlreadyPaidForNewspaper;
GameLoaded = sg->GameLoaded;
if (State != 2 || !SharePreferences)
{
AlwaysIgnoreTradeInOrbit = sg->AlwaysIgnoreTradeInOrbit;
Shortcut1 = sg->Shortcut1;
Shortcut2 = sg->Shortcut2;
Shortcut3 = sg->Shortcut3;
Shortcut4 = sg->Shortcut4;
IdentifyStartup = sg->IdentifyStartup;
RectangularButtonsOn = sg->RectangularButtonsOn;
}
}
if (State != 2 || !SharePreferences)
{
ReserveMoney = sg->ReserveMoney;
PriceDifferences = sg->PriceDifferences;
APLscreen = sg->APLscreen;
TribbleMessage = sg->TribbleMessage;
AlwaysInfo = sg->AlwaysInfo;
LeaveEmpty = sg->LeaveEmpty;
TextualEncounters = sg->TextualEncounters;
Continuous = sg->Continuous;
AttackFleeing = sg->AttackFleeing;
AutoFuel = sg->AutoFuel;
AutoRepair = sg->AutoRepair;
AlwaysIgnoreTraders = sg->AlwaysIgnoreTraders;
AlwaysIgnorePolice = sg->AlwaysIgnorePolice;
AlwaysIgnorePirates = sg->AlwaysIgnorePirates;
}
SolarSystem[UTOPIASYSTEM].Special = MOONBOUGHT;
}
// Load game and returns true if OK
Boolean LoadGame( int State )
{
Word prefsSize;
SWord prefsVersion = noPreferenceFound;
SAVEGAMETYPE* sg;
Handle sgH;
Boolean DontLoad = false;
UInt index = 0;
VoidHand RecHandle;
VoidPtr RecPointer;
LocalID DbId;
DmOpenRef pmDB;
sgH = MemHandleNew( sizeof( SAVEGAMETYPE ) );
sg = MemHandleLock( sgH );
if (State == 0)
{
prefsSize = sizeof( SAVEGAMETYPE );
prefsVersion = PrefGetAppPreferences ( appFileCreator, appPrefID, sg, &prefsSize, true );
if (prefsVersion > 1)
prefsVersion = noPreferenceFound;
if (prefsVersion == noPreferenceFound)
{
CurForm = MainForm;
DontLoad = true;
}
}
else
{
DbId = DmFindDatabase( 0, (State == 1 ? SAVEGAMENAME : SWITCHGAMENAME ) );
if (DbId == 0)
{
if (State == 1)
FrmAlert( CannotLoadAlert );
MemPtrUnlock( sg );
MemHandleFree( sgH );
return false;
}
pmDB = DmOpenDatabase( 0, DbId, dmModeReadWrite );
RecHandle = DmGetRecord( pmDB, 0 );
if (RecHandle == NULL)
{
if (State == 1)
FrmAlert( CannotLoadAlert );
DmReleaseRecord( pmDB, 0, true );
DmCloseDatabase( pmDB );
MemPtrUnlock( sg );
MemHandleFree( sgH );
return false;
}
RecPointer = MemHandleLock( RecHandle );
MemMove( sg, RecPointer, sizeof( SAVEGAMETYPE ) );
MemHandleUnlock( RecHandle );
DmReleaseRecord( pmDB, 0, true );
DmCloseDatabase( pmDB );
}
if (!DontLoad)
FillGlobals( sg, State );
MemPtrUnlock( sg );
MemHandleFree( sgH );
return true;
}
// *************************************************************************
// Get the current application's preferences.
// *************************************************************************
static Err AppStart(void)
{
FtrGet( sysFtrCreator, sysFtrNumROMVersion, &romVersion );
LoadGame( 0 );
ChanceOfVeryRareEncounter = CHANCEOFVERYRAREENCOUNTER;
ChanceOfTradeInOrbit = CHANCEOFTRADEINORBIT;
return 0;
}
// *************************************************************************
// Pack two limited range bytes into a two nibbles (a single byte) for storage.
// Use this with caution -- it doesn't check that the values are really
// within the range of 0-15
// *************************************************************************
Byte PackBytes(Byte a, Byte b)
{
return (Byte)(a<<4 | (b & (Byte)0x0F));
}
// *************************************************************************
// Unpack two limited range bytes from a single byte from storage.
// High order 4 bits become Byte a, low order 4 bits become Byte b
// *************************************************************************
void UnpackBytes(Byte val, Byte *a, Byte *b)
{
*a = val >> 4;
*b = val & (Byte) 15; // 0x0F
}
// *************************************************************************
// Pack eight booleans into a single byte for storage.
// *************************************************************************
Byte PackBooleans(Boolean a, Boolean b, Boolean c, Boolean d,
Boolean e, Boolean f, Boolean g, Boolean h)
{
Byte retByte = 0;
if (a) retByte |= (Byte)128; // 0x80
if (b) retByte |= (Byte) 64; // 0x40
if (c) retByte |= (Byte) 32; // 0x20
if (d) retByte |= (Byte) 16; // etc.
if (e) retByte |= (Byte) 8;
if (f) retByte |= (Byte) 4;
if (g) retByte |= (Byte) 2;
if (h) retByte |= (Byte) 1;
return retByte;
}
// *************************************************************************
// unpack eight booleans from a single byte out of storage.
// *************************************************************************
void UnpackBooleans(Byte val, Boolean *a, Boolean *b, Boolean *c, Boolean *d,
Boolean *e, Boolean *f, Boolean *g, Boolean *h)
{
if ( val & (Byte)128 )
*a = true;
else
*a = false;
if (val & (Byte) 64 )
*b = true;
else
*b = false;
if (val & (Byte) 32 )
*c = true;
else
*c = false;
if (val & (Byte) 16 )
*d = true;
else
*d = false;
if (val & (Byte) 8 )
*e = true;
else
*e = false;
if (val & (Byte) 4 )
*f = true;
else
*f = false;
if (val & (Byte) 2 )
*g = true;
else
*g = false;
if (val & (Byte) 1 )
*h = true;
else
*h = false;
}
// Save the game, either in the Statesave or in a file
Boolean SaveGame( int State )
{
int i;
SAVEGAMETYPE* sg;
Handle sgH;
Err err;
VoidHand RecHandle;
LocalID DbId;
UInt index = 0;
VoidPtr p;
DmOpenRef pmDB;
Word theAttrs;
sgH = MemHandleNew( sizeof( SAVEGAMETYPE ) );
sg = MemHandleLock( sgH );
sg->Credits = Credits;
sg->Debt = Debt;
sg->Days = Days;
sg->WarpSystem = WarpSystem;
sg->SelectedShipType = SelectedShipType;
for (i=0; i<MAXTRADEITEM; ++i)
{
sg->BuyPrice[i] = BuyPrice[i];
sg->SellPrice[i] = SellPrice[i];
}
for (i=0; i<MAXSHIPTYPE; ++i)
sg->ShipPrice[i] = ShipPrice[i];
sg->GalacticChartSystem = GalacticChartSystem;
sg->PoliceKills = PoliceKills;
sg->TraderKills = TraderKills;
sg->PirateKills = PirateKills;
sg->PoliceRecordScore = PoliceRecordScore;
sg->ReputationScore = ReputationScore;
sg->AutoFuel = AutoFuel;
sg->AutoRepair = AutoRepair;
sg->Clicks = Clicks;
sg->EncounterType = EncounterType;
sg->Raided = Raided;
sg->MonsterStatus = MonsterStatus;
sg->DragonflyStatus = DragonflyStatus;
sg->JaporiDiseaseStatus = JaporiDiseaseStatus;
sg->MoonBought = MoonBought;
sg->MonsterHull = MonsterHull;
StrCopy( sg->NameCommander, NameCommander );
sg->CurForm = CurForm;
MemMove( &(sg->Ship), &Ship, sizeof( sg->Ship ) );
MemMove( &(sg->Opponent), &Opponent, sizeof( sg->Opponent ) );
for (i=0; i<MAXCREWMEMBER+1; ++i)
MemMove( &(sg->Mercenary[i]), &Mercenary[i], sizeof( sg->Mercenary[i] ) );
for (i=0; i<MAXSOLARSYSTEM; ++i)
MemMove( &(sg->SolarSystem[i]), &SolarSystem[i], sizeof( sg->SolarSystem[i] ) );
for (i=0; i<MAXFORFUTUREUSE; ++i)
sg->ForFutureUse[i] = 0;
sg->EscapePod = EscapePod;
sg->Insurance = Insurance;
sg->NoClaim = NoClaim;
sg->Inspected = Inspected;
sg->LitterWarning = LitterWarning;
sg->AlwaysIgnoreTraders = AlwaysIgnoreTraders;
sg->AlwaysIgnorePolice = AlwaysIgnorePolice;
sg->AlwaysIgnorePirates = AlwaysIgnorePirates;
sg->Difficulty = Difficulty;
sg->VersionMajor = 1;
// changed from 3 to 4. SjG
sg->VersionMinor = 4;
for (i=0; i<MAXWORMHOLE; ++i)
sg->Wormhole[i] = Wormhole[i];
for (i=0; i<MAXTRADEITEM; ++i)
sg->BuyingPrice[i] = BuyingPrice[i];
sg->ArtifactOnBoard = ArtifactOnBoard;
sg->ReserveMoney = ReserveMoney;
sg->PriceDifferences = PriceDifferences;
sg->APLscreen = APLscreen;
sg->TribbleMessage = TribbleMessage;
sg->AlwaysInfo = AlwaysInfo;
sg->LeaveEmpty = LeaveEmpty;
sg->TextualEncounters = TextualEncounters;
sg->JarekStatus = JarekStatus;
sg->InvasionStatus = InvasionStatus;
sg->Continuous = Continuous;
sg->AttackFleeing = AttackFleeing;
sg->ExperimentAndWildStatus = PackBytes(ExperimentStatus, WildStatus);
sg->FabricRipProbability = FabricRipProbability;
sg->VeryRareEncounter = VeryRareEncounter;
sg->BooleanCollection = PackBooleans(UseHWButtons, NewsAutoPay,
ShowTrackedRange, JustLootedMarie, ArrivedViaWormhole, TrackAutoOff,
RemindLoans, CanSuperWarp);
sg->ReactorStatus = ReactorStatus;
sg->TrackedSystem = TrackedSystem;
sg->ScarabStatus = ScarabStatus;
sg->AlwaysIgnoreTradeInOrbit = AlwaysIgnoreTradeInOrbit;
sg->AlreadyPaidForNewspaper = AlreadyPaidForNewspaper;
sg->GameLoaded = GameLoaded;
sg->SharePreferences = SharePreferences;
sg->IdentifyStartup = IdentifyStartup;
sg->Shortcut1 = Shortcut1;
sg->Shortcut2 = Shortcut2;
sg->Shortcut3 = Shortcut3;
sg->Shortcut4 = Shortcut4;
sg->RectangularButtonsOn = RectangularButtonsOn;
if (State == 0)
PrefSetAppPreferences( appFileCreator, appPrefID, appPrefVersionNum,
sg, sizeof( SAVEGAMETYPE ), true );
else
{
if (State == 2)
{
if (!LoadGame( 2 ))
NameCommander[0] = '\0';
}
DbId = DmFindDatabase( 0, (State == 1 ? SAVEGAMENAME : SWITCHGAMENAME ) );
if (DbId == 0)
{
err = DmCreateDatabase( 0, (State == 1 ? SAVEGAMENAME : SWITCHGAMENAME ), appFileCreator, 'Data', false );
if (err != errNone)
{
FrmAlert( (State == 1 ? CannotSaveAlert : CannotSwitchAlert ) );
if (State == 2)
FillGlobals( sg, State );
MemPtrUnlock( sg );
MemHandleFree( sgH );
return false;
}
DbId = DmFindDatabase( 0, (State == 1 ? SAVEGAMENAME : SWITCHGAMENAME ) );
if (DbId == 0)
{
FrmAlert( (State == 1 ? CannotSaveAlert : CannotSwitchAlert ) );
if (State == 2)
FillGlobals( sg, State ); // Restore previous setting
MemPtrUnlock( sg );
MemHandleFree( sgH );
return false;
}
pmDB = DmOpenDatabase( 0, DbId, dmModeReadWrite );
RecHandle = DmNewRecord( pmDB, &index, sizeof( SAVEGAMETYPE ) );
DmWrite( MemHandleLock( RecHandle ), 0, sg, sizeof( SAVEGAMETYPE ) );
MemHandleUnlock( RecHandle );
}
else
{
pmDB = DmOpenDatabase( 0, DbId, dmModeReadWrite );
p = MemHandleLock( DmGetRecord( pmDB, 0 ) );
DmWrite( p, 0, sg, sizeof( SAVEGAMETYPE ) );
MemPtrUnlock( p );
}
DmReleaseRecord( pmDB, 0, true );
// Get the attributes for our database
DmDatabaseInfo( 0, DbId, NULL, &theAttrs, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL);
// Set the backup flag
theAttrs |= dmHdrAttrBackup;
// Set the attributes
DmSetDatabaseInfo( 0, DbId, NULL, &theAttrs, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL);
DmCloseDatabase( pmDB );
}
MemPtrUnlock( sg );
MemHandleFree( sgH );
return true;
}
// *************************************************************************
// Save the current state of the application.
// *************************************************************************
static void AppStop(void)
{
SaveGame( 0 );
FrmCloseAllForms();
}
// *************************************************************************
// This routine is the event loop for the application.
// *************************************************************************
static void AppEventLoop(void)
{
Word error;
EventType event;
UInt32 LastTicks;
do
{
if (Continuous && (AutoAttack || AutoFlee) && (CurForm == EncounterForm))
{
LastTicks = TimGetTicks();
EvtGetEvent( &event, SysTicksPerSecond());
if (event.eType == nilEvent &&
(3 * (TimGetTicks() - LastTicks) > 2 * SysTicksPerSecond()))
{
EncounterFormHandleEvent( &event );
continue;
}
}
else
EvtGetEvent(&event, evtWaitForever);
if ( (UseHWButtons && event.eType == keyDownEvent && (event.data.keyDown.chr == vchrHard1 ||
event.data.keyDown.chr == vchrHard2 || event.data.keyDown.chr == vchrHard3 ||
event.data.keyDown.chr == vchrHard4) ) ||
!SysHandleEvent(&event))
if (!MenuHandleEvent(0, &event, &error))
if (!AppHandleEvent(&event))
FrmDispatchEvent(&event);
if (CurForm != EncounterForm)
{
AutoAttack = false;
AutoFlee = false;
}
} while (event.eType != appStopEvent);
}
// *************************************************************************
// This routine is the event handler for the Start screen.
// *************************************************************************
Boolean MainFormHandleEvent(EventPtr eventP)
{
Boolean handled = false;
FormPtr frmP = FrmGetActiveForm();
switch (eventP->eType)
{
case frmOpenEvent:
FrmDrawForm ( frmP);
handled = true;
break;
case frmUpdateEvent:
FrmDrawForm ( frmP );
handled = true;
break;
// Start new game
case penDownEvent:
case keyDownEvent:
StartNewGame();
handled = true;
break;
default:
break;
}
return handled;
}
// *************************************************************************
// Handling of the events of several forms.
// *************************************************************************
Boolean DefaultFormHandleEvent(EventPtr eventP)
{
Boolean handled = false;
FormPtr frmP = FrmGetActiveForm();
switch (eventP->eType)
{
case frmOpenEvent:
FrmDrawForm ( frmP);
handled = true;
break;
case frmUpdateEvent:
FrmDrawForm ( frmP );
handled = true;
break;
}
return handled;
}
// *************************************************************************
// This is the main application.
// *************************************************************************
long MerchantPilotMain( Word cmd, Ptr cmdPBP, Word launchFlags )
{
Err error;
int i;
switch (cmd)
{
case sysAppLaunchCmdNormalLaunch:
error = RomVersionCompatible (ourMinVersion, launchFlags);
if (error)
return error;
error = OutdatedSoftware();
if (error)
return error;
error = GraphicsSupport();
if (error)
return error;
SystemBmp = DmGetResource( bitmapRsc, SystemBitmapFamily );
SystemBmpPtr = MemHandleLock( SystemBmp );
CurrentSystemBmp = DmGetResource( bitmapRsc, CurrentSystemBitmapFamily );
CurrentSystemBmpPtr = MemHandleLock( CurrentSystemBmp );
ShortRangeSystemBmp = DmGetResource( bitmapRsc, ShortRangeSystemBitmapFamily );
ShortRangeSystemBmpPtr = MemHandleLock( ShortRangeSystemBmp );
WormholeBmp = DmGetResource( bitmapRsc, WormholeBitmapFamily );
WormholeBmpPtr = MemHandleLock( WormholeBmp );
SmallWormholeBmp = DmGetResource( bitmapRsc, SmallWormholeBitmapFamily );
SmallWormholeBmpPtr = MemHandleLock( SmallWormholeBmp );
VisitedSystemBmp = DmGetResource( bitmapRsc, VisitedSystemBitmapFamily );
VisitedSystemBmpPtr = MemHandleLock( VisitedSystemBmp );
CurrentVisitedSystemBmp = DmGetResource( bitmapRsc, CurrentVisitedSystemBitmapFamily );
CurrentVisitedSystemBmpPtr = MemHandleLock( CurrentVisitedSystemBmp );
VisitedShortRangeSystemBmp = DmGetResource( bitmapRsc, VisitedShortRangeSystemBitmapFamily );
VisitedShortRangeSystemBmpPtr = MemHandleLock( VisitedShortRangeSystemBmp );
// Load bitmaps for the ships (4 Bitmap Family Groups Per Ship) FleaBitmapFamily is the Base
for (i=0; i<MAXSHIPTYPE+EXTRASHIPS; i++)
{
ShipBmp[i] = DmGetResource( bitmapRsc, FleaBitmapFamily + i*400);
ShipBmpPtr[i] = MemHandleLock( ShipBmp[i] );
DamagedShipBmp[i] = DmGetResource( bitmapRsc, FleaDamagedBitmapFamily + i*400 );
DamagedShipBmpPtr[i] = MemHandleLock( DamagedShipBmp[i] );
if (Shiptype[i].ShieldSlots <= 0)
{
ShieldedShipBmp[i] = ShipBmp[i];
ShieldedShipBmpPtr[i] = ShipBmpPtr[i];
DamagedShieldedShipBmp[i] = DamagedShipBmp[i];
DamagedShieldedShipBmpPtr[i] = DamagedShipBmpPtr[i];
}
else
{
ShieldedShipBmp[i] = DmGetResource( bitmapRsc, FireflyShieldedBitmapFamily + (i-2)*400);
ShieldedShipBmpPtr[i] = MemHandleLock( ShieldedShipBmp[i] );
DamagedShieldedShipBmp[i] = DmGetResource( bitmapRsc, FireflyShDamBitmapFamily + (i-2)*400);
DamagedShieldedShipBmpPtr[i] = MemHandleLock( DamagedShieldedShipBmp[i] );
}
}
for (i=0; i<5; i++)
{
IconBmp[i] = DmGetResource( bitmapRsc, PirateBitmapFamily + i*100);
IconBmpPtr[i] = MemHandleLock( IconBmp[i] );
}
error = AppStart();
if (error)
return error;
if (IdentifyStartup)
FrmCustomAlert( IdentifyStartupAlert, NameCommander, "", "" );
FrmGotoForm( CurForm );
AppEventLoop();
AppStop();
for (i=4; i>=0; i--)
{
MemHandleUnlock( IconBmp[i] );
DmReleaseResource( IconBmp[i] );
}
for (i=MAXSHIPTYPE+EXTRASHIPS-1; i>=0; i--)
{
if (Shiptype[i].ShieldSlots > 0)
{
MemHandleUnlock( DamagedShieldedShipBmp[i] );
DmReleaseResource( DamagedShieldedShipBmp[i] );
MemHandleUnlock( ShieldedShipBmp[i] );
DmReleaseResource( ShieldedShipBmp[i] );
}
MemHandleUnlock( DamagedShipBmp[i] );
DmReleaseResource( DamagedShipBmp[i] );
MemHandleUnlock( ShipBmp[i] );
DmReleaseResource( ShipBmp[i] );
}
MemHandleUnlock( VisitedShortRangeSystemBmp );
DmReleaseResource( VisitedShortRangeSystemBmp );
MemHandleUnlock( CurrentVisitedSystemBmp );
DmReleaseResource( CurrentVisitedSystemBmp );
MemHandleUnlock( VisitedSystemBmp );
DmReleaseResource( VisitedSystemBmp );
MemHandleUnlock( SmallWormholeBmp );
DmReleaseResource( SmallWormholeBmp );
MemHandleUnlock( WormholeBmp );
DmReleaseResource( WormholeBmp );
MemHandleUnlock( ShortRangeSystemBmp );
DmReleaseResource( ShortRangeSystemBmp );
MemHandleUnlock( CurrentSystemBmp );
DmReleaseResource( CurrentSystemBmp );
MemHandleUnlock( SystemBmp );
DmReleaseResource( SystemBmp );
break;
default:
break;
}
EndGraphicsSupport();
return 0;
}
// *************************************************************************
// This is the main entry point for the application.
// *************************************************************************
DWord PilotMain( Word cmd, Ptr cmdPBP, Word launchFlags)
{
return MerchantPilotMain(cmd, cmdPBP, launchFlags);
}

71
Src/Money.c Normal file
View File

@ -0,0 +1,71 @@
/***********************************************************************
*
* SPACE TRADER 1.2.0
*
* Money.c
*
* Copyright (C) 2000-2002 Pieter Spronck, All Rights Reserved
*
* Additional coding by Sam Anderson (rulez2@home.com)
* Additional coding by Samuel Goldstein (palm@fogbound.net)
*
* Some code of Matt Lee's Dope Wars program has been used.
*
* 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.
*
* You can contact the author at space_trader@hotmail.com
*
* For those who are familiar with the classic game Elite: many of the
* ideas in Space Trader are heavily inspired by Elite.
*
**********************************************************************/
#include "external.h"
// *************************************************************************
// Functions Include:
//
// long CurrentWorth( void )
// void PayInterest( void )
//
// *************************************************************************
// Current worth of commander
// *************************************************************************
long CurrentWorth( void )
{
return (CurrentShipPrice( false ) + Credits - Debt + (MoonBought ? COSTMOON : 0));
}
// *************************************************************************
// Pay interest on debt
// *************************************************************************
void PayInterest( void )
{
long IncDebt;
if (Debt > 0)
{
IncDebt = max( 1, Debt / 10 );
if (Credits > IncDebt)
Credits -= IncDebt;
else
{
Debt += (IncDebt - Credits);
Credits = 0;
}
}
}

164
Src/OtherEvent.c Normal file
View File

@ -0,0 +1,164 @@
/***********************************************************************
*
* SPACE TRADER 1.2.0
*
* OtherEvent.c
*
* Copyright (C) 2000-2002 Pieter Spronck, All Rights Reserved
*
* Additional coding by Sam Anderson (rulez2@home.com)
* Additional coding by Samuel Goldstein (palm@fogbound.net)
*
* Some code of Matt Lee's Dope Wars program has been used.
*
* 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.
*
* You can contact the author at space_trader@hotmail.com
*
* For those who are familiar with the classic game Elite: many of the
* ideas in Space Trader are heavily inspired by Elite.
*
**********************************************************************/
// *************************************************************************
//
// Special Cargo Screen Event Handler
//
// *************************************************************************
#include "external.h"
static Boolean MessageHasBeenShown = false;
static void DrawSpecialCargoForm()
{
FormPtr frmP;
int Line;
frmP = FrmGetActiveForm();
RectangularShortcuts( frmP, SpecialCargoBButton );
FrmDrawForm( frmP );
Line = 18;
FntSetFont ( stdFont );
if (Ship.Tribbles > 0)
{
if (Ship.Tribbles >= MAXTRIBBLES)
StrCopy( SBuf, "An infestation of tribbles." );
else
{
StrCopy( SBuf, "" );
SBufMultiples( Ship.Tribbles, "cute, furry tribble" );
StrCat( SBuf, "." );
}
DrawChars (SBuf, 0, Line);
Line += 14;
}
if (JaporiDiseaseStatus == 1)
{
DrawChars( "10 bays of antidote.", 0, Line);
Line += 14;
}
if (ArtifactOnBoard)
{
DrawChars( "An alien artifact.", 0, Line);
Line += 14;
}
if (JarekStatus == 2)
{
DrawChars( "A haggling computer.", 0, Line);
Line += 14;
}
if (ReactorStatus > 0 && ReactorStatus < 21)
{
DrawChars( "An unstable reactor taking up 5 bays.", 0, Line);
Line += 14;
StrCopy( SBuf, "" );
SBufMultiples( 10 - ((ReactorStatus - 1) / 2), "bay" );
StrCat( SBuf, " of enriched fuel." );
DrawChars (SBuf, 0, Line);
Line += 14;
}
if (CanSuperWarp)
{
DrawChars( "A Portable Singularity.", 0, Line);
Line += 14;
}
if (Line == 18)
{
DrawChars ("No special items.", 0, Line);
}
}
Boolean SpecialCargoFormHandleEvent( EventPtr eventP )
{
Boolean handled = false;
switch (eventP->eType)
{
case ctlSelectEvent:
if (eventP->data.ctlSelect.controlID ==SpecialCargoStatusButton)
{
CurForm = CommanderStatusForm;
}
else if (eventP->data.ctlSelect.controlID == SpecialCargoShipButton)
{
CurForm = CurrentShipForm;
}
else if (eventP->data.ctlSelect.controlID == SpecialCargoQuestsButton)
{
CurForm = QuestsForm;
}
FrmGotoForm( CurForm );
handled = true;
break;
case frmOpenEvent:
case frmUpdateEvent:
DrawSpecialCargoForm();
handled = true;
break;
default:
break;
}
return handled;
}
/***********************************************************************
* Show message shows a general message, usually for debugging.
***********************************************************************/
void ShowMessage( char *str1, char* str2, char* str3, Boolean ShowAlways )
{
if (MessageHasBeenShown && !ShowAlways)
return;
FrmCustomAlert( GeneralMessageAlert, str1, str2, str3 );
MessageHasBeenShown = true;
return;
}

278
Src/Prototype.h Normal file
View File

@ -0,0 +1,278 @@
/***********************************************************************
*
* SPACE TRADER 1.2.0
*
* Prototype.h
*
* Copyright (C) 2000-2002 Pieter Spronck, All Rights Reserved
*
* Additional coding by Sam Anderson (rulez2@home.com)
* Additional coding by Samuel Goldstein (palm@fogbound.net)
*
* Some code of Matt Lee's Dope Wars program has been used.
*
* 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.
*
* You can contact the author at space_trader@hotmail.com
*
* For those who are familiar with the classic game Elite: many of the
* ideas in Space Trader are heavily inspired by Elite.
*
**********************************************************************/
// Prototype.h
// All Function prototypes are defined here and can be referenced
// from any source file. Functions are referenced from multiple
// sources.
// Shipyard.c
extern void BuyRepairs( int _Amount );
extern Boolean ShipYardFormHandleEvent( EventPtr eventP );
extern long GetHullStrength( void );
// Math.c
extern int sqrt( int _a );
extern long SqrDistance( SOLARSYSTEM _a, SOLARSYSTEM _b );
extern long RealDistance( SOLARSYSTEM _a, SOLARSYSTEM _b );
extern UInt16 Rand();
extern void RandSeed( UInt16 _seed1, UInt16 _seed2 );
extern int GetRandom2(int _maxVal);
// Money.c
extern long CurrentWorth();
extern void PayInterest();
// Field.c
extern Handle SetField( FormPtr _frm, int _Nr, char* _Value, int _Size, Boolean _Focus );
extern void GetField( FormPtr _frm, int _Nr, char* _Value, Handle _AmountH );
extern void SetCheckBox( FormPtr _frm, int _Nr, Boolean _Value );
extern Boolean GetCheckBox( FormPtr _frm, int _Nr );
extern void SetTriggerList( FormPtr _frm, int _Nr, int _Index );
extern int GetTriggerList( FormPtr _frm, int _Nr);
extern void SetControlLabel( FormPtr _frm, int _Nr, Char * _Label );
// Fuel.c
extern char GetFuelTanks();
extern char GetFuel();
extern void BuyFuel( int _Amount );
// Skill.c
extern char TraderSkill( SHIP* _Sh );
extern void RecalculateBuyPrices(Byte SystemID);
extern void IncreaseRandomSkill();
extern void TonicTweakRandomSkill();
extern char FighterSkill( SHIP* _Sh );
extern char PilotSkill( SHIP* _Sh );
extern char EngineerSkill( SHIP* _Sh );
extern char AdaptDifficulty( char _Level );
extern void RecalculateSellPrices();
extern char RandomSkill();
extern Boolean HasGadget( SHIP* _Sh, char _Gg );
extern Boolean HasShield( SHIP* _Sh, char _Gg );
extern Boolean HasWeapon( SHIP* _Sh, char _Gg, Boolean _exactMatch );
extern Byte NthLowestSkill( SHIP* _Sh, Byte _n );
extern int DifficultyRange(int _low, int _high);
// Draw.c
extern void DrawShortRange( int _Index );
extern void DrawCircle( int _Xs, int _Ys, int _R );
extern void DrawGalaxy( int _Index );
extern ControlPtr RectangularButton( FormPtr _frmP, int _Nr );
extern void SBufMultiples( long _Count, char* _Txt );
extern void SBufShortMultiples( long _Count, char* _Txt );
extern void setFormTitle( int _formID, CharPtr _s );
extern void setCurrentWinTitle( CharPtr _s );
extern void setLabelText( FormPtr _frm, int _labelid, CharPtr _s );
extern void RectangularShortcuts( FormPtr _frm, int _First );
extern void EraseRectangle( int _x, int _y, int _ex, int _ey );
extern void DrawChars( char* _Text, int _x, int _y );
extern void DrawCharsCentered( char* _Text, int _y, Boolean _useBold );
extern int ScrollButton( EventPtr _eventP );
extern Boolean DisplayHeadline(char* _text, int* _y_coord);
extern void DisplayPage(char* _text, int _start_y);
// Cargo.c
// Note the following four functions must stay together
// These functions use QtyBuf which cannot be referenced externally
// in it's current form.
// ------------------------------------------------------------------
extern void DisplayTradeQuantity( int Line, int Qty, int FirstQtyButton );
extern Boolean PlunderFormHandleEvent( EventPtr eventP );
extern Boolean BuyCargoFormHandleEvent(EventPtr eventP);
extern Boolean SellCargoFormHandleEvent( EventPtr eventP );
// ------------------------------------------------------------------
extern int GetAmountToBuy( int Index ); // used in Traveler.c also
extern void PlunderCargo( int _Index, int _Amount );
extern int GetAmountToPlunder( int _Index );
extern void BuyCargo( int _Index, int _Amount, Boolean _DisplayInfo );
extern void SellCargo( int _Index, int _Amount, Byte Operation );
extern void DisplayTradeItemName( int _i, Byte Operation );
extern int TotalCargoBays();
extern int FilledCargoBays();
extern void DisplayPlunderCargoBays();
extern void BuyItem( char _Slots, int* _Item, long _Price, char* _Name, int _ItemIndex );
extern long BasePrice( char _ItemTechLevel, long _Price );
extern long BaseSellPrice( int _Index, long _Price );
extern void DrawSellEquipment();
extern void SBufBays( void );
extern void DisplayTradeCargoBays();
extern void DisplayTradeCredits();
extern void DisplayDumpCredits();
extern Boolean HasTradeableItems (SHIP *_sh, Byte _theSystem, Byte _Operation);
extern int GetRandomTradeableItem (SHIP *_sh, Byte _Operation);
// Encounter.c
extern Boolean EncounterFormHandleEvent( EventPtr _eventP );
extern long TotalWeapons( SHIP* _Sh, int _minWeapon, int _maxWeapon ); // used in Traveler also
extern void ShowShip( SHIP* _Sh, int _offset, Boolean _commandersShip );
extern void EscapeWithPod(); // used in IncDays for Reactor meltdown
// Traveler.c
extern Boolean AveragePricesFormHandleEvent( EventPtr _eventP );
extern Boolean RetireDestroyedUtopiaFormHandleEvent( EventPtr _eventP, char _EndStatus );
extern Boolean UtopiaFormHandleEvent( EventPtr _eventP );
extern Boolean RetireFormHandleEvent( EventPtr _eventP );
extern Boolean ExecuteWarpFormHandleEvent(EventPtr _eventP);
extern Boolean AnyEmptySlots( SHIP* _ship );
extern void DoWarp(Boolean _viaSingularity ); //referenced in WarpForm for the Singularity.
extern void Travel();
extern Boolean StartNewGame();
extern Boolean WormholeExists( int _a, int _b );
extern void Arrival();
extern Boolean Cloaked( SHIP* _Sh, SHIP* _Opp );
extern int GetFirstEmptySlot( char _Slots, int* _Item );
extern void IncDays( int _Amount );
extern void ViewHighScores( void );
extern long GetScore( char EndStatus, int Days, long Worth, char Level ); // Traveler.c
extern long InsuranceMoney();
extern long ToSpend();
// ShipPrice.c
extern long EnemyShipPrice( SHIP* Sh );
extern long CurrentShipPriceWithoutCargo( Boolean _ForInsurance );
extern long CurrentShipPrice( Boolean _ForInsurance );
// BuyShipEvent.c
extern void CreateFlea();
extern Boolean BuyShipFormHandleEvent( EventPtr _eventP );
// SystemInfoEvent.c
extern void DrawPersonnelRoster();
extern Boolean SystemInformationFormHandleEvent( EventPtr _eventP );
extern Boolean NewspaperFormHandleEvent( EventPtr _eventP );
extern void addNewsEvent(int _eventFlag);
extern void resetNewsEvents();
extern Boolean isNewsEvent(int _eventFlag);
extern void replaceNewsEvent(int _originalEventFlag, int _replacementEventFlag);
extern int latestNewsEvent();
// Merchant
Boolean Savegame( int State );
Boolean LoadGame( int State );
GetBitmapWidth( BitmapPtr BmpPtr );
int GetBitmapHeight( BitmapPtr BmpPtr );
// Form Event Handlers
extern void ShowMessage( char *str1, char* str2, char* str3, Boolean ShowAlways );
extern void ShowDumpCargo( void );
extern int OpenQuests( void );
extern Boolean MainFormHandleEvent( EventPtr _eventP );
extern Boolean NewCommanderFormHandleEvent( EventPtr _eventP);
extern Boolean QuestsFormHandleEvent( EventPtr _eventP );
extern Boolean GalacticChartFormHandleEvent( EventPtr _eventP );
extern Boolean WarpFormHandleEvent( EventPtr _eventP );
extern Boolean ExecuteWarpFormHandleEvent( EventPtr _eventP );
extern Boolean BuyEquipmentFormHandleEvent( EventPtr eventP );
extern Boolean SellEquipmentFormHandleEvent( EventPtr _eventP );
extern Boolean ShiptypeInfoFormHandleEvent( EventPtr _eventP );
extern Boolean PersonnelRosterFormHandleEvent( EventPtr _eventP );
extern Boolean SpecialEventFormHandleEvent( EventPtr _eventP );
extern Boolean CommanderStatusFormHandleEvent( EventPtr _eventP );
extern Boolean BankFormHandleEvent( EventPtr _eventP );
extern Boolean CurrentShipFormHandleEvent( EventPtr _eventP );
extern Boolean RetireFormHandleEvent( EventPtr _eventP );
extern Boolean UtopiaFormHandleEvent( EventPtr _eventP );
extern Boolean DestroyedFormHandleEvent( EventPtr _eventP );
extern Boolean AppHandleEvent( EventPtr _eventP);
extern Boolean SpecialEventFormHandleEvent( EventPtr _eventP );
extern Boolean SpecialCargoFormHandleEvent( EventPtr _eventP );
extern Boolean DiscardCargoFormHandleEvent( EventPtr _eventP );
// ----------------------------------------------------------
// Static Functions and their locations
// Function Name Module
// ----------------------------------------------------------
// Err AppStart(); // merchant.c
// void AppStop(); // merchant.c
// Boolean DockedFormDoCommand(Word _command); // AppHandleEvent.c
// void ShowBank( void ) // Bank.c
// long MaxLoan( void ) // Bank.c
// void GetLoan( long _Loan ); // Bank.c
// void PayBack( long _Cash ); // Bank.c
// char AvailableQuarters( void ) // SystemInfoEvent.c
// int GetForHire(); // SystemInfoEvent.c
// void DrawMercenary( int Index, int y ) // SystemInfoEvent.c
// static int GetForHire( void ) // SystemInfoEvent.c
// long TotalShields( SHIP* _Sh ); // Encounter.c
// long TotalShieldStrength( SHIP* _Sh ); // Encounter.c
// void ShowShip(SHIP* _Sh, int _offset); // Encounter.c
// Boolean ExecuteAttack( SHIP* _Attacker, SHIP* _Defender, Boolean _Flees, Boolean _CommanderUnderAttack ); // Encounter.c
// int ExecuteAction( Boolean _CommanderFlees ); // Encounter.c
// void Arrested(); // Encounter.c
// void EscapeWithPod(); // Encounter.c
// void Scoop(); // Encounter.c
// void EncounterButtons( void ) // Encounter.c
// void DetermineShipPrices(); // BuyShipEvent.c
// void BuyShip( int _Index ); // BuyShipEvent.c
// void CreateShip ( int _Index ); // BuyShipEvent.c
// void NewCommanderDrawSkills(); // NewCmdrEvent.c
// void ShowCommanderStatus(); // CmdrStatusEvent.c
// void DisplaySkill( int Skill, int AdaptedSkill, FormPtr frmP, long Label ) // CmdrStatusEvent.c
// void ShowAveragePrices(); // Traveler.c
// void ShuffleStatus(); // Traveler.c
// void DeterminePrices(Byte SystemID); // Traveler.c
// void GenerateOpponent( char _Opp ); // Traveler.c
// void ChangeQuantities(); // Traveler.c
// void InitializeTradeitems( const int _Index ); // Traveler.c
// void ShowExecuteWarp( void ); // Traveler.c
// void InitHighScores (void); // Traveler.c
// Err CreateEmptyHighscoreTable( void ); // Traveler.c
// Err OpenDatabase( void ); // Traveler.c
// void ClearHighScores( void ); // Traveler.c
// long WormholeTax( int a, int b ) // Traveler.c
// int MercenaryMoney(); // Traveler.c
// extern long StandardPrice( char _Good, char _Size, char _Tech, char _Government, int _Resources ); // Traveler.c
// int NextSystemWithinRange(int Current, Boolean Back); // Traveler.c
// void DrawShortRange( int Index ) // WarpFormEvent.c
// void DrawCircle( int Xs, int Ys, int R ) // WarpFormEvent.c
// void DrawGalaxy( int Index ) // WarpFormEvent.c
// int GetAmountToSell( int Index ) // Trader.c
// int GetAmountForFuel( void ) // Shipyard.c
// int GetAmountForRepairs( void ) // Shipyard.c
// void ShowShipYard(); // Shipyard.c
// void DrawItem( char* Name, int y, long Price ) // BuyEquipEvent.c

280
Src/QuestEvent.c Normal file
View File

@ -0,0 +1,280 @@
/***********************************************************************
*
* SPACE TRADER 1.2.0
*
* QuestEvent.c
*
* Copyright (C) 2000-2002 Pieter Spronck, All Rights Reserved
*
* Additional coding by Sam Anderson (rulez2@home.com)
* Additional coding by Samuel Goldstein (palm@fogbound.net)
*
* Some code of Matt Lee's Dope Wars program has been used.
*
* 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.
*
* You can contact the author at space_trader@hotmail.com
*
* For those who are familiar with the classic game Elite: many of the
* ideas in Space Trader are heavily inspired by Elite.
*
**********************************************************************/
// *************************************************************************
//
// Quests Screen Event Handler
//
// *************************************************************************
#include "external.h"
// Returns number of open quests.
int OpenQuests( void )
{
int r = 0;
if (MonsterStatus == 1)
++r;
if (DragonflyStatus >= 1 && DragonflyStatus <= 4)
++r;
else if (SolarSystem[ZALKONSYSTEM].Special == INSTALLLIGHTNINGSHIELD)
++r;
if (JaporiDiseaseStatus == 1)
++r;
if (ArtifactOnBoard)
++r;
if (WildStatus == 1)
++r;
if (JarekStatus == 1)
++r;
if (InvasionStatus >= 1 && InvasionStatus < 7)
++r;
else if (SolarSystem[GEMULONSYSTEM].Special == GETFUELCOMPACTOR)
++r;
if (ExperimentStatus >= 1 && ExperimentStatus < 11)
++r;
if (ReactorStatus >= 1 && ReactorStatus < 21)
++r;
if (SolarSystem[NIXSYSTEM].Special == GETSPECIALLASER)
++r;
if (ScarabStatus == 1)
++r;
if (Ship.Tribbles > 0)
++r;
if (MoonBought)
++r;
return r;
}
static void DrawQuestsForm()
{
FormPtr frmP;
int Line;
frmP = FrmGetActiveForm();
RectangularShortcuts( frmP, QuestsBButton );
FrmDrawForm( frmP );
FntSetFont( stdFont );
Line = 18;
if (MonsterStatus == 1)
{
DrawChars( "Kill the space monster at Acamar.", 0, Line );
Line += 16;
}
if (DragonflyStatus >= 1 && DragonflyStatus <= 4)
{
StrCopy( SBuf, "Follow the Dragonfly to " );
if (DragonflyStatus == 1)
StrCat( SBuf, "Baratas." );
else if (DragonflyStatus == 2)
StrCat( SBuf, "Melina." );
else if (DragonflyStatus == 3)
StrCat( SBuf, "Regulas." );
else if (DragonflyStatus == 4)
StrCat( SBuf, "Zalkon." );
DrawChars( SBuf, 0, Line );
Line += 16;
}
else if (SolarSystem[ZALKONSYSTEM].Special == INSTALLLIGHTNINGSHIELD)
{
DrawChars( "Get your lightning shield at Zalkon.", 0, Line );
Line += 16;
}
if (JaporiDiseaseStatus == 1)
{
DrawChars( "Deliver antidote to Japori.", 0, Line );
Line += 16;
}
if (ArtifactOnBoard)
{
DrawChars( "Deliver the alien artifact to professor", 0, Line );
Line += 12;
DrawChars( "Berger at some hi-tech system.", 0, Line );
Line += 16;
}
if (WildStatus == 1)
{
DrawChars( "Smuggle Jonathan Wild to Kravat.", 0, Line );
Line += 16;
}
if (JarekStatus == 1)
{
DrawChars( "Bring ambassador Jarek to Devidia.", 0, Line );
Line += 16;
}
// I changed this, and the reused the code in the Experiment quest.
// I think it makes more sense to display the time remaining in
// this fashion. SjG 10 July 2002
if (InvasionStatus >= 1 && InvasionStatus < 7)
{
DrawChars( "Inform Gemulon about alien invasion", 0, Line );
Line += 12;
if (InvasionStatus == 6)
StrCopy( SBuf, "by tomorrow" );
else
{
StrCopy( SBuf, "within " );
SBufMultiples( 7 - InvasionStatus, "day" );
}
StrCat( SBuf, "." );
DrawChars( SBuf, 0, Line );
Line += 16;
}
else if (SolarSystem[GEMULONSYSTEM].Special == GETFUELCOMPACTOR)
{
DrawChars( "Get your fuel compactor at Gemulon.", 0, Line );
Line += 16;
}
if (ExperimentStatus >= 1 && ExperimentStatus < 11)
{
DrawChars( "Stop Dr. Fehler's experiment at Daled", 0, Line );
Line += 12;
if (ExperimentStatus == 10)
StrCopy( SBuf, "by tomorrow" );
else
{
StrCopy( SBuf, "within " );
SBufMultiples( 11 - ExperimentStatus, "day" );
}
StrCat( SBuf, "." );
DrawChars( SBuf, 0, Line );
Line += 16;
}
if (ReactorStatus >= 1 && ReactorStatus < 21)
{
DrawChars( "Deliver the unstable reactor to Nix", 0, Line );
Line += 12;
if (ReactorStatus < 2)
{
DrawChars( "for Henry Morgan.", 0, Line );
}
else
{
DrawChars( "before it consumes all its fuel.", 0, Line );
}
Line += 16;
}
if (SolarSystem[NIXSYSTEM].Special == GETSPECIALLASER)
{
DrawChars( "Get your special laser at Nix.", 0, Line );
Line += 16;
}
if (ScarabStatus == 1)
{
DrawChars( "Find and destroy the Scarab (which", 0, Line );
Line += 12;
DrawChars( "is hiding at the exit to a wormhole).", 0, Line );
Line += 16;
}
if (Ship.Tribbles > 0)
{
DrawChars( "Get rid of those pesky tribbles.", 0, Line );
Line += 16;
}
if (MoonBought)
{
DrawChars( "Claim your moon at Utopia.", 0, Line );
Line += 16;
}
if (Line <= 18)
DrawChars( "There are no open quests.", 0, Line );
}
Boolean QuestsFormHandleEvent( EventPtr eventP )
{
Boolean handled = false;
switch (eventP->eType)
{
case frmOpenEvent:
case frmUpdateEvent:
DrawQuestsForm();
handled = true;
break;
case ctlSelectEvent:
if (eventP->data.ctlSelect.controlID == QuestsStatusButton)
{
CurForm = CommanderStatusForm;
}
else if (eventP->data.ctlSelect.controlID == QuestsShipButton)
{
CurForm = CurrentShipForm;
}
else if (eventP->data.ctlSelect.controlID == QuestsSpecialButton)
{
CurForm = SpecialCargoForm;
}
FrmGotoForm( CurForm );
handled = true;
break;
default:
break;
}
return handled;
}

124
Src/SellEquipEvent.c Normal file
View File

@ -0,0 +1,124 @@
/***********************************************************************
*
* SPACE TRADER 1.2.0
*
* SellEquipEvent.c
*
* Copyright (C) 2000-2002 Pieter Spronck, All Rights Reserved
*
* Additional coding by Sam Anderson (rulez2@home.com)
* Additional coding by Samuel Goldstein (palm@fogbound.net)
*
* Some code of Matt Lee's Dope Wars program has been used.
*
* 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.
*
* You can contact the author at space_trader@hotmail.com
*
* For those who are familiar with the classic game Elite: many of the
* ideas in Space Trader are heavily inspired by Elite.
*
**********************************************************************/
// *************************************************************************
// Handling of the events of the Sell Equipment form.
// *************************************************************************
#include "external.h"
Boolean SellEquipmentFormHandleEvent( EventPtr eventP )
{
Boolean handled = false;
Boolean Sale;
FormPtr frmP;
int i;
switch (eventP->eType)
{
case frmOpenEvent:
DrawSellEquipment();
handled = true;
break;
case frmUpdateEvent:
DrawSellEquipment();
handled = true;
break;
case ctlSelectEvent:
if (FrmAlert( SellItemAlert ) != SellItemYes)
{
handled = true;
break;
}
frmP = FrmGetActiveForm();
Sale = true;
if (eventP->data.ctlSelect.controlID >= SellEquipmentSell0Button &&
eventP->data.ctlSelect.controlID < SellEquipmentSell0Button+MAXWEAPON)
{
Credits += WEAPONSELLPRICE( eventP->data.ctlSelect.controlID - SellEquipmentSell0Button );
for (i=eventP->data.ctlSelect.controlID - SellEquipmentSell0Button + 1; i<MAXWEAPON; ++i)
Ship.Weapon[i-1] = Ship.Weapon[i];
Ship.Weapon[MAXWEAPON-1] = -1;
}
if (eventP->data.ctlSelect.controlID >= SellEquipmentSell0Button+MAXWEAPON &&
eventP->data.ctlSelect.controlID < SellEquipmentSell0Button+MAXWEAPON+MAXSHIELD)
{
Credits += SHIELDSELLPRICE( eventP->data.ctlSelect.controlID - SellEquipmentSell0Button - MAXWEAPON );
for (i=eventP->data.ctlSelect.controlID - SellEquipmentSell0Button - MAXWEAPON + 1; i<MAXSHIELD; ++i)
{
Ship.Shield[i-1] = Ship.Shield[i];
Ship.ShieldStrength[i-1] = Ship.ShieldStrength[i];
}
Ship.Shield[MAXSHIELD-1] = -1;
Ship.ShieldStrength[MAXSHIELD-1] = 0;
}
if (eventP->data.ctlSelect.controlID >= SellEquipmentSell0Button+MAXWEAPON+MAXSHIELD &&
eventP->data.ctlSelect.controlID < SellEquipmentSell0Button+MAXWEAPON+MAXSHIELD+MAXGADGET)
{
if (Ship.Gadget[eventP->data.ctlSelect.controlID - SellEquipmentSell0Button - MAXWEAPON - MAXSHIELD] == EXTRABAYS)
{
if (FilledCargoBays() > TotalCargoBays() - 5)
{
FrmAlert( CargoBaysFullAlert );
Sale = false;
}
}
if (Sale)
{
Credits += GADGETSELLPRICE( eventP->data.ctlSelect.controlID - SellEquipmentSell0Button - MAXWEAPON - MAXSHIELD );
for (i=eventP->data.ctlSelect.controlID - SellEquipmentSell0Button - MAXWEAPON - MAXSHIELD + 1; i<MAXGADGET; ++i)
Ship.Gadget[i-1] = Ship.Gadget[i];
Ship.Gadget[MAXGADGET-1] = -1;
}
}
if (Sale)
DrawSellEquipment();
handled = true;
break;
default:
break;
}
return handled;
}

26
Src/SetField.c Normal file
View File

@ -0,0 +1,26 @@
// *************************************************************************
// SetField.c
//
// Modifications:
// mm/dd/yy - description - author
// *************************************************************************
#include "external.h"
Handle SetField( FormPtr frm, int Nr, char* Value, int Size, Boolean Focus )
{
Word objIndex;
CharPtr AmountP;
Handle AmountH;
objIndex = FrmGetObjectIndex( frm, Nr );
AmountH = MemHandleNew( Size );
AmountP = MemHandleLock( AmountH );
StrCopy( AmountP, Value );
MemPtrUnlock( AmountP );
FldSetTextHandle( FrmGetObjectPtr( frm, objIndex ), AmountH );
if (Focus)
FrmSetFocus( frm, objIndex );
return AmountH;
}

208
Src/ShipEvent.c Normal file
View File

@ -0,0 +1,208 @@
/***********************************************************************
*
* SPACE TRADER 1.2.0
*
* ShipEvent.c
*
* Copyright (C) 2000-2002 Pieter Spronck, All Rights Reserved
*
* Additional coding by Sam Anderson (rulez2@home.com)
* Additional coding by Samuel Goldstein (palm@fogbound.net)
*
* Some code of Matt Lee's Dope Wars program has been used.
*
* 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.
*
* You can contact the author at space_trader@hotmail.com
*
* For those who are familiar with the classic game Elite: many of the
* ideas in Space Trader are heavily inspired by Elite.
*
**********************************************************************/
#include "external.h"
static void DrawCurrentShipForm()
{
FormPtr frmP = FrmGetActiveForm();
int i, j, k, Line, FirstEmptySlot;
RectangularShortcuts( frmP, CurrentShipBButton );
FrmDrawForm( frmP );
FntSetFont( boldFont );
DrawChars( "Type:", 0, 18 );
DrawChars( "Equipment:", 0, 32 );
FntSetFont( stdFont );
if (ScarabStatus == 3)
{
StrCopy( SBuf, Shiptype[Ship.Type].Name);
StrCat ( SBuf, "/hardened hull");
DrawChars( SBuf, 60, 18 );
}
else
DrawChars( Shiptype[Ship.Type].Name, 60, 18 );
Line = 32;
for (i=0; i<MAXWEAPONTYPE+EXTRAWEAPONS; ++i)
{
j = 0;
for (k=0; k<MAXWEAPON; ++k)
{
if (Ship.Weapon[k] == i)
++j;
}
if (j > 0)
{
SBuf[0] = '\0';
SBufMultiples( j, Weapontype[i].Name );
StrToLower( SBuf2, SBuf );
DrawChars( SBuf2, 60, Line );
Line += 14;
}
}
for (i=0; i<MAXSHIELDTYPE+EXTRASHIELDS; ++i)
{
j = 0;
for (k=0; k<MAXSHIELD; ++k)
{
if (Ship.Shield[k] == i)
++j;
}
if (j > 0)
{
SBuf[0] = '\0';
SBufMultiples( j, Shieldtype[i].Name );
StrToLower( SBuf2, SBuf );
DrawChars( SBuf2, 60, Line );
Line += 14;
}
}
for (i=0; i<MAXGADGETTYPE+EXTRAGADGETS; ++i)
{
j = 0;
for (k=0; k<MAXGADGET; ++k)
{
if (Ship.Gadget[k] == i)
++j;
}
if (j > 0)
{
if (i == EXTRABAYS)
{
j = j*5;
StrIToA( SBuf, j );
StrCat( SBuf, " extra cargo bays" );
}
else
{
StrCopy(SBuf, Gadgettype[i].Name );
}
StrToLower( SBuf2, SBuf );
DrawChars( SBuf2, 60, Line );
Line += 14;
}
}
if (EscapePod)
{
DrawChars( "an escape pod", 60, Line );
Line += 14;
}
if (AnyEmptySlots(&Ship))
{
FntSetFont( boldFont );
DrawChars( "Unfilled: ", 0, Line );
FntSetFont( stdFont );
FirstEmptySlot = GetFirstEmptySlot( Shiptype[Ship.Type].WeaponSlots, Ship.Weapon );
if (FirstEmptySlot >= 0)
{
SBuf[0] = '\0';
SBufMultiples( Shiptype[Ship.Type].WeaponSlots - FirstEmptySlot, "weapon slot" );
DrawChars( SBuf, 60, Line );
Line += 14;
}
FirstEmptySlot = GetFirstEmptySlot( Shiptype[Ship.Type].ShieldSlots, Ship.Shield );
if (FirstEmptySlot >= 0)
{
SBuf[0] = '\0';
SBufMultiples( Shiptype[Ship.Type].ShieldSlots - FirstEmptySlot, "shield slot" );
DrawChars( SBuf, 60, Line );
Line += 14;
}
FirstEmptySlot = GetFirstEmptySlot( Shiptype[Ship.Type].GadgetSlots, Ship.Gadget );
if (FirstEmptySlot >= 0)
{
SBuf[0] = '\0';
SBufMultiples( Shiptype[Ship.Type].GadgetSlots - FirstEmptySlot, "gadget slot" );
DrawChars( SBuf, 60, Line );
Line += 14;
}
}
}
// *************************************************************************
// Event handler for the Current Ship screen
// ********************************************************************
Boolean CurrentShipFormHandleEvent( EventPtr eventP )
{
Boolean handled = false;
switch (eventP->eType)
{
case frmOpenEvent:
case frmUpdateEvent:
DrawCurrentShipForm();
handled = true;
break;
case ctlSelectEvent:
if (eventP->data.ctlSelect.controlID == CurrentShipStatusButton)
{
CurForm = CommanderStatusForm;
}
else if (eventP->data.ctlSelect.controlID == CurrentShipQuestsButton)
{
CurForm = QuestsForm;
}
else if (eventP->data.ctlSelect.controlID == CurrentShipSpecialButton)
{
CurForm = SpecialCargoForm;
}
FrmGotoForm( CurForm );
handled = true;
break;
default:
break;
}
return handled;
}

112
Src/ShipPrice.c Normal file
View File

@ -0,0 +1,112 @@
/***********************************************************************
*
* SPACE TRADER 1.2.0
*
* Shipprice.c
*
* Copyright (C) 2000-2002 Pieter Spronck, All Rights Reserved
*
* Additional coding by Sam Anderson (rulez2@home.com)
* Additional coding by Samuel Goldstein (palm@fogbound.net)
*
* Some code of Matt Lee's Dope Wars program has been used.
*
* 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.
*
* You can contact the author at space_trader@hotmail.com
*
* For those who are familiar with the classic game Elite: many of the
* ideas in Space Trader are heavily inspired by Elite.
*
**********************************************************************/
// *************************************************************************
// ShipPrice.c - Functions include:
// long CurrentShipPriceWithoutCargo( Boolean ForInsurance )
// long CurrentShipPrice( Boolean ForInsurance )
//
// Modifications:
// mm/dd/yy - description - author
// *************************************************************************
#include "external.h"
// *************************************************************************
// Determine value of ship
// *************************************************************************
long EnemyShipPrice( SHIP* Sh )
{
int i;
long CurPrice;
CurPrice = Shiptype[Sh->Type].Price;
for (i=0; i<MAXWEAPON; ++i)
if (Sh->Weapon[i] >= 0)
CurPrice += Weapontype[Sh->Weapon[i]].Price;
for (i=0; i<MAXSHIELD; ++i)
if (Sh->Shield[i] >= 0)
CurPrice += Shieldtype[Sh->Shield[i]].Price;
// Gadgets aren't counted in the price, because they are already taken into account in
// the skill adjustment of the price.
CurPrice = CurPrice * (2 * PilotSkill( Sh ) + EngineerSkill( Sh ) + 3 * FighterSkill( Sh )) / 60;
return CurPrice;
}
// *************************************************************************
// Determine value of current ship, including equipment.
// *************************************************************************
long CurrentShipPriceWithoutCargo( Boolean ForInsurance )
{
int i;
long CurPrice;
CurPrice =
// Trade-in value is three-fourths the original price
((Shiptype[Ship.Type].Price * (Ship.Tribbles > 0 && !ForInsurance? 1 : 3)) / 4)
// subtract repair costs
- (GetHullStrength() - Ship.Hull) * Shiptype[Ship.Type].RepairCosts
// subtract costs to fill tank with fuel
- (Shiptype[Ship.Type].FuelTanks - GetFuel()) * Shiptype[Ship.Type].CostOfFuel;
// Add 2/3 of the price of each item of equipment
for (i=0; i<MAXWEAPON; ++i)
if (Ship.Weapon[i] >= 0)
CurPrice += WEAPONSELLPRICE( i );
for (i=0; i<MAXSHIELD; ++i)
if (Ship.Shield[i] >= 0)
CurPrice += SHIELDSELLPRICE( i );
for (i=0; i<MAXGADGET; ++i)
if (Ship.Gadget[i] >= 0)
CurPrice += GADGETSELLPRICE( i );
return CurPrice;
}
// *************************************************************************
// Determine value of current ship, including goods and equipment.
// *************************************************************************
long CurrentShipPrice( Boolean ForInsurance )
{
int i;
long CurPrice;
CurPrice = CurrentShipPriceWithoutCargo( ForInsurance );
for (i=0; i<MAXTRADEITEM; ++i)
CurPrice += BuyingPrice[i];
return CurPrice;
}

94
Src/ShiptypeInfoEvent.c Normal file
View File

@ -0,0 +1,94 @@
/***********************************************************************
*
* SPACE TRADER 1.2.0
*
* ShiptypeInfoEvent.c
*
* Copyright (C) 2000-2002 Pieter Spronck, All Rights Reserved
*
* Additional coding by Sam Anderson (rulez2@home.com)
* Additional coding by Samuel Goldstein (palm@fogbound.net)
*
* Some code of Matt Lee's Dope Wars program has been used.
*
* 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.
*
* You can contact the author at space_trader@hotmail.com
*
* For those who are familiar with the classic game Elite: many of the
* ideas in Space Trader are heavily inspired by Elite.
*
**********************************************************************/
// *************************************************************************
// Handling of the events of the Shiptype Information form.
// *************************************************************************
#include "external.h"
static void DrawShiptypeInfoForm()
{
FormPtr frmP;
frmP = FrmGetActiveForm();
setLabelText( frmP, ShiptypeInfoShipNameLabel,
Shiptype[SelectedShipType].Name );
setLabelText( frmP, ShiptypeInfoSizeLabel,
SystemSize[Shiptype[SelectedShipType].Size] );
setLabelText( frmP, ShiptypeInfoCargoBaysLabel,
StrIToA( SBuf, Shiptype[SelectedShipType].CargoBays ) );
setLabelText( frmP, ShiptypeInfoWeaponSlotsLabel,
StrIToA( SBuf, Shiptype[SelectedShipType].WeaponSlots ) );
setLabelText( frmP, ShiptypeInfoShieldSlotsLabel,
StrIToA( SBuf, Shiptype[SelectedShipType].ShieldSlots ) );
setLabelText( frmP, ShiptypeInfoGadgetSlotsLabel,
StrIToA( SBuf, Shiptype[SelectedShipType].GadgetSlots ) );
setLabelText( frmP, ShiptypeInfoCrewQuartersLabel,
StrIToA( SBuf, Shiptype[SelectedShipType].CrewQuarters ) );
StrIToA( SBuf, Shiptype[SelectedShipType].FuelTanks );
StrCat( SBuf, " parsecs" );
setLabelText( frmP, ShiptypeInfoMaximumRangeLabel, SBuf );
setLabelText( frmP, ShiptypeInfoHullStrengthLabel,
StrIToA( SBuf, Shiptype[SelectedShipType].HullStrength ) );
FrmDrawForm( frmP );
WinDrawBitmap( ShipBmpPtr[SelectedShipType],
94+((60-GetBitmapWidth( ShipBmpPtr[SelectedShipType] ))>>1),
83+((48-GetBitmapHeight( ShipBmpPtr[SelectedShipType] ))>>1) );
}
Boolean ShiptypeInfoFormHandleEvent( EventPtr eventP )
{
Boolean handled = false;
switch (eventP->eType)
{
case frmOpenEvent:
case frmUpdateEvent:
DrawShiptypeInfoForm();
handled = true;
break;
case ctlSelectEvent:
CurForm = BuyShipForm;
FrmGotoForm( CurForm );
handled = true;
break;
default:
break;
}
return handled;
}

330
Src/Shipyard.c Normal file
View File

@ -0,0 +1,330 @@
/***********************************************************************
*
* SPACE TRADER 1.2.0
*
* Shipyard.c
*
* Copyright (C) 2000-2002 Pieter Spronck, All Rights Reserved
*
* Additional coding by Sam Anderson (rulez2@home.com)
* Additional coding by Samuel Goldstein (palm@fogbound.net)
*
* Some code of Matt Lee's Dope Wars program has been used.
*
* 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.
*
* You can contact the author at space_trader@hotmail.com
*
* For those who are familiar with the classic game Elite: many of the
* ideas in Space Trader are heavily inspired by Elite.
*
**********************************************************************/
// *************************************************************************
// Shipyard.c - Shipyard Module.
//
// Boolean ShipYardFormHandleEvent( EventPtr eventP )
// void BuyRepairs( int Amount )
//
// Static Local Functions
// -------------------------------
// int GetAmountForRepairs( void )
// int GetAmountForFuel( void )
// void ShowShipYard( void )
//
// *************************************************************************
#include "external.h"
// *************************************************************************
// Let the commander indicate how much he wants to spend on repairs
// *************************************************************************
static int GetAmountForRepairs( void )
{
FormPtr frm;
int d, Amount;
Handle AmountH;
frm = FrmInitForm( BuyRepairsForm );
AmountH = (Handle) SetField( frm, BuyRepairsForRepairsField, "", 5, true );
d = FrmDoDialog( frm );
GetField( frm, BuyRepairsForRepairsField, SBuf, AmountH );
if (SBuf[0] == '\0')
Amount = 0;
else
Amount = StrAToI( SBuf );
FrmDeleteForm( frm );
if (d == BuyFuelAllButton)
return( 9999 );
else if (d == BuyFuelNoneButton)
return( 0 );
return( Amount );
}
// *************************************************************************
// Let the commander indicate how much he wants to spend on fuel
// *************************************************************************
static int GetAmountForFuel( void )
{
FormPtr frm;
int d, Amount;
Handle AmountH;
frm = FrmInitForm( BuyFuelForm );
AmountH = (Handle) SetField( frm, BuyFuelForFuelField, "", 4, true );
d = FrmDoDialog( frm );
GetField( frm, BuyFuelForFuelField, SBuf, AmountH );
if (SBuf[0] == '\0')
Amount = 0;
else
Amount = StrAToI( SBuf );
FrmDeleteForm( frm );
if (d == BuyFuelAllButton)
return( 999 );
else if (d == BuyFuelNoneButton)
return( 0 );
return( Amount );
}
// *************************************************************************
// Determine ship's hull strength
// *************************************************************************
long GetHullStrength(void)
{
if (ScarabStatus == 3)
return Shiptype[Ship.Type].HullStrength + UPGRADEDHULL;
else
return Shiptype[Ship.Type].HullStrength;
}
// *************************************************************************
// Display the Ship Yard form.
// Modified by SRA 04/19/01 - DisplayTradeCredits if Enabled
// *************************************************************************
static void ShowShipYard( void )
{
FormPtr frmP;
frmP = FrmGetActiveForm();
RectangularShortcuts( frmP, ShipYardBButton );
if (GetFuel() < GetFuelTanks())
{
FrmShowObject( frmP, FrmGetObjectIndex( frmP, ShipYardBuyFuelButton ) );
FrmShowObject( frmP, FrmGetObjectIndex( frmP, ShipYardFullTankButton ) );
}
else
{
FrmHideObject( frmP, FrmGetObjectIndex( frmP, ShipYardBuyFuelButton ) );
FrmHideObject( frmP, FrmGetObjectIndex( frmP, ShipYardFullTankButton ) );
}
if (Ship.Hull < GetHullStrength())
{
FrmShowObject( frmP, FrmGetObjectIndex( frmP, ShipYardRepairButton ) );
FrmShowObject( frmP, FrmGetObjectIndex( frmP, ShipYardFullRepairsButton ) );
}
else
{
FrmHideObject( frmP, FrmGetObjectIndex( frmP, ShipYardRepairButton ) );
FrmHideObject( frmP, FrmGetObjectIndex( frmP, ShipYardFullRepairsButton ) );
}
if (CURSYSTEM.TechLevel >= Shiptype[0].MinTechLevel)
{
FrmHideObject( frmP, FrmGetObjectIndex( frmP, ShipYardShipInformationButton ) );
FrmShowObject( frmP, FrmGetObjectIndex( frmP, ShipYardBuyNewShipButton ) );
}
else
{
FrmHideObject( frmP, FrmGetObjectIndex( frmP, ShipYardBuyNewShipButton ) );
FrmShowObject( frmP, FrmGetObjectIndex( frmP, ShipYardShipInformationButton ) );
}
if (EscapePod || ToSpend() < 2000 || CURSYSTEM.TechLevel < Shiptype[0].MinTechLevel)
FrmHideObject( frmP, FrmGetObjectIndex( frmP, ShipYardEscapePodButton ) );
else
FrmShowObject( frmP, FrmGetObjectIndex( frmP, ShipYardEscapePodButton ) );
FrmDrawForm( frmP );
FntSetFont( stdFont );
EraseRectangle( 0, 18, 160, 25 );
StrCopy( SBuf, "You have fuel to fly " );
SBufMultiples( GetFuel(), "parsec" );
StrCat( SBuf, "." );
DrawChars( SBuf, 0, 18 );
if (GetFuel() < GetFuelTanks())
{
StrCopy( SBuf, "A full tank costs " );
StrIToA( SBuf2, (GetFuelTanks() - GetFuel()) * Shiptype[Ship.Type].CostOfFuel );
StrCat( SBuf, SBuf2 );
StrCat( SBuf, " cr." );
DrawChars( SBuf, 0, 30 );
}
else
DrawChars( "Your tank cannot hold more fuel.", 0, 30 );
EraseRectangle( 0, 60, 160, 25 );
StrCopy( SBuf, "Your hull strength is at " );
StrIToA( SBuf2, (Ship.Hull * 100) / GetHullStrength() );
StrCat( SBuf, SBuf2 );
StrCat( SBuf, "%." );
DrawChars( SBuf, 0, 60 );
if (Ship.Hull < GetHullStrength())
{
StrCopy( SBuf, "Full repair will cost " );
StrIToA( SBuf2, (GetHullStrength() - Ship.Hull) *
Shiptype[Ship.Type].RepairCosts );
StrCat( SBuf, SBuf2 );
StrCat( SBuf, " cr." );
DrawChars( SBuf, 0, 72 );
}
else
DrawChars( "No repairs are needed.", 0, 72 );
EraseRectangle( 0, 102, 160, 12 );
if (CURSYSTEM.TechLevel >= Shiptype[0].MinTechLevel)
DrawChars( "There are new ships for sale.", 0, 102 );
else
DrawChars( "No new ships are for sale.", 0, 102 );
#ifdef _STRA_SHIPYARDCREDITS_
DisplayTradeCredits(); // SRA 04/19/01
#endif
EraseRectangle( 0, 132, 160, 12 );
if (EscapePod)
DrawChars( "You have an escape pod installed.", 0, 132 );
else if (CURSYSTEM.TechLevel < Shiptype[0].MinTechLevel)
DrawChars( "No escape pods are for sale.", 0, 132 );
else if (ToSpend() < 2000)
DrawChars( "You need 2000 cr. for an escape pod.", 0, 132 );
else
DrawChars( "You can buy an escape pod for 2000 cr.", 0, 132 );
}
// *************************************************************************
// Repair Ship for Amount credits
// *************************************************************************
void BuyRepairs( int Amount )
{
int MaxRepairs;
int Percentage;
MaxRepairs = (GetHullStrength() - Ship.Hull) *
Shiptype[Ship.Type].RepairCosts;
if (Amount > MaxRepairs)
Amount = MaxRepairs;
if (Amount > Credits)
Amount = Credits;
Percentage = Amount / Shiptype[Ship.Type].RepairCosts;
Ship.Hull += Percentage;
Credits -= Percentage * Shiptype[Ship.Type].RepairCosts;
}
// *************************************************************************
// Ship Yard Form Event Handler.
// *************************************************************************
Boolean ShipYardFormHandleEvent( EventPtr eventP )
{
Boolean handled = false;
int Amount;
switch (eventP->eType)
{
case frmOpenEvent:
ShowShipYard();
handled = true;
break;
case ctlSelectEvent:
switch (eventP->data.ctlSelect.controlID)
{
case ShipYardBuyFuelButton:
Amount = GetAmountForFuel();
if (Amount > 0)
BuyFuel( Amount );
ShowShipYard();
break;
case ShipYardFullTankButton:
BuyFuel( 999 );
ShowShipYard();
break;
case ShipYardRepairButton:
Amount = GetAmountForRepairs();
if (Amount > 0)
BuyRepairs( Amount );
ShowShipYard();
break;
case ShipYardFullRepairsButton:
BuyRepairs( 9999 );
ShowShipYard();
break;
case ShipYardBuyNewShipButton:
CurForm = BuyShipForm;
FrmGotoForm( CurForm );
break;
case ShipYardShipInformationButton:
CurForm = BuyShipForm;
FrmGotoForm( CurForm );
break;
case ShipYardEscapePodButton:
if (FrmAlert( BuyEscapePodAlert ) == BuyEscapePodYes)
{
Credits -= 2000;
EscapePod = true;
ShowShipYard();
}
break;
}
handled = true;
break;
default:
break;
}
return handled;
}

437
Src/Skill.c Normal file
View File

@ -0,0 +1,437 @@
/***********************************************************************
*
* SPACE TRADER 1.2.0
*
* Skill.c
*
* Copyright (C) 2000-2002 Pieter Spronck, All Rights Reserved
*
* Additional coding by Sam Anderson (rulez2@home.com)
* Additional coding by Samuel Goldstein (palm@fogbound.net)
*
* Some code of Matt Lee's Dope Wars program has been used.
*
* 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.
*
* You can contact the author at space_trader@hotmail.com
*
* For those who are familiar with the classic game Elite: many of the
* ideas in Space Trader are heavily inspired by Elite.
*
**********************************************************************/
// *************************************************************************
// Skill.c - Functions in this module:
//
// char TraderSkill( SHIP* _Sh );
// void RecalculateBuyPrices(Byte SystemID);
// void IncreaseRandomSkill();
// char FighterSkill( SHIP* _Sh );
// char PilotSkill( SHIP* _Sh );
// char EngineerSkill( SHIP* _Sh );
// char AdaptDifficulty( char _Level );
// void RecalculateSellPrices();
// char RandomSkill( void )
// Boolean HasGadget( SHIP* Sh, char Gg )
// Byte NthLowestSkill( SHIP* Sh, Byte n )
//
// Modifications:
// mm/dd/yy - description - author
// *************************************************************************
#include "external.h"
// *************************************************************************
// NthLowest Skill. Returns skill with the nth lowest score
// (i.e., 2 is the second worst skill). If there is a tie, it will return
// in the order of Pilot, Fighter, Trader, Engineer.
// *************************************************************************
Byte NthLowestSkill( SHIP* Sh, Byte n )
{
Byte i = 0, lower = 1, retVal;
Boolean looping = true;
while (looping)
{
retVal = 0;
if (Mercenary[Sh->Crew[0]].Pilot == i)
{
if (lower == n)
{
looping = false;
retVal = PILOTSKILL;
}
lower++;
}
if (Mercenary[Sh->Crew[0]].Fighter == i)
{
if (lower == n)
{
looping = false;
retVal = FIGHTERSKILL;
}
lower++;
}
if (Mercenary[Sh->Crew[0]].Trader == i)
{
if (lower == n)
{
looping = false;
retVal = TRADERSKILL;
}
lower++;
}
if (Mercenary[Sh->Crew[0]].Engineer == i)
{
if (lower == n)
{
looping = false;
retVal = ENGINEERSKILL;
}
lower++;
}
i++;
}
return retVal;
}
// *************************************************************************
// Trader skill
// *************************************************************************
char TraderSkill( SHIP* Sh )
{
int i;
char MaxSkill;
MaxSkill = Mercenary[Sh->Crew[0]].Trader;
for (i=1; i<MAXCREW; ++i)
{
if (Sh->Crew[i] < 0)
break;
if (Mercenary[Sh->Crew[i]].Trader > MaxSkill)
MaxSkill = Mercenary[Sh->Crew[i]].Trader;
}
if (JarekStatus >= 2)
++MaxSkill;
return AdaptDifficulty( MaxSkill );
}
// *************************************************************************
// After changing the trader skill, buying prices must be recalculated.
// Revised to be callable on an arbitrary Solar System
// *************************************************************************
void RecalculateBuyPrices( Byte SystemID )
{
int i;
for (i=0; i<MAXTRADEITEM; ++i)
{
if (SolarSystem[SystemID].TechLevel < Tradeitem[i].TechProduction)
BuyPrice[i] = 0;
else if (((i == NARCOTICS) && (!Politics[SolarSystem[SystemID].Politics].DrugsOK)) ||
((i == FIREARMS) && (!Politics[SolarSystem[SystemID].Politics].FirearmsOK)))
BuyPrice[i] = 0;
else
{
if (PoliceRecordScore < DUBIOUSSCORE)
BuyPrice[i] = (SellPrice[i] * 100) / 90;
else
BuyPrice[i] = SellPrice[i];
// BuyPrice = SellPrice + 1 to 12% (depending on trader skill (minimum is 1, max 12))
BuyPrice[i] = (BuyPrice[i] * (103 + (MAXSKILL - TraderSkill( &Ship ))) / 100);
if (BuyPrice[i] <= SellPrice[i])
BuyPrice[i] = SellPrice[i] + 1;
}
}
}
// *************************************************************************
// Increase one of the skills of the commander
// *************************************************************************
void IncreaseRandomSkill( void )
{
Boolean Redo;
int d, oldtraderskill;
if (COMMANDER.Pilot >= MAXSKILL && COMMANDER.Trader >= MAXSKILL &&
COMMANDER.Fighter >= MAXSKILL && COMMANDER.Engineer >= MAXSKILL)
return;
oldtraderskill = TraderSkill( &Ship );
Redo = true;
while (Redo)
{
d = (GetRandom( MAXSKILLTYPE ));
if ((d == 0 && COMMANDER.Pilot < MAXSKILL) ||
(d == 1 && COMMANDER.Fighter < MAXSKILL) ||
(d == 2 && COMMANDER.Trader < MAXSKILL) ||
(d == 3 && COMMANDER.Engineer < MAXSKILL))
Redo = false;
}
if (d == 0)
COMMANDER.Pilot += 1;
else if (d == 1)
COMMANDER.Fighter += 1;
else if (d == 2)
{
COMMANDER.Trader += 1;
if (oldtraderskill != TraderSkill( &Ship ))
RecalculateBuyPrices(COMMANDER.CurSystem);
}
else
COMMANDER.Engineer += 1;
}
// *************************************************************************
// Decrease one of the skills of the commander
// *************************************************************************
void DecreaseRandomSkill( int amount )
{
Boolean Redo;
int d, oldtraderskill;
if (COMMANDER.Pilot >= MAXSKILL && COMMANDER.Trader >= MAXSKILL &&
COMMANDER.Fighter >= MAXSKILL && COMMANDER.Engineer >= MAXSKILL)
return;
oldtraderskill = TraderSkill( &Ship );
Redo = true;
while (Redo)
{
d = (GetRandom( MAXSKILLTYPE ));
if ((d == 0 && COMMANDER.Pilot > amount) ||
(d == 1 && COMMANDER.Fighter > amount) ||
(d == 2 && COMMANDER.Trader > amount) ||
(d == 3 && COMMANDER.Engineer > amount))
Redo = false;
}
if (d == 0)
COMMANDER.Pilot -= amount;
else if (d == 1)
COMMANDER.Fighter -= amount;
else if (d == 2)
{
COMMANDER.Trader -= amount;
if (oldtraderskill != TraderSkill( &Ship ))
RecalculateBuyPrices(COMMANDER.CurSystem);
}
else
COMMANDER.Engineer -= amount;
}
// *************************************************************************
// Randomly tweak one of the skills of the commander
// *************************************************************************
void TonicTweakRandomSkill( void )
{
int oldPilot, oldFighter, oldTrader, oldEngineer;
oldPilot = COMMANDER.Pilot;
oldFighter = COMMANDER.Fighter;
oldTrader = COMMANDER.Trader;
oldEngineer = COMMANDER.Engineer;
if (Difficulty < HARD)
{
// add one to a random skill, subtract one from a random skill
while ( oldPilot == COMMANDER.Pilot &&
oldFighter == COMMANDER.Fighter &&
oldTrader == COMMANDER.Trader &&
oldEngineer == COMMANDER.Engineer)
{
IncreaseRandomSkill();
DecreaseRandomSkill(1);
}
}
else
{
// add one to two random skills, subtract three from one random skill
IncreaseRandomSkill();
IncreaseRandomSkill();
DecreaseRandomSkill(3);
}
}
// *************************************************************************
// Fighter skill
// *************************************************************************
char FighterSkill( SHIP* Sh )
{
int i;
char MaxSkill;
MaxSkill = Mercenary[Sh->Crew[0]].Fighter;
for (i=1; i<MAXCREW; ++i)
{
if (Sh->Crew[i] < 0)
break;
if (Mercenary[Sh->Crew[i]].Fighter > MaxSkill)
MaxSkill = Mercenary[Sh->Crew[i]].Fighter;
}
if (HasGadget( Sh, TARGETINGSYSTEM ))
MaxSkill += SKILLBONUS;
return AdaptDifficulty( MaxSkill );
}
// *************************************************************************
// Pilot skill
// *************************************************************************
char PilotSkill( SHIP* Sh )
{
int i;
char MaxSkill;
MaxSkill = Mercenary[Sh->Crew[0]].Pilot;
for (i=1; i<MAXCREW; ++i)
{
if (Sh->Crew[i] < 0)
break;
if (Mercenary[Sh->Crew[i]].Pilot > MaxSkill)
MaxSkill = Mercenary[Sh->Crew[i]].Pilot;
}
if (HasGadget( Sh, NAVIGATINGSYSTEM ))
MaxSkill += SKILLBONUS;
if (HasGadget( Sh, CLOAKINGDEVICE ))
MaxSkill += CLOAKBONUS;
return AdaptDifficulty( MaxSkill );
}
// *************************************************************************
// Engineer skill
// *************************************************************************
char EngineerSkill( SHIP* Sh )
{
int i;
char MaxSkill;
MaxSkill = Mercenary[Sh->Crew[0]].Engineer;
for (i=1; i<MAXCREW; ++i)
{
if (Sh->Crew[i] < 0)
break;
if (Mercenary[Sh->Crew[i]].Engineer > MaxSkill)
MaxSkill = Mercenary[Sh->Crew[i]].Engineer;
}
if (HasGadget( Sh, AUTOREPAIRSYSTEM ))
MaxSkill += SKILLBONUS;
return AdaptDifficulty( MaxSkill );
}
// *************************************************************************
// Adapt a skill to the difficulty level
// *************************************************************************
char AdaptDifficulty( char Level )
{
if (Difficulty == BEGINNER || Difficulty == EASY)
return (Level+1);
else if (Difficulty == IMPOSSIBLE)
return max( 1, Level-1 );
else
return Level;
}
// *************************************************************************
// After erasure of police record, selling prices must be recalculated
// *************************************************************************
void RecalculateSellPrices( void )
{
int i;
for (i=0; i<MAXTRADEITEM; ++i)
SellPrice[i] = (SellPrice[i] * 100) / 90;
}
// *************************************************************************
// Random mercenary skill
// *************************************************************************
char RandomSkill( void )
{
return 1 + GetRandom( 5 ) + GetRandom( 6 );
}
// *************************************************************************
// Determines whether a certain gadget is on board
// *************************************************************************
Boolean HasGadget( SHIP* Sh, char Gg )
{
int i;
for (i=0; i<MAXGADGET; ++i)
{
if (Sh->Gadget[i] < 0)
continue;
if (Sh->Gadget[i] == Gg)
return true;
}
return false;
}
// *************************************************************************
// Determines whether a certain shield type is on board
// *************************************************************************
Boolean HasShield( SHIP* Sh, char Gg )
{
int i;
for (i=0; i<MAXSHIELD; ++i)
{
if (Sh->Shield[i] < 0)
continue;
if (Sh->Shield[i] == Gg)
return true;
}
return false;
}
// *************************************************************************
// Determines whether a certain weapon type is on board. If exactCompare is
// false, then better weapons will also return TRUE
// *************************************************************************
Boolean HasWeapon( SHIP* Sh, char Gg, Boolean exactCompare )
{
int i;
for (i=0; i<MAXWEAPON; ++i)
{
if (Sh->Weapon[i] < 0)
continue;
if ((Sh->Weapon[i] == Gg) || (Sh->Weapon[i] > Gg && !exactCompare))
return true;
}
return false;
}

406
Src/SpecialEvent.c Normal file
View File

@ -0,0 +1,406 @@
/***********************************************************************
*
* SPACE TRADER 1.2.2
*
* SpecialEvent.c
*
* Copyright (C) 2000-2002 Pieter Spronck, All Rights Reserved
*
* Additional coding by Sam Anderson (rulez2@home.com)
* Additional coding by Samuel Goldstein (palm@fogbound.net)
*
* Some code of Matt Lee's Dope Wars program has been used.
*
* 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.
*
* You can contact the author at space_trader@hotmail.com
*
* For those who are familiar with the classic game Elite: many of the
* ideas in Space Trader are heavily inspired by Elite.
*
**********************************************************************/
// *************************************************************************
// Handling of events on the Special Event screen
// *************************************************************************
#include "external.h"
static void DrawSpecialEventForm()
{
FormPtr frmP;
char theText[320];
frmP = FrmGetActiveForm();
setCurrentWinTitle( SpecialEvent[CURSYSTEM.Special].Title );
if (SpecialEvent[CURSYSTEM.Special].JustAMessage)
{
FrmHideObject( frmP, FrmGetObjectIndex( frmP, SpecialEventYesButton ) );
FrmHideObject( frmP, FrmGetObjectIndex( frmP, SpecialEventNoButton ) );
FrmShowObject( frmP, FrmGetObjectIndex( frmP, SpecialEventOKButton ) );
}
else
{
FrmShowObject( frmP, FrmGetObjectIndex( frmP, SpecialEventYesButton ) );
FrmShowObject( frmP, FrmGetObjectIndex( frmP, SpecialEventNoButton ) );
FrmHideObject( frmP, FrmGetObjectIndex( frmP, SpecialEventOKButton ) );
}
FrmDrawForm ( frmP );
SysCopyStringResource(theText, SpecialEvent[CURSYSTEM.Special].QuestStringID);
DisplayPage(theText, 18);
}
Boolean SpecialEventFormHandleEvent( EventPtr eventP )
{
Boolean handled = false;
int i, FirstEmptySlot;
switch (eventP->eType)
{
case frmOpenEvent:
case frmUpdateEvent:
DrawSpecialEventForm();
handled = true;
break;
// Special event
case ctlSelectEvent:
if (eventP->data.ctlSelect.controlID != SpecialEventNoButton)
{
if (ToSpend() < SpecialEvent[CURSYSTEM.Special].Price)
{
FrmAlert( NotEnoughForEventAlert );
handled = true;
break;
}
Credits -= SpecialEvent[CURSYSTEM.Special].Price;
switch (CURSYSTEM.Special)
{
case GETREACTOR:
if (FilledCargoBays() > TotalCargoBays() - 15)
{
FrmAlert( NotEnoughBaysAlert );
handled = true;
break;
}
else if (WildStatus == 1)
{
if (FrmCustomAlert(WildWontStayOnboardAlert, SolarSystemName[CURSYSTEM.NameIndex],
NULL, NULL) == WildWontStayOnboardSayGoodbyetoWild)
{
WildStatus = 0;
FrmCustomAlert( WildLeavesShipAlert,SolarSystemName[CURSYSTEM.NameIndex],
NULL, NULL);
}
else
{
handled = true;
break;
}
}
FrmAlert( ReactorAlert );
ReactorStatus = 1;
break;
case REACTORDELIVERED:
CURSYSTEM.Special = GETSPECIALLASER;
ReactorStatus = 21;
handled = true;
break;
case MONSTERKILLED:
break;
case SCARAB:
ScarabStatus = 1;
break;
case SCARABDESTROYED:
ScarabStatus = 2;
CURSYSTEM.Special = GETHULLUPGRADED;
handled = true;
break;
case GETHULLUPGRADED:
FrmAlert( HullUpgradeAlert );
Ship.Hull += UPGRADEDHULL;
ScarabStatus = 3;
handled = true;
break;
case EXPERIMENT:
ExperimentStatus = 1;
break;
case EXPERIMENTSTOPPED:
ExperimentStatus = 13;
CanSuperWarp = true;
break;
case EXPERIMENTNOTSTOPPED:
break;
case ARTIFACTDELIVERY:
ArtifactOnBoard = false;
break;
case ALIENARTIFACT:
ArtifactOnBoard = true;
break;
case FLYBARATAS:
case FLYMELINA:
case FLYREGULAS:
++DragonflyStatus;
break;
case DRAGONFLYDESTROYED:
CURSYSTEM.Special = INSTALLLIGHTNINGSHIELD;
handled = true;
break;
case GEMULONRESCUED:
CURSYSTEM.Special = GETFUELCOMPACTOR;
InvasionStatus = 0;
handled = true;
break;
case MEDICINEDELIVERY:
JaporiDiseaseStatus = 2;
IncreaseRandomSkill();
IncreaseRandomSkill();
break;
case MOONFORSALE:
FrmAlert( BoughtMoonAlert );
MoonBought = true;
break;
case MOONBOUGHT:
EraseRectangle( 0, 0, 160, 160 );
CurForm = UtopiaForm;
FrmGotoForm( UtopiaForm );
return true;
break;
case SKILLINCREASE:
FrmAlert( SkillIncreaseAlert );
IncreaseRandomSkill();
break;
case TRIBBLE:
FrmAlert( YouHaveATribbleAlert );
Ship.Tribbles = 1;
break;
case BUYTRIBBLE:
FrmAlert( BeamOverTribblesAlert );
Credits += (Ship.Tribbles >> 1);
Ship.Tribbles = 0;
break;
case ERASERECORD:
FrmAlert( CleanRecordAlert );
PoliceRecordScore = CLEANSCORE;
RecalculateSellPrices();
break;
case SPACEMONSTER:
MonsterStatus = 1;
for (i=0; i<MAXSOLARSYSTEM; ++i)
if (SolarSystem[i].Special == SPACEMONSTER)
SolarSystem[i].Special = -1;
break;
case DRAGONFLY:
DragonflyStatus = 1;
for (i=0; i<MAXSOLARSYSTEM; ++i)
if (SolarSystem[i].Special == DRAGONFLY)
SolarSystem[i].Special = -1;
break;
case AMBASSADORJAREK:
if (Ship.Crew[Shiptype[Ship.Type].CrewQuarters-1] >= 0)
{
FrmCustomAlert( NoQuartersAvailableAlert, "Ambassador Jarek", NULL, NULL );
handled = true;
break;
}
FrmCustomAlert( PassengerTakenOnBoardAlert, "Ambassador Jarek", NULL, NULL );
JarekStatus = 1;
break;
case TRANSPORTWILD:
if (Ship.Crew[Shiptype[Ship.Type].CrewQuarters-1] >= 0)
{
FrmCustomAlert( NoQuartersAvailableAlert, "Jonathan Wild", NULL, NULL );
handled = true;
break;
}
if (!HasWeapon(&Ship, BEAMLASERWEAPON, false))
{
FrmAlert (WildWontGetAboardAlert);
handled = true;
break;
}
if (ReactorStatus > 0 && ReactorStatus < 21)
{
FrmAlert( WildAfraidOfReactorAlert );
handled = true;
break;
}
FrmCustomAlert( PassengerTakenOnBoardAlert, "Jonathan Wild", NULL, NULL );
WildStatus = 1;
break;
case ALIENINVASION:
InvasionStatus = 1;
break;
case JAREKGETSOUT:
JarekStatus = 2;
RecalculateBuyPrices(COMMANDER.CurSystem);
break;
case WILDGETSOUT:
WildStatus = 2;
Mercenary[MAXCREWMEMBER-1].CurSystem = KRAVATSYSTEM;
// Zeethibal has a 10 in player's lowest score, an 8
// in the next lowest score, and 5 elsewhere.
Mercenary[MAXCREWMEMBER-1].Pilot = 5;
Mercenary[MAXCREWMEMBER-1].Fighter = 5;
Mercenary[MAXCREWMEMBER-1].Trader = 5;
Mercenary[MAXCREWMEMBER-1].Engineer = 5;
switch (NthLowestSkill(&Ship, 1))
{
case PILOTSKILL:
Mercenary[MAXCREWMEMBER-1].Pilot = 10;
break;
case FIGHTERSKILL:
Mercenary[MAXCREWMEMBER-1].Fighter = 10;
break;
case TRADERSKILL:
Mercenary[MAXCREWMEMBER-1].Trader = 10;
break;
case ENGINEERSKILL:
Mercenary[MAXCREWMEMBER-1].Engineer = 10;
break;
}
switch (NthLowestSkill(&Ship, 2))
{
case PILOTSKILL:
Mercenary[MAXCREWMEMBER-1].Pilot = 8;
break;
case FIGHTERSKILL:
Mercenary[MAXCREWMEMBER-1].Fighter = 8;
break;
case TRADERSKILL:
Mercenary[MAXCREWMEMBER-1].Trader = 8;
break;
case ENGINEERSKILL:
Mercenary[MAXCREWMEMBER-1].Engineer = 8;
break;
}
if (PoliceRecordScore < CLEANSCORE)
PoliceRecordScore = CLEANSCORE;
break;
case CARGOFORSALE:
FrmAlert( SealedCannistersAlert );
i = GetRandom( MAXTRADEITEM );
Ship.Cargo[i] += 3;
BuyingPrice[i] += SpecialEvent[CURSYSTEM.Special].Price;
break;
case INSTALLLIGHTNINGSHIELD:
FirstEmptySlot = GetFirstEmptySlot( Shiptype[Ship.Type].ShieldSlots, Ship.Shield );
if (FirstEmptySlot < 0)
{
FrmAlert( NotEnoughSlotsAlert );
handled = true;
}
else
{
FrmAlert( LightningShieldAlert );
Ship.Shield[FirstEmptySlot] = LIGHTNINGSHIELD;
Ship.ShieldStrength[FirstEmptySlot] = Shieldtype[LIGHTNINGSHIELD].Power;
}
break;
case GETSPECIALLASER:
FirstEmptySlot = GetFirstEmptySlot( Shiptype[Ship.Type].WeaponSlots, Ship.Weapon );
if (FirstEmptySlot < 0)
{
FrmAlert( NotEnoughSlotsAlert );
handled = true;
}
else
{
FrmAlert(MorganLaserAlert );
Ship.Weapon[FirstEmptySlot] = MORGANLASERWEAPON;
}
break;
case GETFUELCOMPACTOR:
FirstEmptySlot = GetFirstEmptySlot( Shiptype[Ship.Type].GadgetSlots, Ship.Gadget );
if (FirstEmptySlot < 0)
{
FrmAlert( NotEnoughSlotsAlert );
handled = true;
}
else
{
FrmAlert( FuelCompactorAlert );
Ship.Gadget[FirstEmptySlot] = FUELCOMPACTOR;
Ship.Fuel = GetFuelTanks();
}
break;
case JAPORIDISEASE:
if (FilledCargoBays() > TotalCargoBays() - 10)
{
FrmAlert( NotEnoughBaysAlert );
handled = true;
}
else
{
FrmAlert( AntidoteAlert );
JaporiDiseaseStatus = 1;
}
break;
}
if (!handled)
CURSYSTEM.Special = -1;
}
CurForm = SystemInformationForm;
FrmGotoForm( CurForm );
handled = true;
break;
default:
break;
}
return handled;
}

917
Src/SystemInfoEvent.c Normal file
View File

@ -0,0 +1,917 @@
/***********************************************************************
*
* SPACE TRADER 1.2.0
*
* SystemInfoEvent.c
*
* Copyright (C) 2000-2002 Pieter Spronck, All Rights Reserved
*
* Additional coding by Sam Anderson (rulez2@home.com)
* Additional coding by Samuel Goldstein (palm@fogbound.net)
*
* Some code of Matt Lee's Dope Wars program has been used.
*
* 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.
*
* You can contact the author at space_trader@hotmail.com
*
* For those who are familiar with the classic game Elite: many of the
* ideas in Space Trader are heavily inspired by Elite.
*
**********************************************************************/
#include "external.h"
static int NewsEvents[MAXSPECIALNEWSEVENTS];
// *************************************************************************
// Draw one mercenary
// *************************************************************************
static void DrawMercenary( int Index, int y )
{
int j, d;
DrawChars( MercenaryName[Mercenary[Index].NameIndex], 30, y );
StrIToA( SBuf, MERCENARYHIREPRICE( Index ) );
StrCat( SBuf, " cr." );
j = MAXDIGITS - StrLen( SBuf );
d = 101+j*5;
StrCat( SBuf, " daily" );
DrawChars( SBuf, d, y );
StrCopy( SBuf, "Pilot: " );
StrIToA( SBuf2, Mercenary[Index].Pilot );
StrCat( SBuf, SBuf2 );
DrawChars( SBuf, 30, y + 13 );
StrCopy( SBuf, "Trader: " );
StrIToA( SBuf2, Mercenary[Index].Trader );
StrCat( SBuf, SBuf2 );
DrawChars( SBuf, 30, y + 26 );
StrCopy( SBuf, "Fighter: " );
StrIToA( SBuf2, Mercenary[Index].Fighter );
StrCat( SBuf, SBuf2 );
DrawChars( SBuf, 80, y + 13 );
StrCopy( SBuf, "Engineer: " );
StrIToA( SBuf2, Mercenary[Index].Engineer );
StrCat( SBuf, SBuf2 );
DrawChars( SBuf, 80, y + 26 );
}
// *************************************************************************
// Return available crew quarters
// *************************************************************************
static char AvailableQuarters( void )
{
return Shiptype[Ship.Type].CrewQuarters - (JarekStatus == 1 ? 1 : 0) -
(WildStatus == 1 ? 1 : 0);
}
// *************************************************************************
// Determine which mercenary is for hire in the current system
// *************************************************************************
static int GetForHire( void )
{
int ForHire = -1;
int i;
for (i=1; i<MAXCREWMEMBER; ++i)
{
if (i == Ship.Crew[1] || i == Ship.Crew[2])
continue;
if (Mercenary[i].CurSystem == Mercenary[0].CurSystem)
{
ForHire = i;
break;
}
}
return ForHire;
}
// *************************************************************************
// Drawing the Personnel Roster screen
// *************************************************************************
static void DrawPersonnelRoster( void )
{
FormPtr frmP;
RectangleType a;
int i, ForHire;
frmP = FrmGetActiveForm();
RectangularShortcuts( frmP, PersonnelRosterBButton );
for (i=0; i<3; ++i)
RectangularButton( frmP, PersonnelRosterFire0Button + i );
FrmDrawForm( frmP );
EraseRectangle( 30, 18, 130, 142 );
a.topLeft.x = 0;
a.topLeft.y = BOUNDSY + 38;
a.extent.x = 160;
a.extent.y = 2;
WinDrawRectangle( &a, 0 );
a.topLeft.y = BOUNDSY + 83;
WinDrawRectangle( &a, 0 );
FntSetFont( stdFont );
for (i=0; i<2; ++i)
{
if (i == Shiptype[Ship.Type].CrewQuarters-2 && (JarekStatus == 1 || WildStatus == 1))
{
if (JarekStatus == 1)
DrawChars( "Jarek's quarters", 30, 30 + i*45 );
else
DrawChars( "Wild's quarters", 30, 30 + i*45 );
FrmHideObject( frmP, FrmGetObjectIndex( frmP, PersonnelRosterFire0Button + i ) );
continue;
}
if (Shiptype[Ship.Type].CrewQuarters <= i+1)
{
DrawChars( "No quarters available", 30, 30 + i*45 );
FrmHideObject( frmP, FrmGetObjectIndex( frmP, PersonnelRosterFire0Button + i ) );
continue;
}
if (Ship.Crew[i+1] < 0)
{
DrawChars( "Vacancy", 30, 30 + i*45 );
FrmHideObject( frmP, FrmGetObjectIndex( frmP, PersonnelRosterFire0Button + i ) );
continue;
}
FrmShowObject( frmP, FrmGetObjectIndex( frmP, PersonnelRosterFire0Button + i ) );
DrawMercenary( Ship.Crew[i+1], 17+i*45 );
}
ForHire = GetForHire();
if (ForHire < 0)
{
DrawChars( "No one for hire", 30, 120 );
FrmHideObject( frmP, FrmGetObjectIndex( frmP, PersonnelRosterHire0Button ) );
}
else
{
FrmShowObject( frmP, FrmGetObjectIndex( frmP, PersonnelRosterHire0Button ) );
DrawMercenary( ForHire, 107 );
}
DisplayTradeCredits();
}
// *************************************************************************
// Add a news event flag
// *************************************************************************
void addNewsEvent(int eventFlag)
{
if (NewsSpecialEventCount < MAXSPECIALNEWSEVENTS - 1)
NewsEvents[NewsSpecialEventCount++] = eventFlag;
}
// *************************************************************************
// replace a news event flag with another
// *************************************************************************
void replaceNewsEvent(int originalEventFlag, int replacementEventFlag)
{
int i;
if (originalEventFlag == -1)
{
addNewsEvent(replacementEventFlag);
}
else
{
for (i=0;i<NewsSpecialEventCount; i++)
{
if (NewsEvents[i] == originalEventFlag)
NewsEvents[i] = replacementEventFlag;
}
}
}
// *************************************************************************
// Reset news event flags
// *************************************************************************
void resetNewsEvents(void)
{
NewsSpecialEventCount = 0;
}
// *************************************************************************
// get most recently addded news event flag
// *************************************************************************
int latestNewsEvent(void)
{
if (NewsSpecialEventCount == 0)
return -1;
else
return NewsEvents[NewsSpecialEventCount - 1];
}
// *************************************************************************
// Query news event flags
// *************************************************************************
Boolean isNewsEvent(int eventFlag)
{
int i;
for (i=0;i<NewsSpecialEventCount; i++)
{
if (NewsEvents[i] == eventFlag)
return true;
}
return false;
}
static void DrawSystemInformationForm()
{
FormPtr frmP;
int OpenQ = OpenQuests();
frmP = FrmGetActiveForm();
setLabelText( frmP, SystemInformationSystemNameLabel,
SolarSystemName[CURSYSTEM.NameIndex] );
setLabelText( frmP, SystemInformationTechLevelLabel,
TechLevel[CURSYSTEM.TechLevel] );
setLabelText( frmP, SystemInformationGovernmentLabel,
Politics[CURSYSTEM.Politics].Name );
setLabelText( frmP, SystemInformationResourcesLabel,
SpecialResources[CURSYSTEM.SpecialResources] );
setLabelText( frmP, SystemInformationStatusLabel,
Status[CURSYSTEM.Status] );
setLabelText( frmP, SystemInformationSizeLabel,
SystemSize[CURSYSTEM.Size] );
setLabelText( frmP, SystemInformationPoliceLabel,
Activity[Politics[CURSYSTEM.Politics].StrengthPolice] );
setLabelText( frmP, SystemInformationPiratesLabel,
Activity[Politics[CURSYSTEM.Politics].StrengthPirates] );
if ((CURSYSTEM.Special < 0) ||
(CURSYSTEM.Special == BUYTRIBBLE && Ship.Tribbles <= 0) ||
(CURSYSTEM.Special == ERASERECORD && PoliceRecordScore >= DUBIOUSSCORE) ||
(CURSYSTEM.Special == CARGOFORSALE && (FilledCargoBays() > TotalCargoBays() - 3)) ||
((CURSYSTEM.Special == DRAGONFLY || CURSYSTEM.Special == JAPORIDISEASE ||
CURSYSTEM.Special == ALIENARTIFACT || CURSYSTEM.Special == AMBASSADORJAREK ||
CURSYSTEM.Special == EXPERIMENT) && (PoliceRecordScore < DUBIOUSSCORE)) ||
(CURSYSTEM.Special == TRANSPORTWILD && (PoliceRecordScore >= DUBIOUSSCORE)) ||
(CURSYSTEM.Special == GETREACTOR && (PoliceRecordScore >= DUBIOUSSCORE || ReputationScore < AVERAGESCORE || ReactorStatus != 0)) ||
(CURSYSTEM.Special == REACTORDELIVERED && !(ReactorStatus > 0 && ReactorStatus < 21)) ||
(CURSYSTEM.Special == MONSTERKILLED && MonsterStatus < 2) ||
(CURSYSTEM.Special == EXPERIMENTSTOPPED && !(ExperimentStatus >= 1 && ExperimentStatus < 12)) ||
(CURSYSTEM.Special == FLYBARATAS && DragonflyStatus < 1) ||
(CURSYSTEM.Special == FLYMELINA && DragonflyStatus < 2) ||
(CURSYSTEM.Special == FLYREGULAS && DragonflyStatus < 3) ||
(CURSYSTEM.Special == DRAGONFLYDESTROYED && DragonflyStatus < 5) ||
(CURSYSTEM.Special == SCARAB && (ReputationScore < AVERAGESCORE || ScarabStatus != 0)) ||
(CURSYSTEM.Special == SCARABDESTROYED && ScarabStatus != 2) ||
(CURSYSTEM.Special == GETHULLUPGRADED && ScarabStatus != 2) ||
(CURSYSTEM.Special == MEDICINEDELIVERY && JaporiDiseaseStatus != 1) ||
(CURSYSTEM.Special == JAPORIDISEASE && (JaporiDiseaseStatus != 0)) ||
(CURSYSTEM.Special == ARTIFACTDELIVERY && !ArtifactOnBoard) ||
(CURSYSTEM.Special == JAREKGETSOUT && JarekStatus != 1) ||
(CURSYSTEM.Special == WILDGETSOUT && WildStatus != 1) ||
(CURSYSTEM.Special == GEMULONRESCUED && !(InvasionStatus >= 1 && InvasionStatus <= 7)) ||
(CURSYSTEM.Special == MOONFORSALE && (MoonBought || CurrentWorth() < (COSTMOON * 4) / 5)) ||
(CURSYSTEM.Special == MOONBOUGHT && MoonBought != true))
FrmHideObject( frmP, FrmGetObjectIndex( frmP, SystemInformationSpecialButton ) );
else if (OpenQ > 3 &&
(CURSYSTEM.Special == TRIBBLE ||
CURSYSTEM.Special == SPACEMONSTER ||
CURSYSTEM.Special == DRAGONFLY ||
CURSYSTEM.Special == JAPORIDISEASE ||
CURSYSTEM.Special == ALIENARTIFACT ||
CURSYSTEM.Special == AMBASSADORJAREK ||
CURSYSTEM.Special == ALIENINVASION ||
CURSYSTEM.Special == EXPERIMENT ||
CURSYSTEM.Special == TRANSPORTWILD ||
CURSYSTEM.Special == GETREACTOR ||
CURSYSTEM.Special == SCARAB))
FrmHideObject( frmP, FrmGetObjectIndex( frmP, SystemInformationSpecialButton ) );
else
FrmShowObject( frmP, FrmGetObjectIndex( frmP, SystemInformationSpecialButton ) );
if (GetForHire() < 0)
FrmHideObject( frmP, FrmGetObjectIndex( frmP, SystemInformationMercenaryForHireButton ) );
else
FrmShowObject( frmP, FrmGetObjectIndex( frmP, SystemInformationMercenaryForHireButton ) );
RectangularShortcuts( frmP, SystemInformationBButton );
FrmDrawForm( frmP );
}
// *************************************************************************
// Handling of events on the System Information screen
// *************************************************************************
Boolean SystemInformationFormHandleEvent(EventPtr eventP)
{
Boolean handled = false;
int OpenQ = OpenQuests();
switch (eventP->eType)
{
// Show information on current system
case frmOpenEvent:
// also, we decide if we want to set the News Flags here...
if (CURSYSTEM.Special > -1)
{
if (CURSYSTEM.Special == MONSTERKILLED && MonsterStatus == 2)
addNewsEvent(MONSTERKILLED);
else if (CURSYSTEM.Special == DRAGONFLY)
addNewsEvent(DRAGONFLY);
else if (CURSYSTEM.Special == SCARAB)
addNewsEvent(SCARAB);
else if (CURSYSTEM.Special == SCARABDESTROYED && ScarabStatus == 2)
addNewsEvent(SCARABDESTROYED);
else if (CURSYSTEM.Special == FLYBARATAS && DragonflyStatus == 1)
addNewsEvent(FLYBARATAS);
else if (CURSYSTEM.Special == FLYMELINA && DragonflyStatus == 2)
addNewsEvent(FLYMELINA);
else if (CURSYSTEM.Special == FLYREGULAS && DragonflyStatus == 3)
addNewsEvent(FLYREGULAS);
else if (CURSYSTEM.Special == DRAGONFLYDESTROYED && DragonflyStatus == 5)
addNewsEvent(DRAGONFLYDESTROYED);
else if (CURSYSTEM.Special == MEDICINEDELIVERY && JaporiDiseaseStatus == 1)
addNewsEvent(MEDICINEDELIVERY);
else if (CURSYSTEM.Special == ARTIFACTDELIVERY && ArtifactOnBoard)
addNewsEvent(ARTIFACTDELIVERY);
else if (CURSYSTEM.Special == JAPORIDISEASE && JaporiDiseaseStatus == 0)
addNewsEvent(JAPORIDISEASE);
else if (CURSYSTEM.Special == JAREKGETSOUT && JarekStatus == 1)
addNewsEvent(JAREKGETSOUT);
else if (CURSYSTEM.Special == WILDGETSOUT && WildStatus == 1)
addNewsEvent(WILDGETSOUT);
else if (CURSYSTEM.Special == GEMULONRESCUED && InvasionStatus > 0 && InvasionStatus < 8)
addNewsEvent(GEMULONRESCUED);
else if (CURSYSTEM.Special == ALIENINVASION)
addNewsEvent(ALIENINVASION);
else if (CURSYSTEM.Special == EXPERIMENTSTOPPED && ExperimentStatus > 0 && ExperimentStatus < 12)
addNewsEvent(EXPERIMENTSTOPPED);
else if (CURSYSTEM.Special == EXPERIMENTNOTSTOPPED)
addNewsEvent(EXPERIMENTNOTSTOPPED);
}
DrawSystemInformationForm();
CURSYSTEM.Visited = true;
handled = true;
break;
case frmUpdateEvent:
DrawSystemInformationForm();
handled = true;
break;
// Special event
case ctlSelectEvent:
if (eventP->data.ctlSelect.controlID == SystemInformationSpecialButton)
{
CurForm = SpecialEventForm;
}
else if (eventP->data.ctlSelect.controlID == SystemInformationMercenaryForHireButton)
{
CurForm = PersonnelRosterForm;
}
else if (eventP->data.ctlSelect.controlID == SystemInformationNewsButton)
{
StrIToA( SBuf, Difficulty + 1 );
if (!AlreadyPaidForNewspaper && ToSpend() < (long)(Difficulty + 1.0) )
{
FrmCustomAlert(CantAffordPaperAlert, SBuf, NULL, NULL);
return true;
}
else
{
if (!NewsAutoPay && !AlreadyPaidForNewspaper)
if (FrmCustomAlert( BuyNewspaperAlert, SBuf, NULL, NULL ) == BuyNewspaperCancel)
return true;
if (!AlreadyPaidForNewspaper)
{
Credits -= (Difficulty + 1);
AlreadyPaidForNewspaper = true;
}
CurForm = NewspaperForm;
}
}
FrmGotoForm( CurForm );
handled = true;
break;
default:
break;
}
return handled;
}
static void DrawNewspaperForm()
{
FormPtr frmP;
int line = 18, i, j;
Boolean shown[MAXSTORIES];
Boolean realNews = false;
frmP = FrmGetActiveForm();
FrmDrawForm( frmP );
i = WarpSystem % MAXMASTHEADS;
SysStringByIndex(AnarchyMastheadsStringList + CURSYSTEM.Politics * 100,i,SBuf2,50);
if (StrNCompare(SBuf2,"*",1) == 0)
{
StrCopy(SBuf,"The ");
StrCat(SBuf, SolarSystemName[CURSYSTEM.NameIndex]);
StrCat(SBuf, SBuf2 + 1);
//DrawCharsCentered(SBuf, line, true);
setCurrentWinTitle(SBuf);
}
else if (StrNCompare(SBuf2,"+",1) == 0)
{
StrCopy(SBuf, SolarSystemName[CURSYSTEM.NameIndex]);
StrCat(SBuf, SBuf2 + 1);
//DrawCharsCentered(SBuf, line, true);
setCurrentWinTitle(SBuf);
}
else
{
//DrawCharsCentered(SBuf2, line, true);
setCurrentWinTitle(SBuf2);
}
RandSeed( WarpSystem, Days );
// Special Events get to go first, crowding out other news
if (isNewsEvent(CAPTAINHUIEATTACKED))
{
DisplayHeadline("Famed Captain Huie Attacked by Brigand!", &line);
}
if (isNewsEvent(EXPERIMENTPERFORMED))
{
DisplayHeadline("Travelers Report Timespace Damage, Warp Problems!", &line);
}
if (isNewsEvent(CAPTAINHUIEDESTROYED))
{
DisplayHeadline("Citizens Mourn Destruction of Captain Huie's Ship!", &line);
}
if (isNewsEvent(CAPTAINAHABATTACKED))
{
DisplayHeadline("Thug Assaults Captain Ahab!", &line);
}
if (isNewsEvent(CAPTAINAHABDESTROYED))
{
DisplayHeadline("Destruction of Captain Ahab's Ship Causes Anger!", &line);
}
if (isNewsEvent(CAPTAINCONRADATTACKED))
{
DisplayHeadline("Captain Conrad Comes Under Attack By Criminal!", &line);
}
if (isNewsEvent(CAPTAINCONRADDESTROYED))
{
DisplayHeadline("Captain Conrad's Ship Destroyed by Villain!", &line);
}
if (isNewsEvent(MONSTERKILLED))
{
DisplayHeadline("Hero Slays Space Monster! Parade, Honors Planned for Today.", &line);
}
if (isNewsEvent(WILDARRESTED))
{
DisplayHeadline("Notorious Criminal Jonathan Wild Arrested!", &line);
}
if (CURSYSTEM.Special == MONSTERKILLED && MonsterStatus == 1)
{
DisplayHeadline("Space Monster Threatens Homeworld!", &line);
}
if (CURSYSTEM.Special == SCARABDESTROYED && ScarabStatus == 1)
{
DisplayHeadline("Wormhole Travelers Harassed by Unusual Ship!", &line);
}
if (isNewsEvent(EXPERIMENTSTOPPED))
{
DisplayHeadline("Scientists Cancel High-profile Test! Committee to Investigate Design.", &line);
}
if (isNewsEvent(EXPERIMENTNOTSTOPPED))
{
DisplayHeadline("Huge Explosion Reported at Research Facility.", &line);
}
if (isNewsEvent(DRAGONFLY))
{
DisplayHeadline("Experimental Craft Stolen! Critics Demand Security Review.", &line);
}
if (isNewsEvent(SCARAB))
{
DisplayHeadline("Security Scandal: Test Craft Confirmed Stolen.", &line);
}
if (isNewsEvent(FLYBARATAS))
{
DisplayHeadline("Investigators Report Strange Craft.", &line);
}
if (isNewsEvent(FLYMELINA))
{
DisplayHeadline("Rumors Continue: Melina Orbitted by Odd Starcraft.", &line);
}
if (isNewsEvent(FLYREGULAS))
{
DisplayHeadline("Strange Ship Observed in Regulas Orbit.", &line);
}
if (CURSYSTEM.Special == DRAGONFLYDESTROYED && DragonflyStatus == 4 &&
!isNewsEvent(DRAGONFLYDESTROYED))
{
DisplayHeadline("Unidentified Ship: A Threat to Zalkon?", &line);
}
if (isNewsEvent(DRAGONFLYDESTROYED))
{
DisplayHeadline("Spectacular Display as Stolen Ship Destroyed in Fierce Space Battle.", &line);
}
if (isNewsEvent(SCARABDESTROYED))
{
DisplayHeadline("Wormhole Traffic Delayed as Stolen Craft Destroyed.", &line);
}
if (isNewsEvent(MEDICINEDELIVERY))
{
DisplayHeadline("Disease Antidotes Arrive! Health Officials Optimistic.", &line);
}
if (isNewsEvent(JAPORIDISEASE))
{
DisplayHeadline("Editorial: We Must Help Japori!",&line);
}
if (isNewsEvent(ARTIFACTDELIVERY))
{
DisplayHeadline("Scientist Adds Alien Artifact to Museum Collection.", &line);
}
if (isNewsEvent(JAREKGETSOUT))
{
DisplayHeadline("Ambassador Jarek Returns from Crisis.", &line);
}
if (isNewsEvent(WILDGETSOUT))
{
DisplayHeadline("Rumors Suggest Known Criminal J. Wild May Come to Kravat!", &line);
}
if (isNewsEvent(GEMULONRESCUED))
{
DisplayHeadline("Invasion Imminent! Plans in Place to Repel Hostile Invaders.", &line);
}
if (CURSYSTEM.Special == GEMULONRESCUED && !isNewsEvent(GEMULONRESCUED))
{
DisplayHeadline("Alien Invasion Devastates Planet!", &line);
}
if (isNewsEvent(ALIENINVASION))
{
DisplayHeadline("Editorial: Who Will Warn Gemulon?", &line);
}
if (isNewsEvent(ARRIVALVIASINGULARITY))
{
DisplayHeadline("Travelers Claim Sighting of Ship Materializing in Orbit!", &line);
}
// local system status information
if (CURSYSTEM.Status > 0)
{
switch (CURSYSTEM.Status)
{
case WAR:
DisplayHeadline("War News: Offensives Continue!", &line);
break;
case PLAGUE:
DisplayHeadline("Plague Spreads! Outlook Grim.", &line);
break;
case DROUGHT:
DisplayHeadline("No Rain in Sight!",&line);
break;
case BOREDOM:
DisplayHeadline("Editors: Won't Someone Entertain Us?",&line);
break;
case COLD:
DisplayHeadline("Cold Snap Continues!", &line);
break;
case CROPFAILURE:
DisplayHeadline("Serious Crop Failure! Must We Ration?", &line);
break;
case LACKOFWORKERS:
DisplayHeadline("Jobless Rate at All-Time Low!", &line);
break;
}
}
// character-specific news.
if (PoliceRecordScore <= VILLAINSCORE)
{
j = GetRandom2(4);
switch (j)
{
case 0:
StrCopy( SBuf, "Police Warning: ");
StrCat( SBuf, NameCommander);
StrCat( SBuf, " Will Dock At ");
StrCat( SBuf, SolarSystemName[CURSYSTEM.NameIndex]);
StrCat( SBuf, "!");
break;
case 1:
StrCopy(SBuf,"Notorious Criminal ");
StrCat(SBuf, NameCommander);
StrCat(SBuf, " Sighted in ");
StrCat( SBuf, SolarSystemName[CURSYSTEM.NameIndex]);
StrCat( SBuf, "!");
break;
case 2:
StrCopy(SBuf,"Locals Rally to Deny Spaceport Access to ");
StrCat(SBuf, NameCommander);
StrCat(SBuf, "!");
break;
case 3:
StrCopy(SBuf,"Terror Strikes Locals on Arrival of ");
StrCat(SBuf, NameCommander);
StrCat(SBuf, "!");
break;
}
DisplayHeadline(SBuf, &line);
}
if (PoliceRecordScore == HEROSCORE)
{
j = GetRandom2(3);
switch (j)
{
case 0:
StrCopy(SBuf,"Locals Welcome Visiting Hero ");
StrCat(SBuf, NameCommander);
StrCat(SBuf, "!");
break;
case 1:
StrCopy(SBuf,"Famed Hero ");
StrCat(SBuf, NameCommander);
StrCat(SBuf, " to Visit System!");
break;
case 2:
StrCopy(SBuf,"Large Turnout At Spaceport to Welcome ");
StrCat(SBuf, NameCommander);
StrCat(SBuf, "!");
break;
}
DisplayHeadline(SBuf, &line);
}
// caught littering?
if (isNewsEvent(CAUGHTLITTERING))
{
StrCopy( SBuf, "Police Trace Orbiting Space Litter to ");
StrCat( SBuf, NameCommander );
StrCat( SBuf, ".");
DisplayHeadline(SBuf, &line);
}
// and now, finally, useful news (if any)
// base probability of a story showing up is (50 / MAXTECHLEVEL) * Current Tech Level
// This is then modified by adding 10% for every level of play less than Impossible
for (i=0; i < MAXSOLARSYSTEM; i++)
{
if (i != COMMANDER.CurSystem &&
((RealDistance(CURSYSTEM, SolarSystem[i]) <= Shiptype[Ship.Type].FuelTanks)
||
(WormholeExists( COMMANDER.CurSystem, i )))
&&
SolarSystem[i].Status > 0)
{
// Special stories that always get shown: moon, millionaire
if (SolarSystem[i].Special == MOONFORSALE)
{
StrCopy(SBuf, "Seller in ");
StrCat(SBuf,SolarSystemName[i]);
StrCat(SBuf, " System has Utopian Moon available.");
DisplayHeadline(SBuf, &line);
}
if (SolarSystem[i].Special == BUYTRIBBLE)
{
StrCopy(SBuf, "Collector in ");
StrCat(SBuf,SolarSystemName[i]);
StrCat(SBuf, " System seeks to purchase Tribbles.");
DisplayHeadline(SBuf, &line);
}
// And not-always-shown stories
if (GetRandom2(100) <= STORYPROBABILITY * CURSYSTEM.TechLevel + 10 * (5 - Difficulty))
{
j = GetRandom2(6);
switch (j)
{
case 0:
StrCopy(SBuf, "Reports of");
break;
case 1:
StrCopy(SBuf, "News of");
break;
case 2:
StrCopy(SBuf, "New Rumors of");
break;
case 3:
StrCopy(SBuf, "Sources say");
break;
case 4:
StrCopy(SBuf, "Notice:");
break;
case 5:
StrCopy(SBuf, "Evidence Suggests");
break;
}
StrCat(SBuf, " ");
switch (SolarSystem[i].Status)
{
case WAR:
StrCat(SBuf,"Strife and War");
break;
case PLAGUE:
StrCat(SBuf, "Plague Outbreaks");
break;
case DROUGHT:
StrCat(SBuf, "Severe Drought");
break;
case BOREDOM:
StrCat(SBuf, "Terrible Boredom");
break;
case COLD:
StrCat(SBuf, "Cold Weather");
break;
case CROPFAILURE:
StrCat(SBuf, "Crop Failures");
break;
case LACKOFWORKERS:
StrCat(SBuf, "Labor Shortages");
break;
}
StrCat(SBuf, " in the ");
StrCat(SBuf,SolarSystemName[i]);
StrCat(SBuf, " System.");
DisplayHeadline(SBuf, &line);
realNews = true;
}
}
}
// if there's no useful news, we throw up at least one
// headline from our canned news list.
if (! realNews)
{
for (i=0; i< MAXSTORIES; i++)
{
shown[i]= false;
}
for (i=0; i <=GetRandom2(MAXSTORIES); i++)
{
j = GetRandom2(MAXSTORIES);
if (!shown[j] && line <= 150)
{
SysStringByIndex(AnarchyHeadlinesStringList + CURSYSTEM.Politics * 100,j,SBuf,63);
DisplayHeadline(SBuf, &line);
shown[j] = true;
}
}
}
}
// Show the newspaper screen
Boolean NewspaperFormHandleEvent(EventPtr eventP)
{
Boolean handled = false;
switch (eventP->eType)
{
// Show information on current system
case frmOpenEvent:
case frmUpdateEvent:
DrawNewspaperForm();
handled = true;
break;
// Special event
case ctlSelectEvent:
if (eventP->data.ctlSelect.controlID == NewspaperDoneButton)
{
CurForm = SystemInformationForm;
}
FrmGotoForm( CurForm );
handled = true;
break;
default:
break;
}
return handled;
}
// *****************************************************************
// Handling of the events of the Personnel Roster form
// *****************************************************************
Boolean PersonnelRosterFormHandleEvent( EventPtr eventP )
{
Boolean handled = false;
Boolean Sale;
int FirstFree, ForHire, oldtraderskill;
switch (eventP->eType)
{
case frmOpenEvent:
DrawPersonnelRoster();
handled = true;
break;
case frmUpdateEvent:
DrawPersonnelRoster();
handled = true;
break;
case ctlSelectEvent:
Sale = true;
oldtraderskill = TraderSkill( &Ship );
if (eventP->data.ctlSelect.controlID == PersonnelRosterFire0Button)
{
if (FrmAlert( FireMercenaryAlert ) == 0)
{
Ship.Crew[1] = Ship.Crew[2];
Ship.Crew[2] = -1;
}
}
else if (eventP->data.ctlSelect.controlID == PersonnelRosterFire1Button)
{
if (FrmAlert( FireMercenaryAlert ) == 0)
{
Ship.Crew[2] = -1;
}
}
else if (eventP->data.ctlSelect.controlID == PersonnelRosterHire0Button)
{
/*
ForHire = -1;
for (i=1; i<MAXCREWMEMBER; ++i)
{
if (i == Ship.Crew[1] || i == Ship.Crew[2])
continue;
if (Mercenary[i].CurSystem == Mercenary[0].CurSystem)
{
ForHire = i;
break;
}
}
*/
ForHire = GetForHire();
FirstFree = -1;
if (Ship.Crew[1] == -1)
FirstFree = 1;
else if (Ship.Crew[2] == -1)
FirstFree = 2;
if ((FirstFree < 0) ||
(AvailableQuarters() <= FirstFree))
{
FrmAlert( NoFreeQuartersAlert );
Sale = false;
}
else
Ship.Crew[FirstFree] = ForHire;
}
if (Sale)
{
DrawPersonnelRoster();
if (oldtraderskill != TraderSkill( &Ship ))
RecalculateBuyPrices(COMMANDER.CurSystem);
}
handled = true;
break;
default:
break;
}
return handled;
}

2922
Src/Traveler.c Normal file

File diff suppressed because it is too large Load Diff

762
Src/WarpFormEvent.c Normal file
View File

@ -0,0 +1,762 @@
/***********************************************************************
*
* SPACE TRADER 1.2.0
*
* WarpFormEvent.c
*
* Copyright (C) 2000-2002 Pieter Spronck, All Rights Reserved
*
* Additional coding by Sam Anderson (rulez2@home.com)
* Additional coding by Samuel Goldstein (palm@fogbound.net)
*
* Some code of Matt Lee's Dope Wars program has been used.
*
* 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.
*
* You can contact the author at space_trader@hotmail.com
*
* For those who are familiar with the classic game Elite: many of the
* ideas in Space Trader are heavily inspired by Elite.
*
**********************************************************************/
#include "external.h"
// *************************************************************************
// To draw a circle with centre Xs, Ys and radius R.
// *************************************************************************
static void DrawCircle( int Xs, int Ys, int R )
{
int Xp, Yp, i, Xt, Yt;
Xp = Xs;
Yp = Ys - R;
for (i=0; i<=R; ++i)
{
Xt = Xs + i;
Yt = Ys - sqrt( SQR( R ) - SQR( i ) );
WinDrawLine( Xp, Yp, Xt, Yt );
Xp = Xt;
Yp = Yt;
}
Xp = Xs;
Yp = Ys + R;
for (i=0; i<=R; ++i)
{
Xt = Xs + i;
Yt = Ys + sqrt( SQR( R ) - SQR( i ) );
WinDrawLine( Xp, Yp, Xt, Yt );
Xp = Xt;
Yp = Yt;
}
Xp = Xs;
Yp = Ys + R;
for (i=0; i<=R; ++i)
{
Xt = Xs - i;
Yt = Ys + sqrt( SQR( R ) - SQR( i ) );
WinDrawLine( Xp, Yp, Xt, Yt );
Xp = Xt;
Yp = Yt;
}
Xp = Xs;
Yp = Ys - R;
for (i=0; i<=R; ++i)
{
Xt = Xs - i;
Yt = Ys - sqrt( SQR( R ) - SQR( i ) );
WinDrawLine( Xp, Yp, Xt, Yt );
Xp = Xt;
Yp = Yt;
}
}
// *************************************************************************
// Draw the short range chart
// *************************************************************************
static void DrawShortRange( int Index )
{
FormPtr frmP;
RectangleType bounds;
int i, j, Xs, Ys, Xp, Yp, delta;
int dX, dY, dX3, dY3, distToTracked;
frmP = FrmGetActiveForm();
RectangularShortcuts( frmP, WarpBButton );
FrmDrawForm ( frmP);
// Rectangle for chart
bounds.topLeft.x = 0;
bounds.topLeft.y = BOUNDSY - EXTRAERASE;
bounds.extent.x = 160;
bounds.extent.y = 160 - BOUNDSY + EXTRAERASE;
WinEraseRectangle( &bounds, 0 );
WinSetClip( &bounds );
// Centre of chart
Xs = (int)((SHORTRANGEWIDTH >> 1) + SHORTRANGEBOUNDSX);
Ys = (int)((SHORTRANGEHEIGHT >> 1) + BOUNDSY);
delta = (SHORTRANGEWIDTH / (MAXRANGE << 1));
FntSetFont( stdFont );
// Draw the maximum range circle
if (GetFuel() > 0)
DrawCircle( Xs, Ys, GetFuel()*delta );
// show the tracked system (if any)
if (TrackedSystem >= 0)
{
distToTracked = RealDistance(SolarSystem[COMMANDER.CurSystem], SolarSystem[TrackedSystem]);
if (distToTracked > 0)
{
dX = (int)(25.0 * ((float)SolarSystem[COMMANDER.CurSystem].X - (float)SolarSystem[TrackedSystem].X) /
(float)distToTracked);
dY = (int)(25.0 * ((float)SolarSystem[COMMANDER.CurSystem].Y - (float)SolarSystem[TrackedSystem].Y) /
(float)distToTracked);
// draw directional arrow from planet -- I'd do this in color if it were easier.
dY3 = -(int)(4.0 * ((float)SolarSystem[COMMANDER.CurSystem].X - (float)SolarSystem[TrackedSystem].X) /
(float)distToTracked);
dX3 = (int)(4.0 * ((float)SolarSystem[COMMANDER.CurSystem].Y - (float)SolarSystem[TrackedSystem].Y) /
(float)distToTracked);
WinDrawLine( Xs - dX, Ys - dY, Xs - dX3, Ys - dY3 );
WinDrawLine( Xs - dX, Ys - dY, Xs + dX3, Ys + dY3 );
}
}
// Two loops: first draw the names and then the systems. The names may
// overlap and the systems may be drawn on the names, but at least every
// system is visible.
for (j=0; j<2; ++j)
{
for (i=0; i<MAXSOLARSYSTEM; ++i)
{
if ((ABS( SolarSystem[i].X - SolarSystem[Index].X ) <= MAXRANGE) &&
(ABS( SolarSystem[i].Y - SolarSystem[Index].Y ) <= MAXRANGE))
{
Xp = (int)((SHORTRANGEWIDTH >> 1) +
(SolarSystem[i].X - SolarSystem[Index].X) *
(SHORTRANGEWIDTH / (MAXRANGE << 1)) +
SHORTRANGEBOUNDSX - EXTRAERASE);
Yp = (int)((SHORTRANGEHEIGHT >> 1) +
(SolarSystem[i].Y - SolarSystem[Index].Y) *
(SHORTRANGEHEIGHT / (MAXRANGE << 1)) +
BOUNDSY - EXTRAERASE);
if (j == 1)
{
if (i == WarpSystem)
{
WinDrawLine( Xp-2, Yp+3, Xp+8, Yp+3 );
WinDrawLine( Xp+3, Yp-2, Xp+3, Yp+8 );
}
WinDrawBitmap( (SolarSystem[i].Visited ? VisitedShortRangeSystemBmpPtr :
ShortRangeSystemBmpPtr), Xp, Yp );
if (WormholeExists( i, -1 ))
{
delta = WORMHOLEDISTANCE * (SHORTRANGEWIDTH / (MAXRANGE << 1));
if (WormholeExists( i, WarpSystem ))
{
WinDrawLine( Xp-2+delta, Yp+3, Xp+8+delta, Yp+3 );
WinDrawLine( Xp+3+delta, Yp-2, Xp+3+delta, Yp+8 );
}
WinDrawBitmap( WormholeBmpPtr, Xp + delta, Yp );
}
}
else
{
DrawChars( SolarSystemName[SolarSystem[i].NameIndex],
Xp - StrLen( SolarSystemName[SolarSystem[i].NameIndex] ) * 2,
Yp - 12 );
}
}
}
}
// if they're tracking, and they want range info:
if (TrackedSystem >= 0 && ShowTrackedRange)
{
StrPrintF(SBuf, "%d", distToTracked);
StrCat(SBuf, " parsecs to ");
StrCat(SBuf, SolarSystemName[SolarSystem[TrackedSystem].NameIndex]);
DrawChars( SBuf, 0, 149);
}
WinResetClip();
}
// *************************************************************************
// Draw the galactic chart, with system Index selected.
// *************************************************************************
static void DrawGalaxy( int Index )
{
FormPtr frmP;
RectangleType bounds;
int i;
frmP = FrmGetActiveForm();
RectangularShortcuts( frmP, GalacticChartBButton );
FrmDrawForm ( frmP);
EraseRectangle( 0, 136, 120, 12 );
EraseRectangle( 0, 148, 160, 12 );
bounds.topLeft.x = 0;
bounds.topLeft.y = BOUNDSY;
bounds.extent.x = 160;
bounds.extent.y = GALAXYHEIGHT+2*EXTRAERASE-2;
WinEraseRectangle( &bounds, 0 );
WinSetClip( &bounds );
if (GetFuel() > 0)
DrawCircle( CURSYSTEM.X+BOUNDSX, CURSYSTEM.Y+BOUNDSY, GetFuel() );
for (i=0; i<MAXWORMHOLE; i++)
{
// Gosh, my idea of designating wormholes by using a negative index would
// have been a lot cleverer, had both systems and wormholes not started with
// an index of 0! SjG
if (i == -Index - 1)
{
WinDrawLine(SolarSystem[Wormhole[i]].X + BOUNDSX - EXTRAERASE + 3 + WORMHOLEDISTANCE,
SolarSystem[Wormhole[i]].Y + BOUNDSY - EXTRAERASE + 3,
SolarSystem[Wormhole[i]].X + BOUNDSX - EXTRAERASE + 7 + WORMHOLEDISTANCE,
SolarSystem[Wormhole[i]].Y + BOUNDSY - EXTRAERASE + 3);
WinDrawLine(SolarSystem[Wormhole[i]].X + BOUNDSX - EXTRAERASE + 4 + WORMHOLEDISTANCE,
SolarSystem[Wormhole[i]].Y + BOUNDSY - EXTRAERASE,
SolarSystem[Wormhole[i]].X + BOUNDSX - EXTRAERASE + 4 + WORMHOLEDISTANCE,
SolarSystem[Wormhole[i]].Y + BOUNDSY - EXTRAERASE + 6);
WinDrawLine(SolarSystem[Wormhole[i]].X + BOUNDSX - EXTRAERASE + 4 + WORMHOLEDISTANCE,
SolarSystem[Wormhole[i]].Y + BOUNDSY - EXTRAERASE + 3,
SolarSystem[i < MAXWORMHOLE-1 ? Wormhole[i+1] : Wormhole[0]].X + 3 + BOUNDSX - EXTRAERASE,
SolarSystem[i < MAXWORMHOLE-1 ? Wormhole[i+1] : Wormhole[0]].Y + 3 + BOUNDSY - EXTRAERASE);
}
}
for (i=0; i<MAXSOLARSYSTEM; ++i)
{
if (i == Index)
{
WinDrawBitmap(
(SolarSystem[i].Visited ? CurrentVisitedSystemBmpPtr : CurrentSystemBmpPtr),
SolarSystem[i].X+BOUNDSX-EXTRAERASE, SolarSystem[i].Y+BOUNDSY-EXTRAERASE );
}
else
{
WinDrawBitmap(
(SolarSystem[i].Visited ? VisitedSystemBmpPtr : SystemBmpPtr),
SolarSystem[i].X+BOUNDSX-EXTRAERASE+1, SolarSystem[i].Y+BOUNDSY-EXTRAERASE+1 );
}
if (i == TrackedSystem)
{
WinDrawLine( SolarSystem[i].X+BOUNDSX-3, SolarSystem[i].Y+BOUNDSY+3,
SolarSystem[i].X+BOUNDSX-2, SolarSystem[i].Y+BOUNDSY+2);
WinDrawLine( SolarSystem[i].X+BOUNDSX-3, SolarSystem[i].Y+BOUNDSY-3,
SolarSystem[i].X+BOUNDSX-2, SolarSystem[i].Y+BOUNDSY-2);
WinDrawLine( SolarSystem[i].X+BOUNDSX+3, SolarSystem[i].Y+BOUNDSY+3,
SolarSystem[i].X+BOUNDSX+2, SolarSystem[i].Y+BOUNDSY+2);
WinDrawLine( SolarSystem[i].X+BOUNDSX+3, SolarSystem[i].Y+BOUNDSY-3,
SolarSystem[i].X+BOUNDSX+2, SolarSystem[i].Y+BOUNDSY-2);
}
if (WormholeExists( i, -1 ))
WinDrawBitmap( SmallWormholeBmpPtr, SolarSystem[i].X+BOUNDSX-EXTRAERASE+2+
WORMHOLEDISTANCE, SolarSystem[i].Y+BOUNDSY-EXTRAERASE+1 );
}
WinResetClip();
if (Index >= 0)
{
DrawChars( SolarSystemName[SolarSystem[Index].NameIndex], 0, 136 );
StrCopy( SBuf, SystemSize[SolarSystem[Index].Size] );
StrCat( SBuf, " " );
StrCat( SBuf, TechLevel[SolarSystem[Index].TechLevel] );
StrCat( SBuf, " " );
StrCat( SBuf, Politics[SolarSystem[Index].Politics].Name );
DrawChars( SBuf, 0, 148 );
StrIToA( SBuf, RealDistance( CURSYSTEM, SolarSystem[Index] ) );
StrCat( SBuf, " parsecs" );
DrawChars( SBuf, 58, 136 );
GalacticChartSystem = Index;
}
else
{
i = -Index - 1;
StrCopy( SBuf, "Wormhole to ");
StrCat( SBuf, SolarSystemName[i < MAXWORMHOLE-1 ? Wormhole[i+1] : Wormhole[0]]);
DrawChars( SBuf, 0,136);
StrCopy ( SBuf, "(from ");
StrCat( SBuf, SolarSystemName[Wormhole[i]]);
StrCat( SBuf, " System)");
DrawChars( SBuf, 0, 148);
}
if (CanSuperWarp)
{
FrmShowObject( frmP, FrmGetObjectIndex( frmP, GalacticChartSuperWarpButton ) );
}
else
{
FrmHideObject( frmP, FrmGetObjectIndex( frmP, GalacticChartSuperWarpButton ) );
}
}
// *************************************************************************
// Events of the short range chart
// *************************************************************************
Boolean WarpFormHandleEvent(EventPtr eventP)
{
Boolean handled = false;
int Xp, Yp, i, Index;
switch (eventP->eType)
{
// Tap one of the systems on the short range chart
case penDownEvent:
if ((eventP->screenX >= SHORTRANGEBOUNDSX-EXTRAERASE) &&
(eventP->screenX <= SHORTRANGEBOUNDSX+SHORTRANGEWIDTH+EXTRAERASE) &&
(eventP->screenY >= BOUNDSY-EXTRAERASE) &&
(eventP->screenY <= BOUNDSY+SHORTRANGEHEIGHT+EXTRAERASE))
{
i = 0;
Index = COMMANDER.CurSystem;
while (i < MAXSOLARSYSTEM)
{
Xp = (int)((SHORTRANGEWIDTH >> 1) +
(SolarSystem[i].X - SolarSystem[Index].X) *
(SHORTRANGEWIDTH / (MAXRANGE << 1)) +
SHORTRANGEBOUNDSX);
Yp = (int)((SHORTRANGEHEIGHT >> 1) +
(SolarSystem[i].Y - SolarSystem[Index].Y) *
(SHORTRANGEHEIGHT / (MAXRANGE << 1)) +
BOUNDSY);
if ((ABS( Xp - (eventP->screenX) ) <= MINDISTANCE) &&
(ABS( Yp - (eventP->screenY) ) <= MINDISTANCE))
break;
++i;
}
if (i < MAXSOLARSYSTEM)
{
WarpSystem = i;
if (!AlwaysInfo && APLscreen && RealDistance( CURSYSTEM, SolarSystem[WarpSystem] ) <= GetFuel() &&
RealDistance( CURSYSTEM, SolarSystem[WarpSystem] ) > 0)
CurForm = AveragePricesForm;
else
CurForm = ExecuteWarpForm;
FrmGotoForm( CurForm );
handled = true;
break;
}
i = 0;
while (i < MAXWORMHOLE)
{
Xp = (int)((SHORTRANGEWIDTH >> 1) +
(SolarSystem[Wormhole[i]].X + WORMHOLEDISTANCE - SolarSystem[Index].X) *
(SHORTRANGEWIDTH / (MAXRANGE << 1)) +
SHORTRANGEBOUNDSX);
Yp = (int)((SHORTRANGEHEIGHT >> 1) +
(SolarSystem[Wormhole[i]].Y - SolarSystem[Index].Y) *
(SHORTRANGEHEIGHT / (MAXRANGE << 1)) +
BOUNDSY);
if ((ABS( Xp - (eventP->screenX) ) <= MINDISTANCE) &&
(ABS( Yp - (eventP->screenY) ) <= MINDISTANCE))
break;
++i;
}
if (i < MAXWORMHOLE)
{
if (COMMANDER.CurSystem != Wormhole[i])
FrmCustomAlert( WormholeOutOfRangeAlert, SolarSystemName[i < MAXWORMHOLE-1 ? Wormhole[i+1] : Wormhole[0]], SolarSystemName[Wormhole[i]], "" );
else
{
WarpSystem = (i < MAXWORMHOLE-1 ? Wormhole[i+1] : Wormhole[0] );
if (!AlwaysInfo && APLscreen)
CurForm = AveragePricesForm;
else
CurForm = ExecuteWarpForm;
FrmGotoForm( CurForm );
}
handled = true;
break;
}
}
break;
case frmOpenEvent:
DrawShortRange( COMMANDER.CurSystem );
handled = true;
break;
case frmUpdateEvent:
DrawShortRange( COMMANDER.CurSystem );
handled = true;
break;
default:
break;
}
return handled;
}
// *************************************************************************
// Handling of events on Galactic Chart
// *************************************************************************
Boolean GalacticChartFormHandleEvent(EventPtr eventP)
{
Boolean handled = false;
Boolean track = false;
int i=0, d, delta;
static int last = -1;
Handle SystemH;
Handle SystemH2;
FormPtr frm;
char FindSystem[NAMELEN+1];
Boolean DontLoad;
switch (eventP->eType)
{
case keyDownEvent:
d = ScrollButton( eventP );
if (d == chrPageUp || d == chrPageDown)
{
if (d == chrPageDown)
{
i = GalacticChartSystem + 1;
if (i >= MAXSOLARSYSTEM)
i = 0;
}
else
{
i = GalacticChartSystem - 1;
if (i < 0)
i = MAXSOLARSYSTEM-1;
}
DrawGalaxy( i );
handled = true;
}
break;
// tap one of the systems
case penDownEvent:
if ((eventP->screenX >= BOUNDSX-EXTRAERASE) &&
(eventP->screenX <= BOUNDSX+GALAXYWIDTH+EXTRAERASE) &&
(eventP->screenY >= BOUNDSY-EXTRAERASE) &&
(eventP->screenY <= BOUNDSY+GALAXYHEIGHT+EXTRAERASE))
{
i = 0;
delta = WORMHOLEDISTANCE * (SHORTRANGEWIDTH / (MAXRANGE << 1))>>1;
while (i < MAXWORMHOLE)
{
if ((ABS( SolarSystem[Wormhole[i]].X + delta - (eventP->screenX - BOUNDSX) ) <= 1) &&
(ABS( SolarSystem[Wormhole[i]].Y - (eventP->screenY - BOUNDSY) ) <= 1))
break;
++i;
}
if (i < MAXWORMHOLE)
{
DrawGalaxy(-i-1);
last = -1;
handled = true;
break;
}
i = 0;
while (i < MAXSOLARSYSTEM)
{
if ((ABS( SolarSystem[i].X - (eventP->screenX - BOUNDSX) ) <= MINDISTANCE>>1) &&
(ABS( SolarSystem[i].Y - (eventP->screenY - BOUNDSY) ) <= MINDISTANCE>>1))
break;
++i;
}
if (i < MAXSOLARSYSTEM)
{
if (i == TrackedSystem)
{
StrCopy( SBuf, "Do you wish to stop tracking ");
StrCat( SBuf, SolarSystemName[i]);
if (FrmCustomAlert(TrackSystemAlert,SBuf, NULL, NULL) == TrackSystemYes)
{
TrackedSystem = -1;
}
}
else if (i == last)
{
if (TrackedSystem == -1)
{
StrCopy( SBuf, "Do you wish to track ");
StrCat( SBuf, SolarSystemName[i] );
}
else
{
StrCopy( SBuf, "Do you wish to stop tracking ");
StrCat( SBuf, SolarSystemName[TrackedSystem] );
StrCat( SBuf, ", and track ");
StrCat( SBuf, SolarSystemName[i] );
StrCat( SBuf, " instead");
}
if (FrmCustomAlert(TrackSystemAlert,SBuf, NULL, NULL) == TrackSystemYes)
{
TrackedSystem = i;
}
}
last = i;
DrawGalaxy( i );
handled = true;
break;
}
}
break;
// Find System
case ctlSelectEvent:
if (eventP->data.ctlSelect.controlID == GalacticChartSuperWarpButton)
{
if (TrackedSystem < 0)
{
FrmAlert(NoSystemSelectedAlert);
return true;
}
else if (TrackedSystem == COMMANDER.CurSystem)
{
FrmAlert( NoJumpToCurSystemAlert );
return true;
}
else if (FrmCustomAlert(UseSingularityAlert, SolarSystemName[TrackedSystem], " ", " ") == UseSingularityUseSingularity)
{
WarpSystem = TrackedSystem;
CanSuperWarp = false;
DoWarp(true);
}
}
else if (eventP->data.ctlSelect.controlID == GalacticChartFindButton)
{
frm = FrmInitForm( FindSystemForm );
SystemH = (Handle) SetField( frm, FindSystemSystemField, "", NAMELEN+1, true );
d = FrmDoDialog( frm );
GetField( frm, FindSystemSystemField, SBuf, SystemH );
if (SBuf[0] == '\0')
d = FindSystemCancelButton;
else
StrCopy( FindSystem, SBuf );
track = GetCheckBox( frm, FindSystemTrackCheckbox );
FrmDeleteForm( frm );
if (d != FindSystemOKButton)
{
handled = true;
break;
}
if (StrCompare( FindSystem, "Moolah" ) == 0)
{
Credits += 100000;
}
else if (StrCompare( FindSystem, "Very rare" ) == 0)
{
frm = FrmInitForm( RareCheatForm );
SetCheckBox( frm, RareCheatMarieCheckbox, VeryRareEncounter & (Byte)ALREADYMARIE );
SetCheckBox( frm, RareCheatHuieCheckbox, VeryRareEncounter & (Byte)ALREADYHUIE );
SetCheckBox( frm, RareCheatAhabCheckbox, VeryRareEncounter & (Byte)ALREADYAHAB );
SetCheckBox( frm, RareCheatConradCheckbox, VeryRareEncounter & (Byte)ALREADYCONRAD );
SetCheckBox( frm, RareCheatGoodTonicCheckbox, VeryRareEncounter & (Byte)ALREADYBOTTLEGOOD );
SetCheckBox( frm, RareCheatBadTonicCheckbox, VeryRareEncounter & (Byte)ALREADYBOTTLEOLD );
StrIToA( SBuf, ChanceOfVeryRareEncounter );
SystemH = (Handle) SetField( frm, RareCheatChancesField, SBuf, 5, true );
StrIToA( SBuf, ChanceOfTradeInOrbit );
SystemH2 = (Handle) SetField( frm, RareCheatTradeField, SBuf, 5, true );
d = FrmDoDialog( frm );
GetField( frm, RareCheatChancesField, SBuf, SystemH );
if (SBuf[0] != '\0')
{
ChanceOfVeryRareEncounter = StrAToI(SBuf);
}
GetField( frm, RareCheatTradeField, SBuf, SystemH2 );
if (SBuf[0] != '\0')
{
ChanceOfTradeInOrbit = StrAToI(SBuf);
}
VeryRareEncounter = 0;
if (GetCheckBox( frm, RareCheatMarieCheckbox))
VeryRareEncounter |= (Byte)ALREADYMARIE;
if (GetCheckBox( frm, RareCheatHuieCheckbox))
VeryRareEncounter |= (Byte)ALREADYHUIE;
if (GetCheckBox( frm, RareCheatAhabCheckbox))
VeryRareEncounter |= (Byte)ALREADYAHAB;
if (GetCheckBox( frm, RareCheatConradCheckbox))
VeryRareEncounter |= (Byte)ALREADYCONRAD;
if (GetCheckBox( frm, RareCheatGoodTonicCheckbox))
VeryRareEncounter |= (Byte)ALREADYBOTTLEGOOD;
if (GetCheckBox( frm, RareCheatBadTonicCheckbox))
VeryRareEncounter |= (Byte)ALREADYBOTTLEOLD;
FrmDeleteForm( frm );
}
else if (StrCompare( FindSystem, "Cheetah" ) == 0)
{
CheatCounter = 3;
}
else if (StrNCompare(FindSystem,"Go ",3) == 0 && StrLen(FindSystem) > 3 )
{
StrCopy(FindSystem, FindSystem+3);
i = 0;
while (i < MAXSOLARSYSTEM)
{
if (StrCaselessCompare( SolarSystemName[i], FindSystem ) >= 0)
break;
++i;
}
if (i < MAXSOLARSYSTEM)
{
COMMANDER.CurSystem = i;
DrawGalaxy( i );
}
}
else if (StrCompare( FindSystem, "Quests" ) == 0)
{
frm = FrmInitForm( QuestListForm );
for (i=0; i<MAXSOLARSYSTEM; ++i)
{
if (SolarSystem[i].Special == DRAGONFLY)
setLabelText( frm, QuestListDragonflyLabel, SolarSystemName[SolarSystem[i].NameIndex] );
else if (SolarSystem[i].Special == SPACEMONSTER)
setLabelText( frm, QuestListMonsterLabel, SolarSystemName[SolarSystem[i].NameIndex] );
else if (SolarSystem[i].Special == JAPORIDISEASE)
setLabelText( frm, QuestListDiseaseLabel, SolarSystemName[SolarSystem[i].NameIndex] );
else if (SolarSystem[i].Special == ALIENARTIFACT)
{
setLabelText( frm, QuestListArtifactQuestLabel, "Artifact:" );
setLabelText( frm, QuestListArtifactLabel, SolarSystemName[SolarSystem[i].NameIndex] );
}
else if (SolarSystem[i].Special == ARTIFACTDELIVERY && ArtifactOnBoard)
{
setLabelText( frm, QuestListArtifactQuestLabel, "Berger:" );
setLabelText( frm, QuestListArtifactLabel, SolarSystemName[SolarSystem[i].NameIndex] );
}
else if (SolarSystem[i].Special == TRIBBLE)
setLabelText( frm, QuestListTribblesLabel, SolarSystemName[SolarSystem[i].NameIndex] );
else if (SolarSystem[i].Special == GETREACTOR)
setLabelText( frm, QuestListReactorLabel, SolarSystemName[SolarSystem[i].NameIndex] );
else if (SolarSystem[i].Special == AMBASSADORJAREK)
setLabelText( frm, QuestListJarekLabel, SolarSystemName[SolarSystem[i].NameIndex] );
else if (SolarSystem[i].Special == ALIENINVASION)
setLabelText( frm, QuestListInvasionLabel, SolarSystemName[SolarSystem[i].NameIndex] );
else if (SolarSystem[i].Special == EXPERIMENT)
setLabelText( frm, QuestListExperimentLabel, SolarSystemName[SolarSystem[i].NameIndex] );
else if (SolarSystem[i].Special == TRANSPORTWILD)
setLabelText( frm, QuestListWildLabel, SolarSystemName[SolarSystem[i].NameIndex] );
else if (SolarSystem[i].Special == SCARAB)
setLabelText( frm, QuestListScarabLabel, SolarSystemName[SolarSystem[i].NameIndex] );
else if (SolarSystem[i].Special == SCARABDESTROYED && ScarabStatus > 0 && ScarabStatus < 2)
setLabelText( frm, QuestListScarabLabel, SolarSystemName[SolarSystem[i].NameIndex] );
}
FrmDoDialog( frm );
FrmDeleteForm( frm );
}
#ifdef BETATEST
else if (StrCompare( FindSystem, "Load" ) == 0)
#else
else if (StrCompare( FindSystem, "Timewarp" ) == 0)
#endif
{
DontLoad = false;
if (!GameLoaded)
{
if (FrmAlert( DisableScoringAlert ) != DisableScoringYes)
DontLoad = true;
}
else if (FrmAlert( ReallyLoadAlert ) != ReallyLoadYes)
DontLoad = true;
if (!DontLoad)
{
if (LoadGame( 1 ))
{
GameLoaded = true;
FrmGotoForm( CurForm );
}
}
}
else
{
i = 0;
while (i < MAXSOLARSYSTEM)
{
if (StrCaselessCompare( SolarSystemName[i], FindSystem ) >= 0)
break;
++i;
}
if (i >= MAXSOLARSYSTEM)
{
i = COMMANDER.CurSystem;
}
else if (track)
{
TrackedSystem = i;
}
DrawGalaxy( i );
}
}
handled = true;
break;
case frmOpenEvent:
DrawGalaxy( COMMANDER.CurSystem );
handled = true;
break;
case frmUpdateEvent:
DrawGalaxy( COMMANDER.CurSystem );
handled = true;
break;
default:
break;
}
return handled;
}

205
Src/external.h Normal file
View File

@ -0,0 +1,205 @@
/***********************************************************************
*
* SPACE TRADER 1.2.0
*
* External.h
*
* Copyright (C) 2000-2002 Pieter Spronck, All Rights Reserved
*
* Additional coding by Sam Anderson (rulez2@home.com)
* Additional coding by Samuel Goldstein (palm@fogbound.net)
*
* Some code of Matt Lee's Dope Wars program has been used.
*
* 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.
*
* You can contact the author at space_trader@hotmail.com
*
* For those who are familiar with the classic game Elite: many of the
* ideas in Space Trader are heavily inspired by Elite.
*
**********************************************************************/
// External Definitions
// This file is included into all sources
// Defines Global Variables for external reference
//
// Global Variables defined in Global.c
// Any new Global Variable should be referenced here and can then
// be used in any source file
#define PILOT_PRECOMPILED_HEADERS_OFF 1
#include <PalmCompatibility.h>
#include <PalmOS.h>
#include <SysEvtMgr.h>
#include <Graffiti.h>
#include <font.h>
#include <datetime.h>
#include <StringMgr.h>
#include "MerchantRsc.h"
#include "MerchantGraphics.h"
#include "spacetrader.h" // Includes data definitions and Prototypes
// Global Variables
extern long Credits;
extern long Debt;
extern long PoliceRecordScore;
extern long ReputationScore;
extern long PoliceKills;
extern long TraderKills;
extern long PirateKills;
extern long SellPrice[];
extern long BuyPrice[];
extern long BuyingPrice[];
extern long ShipPrice[];
extern long MonsterHull;
extern unsigned long GalacticChartUpdateTicks;
extern int CheatCounter;
extern int Days;
extern int CurForm;
extern int EncounterType;
extern int WarpSystem;
extern int NoClaim;
extern int SelectedShipType;
extern int LeaveEmpty;
extern int GalacticChartSystem;
extern int NewsSpecialEventCount;
extern int TrackedSystem;
extern int ChanceOfVeryRareEncounter;
extern int ChanceOfTradeInOrbit;
extern int Shortcut1;
extern int Shortcut2;
extern int Shortcut3;
extern int Shortcut4;
extern int ShortcutTarget[];
extern char MonsterStatus;
extern char DragonflyStatus;
extern char JaporiDiseaseStatus;
extern char JarekStatus;
extern char WildStatus;
extern char InvasionStatus;
extern char ExperimentStatus;
extern char FabricRipProbability;
extern char VeryRareEncounter;
extern char Difficulty;
extern char ReactorStatus;
extern char ScarabStatus;
extern char SBuf[];
extern char SBuf2[];
extern char NameCommander[];
extern char Wormhole[];
extern char* Shortcuts[];
extern char* SolarSystemName[];
extern char* SystemSize[];
extern char* TechLevel[];
extern char* Activity[];
extern char* DifficultyLevel[];
extern char* SpecialResources[];
extern char* Status[];
extern char* MercenaryName[];
extern Boolean MoonBought;
extern Boolean Clicks;
extern Boolean Raided;
extern Boolean Inspected;
extern Boolean AlwaysIgnoreTraders;
extern Boolean AlwaysIgnorePolice;
extern Boolean AlwaysIgnorePirates;
extern Boolean AlwaysIgnoreTradeInOrbit;
extern Boolean TribbleMessage;
extern Boolean AutoFuel;
extern Boolean AutoRepair;
extern Boolean Insurance;
extern Boolean EscapePod;
extern Boolean PriceDifferences;
extern Boolean ArtifactOnBoard;
extern Boolean APLscreen;
extern Boolean ReserveMoney;
extern Boolean AlwaysInfo;
extern Boolean TextualEncounters;
extern Boolean AutoAttack;
extern Boolean AutoFlee;
extern Boolean Continuous;
extern Boolean AttackIconStatus;
extern Boolean AttackFleeing;
extern Boolean PossibleToGoThroughRip;
extern Boolean UseHWButtons;
extern Boolean NewsAutoPay;
extern Boolean ShowTrackedRange;
extern Boolean JustLootedMarie;
extern Boolean ArrivedViaWormhole;
extern Boolean AlreadyPaidForNewspaper;
extern Boolean TrackAutoOff;
extern Boolean RemindLoans;
extern Boolean CanSuperWarp;
extern Boolean GameLoaded;
extern Boolean LitterWarning;
extern Boolean SharePreferences;
extern Boolean IdentifyStartup;
extern Boolean RectangularButtonsOn;
extern SHIP Ship;
extern SHIP Opponent;
extern SHIP Dragonfly;
extern SHIP SpaceMonster;
extern SHIP Scarab;
extern SOLARSYSTEM SolarSystem[];
extern SHIPTYPE Shiptype[];
extern SHIELD Shieldtype[];
extern WEAPON Weapontype[];
extern GADGET Gadgettype[];
extern CREWMEMBER Mercenary[];
extern POLITICS Politics[];
extern POLICERECORD PoliceRecord[];
extern TRADEITEM Tradeitem[];
extern SPECIALEVENT SpecialEvent[];
extern HIGHSCORE Hscores[];
extern REPUTATION Reputation[];
extern Handle SystemBmp;
extern Handle CurrentSystemBmp;
extern Handle ShortRangeSystemBmp;
extern Handle WormholeBmp;
extern Handle SmallWormholeBmp;
extern Handle VisitedSystemBmp;
extern Handle CurrentVisitedSystemBmp;
extern Handle VisitedShortRangeSystemBmp;
extern Handle ShipBmp[];
extern Handle DamagedShipBmp[];
extern Handle ShieldedShipBmp[];
extern Handle DamagedShieldedShipBmp[];
extern Handle IconBmp[];
extern BitmapPtr ShipBmpPtr[];
extern BitmapPtr SystemBmpPtr;
extern BitmapPtr CurrentSystemBmpPtr;
extern BitmapPtr ShortRangeSystemBmpPtr;
extern BitmapPtr WormholeBmpPtr;
extern BitmapPtr SmallWormholeBmpPtr;
extern BitmapPtr VisitedSystemBmpPtr;
extern BitmapPtr CurrentVisitedSystemBmpPtr;
extern BitmapPtr VisitedShortRangeSystemBmpPtr;
extern BitmapPtr DamagedShipBmpPtr[];
extern BitmapPtr ShieldedShipBmpPtr[];
extern BitmapPtr DamagedShieldedShipBmpPtr[];
extern BitmapPtr IconBmpPtr[];
extern Handle NameH;
//extern DmOpenRef pmDB;
extern DWord romVersion;

475
Src/spacetrader.h Normal file
View File

@ -0,0 +1,475 @@
/***********************************************************************
*
* SPACE TRADER 1.2.0
*
* Spacetrader.h
*
* Copyright (C) 2000-2002 Pieter Spronck, All Rights Reserved
*
* Additional coding by Sam Anderson (rulez2@home.com)
* Additional coding by Samuel Goldstein (palm@fogbound.net)
*
* Some code of Matt Lee's Dope Wars program has been used.
*
* 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.
*
* You can contact the author at space_trader@hotmail.com
*
* For those who are familiar with the classic game Elite: many of the
* ideas in Space Trader are heavily inspired by Elite.
*
**********************************************************************/
//
// Space Trader Main Include
//
#define appFileCreator 'STra'
#define appVersionNum 0x01
#define appPrefID 0x00
#define appPrefVersionNum 0x01
// Special Enables // Comment these out to disable code
#define _STRA_CHEAT_ // Cheat Enable
#define _STRA_SHIPYARDCREDITS_ // Display Trade Credits in Ship Yard
#define _INCLUDE_DEBUG_DIALOGS_ // Include code for displaying Debug Alerts
// Add Ships, Weapons, Shields, and Gadgets that don't show up normally
#define EXTRAWEAPONS 1 // Number of weapons over standard
#define EXTRAGADGETS 1 // Number of Gadgets over standard
#define EXTRASHIELDS 1 // Number of Shields over standard
#define EXTRASHIPS 5 // Number of Ships over standard
// Tradeable items
#define MAXTRADEITEM 10 // Number of items traded
#define MAXDIGITS 8 // Maximum amount of cash 99,999,999
#define MAXPRICEDIGITS 5 // Maximum price 99,999.
#define MAXQTYDIGITS 3 // Maximum quantity 999
// Activity level of police, traders or pirates
#define MAXACTIVITY 8
#define MAXSTATUS 8
// System status: normally this is uneventful, but sometimes a system has a
// special event occurring. This influences some prices.
#define UNEVENTFUL 0
#define WAR 1
#define PLAGUE 2
#define DROUGHT 3
#define BOREDOM 4
#define COLD 5
#define CROPFAILURE 6
#define LACKOFWORKERS 7
// Difficulty levels
#define MAXDIFFICULTY 5
#define BEGINNER 0
#define EASY 1
#define NORMAL 2
#define HARD 3
#define IMPOSSIBLE 4
// Crewmembers. The commander is always the crewmember with index 0.
// Zeethibal is always the last
#define MAXCREWMEMBER 31
// Extra Crewmembers who won't be found randomly
#define MAXSKILL 10
#define NAMELEN 20
// Skills
#define PILOTSKILL 1
#define FIGHTERSKILL 2
#define TRADERSKILL 3
#define ENGINEERSKILL 4
// Tradeitems
#define WATER 0
#define FURS 1
#define FOOD 2
#define ORE 3
#define GAMES 4
#define FIREARMS 5
#define MEDICINE 6
#define MACHINERY 7
#define NARCOTICS 8
#define ROBOTS 9
// Ship types
#define MAXSHIPTYPE 10
#define MAXRANGE 20
#define MANTISTYPE MAXSHIPTYPE+2
#define SCARABTYPE MAXSHIPTYPE+3
#define BOTTLETYPE MAXSHIPTYPE+4
// Weapons
#define MAXWEAPONTYPE 3
#define PULSELASERWEAPON 0
#define PULSELASERPOWER 15
#define BEAMLASERWEAPON 1
#define BEAMLASERPOWER 25
#define MILITARYLASERWEAPON 2
#define MILITARYLASERPOWER 35
#define MORGANLASERWEAPON 3
#define MORGANLASERPOWER 85 // fixme!
// Shields
#define MAXSHIELDTYPE 2
#define ENERGYSHIELD 0
#define ESHIELDPOWER 100
#define REFLECTIVESHIELD 1
#define RSHIELDPOWER 200
#define LIGHTNINGSHIELD 2
#define LSHIELDPOWER 350
// Hull Upgrade
#define UPGRADEDHULL 50
// Gadgets
#define MAXGADGETTYPE 5
#define EXTRABAYS 0
#define AUTOREPAIRSYSTEM 1
#define NAVIGATINGSYSTEM 2
#define TARGETINGSYSTEM 3
#define CLOAKINGDEVICE 4
#define FUELCOMPACTOR 5 // MAXGADGETTYPE + 1
// Skills
#define MAXSKILLTYPE 4
#define SKILLBONUS 3
#define CLOAKBONUS 2
// Police Action
#define POLICE 0
#define POLICEINSPECTION 0 // Police asks to submit for inspection
#define POLICEIGNORE 1 // Police just ignores you
#define POLICEATTACK 2 // Police attacks you (sometimes on sight)
#define POLICEFLEE 3 // Police is fleeing
#define MAXPOLICE 9
// Pirate Actions
#define PIRATE 10
#define PIRATEATTACK 10 // Pirate attacks
#define PIRATEFLEE 11 // Pirate flees
#define PIRATEIGNORE 12 // Pirate ignores you (because of cloak)
#define PIRATESURRENDER 13 // Pirate surrenders
#define MAXPIRATE 19
// Trader Actions
#define TRADER 20
#define TRADERIGNORE 20 // Trader passes
#define TRADERFLEE 21 // Trader flees
#define TRADERATTACK 22 // Trader is attacking (after being provoked)
#define TRADERSURRENDER 23 // Trader surrenders
#define TRADERSELL 24 // Trader will sell products in orbit
#define TRADERBUY 25 // Trader will buy products in orbit
#define TRADERNOTRADE 26 // Player has declined to transact with Trader
#define MAXTRADER 29
// Space Monster Actions
#define SPACEMONSTERATTACK 30
#define SPACEMONSTERIGNORE 31
#define MAXSPACEMONSTER 39
// Dragonfly Actions
#define DRAGONFLYATTACK 40
#define DRAGONFLYIGNORE 41
#define MAXDRAGONFLY 49
#define MANTIS 50
// Scarab Actions
#define SCARABATTACK 60
#define SCARABIGNORE 61
#define MAXSCARAB 69
// Famous Captain
#define FAMOUSCAPTAIN 70
#define FAMOUSCAPATTACK 71
#define CAPTAINAHABENCOUNTER 72
#define CAPTAINCONRADENCOUNTER 73
#define CAPTAINHUIEENCOUNTER 74
#define MAXFAMOUSCAPTAIN 79
// Other Special Encounters
#define MARIECELESTEENCOUNTER 80
#define BOTTLEOLDENCOUNTER 81
#define BOTTLEGOODENCOUNTER 82
#define POSTMARIEPOLICEENCOUNTER 83
// The commander's ship
#define MAXWEAPON 3
#define MAXSHIELD 3
#define MAXGADGET 3
#define MAXCREW 3
#define MAXTRIBBLES 100000
// Solar systems
#define MAXSOLARSYSTEM 120
#define ACAMARSYSTEM 0
#define BARATASSYSTEM 6
#define DALEDSYSTEM 17
#define DEVIDIASYSTEM 22
#define GEMULONSYSTEM 32
#define JAPORISYSTEM 41
#define KRAVATSYSTEM 50
#define MELINASYSTEM 59
#define NIXSYSTEM 67
#define OGSYSTEM 70
#define REGULASSYSTEM 82
#define SOLSYSTEM 92
#define UTOPIASYSTEM 109
#define ZALKONSYSTEM 118
// Special events
#define COSTMOON 500000L
#define MAXSPECIALEVENT 37
#define ENDFIXED 7
#define MAXTEXT 9
#define DRAGONFLYDESTROYED 0
#define FLYBARATAS 1
#define FLYMELINA 2
#define FLYREGULAS 3
#define MONSTERKILLED 4
#define MEDICINEDELIVERY 5
#define MOONBOUGHT 6
// ----- fixed locations precede
#define MOONFORSALE 7
#define SKILLINCREASE 8
#define TRIBBLE 9
#define ERASERECORD 10
#define BUYTRIBBLE 11
#define SPACEMONSTER 12
#define DRAGONFLY 13
#define CARGOFORSALE 14
#define INSTALLLIGHTNINGSHIELD 15
#define JAPORIDISEASE 16
#define LOTTERYWINNER 17
#define ARTIFACTDELIVERY 18
#define ALIENARTIFACT 19
#define AMBASSADORJAREK 20
#define ALIENINVASION 21
#define GEMULONINVADED 22
#define GETFUELCOMPACTOR 23
#define EXPERIMENT 24
#define TRANSPORTWILD 25
#define GETREACTOR 26
#define GETSPECIALLASER 27
#define SCARAB 28
#define GETHULLUPGRADED 29
// ------ fixed locations follow
#define SCARABDESTROYED 30
#define REACTORDELIVERED 31
#define JAREKGETSOUT 32
#define GEMULONRESCUED 33
#define EXPERIMENTSTOPPED 34
#define EXPERIMENTNOTSTOPPED 35
#define WILDGETSOUT 36
// Max Number of Tribble Buttons
#define TRIBBLESONSCREEN 31
// Other special events (Encounters)
// First is probability in 1000 that one could happen at all:
#define CHANCEOFVERYRAREENCOUNTER 5
#define MAXVERYRAREENCOUNTER 6
#define MARIECELESTE 0
#define CAPTAINAHAB 1
#define CAPTAINCONRAD 2
#define CAPTAINHUIE 3
#define BOTTLEOLD 4
#define BOTTLEGOOD 5
// Already done this encounter?
#define ALREADYMARIE 1
#define ALREADYAHAB 2
#define ALREADYCONRAD 4
#define ALREADYHUIE 8
#define ALREADYBOTTLEOLD 16
#define ALREADYBOTTLEGOOD 32
// Propability in 1000 that a trader will make offer while in orbit
#define CHANCEOFTRADEINORBIT 100
// Political systems (governments)
#define MAXPOLITICS 17
#define MAXSTRENGTH 8
#define ANARCHY 0
// Tech levels.
#define MAXTECHLEVEL 8
// Cargo Dumping Codes. These identify the operation so we can reuse
// some of the Sell Cargo code.
// SELL is obvious, Dump is when in dock, Jettison is when in space.
#define SELLCARGO 1
#define DUMPCARGO 2
#define JETTISONCARGO 3
// System sizes (influences the number of goods available)
#define MAXSIZE 5
// Newspaper Defines
// Newspaper Mastheads and Headlines have been moved into String Resources, where
// they belong. Mastheads starting with codes will have the codes replaced as follows:
// + -> System Name
// * -> The System Name
#define MAXMASTHEADS 3 // number of newspaper names per Political situation
#define MAXSTORIES 4 // number of canned stories per Political situation
#define NEWSINDENT1 5 // pixels to indent 1st line of news story
#define NEWSINDENT2 5 // pixels to indent 2nd line of news story
#define STORYPROBABILITY 50/MAXTECHLEVEL // probability of a story being shown
#define MAXSPECIALNEWSEVENTS 5 // maximum number of special news events to keep for a system
// News Events that don't exactly match special events
#define WILDARRESTED 90
#define CAUGHTLITTERING 91
#define EXPERIMENTPERFORMED 92
#define ARRIVALVIASINGULARITY 93
#define CAPTAINHUIEATTACKED 100
#define CAPTAINCONRADATTACKED 101
#define CAPTAINAHABATTACKED 102
#define CAPTAINHUIEDESTROYED 110
#define CAPTAINCONRADDESTROYED 111
#define CAPTAINAHABDESTROYED 112
// Police record
#define MAXPOLICERECORD 10
#define ATTACKPOLICESCORE -3
#define KILLPOLICESCORE -6
#define CAUGHTWITHWILDSCORE -4
#define ATTACKTRADERSCORE -2
#define PLUNDERTRADERSCORE -2
#define KILLTRADERSCORE -4
#define ATTACKPIRATESCORE 0
#define KILLPIRATESCORE 1
#define PLUNDERPIRATESCORE -1
#define TRAFFICKING -1
#define FLEEFROMINSPECTION -2
#define TAKEMARIENARCOTICS -4
// Police Record Score
#define PSYCHOPATHSCORE -70
#define VILLAINSCORE -30
#define CRIMINALSCORE -10
#define DUBIOUSSCORE -5
#define CLEANSCORE 0
#define LAWFULSCORE 5
#define TRUSTEDSCORE 10
#define HELPERSCORE 25
#define HEROSCORE 75
// Reputation (depends on number of kills)
#define MAXREPUTATION 9
#define HARMLESSREP 0
#define MOSTLYHARMLESSREP 10
#define POORREP 20
#define AVERAGESCORE 40
#define ABOVEAVERAGESCORE 80
#define COMPETENTREP 150
#define DANGEROUSREP 300
#define DEADLYREP 600
#define ELITESCORE 1500
// Debt Control
#define DEBTWARNING 75000
#define DEBTTOOLARGE 100000
// Resources. Some systems have special resources, which influences some prices.
#define MAXRESOURCES 13
#define NOSPECIALRESOURCES 0
#define MINERALRICH 1
#define MINERALPOOR 2
#define DESERT 3
#define LOTSOFWATER 4
#define RICHSOIL 5
#define POORSOIL 6
#define RICHFAUNA 7
#define LIFELESS 8
#define WEIRDMUSHROOMS 9
#define LOTSOFHERBS 10
#define ARTISTIC 11
#define WARLIKE 12
// Wormholes
#define MAXWORMHOLE 6
#define GALAXYWIDTH 150
#define GALAXYHEIGHT 110
#define SHORTRANGEWIDTH 140
#define SHORTRANGEHEIGHT 140
#define SHORTRANGEBOUNDSX 10
#define BOUNDSX 5
#define BOUNDSY 20
#define MINDISTANCE 6
#define CLOSEDISTANCE 13
#define WORMHOLEDISTANCE 3
#define EXTRAERASE 3
// (There are new functions for crunching down booleans and
// nibbles, which gain us a little room...)
#define MAXFORFUTUREUSE 96
// this is in percentage, and will decrease by one every day.
#define FABRICRIPINITIALPROBABILITY 25
#define MAXHIGHSCORE 3
#define KILLED 0
#define RETIRED 1
#define MOON 2
// size of a UInt16
#define MAX_WORD 65535
// these have been added to avoid tracking down the math library.
#define min( a, b ) ( (a) <= (b) ? (a) : (b) )
#define max( a, b ) ( (a) >= (b) ? (a) : (b) )
#define GetRandom( a ) (SysRandom( 0 )%(a))
#define TOLOWER( a ) ((a) >= 'A' && (a) <= 'Z' ? (a) - 'A' + 'a' : (a))
#define ABS( a ) ((a) < 0 ? (-(a)) : (a))
#define SQR( a ) ((a) * (a))
#define COMMANDER Mercenary[0]
#define CURSYSTEM SolarSystem[COMMANDER.CurSystem]
#define BASEWEAPONPRICE( a ) (BasePrice( Weapontype[a].TechLevel, Weapontype[a].Price ))
#define BASESHIELDPRICE( a ) (BasePrice( Shieldtype[a].TechLevel, Shieldtype[a].Price ))
#define BASEGADGETPRICE( a ) (BasePrice( Gadgettype[a].TechLevel, Gadgettype[a].Price ))
#define BASESHIPPRICE( a ) (((Shiptype[a].Price * (100 - TraderSkill( &Ship ))) / 100) /* * (Difficulty < 3 ? 1 : (Difficulty + 3)) / (Difficulty < 3 ? 1 : 5)*/)
#define WEAPONSELLPRICE( a ) (BaseSellPrice( Ship.Weapon[a], Weapontype[Ship.Weapon[a]].Price ))
#define SHIELDSELLPRICE( a ) (BaseSellPrice( Ship.Shield[a], Shieldtype[Ship.Shield[a]].Price ))
#define GADGETSELLPRICE( a ) (BaseSellPrice( Ship.Gadget[a], Gadgettype[Ship.Gadget[a]].Price ))
#define MERCENARYHIREPRICE( a ) (a < 0 || (a >= MAXCREWMEMBER && WildStatus == 2) ? 0 : ((Mercenary[a].Pilot + Mercenary[a].Fighter + Mercenary[a].Trader + Mercenary[a].Engineer) * 3))
#define ENCOUNTERPOLICE( a ) ((a) >= POLICE && (a) <= MAXPOLICE)
#define ENCOUNTERPIRATE( a ) ((a) >= PIRATE && (a) <= MAXPIRATE)
#define ENCOUNTERTRADER( a ) ((a) >= TRADER && (a) <= MAXTRADER)
#define ENCOUNTERMONSTER( a ) ((a) >= SPACEMONSTERATTACK && (a) <= MAXSPACEMONSTER)
#define ENCOUNTERDRAGONFLY( a ) ((a) >= DRAGONFLYATTACK && (a) <= MAXDRAGONFLY)
#define ENCOUNTERSCARAB( a ) ((a) >= SCARABATTACK && (a) <= MAXSCARAB)
#define ENCOUNTERFAMOUS( a ) ((a) >= FAMOUSCAPTAIN && (a) <= MAXFAMOUSCAPTAIN)
#define STRENGTHPOLICE( a ) (PoliceRecordScore < PSYCHOPATHSCORE ? 3 * Politics[SolarSystem[a].Politics].StrengthPolice : (PoliceRecordScore < VILLAINSCORE ? 2 * Politics[SolarSystem[a].Politics].StrengthPolice : Politics[SolarSystem[a].Politics].StrengthPolice))
#define STARTCOUNTDOWN (3 + Difficulty)
#define BELOW50 (romVersion < sysMakeROMVersion( 5, 0, 0, sysROMStageRelease, 0 ))
#define __SPACETRADER_INC__
// Always include DataTypes after all maximum definitions have occured.
#include "DataTypes.h" // Structure Definitions
#include "Prototype.h" // Function Prototypes